From 0142fbfbfbd1ba7fe66f6acd9a364d378013f0d7 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 28 Nov 2025 11:20:10 +0100 Subject: [PATCH 001/110] Update requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 8cc3f83..47daecc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites +git+https://github.com/TeachBooks/Sphinx-Metadata-Figure teachbooks-sphinx-grasple From 00c79afadebd2864b0c40771ff078fbde741855d Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 28 Nov 2025 11:22:19 +0100 Subject: [PATCH 002/110] Update _config.yml --- book/_config.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/book/_config.yml b/book/_config.yml index 7dfb1d3..ce80713 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -18,6 +18,7 @@ sphinx: - teachbooks_sphinx_grasple - sphinx_apa_references - sphinx_github_alerts + - sphinx_metadata_figure config: html_js_files: - https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js @@ -45,6 +46,10 @@ sphinx: macros: "newcolor": ['\definecolor{newcolor}{RGB}{111, 29, 119}{\color{newcolor}#1}',1] named_colors_custom_colors: {'onlylight':[165,21,160],'lightanddark':[45,180,117,204,158,110],'hyphen-color':[45,180,117,165,21,160],'attributiongrey':[150,150,150]} + metadata_figure_settings: + license: + summaries: false + individual: false teachbooks: attribution_location: margin From 256163c70b915fb062509ebb56b82da4959ff497 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 28 Nov 2025 11:22:56 +0100 Subject: [PATCH 003/110] Add external link to Sphinx-Metadata-Figure manual --- book/_toc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/book/_toc.yml b/book/_toc.yml index dcbfc9d..17e5d9b 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,6 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.md - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 58ec1c78ad7f2215a135c19557bdd70de7749531 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 28 Nov 2025 14:31:47 +0100 Subject: [PATCH 004/110] Update Sphinx Metadata Figure dependency Replaces the git-based Sphinx-Metadata-Figure dependency with the PyPI package sphinx-metadata-figure version 1.0.0 in requirements.txt. --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 47daecc..a2233b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,8 @@ teachbooks == 0.2.3 sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites -git+https://github.com/TeachBooks/Sphinx-Metadata-Figure + +sphinx-metadata-figure==1.0.0 teachbooks-sphinx-grasple From 130a5e37559b0c7c63355b65acd0fb3713da37d1 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 28 Nov 2025 15:16:16 +0100 Subject: [PATCH 005/110] Add style settings for metadata figure placement --- book/_config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/book/_config.yml b/book/_config.yml index ce80713..1cf67a0 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -47,6 +47,8 @@ sphinx: "newcolor": ['\definecolor{newcolor}{RGB}{111, 29, 119}{\color{newcolor}#1}',1] named_colors_custom_colors: {'onlylight':[165,21,160],'lightanddark':[45,180,117,204,158,110],'hyphen-color':[45,180,117,165,21,160],'attributiongrey':[150,150,150]} metadata_figure_settings: + style: + placement: hide license: summaries: false individual: false From 33613846f64e9e07f5df3c3721c8ea48d911cd66 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 28 Nov 2025 16:28:51 +0100 Subject: [PATCH 006/110] Update sphinx-metadata-figure version to 1.0.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a2233b4..4945c7f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites -sphinx-metadata-figure==1.0.0 +sphinx-metadata-figure==1.0.2 teachbooks-sphinx-grasple From a27da88f79be6ba1f0de9343c82f0ab7a2c7d6fa Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 28 Nov 2025 17:09:26 +0100 Subject: [PATCH 007/110] Fix formatting in requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4945c7f..f060f38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites -sphinx-metadata-figure==1.0.2 +sphinx-metadata-figure == 1.0.2 teachbooks-sphinx-grasple From 61b577381884a94feffea965c9e83f94f0066467 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 30 Nov 2025 22:05:40 +0000 Subject: [PATCH 008/110] Bump book/external/sphinx-iframes from `d92bc03` to `b0fcde7` Bumps [book/external/sphinx-iframes](https://github.com/TeachBooks/sphinx-iframes) from `d92bc03` to `b0fcde7`. - [Release notes](https://github.com/TeachBooks/sphinx-iframes/releases) - [Commits](https://github.com/TeachBooks/sphinx-iframes/compare/d92bc03af5f067453caf104a424e0cc0ebdbf04b...b0fcde7e8957babcbda79bf861f6c2e2885c0df4) --- updated-dependencies: - dependency-name: book/external/sphinx-iframes dependency-version: b0fcde7e8957babcbda79bf861f6c2e2885c0df4 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- book/external/sphinx-iframes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/external/sphinx-iframes b/book/external/sphinx-iframes index d92bc03..b0fcde7 160000 --- a/book/external/sphinx-iframes +++ b/book/external/sphinx-iframes @@ -1 +1 @@ -Subproject commit d92bc03af5f067453caf104a424e0cc0ebdbf04b +Subproject commit b0fcde7e8957babcbda79bf861f6c2e2885c0df4 From 268ac7142e586a9641f46d4fa0218bb02c77eb8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 30 Nov 2025 22:05:47 +0000 Subject: [PATCH 009/110] Bump sphinx-metadata-figure from 1.0.2 to 1.0.3 Bumps [sphinx-metadata-figure](https://github.com/TeachBooks/Sphinx-Metadata-Figure) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/TeachBooks/Sphinx-Metadata-Figure/releases) - [Commits](https://github.com/TeachBooks/Sphinx-Metadata-Figure/compare/v1.0.2...v1.0.3) --- updated-dependencies: - dependency-name: sphinx-metadata-figure dependency-version: 1.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f060f38..aa145b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites -sphinx-metadata-figure == 1.0.2 +sphinx-metadata-figure == 1.0.3 teachbooks-sphinx-grasple From eb219bfa0603d9889f2eb6926175298bb9dc7a18 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 1 Dec 2025 09:02:37 +0100 Subject: [PATCH 010/110] Add Sphinx Metadata Figure to favourites list --- book/features/favourites.md | 1 + 1 file changed, 1 insertion(+) diff --git a/book/features/favourites.md b/book/features/favourites.md index 924ce7c..e271ecf 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -42,6 +42,7 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Sphinx Launch Buttons](../external/Sphinx-launch-buttons/README.md) - [Sphinx External ToC (TeachBooks contribution to the original)](https://github.com/TeachBooks/sphinx-external-toc/blob/main/README.md) - [Sphinx GitHub Alerts](../_git/github.com_TeachBooks_Sphinx-GitHub-Alerts/main/README.md) +- [Sphinx Metadata Figure](../_git/github.com_TeachBooks_Sphinx-Metadata-Figure/main/MANUAL.md) The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. From b4fbdd90b2bbcc53cbce86e97bc3c56d097d9352 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 1 Dec 2025 09:15:51 +0100 Subject: [PATCH 011/110] Update _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 17e5d9b..2e20a07 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.md + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.md #BUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 8ce33ecfeee7e2b43b32b50028c77201ae4913d5 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 11:57:21 +0100 Subject: [PATCH 012/110] test --- book/_config.yml | 1 + book/_toc.yml | 2 +- requirements.txt | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/book/_config.yml b/book/_config.yml index 1cf67a0..409f9b0 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -52,6 +52,7 @@ sphinx: license: summaries: false individual: false + nb_execution_includepatterns: "**/MANUAL.ipynb" teachbooks: attribution_location: margin diff --git a/book/_toc.yml b/book/_toc.yml index 2e20a07..89a2d8c 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.md #BUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md diff --git a/requirements.txt b/requirements.txt index aa145b5..6e18875 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites +git+https://github.com/TeachBooks/TeachBooks-Favourites@test_metadata sphinx-metadata-figure == 1.0.3 From 91a861c307c4dae1cf07a0b6e7ef005d7082d3b7 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 11:59:17 +0100 Subject: [PATCH 013/110] fix --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6e18875..503a102 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,8 +3,6 @@ sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites@test_metadata -sphinx-metadata-figure == 1.0.3 - teachbooks-sphinx-grasple sphinx-apa-references From b4b78f6eea3bdf63f13b303661b375639840b130 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 11:59:27 +0100 Subject: [PATCH 014/110] Update requirements.txt --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index aa145b5..8cc3f83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,8 +3,6 @@ sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites -sphinx-metadata-figure == 1.0.3 - teachbooks-sphinx-grasple sphinx-apa-references From a2eb698b217b704782f82995b3ed236be7de119c Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 12:03:07 +0100 Subject: [PATCH 015/110] Update _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 89a2d8c..52639e4 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/test_document/MANUAL.ipynb #BUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 6b868f3d8e50acb1871764adc9dd96a242792d13 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 12:14:00 +0100 Subject: [PATCH 016/110] Update _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 52639e4..9908d6e 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/test_document/MANUAL.ipynb #BUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/test_document/MANUAL.ipynb #BUMPBUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 9bdbb866dcaea397865853cc2bf6f568ce74841e Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 12:19:19 +0100 Subject: [PATCH 017/110] Change execute_notebooks setting to 'auto' --- book/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_config.yml b/book/_config.yml index 409f9b0..2c6585c 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -2,7 +2,7 @@ title: TeachBooks Manual author: TeachBooks Development Team and TeachBooks users, built with TeachBooks, CC BY 4.0 execute: - execute_notebooks: 'off' + execute_notebooks: 'auto' only_build_toc_files: true From c83987b8bed05dcfce545766758d20dbc2888a9f Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 12:30:49 +0100 Subject: [PATCH 018/110] Update requirements.txt --- requirements.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/requirements.txt b/requirements.txt index 503a102..e305dad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,8 @@ git+https://github.com/TeachBooks/TeachBooks-Favourites@test_metadata teachbooks-sphinx-grasple sphinx-apa-references + +# For executing Jupyter Notebooks +myst_nb +numpy +matplotlib \ No newline at end of file From 0f48b937769bfe61eb62eb9f8bb252a4c057a447 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 12:37:47 +0100 Subject: [PATCH 019/110] prepare for updates --- book/_toc.yml | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/book/_toc.yml b/book/_toc.yml index 9908d6e..16a1454 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/test_document/MANUAL.ipynb #BUMPBUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMPBUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md diff --git a/requirements.txt b/requirements.txt index e305dad..21a0bb3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites@test_metadata +git+https://github.com/TeachBooks/TeachBooks-Favourites teachbooks-sphinx-grasple From 73a40953580e6b48fa5bd134622c28d47978cc83 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 3 Dec 2025 12:38:47 +0100 Subject: [PATCH 020/110] Update _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 16a1454..a5ff363 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMPBUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 45b20ffdc65155ac89e46a1b72417b57d35b71b9 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 5 Dec 2025 11:31:42 +0100 Subject: [PATCH 021/110] Update sphinx-iframes --- book/external/sphinx-iframes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/external/sphinx-iframes b/book/external/sphinx-iframes index b0fcde7..2bc21b6 160000 --- a/book/external/sphinx-iframes +++ b/book/external/sphinx-iframes @@ -1 +1 @@ -Subproject commit b0fcde7e8957babcbda79bf861f6c2e2885c0df4 +Subproject commit 2bc21b6174b8e7dbd15c862c219bd506e06f9d13 From a0636f0bc88e598f727bfe5acc8235a936b9e74b Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 8 Dec 2025 20:05:50 +0100 Subject: [PATCH 022/110] Update TeachBooks-Favourites dependency version Updated the TeachBooks-Favourites dependency to a new version. --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 21a0bb3..64fc228 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites +git+https://github.com/TeachBooks/TeachBooks-Favourites #BUMP8-12 teachbooks-sphinx-grasple @@ -10,4 +10,4 @@ sphinx-apa-references # For executing Jupyter Notebooks myst_nb numpy -matplotlib \ No newline at end of file +matplotlib From 2d7633c496d5b738614e0796003fcbc8118a7d5e Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 8 Dec 2025 20:08:47 +0100 Subject: [PATCH 023/110] Fix link for Sphinx Metadata Figure in favourites.md Updated the link for Sphinx Metadata Figure to point to the correct manual file format. --- book/features/favourites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/features/favourites.md b/book/features/favourites.md index e271ecf..0a797c7 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -42,7 +42,7 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Sphinx Launch Buttons](../external/Sphinx-launch-buttons/README.md) - [Sphinx External ToC (TeachBooks contribution to the original)](https://github.com/TeachBooks/sphinx-external-toc/blob/main/README.md) - [Sphinx GitHub Alerts](../_git/github.com_TeachBooks_Sphinx-GitHub-Alerts/main/README.md) -- [Sphinx Metadata Figure](../_git/github.com_TeachBooks_Sphinx-Metadata-Figure/main/MANUAL.md) +- [Sphinx Metadata Figure](../_git/github.com_TeachBooks_Sphinx-Metadata-Figure/main/MANUAL.ipynb) The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. From 19120550e9891b3bf6269cf52b489e1f1c0c83ae Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 8 Dec 2025 20:10:25 +0100 Subject: [PATCH 024/110] Add comment to external link in _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index a5ff363..89a2d8c 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 774882515eef5614d3988b26194da2efa3403d43 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 8 Dec 2025 20:17:03 +0100 Subject: [PATCH 025/110] Update external link comment in _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 89a2d8c..16a1454 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMPBUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 00e40c5be7b122fbd76dfb97afc5e0a8f9394c71 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 8 Dec 2025 20:32:06 +0100 Subject: [PATCH 026/110] Update external link comment in _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 16a1454..bcf0740 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMPBUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMPBUMPBUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 7330aae9fddb9c8eed7a89772d10755e119541f9 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst <49307154+douden@users.noreply.github.com> Date: Tue, 9 Dec 2025 10:37:13 +0100 Subject: [PATCH 027/110] Update external link in _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index bcf0740..16a1454 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMPBUMPBUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMPBUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From ce760deb7bf7442da7988937ce766f5e60c63b9a Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst <49307154+douden@users.noreply.github.com> Date: Tue, 9 Dec 2025 10:41:55 +0100 Subject: [PATCH 028/110] Remove comment from external link in _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 16a1454..a5ff363 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb #BUMPBUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 9ac3763de02dc2c6f7b9d186c9905878d7f16c5e Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst <49307154+douden@users.noreply.github.com> Date: Tue, 9 Dec 2025 10:51:46 +0100 Subject: [PATCH 029/110] Add comment to external link in _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index a5ff363..4fc09d5 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,7 +88,7 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb # BUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From ff67aa5572d17ac9fef02d9cd1f3b0a4ca42571e Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 15 Dec 2025 18:08:27 +0100 Subject: [PATCH 030/110] Add Sphinx last updated by git to favourites list --- book/features/favourites.md | 1 + 1 file changed, 1 insertion(+) diff --git a/book/features/favourites.md b/book/features/favourites.md index 0a797c7..c31c211 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -43,6 +43,7 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Sphinx External ToC (TeachBooks contribution to the original)](https://github.com/TeachBooks/sphinx-external-toc/blob/main/README.md) - [Sphinx GitHub Alerts](../_git/github.com_TeachBooks_Sphinx-GitHub-Alerts/main/README.md) - [Sphinx Metadata Figure](../_git/github.com_TeachBooks_Sphinx-Metadata-Figure/main/MANUAL.ipynb) +- [Sphinx last updated by git](https://github.com/mgeier/sphinx-last-updated-by-git) The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. From eeb71c404df62b26b6802fa21b4980ddd695401b Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst <49307154+douden@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:10:24 +0100 Subject: [PATCH 031/110] Update favourites.md --- book/features/favourites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/features/favourites.md b/book/features/favourites.md index c31c211..d06158c 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -43,7 +43,7 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Sphinx External ToC (TeachBooks contribution to the original)](https://github.com/TeachBooks/sphinx-external-toc/blob/main/README.md) - [Sphinx GitHub Alerts](../_git/github.com_TeachBooks_Sphinx-GitHub-Alerts/main/README.md) - [Sphinx Metadata Figure](../_git/github.com_TeachBooks_Sphinx-Metadata-Figure/main/MANUAL.ipynb) -- [Sphinx last updated by git](https://github.com/mgeier/sphinx-last-updated-by-git) +- [Sphinx last updated by git](https://github.com/TeachBooks/sphinx-last-updated-by-git) The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. From 025b2ff5c72611faf269ac6b47d3d571610a1238 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 19 Dec 2025 13:32:17 +0100 Subject: [PATCH 032/110] Update plotyl instructions --- book/features/plotly.ipynb | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/book/features/plotly.ipynb b/book/features/plotly.ipynb index 6852a21..08005fc 100644 --- a/book/features/plotly.ipynb +++ b/book/features/plotly.ipynb @@ -437,6 +437,58 @@ "\n", "fig.show()" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you want to create the plot during the build of the book, don't use `fig.show()` but use the code below:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython import get_ipython\n", + "from IPython.display import HTML\n", + "\n", + "def show_plotly(fig):\n", + " ip = get_ipython()\n", + " if ip is None:\n", + " return fig\n", + "\n", + " # Sphinx / Jupyter Book execution\n", + " if \"sphinx\" in ip.config:\n", + " return HTML(fig.to_html(include_plotlyjs=\"cdn\"))\n", + "\n", + " # Local execution in Jupyter Notebook / JupyterLab / VS Code\n", + " fig.show()\n", + "\n", + "....\n", + "\n", + "show_plotly(fig)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Make sure you have in your `_config.yml`:\n", + "\n", + "```yaml\n", + "execute:\n", + " execute_notebooks: \"auto\"\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Eventually in combination with [](../_git/github.com_TeachBooks_Sphinx-NB-Execution-Patterns/Manual/README.html)" + ] } ], "metadata": { From 88c67fe4cde1ea471af99ca7fd562ad6db235b3a Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 19 Dec 2025 13:48:14 +0100 Subject: [PATCH 033/110] fix url --- book/features/plotly.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/features/plotly.ipynb b/book/features/plotly.ipynb index 08005fc..0f0a451 100644 --- a/book/features/plotly.ipynb +++ b/book/features/plotly.ipynb @@ -487,7 +487,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Eventually in combination with [](../_git/github.com_TeachBooks_Sphinx-NB-Execution-Patterns/Manual/README.html)" + "Eventually in combination with [](../_git/github.com_TeachBooks_Sphinx-NB-Execution-Patterns/Manual/README.md)" ] } ], From b3469006d43d20bd58842e4302c44068aabc7e22 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 19 Dec 2025 13:55:25 +0100 Subject: [PATCH 034/110] reorder --- book/features/plotly.ipynb | 102 +++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 54 deletions(-) diff --git a/book/features/plotly.ipynb b/book/features/plotly.ipynb index 0f0a451..8f81598 100644 --- a/book/features/plotly.ipynb +++ b/book/features/plotly.ipynb @@ -16,14 +16,60 @@ "\n", "# Interactive plots: plotly\n", "\n", - "The use of the [plotly](https://plotly.com/python/getting-started/) package is an example which allows you to create HTML/Javascript widgets from python code without any knowledge on HTML/Javascript." + "The use of the [plotly](https://plotly.com/python/getting-started/) package is an example which allows you to create HTML/Javascript widgets from python code without any knowledge on HTML/Javascript. The example below is taken from the FEM-module by Frans van der Meer." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you want to create the plot during the build of the book, don't use `fig.show()` but use the code below:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython import get_ipython\n", + "from IPython.display import HTML\n", + "\n", + "def show_plotly(fig):\n", + " ip = get_ipython()\n", + " if ip is None:\n", + " return fig\n", + "\n", + " # Sphinx / Jupyter Book execution\n", + " if \"sphinx\" in ip.config:\n", + " return HTML(fig.to_html(include_plotlyjs=\"cdn\"))\n", + "\n", + " # Local execution in Jupyter Notebook / JupyterLab / VS Code\n", + " fig.show()\n", + "\n", + "....\n", + "\n", + "show_plotly(fig)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Make sure you have in your `_config.yml`:\n", + "\n", + "```yaml\n", + "execute:\n", + " execute_notebooks: \"auto\"\n", + "```\n", + "\n", + "Eventually in combination with [](../_git/github.com_TeachBooks_Sphinx-NB-Execution-Patterns/Manual/README.md)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The example below is taken from the FEM-module by Frans van der Meer.\n", "When using Plotly graphs, make sure the notebook is executed in Jupyter Lab / Jupyter Notebook for the figures to be shown in the book. Running the code in VS code might break the result in the book, although the output is visible in VS code. Alternatively, add the following lines of code to your notebook to have a valid output in the book as well:\n", "\n", "```python\n", @@ -437,58 +483,6 @@ "\n", "fig.show()" ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you want to create the plot during the build of the book, don't use `fig.show()` but use the code below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from IPython import get_ipython\n", - "from IPython.display import HTML\n", - "\n", - "def show_plotly(fig):\n", - " ip = get_ipython()\n", - " if ip is None:\n", - " return fig\n", - "\n", - " # Sphinx / Jupyter Book execution\n", - " if \"sphinx\" in ip.config:\n", - " return HTML(fig.to_html(include_plotlyjs=\"cdn\"))\n", - "\n", - " # Local execution in Jupyter Notebook / JupyterLab / VS Code\n", - " fig.show()\n", - "\n", - "....\n", - "\n", - "show_plotly(fig)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Make sure you have in your `_config.yml`:\n", - "\n", - "```yaml\n", - "execute:\n", - " execute_notebooks: \"auto\"\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Eventually in combination with [](../_git/github.com_TeachBooks_Sphinx-NB-Execution-Patterns/Manual/README.md)" - ] } ], "metadata": { From 0bac6738eac63614feecb1a686ce002613ce7478 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst <49307154+douden@users.noreply.github.com> Date: Fri, 19 Dec 2025 16:27:34 +0100 Subject: [PATCH 035/110] Add TeachBooks logo reference to bibliography --- book/references.bib | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/book/references.bib b/book/references.bib index 0358ae3..79e2b1e 100644 --- a/book/references.bib +++ b/book/references.bib @@ -207,3 +207,13 @@ url = {https://arxiv.org/abs/1301.3781}, } +@misc{TeachBooksLogo, + author = {Veronica Comin}, + title = {The logo of TeachBooks.}, + year = {2024}, + date = {2024-11-13}, + note = {License: CC-BY}, + url = {https://github.com/TeachBooks/logos_and_visualisations}, + howpublished = {\url{https://github.com/TeachBooks/logos_and_visualisations}}, + copyright = {© TeachBooks 2024} +} From 64c1647ca5e617a4e630763bcb0faedca2885eff Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst <49307154+douden@users.noreply.github.com> Date: Tue, 23 Dec 2025 13:23:12 +0100 Subject: [PATCH 036/110] Update references.bib --- book/references.bib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/references.bib b/book/references.bib index 79e2b1e..6b03119 100644 --- a/book/references.bib +++ b/book/references.bib @@ -212,7 +212,7 @@ title = {The logo of TeachBooks.}, year = {2024}, date = {2024-11-13}, - note = {License: CC-BY}, + note = {License: CC BY}, url = {https://github.com/TeachBooks/logos_and_visualisations}, howpublished = {\url{https://github.com/TeachBooks/logos_and_visualisations}}, copyright = {© TeachBooks 2024} From b56ad3336be9d34191871c3fcb6466843100ba58 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Tue, 23 Dec 2025 15:51:43 +0100 Subject: [PATCH 037/110] Update requirements and fix BibTeX formatting Pinned TeachBooks-Favourites to version v1.7.3 in requirements.txt for reproducibility. Added a missing comma and newline in references.bib to correct BibTeX formatting. --- book/references.bib | 3 ++- requirements.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/book/references.bib b/book/references.bib index 6b03119..884c860 100644 --- a/book/references.bib +++ b/book/references.bib @@ -215,5 +215,6 @@ note = {License: CC BY}, url = {https://github.com/TeachBooks/logos_and_visualisations}, howpublished = {\url{https://github.com/TeachBooks/logos_and_visualisations}}, - copyright = {© TeachBooks 2024} + copyright = {© TeachBooks 2024}, } + diff --git a/requirements.txt b/requirements.txt index 64fc228..c61c8d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites #BUMP8-12 +git+https://github.com/TeachBooks/TeachBooks-Favourites@v1.7.3 teachbooks-sphinx-grasple @@ -11,3 +11,4 @@ sphinx-apa-references myst_nb numpy matplotlib + From 233df5631e87c35eafe8c16b60d63bad5e4b85ce Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Tue, 23 Dec 2025 16:01:43 +0100 Subject: [PATCH 038/110] BUMP without fixing versoin --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index c61c8d2..3b6ef5b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites@v1.7.3 +git+https://github.com/TeachBooks/TeachBooks-Favourites teachbooks-sphinx-grasple @@ -11,4 +11,3 @@ sphinx-apa-references myst_nb numpy matplotlib - From c7486c0b423959fbf7501f65f651183c78bf31f6 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 2 Jan 2026 17:09:33 +0100 Subject: [PATCH 039/110] Add sphinx_gated_directives extension and code-align CSS Introduces the custom Sphinx extension 'sphinx_gated_directives' for start/end directive gating and validation, registering it in the Sphinx local extensions. Also adds a CSS file to enforce left alignment for code cells. Updates _config.yml to configure the new extension and set the documentation language to English. --- book/_config.yml | 5 +- book/_ext/sphinx_gated_directives/__init__.py | 520 ++++++++++++++++++ book/_static/code-align.css | 4 + 3 files changed, 527 insertions(+), 2 deletions(-) create mode 100644 book/_ext/sphinx_gated_directives/__init__.py create mode 100644 book/_static/code-align.css diff --git a/book/_config.yml b/book/_config.yml index 2c6585c..580aa76 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -11,15 +11,16 @@ html: baseurl : "https://teachbooks.io/manual/" sphinx: + local_extensions: + sphinx_gated_directives: _ext extra_extensions: - sphinx_inline_tabs - sphinx.ext.imgconverter - teachbooks_favourites - teachbooks_sphinx_grasple - sphinx_apa_references - - sphinx_github_alerts - - sphinx_metadata_figure config: + language: en html_js_files: - https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js thebe_config: diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py new file mode 100644 index 0000000..e3cb8b0 --- /dev/null +++ b/book/_ext/sphinx_gated_directives/__init__.py @@ -0,0 +1,520 @@ +# startify_directives_all.py +""" +Create a '-start' companion for every registered directive (class-based). + +Rules: + - Skip originals whose name already ends with '-start' or '-end'. + - Skip if '-start' already exists. + - Class-based originals -> register a subclass calling original run(). + +Usage: + extensions = ["startify_directives_all"] +""" + +from __future__ import annotations +from docutils.nodes import Element +from typing import Iterator +import re +import copy +import importlib +import inspect +from typing import Callable, Dict, Iterable, List, Optional +from sphinx.transforms import SphinxTransform +from sphinx.application import Sphinx +from sphinx.environment import BuildEnvironment + +from sphinx.util import logging +logger = logging.getLogger(__name__) + +from docutils import nodes +from docutils.parsers.rst import Directive +from docutils.parsers.rst import directives as du_directives + +SUFFIX_START = "-start" +SUFFIX_END = "-end" + + +# --------------------------- +# Helpers: identification +# --------------------------- + +def _is_class_directive(obj) -> bool: + return inspect.isclass(obj) and issubclass(obj, Directive) + + +# --------------------------- +# Helpers: registry access +# --------------------------- + +def _get_unified_registry(app=None) -> Dict[str, object]: + """ + Build a unified {name -> implementation} mapping of directives. + + Sources: + 1) docutils.parsers.rst.directives._directives (loaded/added so far) + 2) docutils.parsers.rst.directives._directive_registry (lazy map of + name -> (module, class) for builtins); import any missing ones. + 3) Sphinx app.registry (if provided) for extension-registered directives + """ + # 1) Already-loaded directives (includes Sphinx & extensions registered via add_directive) + unified: Dict[str, object] = dict(getattr(du_directives, "_directives", {})) + + # 2) Ensure Docutils built-ins are present by importing from _directive_registry + reg = getattr(du_directives, "_directive_registry", {}) + for name, (modname, clsname) in reg.items(): + if name in unified: + continue + try: + mod = importlib.import_module(f"docutils.parsers.rst.directives.{modname}") + obj = getattr(mod, clsname, None) + if obj is not None: + unified[name] = obj + except Exception: + # Be defensive: if an import fails, just skip that name + continue + + # 3) Add Sphinx's registry if app is provided + if app is not None: + # Sphinx stores directives in app.registry + # Try different ways to access the directives mapping + if hasattr(app.registry, 'directives'): + # Newer Sphinx versions may have a directives attribute + try: + unified.update(app.registry.directives) + except (AttributeError, TypeError): + pass + + # Also check for domains which contain directives (e.g., prf:theorem from sphinx-proof) + if hasattr(app.registry, 'domains'): + for domain_name, domain_cls in app.registry.domains.items(): + try: + # Instantiate domain or use class attributes + if hasattr(domain_cls, 'directives'): + domain_directives = domain_cls.directives + for dir_name, dir_impl in domain_directives.items(): + # Fully qualified name: domain:directive + full_name = f"{domain_name}:{dir_name}" + if full_name not in unified: + unified[full_name] = dir_impl + except Exception: + continue + + return unified + + +# --------------------------- +# Helpers: class generation +# --------------------------- + +def _copy_option_spec(option_spec): + return copy.copy(option_spec) if isinstance(option_spec, dict) else option_spec + +def make_startified_class( + orig_name: str, + base_cls: type[Directive], +) -> type[Directive]: + """ + Subclass `base_cls` to call original run(). + """ + attrs = {} + for attr in ( + "required_arguments", + "optional_arguments", + "final_argument_whitespace", + "has_content", + "option_spec", + ): + if hasattr(base_cls, attr): + val = getattr(base_cls, attr) + if attr == "option_spec": + attrs[attr] = _copy_option_spec(val) or {} + else: + attrs[attr] = val + + def run(self: Directive): + current_name = self.name + self.name = orig_name # temporarily set to original for base run() + children = base_cls.run(self) + self.name = current_name # restore + if not isinstance(children, list): + if isinstance(children, Iterable): + children = list(children) + else: + children = [children] + # create a start_node and add all result nodes as its children + start_node_instance = start_node() + start_node_instance += children + result = [start_node_instance] + + # Get environment from state.document.settings + env = getattr(self.state.document.settings, "env", None) + if env is not None: + # 1) Check whether main registry is already created, if not, create it + if not hasattr(env, "sphinx_gated_directives_registry"): + env.sphinx_gated_directives_registry = {} + # 2) Check whether a sub-registry for current directive type is already created, if not, create it + if orig_name not in env.sphinx_gated_directives_registry: + env.sphinx_gated_directives_registry[orig_name] = {} + # 3) Register current usage in the registry for this doc and this type + gated_registry = env.sphinx_gated_directives_registry[orig_name] + docname = env.docname + if docname not in gated_registry: + gated_registry[docname] = { + "start": [], + "end": [], + "sequence": [], + "msg": [], + } + gated_registry[docname]["start"].append(self.lineno) + gated_registry[docname]["sequence"].append("S") + gated_registry[docname]["msg"].append( + f"{self.name} at line: {self.lineno}" + ) + # 4) Check whether super registry has been created, if not, create it + if not hasattr(env, "sphinx_gated_directives_super_registry"): + env.sphinx_gated_directives_super_registry = {} + # 5) Register current usage in the super registry + super_registry = env.sphinx_gated_directives_super_registry + if docname not in super_registry: + super_registry[docname] = { + "start": [], + "end": [], + "sequence": [], + "msg": [], + "type": [], + } + super_registry[docname]["start"].append(self.lineno) + super_registry[docname]["sequence"].append("S") + super_registry[docname]["msg"].append( + f"{self.name} at line: {self.lineno}" + ) + super_registry[docname]["type"].append(orig_name) + + return result + + attrs["run"] = run + new_cls_name = f"{base_cls.__name__}_Start_For_{orig_name.replace(':', '_')}" + return type(new_cls_name, (base_cls,), attrs) + +def make_endified_class( + orig_name: str, + base_cls: type[Directive], +) -> type[Directive]: + """ + Just create a subclass to obtain an end node. + """ + attrs = {} + for attr in ( + "required_arguments", + "optional_arguments", + "final_argument_whitespace", + "has_content", + "option_spec", + ): + if hasattr(base_cls, attr): + val = getattr(base_cls, attr) + if attr == "option_spec": + attrs[attr] = _copy_option_spec(val) or {} + else: + attrs[attr] = val + + def run(self: Directive): + + # Get environment from state.document.settings + env = getattr(self.state.document.settings, "env", None) + if env is not None: + # 1) Check whether main registry is already created, if not, create it + if not hasattr(env, "sphinx_gated_directives_registry"): + env.sphinx_gated_directives_registry = {} + # 2) Check whether a sub-registry for current directive type is already created, if not, create it + if orig_name not in env.sphinx_gated_directives_registry: + env.sphinx_gated_directives_registry[orig_name] = {} + # 3) Register current usage in the registry for this doc and this type + gated_registry = env.sphinx_gated_directives_registry[orig_name] + docname = env.docname + if docname not in gated_registry: + gated_registry[docname] = { + "start": [], + "end": [], + "sequence": [], + "msg": [], + } + gated_registry[docname]["end"].append(self.lineno) + gated_registry[docname]["sequence"].append("E") + gated_registry[docname]["msg"].append( + f"{self.name} at line: {self.lineno}" + ) + # 4) Check whether super registry has been created, if not, create it + if not hasattr(env, "sphinx_gated_directives_super_registry"): + env.sphinx_gated_directives_super_registry = {} + # 5) Register current usage in the super registry + super_registry = env.sphinx_gated_directives_super_registry + if docname not in super_registry: + super_registry[docname] = { + "start": [], + "end": [], + "sequence": [], + "msg": [], + "type": [], + } + super_registry[docname]["end"].append(self.lineno) + super_registry[docname]["sequence"].append("E") + super_registry[docname]["msg"].append( + f"{self.name} at line: {self.lineno}" + ) + super_registry[docname]["type"].append(orig_name) + + # return [] + # next line should be good enough, but raises an error as not all has been implemented + # maybe we need end nodes per directive type? + return [end_node()] + + attrs["run"] = run + new_cls_name = f"{base_cls.__name__}_End_For_{orig_name.replace(':', '_')}" + return type(new_cls_name, (base_cls,), attrs) + +# --------------------------- +# Core logic +# --------------------------- + +def _should_skip_name(orig_name: str) -> bool: + return orig_name.endswith(SUFFIX_START) or orig_name.endswith(SUFFIX_END) + +def _register_startified_directives(app, env, docnames): + unified = _get_unified_registry(app) + snapshot_names = set(unified.keys()) + added = 0 + + for orig_name, obj in sorted(unified.items()): + if _should_skip_name(orig_name): + continue + + new_name = f"{orig_name}{SUFFIX_START}" + if new_name in snapshot_names: + continue + + try: + if _is_class_directive(obj): + start_cls = make_startified_class(orig_name, obj) + app.add_directive(new_name, start_cls) + end_cls = make_endified_class(orig_name, Directive) # because it does generate anything, most simple directive + app.add_directive(f"{orig_name}{SUFFIX_END}", end_cls) + added += 1 + else: + logger.debug(f"[startify] '{orig_name}' is not a class directive; skipping.") + except Exception as e: + logger.warning(f"[startify] failed to register '{new_name}': {e}") + +def setup(app): + + # register function to perge registries at start of build per document + app.connect("env-purge-doc", purge_registries) + + # At the latest possible moment, register startified directives (also creates the endified ones) + app.connect("env-before-read-docs", _register_startified_directives,priority=10000000000000000000000000000) + + # Register nodes, used as placeholder for end directives + # will be resolved in the transforms to something meaningful + # during merging of start-end blocks + app.add_node(start_node) + app.add_node(end_node) + + # Register a transform to check validity of start-end pairs + app.add_transform(CheckGatedDirectivesTransform) + + # Register a transform to merge start-end pairs into gated content + app.add_transform(MergeGatedDirectivesTransform) + + return { + "version": "1.0", + "parallel_read_safe": True, + } + +# Node classes for start and end directives + +class start_node(nodes.Admonition, nodes.Element): + pass + +class end_node(nodes.Admonition, nodes.Element): + pass + +# purge_registry +def purge_registries(app: Sphinx, env: BuildEnvironment, docname: str) -> None: + + if hasattr(env, "sphinx_gated_directives_registry") or hasattr(env, "sphinx_gated_directives_super_registry"): + # only perge if needed + if hasattr(env, "sphinx_gated_directives_registry"): + registry = env.sphinx_gated_directives_registry + for directive_name in registry: + if docname in registry[directive_name]: + del registry[directive_name][docname] + if hasattr(env, "sphinx_gated_directives_super_registry"): + super_registry = env.sphinx_gated_directives_super_registry + if docname in super_registry: + del super_registry[docname] + +# Transform to check validity of start-end pairs +class CheckGatedDirectivesTransform(SphinxTransform): + default_priority = 1 + + def apply(self, **kwargs): + env = self.env + if not hasattr(env, "sphinx_gated_directives_registry"): + return + if not hasattr(env, "sphinx_gated_directives_super_registry"): + return + + # First check the super registry for a correct structure + # demands: + # 1) equal number of start and end directives + # 2) no nesting of start-end pairs (so SSEE is not allowed, only SESE) + super_registry = env.sphinx_gated_directives_super_registry + error = False + docname = self.env.docname + if docname in super_registry: + start = super_registry[docname]["start"] + end = super_registry[docname]["end"] + structure = "\n ".join(super_registry[docname]["msg"]) + sequence = "".join(super_registry[docname]["sequence"]) + groups = re.findall("(SE)", sequence) + if len(start) > len(end): + msg = f"The document {docname} contains more start directives than end directives:\n {structure}\nPlease ensure each start directive has a corresponding end directive." + logger.error(msg) + error = True + elif len(end) > len(start): + msg = f"The document {docname} contains more end directives than start directives:\n {structure}\nPlease ensure each end directive has a corresponding start directive." + logger.error(msg) + error = True + # at this point, len(start) == len(end) + elif len(groups) != len(start) or len(groups) != len(end): + msg = f"The document {docname} contains nested start and end directives:\n {structure}\nThis is not allowed. Please correct the nesting." + logger.error(msg) + error = True + else: + # At this point, every start is followed by an end. + # Now check that types match in order. + types = super_registry[docname]["type"] + start_type = types[::2] + end_type = types[1::2] + for i in range(len(start_type)): + if start_type[i] != end_type[i]: + msg = f"The document {docname} contains mismatched start and end directives at lines {start[i]} and {end[i]}:\n {structure}\nPlease ensure that start and end directives match in type." + logger.error(msg) + error = True + + if error: + raise Exception(f"[sphinx-gated-directives] An error has occurred when parsing gated directives in {docname}.\nPlease check warning messages above.") + + # no check per directive type is needed if no error in super registry is raised, + # as the super registry already ensures correctness for each type. + # if nesting is allowed in the future, this part needs to be re-implemented. + + +class MergeGatedDirectivesTransform(SphinxTransform): + default_priority = 10 + + def apply(self, **kwargs): + env = self.env + # Something to do here + # idea: + # 1) Find all start_nodes + # 2) for each start_node, find the corresponding end_node (i.e. next end_node) + # 3) collect all nodes in between + # 4) Take the first node after start_node, and add all other collected nodes as its children + if not hasattr(env, "sphinx_gated_directives_super_registry"): + return + super_registry = env.sphinx_gated_directives_super_registry + docname = self.env.docname + if docname not in super_registry: + return + + # Each start-end pair is valid (checked before), so we can proceed to merge + # find all start nodes, as an iterator + # for each start node, find the next end node within the parent of start node + start_nodes = findall(self.document, start_node) + for start_n in start_nodes: + parent = start_n.parent + # find the next end_node after start_n in parent + found_start = False + end_n = None + for child in parent.children: + if child is start_n: + found_start = True + elif found_start and isinstance(child, end_node): + end_n = child + break + if end_n is None: + continue # should not happen due to prior checks + + # collect all nodes between start_n and end_n + start_index = parent.children.index(start_n) + end_index = parent.children.index(end_n) + between_nodes = parent.children[start_index + 1:end_index] + + # print the nodes for debugging + logger.info(f"{start_n.pformat()}",color="green") + if between_nodes: + for bn in between_nodes: + logger.info(f"{bn.pformat()}",color="yellow") + logger.info(f"{end_n.pformat()}",color="red") + + # We have to merge, but how is the question. + # we handle based on "experience" and "observation" of what kind of nodes are generated + # step 1: create a new container node to hold the merged content + # content of start_node + new_nodes = start_n.children + # add content in between, depending on content in start_n + if between_nodes: + has_section = False + has_caption = False + si = -1 + content = new_nodes[-1] # we assume that the last child of start_n holds the main content + for sn in content.children: + si += 1 + if isinstance(sn, nodes.section): + has_section = True # So probably a topic or similar (from sphinx-proof) + section_index = si + section_node = sn + break + elif isinstance(sn, nodes.caption): + has_caption = True # So probably a figure or similar + caption_index = si + caption_node = sn + break + if has_section: + # if there are sections, we add all between nodes to this section + content[section_index] += between_nodes + elif has_caption: + # if there is a caption, we add all between nodes before the caption + n = len(content.children) + pos = n - 1 + for i, bn in enumerate(between_nodes): + content.insert(pos + i, bn) # insert sets parent/doc links + else: + logger.info(f"Found no caption and no section node in start_node content.",color="blue") + # otherwise, we add all between nodes to the main content directly\ + for bn in between_nodes: + content += bn # add sets parent/doc links + logger.info(f"New nodes after merging:",color="blue") + for nn in new_nodes: + logger.info(f"{nn.pformat()}",color="blue") + + # finally, replace start_n with new_nodes, and remove end_n and between_nodes + start_pos = parent.children.index(start_n) + # remove end_n + parent.remove(end_n) + # remove start_n + parent.remove(start_n) + # remove between_nodes + for bn in between_nodes: + parent.remove(bn) + # insert new_nodes at start_pos + for i, nn in enumerate(new_nodes): + parent.insert(start_pos + i, nn) # insert new structure + + +def findall(node: Element, *args, **kwargs) -> Iterator[Element]: + # findall replaces traverse in docutils v0.18 + # note a difference is that findall is an iterator + impl = getattr(node, "findall", node.traverse) + return iter(impl(*args, **kwargs)) \ No newline at end of file diff --git a/book/_static/code-align.css b/book/_static/code-align.css new file mode 100644 index 0000000..10aa7b4 --- /dev/null +++ b/book/_static/code-align.css @@ -0,0 +1,4 @@ +/* this to enforce left alignment for docutils content (i.e. code cells) */ +div.cell.docutils.container { + text-align: left !important; +} \ No newline at end of file From fddd493e39791f5b2441212a1941ea6065a82563 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 2 Jan 2026 17:18:18 +0100 Subject: [PATCH 040/110] Comment out legacy registry logic in sphinx_gated_directives Commented out the code related to the 'sphinx_gated_directives_registry' in favor of using only the 'sphinx_gated_directives_super_registry'. Updated purge and transform logic accordingly. Added clarifying comments to code-align.css regarding left alignment enforcement. --- book/_ext/sphinx_gated_directives/__init__.py | 105 +++++++++--------- book/_static/code-align.css | 2 + 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py index e3cb8b0..9bb60d8 100644 --- a/book/_ext/sphinx_gated_directives/__init__.py +++ b/book/_ext/sphinx_gated_directives/__init__.py @@ -149,27 +149,27 @@ def make_startified_class( # Get environment from state.document.settings env = getattr(self.state.document.settings, "env", None) if env is not None: - # 1) Check whether main registry is already created, if not, create it - if not hasattr(env, "sphinx_gated_directives_registry"): - env.sphinx_gated_directives_registry = {} - # 2) Check whether a sub-registry for current directive type is already created, if not, create it - if orig_name not in env.sphinx_gated_directives_registry: - env.sphinx_gated_directives_registry[orig_name] = {} - # 3) Register current usage in the registry for this doc and this type - gated_registry = env.sphinx_gated_directives_registry[orig_name] docname = env.docname - if docname not in gated_registry: - gated_registry[docname] = { - "start": [], - "end": [], - "sequence": [], - "msg": [], - } - gated_registry[docname]["start"].append(self.lineno) - gated_registry[docname]["sequence"].append("S") - gated_registry[docname]["msg"].append( - f"{self.name} at line: {self.lineno}" - ) + # # 1) Check whether main registry is already created, if not, create it + # if not hasattr(env, "sphinx_gated_directives_registry"): + # env.sphinx_gated_directives_registry = {} + # # 2) Check whether a sub-registry for current directive type is already created, if not, create it + # if orig_name not in env.sphinx_gated_directives_registry: + # env.sphinx_gated_directives_registry[orig_name] = {} + # # 3) Register current usage in the registry for this doc and this type + # gated_registry = env.sphinx_gated_directives_registry[orig_name] + # if docname not in gated_registry: + # gated_registry[docname] = { + # "start": [], + # "end": [], + # "sequence": [], + # "msg": [], + # } + # gated_registry[docname]["start"].append(self.lineno) + # gated_registry[docname]["sequence"].append("S") + # gated_registry[docname]["msg"].append( + # f"{self.name} at line: {self.lineno}" + # ) # 4) Check whether super registry has been created, if not, create it if not hasattr(env, "sphinx_gated_directives_super_registry"): env.sphinx_gated_directives_super_registry = {} @@ -223,27 +223,27 @@ def make_endified_class( # Get environment from state.document.settings env = getattr(self.state.document.settings, "env", None) if env is not None: - # 1) Check whether main registry is already created, if not, create it - if not hasattr(env, "sphinx_gated_directives_registry"): - env.sphinx_gated_directives_registry = {} - # 2) Check whether a sub-registry for current directive type is already created, if not, create it - if orig_name not in env.sphinx_gated_directives_registry: - env.sphinx_gated_directives_registry[orig_name] = {} - # 3) Register current usage in the registry for this doc and this type - gated_registry = env.sphinx_gated_directives_registry[orig_name] docname = env.docname - if docname not in gated_registry: - gated_registry[docname] = { - "start": [], - "end": [], - "sequence": [], - "msg": [], - } - gated_registry[docname]["end"].append(self.lineno) - gated_registry[docname]["sequence"].append("E") - gated_registry[docname]["msg"].append( - f"{self.name} at line: {self.lineno}" - ) + # # 1) Check whether main registry is already created, if not, create it + # if not hasattr(env, "sphinx_gated_directives_registry"): + # env.sphinx_gated_directives_registry = {} + # # 2) Check whether a sub-registry for current directive type is already created, if not, create it + # if orig_name not in env.sphinx_gated_directives_registry: + # env.sphinx_gated_directives_registry[orig_name] = {} + # # 3) Register current usage in the registry for this doc and this type + # gated_registry = env.sphinx_gated_directives_registry[orig_name] + # if docname not in gated_registry: + # gated_registry[docname] = { + # "start": [], + # "end": [], + # "sequence": [], + # "msg": [], + # } + # gated_registry[docname]["end"].append(self.lineno) + # gated_registry[docname]["sequence"].append("E") + # gated_registry[docname]["msg"].append( + # f"{self.name} at line: {self.lineno}" + # ) # 4) Check whether super registry has been created, if not, create it if not hasattr(env, "sphinx_gated_directives_super_registry"): env.sphinx_gated_directives_super_registry = {} @@ -341,17 +341,16 @@ class end_node(nodes.Admonition, nodes.Element): # purge_registry def purge_registries(app: Sphinx, env: BuildEnvironment, docname: str) -> None: - if hasattr(env, "sphinx_gated_directives_registry") or hasattr(env, "sphinx_gated_directives_super_registry"): - # only perge if needed - if hasattr(env, "sphinx_gated_directives_registry"): - registry = env.sphinx_gated_directives_registry - for directive_name in registry: - if docname in registry[directive_name]: - del registry[directive_name][docname] - if hasattr(env, "sphinx_gated_directives_super_registry"): - super_registry = env.sphinx_gated_directives_super_registry - if docname in super_registry: - del super_registry[docname] + # only perge if needed + # if hasattr(env, "sphinx_gated_directives_registry"): + # registry = env.sphinx_gated_directives_registry + # for directive_name in registry: + # if docname in registry[directive_name]: + # del registry[directive_name][docname] + if hasattr(env, "sphinx_gated_directives_super_registry"): + super_registry = env.sphinx_gated_directives_super_registry + if docname in super_registry: + del super_registry[docname] # Transform to check validity of start-end pairs class CheckGatedDirectivesTransform(SphinxTransform): @@ -359,8 +358,8 @@ class CheckGatedDirectivesTransform(SphinxTransform): def apply(self, **kwargs): env = self.env - if not hasattr(env, "sphinx_gated_directives_registry"): - return + # if not hasattr(env, "sphinx_gated_directives_registry"): + # return if not hasattr(env, "sphinx_gated_directives_super_registry"): return diff --git a/book/_static/code-align.css b/book/_static/code-align.css index 10aa7b4..b9b324a 100644 --- a/book/_static/code-align.css +++ b/book/_static/code-align.css @@ -1,4 +1,6 @@ /* this to enforce left alignment for docutils content (i.e. code cells) */ +/* assumption is that all code is left aligned, so we enforce that */ +/* if not desired, raise an issue with a use case */ div.cell.docutils.container { text-align: left !important; } \ No newline at end of file From bd47d63475b6837e196cdc7fdd491674ea1e3b35 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 2 Jan 2026 17:40:03 +0100 Subject: [PATCH 041/110] Remove debug logging and update intro content Debug logging statements were removed from MergeGatedDirectivesTransform in sphinx_gated_directives. The intro.md file was updated to include new theorem and figure directive examples, code cells, and additional documentation content. --- book/_ext/sphinx_gated_directives/__init__.py | 13 +--- book/intro.md | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py index 9bb60d8..7afe003 100644 --- a/book/_ext/sphinx_gated_directives/__init__.py +++ b/book/_ext/sphinx_gated_directives/__init__.py @@ -450,13 +450,6 @@ class MergeGatedDirectivesTransform(SphinxTransform): end_index = parent.children.index(end_n) between_nodes = parent.children[start_index + 1:end_index] - # print the nodes for debugging - logger.info(f"{start_n.pformat()}",color="green") - if between_nodes: - for bn in between_nodes: - logger.info(f"{bn.pformat()}",color="yellow") - logger.info(f"{end_n.pformat()}",color="red") - # We have to merge, but how is the question. # we handle based on "experience" and "observation" of what kind of nodes are generated # step 1: create a new container node to hold the merged content @@ -490,14 +483,10 @@ class MergeGatedDirectivesTransform(SphinxTransform): for i, bn in enumerate(between_nodes): content.insert(pos + i, bn) # insert sets parent/doc links else: - logger.info(f"Found no caption and no section node in start_node content.",color="blue") # otherwise, we add all between nodes to the main content directly\ for bn in between_nodes: content += bn # add sets parent/doc links - logger.info(f"New nodes after merging:",color="blue") - for nn in new_nodes: - logger.info(f"{nn.pformat()}",color="blue") - + # finally, replace start_n with new_nodes, and remove end_n and between_nodes start_pos = parent.children.index(start_n) # remove end_n diff --git a/book/intro.md b/book/intro.md index 165c9f7..5df72ca 100644 --- a/book/intro.md +++ b/book/intro.md @@ -1,5 +1,67 @@ +--- +file_format: mystnb +kernelspec: + name: python3 +--- + # TeachBooks Manual +:::{prf:theorem-start} A title +:label: theorem-label + +This is a theorem. This text is inside the directive. +::: + +Now some extra text that should come inside the theorem. + +:::{figure} images/sphinx-logo.svg +:alt: Sphinx logo +:width: 200px +:align: center + +Sphinx is a great tool for documentation! This figure should be inside the theorem. +::: + +```{code-cell} ipython3 +a = "This is some" +b = "Python code" +c = "that should be inside the theorem." +print(f"{a} {b} {c}") +``` + +:::{prf:theorem-end} +::: + +:::{figure-start} images/logo-wide.svg +:name: figure-label +:alt: JupyterBook logo +:width: 200px +:align: center + +This is a figure. This text is inside the caption. +::: + +```{code-cell} ipython3 +a = "This is some" +b = "Python code" +c = "that should be inside the figure," +d = "above the caption." +print(f"{a} {b} {c} {d}") +``` + +Now some extra text that should come inside the figure, above the caption. + +:::{figure} images/sphinx-logo.svg +:alt: Sphinx logo +:width: 200px +:align: center + +Sphinx is a great tool for documentation! This figure should be inside the parent figure, above the parent caption. +::: + +:::{figure-end} +::: + This manual is primarily designed for and by teachers for use in education, but should be a useful resource for anyone interested in creating and collaborating on a TeachBook: a Jupyter book v1 v1 using the Sphinx logo Sphinx backend with additional editing tools and book features. Our aim is to provide a simple way to start book-making for new users (it only takes 10 clicks!), ease the editing process for anyone, and provide additional features developed for education-purposes. We hope you find this resource useful and refer back to it often. TeachBooks originated at Delft University of Technology in the Netherlands, and some of the material in this Manual reflects tools and resources specific to TU Delft. With the exception of a few tools for which we have educational licenses at Delft, everything in this Manual is open source. Despite this, we are happy to grow our open source community beyond Delft and welcome contributions from all users. From a5f014ddf6ddf75255be771d9bfb39498b4c37cb Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 2 Jan 2026 17:55:31 +0100 Subject: [PATCH 042/110] Replace logo figure with nothing.svg in intro Added a new SVG file 'nothing.svg' and updated the intro.md to use this image in place of the previous logo-wide.svg. Adjusted figure attributes and alt text accordingly. --- book/images/nothing.svg | 1 + book/intro.md | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 book/images/nothing.svg diff --git a/book/images/nothing.svg b/book/images/nothing.svg new file mode 100644 index 0000000..2c4a47c --- /dev/null +++ b/book/images/nothing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/book/intro.md b/book/intro.md index 5df72ca..204b5a3 100644 --- a/book/intro.md +++ b/book/intro.md @@ -32,10 +32,9 @@ print(f"{a} {b} {c}") :::{prf:theorem-end} ::: -:::{figure-start} images/logo-wide.svg +:::{figure-start} images/nothing.svg :name: figure-label -:alt: JupyterBook logo -:width: 200px +:alt: Nothing :align: center This is a figure. This text is inside the caption. From f9e4a0f0b7265975d8b981f2e39fba4ba332833d Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 2 Jan 2026 20:05:44 +0100 Subject: [PATCH 043/110] Improve gated directive nesting validation and docs Added a robust validate_SE function to check for correct nesting of start and end directives, with detailed error reporting. Updated the CheckGatedDirectivesTransform to use this validation and improved error messages for mismatched or incorrectly nested directives. Extended intro.md with comprehensive examples of nested directives, including both valid and invalid cases, to document and test the new behavior. Also added the sphinx_tudelft_theme extension in _config.yml. --- book/_config.yml | 1 + book/_ext/sphinx_gated_directives/__init__.py | 88 +++++++++++-- book/intro.md | 120 ++++++++++++++++++ 3 files changed, 198 insertions(+), 11 deletions(-) diff --git a/book/_config.yml b/book/_config.yml index 580aa76..1e55627 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -19,6 +19,7 @@ sphinx: - teachbooks_favourites - teachbooks_sphinx_grasple - sphinx_apa_references + - sphinx_tudelft_theme config: language: en html_js_files: diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py index 7afe003..d213d60 100644 --- a/book/_ext/sphinx_gated_directives/__init__.py +++ b/book/_ext/sphinx_gated_directives/__init__.py @@ -30,6 +30,9 @@ from docutils import nodes from docutils.parsers.rst import Directive from docutils.parsers.rst import directives as du_directives +from dataclasses import dataclass, field +from typing import Dict, Optional + SUFFIX_START = "-start" SUFFIX_END = "-end" @@ -142,7 +145,7 @@ def make_startified_class( else: children = [children] # create a start_node and add all result nodes as its children - start_node_instance = start_node() + start_node_instance = start_node(orig_name) start_node_instance += children result = [start_node_instance] @@ -267,7 +270,7 @@ def make_endified_class( # return [] # next line should be good enough, but raises an error as not all has been implemented # maybe we need end nodes per directive type? - return [end_node()] + return [end_node(orig_name)] attrs["run"] = run new_cls_name = f"{base_cls.__name__}_End_For_{orig_name.replace(':', '_')}" @@ -333,10 +336,15 @@ def setup(app): # Node classes for start and end directives class start_node(nodes.Admonition, nodes.Element): - pass + + def __init__(self, type_of_directive: str=""): + self.type_of_directive = type_of_directive + super().__init__() class end_node(nodes.Admonition, nodes.Element): - pass + def __init__(self, type_of_directive: str=""): + self.type_of_directive = type_of_directive + super().__init__() # purge_registry def purge_registries(app: Sphinx, env: BuildEnvironment, docname: str) -> None: @@ -375,7 +383,7 @@ class CheckGatedDirectivesTransform(SphinxTransform): end = super_registry[docname]["end"] structure = "\n ".join(super_registry[docname]["msg"]) sequence = "".join(super_registry[docname]["sequence"]) - groups = re.findall("(SE)", sequence) + validate_SE_result = validate_SE(sequence) if len(start) > len(end): msg = f"The document {docname} contains more start directives than end directives:\n {structure}\nPlease ensure each start directive has a corresponding end directive." logger.error(msg) @@ -385,21 +393,23 @@ class CheckGatedDirectivesTransform(SphinxTransform): logger.error(msg) error = True # at this point, len(start) == len(end) - elif len(groups) != len(start) or len(groups) != len(end): - msg = f"The document {docname} contains nested start and end directives:\n {structure}\nThis is not allowed. Please correct the nesting." + # now check for correct nesting + elif not validate_SE_result.is_valid: + msg = f"The document {docname} contains incorrectly nested start and end directives:\n {structure}\nThis is not allowed. Please correct the nesting." logger.error(msg) error = True else: - # At this point, every start is followed by an end. + # At this point, every start is matched with an end # Now check that types match in order. types = super_registry[docname]["type"] - start_type = types[::2] - end_type = types[1::2] + start_type = [types[k] for k in validate_SE_result.pairs.keys()] + end_type = [types[v] for v in validate_SE_result.pairs.values()] for i in range(len(start_type)): if start_type[i] != end_type[i]: msg = f"The document {docname} contains mismatched start and end directives at lines {start[i]} and {end[i]}:\n {structure}\nPlease ensure that start and end directives match in type." logger.error(msg) error = True + break if error: raise Exception(f"[sphinx-gated-directives] An error has occurred when parsing gated directives in {docname}.\nPlease check warning messages above.") @@ -505,4 +515,60 @@ def findall(node: Element, *args, **kwargs) -> Iterator[Element]: # findall replaces traverse in docutils v0.18 # note a difference is that findall is an iterator impl = getattr(node, "findall", node.traverse) - return iter(impl(*args, **kwargs)) \ No newline at end of file + return iter(impl(*args, **kwargs)) + +@dataclass +class SEValidationResult: + is_valid: bool + pairs: Dict[int, int] = field(default_factory=dict) # {S_index: E_index} + error_index: Optional[int] = None # index of first error, if any + error_message: Optional[str] = None # description of the error, if any + +def validate_SE(s: str) -> SEValidationResult: + """ + Validates a string containing only 'S' (open) and 'E' (close). + Returns: + SEValidationResult with: + - is_valid: True iff all brackets match and no invalid characters occur. + - pairs: dict mapping each 'S' index to the corresponding 'E' index. + (zero-based indices in the original string) + - error_index, error_message: populated on first failure. + Errors reported: + * Invalid character (not 'S' or 'E'). + * 'E' encountered before any available 'S'. + * Unmatched 'S' remaining at the end. + The pairs dict is still returned for all successfully matched pairs up to the error. + """ + stack = [] # stack of indices of unmatched 'S' + pairs: Dict[int, int] = {} + + for i, ch in enumerate(s): + if ch == 'S': + stack.append(i) + elif ch == 'E': + if not stack: + return SEValidationResult( + is_valid=False, + pairs=pairs, + error_index=i, + error_message="Encountered 'E' before a matching 'S'." + ) + s_index = stack.pop() + pairs[s_index] = i + else: + return SEValidationResult( + is_valid=False, + pairs=pairs, + error_index=i, + error_message=f"Invalid character: {ch!r}. Only 'S' and 'E' are allowed." + ) + + if stack: + return SEValidationResult( + is_valid=False, + pairs=pairs, + error_index=len(s), + error_message=f"{len(stack)} unmatched 'S' remaining at end." + ) + + return SEValidationResult(is_valid=True, pairs=pairs) diff --git a/book/intro.md b/book/intro.md index 204b5a3..c70a559 100644 --- a/book/intro.md +++ b/book/intro.md @@ -6,6 +6,124 @@ kernelspec: # TeachBooks Manual +## Nesting inside of a start-directive + +### Different directives + +::::{prf:theorem-start} The parent theorem +:label: parent-theorem-label + +This is a parent theorem. This text is inside the parent theorem. + +:::{prf:axiom-start} A child theorem +:label: child-axiom-label + +This is a child axiom. This text is inside the child directive. +::: + +This is text after the child-start, before the child-end, inside the parent theorem. + +:::{prf:axiom-end} +::: + +Finally some text after the entire child, inside the theorem start. + +:::: + +Some text after the entire parent theorem start, but before the parent theorem end. + +:::{prf:theorem-end} +::: + +### Same directives + +::::{prf:theorem-start} The parent theorem +:label: parent-theorem-label2 + +This is a parent theorem. This text is inside the parent theorem. + +:::{prf:theorem-start} A child theorem +:label: child-theorem-label + +This is a child theorem. This text is inside the child directive. +::: + +This is text after the child-start, before the child-end, inside the parent theorem. + +:::{prf:theorem-end} +::: + +Finally some text after the entire child, inside the theorem start. + +:::: + +Some text after the entire parent theorem start, but before the parent theorem end. + +:::{prf:theorem-end} +::: + +## Nesting outside of a start-directive + +### Different directives + +Crashes still: + + + +### Same directives + +Crashes still: + + + +## Examples with code + +### Block directive with also a figure + :::{prf:theorem-start} A title :label: theorem-label @@ -32,6 +150,8 @@ print(f"{a} {b} {c}") :::{prf:theorem-end} ::: +### Figure directive with nothing with also another figure + :::{figure-start} images/nothing.svg :name: figure-label :alt: Nothing From f4815885090b62377c50bf221a27b318dd4240f0 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 2 Jan 2026 20:08:02 +0100 Subject: [PATCH 044/110] Update child theorem to axiom and add Sphinx theme Changed the label from 'A child theorem' to 'A child axiom' in the intro.md file for clarity. Added 'sphinx-tudelft-theme==1.2.1' to requirements.txt to specify the documentation theme. --- book/intro.md | 2 +- requirements.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/book/intro.md b/book/intro.md index c70a559..c51c487 100644 --- a/book/intro.md +++ b/book/intro.md @@ -15,7 +15,7 @@ kernelspec: This is a parent theorem. This text is inside the parent theorem. -:::{prf:axiom-start} A child theorem +:::{prf:axiom-start} A child axiom :label: child-axiom-label This is a child axiom. This text is inside the child directive. diff --git a/requirements.txt b/requirements.txt index 3b6ef5b..1c93c95 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,5 @@ sphinx-apa-references myst_nb numpy matplotlib + +sphinx-tudelft-theme == 1.2.1 \ No newline at end of file From 144c7a95beed2d739da48c1bd010f072804c7daf Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sat, 3 Jan 2026 10:30:39 +0100 Subject: [PATCH 045/110] Refactor sphinx_gated_directives and update intro.md examples Improved code structure and comments in sphinx_gated_directives/__init__.py, clarified logic, and removed unused/legacy code. Updated intro.md to remove commented-out directive examples and replaced them with active ones for better demonstration and testing. --- book/_ext/sphinx_gated_directives/__init__.py | 257 +++++------------- book/intro.md | 12 +- 2 files changed, 69 insertions(+), 200 deletions(-) diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py index d213d60..e956b0b 100644 --- a/book/_ext/sphinx_gated_directives/__init__.py +++ b/book/_ext/sphinx_gated_directives/__init__.py @@ -1,24 +1,34 @@ -# startify_directives_all.py """ -Create a '-start' companion for every registered directive (class-based). +~~~~~~~~~~~~~~~~~~~~ -Rules: - - Skip originals whose name already ends with '-start' or '-end'. - - Skip if '-start' already exists. - - Class-based originals -> register a subclass calling original run(). +sphinx_gated_directives + +~~~~~~~~~~~~~~~~~~~~ + +This package is an extension for Sphinx that creates a '-start' companion +and a '-end' companion for every registered class-based directive. + +These new directives can be used to "gate" content in the documentation, +similar to how the gated directives of sphinx-exercise work. + +This extension is based on the extension executablebooks/sphinx-exercise: +https://github.com/executablebooks/sphinx-exercise + +Original project licensed under MIT © Executable Books Developers. +See the repository LICENSE for details. + +Our implementation reuses certain ideas and code snippets (e.g., Docutils +compatibility helpers) to fit the needs of this extension. -Usage: - extensions = ["startify_directives_all"] """ from __future__ import annotations from docutils.nodes import Element from typing import Iterator -import re import copy import importlib import inspect -from typing import Callable, Dict, Iterable, List, Optional +from typing import Dict, Iterable, Optional from sphinx.transforms import SphinxTransform from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment @@ -31,34 +41,14 @@ from docutils.parsers.rst import Directive from docutils.parsers.rst import directives as du_directives from dataclasses import dataclass, field -from typing import Dict, Optional SUFFIX_START = "-start" SUFFIX_END = "-end" - -# --------------------------- -# Helpers: identification -# --------------------------- - def _is_class_directive(obj) -> bool: return inspect.isclass(obj) and issubclass(obj, Directive) - -# --------------------------- -# Helpers: registry access -# --------------------------- - def _get_unified_registry(app=None) -> Dict[str, object]: - """ - Build a unified {name -> implementation} mapping of directives. - - Sources: - 1) docutils.parsers.rst.directives._directives (loaded/added so far) - 2) docutils.parsers.rst.directives._directive_registry (lazy map of - name -> (module, class) for builtins); import any missing ones. - 3) Sphinx app.registry (if provided) for extension-registered directives - """ # 1) Already-loaded directives (includes Sphinx & extensions registered via add_directive) unified: Dict[str, object] = dict(getattr(du_directives, "_directives", {})) @@ -104,21 +94,11 @@ def _get_unified_registry(app=None) -> Dict[str, object]: return unified - -# --------------------------- -# Helpers: class generation -# --------------------------- - def _copy_option_spec(option_spec): return copy.copy(option_spec) if isinstance(option_spec, dict) else option_spec -def make_startified_class( - orig_name: str, - base_cls: type[Directive], -) -> type[Directive]: - """ - Subclass `base_cls` to call original run(). - """ +def make_start_class(orig_name: str, base_cls: type[Directive]) -> type[Directive]: + attrs = {} for attr in ( "required_arguments", @@ -145,7 +125,7 @@ def make_startified_class( else: children = [children] # create a start_node and add all result nodes as its children - start_node_instance = start_node(orig_name) + start_node_instance = start_node() start_node_instance += children result = [start_node_instance] @@ -153,30 +133,10 @@ def make_startified_class( env = getattr(self.state.document.settings, "env", None) if env is not None: docname = env.docname - # # 1) Check whether main registry is already created, if not, create it - # if not hasattr(env, "sphinx_gated_directives_registry"): - # env.sphinx_gated_directives_registry = {} - # # 2) Check whether a sub-registry for current directive type is already created, if not, create it - # if orig_name not in env.sphinx_gated_directives_registry: - # env.sphinx_gated_directives_registry[orig_name] = {} - # # 3) Register current usage in the registry for this doc and this type - # gated_registry = env.sphinx_gated_directives_registry[orig_name] - # if docname not in gated_registry: - # gated_registry[docname] = { - # "start": [], - # "end": [], - # "sequence": [], - # "msg": [], - # } - # gated_registry[docname]["start"].append(self.lineno) - # gated_registry[docname]["sequence"].append("S") - # gated_registry[docname]["msg"].append( - # f"{self.name} at line: {self.lineno}" - # ) - # 4) Check whether super registry has been created, if not, create it + # 1) Check whether super registry has been created, if not, create it if not hasattr(env, "sphinx_gated_directives_super_registry"): env.sphinx_gated_directives_super_registry = {} - # 5) Register current usage in the super registry + # 2) Register current usage in the super registry super_registry = env.sphinx_gated_directives_super_registry if docname not in super_registry: super_registry[docname] = { @@ -199,13 +159,8 @@ def make_startified_class( new_cls_name = f"{base_cls.__name__}_Start_For_{orig_name.replace(':', '_')}" return type(new_cls_name, (base_cls,), attrs) -def make_endified_class( - orig_name: str, - base_cls: type[Directive], -) -> type[Directive]: - """ - Just create a subclass to obtain an end node. - """ +def make_end_class(orig_name: str, base_cls: type[Directive]) -> type[Directive]: + attrs = {} for attr in ( "required_arguments", @@ -227,30 +182,10 @@ def make_endified_class( env = getattr(self.state.document.settings, "env", None) if env is not None: docname = env.docname - # # 1) Check whether main registry is already created, if not, create it - # if not hasattr(env, "sphinx_gated_directives_registry"): - # env.sphinx_gated_directives_registry = {} - # # 2) Check whether a sub-registry for current directive type is already created, if not, create it - # if orig_name not in env.sphinx_gated_directives_registry: - # env.sphinx_gated_directives_registry[orig_name] = {} - # # 3) Register current usage in the registry for this doc and this type - # gated_registry = env.sphinx_gated_directives_registry[orig_name] - # if docname not in gated_registry: - # gated_registry[docname] = { - # "start": [], - # "end": [], - # "sequence": [], - # "msg": [], - # } - # gated_registry[docname]["end"].append(self.lineno) - # gated_registry[docname]["sequence"].append("E") - # gated_registry[docname]["msg"].append( - # f"{self.name} at line: {self.lineno}" - # ) - # 4) Check whether super registry has been created, if not, create it + # 1) Check whether super registry has been created, if not, create it if not hasattr(env, "sphinx_gated_directives_super_registry"): env.sphinx_gated_directives_super_registry = {} - # 5) Register current usage in the super registry + # 2) Register current usage in the super registry super_registry = env.sphinx_gated_directives_super_registry if docname not in super_registry: super_registry[docname] = { @@ -267,23 +202,16 @@ def make_endified_class( ) super_registry[docname]["type"].append(orig_name) - # return [] - # next line should be good enough, but raises an error as not all has been implemented - # maybe we need end nodes per directive type? - return [end_node(orig_name)] + return [end_node()] attrs["run"] = run new_cls_name = f"{base_cls.__name__}_End_For_{orig_name.replace(':', '_')}" return type(new_cls_name, (base_cls,), attrs) -# --------------------------- -# Core logic -# --------------------------- - def _should_skip_name(orig_name: str) -> bool: return orig_name.endswith(SUFFIX_START) or orig_name.endswith(SUFFIX_END) -def _register_startified_directives(app, env, docnames): +def _register_new_directives(app, env, docnames): unified = _get_unified_registry(app) snapshot_names = set(unified.keys()) added = 0 @@ -298,27 +226,26 @@ def _register_startified_directives(app, env, docnames): try: if _is_class_directive(obj): - start_cls = make_startified_class(orig_name, obj) + start_cls = make_start_class(orig_name, obj) # new class based on original so all properties are inherited app.add_directive(new_name, start_cls) - end_cls = make_endified_class(orig_name, Directive) # because it does generate anything, most simple directive + end_cls = make_end_class(orig_name, Directive) # because it does not generate anything, most simple directive possible app.add_directive(f"{orig_name}{SUFFIX_END}", end_cls) added += 1 else: - logger.debug(f"[startify] '{orig_name}' is not a class directive; skipping.") + logger.debug(f"[sphinx-gated-directives] '{orig_name}' is not a class directive; skipping.") except Exception as e: - logger.warning(f"[startify] failed to register '{new_name}': {e}") + logger.warning(f"[sphinx-gated-directives] failed to register new classes for directive '{orig_name}':\n{e}") def setup(app): - # register function to perge registries at start of build per document + # register function to purge registries at start of build per document app.connect("env-purge-doc", purge_registries) - # At the latest possible moment, register startified directives (also creates the endified ones) - app.connect("env-before-read-docs", _register_startified_directives,priority=10000000000000000000000000000) + # At the latest possible moment, register new directives + app.connect("env-before-read-docs", _register_new_directives,priority=10000000000000000000000000000) - # Register nodes, used as placeholder for end directives - # will be resolved in the transforms to something meaningful - # during merging of start-end blocks + # Register nodes + # During transformation phase, these nodes will be removed app.add_node(start_node) app.add_node(end_node) @@ -329,32 +256,17 @@ def setup(app): app.add_transform(MergeGatedDirectivesTransform) return { - "version": "1.0", "parallel_read_safe": True, } -# Node classes for start and end directives - class start_node(nodes.Admonition, nodes.Element): - - def __init__(self, type_of_directive: str=""): - self.type_of_directive = type_of_directive - super().__init__() + pass class end_node(nodes.Admonition, nodes.Element): - def __init__(self, type_of_directive: str=""): - self.type_of_directive = type_of_directive - super().__init__() + pass -# purge_registry def purge_registries(app: Sphinx, env: BuildEnvironment, docname: str) -> None: - # only perge if needed - # if hasattr(env, "sphinx_gated_directives_registry"): - # registry = env.sphinx_gated_directives_registry - # for directive_name in registry: - # if docname in registry[directive_name]: - # del registry[directive_name][docname] if hasattr(env, "sphinx_gated_directives_super_registry"): super_registry = env.sphinx_gated_directives_super_registry if docname in super_registry: @@ -366,15 +278,9 @@ class CheckGatedDirectivesTransform(SphinxTransform): def apply(self, **kwargs): env = self.env - # if not hasattr(env, "sphinx_gated_directives_registry"): - # return if not hasattr(env, "sphinx_gated_directives_super_registry"): return - # First check the super registry for a correct structure - # demands: - # 1) equal number of start and end directives - # 2) no nesting of start-end pairs (so SSEE is not allowed, only SESE) super_registry = env.sphinx_gated_directives_super_registry error = False docname = self.env.docname @@ -385,17 +291,17 @@ class CheckGatedDirectivesTransform(SphinxTransform): sequence = "".join(super_registry[docname]["sequence"]) validate_SE_result = validate_SE(sequence) if len(start) > len(end): - msg = f"The document {docname} contains more start directives than end directives:\n {structure}\nPlease ensure each start directive has a corresponding end directive." + msg = f"[sphinx-gated-directives] The document {docname} contains more start directives than end directives:\n {structure}\nPlease ensure each start directive has a corresponding end directive." logger.error(msg) error = True elif len(end) > len(start): - msg = f"The document {docname} contains more end directives than start directives:\n {structure}\nPlease ensure each end directive has a corresponding start directive." + msg = f"[sphinx-gated-directives] The document {docname} contains more end directives than start directives:\n {structure}\nPlease ensure each end directive has a corresponding start directive." logger.error(msg) error = True # at this point, len(start) == len(end) # now check for correct nesting elif not validate_SE_result.is_valid: - msg = f"The document {docname} contains incorrectly nested start and end directives:\n {structure}\nThis is not allowed. Please correct the nesting." + msg = f"[sphinx-gated-directives] The document {docname} contains incorrectly nested start and end directives:\n {structure}\nThis is not allowed. Please correct the nesting." logger.error(msg) error = True else: @@ -406,7 +312,7 @@ class CheckGatedDirectivesTransform(SphinxTransform): end_type = [types[v] for v in validate_SE_result.pairs.values()] for i in range(len(start_type)): if start_type[i] != end_type[i]: - msg = f"The document {docname} contains mismatched start and end directives at lines {start[i]} and {end[i]}:\n {structure}\nPlease ensure that start and end directives match in type." + msg = f"[sphinx-gated-directives] The document {docname} contains mismatched start and end directives at lines {start[i]} and {end[i]}:\n {structure}\nPlease ensure that start and end directives match in type." logger.error(msg) error = True break @@ -414,22 +320,11 @@ class CheckGatedDirectivesTransform(SphinxTransform): if error: raise Exception(f"[sphinx-gated-directives] An error has occurred when parsing gated directives in {docname}.\nPlease check warning messages above.") - # no check per directive type is needed if no error in super registry is raised, - # as the super registry already ensures correctness for each type. - # if nesting is allowed in the future, this part needs to be re-implemented. - - class MergeGatedDirectivesTransform(SphinxTransform): default_priority = 10 def apply(self, **kwargs): env = self.env - # Something to do here - # idea: - # 1) Find all start_nodes - # 2) for each start_node, find the corresponding end_node (i.e. next end_node) - # 3) collect all nodes in between - # 4) Take the first node after start_node, and add all other collected nodes as its children if not hasattr(env, "sphinx_gated_directives_super_registry"): return super_registry = env.sphinx_gated_directives_super_registry @@ -437,80 +332,72 @@ class MergeGatedDirectivesTransform(SphinxTransform): if docname not in super_registry: return - # Each start-end pair is valid (checked before), so we can proceed to merge - # find all start nodes, as an iterator - # for each start node, find the next end node within the parent of start node start_nodes = findall(self.document, start_node) for start_n in start_nodes: parent = start_n.parent - # find the next end_node after start_n in parent found_start = False end_n = None + skip_end = 0 for child in parent.children: if child is start_n: found_start = True - elif found_start and isinstance(child, end_node): + elif found_start and isinstance(child, end_node) and skip_end==0: end_n = child break + elif found_start and isinstance(child, end_node): + skip_end -= 1 + elif found_start and isinstance(child, start_node): + skip_end += 1 if end_n is None: - continue # should not happen due to prior checks + logger.error(f"[sphinx-gated-directives] Could not find matching end directive for start directive at line {start_n.line} in document {docname}. Skipping merging for this pair.") + raise Exception(f"[sphinx-gated-directives] An error has occurred when parsing gated directives in {docname}.\nPlease check warning messages above.") - # collect all nodes between start_n and end_n start_index = parent.children.index(start_n) end_index = parent.children.index(end_n) between_nodes = parent.children[start_index + 1:end_index] - # We have to merge, but how is the question. - # we handle based on "experience" and "observation" of what kind of nodes are generated - # step 1: create a new container node to hold the merged content - # content of start_node new_nodes = start_n.children - # add content in between, depending on content in start_n if between_nodes: has_section = False has_caption = False si = -1 - content = new_nodes[-1] # we assume that the last child of start_n holds the main content + content = new_nodes[-1] for sn in content.children: si += 1 if isinstance(sn, nodes.section): - has_section = True # So probably a topic or similar (from sphinx-proof) + has_section = True section_index = si section_node = sn break elif isinstance(sn, nodes.caption): - has_caption = True # So probably a figure or similar + has_caption = True caption_index = si caption_node = sn break if has_section: - # if there are sections, we add all between nodes to this section content[section_index] += between_nodes elif has_caption: - # if there is a caption, we add all between nodes before the caption n = len(content.children) pos = n - 1 for i, bn in enumerate(between_nodes): - content.insert(pos + i, bn) # insert sets parent/doc links + content.insert(pos + i, bn) else: - # otherwise, we add all between nodes to the main content directly\ for bn in between_nodes: - content += bn # add sets parent/doc links + content += bn - # finally, replace start_n with new_nodes, and remove end_n and between_nodes start_pos = parent.children.index(start_n) - # remove end_n parent.remove(end_n) - # remove start_n parent.remove(start_n) - # remove between_nodes for bn in between_nodes: parent.remove(bn) - # insert new_nodes at start_pos for i, nn in enumerate(new_nodes): - parent.insert(start_pos + i, nn) # insert new structure + parent.insert(start_pos + i, nn) +# SPDX-License-Identifier: MIT +# Adapted from: executablebooks/sphinx-exercise, file: sphinx_exercise/_compat.py +# Source: https://github.com/executablebooks/sphinx-exercise/blob/main/sphinx_exercise/_compat.py +# License: MIT — © Executable Books Developers (see repository LICENSE). def findall(node: Element, *args, **kwargs) -> Iterator[Element]: # findall replaces traverse in docutils v0.18 # note a difference is that findall is an iterator @@ -525,21 +412,7 @@ class SEValidationResult: error_message: Optional[str] = None # description of the error, if any def validate_SE(s: str) -> SEValidationResult: - """ - Validates a string containing only 'S' (open) and 'E' (close). - Returns: - SEValidationResult with: - - is_valid: True iff all brackets match and no invalid characters occur. - - pairs: dict mapping each 'S' index to the corresponding 'E' index. - (zero-based indices in the original string) - - error_index, error_message: populated on first failure. - Errors reported: - * Invalid character (not 'S' or 'E'). - * 'E' encountered before any available 'S'. - * Unmatched 'S' remaining at the end. - The pairs dict is still returned for all successfully matched pairs up to the error. - """ - stack = [] # stack of indices of unmatched 'S' + stack = [] pairs: Dict[int, int] = {} for i, ch in enumerate(s): diff --git a/book/intro.md b/book/intro.md index c51c487..3a415f8 100644 --- a/book/intro.md +++ b/book/intro.md @@ -66,9 +66,7 @@ Some text after the entire parent theorem start, but before the parent theorem e ### Different directives -Crashes still: - - +::: ### Same directives -Crashes still: - - +::: ## Examples with code From f4ea60d42c4af8378e5e778a3a31d3b0365de38e Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sat, 3 Jan 2026 12:45:24 +0100 Subject: [PATCH 046/110] Enhance sphinx_gated_directives with configurable suffixes and override logic Refactor the sphinx_gated_directives extension to support configurable suffixes and separator for start/end directives, and add an 'override_existing' option for more flexible directive registration. Update the registry naming and logic throughout the extension, add configuration validation, and update the book config and intro to demonstrate new exercise directives and nesting. --- book/_config.yml | 2 + book/_ext/sphinx_gated_directives/__init__.py | 176 +++++++++++++----- book/intro.md | 35 +++- 3 files changed, 167 insertions(+), 46 deletions(-) diff --git a/book/_config.yml b/book/_config.yml index 1e55627..8f88cff 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -21,6 +21,8 @@ sphinx: - sphinx_apa_references - sphinx_tudelft_theme config: + sphinx_gated_directives: + override_existing: ['exercise'] language: en html_js_files: - https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py index e956b0b..c650d97 100644 --- a/book/_ext/sphinx_gated_directives/__init__.py +++ b/book/_ext/sphinx_gated_directives/__init__.py @@ -42,8 +42,9 @@ from docutils.parsers.rst import directives as du_directives from dataclasses import dataclass, field -SUFFIX_START = "-start" -SUFFIX_END = "-end" +SUFFIX_START = "start" +SUFFIX_END = "end" +SUFFIX_SEPARATOR = "-" def _is_class_directive(obj) -> bool: return inspect.isclass(obj) and issubclass(obj, Directive) @@ -134,24 +135,24 @@ def make_start_class(orig_name: str, base_cls: type[Directive]) -> type[Directiv if env is not None: docname = env.docname # 1) Check whether super registry has been created, if not, create it - if not hasattr(env, "sphinx_gated_directives_super_registry"): - env.sphinx_gated_directives_super_registry = {} + if not hasattr(env, "sphinx_gated_directives_registry"): + env.sphinx_gated_directives_registry = {} # 2) Register current usage in the super registry - super_registry = env.sphinx_gated_directives_super_registry - if docname not in super_registry: - super_registry[docname] = { + registry = env.sphinx_gated_directives_registry + if docname not in registry: + registry[docname] = { "start": [], "end": [], "sequence": [], "msg": [], "type": [], } - super_registry[docname]["start"].append(self.lineno) - super_registry[docname]["sequence"].append("S") - super_registry[docname]["msg"].append( + registry[docname]["start"].append(self.lineno) + registry[docname]["sequence"].append("S") + registry[docname]["msg"].append( f"{self.name} at line: {self.lineno}" ) - super_registry[docname]["type"].append(orig_name) + registry[docname]["type"].append(orig_name) return result @@ -183,24 +184,24 @@ def make_end_class(orig_name: str, base_cls: type[Directive]) -> type[Directive] if env is not None: docname = env.docname # 1) Check whether super registry has been created, if not, create it - if not hasattr(env, "sphinx_gated_directives_super_registry"): - env.sphinx_gated_directives_super_registry = {} + if not hasattr(env, "sphinx_gated_directives_registry"): + env.sphinx_gated_directives_registry = {} # 2) Register current usage in the super registry - super_registry = env.sphinx_gated_directives_super_registry - if docname not in super_registry: - super_registry[docname] = { + registry = env.sphinx_gated_directives_registry + if docname not in registry: + registry[docname] = { "start": [], "end": [], "sequence": [], "msg": [], "type": [], } - super_registry[docname]["end"].append(self.lineno) - super_registry[docname]["sequence"].append("E") - super_registry[docname]["msg"].append( + registry[docname]["end"].append(self.lineno) + registry[docname]["sequence"].append("E") + registry[docname]["msg"].append( f"{self.name} at line: {self.lineno}" ) - super_registry[docname]["type"].append(orig_name) + registry[docname]["type"].append(orig_name) return [end_node()] @@ -208,28 +209,73 @@ def make_end_class(orig_name: str, base_cls: type[Directive]) -> type[Directive] new_cls_name = f"{base_cls.__name__}_End_For_{orig_name.replace(':', '_')}" return type(new_cls_name, (base_cls,), attrs) -def _should_skip_name(orig_name: str) -> bool: - return orig_name.endswith(SUFFIX_START) or orig_name.endswith(SUFFIX_END) +def _should_skip_name(orig_name: str, cfg: dict) -> bool: + if isinstance(cfg["override_existing"],bool): + if cfg["override_existing"] is True: + return False + else: + if orig_name.endswith(f"{cfg["suffix_separator"]}{cfg["suffix_start"]}"): + return True + else: + return orig_name.endswith(f"{cfg["suffix_separator"]}{cfg["suffix_end"]}") + elif isinstance(cfg["override_existing"],list): + if orig_name in cfg["override_existing"]: + return False + else: + if orig_name.endswith(f"{cfg["suffix_separator"]}{cfg["suffix_start"]}"): + return True + else: + return orig_name.endswith(f"{cfg["suffix_separator"]}{cfg["suffix_end"]}") def _register_new_directives(app, env, docnames): + + # get options and add missing default values + cfg = app.config.sphinx_gated_directives + if "override_existing" not in cfg: + cfg["override_existing"] = False + elif isinstance(cfg["override_existing"], str): + cfg["override_existing"] = [cfg["override_existing"]] + if "suffix_start" not in cfg: + cfg["suffix_start"] = SUFFIX_START + if "suffix_end" not in cfg: + cfg["suffix_end"] = SUFFIX_END + if "suffix_separator" not in cfg: + cfg["suffix_separator"] = SUFFIX_SEPARATOR + unified = _get_unified_registry(app) snapshot_names = set(unified.keys()) added = 0 for orig_name, obj in sorted(unified.items()): - if _should_skip_name(orig_name): - continue - new_name = f"{orig_name}{SUFFIX_START}" + new_name = f"{orig_name}{cfg["suffix_separator"]}{cfg["suffix_start"]}" + # add start and end directives if not already present, or if override is requested explicitly if new_name in snapshot_names: + if isinstance(cfg["override_existing"], bool): + if cfg["override_existing"] is False: + continue + else: + if orig_name not in cfg["override_existing"]: + continue + end_name = f"{orig_name}{cfg["suffix_separator"]}{cfg["suffix_end"]}" + if end_name in snapshot_names: + if isinstance(cfg["override_existing"], bool): + if cfg["override_existing"] is False: + continue + else: + if orig_name not in cfg["override_existing"]: + continue + + # if the original name is itself a start or end directive, skip + if _should_skip_name(orig_name,cfg): continue try: if _is_class_directive(obj): start_cls = make_start_class(orig_name, obj) # new class based on original so all properties are inherited - app.add_directive(new_name, start_cls) + app.add_directive(new_name, start_cls,override=True) end_cls = make_end_class(orig_name, Directive) # because it does not generate anything, most simple directive possible - app.add_directive(f"{orig_name}{SUFFIX_END}", end_cls) + app.add_directive(end_name, end_cls,override=True) added += 1 else: logger.debug(f"[sphinx-gated-directives] '{orig_name}' is not a class directive; skipping.") @@ -237,6 +283,11 @@ def _register_new_directives(app, env, docnames): logger.warning(f"[sphinx-gated-directives] failed to register new classes for directive '{orig_name}':\n{e}") def setup(app): + # Register a config value to set options for the extension + app.add_config_value("sphinx_gated_directives", {}, "env") + + # Register a function to check if config value structure is correct + app.connect("config-inited", check_config_values) # register function to purge registries at start of build per document app.connect("env-purge-doc", purge_registries) @@ -267,10 +318,10 @@ class end_node(nodes.Admonition, nodes.Element): def purge_registries(app: Sphinx, env: BuildEnvironment, docname: str) -> None: - if hasattr(env, "sphinx_gated_directives_super_registry"): - super_registry = env.sphinx_gated_directives_super_registry - if docname in super_registry: - del super_registry[docname] + if hasattr(env, "sphinx_gated_directives_registry"): + registry = env.sphinx_gated_directives_registry + if docname in registry: + del registry[docname] # Transform to check validity of start-end pairs class CheckGatedDirectivesTransform(SphinxTransform): @@ -278,17 +329,17 @@ class CheckGatedDirectivesTransform(SphinxTransform): def apply(self, **kwargs): env = self.env - if not hasattr(env, "sphinx_gated_directives_super_registry"): + if not hasattr(env, "sphinx_gated_directives_registry"): return - super_registry = env.sphinx_gated_directives_super_registry + registry = env.sphinx_gated_directives_registry error = False docname = self.env.docname - if docname in super_registry: - start = super_registry[docname]["start"] - end = super_registry[docname]["end"] - structure = "\n ".join(super_registry[docname]["msg"]) - sequence = "".join(super_registry[docname]["sequence"]) + if docname in registry: + start = registry[docname]["start"] + end = registry[docname]["end"] + structure = "\n ".join(registry[docname]["msg"]) + sequence = "".join(registry[docname]["sequence"]) validate_SE_result = validate_SE(sequence) if len(start) > len(end): msg = f"[sphinx-gated-directives] The document {docname} contains more start directives than end directives:\n {structure}\nPlease ensure each start directive has a corresponding end directive." @@ -307,7 +358,7 @@ class CheckGatedDirectivesTransform(SphinxTransform): else: # At this point, every start is matched with an end # Now check that types match in order. - types = super_registry[docname]["type"] + types = registry[docname]["type"] start_type = [types[k] for k in validate_SE_result.pairs.keys()] end_type = [types[v] for v in validate_SE_result.pairs.values()] for i in range(len(start_type)): @@ -325,11 +376,11 @@ class MergeGatedDirectivesTransform(SphinxTransform): def apply(self, **kwargs): env = self.env - if not hasattr(env, "sphinx_gated_directives_super_registry"): + if not hasattr(env, "sphinx_gated_directives_registry"): return - super_registry = env.sphinx_gated_directives_super_registry + registry = env.sphinx_gated_directives_registry docname = self.env.docname - if docname not in super_registry: + if docname not in registry: return start_nodes = findall(self.document, start_node) @@ -445,3 +496,44 @@ def validate_SE(s: str) -> SEValidationResult: ) return SEValidationResult(is_valid=True, pairs=pairs) + +def check_config_values(app: Sphinx, config) -> None: + cfg = config.sphinx_gated_directives + if not isinstance(cfg, dict): + logger.error("[sphinx-gated-directives] The configuration value 'sphinx_gated_directives' should be a dictionary.") + raise ValueError("Invalid configuration for 'sphinx_gated_directives'. Expected a dictionary.") + return + # Implemented options: + # - override_existing: bool (default: False), string or list of strings + override_existing = cfg.get("override_existing", False) + if not (isinstance(override_existing, bool) or isinstance(override_existing, str) or (isinstance(override_existing, list) and all(isinstance(x, str) for x in override_existing))): + logger.error("[sphinx-gated-directives] The configuration option 'override_existing' should be a boolean, a string, or a list of strings.") + raise ValueError("Invalid configuration for 'sphinx_gated_directives.override_existing'. Expected a boolean, string, or list of strings.") + # - suffix_start: string (default: 'start'), only a-z allowed, or empty string + suffix_start = cfg.get("suffix_start", SUFFIX_START) + if not isinstance(suffix_start, str): + logger.error("[sphinx-gated-directives] The configuration option 'suffix_start' should be a string.") + raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_start'. Expected a string.") + if suffix_start != "" and (not suffix_start.islower() or not suffix_start.isalpha()): + logger.error("[sphinx-gated-directives] The configuration option 'suffix_start' should contain only lowercase letters (a-z).") + raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_start'. Expected only lowercase letters (a-z).") + # - suffix_end: string (default: 'end'), only a-z allowed, or empty string + suffix_end = cfg.get("suffix_end", SUFFIX_END) + if not isinstance(suffix_end, str): + logger.error("[sphinx-gated-directives] The configuration option 'suffix_end' should be a string.") + raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_end'. Expected a string.") + if suffix_end != "" and (not suffix_end.islower() or not suffix_end.isalpha()): + logger.error("[sphinx-gated-directives] The configuration option 'suffix_end' should contain only lowercase letters (a-z).") + raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_end'. Expected only lowercase letters (a-z).") + # - suffix_separator: string (default: '-'), single character, no space, no underscore, no colon, or empty string + suffix_separator = cfg.get("suffix_separator", SUFFIX_SEPARATOR) + if not isinstance(suffix_separator, str): + logger.error("[sphinx-gated-directives] The configuration option 'suffix_separator' should be a string.") + raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_separator'. Expected a string.") + if len(suffix_separator) > 1: + logger.error("[sphinx-gated-directives] The configuration option 'suffix_separator' should be a single character or an empty string.") + raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_separator'. Expected a single character or an empty string.") + if suffix_separator in [' ', '_',':']: + logger.error("[sphinx-gated-directives] The configuration option 'suffix_separator' should not be a space, nor an underscore, nor a colon.") + raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_separator'. Expected something other than a space, an underscore, or a colon.") + \ No newline at end of file diff --git a/book/intro.md b/book/intro.md index 3a415f8..4df190b 100644 --- a/book/intro.md +++ b/book/intro.md @@ -74,15 +74,15 @@ This is a parent theorem. This text is inside the parent theorem. Some text outside the parent theorem start, before the child start directive. -:::{prf:axiom-start} A child theorem -:label: child-axiom-label2 +:::{exercise-start} A child exercise +:label: child-exercise-label2 -This is a child axiom. This text is inside the child directive. +This is a child exercise. This text is inside the child directive. ::: This is text after the child-start, before the child-end. -:::{prf:axiom-end} +:::{exercise-end} ::: Finally some text after the entire child, outside the theorem start, before the end. @@ -90,6 +90,12 @@ Finally some text after the entire child, outside the theorem start, before the :::{prf:theorem-end} ::: +:::{exercise} This is an exercise outside any theorem. +:label: exercise-outside-theorem + +Solve this exercise. +::: + ### Same directives ::::{prf:theorem-start} The parent theorem @@ -116,6 +122,27 @@ Finally some text after the entire child, outside the theorem start, before the :::{prf:theorem-end} ::: +### Nested exercise directives + +:::{exercise-start} An outer exercise with an inner exercise between start and end +:label: outer-exercise-label +This is an outer exercise. This text is inside the outer exercise. +::: + +:::{exercise-start} An inner exercise +:label: inner-exercise-label +This is an inner exercise. This text is inside the inner exercise. +::: +This is text after the inner exercise start, before the inner exercise end. + +:::{exercise-end} +::: + +Finally some text after the entire inner exercise, inside the outer exercise. + +:::{exercise-end} +::: + ## Examples with code ### Block directive with also a figure From e12183af9eee6338e765aa6e3bdb7a0e19ac4025 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sat, 3 Jan 2026 12:48:34 +0100 Subject: [PATCH 047/110] Refactor _should_skip_name for clarity and efficiency Extracted suffix_separator, suffix_start, and suffix_end from cfg at the start of the function to avoid repeated dictionary lookups and improve code readability. --- book/_ext/sphinx_gated_directives/__init__.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py index c650d97..f85538a 100644 --- a/book/_ext/sphinx_gated_directives/__init__.py +++ b/book/_ext/sphinx_gated_directives/__init__.py @@ -210,22 +210,25 @@ def make_end_class(orig_name: str, base_cls: type[Directive]) -> type[Directive] return type(new_cls_name, (base_cls,), attrs) def _should_skip_name(orig_name: str, cfg: dict) -> bool: + suffix_separator = cfg["suffix_separator"] + suffix_start = cfg["suffix_start"] + suffix_end = cfg["suffix_end"] if isinstance(cfg["override_existing"],bool): if cfg["override_existing"] is True: return False else: - if orig_name.endswith(f"{cfg["suffix_separator"]}{cfg["suffix_start"]}"): + if orig_name.endswith(f"{suffix_separator}{suffix_start}"): return True else: - return orig_name.endswith(f"{cfg["suffix_separator"]}{cfg["suffix_end"]}") + return orig_name.endswith(f"{suffix_separator}{suffix_end}") elif isinstance(cfg["override_existing"],list): if orig_name in cfg["override_existing"]: return False else: - if orig_name.endswith(f"{cfg["suffix_separator"]}{cfg["suffix_start"]}"): + if orig_name.endswith(f"{suffix_separator}{suffix_start}"): return True else: - return orig_name.endswith(f"{cfg["suffix_separator"]}{cfg["suffix_end"]}") + return orig_name.endswith(f"{suffix_separator}{suffix_end}") def _register_new_directives(app, env, docnames): From 1ac94844a33e1a9ee12a7e956c01e9fb0900d385 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sat, 3 Jan 2026 12:50:11 +0100 Subject: [PATCH 048/110] Refactor directive name construction for clarity Extracted suffix_separator, suffix_start, and suffix_end from cfg to local variables for improved readability and maintainability in directive name construction. --- book/_ext/sphinx_gated_directives/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py index f85538a..5aef914 100644 --- a/book/_ext/sphinx_gated_directives/__init__.py +++ b/book/_ext/sphinx_gated_directives/__init__.py @@ -249,9 +249,12 @@ def _register_new_directives(app, env, docnames): snapshot_names = set(unified.keys()) added = 0 + suffix_separator = cfg["suffix_separator"] + suffix_start = cfg["suffix_start"] + suffix_end = cfg["suffix_end"] for orig_name, obj in sorted(unified.items()): - new_name = f"{orig_name}{cfg["suffix_separator"]}{cfg["suffix_start"]}" + new_name = f"{orig_name}{suffix_separator}{suffix_start}" # add start and end directives if not already present, or if override is requested explicitly if new_name in snapshot_names: if isinstance(cfg["override_existing"], bool): @@ -260,7 +263,7 @@ def _register_new_directives(app, env, docnames): else: if orig_name not in cfg["override_existing"]: continue - end_name = f"{orig_name}{cfg["suffix_separator"]}{cfg["suffix_end"]}" + end_name = f"{orig_name}{suffix_separator}{suffix_end}" if end_name in snapshot_names: if isinstance(cfg["override_existing"], bool): if cfg["override_existing"] is False: From e22ea50d6d57bcdf744ee0b6083293c7027024df Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Sat, 3 Jan 2026 15:35:40 +0100 Subject: [PATCH 049/110] added gates --- book/_config.yml | 2 + book/_toc.yml | 5 + book/instructie.ipynb | 1470 ++++++++++++++++++++++++++++++++++++++ book/instructie_2.ipynb | 1470 ++++++++++++++++++++++++++++++++++++++ book/lesoefeningen.ipynb | 316 ++++++++ 5 files changed, 3263 insertions(+) create mode 100644 book/instructie.ipynb create mode 100644 book/instructie_2.ipynb create mode 100644 book/lesoefeningen.ipynb diff --git a/book/_config.yml b/book/_config.yml index 8f88cff..ab31891 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -57,6 +57,8 @@ sphinx: summaries: false individual: false nb_execution_includepatterns: "**/MANUAL.ipynb" + sphinx_codex_name: "Voorbeeld" + sphinx_codex_merge_with_proof: true # default value teachbooks: attribution_location: margin diff --git a/book/_toc.yml b/book/_toc.yml index 4fc09d5..561237f 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -2,6 +2,11 @@ format: jb-book root: intro parts: + - caption: test sphinx_gated_directives + chapters: + - file: instructie.ipynb + - file: instructie_2.ipynb + - file: lesoefeningen.ipynb - caption: Your First TeachBook! chapters: - file: intro/book.md diff --git a/book/instructie.ipynb b/book/instructie.ipynb new file mode 100644 index 0000000..e2ec472 --- /dev/null +++ b/book/instructie.ipynb @@ -0,0 +1,1470 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "````{margin}\n", + "```{attributiongrey} Attribution\n", + ":class: attribution\n", + "\n", + "Deze pagina is aangepast van https://github.com/TUDelft-books/CT1000/blob/2025/book/week_2/session_1/intro.ipynb\n", + "\n", + "% Figures from https://github.com/TUDelft-books/CT1000/blob/2025/book/week_2/session_1/intro_data/Tekening1.vsdx\n", + "\n", + "```\n", + "```` " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Instructie_oud\n", + "\n", + "In constructiemechanica 2 heb je geleerd hoe je met differentiaalvergelijkingen voor statisch bepaalde constructies de krachtsverdeling en vervormingen kan vinden. Precies dezelfde aanpak werkt ook voor statisch onbepaalde constructie, met als enige verschil dat we de inwendige krachten niet kunnen vinden zonder ook de vergelijkingen en randvoorwaarden voor verplaatsingen op te stellen. Dat doen we volgens de volgende stappen:\n", + "\n", + "::::::{prf:algorithm} Differentiaalvergelijkingen toepassen\n", + ":nonumber: true\n", + ":label: differentiaalvergelijkingen_algoritme\n", + "\n", + "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", + "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", + "3. Er zijn nog meer vergelijkingen nodig om alle onbekende integratieconstantes op te lossen, deze kunnen we vinden door de overgangen tussen de verschillende elementen te analyseren waarbij zowel verplaatsingen als krachten in overeenstemming moeten zijn.\n", + "4. Er zijn nu evenveel vergelijkingen als onbekenden opgesteld. Deze kunnen nu worden opgelost en ingevuld in de opgestelde vergelijkingen voor het gewenste resultaat. Omdat het aantal onbekenden bij statisch onbepaalde constructies als snel uit de hand loopt wordt wordt aangeraden om je rekenmachine of een symbolische wiskundetool te gebruiken om dit op te lossen. Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python. Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt:\n", + "\n", + "::::::\n", + "\n", + "Als voorbeeld bepalen we de een simpele statisch onbepaalde constructie:\n", + "\n", + "::::::{prf:example}\n", + ":nonumber: true\n", + ":label: df_example_0\n", + "\n", + "Gegeven een constructie zoals hieronder weergegeven:\n", + "\n", + "```{figure} intro_data/structure.svg\n", + "---\n", + "align: center\n", + "---\n", + "Constructie, $EI = 5000 \\ \\rm{kNm^2}$\n", + "```\n", + "::::::\n", + "\n", + "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", + "\n", + "::::::{prf:example}\n", + ":nonumber: true\n", + ":label: df_example_1\n", + "\n", + "In dit voorbeeld moeten we element AB in twee delen opsplitsen omdat de verdeelde belasting een discontinuïteit veroorzaakt.\n", + "\n", + "Voor AC leidt dit tot:\n", + "\n", + "```{figure} intro_data/FBD_AC.svg\n", + ":align: center\n", + "\n", + "Vrijlichaamdiagram element AC\n", + "```\n", + "\n", + "Voor BC leidt dit tot:\n", + "\n", + "```{figure} intro_data/FBD_BC.svg\n", + ":align: center\n", + "\n", + "Vrijlichaamdiagram element BC\n", + "```\n", + "::::::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", + "\n", + "::::::{prf:example}\n", + ":nonumber: true\n", + ":label: df_example_3\n", + "\n", + "In dit voorbeeld is er enkel invloed door buiging, dus hebben we aan deze differentiaalvergelijking genoeg: $ -EI \\cfrac{{d}^4w}{{d}x^4} = -q_z$. De differentiaalvergelijkingen voor rek $ EA \\cfrac{{d}^2u}{{d}x^2} = -q_x$ en torsie $ GI \\cfrac{{d}^2\\varphi_x}{{d}x^2} = -q_T$ hebben we in dit geval niet nodig.\n", + "\n", + "**Element AC**\n", + "\n", + "Omdat dit element onbelast is, geeft de belastingsvergelijking voor dit element:\n", + "\n", + "$$q_{z,{\\rm{AC}}}=0$$\n", + "\n", + "wat leidt tot de vergelijkingen:\n", + "\n", + "$$ V_{\\rm{AC}} \\left(x\\right) = C_1$$\n", + "\n", + "$$ M_{\\rm{AC}} \\left(x\\right) = C_1 \\cdot x + C_2 $$\n", + "\n", + "$$ \\kappa_{\\rm{AC}} \\left(x\\right) = \\cfrac{C_1 \\cdot x + C_2}{5000}$$\n", + "\n", + "$$ \\varphi_{\\rm{AC}} \\left(x\\right) = \\cfrac{\\cfrac{1}{2}\\cdot C_1 \\cdot x^2 + C_2 \\cdot x}{5000} + C_3$$\n", + "\n", + "$$ w_{\\rm{AC}} \\left(x\\right) = \\cfrac{-\\cfrac{1}{6}\\cdot C_1 \\cdot x^3 - \\cfrac{1}{2} C_2 \\cdot x^2}{5000} - C_3 \\cdot x + C_4$$\n", + "\n", + "Vanwege de oplegging bij A kan een randvoorwaarde worden geformuleerd als:\n", + "\n", + "```{math}\n", + ":label: BC_1\n", + "w_{\\rm{AC}} \\left(0\\right) = 0\n", + "```\n", + "\n", + "Omdat A ook een onbelast uiteinde is, kan een andere randvoorwaarde worden geformuleerd als:\n", + "\n", + "```{math}\n", + ":label: BC_2\n", + "M_{\\rm{AC}} \\left(0\\right) = 0\n", + "```\n", + "\n", + "Als dit uiteinde belast werd kon met een krachten- of momentenevenwicht ook een relatie gevonden worden.\n", + "\n", + "**Element BC**\n", + "\n", + "Omdat dit element belast is, geeft de belastingsvergelijking voor dit element:\n", + "\n", + "$$q_{z,\\rm{BC}}=10$$\n", + "\n", + "wat leidt tot de vergelijkingen:\n", + "\n", + "$$ V_{\\rm{BC}} \\left(x\\right) = -10 \\cdot x + C_5$$\n", + "\n", + "$$ M_{\\rm{BC}} \\left(x\\right) = -5 \\cdot x^2 + C_5 \\cdot x + C_6 $$\n", + "\n", + "$$ \\kappa_{\\rm{BC}} \\left(x\\right) = \\cfrac{-5 \\cdot x^2 + C_5 \\cdot x + C_6}{5000}$$\n", + "\n", + "$$ \\varphi_{\\rm{BC}} \\left(x\\right) = \\cfrac{-\\cfrac{5}{3} \\cdot x^3 + \\cfrac{1}{2}\\cdot C_5 \\cdot x^2 + C_6 \\cdot x}{5000} + C_7$$\n", + "\n", + "$$ w_{\\rm{BC}} \\left(x\\right) = \\cfrac{\\cfrac{5}{12} \\cdot x^4 -\\cfrac{1}{6}\\cdot C_5 \\cdot x^3 - \\cfrac{1}{2} C_6 \\cdot x^2}{5000} - C_7 \\cdot x + C_8$$\n", + "\n", + "Vanwege de inklemming bij B kunnen twee randvoorwaarden direct worden geformuleerd:\n", + "\n", + "```{math}\n", + ":label: BC_3\n", + "\\varphi_{\\rm{BC}} \\left(4\\right) = 0\n", + "```\n", + "\n", + "```{math}\n", + ":label: BC_4\n", + "w_{\\rm{BC}} \\left(4\\right) = 0\n", + "```\n", + "\n", + "::::::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3. Er zijn nog meer vergelijkingen nodig om alle onbekende integratieconstantes op te lossen, deze kunnen we vinden door de overgangen tussen de verschillende elementen te analyseren waarbij zowel verplaatsingen als krachten in overeenstemming moeten zijn.\n", + "\n", + "::::::{prf:example}\n", + ":nonumber: true\n", + ":label: df_example_4\n", + "\n", + "Bij C kan een randvoorwaarde worden geïdentificeerd uit de consistentie van verplaatsingen: zowel de neerwaartse als rotatieverplaatsing moeten hetzelfde zijn als de neerwaartse en rotatieverplaatsing aan de linkerkant van element BE:\n", + "\n", + "```{math}\n", + ":label: BC_5\n", + "w_{\\rm{AC}} \\left(4\\right) = w_{\\rm{BC}} \\left(0\\right)\n", + "```\n", + "\n", + "```{math}\n", + ":label: BC_6\n", + "\\varphi_{\\rm{AC}} \\left(4\\right) = \\varphi_{\\rm{BC}} \\left(0 \\right)\n", + "```\n", + "\n", + "Ten slotte moet er ook consistentie zijn met de snedekrachten, zoals getoond in het vrijlichaamdiagram:\n", + "\n", + "```{figure} intro_data/FBD_C.svg\n", + ":align: center\n", + "\n", + "Vrijlichaamdiagram knoop C\n", + "```\n", + "\n", + "Verticaal evenwicht geeft:\n", + "\n", + "```{math}\n", + ":label: BC_7\n", + "\\sum {{{\\left. {{F_{\\rm{v}}}} \\right|}^{\\rm{C}}} = 0} \\to -{V_{\\rm{AC}}}\\left(4\\right) + V_{\\rm{BC}}\\left(0\\right) = 0\n", + "```\n", + "\n", + "Momentevenwicht geeft:\n", + "\n", + "```{math}\n", + ":label: BC_8\n", + "\\sum {{{\\left. {{T}} \\right|}_{\\rm{C}}^{\\rm{C}}} = 0} \\to -{M_{{\\rm{AC}}}}\\left(4\\right) + M_{\\rm{BC}}\\left(0\\right) = 0\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4. Er zijn nu evenveel vergelijkingen als onbekenden opgesteld. Deze kunnen nu worden opgelost en ingevuld in de opgestelde vergelijkingen voor het gewenste resultaat. Omdat het aantal onbekenden bij statisch onbepaalde constructies als snel uit de hand loopt wordt wordt aangeraden om je rekenmachine of een symbolische wiskundetool te gebruiken om dit op te lossen. Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python. Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt:\n", + "\n", + "\n", + "::::::{codex-start}\n", + ":nonumber: true\n", + ":label: df_example_5\n", + "\n", + "::::::\n", + "\n", + "Er zijn 8 randvoorwaarden geformuleerd met 8 integratieconstanten. Deze kunnen nu worden opgelost. \n", + "\n", + "Het invullen van de randvoorwaarden geeft:\n", + "\n", + "$$\n", + "\\begin{align}\n", + "C_{4} = 0 \\\\\n", + "C_{2} = 0 \\\\\n", + "- \\cfrac{4 C_{5}}{1875} - \\cfrac{C_{6}}{625} - 4 C_{7} + C_{8} + \\cfrac{8}{375} = 0 \\\\\n", + "\\cfrac{C_{5}}{625} + \\cfrac{C_{6}}{1250} + C_{7} - \\cfrac{8}{375} = 0 \\\\\n", + "- \\cfrac{4 C_{1}}{1875} - \\cfrac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0 \\\\\n", + "\\cfrac{C_{1}}{625} + \\cfrac{C_{2}}{1250} + C_{3} - C_{7} = 0 \\\\\n", + "4 C_{1} + C_{2} - C_{6} = 0 \\\\\n", + "C_{1} - C_{5} = 0 \\\\\n", + "\\end{align}\n", + "$$\n", + "\n", + "Het oplossen hiervan geeft:\n", + "\n", + "$$\n", + "\\begin{align}\n", + "C_{1} = \\cfrac{35}{8} = 4.375 \\\\\n", + "C_{2} = 0 \\\\\n", + "C_{3} = - \\cfrac{1}{150} \\approx -0.006667 \\\\\n", + "C_{4} = 0 \\\\\n", + "C_{5} = \\cfrac{35}{8} = 4.375\\\\\n", + "C_{6} = \\cfrac{35}{2} = 17.5 \\\\\n", + "C_{7} = \\cfrac{1}{3000} \\approx 0.0003333\\\\\n", + "C_{8} = \\cfrac{13}{750} \\approx 0.01733\n", + "\\end{align}\n", + "$$\n", + "\n", + "Nu is de volledige krachtenverdeling en verplaatsingen van de constructie opgelost. Bijvoorbeeld de momentenverdeling in BC die kan worden uitgezet als:\n", + "\n", + "```{figure} intro_data/Momentenlijn.svg\n", + ":align: center\n", + "\n", + "Momentenlijn BC\n", + "```\n", + "\n", + "De krachtsverdeling en verplaatsingen kunnen no ook \n", + "\n", + "**Oplossen met digitale hulpmiddelen**\n", + "Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python.\n", + "\n", + "\n", + "$$\\left[\\begin{array}{cccccccc}0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & - \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1\\\\0 & 0 & 0 & 0 & \\frac{1}{625} & \\frac{1}{1250} & 1 & 0\\\\- \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1 & 0 & 0 & 0 & -1\\\\\\frac{1}{625} & \\frac{1}{1250} & 1 & 0 & 0 & 0 & -1 & 0\\\\4 & 1 & 0 & 0 & 0 & -1 & 0 & 0\\\\1 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\end{array}\\right] \\left[ \\begin{array}{cccccccc} C_1\\\\C_2\\\\C_3\\\\C_4\\\\C_5\\\\C_6\\\\C_7\\\\C_8 \\end{array} \\right] = \\left[\\begin{matrix}0\\\\0\\\\- \\frac{8}{375}\\\\\\frac{8}{375}\\\\0\\\\0\\\\0\\\\0\\end{matrix}\\right]$$\n", + "\n", + "[Hier](rref_ti_84) is uitgelegd hoe je dit op een grafische rekenmachine kan oplossen.\n", + "\n", + "Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt.\n", + "\n", + "Beide opties zijn hieronder getoond" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAASCAYAAADomNYKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAs9JREFUeJzl102o1FUYx/HPaEh2q3sxCgKtqNRdS7tgQi8g0SZXLgLBCiEsYnITFPTwBLqMUBRq0S2iVhEGtRF6WVTULktLbwTtgsDK6nbpzXFxztTcaeY2M3eGS/SF4YHznJfn9z/nPOeZRqvV0ovM3IwHsBPXYQY/4CRex4sR8UvPwatEZm7E07gbV+EbHEdGxPftfo1u0ZnZQOJxrMOH+BTncb3yETbg/YjYMWkhg5KZNymxXoM3cAbbcAfOYntEnINLeox/AXvxOe6LiJNdk6/HAdw8ofhH5Zgi+NGIONJuzMxn8BgO4iFY0zkqMw8ogr/AbLdgiIjFiDiI/ZOKflgy80blBH6No13uwAL2ZOYUHaIz81rla/yB3RHx03ILRcTi+MJeMXdWeyIiLnQ6qo4PcBlmWXq8m7gUcxFxatJRZmZTSY6D8klEHO/j21rtfB//l8pJ2IK3O0XvqvblIQJZCU0lMQ7KS0om7sV0tef7+NvtM9SdzszLla/QwsdDBPIXmfmEcj2ORsQj/9Y/Im4YZZ0RaVTb4u87fXW1P47y9mbmLPYpT9tq0N7J6T7+Kzv7tY/3QrXrM3NtRPw56GqZOY1X8CCeGmJc0/ju9Nlqt/Txb652nrrTEfGtku7X4fblVs7MNV1Nz+O1iHhnuXE9aCrPyaC/XcvM9W61O7vjy8wrsB2L+Iil2fvZ+juWmfdGxJmuwQ2lvLsfu2vbPqVI2TOw1Mo473REfJWZJ5QM/TCOdLgTU3guIhZYKvowblHq7c/qJPP4HZtwGzbiVcjMrTiEHRHx27gErID9Shl6ODPvUgqsW5UydB5Ptjv2qr3vUZLSNiXB/awU7qfxFt6MiHOZuRdz6Lz/a5UMeQFTEfHrBMT1JTM36f+H47t2v3+IHmKBGWXnO5lTCoFDOB0Ro00+YUYW3YvMfA+nBnmnV5PuTPy/YKw7/V/hImUh8qiSnFTZAAAAAElFTkSuQmCC", + "text/latex": [ + "$\\displaystyle C_{4} = 0$" + ], + "text/plain": [ + "C₄ = 0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAASCAYAAADomNYKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAt9JREFUeJzV10+IVXUUB/DPTBGZmWIYBFpSaruWJZmRBSZtkhYGkZBBUAoxSRDS4nACV1HISANt+kPQMoxqIw1tKmqn/TGdCNwFQX+smYbIei1+99ad17vje773kL5wObx7fud3zvf3O+e8cyc6nY5eyMzNeAw7cQPW4GecxNt4PSJ+62l8iZCZ6/E8duFafIdjyIj4qV430U06MyeQeBZX4BN8jnO4UTmEtfgoIraPm0i/yMyblVivwzs4jduwA2ewLSJ+gMt72L+KR3EKD0fEya7NV+AgNo0p/ovFjEL4qYg4Wr/MzJfwNA7jCZhsWmXmQYXw19jaTRgiYjEiDmP/uKIfFJl5k5KBZ/FylzqwgL2ZuZIG6cy8XjmN89gTEb8u5ygiFkcX9tC4p5LHI+KvpqLi8TGuwlaWpvcUrsRrEfHluKPMzCmlOfaLExFxrEV3SyXnWvTfKJmwBbNN0rsr+eYAgQyDKaUx9os3lE7cC6srea5FX79fQ3XTmXm1cgodfNZvFJl5CA8qJ/07PsWhfjIlIjb262cEmKhkh39rel0lfxnwv/dupWveodTVeXyQmWuHj3Mg1De5ukV/TXNdnd4LlVyRmZdFxJ/9eIqI+5q/M3NvtfE2vLuc7Yhr+kwlt7ToN1dyjop0RHyfmWexUbm92TbPmTnZ3SEbWKVkz49t9g1MGV1Nf1jJnd3xZeYq5RIWlfJb0r2PVM9MZj4QEaebu1aT2i7sw54W50dwot58OYyypiPi28w8rnToAzjaUCdW4pWIWGAp6WncqszbX1SbzOEPbMCdWI+3ejnOzBdwF7b3Wx4jxn5lDJ3OzHuVAet2ZQydw3P1wl6z9/14XJlb12FeGdy/wvt4r55hGzYv4hHsiIhT4+F0YWTmBu0fHP+U3H9IX4SjaTzkEhMeBEORzswZ5YZ3Kx8oNeYjYn640MaHyQsvWRZPKh17Vkml+nlmyH3HiqHT+/+IvwHtQ/pzJbnwjAAAAABJRU5ErkJggg==", + "text/latex": [ + "$\\displaystyle C_{2} = 0$" + ], + "text/plain": [ + "C₂ = 0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle - \\frac{4 C_{5}}{1875} - \\frac{C_{6}}{625} - 4 C_{7} + C_{8} + \\frac{8}{375} = 0$" + ], + "text/plain": [ + " 4⋅C₅ C₆ 8 \n", + "- ──── - ─── - 4⋅C₇ + C₈ + ─── = 0\n", + " 1875 625 375 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\frac{C_{5}}{625} + \\frac{C_{6}}{1250} + C_{7} - \\frac{8}{375} = 0$" + ], + "text/plain": [ + "C₅ C₆ 8 \n", + "─── + ──── + C₇ - ─── = 0\n", + "625 1250 375 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle - \\frac{4 C_{1}}{1875} - \\frac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0$" + ], + "text/plain": [ + " 4⋅C₁ C₂ \n", + "- ──── - ─── - 4⋅C₃ + C₄ - C₈ = 0\n", + " 1875 625 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAATQAAAAUCAYAAAADWsEdAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAACUVJREFUeJztnH+wVVUVxz9PiHCQYLIUJw3E0H5o4SghGgiiqDHleyQ2GgREFkZDL7QR0lp8LdPGzBcm2UzDjyxnmtRwCsgf8ZKKyn4MP8SUVF7mQBgiBIqZSH+sfeG+wzn33XPvOYdH3e/MnX3vOWfvvc53r7PP2mutfZv27dtHHCQNAT4BjAPeDvQHdgBrgfuAxWb2cmzlCpB0LLAZuMPMZkXOjQRagbOBNwPbgfVAm5ktD9ccDbQA44HTgLcBr4brFgGLzOz1mH47gIEJYm01swFp7yVL5MV3aPsgziVdCpwLDAXeB/QFfmhmk2LqF8q5pOOBG4CLgKOBLcBSQGb2YjX3nBfyHKcicLjKX61O9Iyp2AQIuBboBawG7gF24so5DhgLXA6MrEG2S4AjgJ9E+r0e+AqwDfhZEPgtwOnAaGB5uHQi8J1wvh14FjgWmAB8D7hY0kQzi5updwJtMcd313AfmaAAviGe8+vxiWw38Bzwzgr1C+Nc0kk4B8cA9wNPAO8HPgdcJOkcM3uhgqy5oKBxyg2Hs/xpdOKgCQ1YCEwFHgeuMLO1kcaPBGYD76hRvhbgBWBVWZsT8cnsYWCCme2K9PmGsp8bgQ8Dy8qtAklfBB4FPoI/aPfG9L3DzObVKHcsJE3FrZQxZvbLGprIm2+I4Rz4PD6RPYVbau0V6hfJ+QJccWeZ2e1lfX0zyHwjMCNFe1mMERQzTnnicJa/ap3oNKFJmo3f9F+As6ITC4CZ7QFuDASkgqR+wHnA3Wa2Nxw7Avg68DJOdFyf/yn7vjKubTP7h6Q7w82NJv7h6lbIm+/Qx0Gch3bby66p2EZRnEsajFsKHcAd0e6ATwGTJV1tZi/V01dKuXIfpzxxOMufVid6llU8DlfM14DL4m66U0tOQFqMx83d+8qOnQ2ciJu/L0oaD5wKvAI8ama/TdF+aeJ7LeH8GyVNwn0HLwHrgFXlD3pRKIhviOc8S2TJ+XmhfDDqkzOzXZJ+gyv3WcAv6pa8ChQ4TrngcJeflDpRbqG1Ar1xB+9jOQnXgiv1Q2XHhoVyK/Bn3Om8H5JWAZea2T8rNSypJ/Dx8PPnCZcNAO6KHNskaZqZPdK1+Jmilfz5hnjOM0EOnJ8Syo0Jbf0VV96TKWhCo7hxygutFCi/pFY80FAt1pjZ0grnU+lE+YTWHMqo8mUCSb3xCMUKM3ul7NQxoZwBbALOB36POypvBS4EfowvaSrhZtyyW25mD8ScXwT8CtgA7AIGA5/FTdYVkkZE/Qo5ozmUufANFTnPCllz3i+UOxP6Kx3vX6fcadAcytzGKWc0h7Io+VtJjmzHYQkerUxCKp3oCSDpKHyG24dPJlVB0ijgC8AZwHHARDO7J+HyccBRRKKbQI9QNuGWWEnBN0hqwWfmc4Pyxy4/Jc0CrsajH5PjrjGzqKPoMWCGpN2h7jzcmklEF2kI7TG+qCVmNjWmnZr4DnXn4g74U4B/A78D5ia8fZM4rxtFcR5BUyjjc43IboxCW/WM00zg08CgcGgD8FUzW9ZFvQ7STQixqTahrXrkT5JjgZnNTKpnZoPS9JMBOulEyUJ7ayj/lTIHpQ+ev7KIrh3CLXjuUnRASzkkz0QtJDPbI+kBYDoepj1oQguK8y08ejPWzLankB/gTvzhGlXFtW0cbB0MxdMiluCOy3KsSWinVr7BLdUFwB/wwbwBeFjSu2PuPYnzupAj56W3bT/i8abIdXFoI5sxgvrG6TlgDr4kagKmAEslnWFm6yrUexr3H1eLzRXO1SP/MA4YG+CW+EP4aqlIpNKJ0oRWihgdKalHtU5yM1sBrIDKkTJJPYAPASvNLKqMT4ZyR0L10oR3UPQlrNdvw9/8Y83s+WrkjqBUp09XF5pZW4wMU/GHZXGKlICa+A4yXBjpfzI+mOcAPy07XonzmpEz5yVdODmh3pBQJvlTshwjqG+c7o8cuk7SVcAIPDCSVG9sCvm6Qj3yd/JZS5qDT7YVfc05+NBS6cQRAEEpO/Bo2OhKvYc0i7QYhWf3xi19VuERmCGSesWcPzWUHRE5rsUfrDV4flEtDxa4ggE8U2P91MiY7774OEatpEqc14QCOC+lkoyL3rekvvikvQdfZueOrMZJUg9Jl+PL/9UZilgRGcrfC5gELExIni5HK55OUe2nuYv2UulEeVCgLXwWSLrEzJ6IVG7CHczTgMu6ECKKCcDreJZvJ5jZNkk/Aj4GfBnPYC/1eQEeFNhJWRRN0pfwpdafgHFdLXkkvQfYEr1O0kDg2+HnD1LeU71oIxu+2/AJJvqQJ3JeC4rg3MyelvQg7vubCdxeXhW36L5bZA4adYyTpNNwN0lvPCjSbGbrC5C5HG3Ur2fNuNW1uKvOsvahpdWJ8gltPvBefJ/X+tDIRjzP6ATgA8DxwN01yNUMrDazrQnnZwPDcbN8FJ59PhD3Ae0FrjSzHQCSpuAP1l48gjYrZrnbYWaLy35PBOZIascjqbuAk/Acrd74tqpv1HBf9aBuviXdgltiI2OWE81U4FxSMwfejqU9lSMkLQ7ft5nZNeHaIjn/DG7FzJc0Fk8GHQ6Mwfm5Lu5+ckQ94/Qk7r/rj++m+L6k0QWnf2TxXE/HI+WV/HV5omqd2D+hBVNyuqR7gStxJ/wF+J67LfibZhm+z7JqSBqGE3Zb0jVm9ryk4bh11oInye0K/d1kZuXWx4mh7IGbt3F4hM5vk3Y8Kng6vtzpg/vsfo2Hs++qwpTOFPXyLelWfBkwxsyeipzrknP8QZsSOTY4fAD+BlwTvhfGeXgjn8mBjcgfxPmYj29EThuAqAv1jJOZvYpvLQP4YxiXVuCT+Uu+X4Z69Wwgnko1oRCBY5BGJ5qS/m0jLSTtIyZtQ9LXgLnAYDPblEln/+eQNB/4KD6ZPR5zvsF5N4SklcDmpDSL7ghJ8/D0kxPMLGk3SLdB3Ob0qhHyXMo3sw6SNBTYbmbPhmMtwNrGg5UNJC3ALbNmYLuk0nJxt5mV/sGiwfkhhqSbccvn73jg5grcMT/+EIqVCsEJPw3P1ev2kxnUOaEBZ9L5XxpuCeUSfDMsZvauOvtooDOuCmV064/wRNUG590DA/CgxwA8qLUOuDhhR0V3xfn4HtyFh1qQapHZkrOBBhpo4FCjlpyyBhpooIFuicaE1kADDfzP4L+nwvob2OmQoQAAAABJRU5ErkJggg==", + "text/latex": [ + "$\\displaystyle \\frac{C_{1}}{625} + \\frac{C_{2}}{1250} + C_{3} - C_{7} = 0$" + ], + "text/plain": [ + "C₁ C₂ \n", + "─── + ──── + C₃ - C₇ = 0\n", + "625 1250 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKoAAAAUCAYAAAAdtqaHAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAABSNJREFUeJztmmuoVUUYhp9jIpmaQhQIWqFp5A8pMjO8kB5QqR8eioxCRbtAqdjJbmjY62cYgVhHJSG01CQhsDAKBFG0sDQkVDKzk5L4I8HQsjSVLrsf36zarc5ae+3bWUfYDyxm77m+s5j5Zuab1VQoFEjCzKYD74S/j0tam5J3CPAIMBG4HugH/AwcBD4A1kv6LbGxnGnozwczGwAsASYD1wAngS2ASfopytc9pYKBwCrgHNA7JV8TYMALQA/gc2AzcBa4AX9xzcBDwNgq+lQXGvrzw8wG43qvAz4EjgAjgaeAyWY2WtJpSBioofPrgNP4bHw2pb23gZnAYeBhSQdjdfUE5gM3Vd6lZMxsZtA6XtKuCqrIVX8NuJz1r8YH6TxJq6JIM3sNeBpYCjwB0C2hgnnABGAWcD6pFTObj7+kb4BR8ZcEIOmCpKXA7Ep6Uk8a+vPDzAbh1v448EYsWfi4m25mvaCDgWpmtwCvAiskfZrSUH98xP8BTJX0a5owSReyd6P+NPTnzoQQbpP0V3FC6MtnwFXAKIgt/WbWHdgInAAWlmioFbgSWCfpUNWyO59WGvozY2at+AEtKwckbUlJvzmE7Qnp3+EWdyiwI75HfQm4DRiTYQa2hHBjiXxdlZYQNvRnoxU/nGVlA356T6JvCM8mpEfx/aDIoprZSNyKLpe0J02BmfXGR3oB+KKU4ljZccBzwO1Af+ABSZszlj1O8svaaWbxuA2SZnZQTzX6FwD34RbhErAXWJDFqpXQ3xHvSprWQT0V6w/l++Pbu3twj85RYK6kT5LKSLqx3HaqpCmEBQgDtWjJbwcWZajk2hD+UoFvrhfu21sHvF9m2Tb+v/zcCkzBZ/DxWNqBhHqq0X83flrdh7/MJcB2Mxsm6UyJsseAi2W09UNCfMX6zawfvv/bDdwL/AgMAk6VU08NiCxm34T0q4vzRRY1mqEAFzuwTABrzGwNsAJ4JcT1NLMrJP2ZVZ2krcBWgIR20sq2xeOCe2oK7tDelbGqyJNRif5Jsfan4y9zNPBRibLNWdspQcX6geeBk5JmFMV9X6pQHfao34ZwaEL6kBC2w7+n/kvAWwnP/pBnd/i/R9Ip3Hr1wC1MImaW5ALLjRrr74O/x1LWtGZUqb8F2Gtmm8zslJkdMLO5wXeeRivuNsr6tJSob2cIJ8Y1mlkffOJfwLdWblHDwemxhI4uxg9YG2JXqG3hWW1mUyQdiZVrwq/FZgFTS4jOgzZqo78N32LsrYfIEu22Ub7+QcAc4HVgEr51WoXvBeP+zH+o9R5V0jEz24af7OcEDRGGbxHflHQeUq5QM7ASGI7fL38VGm0HfgcGAmOAAcCmKtqoJ1XrN7NlwDhgbJnLby2oVH834EtJC8L//WY2FB8siQO1TszGr1BXmlkzfnFxJzAe78uLUcaKl2VJBUmP4hvyj/GZOQe3zMOBPfitybxK26gn1eo3s+XADKBZ0tFOkPwfqtB/Evg6FneY8rwRNUHSMWAEsB4foM8Ag/FJeFd0zw/QlPb1VL0xswJluKe6Cma2EngQ/77gcN56ysHMNgEDJY0tinsZuF/SsPyUpdPpAzX4AKMPJPbjPtXtwBlJJzpVTAWY2WpgGn5YKB6k5ySdy0VUGZjZHfhyuxh4Dz9/rAUWSurspT8zeZzIR+ADNPImLAu/l+SgpRKexE/6O/BlNHrSvjDrMkjah0+yqcAh/HuBRbhvuMuS69LfoEFWupyPs0GDjmgM1AaXBX8Db+ZLKnj2sa4AAAAASUVORK5CYII=", + "text/latex": [ + "$\\displaystyle 4 C_{1} + C_{2} - C_{6} = 0$" + ], + "text/plain": [ + "4⋅C₁ + C₂ - C₆ = 0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAG4AAAAUCAYAAABs4ghcAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAA6lJREFUeJztmV2IVGUYx3+zimhWCn0KWy2adhGEkNSGFdWCCF20NwlFQqUXYmCTEhEh//6CV4aIktFNukR5Y2EUCEJ4VZt3iWF+sPkBfZOlohukTRfve7az48x4zsyZ2R3YHxwezvv5f+Y57+eUKpUKtbC9EHgZWAbcDcwF/gIOA58CuyVdrll5gulW7bZ7gU3AcuAW4GdgH2BJf6bLTq9RuQQYeAOYAXwN7AXOA/cQfowB4DngsXY50Qxdrn0BQe/twGfAMeAh4FVgue2lkv5Iyl8TOOAD4EXgKPC8pMNVHcwC1gP3tsOBFulm7TsJQVsnaUeSaHsr8BqwGViTpPeka9peT3D8e6C/2nEASaOSNgNr26G+Wbpc+3zCbHAaeLcqW8AlYKXt2UliT6ryPEJUrwArJF1s1Jmk0WJkt043a488Fe0BSf+mM6IvXwE3AP1JenqqLAMzgV2SvmuvzsIp02HttsuETU9WvpW0r07efdGeqJN/kjAiFwFfwvjADUb7YQ4xk4XBaDupvUzY8GRliLBDrMWcaM/XyU/S5yYJ0wFs30iIZgU4lFWJ7ceB14EHgXnAs5L2Zqx7mnyOfyTphRrtNKU91n2bsIak+VXSnderK6kvT18tUop27OyWjLjbor2Q83wzm3A22gV8klPMCPB3jvI/1UlvVnvCceCJ1PvVJtpolWREzamTf3NVubHAXYp2lu1pkjKJl7Qf2A9gO5dSSQO5KtSnKe0prkj6JW+nBa9xx6NdVCd/YbRja2APgKTfCFvRGYz/+q7Bdk+j/E5TgPb5tn+0fcr2Htt9GbsuE6bZrM9gg7YORrusWqPtm4ClwCjwTZKe3pxsi89O289IOlbVQIlwFfMSsCKjc51iG81pPwSsJHzJdwBvAsO275d0rlGHRa5xkkZsHyDsHF8BdqSyTViS3peUzC7jArcdeIBwx3ckNnQC+Ae4C3gU6AU+LkpwgTSlPU71CUdsDwM/EA7yW9svexxrCVde220PEC4SHgaeJPjyVrrw2LCUVJG0Cnga+AJYTIj+asKPMkxwaF27PchLUdrjF32U/9eUjiFpBFgC7CYEbAOwgPBRPpK+pwQo1ft3IC+2K+Q4DkxGbM8ETgHvSdo00XoaUeuSOTPxDJW+sO2zvRg4J+lsK213AtvvAJ8DZwkXvBsJ68nQROrKQkuBIwztg6n3LdEOEaamyU4vsAe4FfidsGvrl3RmQlVloLCpcorOMqnOZFNkZypwXcp/TvVqwtp6oi4AAAAASUVORK5CYII=", + "text/latex": [ + "$\\displaystyle C_{1} - C_{5} = 0$" + ], + "text/plain": [ + "C₁ - C₅ = 0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "C_{4} = 0\n", + "C_{2} = 0\n", + "- \\frac{4 C_{5}}{1875} - \\frac{C_{6}}{625} - 4 C_{7} + C_{8} + \\frac{8}{375} = 0\n", + "\\frac{C_{5}}{625} + \\frac{C_{6}}{1250} + C_{7} - \\frac{8}{375} = 0\n", + "- \\frac{4 C_{1}}{1875} - \\frac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0\n", + "\\frac{C_{1}}{625} + \\frac{C_{2}}{1250} + C_{3} - C_{7} = 0\n", + "4 C_{1} + C_{2} - C_{6} = 0\n", + "C_{1} - C_{5} = 0\n" + ] + } + ], + "source": [ + "import sympy as sym\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "%config InlineBackend.figure_formats = ['svg']\n", + "sym.init_printing()\n", + "\n", + "x = sym.symbols('x')\n", + "\n", + "q = 10 \n", + "EI = 5000 \n", + "EA = 20000 \n", + "F = 150\n", + "\n", + "q_AC = 0\n", + "q_BC = q\n", + "\n", + "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", + "C_5, C_6, C_7, C_8 = sym.symbols('C_5 C_6 C_7 C_8')\n", + "\n", + "V_AC = -sym.integrate(q_AC, x) + C_1\n", + "M_AC = sym.integrate(V_AC, x) + C_2\n", + "kappa_AC = M_AC/EI\n", + "phi_AC = sym.integrate(kappa_AC, x) + C_3\n", + "w_AC = -sym.integrate(phi_AC, x) + C_4\n", + "\n", + "V_BC = -sym.integrate(q_BC, x) + C_5\n", + "M_BC = sym.integrate(V_BC, x) + C_6\n", + "kappa_BC = M_BC/EI\n", + "phi_BC = sym.integrate(kappa_BC, x) + C_7\n", + "w_BC = -sym.integrate(phi_BC, x) + C_8\n", + "\n", + "eq1 = sym.Eq(w_AC.subs(x,0),0)\n", + "eq2 = sym.Eq(M_AC.subs(x,0),0)\n", + "eq3 = sym.Eq(w_BC.subs(x,4),0)\n", + "eq4 = sym.Eq(phi_BC.subs(x,4),0)\n", + "eq5 = sym.Eq(w_AC.subs(x,4)-w_BC.subs(x,0),0)\n", + "eq6 = sym.Eq(phi_AC.subs(x,4)-phi_BC.subs(x,0),0)\n", + "eq7 = sym.Eq(M_AC.subs(x,4) - M_BC.subs(x,0),0)\n", + "eq8 = sym.Eq(V_AC.subs(x,4) - V_BC.subs(x,0),0)\n", + "\n", + "display(eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8)\n", + "for eq in [eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8]:\n", + " print(sym.latex(eq))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\left\\{ C_{1} : \\frac{35}{8}, \\ C_{2} : 0, \\ C_{3} : - \\frac{1}{150}, \\ C_{4} : 0, \\ C_{5} : \\frac{35}{8}, \\ C_{6} : \\frac{35}{2}, \\ C_{7} : \\frac{1}{3000}, \\ C_{8} : \\frac{13}{750}\\right\\}$" + ], + "text/plain": [ + "⎧ 13 ⎫\n", + "⎨C₁: 35/8, C₂: 0, C₃: -1/150, C₄: 0, C₅: 35/8, C₆: 35/2, C₇: 1/3000, C₈: ───⎬\n", + "⎩ 750⎭" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'\\\\left\\\\{ C_{1} : \\\\frac{35}{8}, \\\\ C_{2} : 0, \\\\ C_{3} : - \\\\frac{1}{150}, \\\\ C_{4} : 0, \\\\ C_{5} : \\\\frac{35}{8}, \\\\ C_{6} : \\\\frac{35}{2}, \\\\ C_{7} : \\\\frac{1}{3000}, \\\\ C_{8} : \\\\frac{13}{750}\\\\right\\\\}'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sol = sym.solve([eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8],(C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", + "display(sol)\n", + "sym.latex(sol)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " 2025-07-02T16:58:07.214407\n", + " image/svg+xml\n", + " \n", + " \n", + " Matplotlib v3.10.3, https://matplotlib.org/\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ], + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "M_numpy = sym.lambdify(x, M_BC.subs(sol))\n", + "x_numpy = np.linspace(0,4,100)\n", + "plt.figure()\n", + "plt.plot(x_numpy,M_numpy(x_numpy))\n", + "plt.xlabel('$x$')\n", + "plt.ylabel('$M_{BC}$');\n", + "ax = plt.gca()\n", + "ax.spines['right'].set_color('none')\n", + "ax.spines['top'].set_color('none')\n", + "ax.spines['bottom'].set_position('zero')\n", + "ax.spines['left'].set_position('zero')\n", + "ax.invert_yaxis()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\\left[\\begin{matrix}0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & - \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1\\\\0 & 0 & 0 & 0 & \\frac{1}{625} & \\frac{1}{1250} & 1 & 0\\\\- \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1 & 0 & 0 & 0 & -1\\\\\\frac{1}{625} & \\frac{1}{1250} & 1 & 0 & 0 & 0 & -1 & 0\\\\4 & 1 & 0 & 0 & 0 & -1 & 0 & 0\\\\1 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\end{matrix}\\right]\n", + "\\left[\\begin{matrix}0\\\\0\\\\- \\frac{8}{375}\\\\\\frac{8}{375}\\\\0\\\\0\\\\0\\\\0\\end{matrix}\\right]\n" + ] + } + ], + "source": [ + "A,b = sym.linear_eq_to_matrix((eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8), (C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", + "print(sym.latex(A))\n", + "print(sym.latex(b))\n", + "A = np.array(A).astype(np.float64)\n", + "b = np.array(b).astype(np.float64)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "A = np.array([\n", + " [0, 0, 0, 1, 0, 0, 0, 0],\n", + " [0, 1, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, -4/1875, -1/625, -4, 1],\n", + " [0, 0, 0, 0, 1/625, 1/1250, 1, 0],\n", + " [-4/1875, -1/625, -4, 1, 0, 0, 0, -1],\n", + " [1/625, 1/1250, 1, 0, 0, 0, -1, 0],\n", + " [4, 1, 0, 0, 0, -1, 0, 0],\n", + " [1, 0, 0, 0, -1, 0, 0, 0]\n", + "])\n", + "\n", + "b = np.array([\n", + " 0,\n", + " 0,\n", + " -8/375,\n", + " 8/375,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0\n", + "])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 4.37500000e+00],\n", + " [ 0.00000000e+00],\n", + " [-6.66666667e-03],\n", + " [ 0.00000000e+00],\n", + " [ 4.37500000e+00],\n", + " [ 1.75000000e+01],\n", + " [ 3.33333333e-04],\n", + " [ 1.73333333e-02]])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linalg.solve(A,b)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}4.375\\\\0\\\\-0.00666666666666667\\\\0\\\\4.375\\\\17.5\\\\0.000333333333333334\\\\0.0173333333333333\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[ 4.375],\n", + "[ 0],\n", + "[-0.00666666666666667],\n", + "[ 0],\n", + "[ 4.375],\n", + "[ 17.5],\n", + "[0.000333333333333334],\n", + "[ 0.0173333333333333]])" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\\left[\\begin{matrix}4.375\\\\0\\\\-0.00666666666666667\\\\0\\\\4.375\\\\17.5\\\\0.000333333333333334\\\\0.0173333333333333\\end{matrix}\\right]\n", + "\\left[\\begin{matrix}1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 4.375\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -0.00666666666666667\\\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 4.375\\\\0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 17.5\\\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0.000333333333333334\\\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0.0173333333333333\\end{matrix}\\right]\n" + ] + } + ], + "source": [ + "import sympy as sym\n", + "\n", + "A_sym = sym.Matrix(A)\n", + "b_sym = sym.Matrix(b)\n", + "\n", + "sol_sym = A_sym.LUsolve(b_sym)\n", + "\n", + "display(sol_sym)\n", + "\n", + "print(sym.latex(sol_sym))\n", + "\n", + "identity = sym.eye(sol_sym.rows)\n", + "rr_augmented = identity.row_join(sol_sym)\n", + "print(sym.latex(rr_augmented))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "C_1 = 35/8 ≈ 4.37500000000000\n", + "C_2 = 0 ≈ 0\n", + "C_3 = -1/150 ≈ -0.00666666666666667\n", + "C_4 = 0 ≈ 0\n", + "C_5 = 35/8 ≈ 4.37500000000000\n", + "C_6 = 35/2 ≈ 17.5000000000000\n", + "C_7 = 1/3000 ≈ 0.000333333333333333\n", + "C_8 = 13/750 ≈ 0.0173333333333333\n" + ] + } + ], + "source": [ + "import sympy as sym\n", + "sym.init_printing()\n", + "\n", + "x = sym.symbols('x')\n", + "\n", + "q = 10 \n", + "EI = 5000 \n", + "EA = 20000 \n", + "F = 150\n", + "\n", + "q_AC = 0\n", + "q_BC = q\n", + "\n", + "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", + "C_5, C_6, C_7, C_8 = sym.symbols('C_5 C_6 C_7 C_8')\n", + "\n", + "V_AC = -sym.integrate(q_AC, x) + C_1\n", + "M_AC = sym.integrate(V_AC, x) + C_2\n", + "kappa_AC = M_AC/EI\n", + "phi_AC = sym.integrate(kappa_AC, x) + C_3\n", + "w_AC = -sym.integrate(phi_AC, x) + C_4\n", + "\n", + "V_BC = -sym.integrate(q_BC, x) + C_5\n", + "M_BC = sym.integrate(V_BC, x) + C_6\n", + "kappa_BC = M_BC/EI\n", + "phi_BC = sym.integrate(kappa_BC, x) + C_7\n", + "w_BC = -sym.integrate(phi_BC, x) + C_8\n", + "\n", + "eq1 = sym.Eq(w_AC.subs(x,0),0)\n", + "eq2 = sym.Eq(M_AC.subs(x,0),0)\n", + "eq3 = sym.Eq(w_BC.subs(x,4),0)\n", + "eq4 = sym.Eq(phi_BC.subs(x,4),0)\n", + "eq5 = sym.Eq(w_AC.subs(x,4)-w_BC.subs(x,0),0)\n", + "eq6 = sym.Eq(phi_AC.subs(x,4)-phi_BC.subs(x,0),0)\n", + "eq7 = sym.Eq(M_AC.subs(x,4) - M_BC.subs(x,0),0)\n", + "eq8 = sym.Eq(V_AC.subs(x,4) - V_BC.subs(x,0),0)\n", + "\n", + "sol = sym.solve([eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8],(C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", + "for k, v in sol.items():\n", + " print(f\"{k} = {v} ≈ {v.evalf()}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "::::::{codex-end}\n", + "::::::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Meer voorbeelden\n", + "Het voorbeeld in hoofdstuk 2.7.3 van het boek Mechanica, spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013` richt zich op extensie. Voorbeeld 3b in hoofdstuk 8.2 is een buigingsprobleem.\n", + "\n", + "## Instructies in collegevorm\n", + "\n", + "Dit onderwerp is [in les 3](https://collegerama.tudelft.nl/Mediasite/Channel/public-ceg-ctb2210/watch/757766716fcb45718fca678dadaa396d1d?sortBy=most-recent) gepresenteerd in collegevorm van 0:40:00 tot 0:48:30\n", + "\n", + "## Opgaves\n", + "\n", + "- Opgaves 2.48 en 2.50 in hoofdstuk 2.9 van het boek Mechanica: spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013`, antwoorden zijn beschikbaar op [deze website](https://icozct.tudelft.nl/TUD_CT/boekantwoorden/vol2/Chapter2/).\n", + "- Opgaves 8.7, 8.10, 8.11 in hoofdstuk 8.6 van het boek Mechanica: spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013`, antwoorden zijn beschikbaar op [deze website](https://icozct.tudelft.nl/TUD_CT/boekantwoorden/vol2/Chapter8/)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/instructie_2.ipynb b/book/instructie_2.ipynb new file mode 100644 index 0000000..4b1a93d --- /dev/null +++ b/book/instructie_2.ipynb @@ -0,0 +1,1470 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "````{margin}\n", + "```{attributiongrey} Attribution\n", + ":class: attribution\n", + "\n", + "Deze pagina is aangepast van https://github.com/TUDelft-books/CT1000/blob/2025/book/week_2/session_1/intro.ipynb\n", + "\n", + "% Figures from https://github.com/TUDelft-books/CT1000/blob/2025/book/week_2/session_1/intro_data/Tekening1.vsdx\n", + "\n", + "```\n", + "```` " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Instructie_new\n", + "\n", + "In constructiemechanica 2 heb je geleerd hoe je met differentiaalvergelijkingen voor statisch bepaalde constructies de krachtsverdeling en vervormingen kan vinden. Precies dezelfde aanpak werkt ook voor statisch onbepaalde constructie, met als enige verschil dat we de inwendige krachten niet kunnen vinden zonder ook de vergelijkingen en randvoorwaarden voor verplaatsingen op te stellen. Dat doen we volgens de volgende stappen:\n", + "\n", + "::::::{prf:algorithm} Differentiaalvergelijkingen toepassen\n", + ":nonumber: true\n", + ":label: differentiaalvergelijkingen_algoritme\n", + "\n", + "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", + "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", + "3. Er zijn nog meer vergelijkingen nodig om alle onbekende integratieconstantes op te lossen, deze kunnen we vinden door de overgangen tussen de verschillende elementen te analyseren waarbij zowel verplaatsingen als krachten in overeenstemming moeten zijn.\n", + "4. Er zijn nu evenveel vergelijkingen als onbekenden opgesteld. Deze kunnen nu worden opgelost en ingevuld in de opgestelde vergelijkingen voor het gewenste resultaat. Omdat het aantal onbekenden bij statisch onbepaalde constructies als snel uit de hand loopt wordt wordt aangeraden om je rekenmachine of een symbolische wiskundetool te gebruiken om dit op te lossen. Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python. Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt:\n", + "\n", + "::::::\n", + "\n", + "Als voorbeeld bepalen we de een simpele statisch onbepaalde constructie:\n", + "\n", + "::::::{prf:example}\n", + ":nonumber: true\n", + ":label: df_example_0\n", + "\n", + "Gegeven een constructie zoals hieronder weergegeven:\n", + "\n", + "```{figure} intro_data/structure.svg\n", + "---\n", + "align: center\n", + "---\n", + "Constructie, $EI = 5000 \\ \\rm{kNm^2}$\n", + "```\n", + "::::::\n", + "\n", + "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", + "\n", + "::::::{prf:example}\n", + ":nonumber: true\n", + ":label: df_example_1\n", + "\n", + "In dit voorbeeld moeten we element AB in twee delen opsplitsen omdat de verdeelde belasting een discontinuïteit veroorzaakt.\n", + "\n", + "Voor AC leidt dit tot:\n", + "\n", + "```{figure} intro_data/FBD_AC.svg\n", + ":align: center\n", + "\n", + "Vrijlichaamdiagram element AC\n", + "```\n", + "\n", + "Voor BC leidt dit tot:\n", + "\n", + "```{figure} intro_data/FBD_BC.svg\n", + ":align: center\n", + "\n", + "Vrijlichaamdiagram element BC\n", + "```\n", + "::::::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", + "\n", + "::::::{prf:example}\n", + ":nonumber: true\n", + ":label: df_example_3\n", + "\n", + "In dit voorbeeld is er enkel invloed door buiging, dus hebben we aan deze differentiaalvergelijking genoeg: $ -EI \\cfrac{{d}^4w}{{d}x^4} = -q_z$. De differentiaalvergelijkingen voor rek $ EA \\cfrac{{d}^2u}{{d}x^2} = -q_x$ en torsie $ GI \\cfrac{{d}^2\\varphi_x}{{d}x^2} = -q_T$ hebben we in dit geval niet nodig.\n", + "\n", + "**Element AC**\n", + "\n", + "Omdat dit element onbelast is, geeft de belastingsvergelijking voor dit element:\n", + "\n", + "$$q_{z,{\\rm{AC}}}=0$$\n", + "\n", + "wat leidt tot de vergelijkingen:\n", + "\n", + "$$ V_{\\rm{AC}} \\left(x\\right) = C_1$$\n", + "\n", + "$$ M_{\\rm{AC}} \\left(x\\right) = C_1 \\cdot x + C_2 $$\n", + "\n", + "$$ \\kappa_{\\rm{AC}} \\left(x\\right) = \\cfrac{C_1 \\cdot x + C_2}{5000}$$\n", + "\n", + "$$ \\varphi_{\\rm{AC}} \\left(x\\right) = \\cfrac{\\cfrac{1}{2}\\cdot C_1 \\cdot x^2 + C_2 \\cdot x}{5000} + C_3$$\n", + "\n", + "$$ w_{\\rm{AC}} \\left(x\\right) = \\cfrac{-\\cfrac{1}{6}\\cdot C_1 \\cdot x^3 - \\cfrac{1}{2} C_2 \\cdot x^2}{5000} - C_3 \\cdot x + C_4$$\n", + "\n", + "Vanwege de oplegging bij A kan een randvoorwaarde worden geformuleerd als:\n", + "\n", + "```{math}\n", + ":label: BC_1\n", + "w_{\\rm{AC}} \\left(0\\right) = 0\n", + "```\n", + "\n", + "Omdat A ook een onbelast uiteinde is, kan een andere randvoorwaarde worden geformuleerd als:\n", + "\n", + "```{math}\n", + ":label: BC_2\n", + "M_{\\rm{AC}} \\left(0\\right) = 0\n", + "```\n", + "\n", + "Als dit uiteinde belast werd kon met een krachten- of momentenevenwicht ook een relatie gevonden worden.\n", + "\n", + "**Element BC**\n", + "\n", + "Omdat dit element belast is, geeft de belastingsvergelijking voor dit element:\n", + "\n", + "$$q_{z,\\rm{BC}}=10$$\n", + "\n", + "wat leidt tot de vergelijkingen:\n", + "\n", + "$$ V_{\\rm{BC}} \\left(x\\right) = -10 \\cdot x + C_5$$\n", + "\n", + "$$ M_{\\rm{BC}} \\left(x\\right) = -5 \\cdot x^2 + C_5 \\cdot x + C_6 $$\n", + "\n", + "$$ \\kappa_{\\rm{BC}} \\left(x\\right) = \\cfrac{-5 \\cdot x^2 + C_5 \\cdot x + C_6}{5000}$$\n", + "\n", + "$$ \\varphi_{\\rm{BC}} \\left(x\\right) = \\cfrac{-\\cfrac{5}{3} \\cdot x^3 + \\cfrac{1}{2}\\cdot C_5 \\cdot x^2 + C_6 \\cdot x}{5000} + C_7$$\n", + "\n", + "$$ w_{\\rm{BC}} \\left(x\\right) = \\cfrac{\\cfrac{5}{12} \\cdot x^4 -\\cfrac{1}{6}\\cdot C_5 \\cdot x^3 - \\cfrac{1}{2} C_6 \\cdot x^2}{5000} - C_7 \\cdot x + C_8$$\n", + "\n", + "Vanwege de inklemming bij B kunnen twee randvoorwaarden direct worden geformuleerd:\n", + "\n", + "```{math}\n", + ":label: BC_3\n", + "\\varphi_{\\rm{BC}} \\left(4\\right) = 0\n", + "```\n", + "\n", + "```{math}\n", + ":label: BC_4\n", + "w_{\\rm{BC}} \\left(4\\right) = 0\n", + "```\n", + "\n", + "::::::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3. Er zijn nog meer vergelijkingen nodig om alle onbekende integratieconstantes op te lossen, deze kunnen we vinden door de overgangen tussen de verschillende elementen te analyseren waarbij zowel verplaatsingen als krachten in overeenstemming moeten zijn.\n", + "\n", + "::::::{prf:example}\n", + ":nonumber: true\n", + ":label: df_example_4\n", + "\n", + "Bij C kan een randvoorwaarde worden geïdentificeerd uit de consistentie van verplaatsingen: zowel de neerwaartse als rotatieverplaatsing moeten hetzelfde zijn als de neerwaartse en rotatieverplaatsing aan de linkerkant van element BE:\n", + "\n", + "```{math}\n", + ":label: BC_5\n", + "w_{\\rm{AC}} \\left(4\\right) = w_{\\rm{BC}} \\left(0\\right)\n", + "```\n", + "\n", + "```{math}\n", + ":label: BC_6\n", + "\\varphi_{\\rm{AC}} \\left(4\\right) = \\varphi_{\\rm{BC}} \\left(0 \\right)\n", + "```\n", + "\n", + "Ten slotte moet er ook consistentie zijn met de snedekrachten, zoals getoond in het vrijlichaamdiagram:\n", + "\n", + "```{figure} intro_data/FBD_C.svg\n", + ":align: center\n", + "\n", + "Vrijlichaamdiagram knoop C\n", + "```\n", + "\n", + "Verticaal evenwicht geeft:\n", + "\n", + "```{math}\n", + ":label: BC_7\n", + "\\sum {{{\\left. {{F_{\\rm{v}}}} \\right|}^{\\rm{C}}} = 0} \\to -{V_{\\rm{AC}}}\\left(4\\right) + V_{\\rm{BC}}\\left(0\\right) = 0\n", + "```\n", + "\n", + "Momentevenwicht geeft:\n", + "\n", + "```{math}\n", + ":label: BC_8\n", + "\\sum {{{\\left. {{T}} \\right|}_{\\rm{C}}^{\\rm{C}}} = 0} \\to -{M_{{\\rm{AC}}}}\\left(4\\right) + M_{\\rm{BC}}\\left(0\\right) = 0\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4. Er zijn nu evenveel vergelijkingen als onbekenden opgesteld. Deze kunnen nu worden opgelost en ingevuld in de opgestelde vergelijkingen voor het gewenste resultaat. Omdat het aantal onbekenden bij statisch onbepaalde constructies als snel uit de hand loopt wordt wordt aangeraden om je rekenmachine of een symbolische wiskundetool te gebruiken om dit op te lossen. Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python. Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt:\n", + "\n", + "\n", + "::::::{prf:example-start}\n", + ":nonumber: true\n", + ":label: df_example_5\n", + "\n", + "::::::\n", + "\n", + "Er zijn 8 randvoorwaarden geformuleerd met 8 integratieconstanten. Deze kunnen nu worden opgelost. \n", + "\n", + "Het invullen van de randvoorwaarden geeft:\n", + "\n", + "$$\n", + "\\begin{align}\n", + "C_{4} = 0 \\\\\n", + "C_{2} = 0 \\\\\n", + "- \\cfrac{4 C_{5}}{1875} - \\cfrac{C_{6}}{625} - 4 C_{7} + C_{8} + \\cfrac{8}{375} = 0 \\\\\n", + "\\cfrac{C_{5}}{625} + \\cfrac{C_{6}}{1250} + C_{7} - \\cfrac{8}{375} = 0 \\\\\n", + "- \\cfrac{4 C_{1}}{1875} - \\cfrac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0 \\\\\n", + "\\cfrac{C_{1}}{625} + \\cfrac{C_{2}}{1250} + C_{3} - C_{7} = 0 \\\\\n", + "4 C_{1} + C_{2} - C_{6} = 0 \\\\\n", + "C_{1} - C_{5} = 0 \\\\\n", + "\\end{align}\n", + "$$\n", + "\n", + "Het oplossen hiervan geeft:\n", + "\n", + "$$\n", + "\\begin{align}\n", + "C_{1} = \\cfrac{35}{8} = 4.375 \\\\\n", + "C_{2} = 0 \\\\\n", + "C_{3} = - \\cfrac{1}{150} \\approx -0.006667 \\\\\n", + "C_{4} = 0 \\\\\n", + "C_{5} = \\cfrac{35}{8} = 4.375\\\\\n", + "C_{6} = \\cfrac{35}{2} = 17.5 \\\\\n", + "C_{7} = \\cfrac{1}{3000} \\approx 0.0003333\\\\\n", + "C_{8} = \\cfrac{13}{750} \\approx 0.01733\n", + "\\end{align}\n", + "$$\n", + "\n", + "Nu is de volledige krachtenverdeling en verplaatsingen van de constructie opgelost. Bijvoorbeeld de momentenverdeling in BC die kan worden uitgezet als:\n", + "\n", + "```{figure} intro_data/Momentenlijn.svg\n", + ":align: center\n", + "\n", + "Momentenlijn BC\n", + "```\n", + "\n", + "De krachtsverdeling en verplaatsingen kunnen no ook \n", + "\n", + "**Oplossen met digitale hulpmiddelen**\n", + "Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python.\n", + "\n", + "\n", + "$$\\left[\\begin{array}{cccccccc}0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & - \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1\\\\0 & 0 & 0 & 0 & \\frac{1}{625} & \\frac{1}{1250} & 1 & 0\\\\- \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1 & 0 & 0 & 0 & -1\\\\\\frac{1}{625} & \\frac{1}{1250} & 1 & 0 & 0 & 0 & -1 & 0\\\\4 & 1 & 0 & 0 & 0 & -1 & 0 & 0\\\\1 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\end{array}\\right] \\left[ \\begin{array}{cccccccc} C_1\\\\C_2\\\\C_3\\\\C_4\\\\C_5\\\\C_6\\\\C_7\\\\C_8 \\end{array} \\right] = \\left[\\begin{matrix}0\\\\0\\\\- \\frac{8}{375}\\\\\\frac{8}{375}\\\\0\\\\0\\\\0\\\\0\\end{matrix}\\right]$$\n", + "\n", + "[Hier](rref_ti_84) is uitgelegd hoe je dit op een grafische rekenmachine kan oplossen.\n", + "\n", + "Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt.\n", + "\n", + "Beide opties zijn hieronder getoond" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAASCAYAAADomNYKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAs9JREFUeJzl102o1FUYx/HPaEh2q3sxCgKtqNRdS7tgQi8g0SZXLgLBCiEsYnITFPTwBLqMUBRq0S2iVhEGtRF6WVTULktLbwTtgsDK6nbpzXFxztTcaeY2M3eGS/SF4YHznJfn9z/nPOeZRqvV0ovM3IwHsBPXYQY/4CRex4sR8UvPwatEZm7E07gbV+EbHEdGxPftfo1u0ZnZQOJxrMOH+BTncb3yETbg/YjYMWkhg5KZNymxXoM3cAbbcAfOYntEnINLeox/AXvxOe6LiJNdk6/HAdw8ofhH5Zgi+NGIONJuzMxn8BgO4iFY0zkqMw8ogr/AbLdgiIjFiDiI/ZOKflgy80blBH6No13uwAL2ZOYUHaIz81rla/yB3RHx03ILRcTi+MJeMXdWeyIiLnQ6qo4PcBlmWXq8m7gUcxFxatJRZmZTSY6D8klEHO/j21rtfB//l8pJ2IK3O0XvqvblIQJZCU0lMQ7KS0om7sV0tef7+NvtM9SdzszLla/QwsdDBPIXmfmEcj2ORsQj/9Y/Im4YZZ0RaVTb4u87fXW1P47y9mbmLPYpT9tq0N7J6T7+Kzv7tY/3QrXrM3NtRPw56GqZOY1X8CCeGmJc0/ju9Nlqt/Txb652nrrTEfGtku7X4fblVs7MNV1Nz+O1iHhnuXE9aCrPyaC/XcvM9W61O7vjy8wrsB2L+Iil2fvZ+juWmfdGxJmuwQ2lvLsfu2vbPqVI2TOw1Mo473REfJWZJ5QM/TCOdLgTU3guIhZYKvowblHq7c/qJPP4HZtwGzbiVcjMrTiEHRHx27gErID9Shl6ODPvUgqsW5UydB5Ptjv2qr3vUZLSNiXB/awU7qfxFt6MiHOZuRdz6Lz/a5UMeQFTEfHrBMT1JTM36f+H47t2v3+IHmKBGWXnO5lTCoFDOB0Ro00+YUYW3YvMfA+nBnmnV5PuTPy/YKw7/V/hImUh8qiSnFTZAAAAAElFTkSuQmCC", + "text/latex": [ + "$\\displaystyle C_{4} = 0$" + ], + "text/plain": [ + "C₄ = 0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAASCAYAAADomNYKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAt9JREFUeJzV10+IVXUUB/DPTBGZmWIYBFpSaruWJZmRBSZtkhYGkZBBUAoxSRDS4nACV1HISANt+kPQMoxqIw1tKmqn/TGdCNwFQX+smYbIei1+99ad17vje773kL5wObx7fud3zvf3O+e8cyc6nY5eyMzNeAw7cQPW4GecxNt4PSJ+62l8iZCZ6/E8duFafIdjyIj4qV430U06MyeQeBZX4BN8jnO4UTmEtfgoIraPm0i/yMyblVivwzs4jduwA2ewLSJ+gMt72L+KR3EKD0fEya7NV+AgNo0p/ovFjEL4qYg4Wr/MzJfwNA7jCZhsWmXmQYXw19jaTRgiYjEiDmP/uKIfFJl5k5KBZ/FylzqwgL2ZuZIG6cy8XjmN89gTEb8u5ygiFkcX9tC4p5LHI+KvpqLi8TGuwlaWpvcUrsRrEfHluKPMzCmlOfaLExFxrEV3SyXnWvTfKJmwBbNN0rsr+eYAgQyDKaUx9os3lE7cC6srea5FX79fQ3XTmXm1cgodfNZvFJl5CA8qJ/07PsWhfjIlIjb262cEmKhkh39rel0lfxnwv/dupWveodTVeXyQmWuHj3Mg1De5ukV/TXNdnd4LlVyRmZdFxJ/9eIqI+5q/M3NvtfE2vLuc7Yhr+kwlt7ToN1dyjop0RHyfmWexUbm92TbPmTnZ3SEbWKVkz49t9g1MGV1Nf1jJnd3xZeYq5RIWlfJb0r2PVM9MZj4QEaebu1aT2i7sw54W50dwot58OYyypiPi28w8rnToAzjaUCdW4pWIWGAp6WncqszbX1SbzOEPbMCdWI+3ejnOzBdwF7b3Wx4jxn5lDJ3OzHuVAet2ZQydw3P1wl6z9/14XJlb12FeGdy/wvt4r55hGzYv4hHsiIhT4+F0YWTmBu0fHP+U3H9IX4SjaTzkEhMeBEORzswZ5YZ3Kx8oNeYjYn640MaHyQsvWRZPKh17Vkml+nlmyH3HiqHT+/+IvwHtQ/pzJbnwjAAAAABJRU5ErkJggg==", + "text/latex": [ + "$\\displaystyle C_{2} = 0$" + ], + "text/plain": [ + "C₂ = 0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle - \\frac{4 C_{5}}{1875} - \\frac{C_{6}}{625} - 4 C_{7} + C_{8} + \\frac{8}{375} = 0$" + ], + "text/plain": [ + " 4⋅C₅ C₆ 8 \n", + "- ──── - ─── - 4⋅C₇ + C₈ + ─── = 0\n", + " 1875 625 375 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\frac{C_{5}}{625} + \\frac{C_{6}}{1250} + C_{7} - \\frac{8}{375} = 0$" + ], + "text/plain": [ + "C₅ C₆ 8 \n", + "─── + ──── + C₇ - ─── = 0\n", + "625 1250 375 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle - \\frac{4 C_{1}}{1875} - \\frac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0$" + ], + "text/plain": [ + " 4⋅C₁ C₂ \n", + "- ──── - ─── - 4⋅C₃ + C₄ - C₈ = 0\n", + " 1875 625 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\frac{C_{1}}{625} + \\frac{C_{2}}{1250} + C_{3} - C_{7} = 0$" + ], + "text/plain": [ + "C₁ C₂ \n", + "─── + ──── + C₃ - C₇ = 0\n", + "625 1250 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKoAAAAUCAYAAAAdtqaHAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAABSNJREFUeJztmmuoVUUYhp9jIpmaQhQIWqFp5A8pMjO8kB5QqR8eioxCRbtAqdjJbmjY62cYgVhHJSG01CQhsDAKBFG0sDQkVDKzk5L4I8HQsjSVLrsf36zarc5ae+3bWUfYDyxm77m+s5j5Zuab1VQoFEjCzKYD74S/j0tam5J3CPAIMBG4HugH/AwcBD4A1kv6LbGxnGnozwczGwAsASYD1wAngS2ASfopytc9pYKBwCrgHNA7JV8TYMALQA/gc2AzcBa4AX9xzcBDwNgq+lQXGvrzw8wG43qvAz4EjgAjgaeAyWY2WtJpSBioofPrgNP4bHw2pb23gZnAYeBhSQdjdfUE5gM3Vd6lZMxsZtA6XtKuCqrIVX8NuJz1r8YH6TxJq6JIM3sNeBpYCjwB0C2hgnnABGAWcD6pFTObj7+kb4BR8ZcEIOmCpKXA7Ep6Uk8a+vPDzAbh1v448EYsWfi4m25mvaCDgWpmtwCvAiskfZrSUH98xP8BTJX0a5owSReyd6P+NPTnzoQQbpP0V3FC6MtnwFXAKIgt/WbWHdgInAAWlmioFbgSWCfpUNWyO59WGvozY2at+AEtKwckbUlJvzmE7Qnp3+EWdyiwI75HfQm4DRiTYQa2hHBjiXxdlZYQNvRnoxU/nGVlA356T6JvCM8mpEfx/aDIoprZSNyKLpe0J02BmfXGR3oB+KKU4ljZccBzwO1Af+ABSZszlj1O8svaaWbxuA2SZnZQTzX6FwD34RbhErAXWJDFqpXQ3xHvSprWQT0V6w/l++Pbu3twj85RYK6kT5LKSLqx3HaqpCmEBQgDtWjJbwcWZajk2hD+UoFvrhfu21sHvF9m2Tb+v/zcCkzBZ/DxWNqBhHqq0X83flrdh7/MJcB2Mxsm6UyJsseAi2W09UNCfMX6zawfvv/bDdwL/AgMAk6VU08NiCxm34T0q4vzRRY1mqEAFzuwTABrzGwNsAJ4JcT1NLMrJP2ZVZ2krcBWgIR20sq2xeOCe2oK7tDelbGqyJNRif5Jsfan4y9zNPBRibLNWdspQcX6geeBk5JmFMV9X6pQHfao34ZwaEL6kBC2w7+n/kvAWwnP/pBnd/i/R9Ip3Hr1wC1MImaW5ALLjRrr74O/x1LWtGZUqb8F2Gtmm8zslJkdMLO5wXeeRivuNsr6tJSob2cIJ8Y1mlkffOJfwLdWblHDwemxhI4uxg9YG2JXqG3hWW1mUyQdiZVrwq/FZgFTS4jOgzZqo78N32LsrYfIEu22Ub7+QcAc4HVgEr51WoXvBeP+zH+o9R5V0jEz24af7OcEDRGGbxHflHQeUq5QM7ASGI7fL38VGm0HfgcGAmOAAcCmKtqoJ1XrN7NlwDhgbJnLby2oVH834EtJC8L//WY2FB8siQO1TszGr1BXmlkzfnFxJzAe78uLUcaKl2VJBUmP4hvyj/GZOQe3zMOBPfitybxK26gn1eo3s+XADKBZ0tFOkPwfqtB/Evg6FneY8rwRNUHSMWAEsB4foM8Ag/FJeFd0zw/QlPb1VL0xswJluKe6Cma2EngQ/77gcN56ysHMNgEDJY0tinsZuF/SsPyUpdPpAzX4AKMPJPbjPtXtwBlJJzpVTAWY2WpgGn5YKB6k5ySdy0VUGZjZHfhyuxh4Dz9/rAUWSurspT8zeZzIR+ADNPImLAu/l+SgpRKexE/6O/BlNHrSvjDrMkjah0+yqcAh/HuBRbhvuMuS69LfoEFWupyPs0GDjmgM1AaXBX8Db+ZLKnj2sa4AAAAASUVORK5CYII=", + "text/latex": [ + "$\\displaystyle 4 C_{1} + C_{2} - C_{6} = 0$" + ], + "text/plain": [ + "4⋅C₁ + C₂ - C₆ = 0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAG4AAAAUCAYAAABs4ghcAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAA6lJREFUeJztmV2IVGUYx3+zimhWCn0KWy2adhGEkNSGFdWCCF20NwlFQqUXYmCTEhEh//6CV4aIktFNukR5Y2EUCEJ4VZt3iWF+sPkBfZOlohukTRfve7az48x4zsyZ2R3YHxwezvv5f+Y57+eUKpUKtbC9EHgZWAbcDcwF/gIOA58CuyVdrll5gulW7bZ7gU3AcuAW4GdgH2BJf6bLTq9RuQQYeAOYAXwN7AXOA/cQfowB4DngsXY50Qxdrn0BQe/twGfAMeAh4FVgue2lkv5Iyl8TOOAD4EXgKPC8pMNVHcwC1gP3tsOBFulm7TsJQVsnaUeSaHsr8BqwGViTpPeka9peT3D8e6C/2nEASaOSNgNr26G+Wbpc+3zCbHAaeLcqW8AlYKXt2UliT6ryPEJUrwArJF1s1Jmk0WJkt043a488Fe0BSf+mM6IvXwE3AP1JenqqLAMzgV2SvmuvzsIp02HttsuETU9WvpW0r07efdGeqJN/kjAiFwFfwvjADUb7YQ4xk4XBaDupvUzY8GRliLBDrMWcaM/XyU/S5yYJ0wFs30iIZgU4lFWJ7ceB14EHgXnAs5L2Zqx7mnyOfyTphRrtNKU91n2bsIak+VXSnderK6kvT18tUop27OyWjLjbor2Q83wzm3A22gV8klPMCPB3jvI/1UlvVnvCceCJ1PvVJtpolWREzamTf3NVubHAXYp2lu1pkjKJl7Qf2A9gO5dSSQO5KtSnKe0prkj6JW+nBa9xx6NdVCd/YbRja2APgKTfCFvRGYz/+q7Bdk+j/E5TgPb5tn+0fcr2Htt9GbsuE6bZrM9gg7YORrusWqPtm4ClwCjwTZKe3pxsi89O289IOlbVQIlwFfMSsCKjc51iG81pPwSsJHzJdwBvAsO275d0rlGHRa5xkkZsHyDsHF8BdqSyTViS3peUzC7jArcdeIBwx3ckNnQC+Ae4C3gU6AU+LkpwgTSlPU71CUdsDwM/EA7yW9svexxrCVde220PEC4SHgaeJPjyVrrw2LCUVJG0Cnga+AJYTIj+asKPMkxwaF27PchLUdrjF32U/9eUjiFpBFgC7CYEbAOwgPBRPpK+pwQo1ft3IC+2K+Q4DkxGbM8ETgHvSdo00XoaUeuSOTPxDJW+sO2zvRg4J+lsK213AtvvAJ8DZwkXvBsJ68nQROrKQkuBIwztg6n3LdEOEaamyU4vsAe4FfidsGvrl3RmQlVloLCpcorOMqnOZFNkZypwXcp/TvVqwtp6oi4AAAAASUVORK5CYII=", + "text/latex": [ + "$\\displaystyle C_{1} - C_{5} = 0$" + ], + "text/plain": [ + "C₁ - C₅ = 0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "C_{4} = 0\n", + "C_{2} = 0\n", + "- \\frac{4 C_{5}}{1875} - \\frac{C_{6}}{625} - 4 C_{7} + C_{8} + \\frac{8}{375} = 0\n", + "\\frac{C_{5}}{625} + \\frac{C_{6}}{1250} + C_{7} - \\frac{8}{375} = 0\n", + "- \\frac{4 C_{1}}{1875} - \\frac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0\n", + "\\frac{C_{1}}{625} + \\frac{C_{2}}{1250} + C_{3} - C_{7} = 0\n", + "4 C_{1} + C_{2} - C_{6} = 0\n", + "C_{1} - C_{5} = 0\n" + ] + } + ], + "source": [ + "import sympy as sym\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "%config InlineBackend.figure_formats = ['svg']\n", + "sym.init_printing()\n", + "\n", + "x = sym.symbols('x')\n", + "\n", + "q = 10 \n", + "EI = 5000 \n", + "EA = 20000 \n", + "F = 150\n", + "\n", + "q_AC = 0\n", + "q_BC = q\n", + "\n", + "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", + "C_5, C_6, C_7, C_8 = sym.symbols('C_5 C_6 C_7 C_8')\n", + "\n", + "V_AC = -sym.integrate(q_AC, x) + C_1\n", + "M_AC = sym.integrate(V_AC, x) + C_2\n", + "kappa_AC = M_AC/EI\n", + "phi_AC = sym.integrate(kappa_AC, x) + C_3\n", + "w_AC = -sym.integrate(phi_AC, x) + C_4\n", + "\n", + "V_BC = -sym.integrate(q_BC, x) + C_5\n", + "M_BC = sym.integrate(V_BC, x) + C_6\n", + "kappa_BC = M_BC/EI\n", + "phi_BC = sym.integrate(kappa_BC, x) + C_7\n", + "w_BC = -sym.integrate(phi_BC, x) + C_8\n", + "\n", + "eq1 = sym.Eq(w_AC.subs(x,0),0)\n", + "eq2 = sym.Eq(M_AC.subs(x,0),0)\n", + "eq3 = sym.Eq(w_BC.subs(x,4),0)\n", + "eq4 = sym.Eq(phi_BC.subs(x,4),0)\n", + "eq5 = sym.Eq(w_AC.subs(x,4)-w_BC.subs(x,0),0)\n", + "eq6 = sym.Eq(phi_AC.subs(x,4)-phi_BC.subs(x,0),0)\n", + "eq7 = sym.Eq(M_AC.subs(x,4) - M_BC.subs(x,0),0)\n", + "eq8 = sym.Eq(V_AC.subs(x,4) - V_BC.subs(x,0),0)\n", + "\n", + "display(eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8)\n", + "for eq in [eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8]:\n", + " print(sym.latex(eq))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\left\\{ C_{1} : \\frac{35}{8}, \\ C_{2} : 0, \\ C_{3} : - \\frac{1}{150}, \\ C_{4} : 0, \\ C_{5} : \\frac{35}{8}, \\ C_{6} : \\frac{35}{2}, \\ C_{7} : \\frac{1}{3000}, \\ C_{8} : \\frac{13}{750}\\right\\}$" + ], + "text/plain": [ + "⎧ 13 ⎫\n", + "⎨C₁: 35/8, C₂: 0, C₃: -1/150, C₄: 0, C₅: 35/8, C₆: 35/2, C₇: 1/3000, C₈: ───⎬\n", + "⎩ 750⎭" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'\\\\left\\\\{ C_{1} : \\\\frac{35}{8}, \\\\ C_{2} : 0, \\\\ C_{3} : - \\\\frac{1}{150}, \\\\ C_{4} : 0, \\\\ C_{5} : \\\\frac{35}{8}, \\\\ C_{6} : \\\\frac{35}{2}, \\\\ C_{7} : \\\\frac{1}{3000}, \\\\ C_{8} : \\\\frac{13}{750}\\\\right\\\\}'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sol = sym.solve([eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8],(C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", + "display(sol)\n", + "sym.latex(sol)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " 2025-07-02T16:58:07.214407\n", + " image/svg+xml\n", + " \n", + " \n", + " Matplotlib v3.10.3, https://matplotlib.org/\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ], + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "M_numpy = sym.lambdify(x, M_BC.subs(sol))\n", + "x_numpy = np.linspace(0,4,100)\n", + "plt.figure()\n", + "plt.plot(x_numpy,M_numpy(x_numpy))\n", + "plt.xlabel('$x$')\n", + "plt.ylabel('$M_{BC}$');\n", + "ax = plt.gca()\n", + "ax.spines['right'].set_color('none')\n", + "ax.spines['top'].set_color('none')\n", + "ax.spines['bottom'].set_position('zero')\n", + "ax.spines['left'].set_position('zero')\n", + "ax.invert_yaxis()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\\left[\\begin{matrix}0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & - \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1\\\\0 & 0 & 0 & 0 & \\frac{1}{625} & \\frac{1}{1250} & 1 & 0\\\\- \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1 & 0 & 0 & 0 & -1\\\\\\frac{1}{625} & \\frac{1}{1250} & 1 & 0 & 0 & 0 & -1 & 0\\\\4 & 1 & 0 & 0 & 0 & -1 & 0 & 0\\\\1 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\end{matrix}\\right]\n", + "\\left[\\begin{matrix}0\\\\0\\\\- \\frac{8}{375}\\\\\\frac{8}{375}\\\\0\\\\0\\\\0\\\\0\\end{matrix}\\right]\n" + ] + } + ], + "source": [ + "A,b = sym.linear_eq_to_matrix((eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8), (C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", + "print(sym.latex(A))\n", + "print(sym.latex(b))\n", + "A = np.array(A).astype(np.float64)\n", + "b = np.array(b).astype(np.float64)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "A = np.array([\n", + " [0, 0, 0, 1, 0, 0, 0, 0],\n", + " [0, 1, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, -4/1875, -1/625, -4, 1],\n", + " [0, 0, 0, 0, 1/625, 1/1250, 1, 0],\n", + " [-4/1875, -1/625, -4, 1, 0, 0, 0, -1],\n", + " [1/625, 1/1250, 1, 0, 0, 0, -1, 0],\n", + " [4, 1, 0, 0, 0, -1, 0, 0],\n", + " [1, 0, 0, 0, -1, 0, 0, 0]\n", + "])\n", + "\n", + "b = np.array([\n", + " 0,\n", + " 0,\n", + " -8/375,\n", + " 8/375,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0\n", + "])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 4.37500000e+00],\n", + " [ 0.00000000e+00],\n", + " [-6.66666667e-03],\n", + " [ 0.00000000e+00],\n", + " [ 4.37500000e+00],\n", + " [ 1.75000000e+01],\n", + " [ 3.33333333e-04],\n", + " [ 1.73333333e-02]])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linalg.solve(A,b)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}4.375\\\\0\\\\-0.00666666666666667\\\\0\\\\4.375\\\\17.5\\\\0.000333333333333334\\\\0.0173333333333333\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[ 4.375],\n", + "[ 0],\n", + "[-0.00666666666666667],\n", + "[ 0],\n", + "[ 4.375],\n", + "[ 17.5],\n", + "[0.000333333333333334],\n", + "[ 0.0173333333333333]])" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\\left[\\begin{matrix}4.375\\\\0\\\\-0.00666666666666667\\\\0\\\\4.375\\\\17.5\\\\0.000333333333333334\\\\0.0173333333333333\\end{matrix}\\right]\n", + "\\left[\\begin{matrix}1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 4.375\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -0.00666666666666667\\\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 4.375\\\\0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 17.5\\\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0.000333333333333334\\\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0.0173333333333333\\end{matrix}\\right]\n" + ] + } + ], + "source": [ + "import sympy as sym\n", + "\n", + "A_sym = sym.Matrix(A)\n", + "b_sym = sym.Matrix(b)\n", + "\n", + "sol_sym = A_sym.LUsolve(b_sym)\n", + "\n", + "display(sol_sym)\n", + "\n", + "print(sym.latex(sol_sym))\n", + "\n", + "identity = sym.eye(sol_sym.rows)\n", + "rr_augmented = identity.row_join(sol_sym)\n", + "print(sym.latex(rr_augmented))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "C_1 = 35/8 ≈ 4.37500000000000\n", + "C_2 = 0 ≈ 0\n", + "C_3 = -1/150 ≈ -0.00666666666666667\n", + "C_4 = 0 ≈ 0\n", + "C_5 = 35/8 ≈ 4.37500000000000\n", + "C_6 = 35/2 ≈ 17.5000000000000\n", + "C_7 = 1/3000 ≈ 0.000333333333333333\n", + "C_8 = 13/750 ≈ 0.0173333333333333\n" + ] + } + ], + "source": [ + "import sympy as sym\n", + "sym.init_printing()\n", + "\n", + "x = sym.symbols('x')\n", + "\n", + "q = 10 \n", + "EI = 5000 \n", + "EA = 20000 \n", + "F = 150\n", + "\n", + "q_AC = 0\n", + "q_BC = q\n", + "\n", + "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", + "C_5, C_6, C_7, C_8 = sym.symbols('C_5 C_6 C_7 C_8')\n", + "\n", + "V_AC = -sym.integrate(q_AC, x) + C_1\n", + "M_AC = sym.integrate(V_AC, x) + C_2\n", + "kappa_AC = M_AC/EI\n", + "phi_AC = sym.integrate(kappa_AC, x) + C_3\n", + "w_AC = -sym.integrate(phi_AC, x) + C_4\n", + "\n", + "V_BC = -sym.integrate(q_BC, x) + C_5\n", + "M_BC = sym.integrate(V_BC, x) + C_6\n", + "kappa_BC = M_BC/EI\n", + "phi_BC = sym.integrate(kappa_BC, x) + C_7\n", + "w_BC = -sym.integrate(phi_BC, x) + C_8\n", + "\n", + "eq1 = sym.Eq(w_AC.subs(x,0),0)\n", + "eq2 = sym.Eq(M_AC.subs(x,0),0)\n", + "eq3 = sym.Eq(w_BC.subs(x,4),0)\n", + "eq4 = sym.Eq(phi_BC.subs(x,4),0)\n", + "eq5 = sym.Eq(w_AC.subs(x,4)-w_BC.subs(x,0),0)\n", + "eq6 = sym.Eq(phi_AC.subs(x,4)-phi_BC.subs(x,0),0)\n", + "eq7 = sym.Eq(M_AC.subs(x,4) - M_BC.subs(x,0),0)\n", + "eq8 = sym.Eq(V_AC.subs(x,4) - V_BC.subs(x,0),0)\n", + "\n", + "sol = sym.solve([eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8],(C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", + "for k, v in sol.items():\n", + " print(f\"{k} = {v} ≈ {v.evalf()}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "::::::{prf:example-end}\n", + "::::::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Meer voorbeelden\n", + "Het voorbeeld in hoofdstuk 2.7.3 van het boek Mechanica, spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013` richt zich op extensie. Voorbeeld 3b in hoofdstuk 8.2 is een buigingsprobleem.\n", + "\n", + "## Instructies in collegevorm\n", + "\n", + "Dit onderwerp is [in les 3](https://collegerama.tudelft.nl/Mediasite/Channel/public-ceg-ctb2210/watch/757766716fcb45718fca678dadaa396d1d?sortBy=most-recent) gepresenteerd in collegevorm van 0:40:00 tot 0:48:30\n", + "\n", + "## Opgaves\n", + "\n", + "- Opgaves 2.48 en 2.50 in hoofdstuk 2.9 van het boek Mechanica: spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013`, antwoorden zijn beschikbaar op [deze website](https://icozct.tudelft.nl/TUD_CT/boekantwoorden/vol2/Chapter2/).\n", + "- Opgaves 8.7, 8.10, 8.11 in hoofdstuk 8.6 van het boek Mechanica: spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013`, antwoorden zijn beschikbaar op [deze website](https://icozct.tudelft.nl/TUD_CT/boekantwoorden/vol2/Chapter8/)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/lesoefeningen.ipynb b/book/lesoefeningen.ipynb new file mode 100644 index 0000000..b6e6d48 --- /dev/null +++ b/book/lesoefeningen.ipynb @@ -0,0 +1,316 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "44f13f99", + "metadata": {}, + "source": [ + "````{margin}\n", + "```{attributiongrey} Bronvermelding\n", + ":class: attribution\n", + "\n", + "Deze oefening is aangepast van https://oit.tudelft.nl/CT1000/2024/week_3/session_1/intro.html\n", + "\n", + "% Figures from https://github.com/TUDelft-books/CT1000/blob/2025/book/week_3/session_1/intro_data/Tekening1.vsdx\n", + "\n", + "```\n", + "```` \n", + "\n", + "# Begeleide oefening 1_oud\n", + "\n", + "Gegeven is de volgende constructie:\n", + "\n", + "```{figure} lesoefeningen_data/figure2.svg\n", + "---\n", + "align: center\n", + "---\n", + "Constructie, $EI = 6400 \\ \\rm{kNm^2}$\n", + "```\n", + "\n", + ":::::{exercise}\n", + ":label: ODE_3_1\n", + ":nonumber: true\n", + "\n", + "Bepaal de segmenten en teken de vrijlichaamsschema's.\n", + "\n", + "```{h5p} https://tudelft.h5p.com/content/1292630673009985967/embed\n", + "```\n", + "\n", + ":::::\n", + "\n", + "% solution_start\n", + "\n", + "::::{admonition} Solution\n", + ":class: solution, dropdown\n", + "\n", + "$q_z = -12 \\cdot x + 0$\n", + "\n", + "::::\n", + "\n", + "% solution_end\n", + "\n", + ":::::{exercise}\n", + ":label: ODE_3_2\n", + ":nonumber: true\n", + "\n", + "Bepaal de relaties van de krachtsgrootheden en verplaatsingen.\n", + "\n", + "```{h5p} https://tudelft.h5p.com/content/1292630677998825487/embed\n", + "```\n", + "\n", + ":::::\n", + "\n", + "% solution_start\n", + "\n", + "::::{admonition} Solution\n", + ":class: solution, dropdown\n", + "\n", + "- $ w \\left( 0\\right) = 0 $\n", + "- $ M \\left( 0\\right) = 0$\n", + "- $ w \\left( 8\\right) = 0$\n", + "- $ \\varphi \\left( 8 \\right) = 0$\n", + "\n", + "::::\n", + "\n", + "% solution_end\n", + "\n", + ":::::{exercise-start}\n", + ":label: ODE_3_3\n", + ":nonumber: true\n", + "\n", + "Los de integratieconstanten op. Je kan gebruik maken van de volgende code cellen. (Klik op {fa}`rocket` --> {guilabel}`Live Code` om live python code te activeren op deze pagina.)\n", + "\n", + "```{h5p} https://tudelft.h5p.com/content/1292630704310133517/embed\n", + "```\n", + "\n", + ":::::\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91dc34be", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "A = np.array([\n", + " [ , , , ],\n", + " [ , , , ],\n", + " [ , , , ],\n", + " [ , , , ],\n", + "])\n", + "\n", + "b = np.array([\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + "])\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce6f1792", + "metadata": {}, + "outputs": [], + "source": [ + "np.linalg.solve(A,b)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e466305", + "metadata": {}, + "outputs": [], + "source": [ + "import sympy as sym\n", + "sym.init_printing()\n", + "\n", + "x = sym.symbols('x')\n", + "\n", + "q = \n", + "EI = 6400\n", + "\n", + "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", + "\n", + "V = -sym.integrate(q, x) + C_1\n", + "M = sym.integrate(V, x) + C_2\n", + "kappa = M/EI\n", + "phi = sym.integrate(kappa, x) + C_3\n", + "w = -sym.integrate(phi, x) + C_4\n", + "\n", + "eq1 = sym.Eq(w.subs(x,0), )\n", + "eq2 = sym.Eq( .subs(x,0), )\n", + "eq3 = sym.Eq(w.subs(x,8), )\n", + "eq4 = sym.Eq( .subs(x,8),0)\n", + "\n", + "sol = sym.solve([eq1,eq2,eq3,eq4],(C_1,C_2,C_3,C_4))\n", + "for k, v in sol.items():\n", + " print(f\"{k} = {v} ≈ {v.evalf()}\")" + ] + }, + { + "cell_type": "markdown", + "id": "94270e4f", + "metadata": {}, + "source": [ + ":::::{exercise-end}\n", + ":::::\n", + "\n", + "% solution_start\n", + "\n", + "::::{solution-start} ODE_3_3\n", + ":class: dropdown\n", + "::::\n", + "\n", + "$ w = - \\cfrac{x^{5}}{10} + \\cfrac{64 x^{3}}{5} - \\cfrac{2048 x}{5} = - 0.1 x^{5} + 12.8 x^{3} - 409.6 x $\n", + "% solution_end" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "f46e4efd", + "metadata": { + "tags": [ + "solution" + ] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "A = np.array([\n", + " [ 0 , 0 , 0,1],\n", + " [ 0 , 1 , 0,0],\n", + " [-1/75 ,-1/200,-8,1],\n", + " [ 1/200, 1/800, 1,0],\n", + "])\n", + "\n", + "b = np.array([\n", + " 0,\n", + " 0,\n", + " 64/125,\n", + " -8/25,\n", + "])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "300cd851", + "metadata": { + "tags": [ + "solution" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-7.68e+01, 0.00e+00, 6.40e-02, 0.00e+00])" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linalg.solve(A,b)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "96516034", + "metadata": { + "tags": [ + "solution" + ] + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle - 0.1 x^{5} + 12.8 x^{3} - 409.6 x$" + ], + "text/plain": [ + " 5 3 \n", + "- 0.1⋅x + 12.8⋅x - 409.6⋅x" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import sympy as sym\n", + "sym.init_printing()\n", + "\n", + "x = sym.symbols('x')\n", + "\n", + "q = -12 * x\n", + "EI = 6400\n", + "\n", + "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", + "\n", + "V = -sym.integrate(q, x) + C_1\n", + "M = sym.integrate(V, x) + C_2\n", + "kappa = M/EI\n", + "phi = sym.integrate(kappa, x) + C_3\n", + "w = -sym.integrate(phi, x) + C_4\n", + "\n", + "eq1 = sym.Eq(w.subs(x,0),0)\n", + "eq2 = sym.Eq(M.subs(x,0),0)\n", + "eq3 = sym.Eq(w.subs(x,8),0)\n", + "eq4 = sym.Eq(phi.subs(x,8),0)\n", + "\n", + "sol = sym.solve([eq1,eq2,eq3,eq4],(C_1,C_2,C_3,C_4))\n", + "\n", + "display((w.subs(sol)*EI).evalf())\n", + "\n", + "A,b = sym.linear_eq_to_matrix((eq1,eq2,eq3,eq4), (C_1,C_2,C_3,C_4))" + ] + }, + { + "cell_type": "markdown", + "id": "b3a4c9d4", + "metadata": {}, + "source": [ + "% solution_start\n", + "\n", + "::::{solution-end}\n", + "::::\n", + "\n", + "% solution_end" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 2a78126224a6db81b2bf734253319c9fcd93fa1f Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Sat, 3 Jan 2026 15:42:01 +0100 Subject: [PATCH 050/110] change labels --- book/instructie_2.ipynb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/book/instructie_2.ipynb b/book/instructie_2.ipynb index 4b1a93d..0382117 100644 --- a/book/instructie_2.ipynb +++ b/book/instructie_2.ipynb @@ -26,7 +26,7 @@ "\n", "::::::{prf:algorithm} Differentiaalvergelijkingen toepassen\n", ":nonumber: true\n", - ":label: differentiaalvergelijkingen_algoritme\n", + ":label: differentiaalvergelijkingen_algoritme_2\n", "\n", "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", @@ -39,7 +39,7 @@ "\n", "::::::{prf:example}\n", ":nonumber: true\n", - ":label: df_example_0\n", + ":label: df_example_0_2\n", "\n", "Gegeven een constructie zoals hieronder weergegeven:\n", "\n", @@ -55,7 +55,7 @@ "\n", "::::::{prf:example}\n", ":nonumber: true\n", - ":label: df_example_1\n", + ":label: df_example_1_2\n", "\n", "In dit voorbeeld moeten we element AB in twee delen opsplitsen omdat de verdeelde belasting een discontinuïteit veroorzaakt.\n", "\n", @@ -85,7 +85,7 @@ "\n", "::::::{prf:example}\n", ":nonumber: true\n", - ":label: df_example_3\n", + ":label: df_example_3_2\n", "\n", "In dit voorbeeld is er enkel invloed door buiging, dus hebben we aan deze differentiaalvergelijking genoeg: $ -EI \\cfrac{{d}^4w}{{d}x^4} = -q_z$. De differentiaalvergelijkingen voor rek $ EA \\cfrac{{d}^2u}{{d}x^2} = -q_x$ en torsie $ GI \\cfrac{{d}^2\\varphi_x}{{d}x^2} = -q_T$ hebben we in dit geval niet nodig.\n", "\n", @@ -164,7 +164,7 @@ "\n", "::::::{prf:example}\n", ":nonumber: true\n", - ":label: df_example_4\n", + ":label: df_example_4_2\n", "\n", "Bij C kan een randvoorwaarde worden geïdentificeerd uit de consistentie van verplaatsingen: zowel de neerwaartse als rotatieverplaatsing moeten hetzelfde zijn als de neerwaartse en rotatieverplaatsing aan de linkerkant van element BE:\n", "\n", @@ -210,7 +210,7 @@ "\n", "::::::{prf:example-start}\n", ":nonumber: true\n", - ":label: df_example_5\n", + ":label: df_example_5_2\n", "\n", "::::::\n", "\n", From 29fe49b63c1c2bb6433e904cbff105f11e2c46e4 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Sat, 3 Jan 2026 15:46:57 +0100 Subject: [PATCH 051/110] zonder override --- book/_config.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/book/_config.yml b/book/_config.yml index ab31891..2b6da68 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -21,8 +21,6 @@ sphinx: - sphinx_apa_references - sphinx_tudelft_theme config: - sphinx_gated_directives: - override_existing: ['exercise'] language: en html_js_files: - https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js From 3f6d1f1d1b37811d7786c758c70db908825611f2 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 11:04:17 +0100 Subject: [PATCH 052/110] Update _config.yml --- book/_config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/book/_config.yml b/book/_config.yml index 2b6da68..ab31891 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -21,6 +21,8 @@ sphinx: - sphinx_apa_references - sphinx_tudelft_theme config: + sphinx_gated_directives: + override_existing: ['exercise'] language: en html_js_files: - https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js From c6e968a9473497d7a9eb3084bc9770dafd8532f9 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 11:06:32 +0100 Subject: [PATCH 053/110] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1c93c95..3c790d4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites +git+https://github.com/TeachBooks/TeachBooks-Favourites #bump codex teachbooks-sphinx-grasple From 688c16fe71c2ba208984d6573f25365205b9a8b3 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 11:23:45 +0100 Subject: [PATCH 054/110] Remove custom code alignment CSS and update requirements Deleted the code-align.css file that enforced left alignment for docutils code cells. Updated the requirements.txt comment for TeachBooks-Favourites to reference 'patches' instead of 'codex'. --- book/_static/code-align.css | 6 ------ requirements.txt | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 book/_static/code-align.css diff --git a/book/_static/code-align.css b/book/_static/code-align.css deleted file mode 100644 index b9b324a..0000000 --- a/book/_static/code-align.css +++ /dev/null @@ -1,6 +0,0 @@ -/* this to enforce left alignment for docutils content (i.e. code cells) */ -/* assumption is that all code is left aligned, so we enforce that */ -/* if not desired, raise an issue with a use case */ -div.cell.docutils.container { - text-align: left !important; -} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 3c790d4..5e3d9b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites #bump codex +git+https://github.com/TeachBooks/TeachBooks-Favourites #bump patches teachbooks-sphinx-grasple From abec15b938e181171dcdc057245fb63dded7ae7d Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 11:57:49 +0100 Subject: [PATCH 055/110] Switch sphinx_gated_directives to external package Removed the local sphinx_gated_directives extension and updated configuration to use the external package. Added Sphinx-Gated-Directives as a dependency in requirements.txt and adjusted _config.yml to load it as an extra extension. --- book/_config.yml | 3 +- book/_ext/sphinx_gated_directives/__init__.py | 545 ------------------ requirements.txt | 4 +- 3 files changed, 4 insertions(+), 548 deletions(-) delete mode 100644 book/_ext/sphinx_gated_directives/__init__.py diff --git a/book/_config.yml b/book/_config.yml index ab31891..02e26d1 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -11,8 +11,6 @@ html: baseurl : "https://teachbooks.io/manual/" sphinx: - local_extensions: - sphinx_gated_directives: _ext extra_extensions: - sphinx_inline_tabs - sphinx.ext.imgconverter @@ -20,6 +18,7 @@ sphinx: - teachbooks_sphinx_grasple - sphinx_apa_references - sphinx_tudelft_theme + - sphinx_gated_directives config: sphinx_gated_directives: override_existing: ['exercise'] diff --git a/book/_ext/sphinx_gated_directives/__init__.py b/book/_ext/sphinx_gated_directives/__init__.py deleted file mode 100644 index 5aef914..0000000 --- a/book/_ext/sphinx_gated_directives/__init__.py +++ /dev/null @@ -1,545 +0,0 @@ -""" -~~~~~~~~~~~~~~~~~~~~ - -sphinx_gated_directives - -~~~~~~~~~~~~~~~~~~~~ - -This package is an extension for Sphinx that creates a '-start' companion -and a '-end' companion for every registered class-based directive. - -These new directives can be used to "gate" content in the documentation, -similar to how the gated directives of sphinx-exercise work. - -This extension is based on the extension executablebooks/sphinx-exercise: -https://github.com/executablebooks/sphinx-exercise - -Original project licensed under MIT © Executable Books Developers. -See the repository LICENSE for details. - -Our implementation reuses certain ideas and code snippets (e.g., Docutils -compatibility helpers) to fit the needs of this extension. - -""" - -from __future__ import annotations -from docutils.nodes import Element -from typing import Iterator -import copy -import importlib -import inspect -from typing import Dict, Iterable, Optional -from sphinx.transforms import SphinxTransform -from sphinx.application import Sphinx -from sphinx.environment import BuildEnvironment - -from sphinx.util import logging -logger = logging.getLogger(__name__) - -from docutils import nodes -from docutils.parsers.rst import Directive -from docutils.parsers.rst import directives as du_directives - -from dataclasses import dataclass, field - -SUFFIX_START = "start" -SUFFIX_END = "end" -SUFFIX_SEPARATOR = "-" - -def _is_class_directive(obj) -> bool: - return inspect.isclass(obj) and issubclass(obj, Directive) - -def _get_unified_registry(app=None) -> Dict[str, object]: - # 1) Already-loaded directives (includes Sphinx & extensions registered via add_directive) - unified: Dict[str, object] = dict(getattr(du_directives, "_directives", {})) - - # 2) Ensure Docutils built-ins are present by importing from _directive_registry - reg = getattr(du_directives, "_directive_registry", {}) - for name, (modname, clsname) in reg.items(): - if name in unified: - continue - try: - mod = importlib.import_module(f"docutils.parsers.rst.directives.{modname}") - obj = getattr(mod, clsname, None) - if obj is not None: - unified[name] = obj - except Exception: - # Be defensive: if an import fails, just skip that name - continue - - # 3) Add Sphinx's registry if app is provided - if app is not None: - # Sphinx stores directives in app.registry - # Try different ways to access the directives mapping - if hasattr(app.registry, 'directives'): - # Newer Sphinx versions may have a directives attribute - try: - unified.update(app.registry.directives) - except (AttributeError, TypeError): - pass - - # Also check for domains which contain directives (e.g., prf:theorem from sphinx-proof) - if hasattr(app.registry, 'domains'): - for domain_name, domain_cls in app.registry.domains.items(): - try: - # Instantiate domain or use class attributes - if hasattr(domain_cls, 'directives'): - domain_directives = domain_cls.directives - for dir_name, dir_impl in domain_directives.items(): - # Fully qualified name: domain:directive - full_name = f"{domain_name}:{dir_name}" - if full_name not in unified: - unified[full_name] = dir_impl - except Exception: - continue - - return unified - -def _copy_option_spec(option_spec): - return copy.copy(option_spec) if isinstance(option_spec, dict) else option_spec - -def make_start_class(orig_name: str, base_cls: type[Directive]) -> type[Directive]: - - attrs = {} - for attr in ( - "required_arguments", - "optional_arguments", - "final_argument_whitespace", - "has_content", - "option_spec", - ): - if hasattr(base_cls, attr): - val = getattr(base_cls, attr) - if attr == "option_spec": - attrs[attr] = _copy_option_spec(val) or {} - else: - attrs[attr] = val - - def run(self: Directive): - current_name = self.name - self.name = orig_name # temporarily set to original for base run() - children = base_cls.run(self) - self.name = current_name # restore - if not isinstance(children, list): - if isinstance(children, Iterable): - children = list(children) - else: - children = [children] - # create a start_node and add all result nodes as its children - start_node_instance = start_node() - start_node_instance += children - result = [start_node_instance] - - # Get environment from state.document.settings - env = getattr(self.state.document.settings, "env", None) - if env is not None: - docname = env.docname - # 1) Check whether super registry has been created, if not, create it - if not hasattr(env, "sphinx_gated_directives_registry"): - env.sphinx_gated_directives_registry = {} - # 2) Register current usage in the super registry - registry = env.sphinx_gated_directives_registry - if docname not in registry: - registry[docname] = { - "start": [], - "end": [], - "sequence": [], - "msg": [], - "type": [], - } - registry[docname]["start"].append(self.lineno) - registry[docname]["sequence"].append("S") - registry[docname]["msg"].append( - f"{self.name} at line: {self.lineno}" - ) - registry[docname]["type"].append(orig_name) - - return result - - attrs["run"] = run - new_cls_name = f"{base_cls.__name__}_Start_For_{orig_name.replace(':', '_')}" - return type(new_cls_name, (base_cls,), attrs) - -def make_end_class(orig_name: str, base_cls: type[Directive]) -> type[Directive]: - - attrs = {} - for attr in ( - "required_arguments", - "optional_arguments", - "final_argument_whitespace", - "has_content", - "option_spec", - ): - if hasattr(base_cls, attr): - val = getattr(base_cls, attr) - if attr == "option_spec": - attrs[attr] = _copy_option_spec(val) or {} - else: - attrs[attr] = val - - def run(self: Directive): - - # Get environment from state.document.settings - env = getattr(self.state.document.settings, "env", None) - if env is not None: - docname = env.docname - # 1) Check whether super registry has been created, if not, create it - if not hasattr(env, "sphinx_gated_directives_registry"): - env.sphinx_gated_directives_registry = {} - # 2) Register current usage in the super registry - registry = env.sphinx_gated_directives_registry - if docname not in registry: - registry[docname] = { - "start": [], - "end": [], - "sequence": [], - "msg": [], - "type": [], - } - registry[docname]["end"].append(self.lineno) - registry[docname]["sequence"].append("E") - registry[docname]["msg"].append( - f"{self.name} at line: {self.lineno}" - ) - registry[docname]["type"].append(orig_name) - - return [end_node()] - - attrs["run"] = run - new_cls_name = f"{base_cls.__name__}_End_For_{orig_name.replace(':', '_')}" - return type(new_cls_name, (base_cls,), attrs) - -def _should_skip_name(orig_name: str, cfg: dict) -> bool: - suffix_separator = cfg["suffix_separator"] - suffix_start = cfg["suffix_start"] - suffix_end = cfg["suffix_end"] - if isinstance(cfg["override_existing"],bool): - if cfg["override_existing"] is True: - return False - else: - if orig_name.endswith(f"{suffix_separator}{suffix_start}"): - return True - else: - return orig_name.endswith(f"{suffix_separator}{suffix_end}") - elif isinstance(cfg["override_existing"],list): - if orig_name in cfg["override_existing"]: - return False - else: - if orig_name.endswith(f"{suffix_separator}{suffix_start}"): - return True - else: - return orig_name.endswith(f"{suffix_separator}{suffix_end}") - -def _register_new_directives(app, env, docnames): - - # get options and add missing default values - cfg = app.config.sphinx_gated_directives - if "override_existing" not in cfg: - cfg["override_existing"] = False - elif isinstance(cfg["override_existing"], str): - cfg["override_existing"] = [cfg["override_existing"]] - if "suffix_start" not in cfg: - cfg["suffix_start"] = SUFFIX_START - if "suffix_end" not in cfg: - cfg["suffix_end"] = SUFFIX_END - if "suffix_separator" not in cfg: - cfg["suffix_separator"] = SUFFIX_SEPARATOR - - unified = _get_unified_registry(app) - snapshot_names = set(unified.keys()) - added = 0 - - suffix_separator = cfg["suffix_separator"] - suffix_start = cfg["suffix_start"] - suffix_end = cfg["suffix_end"] - for orig_name, obj in sorted(unified.items()): - - new_name = f"{orig_name}{suffix_separator}{suffix_start}" - # add start and end directives if not already present, or if override is requested explicitly - if new_name in snapshot_names: - if isinstance(cfg["override_existing"], bool): - if cfg["override_existing"] is False: - continue - else: - if orig_name not in cfg["override_existing"]: - continue - end_name = f"{orig_name}{suffix_separator}{suffix_end}" - if end_name in snapshot_names: - if isinstance(cfg["override_existing"], bool): - if cfg["override_existing"] is False: - continue - else: - if orig_name not in cfg["override_existing"]: - continue - - # if the original name is itself a start or end directive, skip - if _should_skip_name(orig_name,cfg): - continue - - try: - if _is_class_directive(obj): - start_cls = make_start_class(orig_name, obj) # new class based on original so all properties are inherited - app.add_directive(new_name, start_cls,override=True) - end_cls = make_end_class(orig_name, Directive) # because it does not generate anything, most simple directive possible - app.add_directive(end_name, end_cls,override=True) - added += 1 - else: - logger.debug(f"[sphinx-gated-directives] '{orig_name}' is not a class directive; skipping.") - except Exception as e: - logger.warning(f"[sphinx-gated-directives] failed to register new classes for directive '{orig_name}':\n{e}") - -def setup(app): - # Register a config value to set options for the extension - app.add_config_value("sphinx_gated_directives", {}, "env") - - # Register a function to check if config value structure is correct - app.connect("config-inited", check_config_values) - - # register function to purge registries at start of build per document - app.connect("env-purge-doc", purge_registries) - - # At the latest possible moment, register new directives - app.connect("env-before-read-docs", _register_new_directives,priority=10000000000000000000000000000) - - # Register nodes - # During transformation phase, these nodes will be removed - app.add_node(start_node) - app.add_node(end_node) - - # Register a transform to check validity of start-end pairs - app.add_transform(CheckGatedDirectivesTransform) - - # Register a transform to merge start-end pairs into gated content - app.add_transform(MergeGatedDirectivesTransform) - - return { - "parallel_read_safe": True, - } - -class start_node(nodes.Admonition, nodes.Element): - pass - -class end_node(nodes.Admonition, nodes.Element): - pass - -def purge_registries(app: Sphinx, env: BuildEnvironment, docname: str) -> None: - - if hasattr(env, "sphinx_gated_directives_registry"): - registry = env.sphinx_gated_directives_registry - if docname in registry: - del registry[docname] - -# Transform to check validity of start-end pairs -class CheckGatedDirectivesTransform(SphinxTransform): - default_priority = 1 - - def apply(self, **kwargs): - env = self.env - if not hasattr(env, "sphinx_gated_directives_registry"): - return - - registry = env.sphinx_gated_directives_registry - error = False - docname = self.env.docname - if docname in registry: - start = registry[docname]["start"] - end = registry[docname]["end"] - structure = "\n ".join(registry[docname]["msg"]) - sequence = "".join(registry[docname]["sequence"]) - validate_SE_result = validate_SE(sequence) - if len(start) > len(end): - msg = f"[sphinx-gated-directives] The document {docname} contains more start directives than end directives:\n {structure}\nPlease ensure each start directive has a corresponding end directive." - logger.error(msg) - error = True - elif len(end) > len(start): - msg = f"[sphinx-gated-directives] The document {docname} contains more end directives than start directives:\n {structure}\nPlease ensure each end directive has a corresponding start directive." - logger.error(msg) - error = True - # at this point, len(start) == len(end) - # now check for correct nesting - elif not validate_SE_result.is_valid: - msg = f"[sphinx-gated-directives] The document {docname} contains incorrectly nested start and end directives:\n {structure}\nThis is not allowed. Please correct the nesting." - logger.error(msg) - error = True - else: - # At this point, every start is matched with an end - # Now check that types match in order. - types = registry[docname]["type"] - start_type = [types[k] for k in validate_SE_result.pairs.keys()] - end_type = [types[v] for v in validate_SE_result.pairs.values()] - for i in range(len(start_type)): - if start_type[i] != end_type[i]: - msg = f"[sphinx-gated-directives] The document {docname} contains mismatched start and end directives at lines {start[i]} and {end[i]}:\n {structure}\nPlease ensure that start and end directives match in type." - logger.error(msg) - error = True - break - - if error: - raise Exception(f"[sphinx-gated-directives] An error has occurred when parsing gated directives in {docname}.\nPlease check warning messages above.") - -class MergeGatedDirectivesTransform(SphinxTransform): - default_priority = 10 - - def apply(self, **kwargs): - env = self.env - if not hasattr(env, "sphinx_gated_directives_registry"): - return - registry = env.sphinx_gated_directives_registry - docname = self.env.docname - if docname not in registry: - return - - start_nodes = findall(self.document, start_node) - for start_n in start_nodes: - parent = start_n.parent - found_start = False - end_n = None - skip_end = 0 - for child in parent.children: - if child is start_n: - found_start = True - elif found_start and isinstance(child, end_node) and skip_end==0: - end_n = child - break - elif found_start and isinstance(child, end_node): - skip_end -= 1 - elif found_start and isinstance(child, start_node): - skip_end += 1 - if end_n is None: - logger.error(f"[sphinx-gated-directives] Could not find matching end directive for start directive at line {start_n.line} in document {docname}. Skipping merging for this pair.") - raise Exception(f"[sphinx-gated-directives] An error has occurred when parsing gated directives in {docname}.\nPlease check warning messages above.") - - start_index = parent.children.index(start_n) - end_index = parent.children.index(end_n) - between_nodes = parent.children[start_index + 1:end_index] - - new_nodes = start_n.children - if between_nodes: - has_section = False - has_caption = False - si = -1 - content = new_nodes[-1] - for sn in content.children: - si += 1 - if isinstance(sn, nodes.section): - has_section = True - section_index = si - section_node = sn - break - elif isinstance(sn, nodes.caption): - has_caption = True - caption_index = si - caption_node = sn - break - if has_section: - content[section_index] += between_nodes - elif has_caption: - n = len(content.children) - pos = n - 1 - for i, bn in enumerate(between_nodes): - content.insert(pos + i, bn) - else: - for bn in between_nodes: - content += bn - - start_pos = parent.children.index(start_n) - parent.remove(end_n) - parent.remove(start_n) - for bn in between_nodes: - parent.remove(bn) - for i, nn in enumerate(new_nodes): - parent.insert(start_pos + i, nn) - - -# SPDX-License-Identifier: MIT -# Adapted from: executablebooks/sphinx-exercise, file: sphinx_exercise/_compat.py -# Source: https://github.com/executablebooks/sphinx-exercise/blob/main/sphinx_exercise/_compat.py -# License: MIT — © Executable Books Developers (see repository LICENSE). -def findall(node: Element, *args, **kwargs) -> Iterator[Element]: - # findall replaces traverse in docutils v0.18 - # note a difference is that findall is an iterator - impl = getattr(node, "findall", node.traverse) - return iter(impl(*args, **kwargs)) - -@dataclass -class SEValidationResult: - is_valid: bool - pairs: Dict[int, int] = field(default_factory=dict) # {S_index: E_index} - error_index: Optional[int] = None # index of first error, if any - error_message: Optional[str] = None # description of the error, if any - -def validate_SE(s: str) -> SEValidationResult: - stack = [] - pairs: Dict[int, int] = {} - - for i, ch in enumerate(s): - if ch == 'S': - stack.append(i) - elif ch == 'E': - if not stack: - return SEValidationResult( - is_valid=False, - pairs=pairs, - error_index=i, - error_message="Encountered 'E' before a matching 'S'." - ) - s_index = stack.pop() - pairs[s_index] = i - else: - return SEValidationResult( - is_valid=False, - pairs=pairs, - error_index=i, - error_message=f"Invalid character: {ch!r}. Only 'S' and 'E' are allowed." - ) - - if stack: - return SEValidationResult( - is_valid=False, - pairs=pairs, - error_index=len(s), - error_message=f"{len(stack)} unmatched 'S' remaining at end." - ) - - return SEValidationResult(is_valid=True, pairs=pairs) - -def check_config_values(app: Sphinx, config) -> None: - cfg = config.sphinx_gated_directives - if not isinstance(cfg, dict): - logger.error("[sphinx-gated-directives] The configuration value 'sphinx_gated_directives' should be a dictionary.") - raise ValueError("Invalid configuration for 'sphinx_gated_directives'. Expected a dictionary.") - return - # Implemented options: - # - override_existing: bool (default: False), string or list of strings - override_existing = cfg.get("override_existing", False) - if not (isinstance(override_existing, bool) or isinstance(override_existing, str) or (isinstance(override_existing, list) and all(isinstance(x, str) for x in override_existing))): - logger.error("[sphinx-gated-directives] The configuration option 'override_existing' should be a boolean, a string, or a list of strings.") - raise ValueError("Invalid configuration for 'sphinx_gated_directives.override_existing'. Expected a boolean, string, or list of strings.") - # - suffix_start: string (default: 'start'), only a-z allowed, or empty string - suffix_start = cfg.get("suffix_start", SUFFIX_START) - if not isinstance(suffix_start, str): - logger.error("[sphinx-gated-directives] The configuration option 'suffix_start' should be a string.") - raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_start'. Expected a string.") - if suffix_start != "" and (not suffix_start.islower() or not suffix_start.isalpha()): - logger.error("[sphinx-gated-directives] The configuration option 'suffix_start' should contain only lowercase letters (a-z).") - raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_start'. Expected only lowercase letters (a-z).") - # - suffix_end: string (default: 'end'), only a-z allowed, or empty string - suffix_end = cfg.get("suffix_end", SUFFIX_END) - if not isinstance(suffix_end, str): - logger.error("[sphinx-gated-directives] The configuration option 'suffix_end' should be a string.") - raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_end'. Expected a string.") - if suffix_end != "" and (not suffix_end.islower() or not suffix_end.isalpha()): - logger.error("[sphinx-gated-directives] The configuration option 'suffix_end' should contain only lowercase letters (a-z).") - raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_end'. Expected only lowercase letters (a-z).") - # - suffix_separator: string (default: '-'), single character, no space, no underscore, no colon, or empty string - suffix_separator = cfg.get("suffix_separator", SUFFIX_SEPARATOR) - if not isinstance(suffix_separator, str): - logger.error("[sphinx-gated-directives] The configuration option 'suffix_separator' should be a string.") - raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_separator'. Expected a string.") - if len(suffix_separator) > 1: - logger.error("[sphinx-gated-directives] The configuration option 'suffix_separator' should be a single character or an empty string.") - raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_separator'. Expected a single character or an empty string.") - if suffix_separator in [' ', '_',':']: - logger.error("[sphinx-gated-directives] The configuration option 'suffix_separator' should not be a space, nor an underscore, nor a colon.") - raise ValueError("Invalid configuration for 'sphinx_gated_directives.suffix_separator'. Expected something other than a space, an underscore, or a colon.") - \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 5e3d9b4..770b879 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,6 @@ myst_nb numpy matplotlib -sphinx-tudelft-theme == 1.2.1 \ No newline at end of file +sphinx-tudelft-theme == 1.2.1 + +git+https://github.com/TeachBooks/Sphinx-Gated-Directives \ No newline at end of file From dda97322466371ce97f4163fabe6c1a329966ae4 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 12:26:58 +0100 Subject: [PATCH 056/110] Update comment for TeachBooks-Favourites dependency Changed the comment for the TeachBooks-Favourites git dependency from 'bump patches' to 'bump codex' to clarify the purpose of the dependency update. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 770b879..1e0384a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.3 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites #bump patches +git+https://github.com/TeachBooks/TeachBooks-Favourites #bump codex teachbooks-sphinx-grasple From 804bae0deec3860af0036d73028f8dfb21d41389 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 13:05:52 +0100 Subject: [PATCH 057/110] Add note inside axiom-end directive in intro Inserted a line of text within the prf:axiom-end directive in intro.md to clarify that this text will not be rendered. --- book/intro.md | 1 + 1 file changed, 1 insertion(+) diff --git a/book/intro.md b/book/intro.md index 4df190b..fae52ac 100644 --- a/book/intro.md +++ b/book/intro.md @@ -24,6 +24,7 @@ This is a child axiom. This text is inside the child directive. This is text after the child-start, before the child-end, inside the parent theorem. :::{prf:axiom-end} +Text inside the end. This text will not be rendered. ::: Finally some text after the entire child, inside the theorem start. From ab38930bb3b16e4844ed98bd9fe669916aa14ab5 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 16:20:16 +0100 Subject: [PATCH 058/110] Update TOC and requirements for TeachBooks changes Added an external manual link to the table of contents. Updated requirements to use TeachBooks from the 'issue-127' branch and adjusted comments for clarity. --- book/_toc.yml | 1 + requirements.txt | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/book/_toc.yml b/book/_toc.yml index 561237f..6c408a7 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -4,6 +4,7 @@ root: intro parts: - caption: test sphinx_gated_directives chapters: + - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md - file: instructie.ipynb - file: instructie_2.ipynb - file: lesoefeningen.ipynb diff --git a/requirements.txt b/requirements.txt index 1e0384a..946f15a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ -teachbooks == 0.2.3 +# teachbooks == 0.2.3 +git+https://github.com/TeachBooks/TeachBooks@issue-127 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites #bump codex +git+https://github.com/TeachBooks/TeachBooks-Favourites teachbooks-sphinx-grasple From a4cb6d70904bffdda6a4db4a9d922223fed1cefc Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 16:51:14 +0100 Subject: [PATCH 059/110] Remove obsolete instruction notebooks and update ToC Deleted instructie.ipynb, instructie_2.ipynb, and lesoefeningen.ipynb from the book. Updated _toc.yml to remove references to these files and moved the Sphinx-Gated-Directives manual link to the correct section. Minor update to intro.md. --- book/_toc.yml | 7 +- book/instructie.ipynb | 1470 -------------------------------------- book/instructie_2.ipynb | 1470 -------------------------------------- book/intro.md | 205 ------ book/lesoefeningen.ipynb | 316 -------- 5 files changed, 1 insertion(+), 3467 deletions(-) delete mode 100644 book/instructie.ipynb delete mode 100644 book/instructie_2.ipynb delete mode 100644 book/lesoefeningen.ipynb diff --git a/book/_toc.yml b/book/_toc.yml index 6c408a7..6441842 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -2,12 +2,6 @@ format: jb-book root: intro parts: - - caption: test sphinx_gated_directives - chapters: - - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md - - file: instructie.ipynb - - file: instructie_2.ipynb - - file: lesoefeningen.ipynb - caption: Your First TeachBook! chapters: - file: intro/book.md @@ -95,6 +89,7 @@ parts: - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb # BUMP + - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md diff --git a/book/instructie.ipynb b/book/instructie.ipynb deleted file mode 100644 index e2ec472..0000000 --- a/book/instructie.ipynb +++ /dev/null @@ -1,1470 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "````{margin}\n", - "```{attributiongrey} Attribution\n", - ":class: attribution\n", - "\n", - "Deze pagina is aangepast van https://github.com/TUDelft-books/CT1000/blob/2025/book/week_2/session_1/intro.ipynb\n", - "\n", - "% Figures from https://github.com/TUDelft-books/CT1000/blob/2025/book/week_2/session_1/intro_data/Tekening1.vsdx\n", - "\n", - "```\n", - "```` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Instructie_oud\n", - "\n", - "In constructiemechanica 2 heb je geleerd hoe je met differentiaalvergelijkingen voor statisch bepaalde constructies de krachtsverdeling en vervormingen kan vinden. Precies dezelfde aanpak werkt ook voor statisch onbepaalde constructie, met als enige verschil dat we de inwendige krachten niet kunnen vinden zonder ook de vergelijkingen en randvoorwaarden voor verplaatsingen op te stellen. Dat doen we volgens de volgende stappen:\n", - "\n", - "::::::{prf:algorithm} Differentiaalvergelijkingen toepassen\n", - ":nonumber: true\n", - ":label: differentiaalvergelijkingen_algoritme\n", - "\n", - "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", - "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", - "3. Er zijn nog meer vergelijkingen nodig om alle onbekende integratieconstantes op te lossen, deze kunnen we vinden door de overgangen tussen de verschillende elementen te analyseren waarbij zowel verplaatsingen als krachten in overeenstemming moeten zijn.\n", - "4. Er zijn nu evenveel vergelijkingen als onbekenden opgesteld. Deze kunnen nu worden opgelost en ingevuld in de opgestelde vergelijkingen voor het gewenste resultaat. Omdat het aantal onbekenden bij statisch onbepaalde constructies als snel uit de hand loopt wordt wordt aangeraden om je rekenmachine of een symbolische wiskundetool te gebruiken om dit op te lossen. Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python. Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt:\n", - "\n", - "::::::\n", - "\n", - "Als voorbeeld bepalen we de een simpele statisch onbepaalde constructie:\n", - "\n", - "::::::{prf:example}\n", - ":nonumber: true\n", - ":label: df_example_0\n", - "\n", - "Gegeven een constructie zoals hieronder weergegeven:\n", - "\n", - "```{figure} intro_data/structure.svg\n", - "---\n", - "align: center\n", - "---\n", - "Constructie, $EI = 5000 \\ \\rm{kNm^2}$\n", - "```\n", - "::::::\n", - "\n", - "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", - "\n", - "::::::{prf:example}\n", - ":nonumber: true\n", - ":label: df_example_1\n", - "\n", - "In dit voorbeeld moeten we element AB in twee delen opsplitsen omdat de verdeelde belasting een discontinuïteit veroorzaakt.\n", - "\n", - "Voor AC leidt dit tot:\n", - "\n", - "```{figure} intro_data/FBD_AC.svg\n", - ":align: center\n", - "\n", - "Vrijlichaamdiagram element AC\n", - "```\n", - "\n", - "Voor BC leidt dit tot:\n", - "\n", - "```{figure} intro_data/FBD_BC.svg\n", - ":align: center\n", - "\n", - "Vrijlichaamdiagram element BC\n", - "```\n", - "::::::" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", - "\n", - "::::::{prf:example}\n", - ":nonumber: true\n", - ":label: df_example_3\n", - "\n", - "In dit voorbeeld is er enkel invloed door buiging, dus hebben we aan deze differentiaalvergelijking genoeg: $ -EI \\cfrac{{d}^4w}{{d}x^4} = -q_z$. De differentiaalvergelijkingen voor rek $ EA \\cfrac{{d}^2u}{{d}x^2} = -q_x$ en torsie $ GI \\cfrac{{d}^2\\varphi_x}{{d}x^2} = -q_T$ hebben we in dit geval niet nodig.\n", - "\n", - "**Element AC**\n", - "\n", - "Omdat dit element onbelast is, geeft de belastingsvergelijking voor dit element:\n", - "\n", - "$$q_{z,{\\rm{AC}}}=0$$\n", - "\n", - "wat leidt tot de vergelijkingen:\n", - "\n", - "$$ V_{\\rm{AC}} \\left(x\\right) = C_1$$\n", - "\n", - "$$ M_{\\rm{AC}} \\left(x\\right) = C_1 \\cdot x + C_2 $$\n", - "\n", - "$$ \\kappa_{\\rm{AC}} \\left(x\\right) = \\cfrac{C_1 \\cdot x + C_2}{5000}$$\n", - "\n", - "$$ \\varphi_{\\rm{AC}} \\left(x\\right) = \\cfrac{\\cfrac{1}{2}\\cdot C_1 \\cdot x^2 + C_2 \\cdot x}{5000} + C_3$$\n", - "\n", - "$$ w_{\\rm{AC}} \\left(x\\right) = \\cfrac{-\\cfrac{1}{6}\\cdot C_1 \\cdot x^3 - \\cfrac{1}{2} C_2 \\cdot x^2}{5000} - C_3 \\cdot x + C_4$$\n", - "\n", - "Vanwege de oplegging bij A kan een randvoorwaarde worden geformuleerd als:\n", - "\n", - "```{math}\n", - ":label: BC_1\n", - "w_{\\rm{AC}} \\left(0\\right) = 0\n", - "```\n", - "\n", - "Omdat A ook een onbelast uiteinde is, kan een andere randvoorwaarde worden geformuleerd als:\n", - "\n", - "```{math}\n", - ":label: BC_2\n", - "M_{\\rm{AC}} \\left(0\\right) = 0\n", - "```\n", - "\n", - "Als dit uiteinde belast werd kon met een krachten- of momentenevenwicht ook een relatie gevonden worden.\n", - "\n", - "**Element BC**\n", - "\n", - "Omdat dit element belast is, geeft de belastingsvergelijking voor dit element:\n", - "\n", - "$$q_{z,\\rm{BC}}=10$$\n", - "\n", - "wat leidt tot de vergelijkingen:\n", - "\n", - "$$ V_{\\rm{BC}} \\left(x\\right) = -10 \\cdot x + C_5$$\n", - "\n", - "$$ M_{\\rm{BC}} \\left(x\\right) = -5 \\cdot x^2 + C_5 \\cdot x + C_6 $$\n", - "\n", - "$$ \\kappa_{\\rm{BC}} \\left(x\\right) = \\cfrac{-5 \\cdot x^2 + C_5 \\cdot x + C_6}{5000}$$\n", - "\n", - "$$ \\varphi_{\\rm{BC}} \\left(x\\right) = \\cfrac{-\\cfrac{5}{3} \\cdot x^3 + \\cfrac{1}{2}\\cdot C_5 \\cdot x^2 + C_6 \\cdot x}{5000} + C_7$$\n", - "\n", - "$$ w_{\\rm{BC}} \\left(x\\right) = \\cfrac{\\cfrac{5}{12} \\cdot x^4 -\\cfrac{1}{6}\\cdot C_5 \\cdot x^3 - \\cfrac{1}{2} C_6 \\cdot x^2}{5000} - C_7 \\cdot x + C_8$$\n", - "\n", - "Vanwege de inklemming bij B kunnen twee randvoorwaarden direct worden geformuleerd:\n", - "\n", - "```{math}\n", - ":label: BC_3\n", - "\\varphi_{\\rm{BC}} \\left(4\\right) = 0\n", - "```\n", - "\n", - "```{math}\n", - ":label: BC_4\n", - "w_{\\rm{BC}} \\left(4\\right) = 0\n", - "```\n", - "\n", - "::::::" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "3. Er zijn nog meer vergelijkingen nodig om alle onbekende integratieconstantes op te lossen, deze kunnen we vinden door de overgangen tussen de verschillende elementen te analyseren waarbij zowel verplaatsingen als krachten in overeenstemming moeten zijn.\n", - "\n", - "::::::{prf:example}\n", - ":nonumber: true\n", - ":label: df_example_4\n", - "\n", - "Bij C kan een randvoorwaarde worden geïdentificeerd uit de consistentie van verplaatsingen: zowel de neerwaartse als rotatieverplaatsing moeten hetzelfde zijn als de neerwaartse en rotatieverplaatsing aan de linkerkant van element BE:\n", - "\n", - "```{math}\n", - ":label: BC_5\n", - "w_{\\rm{AC}} \\left(4\\right) = w_{\\rm{BC}} \\left(0\\right)\n", - "```\n", - "\n", - "```{math}\n", - ":label: BC_6\n", - "\\varphi_{\\rm{AC}} \\left(4\\right) = \\varphi_{\\rm{BC}} \\left(0 \\right)\n", - "```\n", - "\n", - "Ten slotte moet er ook consistentie zijn met de snedekrachten, zoals getoond in het vrijlichaamdiagram:\n", - "\n", - "```{figure} intro_data/FBD_C.svg\n", - ":align: center\n", - "\n", - "Vrijlichaamdiagram knoop C\n", - "```\n", - "\n", - "Verticaal evenwicht geeft:\n", - "\n", - "```{math}\n", - ":label: BC_7\n", - "\\sum {{{\\left. {{F_{\\rm{v}}}} \\right|}^{\\rm{C}}} = 0} \\to -{V_{\\rm{AC}}}\\left(4\\right) + V_{\\rm{BC}}\\left(0\\right) = 0\n", - "```\n", - "\n", - "Momentevenwicht geeft:\n", - "\n", - "```{math}\n", - ":label: BC_8\n", - "\\sum {{{\\left. {{T}} \\right|}_{\\rm{C}}^{\\rm{C}}} = 0} \\to -{M_{{\\rm{AC}}}}\\left(4\\right) + M_{\\rm{BC}}\\left(0\\right) = 0\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "4. Er zijn nu evenveel vergelijkingen als onbekenden opgesteld. Deze kunnen nu worden opgelost en ingevuld in de opgestelde vergelijkingen voor het gewenste resultaat. Omdat het aantal onbekenden bij statisch onbepaalde constructies als snel uit de hand loopt wordt wordt aangeraden om je rekenmachine of een symbolische wiskundetool te gebruiken om dit op te lossen. Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python. Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt:\n", - "\n", - "\n", - "::::::{codex-start}\n", - ":nonumber: true\n", - ":label: df_example_5\n", - "\n", - "::::::\n", - "\n", - "Er zijn 8 randvoorwaarden geformuleerd met 8 integratieconstanten. Deze kunnen nu worden opgelost. \n", - "\n", - "Het invullen van de randvoorwaarden geeft:\n", - "\n", - "$$\n", - "\\begin{align}\n", - "C_{4} = 0 \\\\\n", - "C_{2} = 0 \\\\\n", - "- \\cfrac{4 C_{5}}{1875} - \\cfrac{C_{6}}{625} - 4 C_{7} + C_{8} + \\cfrac{8}{375} = 0 \\\\\n", - "\\cfrac{C_{5}}{625} + \\cfrac{C_{6}}{1250} + C_{7} - \\cfrac{8}{375} = 0 \\\\\n", - "- \\cfrac{4 C_{1}}{1875} - \\cfrac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0 \\\\\n", - "\\cfrac{C_{1}}{625} + \\cfrac{C_{2}}{1250} + C_{3} - C_{7} = 0 \\\\\n", - "4 C_{1} + C_{2} - C_{6} = 0 \\\\\n", - "C_{1} - C_{5} = 0 \\\\\n", - "\\end{align}\n", - "$$\n", - "\n", - "Het oplossen hiervan geeft:\n", - "\n", - "$$\n", - "\\begin{align}\n", - "C_{1} = \\cfrac{35}{8} = 4.375 \\\\\n", - "C_{2} = 0 \\\\\n", - "C_{3} = - \\cfrac{1}{150} \\approx -0.006667 \\\\\n", - "C_{4} = 0 \\\\\n", - "C_{5} = \\cfrac{35}{8} = 4.375\\\\\n", - "C_{6} = \\cfrac{35}{2} = 17.5 \\\\\n", - "C_{7} = \\cfrac{1}{3000} \\approx 0.0003333\\\\\n", - "C_{8} = \\cfrac{13}{750} \\approx 0.01733\n", - "\\end{align}\n", - "$$\n", - "\n", - "Nu is de volledige krachtenverdeling en verplaatsingen van de constructie opgelost. Bijvoorbeeld de momentenverdeling in BC die kan worden uitgezet als:\n", - "\n", - "```{figure} intro_data/Momentenlijn.svg\n", - ":align: center\n", - "\n", - "Momentenlijn BC\n", - "```\n", - "\n", - "De krachtsverdeling en verplaatsingen kunnen no ook \n", - "\n", - "**Oplossen met digitale hulpmiddelen**\n", - "Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python.\n", - "\n", - "\n", - "$$\\left[\\begin{array}{cccccccc}0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & - \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1\\\\0 & 0 & 0 & 0 & \\frac{1}{625} & \\frac{1}{1250} & 1 & 0\\\\- \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1 & 0 & 0 & 0 & -1\\\\\\frac{1}{625} & \\frac{1}{1250} & 1 & 0 & 0 & 0 & -1 & 0\\\\4 & 1 & 0 & 0 & 0 & -1 & 0 & 0\\\\1 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\end{array}\\right] \\left[ \\begin{array}{cccccccc} C_1\\\\C_2\\\\C_3\\\\C_4\\\\C_5\\\\C_6\\\\C_7\\\\C_8 \\end{array} \\right] = \\left[\\begin{matrix}0\\\\0\\\\- \\frac{8}{375}\\\\\\frac{8}{375}\\\\0\\\\0\\\\0\\\\0\\end{matrix}\\right]$$\n", - "\n", - "[Hier](rref_ti_84) is uitgelegd hoe je dit op een grafische rekenmachine kan oplossen.\n", - "\n", - "Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt.\n", - "\n", - "Beide opties zijn hieronder getoond" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAASCAYAAADomNYKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAs9JREFUeJzl102o1FUYx/HPaEh2q3sxCgKtqNRdS7tgQi8g0SZXLgLBCiEsYnITFPTwBLqMUBRq0S2iVhEGtRF6WVTULktLbwTtgsDK6nbpzXFxztTcaeY2M3eGS/SF4YHznJfn9z/nPOeZRqvV0ovM3IwHsBPXYQY/4CRex4sR8UvPwatEZm7E07gbV+EbHEdGxPftfo1u0ZnZQOJxrMOH+BTncb3yETbg/YjYMWkhg5KZNymxXoM3cAbbcAfOYntEnINLeox/AXvxOe6LiJNdk6/HAdw8ofhH5Zgi+NGIONJuzMxn8BgO4iFY0zkqMw8ogr/AbLdgiIjFiDiI/ZOKflgy80blBH6No13uwAL2ZOYUHaIz81rla/yB3RHx03ILRcTi+MJeMXdWeyIiLnQ6qo4PcBlmWXq8m7gUcxFxatJRZmZTSY6D8klEHO/j21rtfB//l8pJ2IK3O0XvqvblIQJZCU0lMQ7KS0om7sV0tef7+NvtM9SdzszLla/QwsdDBPIXmfmEcj2ORsQj/9Y/Im4YZZ0RaVTb4u87fXW1P47y9mbmLPYpT9tq0N7J6T7+Kzv7tY/3QrXrM3NtRPw56GqZOY1X8CCeGmJc0/ju9Nlqt/Txb652nrrTEfGtku7X4fblVs7MNV1Nz+O1iHhnuXE9aCrPyaC/XcvM9W61O7vjy8wrsB2L+Iil2fvZ+juWmfdGxJmuwQ2lvLsfu2vbPqVI2TOw1Mo473REfJWZJ5QM/TCOdLgTU3guIhZYKvowblHq7c/qJPP4HZtwGzbiVcjMrTiEHRHx27gErID9Shl6ODPvUgqsW5UydB5Ptjv2qr3vUZLSNiXB/awU7qfxFt6MiHOZuRdz6Lz/a5UMeQFTEfHrBMT1JTM36f+H47t2v3+IHmKBGWXnO5lTCoFDOB0Ro00+YUYW3YvMfA+nBnmnV5PuTPy/YKw7/V/hImUh8qiSnFTZAAAAAElFTkSuQmCC", - "text/latex": [ - "$\\displaystyle C_{4} = 0$" - ], - "text/plain": [ - "C₄ = 0" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAASCAYAAADomNYKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAt9JREFUeJzV10+IVXUUB/DPTBGZmWIYBFpSaruWJZmRBSZtkhYGkZBBUAoxSRDS4nACV1HISANt+kPQMoxqIw1tKmqn/TGdCNwFQX+smYbIei1+99ad17vje773kL5wObx7fud3zvf3O+e8cyc6nY5eyMzNeAw7cQPW4GecxNt4PSJ+62l8iZCZ6/E8duFafIdjyIj4qV430U06MyeQeBZX4BN8jnO4UTmEtfgoIraPm0i/yMyblVivwzs4jduwA2ewLSJ+gMt72L+KR3EKD0fEya7NV+AgNo0p/ovFjEL4qYg4Wr/MzJfwNA7jCZhsWmXmQYXw19jaTRgiYjEiDmP/uKIfFJl5k5KBZ/FylzqwgL2ZuZIG6cy8XjmN89gTEb8u5ygiFkcX9tC4p5LHI+KvpqLi8TGuwlaWpvcUrsRrEfHluKPMzCmlOfaLExFxrEV3SyXnWvTfKJmwBbNN0rsr+eYAgQyDKaUx9os3lE7cC6srea5FX79fQ3XTmXm1cgodfNZvFJl5CA8qJ/07PsWhfjIlIjb262cEmKhkh39rel0lfxnwv/dupWveodTVeXyQmWuHj3Mg1De5ukV/TXNdnd4LlVyRmZdFxJ/9eIqI+5q/M3NvtfE2vLuc7Yhr+kwlt7ToN1dyjop0RHyfmWexUbm92TbPmTnZ3SEbWKVkz49t9g1MGV1Nf1jJnd3xZeYq5RIWlfJb0r2PVM9MZj4QEaebu1aT2i7sw54W50dwot58OYyypiPi28w8rnToAzjaUCdW4pWIWGAp6WncqszbX1SbzOEPbMCdWI+3ejnOzBdwF7b3Wx4jxn5lDJ3OzHuVAet2ZQydw3P1wl6z9/14XJlb12FeGdy/wvt4r55hGzYv4hHsiIhT4+F0YWTmBu0fHP+U3H9IX4SjaTzkEhMeBEORzswZ5YZ3Kx8oNeYjYn640MaHyQsvWRZPKh17Vkml+nlmyH3HiqHT+/+IvwHtQ/pzJbnwjAAAAABJRU5ErkJggg==", - "text/latex": [ - "$\\displaystyle C_{2} = 0$" - ], - "text/plain": [ - "C₂ = 0" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle - \\frac{4 C_{5}}{1875} - \\frac{C_{6}}{625} - 4 C_{7} + C_{8} + \\frac{8}{375} = 0$" - ], - "text/plain": [ - " 4⋅C₅ C₆ 8 \n", - "- ──── - ─── - 4⋅C₇ + C₈ + ─── = 0\n", - " 1875 625 375 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle \\frac{C_{5}}{625} + \\frac{C_{6}}{1250} + C_{7} - \\frac{8}{375} = 0$" - ], - "text/plain": [ - "C₅ C₆ 8 \n", - "─── + ──── + C₇ - ─── = 0\n", - "625 1250 375 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle - \\frac{4 C_{1}}{1875} - \\frac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0$" - ], - "text/plain": [ - " 4⋅C₁ C₂ \n", - "- ──── - ─── - 4⋅C₃ + C₄ - C₈ = 0\n", - " 1875 625 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle \\frac{C_{1}}{625} + \\frac{C_{2}}{1250} + C_{3} - C_{7} = 0$" - ], - "text/plain": [ - "C₁ C₂ \n", - "─── + ──── + C₃ - C₇ = 0\n", - "625 1250 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKoAAAAUCAYAAAAdtqaHAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAABSNJREFUeJztmmuoVUUYhp9jIpmaQhQIWqFp5A8pMjO8kB5QqR8eioxCRbtAqdjJbmjY62cYgVhHJSG01CQhsDAKBFG0sDQkVDKzk5L4I8HQsjSVLrsf36zarc5ae+3bWUfYDyxm77m+s5j5Zuab1VQoFEjCzKYD74S/j0tam5J3CPAIMBG4HugH/AwcBD4A1kv6LbGxnGnozwczGwAsASYD1wAngS2ASfopytc9pYKBwCrgHNA7JV8TYMALQA/gc2AzcBa4AX9xzcBDwNgq+lQXGvrzw8wG43qvAz4EjgAjgaeAyWY2WtJpSBioofPrgNP4bHw2pb23gZnAYeBhSQdjdfUE5gM3Vd6lZMxsZtA6XtKuCqrIVX8NuJz1r8YH6TxJq6JIM3sNeBpYCjwB0C2hgnnABGAWcD6pFTObj7+kb4BR8ZcEIOmCpKXA7Ep6Uk8a+vPDzAbh1v448EYsWfi4m25mvaCDgWpmtwCvAiskfZrSUH98xP8BTJX0a5owSReyd6P+NPTnzoQQbpP0V3FC6MtnwFXAKIgt/WbWHdgInAAWlmioFbgSWCfpUNWyO59WGvozY2at+AEtKwckbUlJvzmE7Qnp3+EWdyiwI75HfQm4DRiTYQa2hHBjiXxdlZYQNvRnoxU/nGVlA356T6JvCM8mpEfx/aDIoprZSNyKLpe0J02BmfXGR3oB+KKU4ljZccBzwO1Af+ABSZszlj1O8svaaWbxuA2SZnZQTzX6FwD34RbhErAXWJDFqpXQ3xHvSprWQT0V6w/l++Pbu3twj85RYK6kT5LKSLqx3HaqpCmEBQgDtWjJbwcWZajk2hD+UoFvrhfu21sHvF9m2Tb+v/zcCkzBZ/DxWNqBhHqq0X83flrdh7/MJcB2Mxsm6UyJsseAi2W09UNCfMX6zawfvv/bDdwL/AgMAk6VU08NiCxm34T0q4vzRRY1mqEAFzuwTABrzGwNsAJ4JcT1NLMrJP2ZVZ2krcBWgIR20sq2xeOCe2oK7tDelbGqyJNRif5Jsfan4y9zNPBRibLNWdspQcX6geeBk5JmFMV9X6pQHfao34ZwaEL6kBC2w7+n/kvAWwnP/pBnd/i/R9Ip3Hr1wC1MImaW5ALLjRrr74O/x1LWtGZUqb8F2Gtmm8zslJkdMLO5wXeeRivuNsr6tJSob2cIJ8Y1mlkffOJfwLdWblHDwemxhI4uxg9YG2JXqG3hWW1mUyQdiZVrwq/FZgFTS4jOgzZqo78N32LsrYfIEu22Ub7+QcAc4HVgEr51WoXvBeP+zH+o9R5V0jEz24af7OcEDRGGbxHflHQeUq5QM7ASGI7fL38VGm0HfgcGAmOAAcCmKtqoJ1XrN7NlwDhgbJnLby2oVH834EtJC8L//WY2FB8siQO1TszGr1BXmlkzfnFxJzAe78uLUcaKl2VJBUmP4hvyj/GZOQe3zMOBPfitybxK26gn1eo3s+XADKBZ0tFOkPwfqtB/Evg6FneY8rwRNUHSMWAEsB4foM8Ag/FJeFd0zw/QlPb1VL0xswJluKe6Cma2EngQ/77gcN56ysHMNgEDJY0tinsZuF/SsPyUpdPpAzX4AKMPJPbjPtXtwBlJJzpVTAWY2WpgGn5YKB6k5ySdy0VUGZjZHfhyuxh4Dz9/rAUWSurspT8zeZzIR+ADNPImLAu/l+SgpRKexE/6O/BlNHrSvjDrMkjah0+yqcAh/HuBRbhvuMuS69LfoEFWupyPs0GDjmgM1AaXBX8Db+ZLKnj2sa4AAAAASUVORK5CYII=", - "text/latex": [ - "$\\displaystyle 4 C_{1} + C_{2} - C_{6} = 0$" - ], - "text/plain": [ - "4⋅C₁ + C₂ - C₆ = 0" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAG4AAAAUCAYAAABs4ghcAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAA6lJREFUeJztmV2IVGUYx3+zimhWCn0KWy2adhGEkNSGFdWCCF20NwlFQqUXYmCTEhEh//6CV4aIktFNukR5Y2EUCEJ4VZt3iWF+sPkBfZOlohukTRfve7az48x4zsyZ2R3YHxwezvv5f+Y57+eUKpUKtbC9EHgZWAbcDcwF/gIOA58CuyVdrll5gulW7bZ7gU3AcuAW4GdgH2BJf6bLTq9RuQQYeAOYAXwN7AXOA/cQfowB4DngsXY50Qxdrn0BQe/twGfAMeAh4FVgue2lkv5Iyl8TOOAD4EXgKPC8pMNVHcwC1gP3tsOBFulm7TsJQVsnaUeSaHsr8BqwGViTpPeka9peT3D8e6C/2nEASaOSNgNr26G+Wbpc+3zCbHAaeLcqW8AlYKXt2UliT6ryPEJUrwArJF1s1Jmk0WJkt043a488Fe0BSf+mM6IvXwE3AP1JenqqLAMzgV2SvmuvzsIp02HttsuETU9WvpW0r07efdGeqJN/kjAiFwFfwvjADUb7YQ4xk4XBaDupvUzY8GRliLBDrMWcaM/XyU/S5yYJ0wFs30iIZgU4lFWJ7ceB14EHgXnAs5L2Zqx7mnyOfyTphRrtNKU91n2bsIak+VXSnderK6kvT18tUop27OyWjLjbor2Q83wzm3A22gV8klPMCPB3jvI/1UlvVnvCceCJ1PvVJtpolWREzamTf3NVubHAXYp2lu1pkjKJl7Qf2A9gO5dSSQO5KtSnKe0prkj6JW+nBa9xx6NdVCd/YbRja2APgKTfCFvRGYz/+q7Bdk+j/E5TgPb5tn+0fcr2Htt9GbsuE6bZrM9gg7YORrusWqPtm4ClwCjwTZKe3pxsi89O289IOlbVQIlwFfMSsCKjc51iG81pPwSsJHzJdwBvAsO275d0rlGHRa5xkkZsHyDsHF8BdqSyTViS3peUzC7jArcdeIBwx3ckNnQC+Ae4C3gU6AU+LkpwgTSlPU71CUdsDwM/EA7yW9svexxrCVde220PEC4SHgaeJPjyVrrw2LCUVJG0Cnga+AJYTIj+asKPMkxwaF27PchLUdrjF32U/9eUjiFpBFgC7CYEbAOwgPBRPpK+pwQo1ft3IC+2K+Q4DkxGbM8ETgHvSdo00XoaUeuSOTPxDJW+sO2zvRg4J+lsK213AtvvAJ8DZwkXvBsJ68nQROrKQkuBIwztg6n3LdEOEaamyU4vsAe4FfidsGvrl3RmQlVloLCpcorOMqnOZFNkZypwXcp/TvVqwtp6oi4AAAAASUVORK5CYII=", - "text/latex": [ - "$\\displaystyle C_{1} - C_{5} = 0$" - ], - "text/plain": [ - "C₁ - C₅ = 0" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "C_{4} = 0\n", - "C_{2} = 0\n", - "- \\frac{4 C_{5}}{1875} - \\frac{C_{6}}{625} - 4 C_{7} + C_{8} + \\frac{8}{375} = 0\n", - "\\frac{C_{5}}{625} + \\frac{C_{6}}{1250} + C_{7} - \\frac{8}{375} = 0\n", - "- \\frac{4 C_{1}}{1875} - \\frac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0\n", - "\\frac{C_{1}}{625} + \\frac{C_{2}}{1250} + C_{3} - C_{7} = 0\n", - "4 C_{1} + C_{2} - C_{6} = 0\n", - "C_{1} - C_{5} = 0\n" - ] - } - ], - "source": [ - "import sympy as sym\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "%config InlineBackend.figure_formats = ['svg']\n", - "sym.init_printing()\n", - "\n", - "x = sym.symbols('x')\n", - "\n", - "q = 10 \n", - "EI = 5000 \n", - "EA = 20000 \n", - "F = 150\n", - "\n", - "q_AC = 0\n", - "q_BC = q\n", - "\n", - "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", - "C_5, C_6, C_7, C_8 = sym.symbols('C_5 C_6 C_7 C_8')\n", - "\n", - "V_AC = -sym.integrate(q_AC, x) + C_1\n", - "M_AC = sym.integrate(V_AC, x) + C_2\n", - "kappa_AC = M_AC/EI\n", - "phi_AC = sym.integrate(kappa_AC, x) + C_3\n", - "w_AC = -sym.integrate(phi_AC, x) + C_4\n", - "\n", - "V_BC = -sym.integrate(q_BC, x) + C_5\n", - "M_BC = sym.integrate(V_BC, x) + C_6\n", - "kappa_BC = M_BC/EI\n", - "phi_BC = sym.integrate(kappa_BC, x) + C_7\n", - "w_BC = -sym.integrate(phi_BC, x) + C_8\n", - "\n", - "eq1 = sym.Eq(w_AC.subs(x,0),0)\n", - "eq2 = sym.Eq(M_AC.subs(x,0),0)\n", - "eq3 = sym.Eq(w_BC.subs(x,4),0)\n", - "eq4 = sym.Eq(phi_BC.subs(x,4),0)\n", - "eq5 = sym.Eq(w_AC.subs(x,4)-w_BC.subs(x,0),0)\n", - "eq6 = sym.Eq(phi_AC.subs(x,4)-phi_BC.subs(x,0),0)\n", - "eq7 = sym.Eq(M_AC.subs(x,4) - M_BC.subs(x,0),0)\n", - "eq8 = sym.Eq(V_AC.subs(x,4) - V_BC.subs(x,0),0)\n", - "\n", - "display(eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8)\n", - "for eq in [eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8]:\n", - " print(sym.latex(eq))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle \\left\\{ C_{1} : \\frac{35}{8}, \\ C_{2} : 0, \\ C_{3} : - \\frac{1}{150}, \\ C_{4} : 0, \\ C_{5} : \\frac{35}{8}, \\ C_{6} : \\frac{35}{2}, \\ C_{7} : \\frac{1}{3000}, \\ C_{8} : \\frac{13}{750}\\right\\}$" - ], - "text/plain": [ - "⎧ 13 ⎫\n", - "⎨C₁: 35/8, C₂: 0, C₃: -1/150, C₄: 0, C₅: 35/8, C₆: 35/2, C₇: 1/3000, C₈: ───⎬\n", - "⎩ 750⎭" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "'\\\\left\\\\{ C_{1} : \\\\frac{35}{8}, \\\\ C_{2} : 0, \\\\ C_{3} : - \\\\frac{1}{150}, \\\\ C_{4} : 0, \\\\ C_{5} : \\\\frac{35}{8}, \\\\ C_{6} : \\\\frac{35}{2}, \\\\ C_{7} : \\\\frac{1}{3000}, \\\\ C_{8} : \\\\frac{13}{750}\\\\right\\\\}'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sol = sym.solve([eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8],(C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", - "display(sol)\n", - "sym.latex(sol)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " 2025-07-02T16:58:07.214407\n", - " image/svg+xml\n", - " \n", - " \n", - " Matplotlib v3.10.3, https://matplotlib.org/\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "\n" - ], - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "M_numpy = sym.lambdify(x, M_BC.subs(sol))\n", - "x_numpy = np.linspace(0,4,100)\n", - "plt.figure()\n", - "plt.plot(x_numpy,M_numpy(x_numpy))\n", - "plt.xlabel('$x$')\n", - "plt.ylabel('$M_{BC}$');\n", - "ax = plt.gca()\n", - "ax.spines['right'].set_color('none')\n", - "ax.spines['top'].set_color('none')\n", - "ax.spines['bottom'].set_position('zero')\n", - "ax.spines['left'].set_position('zero')\n", - "ax.invert_yaxis()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\\left[\\begin{matrix}0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & - \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1\\\\0 & 0 & 0 & 0 & \\frac{1}{625} & \\frac{1}{1250} & 1 & 0\\\\- \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1 & 0 & 0 & 0 & -1\\\\\\frac{1}{625} & \\frac{1}{1250} & 1 & 0 & 0 & 0 & -1 & 0\\\\4 & 1 & 0 & 0 & 0 & -1 & 0 & 0\\\\1 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\end{matrix}\\right]\n", - "\\left[\\begin{matrix}0\\\\0\\\\- \\frac{8}{375}\\\\\\frac{8}{375}\\\\0\\\\0\\\\0\\\\0\\end{matrix}\\right]\n" - ] - } - ], - "source": [ - "A,b = sym.linear_eq_to_matrix((eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8), (C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", - "print(sym.latex(A))\n", - "print(sym.latex(b))\n", - "A = np.array(A).astype(np.float64)\n", - "b = np.array(b).astype(np.float64)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "A = np.array([\n", - " [0, 0, 0, 1, 0, 0, 0, 0],\n", - " [0, 1, 0, 0, 0, 0, 0, 0],\n", - " [0, 0, 0, 0, -4/1875, -1/625, -4, 1],\n", - " [0, 0, 0, 0, 1/625, 1/1250, 1, 0],\n", - " [-4/1875, -1/625, -4, 1, 0, 0, 0, -1],\n", - " [1/625, 1/1250, 1, 0, 0, 0, -1, 0],\n", - " [4, 1, 0, 0, 0, -1, 0, 0],\n", - " [1, 0, 0, 0, -1, 0, 0, 0]\n", - "])\n", - "\n", - "b = np.array([\n", - " 0,\n", - " 0,\n", - " -8/375,\n", - " 8/375,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0\n", - "])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 4.37500000e+00],\n", - " [ 0.00000000e+00],\n", - " [-6.66666667e-03],\n", - " [ 0.00000000e+00],\n", - " [ 4.37500000e+00],\n", - " [ 1.75000000e+01],\n", - " [ 3.33333333e-04],\n", - " [ 1.73333333e-02]])" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.linalg.solve(A,b)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}4.375\\\\0\\\\-0.00666666666666667\\\\0\\\\4.375\\\\17.5\\\\0.000333333333333334\\\\0.0173333333333333\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[ 4.375],\n", - "[ 0],\n", - "[-0.00666666666666667],\n", - "[ 0],\n", - "[ 4.375],\n", - "[ 17.5],\n", - "[0.000333333333333334],\n", - "[ 0.0173333333333333]])" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\\left[\\begin{matrix}4.375\\\\0\\\\-0.00666666666666667\\\\0\\\\4.375\\\\17.5\\\\0.000333333333333334\\\\0.0173333333333333\\end{matrix}\\right]\n", - "\\left[\\begin{matrix}1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 4.375\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -0.00666666666666667\\\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 4.375\\\\0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 17.5\\\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0.000333333333333334\\\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0.0173333333333333\\end{matrix}\\right]\n" - ] - } - ], - "source": [ - "import sympy as sym\n", - "\n", - "A_sym = sym.Matrix(A)\n", - "b_sym = sym.Matrix(b)\n", - "\n", - "sol_sym = A_sym.LUsolve(b_sym)\n", - "\n", - "display(sol_sym)\n", - "\n", - "print(sym.latex(sol_sym))\n", - "\n", - "identity = sym.eye(sol_sym.rows)\n", - "rr_augmented = identity.row_join(sol_sym)\n", - "print(sym.latex(rr_augmented))" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "C_1 = 35/8 ≈ 4.37500000000000\n", - "C_2 = 0 ≈ 0\n", - "C_3 = -1/150 ≈ -0.00666666666666667\n", - "C_4 = 0 ≈ 0\n", - "C_5 = 35/8 ≈ 4.37500000000000\n", - "C_6 = 35/2 ≈ 17.5000000000000\n", - "C_7 = 1/3000 ≈ 0.000333333333333333\n", - "C_8 = 13/750 ≈ 0.0173333333333333\n" - ] - } - ], - "source": [ - "import sympy as sym\n", - "sym.init_printing()\n", - "\n", - "x = sym.symbols('x')\n", - "\n", - "q = 10 \n", - "EI = 5000 \n", - "EA = 20000 \n", - "F = 150\n", - "\n", - "q_AC = 0\n", - "q_BC = q\n", - "\n", - "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", - "C_5, C_6, C_7, C_8 = sym.symbols('C_5 C_6 C_7 C_8')\n", - "\n", - "V_AC = -sym.integrate(q_AC, x) + C_1\n", - "M_AC = sym.integrate(V_AC, x) + C_2\n", - "kappa_AC = M_AC/EI\n", - "phi_AC = sym.integrate(kappa_AC, x) + C_3\n", - "w_AC = -sym.integrate(phi_AC, x) + C_4\n", - "\n", - "V_BC = -sym.integrate(q_BC, x) + C_5\n", - "M_BC = sym.integrate(V_BC, x) + C_6\n", - "kappa_BC = M_BC/EI\n", - "phi_BC = sym.integrate(kappa_BC, x) + C_7\n", - "w_BC = -sym.integrate(phi_BC, x) + C_8\n", - "\n", - "eq1 = sym.Eq(w_AC.subs(x,0),0)\n", - "eq2 = sym.Eq(M_AC.subs(x,0),0)\n", - "eq3 = sym.Eq(w_BC.subs(x,4),0)\n", - "eq4 = sym.Eq(phi_BC.subs(x,4),0)\n", - "eq5 = sym.Eq(w_AC.subs(x,4)-w_BC.subs(x,0),0)\n", - "eq6 = sym.Eq(phi_AC.subs(x,4)-phi_BC.subs(x,0),0)\n", - "eq7 = sym.Eq(M_AC.subs(x,4) - M_BC.subs(x,0),0)\n", - "eq8 = sym.Eq(V_AC.subs(x,4) - V_BC.subs(x,0),0)\n", - "\n", - "sol = sym.solve([eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8],(C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", - "for k, v in sol.items():\n", - " print(f\"{k} = {v} ≈ {v.evalf()}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "::::::{codex-end}\n", - "::::::" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Meer voorbeelden\n", - "Het voorbeeld in hoofdstuk 2.7.3 van het boek Mechanica, spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013` richt zich op extensie. Voorbeeld 3b in hoofdstuk 8.2 is een buigingsprobleem.\n", - "\n", - "## Instructies in collegevorm\n", - "\n", - "Dit onderwerp is [in les 3](https://collegerama.tudelft.nl/Mediasite/Channel/public-ceg-ctb2210/watch/757766716fcb45718fca678dadaa396d1d?sortBy=most-recent) gepresenteerd in collegevorm van 0:40:00 tot 0:48:30\n", - "\n", - "## Opgaves\n", - "\n", - "- Opgaves 2.48 en 2.50 in hoofdstuk 2.9 van het boek Mechanica: spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013`, antwoorden zijn beschikbaar op [deze website](https://icozct.tudelft.nl/TUD_CT/boekantwoorden/vol2/Chapter2/).\n", - "- Opgaves 8.7, 8.10, 8.11 in hoofdstuk 8.6 van het boek Mechanica: spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013`, antwoorden zijn beschikbaar op [deze website](https://icozct.tudelft.nl/TUD_CT/boekantwoorden/vol2/Chapter8/)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.11" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/book/instructie_2.ipynb b/book/instructie_2.ipynb deleted file mode 100644 index 0382117..0000000 --- a/book/instructie_2.ipynb +++ /dev/null @@ -1,1470 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "````{margin}\n", - "```{attributiongrey} Attribution\n", - ":class: attribution\n", - "\n", - "Deze pagina is aangepast van https://github.com/TUDelft-books/CT1000/blob/2025/book/week_2/session_1/intro.ipynb\n", - "\n", - "% Figures from https://github.com/TUDelft-books/CT1000/blob/2025/book/week_2/session_1/intro_data/Tekening1.vsdx\n", - "\n", - "```\n", - "```` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Instructie_new\n", - "\n", - "In constructiemechanica 2 heb je geleerd hoe je met differentiaalvergelijkingen voor statisch bepaalde constructies de krachtsverdeling en vervormingen kan vinden. Precies dezelfde aanpak werkt ook voor statisch onbepaalde constructie, met als enige verschil dat we de inwendige krachten niet kunnen vinden zonder ook de vergelijkingen en randvoorwaarden voor verplaatsingen op te stellen. Dat doen we volgens de volgende stappen:\n", - "\n", - "::::::{prf:algorithm} Differentiaalvergelijkingen toepassen\n", - ":nonumber: true\n", - ":label: differentiaalvergelijkingen_algoritme_2\n", - "\n", - "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", - "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", - "3. Er zijn nog meer vergelijkingen nodig om alle onbekende integratieconstantes op te lossen, deze kunnen we vinden door de overgangen tussen de verschillende elementen te analyseren waarbij zowel verplaatsingen als krachten in overeenstemming moeten zijn.\n", - "4. Er zijn nu evenveel vergelijkingen als onbekenden opgesteld. Deze kunnen nu worden opgelost en ingevuld in de opgestelde vergelijkingen voor het gewenste resultaat. Omdat het aantal onbekenden bij statisch onbepaalde constructies als snel uit de hand loopt wordt wordt aangeraden om je rekenmachine of een symbolische wiskundetool te gebruiken om dit op te lossen. Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python. Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt:\n", - "\n", - "::::::\n", - "\n", - "Als voorbeeld bepalen we de een simpele statisch onbepaalde constructie:\n", - "\n", - "::::::{prf:example}\n", - ":nonumber: true\n", - ":label: df_example_0_2\n", - "\n", - "Gegeven een constructie zoals hieronder weergegeven:\n", - "\n", - "```{figure} intro_data/structure.svg\n", - "---\n", - "align: center\n", - "---\n", - "Constructie, $EI = 5000 \\ \\rm{kNm^2}$\n", - "```\n", - "::::::\n", - "\n", - "1. Eerst definiëren we de segmenten zonder discontinuïteiten. Daarna kan elk segment afzonderlijk worden getekend, waarbij de belastingen, coördinatenstelsels, afmetingen en snedekrachten aan de randen van elk segment worden aangegeven.\n", - "\n", - "::::::{prf:example}\n", - ":nonumber: true\n", - ":label: df_example_1_2\n", - "\n", - "In dit voorbeeld moeten we element AB in twee delen opsplitsen omdat de verdeelde belasting een discontinuïteit veroorzaakt.\n", - "\n", - "Voor AC leidt dit tot:\n", - "\n", - "```{figure} intro_data/FBD_AC.svg\n", - ":align: center\n", - "\n", - "Vrijlichaamdiagram element AC\n", - "```\n", - "\n", - "Voor BC leidt dit tot:\n", - "\n", - "```{figure} intro_data/FBD_BC.svg\n", - ":align: center\n", - "\n", - "Vrijlichaamdiagram element BC\n", - "```\n", - "::::::" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Nu kunnen we voor elk element de belastingsvergelijking opstellen en volgens de relaties van de differentiaalvergelijkingen alle krachtsgrootheden en verplaatsingen opstellen. Daarbij kunnen we direct ook de randvoorwaarden opstellen.\n", - "\n", - "::::::{prf:example}\n", - ":nonumber: true\n", - ":label: df_example_3_2\n", - "\n", - "In dit voorbeeld is er enkel invloed door buiging, dus hebben we aan deze differentiaalvergelijking genoeg: $ -EI \\cfrac{{d}^4w}{{d}x^4} = -q_z$. De differentiaalvergelijkingen voor rek $ EA \\cfrac{{d}^2u}{{d}x^2} = -q_x$ en torsie $ GI \\cfrac{{d}^2\\varphi_x}{{d}x^2} = -q_T$ hebben we in dit geval niet nodig.\n", - "\n", - "**Element AC**\n", - "\n", - "Omdat dit element onbelast is, geeft de belastingsvergelijking voor dit element:\n", - "\n", - "$$q_{z,{\\rm{AC}}}=0$$\n", - "\n", - "wat leidt tot de vergelijkingen:\n", - "\n", - "$$ V_{\\rm{AC}} \\left(x\\right) = C_1$$\n", - "\n", - "$$ M_{\\rm{AC}} \\left(x\\right) = C_1 \\cdot x + C_2 $$\n", - "\n", - "$$ \\kappa_{\\rm{AC}} \\left(x\\right) = \\cfrac{C_1 \\cdot x + C_2}{5000}$$\n", - "\n", - "$$ \\varphi_{\\rm{AC}} \\left(x\\right) = \\cfrac{\\cfrac{1}{2}\\cdot C_1 \\cdot x^2 + C_2 \\cdot x}{5000} + C_3$$\n", - "\n", - "$$ w_{\\rm{AC}} \\left(x\\right) = \\cfrac{-\\cfrac{1}{6}\\cdot C_1 \\cdot x^3 - \\cfrac{1}{2} C_2 \\cdot x^2}{5000} - C_3 \\cdot x + C_4$$\n", - "\n", - "Vanwege de oplegging bij A kan een randvoorwaarde worden geformuleerd als:\n", - "\n", - "```{math}\n", - ":label: BC_1\n", - "w_{\\rm{AC}} \\left(0\\right) = 0\n", - "```\n", - "\n", - "Omdat A ook een onbelast uiteinde is, kan een andere randvoorwaarde worden geformuleerd als:\n", - "\n", - "```{math}\n", - ":label: BC_2\n", - "M_{\\rm{AC}} \\left(0\\right) = 0\n", - "```\n", - "\n", - "Als dit uiteinde belast werd kon met een krachten- of momentenevenwicht ook een relatie gevonden worden.\n", - "\n", - "**Element BC**\n", - "\n", - "Omdat dit element belast is, geeft de belastingsvergelijking voor dit element:\n", - "\n", - "$$q_{z,\\rm{BC}}=10$$\n", - "\n", - "wat leidt tot de vergelijkingen:\n", - "\n", - "$$ V_{\\rm{BC}} \\left(x\\right) = -10 \\cdot x + C_5$$\n", - "\n", - "$$ M_{\\rm{BC}} \\left(x\\right) = -5 \\cdot x^2 + C_5 \\cdot x + C_6 $$\n", - "\n", - "$$ \\kappa_{\\rm{BC}} \\left(x\\right) = \\cfrac{-5 \\cdot x^2 + C_5 \\cdot x + C_6}{5000}$$\n", - "\n", - "$$ \\varphi_{\\rm{BC}} \\left(x\\right) = \\cfrac{-\\cfrac{5}{3} \\cdot x^3 + \\cfrac{1}{2}\\cdot C_5 \\cdot x^2 + C_6 \\cdot x}{5000} + C_7$$\n", - "\n", - "$$ w_{\\rm{BC}} \\left(x\\right) = \\cfrac{\\cfrac{5}{12} \\cdot x^4 -\\cfrac{1}{6}\\cdot C_5 \\cdot x^3 - \\cfrac{1}{2} C_6 \\cdot x^2}{5000} - C_7 \\cdot x + C_8$$\n", - "\n", - "Vanwege de inklemming bij B kunnen twee randvoorwaarden direct worden geformuleerd:\n", - "\n", - "```{math}\n", - ":label: BC_3\n", - "\\varphi_{\\rm{BC}} \\left(4\\right) = 0\n", - "```\n", - "\n", - "```{math}\n", - ":label: BC_4\n", - "w_{\\rm{BC}} \\left(4\\right) = 0\n", - "```\n", - "\n", - "::::::" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "3. Er zijn nog meer vergelijkingen nodig om alle onbekende integratieconstantes op te lossen, deze kunnen we vinden door de overgangen tussen de verschillende elementen te analyseren waarbij zowel verplaatsingen als krachten in overeenstemming moeten zijn.\n", - "\n", - "::::::{prf:example}\n", - ":nonumber: true\n", - ":label: df_example_4_2\n", - "\n", - "Bij C kan een randvoorwaarde worden geïdentificeerd uit de consistentie van verplaatsingen: zowel de neerwaartse als rotatieverplaatsing moeten hetzelfde zijn als de neerwaartse en rotatieverplaatsing aan de linkerkant van element BE:\n", - "\n", - "```{math}\n", - ":label: BC_5\n", - "w_{\\rm{AC}} \\left(4\\right) = w_{\\rm{BC}} \\left(0\\right)\n", - "```\n", - "\n", - "```{math}\n", - ":label: BC_6\n", - "\\varphi_{\\rm{AC}} \\left(4\\right) = \\varphi_{\\rm{BC}} \\left(0 \\right)\n", - "```\n", - "\n", - "Ten slotte moet er ook consistentie zijn met de snedekrachten, zoals getoond in het vrijlichaamdiagram:\n", - "\n", - "```{figure} intro_data/FBD_C.svg\n", - ":align: center\n", - "\n", - "Vrijlichaamdiagram knoop C\n", - "```\n", - "\n", - "Verticaal evenwicht geeft:\n", - "\n", - "```{math}\n", - ":label: BC_7\n", - "\\sum {{{\\left. {{F_{\\rm{v}}}} \\right|}^{\\rm{C}}} = 0} \\to -{V_{\\rm{AC}}}\\left(4\\right) + V_{\\rm{BC}}\\left(0\\right) = 0\n", - "```\n", - "\n", - "Momentevenwicht geeft:\n", - "\n", - "```{math}\n", - ":label: BC_8\n", - "\\sum {{{\\left. {{T}} \\right|}_{\\rm{C}}^{\\rm{C}}} = 0} \\to -{M_{{\\rm{AC}}}}\\left(4\\right) + M_{\\rm{BC}}\\left(0\\right) = 0\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "4. Er zijn nu evenveel vergelijkingen als onbekenden opgesteld. Deze kunnen nu worden opgelost en ingevuld in de opgestelde vergelijkingen voor het gewenste resultaat. Omdat het aantal onbekenden bij statisch onbepaalde constructies als snel uit de hand loopt wordt wordt aangeraden om je rekenmachine of een symbolische wiskundetool te gebruiken om dit op te lossen. Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python. Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt:\n", - "\n", - "\n", - "::::::{prf:example-start}\n", - ":nonumber: true\n", - ":label: df_example_5_2\n", - "\n", - "::::::\n", - "\n", - "Er zijn 8 randvoorwaarden geformuleerd met 8 integratieconstanten. Deze kunnen nu worden opgelost. \n", - "\n", - "Het invullen van de randvoorwaarden geeft:\n", - "\n", - "$$\n", - "\\begin{align}\n", - "C_{4} = 0 \\\\\n", - "C_{2} = 0 \\\\\n", - "- \\cfrac{4 C_{5}}{1875} - \\cfrac{C_{6}}{625} - 4 C_{7} + C_{8} + \\cfrac{8}{375} = 0 \\\\\n", - "\\cfrac{C_{5}}{625} + \\cfrac{C_{6}}{1250} + C_{7} - \\cfrac{8}{375} = 0 \\\\\n", - "- \\cfrac{4 C_{1}}{1875} - \\cfrac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0 \\\\\n", - "\\cfrac{C_{1}}{625} + \\cfrac{C_{2}}{1250} + C_{3} - C_{7} = 0 \\\\\n", - "4 C_{1} + C_{2} - C_{6} = 0 \\\\\n", - "C_{1} - C_{5} = 0 \\\\\n", - "\\end{align}\n", - "$$\n", - "\n", - "Het oplossen hiervan geeft:\n", - "\n", - "$$\n", - "\\begin{align}\n", - "C_{1} = \\cfrac{35}{8} = 4.375 \\\\\n", - "C_{2} = 0 \\\\\n", - "C_{3} = - \\cfrac{1}{150} \\approx -0.006667 \\\\\n", - "C_{4} = 0 \\\\\n", - "C_{5} = \\cfrac{35}{8} = 4.375\\\\\n", - "C_{6} = \\cfrac{35}{2} = 17.5 \\\\\n", - "C_{7} = \\cfrac{1}{3000} \\approx 0.0003333\\\\\n", - "C_{8} = \\cfrac{13}{750} \\approx 0.01733\n", - "\\end{align}\n", - "$$\n", - "\n", - "Nu is de volledige krachtenverdeling en verplaatsingen van de constructie opgelost. Bijvoorbeeld de momentenverdeling in BC die kan worden uitgezet als:\n", - "\n", - "```{figure} intro_data/Momentenlijn.svg\n", - ":align: center\n", - "\n", - "Momentenlijn BC\n", - "```\n", - "\n", - "De krachtsverdeling en verplaatsingen kunnen no ook \n", - "\n", - "**Oplossen met digitale hulpmiddelen**\n", - "Om het stelsel vergelijkingen op te lossen met behulp van numerieke hulpmiddelen, kun je de vergelijkingen opschrijven als een matrixformulering $Ax=b$ die eenvoudig kan worden opgelost door bijvoorbeeld je grafische rekenmachine of in python.\n", - "\n", - "\n", - "$$\\left[\\begin{array}{cccccccc}0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & - \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1\\\\0 & 0 & 0 & 0 & \\frac{1}{625} & \\frac{1}{1250} & 1 & 0\\\\- \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1 & 0 & 0 & 0 & -1\\\\\\frac{1}{625} & \\frac{1}{1250} & 1 & 0 & 0 & 0 & -1 & 0\\\\4 & 1 & 0 & 0 & 0 & -1 & 0 & 0\\\\1 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\end{array}\\right] \\left[ \\begin{array}{cccccccc} C_1\\\\C_2\\\\C_3\\\\C_4\\\\C_5\\\\C_6\\\\C_7\\\\C_8 \\end{array} \\right] = \\left[\\begin{matrix}0\\\\0\\\\- \\frac{8}{375}\\\\\\frac{8}{375}\\\\0\\\\0\\\\0\\\\0\\end{matrix}\\right]$$\n", - "\n", - "[Hier](rref_ti_84) is uitgelegd hoe je dit op een grafische rekenmachine kan oplossen.\n", - "\n", - "Als alternatief kan een symbolische programmeertaal worden gebruikt om de vergelijkingen exact op te lossen. Als voorbeeld wordt het [`sympy`](https://docs.sympy.org/latest/index.html) pakket in `Python` gebruikt.\n", - "\n", - "Beide opties zijn hieronder getoond" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAASCAYAAADomNYKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAs9JREFUeJzl102o1FUYx/HPaEh2q3sxCgKtqNRdS7tgQi8g0SZXLgLBCiEsYnITFPTwBLqMUBRq0S2iVhEGtRF6WVTULktLbwTtgsDK6nbpzXFxztTcaeY2M3eGS/SF4YHznJfn9z/nPOeZRqvV0ovM3IwHsBPXYQY/4CRex4sR8UvPwatEZm7E07gbV+EbHEdGxPftfo1u0ZnZQOJxrMOH+BTncb3yETbg/YjYMWkhg5KZNymxXoM3cAbbcAfOYntEnINLeox/AXvxOe6LiJNdk6/HAdw8ofhH5Zgi+NGIONJuzMxn8BgO4iFY0zkqMw8ogr/AbLdgiIjFiDiI/ZOKflgy80blBH6No13uwAL2ZOYUHaIz81rla/yB3RHx03ILRcTi+MJeMXdWeyIiLnQ6qo4PcBlmWXq8m7gUcxFxatJRZmZTSY6D8klEHO/j21rtfB//l8pJ2IK3O0XvqvblIQJZCU0lMQ7KS0om7sV0tef7+NvtM9SdzszLla/QwsdDBPIXmfmEcj2ORsQj/9Y/Im4YZZ0RaVTb4u87fXW1P47y9mbmLPYpT9tq0N7J6T7+Kzv7tY/3QrXrM3NtRPw56GqZOY1X8CCeGmJc0/ju9Nlqt/Txb652nrrTEfGtku7X4fblVs7MNV1Nz+O1iHhnuXE9aCrPyaC/XcvM9W61O7vjy8wrsB2L+Iil2fvZ+juWmfdGxJmuwQ2lvLsfu2vbPqVI2TOw1Mo473REfJWZJ5QM/TCOdLgTU3guIhZYKvowblHq7c/qJPP4HZtwGzbiVcjMrTiEHRHx27gErID9Shl6ODPvUgqsW5UydB5Ptjv2qr3vUZLSNiXB/awU7qfxFt6MiHOZuRdz6Lz/a5UMeQFTEfHrBMT1JTM36f+H47t2v3+IHmKBGWXnO5lTCoFDOB0Ro00+YUYW3YvMfA+nBnmnV5PuTPy/YKw7/V/hImUh8qiSnFTZAAAAAElFTkSuQmCC", - "text/latex": [ - "$\\displaystyle C_{4} = 0$" - ], - "text/plain": [ - "C₄ = 0" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAASCAYAAADomNYKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAt9JREFUeJzV10+IVXUUB/DPTBGZmWIYBFpSaruWJZmRBSZtkhYGkZBBUAoxSRDS4nACV1HISANt+kPQMoxqIw1tKmqn/TGdCNwFQX+smYbIei1+99ad17vje773kL5wObx7fud3zvf3O+e8cyc6nY5eyMzNeAw7cQPW4GecxNt4PSJ+62l8iZCZ6/E8duFafIdjyIj4qV430U06MyeQeBZX4BN8jnO4UTmEtfgoIraPm0i/yMyblVivwzs4jduwA2ewLSJ+gMt72L+KR3EKD0fEya7NV+AgNo0p/ovFjEL4qYg4Wr/MzJfwNA7jCZhsWmXmQYXw19jaTRgiYjEiDmP/uKIfFJl5k5KBZ/FylzqwgL2ZuZIG6cy8XjmN89gTEb8u5ygiFkcX9tC4p5LHI+KvpqLi8TGuwlaWpvcUrsRrEfHluKPMzCmlOfaLExFxrEV3SyXnWvTfKJmwBbNN0rsr+eYAgQyDKaUx9os3lE7cC6srea5FX79fQ3XTmXm1cgodfNZvFJl5CA8qJ/07PsWhfjIlIjb262cEmKhkh39rel0lfxnwv/dupWveodTVeXyQmWuHj3Mg1De5ukV/TXNdnd4LlVyRmZdFxJ/9eIqI+5q/M3NvtfE2vLuc7Yhr+kwlt7ToN1dyjop0RHyfmWexUbm92TbPmTnZ3SEbWKVkz49t9g1MGV1Nf1jJnd3xZeYq5RIWlfJb0r2PVM9MZj4QEaebu1aT2i7sw54W50dwot58OYyypiPi28w8rnToAzjaUCdW4pWIWGAp6WncqszbX1SbzOEPbMCdWI+3ejnOzBdwF7b3Wx4jxn5lDJ3OzHuVAet2ZQydw3P1wl6z9/14XJlb12FeGdy/wvt4r55hGzYv4hHsiIhT4+F0YWTmBu0fHP+U3H9IX4SjaTzkEhMeBEORzswZ5YZ3Kx8oNeYjYn640MaHyQsvWRZPKh17Vkml+nlmyH3HiqHT+/+IvwHtQ/pzJbnwjAAAAABJRU5ErkJggg==", - "text/latex": [ - "$\\displaystyle C_{2} = 0$" - ], - "text/plain": [ - "C₂ = 0" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle - \\frac{4 C_{5}}{1875} - \\frac{C_{6}}{625} - 4 C_{7} + C_{8} + \\frac{8}{375} = 0$" - ], - "text/plain": [ - " 4⋅C₅ C₆ 8 \n", - "- ──── - ─── - 4⋅C₇ + C₈ + ─── = 0\n", - " 1875 625 375 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle \\frac{C_{5}}{625} + \\frac{C_{6}}{1250} + C_{7} - \\frac{8}{375} = 0$" - ], - "text/plain": [ - "C₅ C₆ 8 \n", - "─── + ──── + C₇ - ─── = 0\n", - "625 1250 375 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle - \\frac{4 C_{1}}{1875} - \\frac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0$" - ], - "text/plain": [ - " 4⋅C₁ C₂ \n", - "- ──── - ─── - 4⋅C₃ + C₄ - C₈ = 0\n", - " 1875 625 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAATQAAAAUCAYAAAADWsEdAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAACUVJREFUeJztnH+wVVUVxz9PiHCQYLIUJw3E0H5o4SghGgiiqDHleyQ2GgREFkZDL7QR0lp8LdPGzBcm2UzDjyxnmtRwCsgf8ZKKyn4MP8SUVF7mQBgiBIqZSH+sfeG+wzn33XPvOYdH3e/MnX3vOWfvvc53r7PP2mutfZv27dtHHCQNAT4BjAPeDvQHdgBrgfuAxWb2cmzlCpB0LLAZuMPMZkXOjQRagbOBNwPbgfVAm5ktD9ccDbQA44HTgLcBr4brFgGLzOz1mH47gIEJYm01swFp7yVL5MV3aPsgziVdCpwLDAXeB/QFfmhmk2LqF8q5pOOBG4CLgKOBLcBSQGb2YjX3nBfyHKcicLjKX61O9Iyp2AQIuBboBawG7gF24so5DhgLXA6MrEG2S4AjgJ9E+r0e+AqwDfhZEPgtwOnAaGB5uHQi8J1wvh14FjgWmAB8D7hY0kQzi5updwJtMcd313AfmaAAviGe8+vxiWw38Bzwzgr1C+Nc0kk4B8cA9wNPAO8HPgdcJOkcM3uhgqy5oKBxyg2Hs/xpdOKgCQ1YCEwFHgeuMLO1kcaPBGYD76hRvhbgBWBVWZsT8cnsYWCCme2K9PmGsp8bgQ8Dy8qtAklfBB4FPoI/aPfG9L3DzObVKHcsJE3FrZQxZvbLGprIm2+I4Rz4PD6RPYVbau0V6hfJ+QJccWeZ2e1lfX0zyHwjMCNFe1mMERQzTnnicJa/ap3oNKFJmo3f9F+As6ITC4CZ7QFuDASkgqR+wHnA3Wa2Nxw7Avg68DJOdFyf/yn7vjKubTP7h6Q7w82NJv7h6lbIm+/Qx0Gch3bby66p2EZRnEsajFsKHcAd0e6ATwGTJV1tZi/V01dKuXIfpzxxOMufVid6llU8DlfM14DL4m66U0tOQFqMx83d+8qOnQ2ciJu/L0oaD5wKvAI8ama/TdF+aeJ7LeH8GyVNwn0HLwHrgFXlD3pRKIhviOc8S2TJ+XmhfDDqkzOzXZJ+gyv3WcAv6pa8ChQ4TrngcJeflDpRbqG1Ar1xB+9jOQnXgiv1Q2XHhoVyK/Bn3Om8H5JWAZea2T8rNSypJ/Dx8PPnCZcNAO6KHNskaZqZPdK1+Jmilfz5hnjOM0EOnJ8Syo0Jbf0VV96TKWhCo7hxygutFCi/pFY80FAt1pjZ0grnU+lE+YTWHMqo8mUCSb3xCMUKM3ul7NQxoZwBbALOB36POypvBS4EfowvaSrhZtyyW25mD8ScXwT8CtgA7AIGA5/FTdYVkkZE/Qo5ozmUufANFTnPCllz3i+UOxP6Kx3vX6fcadAcytzGKWc0h7Io+VtJjmzHYQkerUxCKp3oCSDpKHyG24dPJlVB0ijgC8AZwHHARDO7J+HyccBRRKKbQI9QNuGWWEnBN0hqwWfmc4Pyxy4/Jc0CrsajH5PjrjGzqKPoMWCGpN2h7jzcmklEF2kI7TG+qCVmNjWmnZr4DnXn4g74U4B/A78D5ia8fZM4rxtFcR5BUyjjc43IboxCW/WM00zg08CgcGgD8FUzW9ZFvQ7STQixqTahrXrkT5JjgZnNTKpnZoPS9JMBOulEyUJ7ayj/lTIHpQ+ev7KIrh3CLXjuUnRASzkkz0QtJDPbI+kBYDoepj1oQguK8y08ejPWzLankB/gTvzhGlXFtW0cbB0MxdMiluCOy3KsSWinVr7BLdUFwB/wwbwBeFjSu2PuPYnzupAj56W3bT/i8abIdXFoI5sxgvrG6TlgDr4kagKmAEslnWFm6yrUexr3H1eLzRXO1SP/MA4YG+CW+EP4aqlIpNKJ0oRWihgdKalHtU5yM1sBrIDKkTJJPYAPASvNLKqMT4ZyR0L10oR3UPQlrNdvw9/8Y83s+WrkjqBUp09XF5pZW4wMU/GHZXGKlICa+A4yXBjpfzI+mOcAPy07XonzmpEz5yVdODmh3pBQJvlTshwjqG+c7o8cuk7SVcAIPDCSVG9sCvm6Qj3yd/JZS5qDT7YVfc05+NBS6cQRAEEpO/Bo2OhKvYc0i7QYhWf3xi19VuERmCGSesWcPzWUHRE5rsUfrDV4flEtDxa4ggE8U2P91MiY7774OEatpEqc14QCOC+lkoyL3rekvvikvQdfZueOrMZJUg9Jl+PL/9UZilgRGcrfC5gELExIni5HK55OUe2nuYv2UulEeVCgLXwWSLrEzJ6IVG7CHczTgMu6ECKKCcDreJZvJ5jZNkk/Aj4GfBnPYC/1eQEeFNhJWRRN0pfwpdafgHFdLXkkvQfYEr1O0kDg2+HnD1LeU71oIxu+2/AJJvqQJ3JeC4rg3MyelvQg7vubCdxeXhW36L5bZA4adYyTpNNwN0lvPCjSbGbrC5C5HG3Ur2fNuNW1uKvOsvahpdWJ8gltPvBefJ/X+tDIRjzP6ATgA8DxwN01yNUMrDazrQnnZwPDcbN8FJ59PhD3Ae0FrjSzHQCSpuAP1l48gjYrZrnbYWaLy35PBOZIascjqbuAk/Acrd74tqpv1HBf9aBuviXdgltiI2OWE81U4FxSMwfejqU9lSMkLQ7ft5nZNeHaIjn/DG7FzJc0Fk8GHQ6Mwfm5Lu5+ckQ94/Qk7r/rj++m+L6k0QWnf2TxXE/HI+WV/HV5omqd2D+hBVNyuqR7gStxJ/wF+J67LfibZhm+z7JqSBqGE3Zb0jVm9ryk4bh11oInye0K/d1kZuXWx4mh7IGbt3F4hM5vk3Y8Kng6vtzpg/vsfo2Hs++qwpTOFPXyLelWfBkwxsyeipzrknP8QZsSOTY4fAD+BlwTvhfGeXgjn8mBjcgfxPmYj29EThuAqAv1jJOZvYpvLQP4YxiXVuCT+Uu+X4Z69Wwgnko1oRCBY5BGJ5qS/m0jLSTtIyZtQ9LXgLnAYDPblEln/+eQNB/4KD6ZPR5zvsF5N4SklcDmpDSL7ghJ8/D0kxPMLGk3SLdB3Ob0qhHyXMo3sw6SNBTYbmbPhmMtwNrGg5UNJC3ALbNmYLuk0nJxt5mV/sGiwfkhhqSbccvn73jg5grcMT/+EIqVCsEJPw3P1ev2kxnUOaEBZ9L5XxpuCeUSfDMsZvauOvtooDOuCmV064/wRNUG590DA/CgxwA8qLUOuDhhR0V3xfn4HtyFh1qQapHZkrOBBhpo4FCjlpyyBhpooIFuicaE1kADDfzP4L+nwvob2OmQoQAAAABJRU5ErkJggg==", - "text/latex": [ - "$\\displaystyle \\frac{C_{1}}{625} + \\frac{C_{2}}{1250} + C_{3} - C_{7} = 0$" - ], - "text/plain": [ - "C₁ C₂ \n", - "─── + ──── + C₃ - C₇ = 0\n", - "625 1250 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKoAAAAUCAYAAAAdtqaHAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAABSNJREFUeJztmmuoVUUYhp9jIpmaQhQIWqFp5A8pMjO8kB5QqR8eioxCRbtAqdjJbmjY62cYgVhHJSG01CQhsDAKBFG0sDQkVDKzk5L4I8HQsjSVLrsf36zarc5ae+3bWUfYDyxm77m+s5j5Zuab1VQoFEjCzKYD74S/j0tam5J3CPAIMBG4HugH/AwcBD4A1kv6LbGxnGnozwczGwAsASYD1wAngS2ASfopytc9pYKBwCrgHNA7JV8TYMALQA/gc2AzcBa4AX9xzcBDwNgq+lQXGvrzw8wG43qvAz4EjgAjgaeAyWY2WtJpSBioofPrgNP4bHw2pb23gZnAYeBhSQdjdfUE5gM3Vd6lZMxsZtA6XtKuCqrIVX8NuJz1r8YH6TxJq6JIM3sNeBpYCjwB0C2hgnnABGAWcD6pFTObj7+kb4BR8ZcEIOmCpKXA7Ep6Uk8a+vPDzAbh1v448EYsWfi4m25mvaCDgWpmtwCvAiskfZrSUH98xP8BTJX0a5owSReyd6P+NPTnzoQQbpP0V3FC6MtnwFXAKIgt/WbWHdgInAAWlmioFbgSWCfpUNWyO59WGvozY2at+AEtKwckbUlJvzmE7Qnp3+EWdyiwI75HfQm4DRiTYQa2hHBjiXxdlZYQNvRnoxU/nGVlA356T6JvCM8mpEfx/aDIoprZSNyKLpe0J02BmfXGR3oB+KKU4ljZccBzwO1Af+ABSZszlj1O8svaaWbxuA2SZnZQTzX6FwD34RbhErAXWJDFqpXQ3xHvSprWQT0V6w/l++Pbu3twj85RYK6kT5LKSLqx3HaqpCmEBQgDtWjJbwcWZajk2hD+UoFvrhfu21sHvF9m2Tb+v/zcCkzBZ/DxWNqBhHqq0X83flrdh7/MJcB2Mxsm6UyJsseAi2W09UNCfMX6zawfvv/bDdwL/AgMAk6VU08NiCxm34T0q4vzRRY1mqEAFzuwTABrzGwNsAJ4JcT1NLMrJP2ZVZ2krcBWgIR20sq2xeOCe2oK7tDelbGqyJNRif5Jsfan4y9zNPBRibLNWdspQcX6geeBk5JmFMV9X6pQHfao34ZwaEL6kBC2w7+n/kvAWwnP/pBnd/i/R9Ip3Hr1wC1MImaW5ALLjRrr74O/x1LWtGZUqb8F2Gtmm8zslJkdMLO5wXeeRivuNsr6tJSob2cIJ8Y1mlkffOJfwLdWblHDwemxhI4uxg9YG2JXqG3hWW1mUyQdiZVrwq/FZgFTS4jOgzZqo78N32LsrYfIEu22Ub7+QcAc4HVgEr51WoXvBeP+zH+o9R5V0jEz24af7OcEDRGGbxHflHQeUq5QM7ASGI7fL38VGm0HfgcGAmOAAcCmKtqoJ1XrN7NlwDhgbJnLby2oVH834EtJC8L//WY2FB8siQO1TszGr1BXmlkzfnFxJzAe78uLUcaKl2VJBUmP4hvyj/GZOQe3zMOBPfitybxK26gn1eo3s+XADKBZ0tFOkPwfqtB/Evg6FneY8rwRNUHSMWAEsB4foM8Ag/FJeFd0zw/QlPb1VL0xswJluKe6Cma2EngQ/77gcN56ysHMNgEDJY0tinsZuF/SsPyUpdPpAzX4AKMPJPbjPtXtwBlJJzpVTAWY2WpgGn5YKB6k5ySdy0VUGZjZHfhyuxh4Dz9/rAUWSurspT8zeZzIR+ADNPImLAu/l+SgpRKexE/6O/BlNHrSvjDrMkjah0+yqcAh/HuBRbhvuMuS69LfoEFWupyPs0GDjmgM1AaXBX8Db+ZLKnj2sa4AAAAASUVORK5CYII=", - "text/latex": [ - "$\\displaystyle 4 C_{1} + C_{2} - C_{6} = 0$" - ], - "text/plain": [ - "4⋅C₁ + C₂ - C₆ = 0" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAG4AAAAUCAYAAABs4ghcAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAASdAAAEnQB3mYfeAAAA6lJREFUeJztmV2IVGUYx3+zimhWCn0KWy2adhGEkNSGFdWCCF20NwlFQqUXYmCTEhEh//6CV4aIktFNukR5Y2EUCEJ4VZt3iWF+sPkBfZOlohukTRfve7az48x4zsyZ2R3YHxwezvv5f+Y57+eUKpUKtbC9EHgZWAbcDcwF/gIOA58CuyVdrll5gulW7bZ7gU3AcuAW4GdgH2BJf6bLTq9RuQQYeAOYAXwN7AXOA/cQfowB4DngsXY50Qxdrn0BQe/twGfAMeAh4FVgue2lkv5Iyl8TOOAD4EXgKPC8pMNVHcwC1gP3tsOBFulm7TsJQVsnaUeSaHsr8BqwGViTpPeka9peT3D8e6C/2nEASaOSNgNr26G+Wbpc+3zCbHAaeLcqW8AlYKXt2UliT6ryPEJUrwArJF1s1Jmk0WJkt043a488Fe0BSf+mM6IvXwE3AP1JenqqLAMzgV2SvmuvzsIp02HttsuETU9WvpW0r07efdGeqJN/kjAiFwFfwvjADUb7YQ4xk4XBaDupvUzY8GRliLBDrMWcaM/XyU/S5yYJ0wFs30iIZgU4lFWJ7ceB14EHgXnAs5L2Zqx7mnyOfyTphRrtNKU91n2bsIak+VXSnderK6kvT18tUop27OyWjLjbor2Q83wzm3A22gV8klPMCPB3jvI/1UlvVnvCceCJ1PvVJtpolWREzamTf3NVubHAXYp2lu1pkjKJl7Qf2A9gO5dSSQO5KtSnKe0prkj6JW+nBa9xx6NdVCd/YbRja2APgKTfCFvRGYz/+q7Bdk+j/E5TgPb5tn+0fcr2Htt9GbsuE6bZrM9gg7YORrusWqPtm4ClwCjwTZKe3pxsi89O289IOlbVQIlwFfMSsCKjc51iG81pPwSsJHzJdwBvAsO275d0rlGHRa5xkkZsHyDsHF8BdqSyTViS3peUzC7jArcdeIBwx3ckNnQC+Ae4C3gU6AU+LkpwgTSlPU71CUdsDwM/EA7yW9svexxrCVde220PEC4SHgaeJPjyVrrw2LCUVJG0Cnga+AJYTIj+asKPMkxwaF27PchLUdrjF32U/9eUjiFpBFgC7CYEbAOwgPBRPpK+pwQo1ft3IC+2K+Q4DkxGbM8ETgHvSdo00XoaUeuSOTPxDJW+sO2zvRg4J+lsK213AtvvAJ8DZwkXvBsJ68nQROrKQkuBIwztg6n3LdEOEaamyU4vsAe4FfidsGvrl3RmQlVloLCpcorOMqnOZFNkZypwXcp/TvVqwtp6oi4AAAAASUVORK5CYII=", - "text/latex": [ - "$\\displaystyle C_{1} - C_{5} = 0$" - ], - "text/plain": [ - "C₁ - C₅ = 0" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "C_{4} = 0\n", - "C_{2} = 0\n", - "- \\frac{4 C_{5}}{1875} - \\frac{C_{6}}{625} - 4 C_{7} + C_{8} + \\frac{8}{375} = 0\n", - "\\frac{C_{5}}{625} + \\frac{C_{6}}{1250} + C_{7} - \\frac{8}{375} = 0\n", - "- \\frac{4 C_{1}}{1875} - \\frac{C_{2}}{625} - 4 C_{3} + C_{4} - C_{8} = 0\n", - "\\frac{C_{1}}{625} + \\frac{C_{2}}{1250} + C_{3} - C_{7} = 0\n", - "4 C_{1} + C_{2} - C_{6} = 0\n", - "C_{1} - C_{5} = 0\n" - ] - } - ], - "source": [ - "import sympy as sym\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "%config InlineBackend.figure_formats = ['svg']\n", - "sym.init_printing()\n", - "\n", - "x = sym.symbols('x')\n", - "\n", - "q = 10 \n", - "EI = 5000 \n", - "EA = 20000 \n", - "F = 150\n", - "\n", - "q_AC = 0\n", - "q_BC = q\n", - "\n", - "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", - "C_5, C_6, C_7, C_8 = sym.symbols('C_5 C_6 C_7 C_8')\n", - "\n", - "V_AC = -sym.integrate(q_AC, x) + C_1\n", - "M_AC = sym.integrate(V_AC, x) + C_2\n", - "kappa_AC = M_AC/EI\n", - "phi_AC = sym.integrate(kappa_AC, x) + C_3\n", - "w_AC = -sym.integrate(phi_AC, x) + C_4\n", - "\n", - "V_BC = -sym.integrate(q_BC, x) + C_5\n", - "M_BC = sym.integrate(V_BC, x) + C_6\n", - "kappa_BC = M_BC/EI\n", - "phi_BC = sym.integrate(kappa_BC, x) + C_7\n", - "w_BC = -sym.integrate(phi_BC, x) + C_8\n", - "\n", - "eq1 = sym.Eq(w_AC.subs(x,0),0)\n", - "eq2 = sym.Eq(M_AC.subs(x,0),0)\n", - "eq3 = sym.Eq(w_BC.subs(x,4),0)\n", - "eq4 = sym.Eq(phi_BC.subs(x,4),0)\n", - "eq5 = sym.Eq(w_AC.subs(x,4)-w_BC.subs(x,0),0)\n", - "eq6 = sym.Eq(phi_AC.subs(x,4)-phi_BC.subs(x,0),0)\n", - "eq7 = sym.Eq(M_AC.subs(x,4) - M_BC.subs(x,0),0)\n", - "eq8 = sym.Eq(V_AC.subs(x,4) - V_BC.subs(x,0),0)\n", - "\n", - "display(eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8)\n", - "for eq in [eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8]:\n", - " print(sym.latex(eq))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle \\left\\{ C_{1} : \\frac{35}{8}, \\ C_{2} : 0, \\ C_{3} : - \\frac{1}{150}, \\ C_{4} : 0, \\ C_{5} : \\frac{35}{8}, \\ C_{6} : \\frac{35}{2}, \\ C_{7} : \\frac{1}{3000}, \\ C_{8} : \\frac{13}{750}\\right\\}$" - ], - "text/plain": [ - "⎧ 13 ⎫\n", - "⎨C₁: 35/8, C₂: 0, C₃: -1/150, C₄: 0, C₅: 35/8, C₆: 35/2, C₇: 1/3000, C₈: ───⎬\n", - "⎩ 750⎭" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "'\\\\left\\\\{ C_{1} : \\\\frac{35}{8}, \\\\ C_{2} : 0, \\\\ C_{3} : - \\\\frac{1}{150}, \\\\ C_{4} : 0, \\\\ C_{5} : \\\\frac{35}{8}, \\\\ C_{6} : \\\\frac{35}{2}, \\\\ C_{7} : \\\\frac{1}{3000}, \\\\ C_{8} : \\\\frac{13}{750}\\\\right\\\\}'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sol = sym.solve([eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8],(C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", - "display(sol)\n", - "sym.latex(sol)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " 2025-07-02T16:58:07.214407\n", - " image/svg+xml\n", - " \n", - " \n", - " Matplotlib v3.10.3, https://matplotlib.org/\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "\n" - ], - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "M_numpy = sym.lambdify(x, M_BC.subs(sol))\n", - "x_numpy = np.linspace(0,4,100)\n", - "plt.figure()\n", - "plt.plot(x_numpy,M_numpy(x_numpy))\n", - "plt.xlabel('$x$')\n", - "plt.ylabel('$M_{BC}$');\n", - "ax = plt.gca()\n", - "ax.spines['right'].set_color('none')\n", - "ax.spines['top'].set_color('none')\n", - "ax.spines['bottom'].set_position('zero')\n", - "ax.spines['left'].set_position('zero')\n", - "ax.invert_yaxis()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\\left[\\begin{matrix}0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & - \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1\\\\0 & 0 & 0 & 0 & \\frac{1}{625} & \\frac{1}{1250} & 1 & 0\\\\- \\frac{4}{1875} & - \\frac{1}{625} & -4 & 1 & 0 & 0 & 0 & -1\\\\\\frac{1}{625} & \\frac{1}{1250} & 1 & 0 & 0 & 0 & -1 & 0\\\\4 & 1 & 0 & 0 & 0 & -1 & 0 & 0\\\\1 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\end{matrix}\\right]\n", - "\\left[\\begin{matrix}0\\\\0\\\\- \\frac{8}{375}\\\\\\frac{8}{375}\\\\0\\\\0\\\\0\\\\0\\end{matrix}\\right]\n" - ] - } - ], - "source": [ - "A,b = sym.linear_eq_to_matrix((eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8), (C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", - "print(sym.latex(A))\n", - "print(sym.latex(b))\n", - "A = np.array(A).astype(np.float64)\n", - "b = np.array(b).astype(np.float64)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "A = np.array([\n", - " [0, 0, 0, 1, 0, 0, 0, 0],\n", - " [0, 1, 0, 0, 0, 0, 0, 0],\n", - " [0, 0, 0, 0, -4/1875, -1/625, -4, 1],\n", - " [0, 0, 0, 0, 1/625, 1/1250, 1, 0],\n", - " [-4/1875, -1/625, -4, 1, 0, 0, 0, -1],\n", - " [1/625, 1/1250, 1, 0, 0, 0, -1, 0],\n", - " [4, 1, 0, 0, 0, -1, 0, 0],\n", - " [1, 0, 0, 0, -1, 0, 0, 0]\n", - "])\n", - "\n", - "b = np.array([\n", - " 0,\n", - " 0,\n", - " -8/375,\n", - " 8/375,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0\n", - "])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 4.37500000e+00],\n", - " [ 0.00000000e+00],\n", - " [-6.66666667e-03],\n", - " [ 0.00000000e+00],\n", - " [ 4.37500000e+00],\n", - " [ 1.75000000e+01],\n", - " [ 3.33333333e-04],\n", - " [ 1.73333333e-02]])" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.linalg.solve(A,b)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}4.375\\\\0\\\\-0.00666666666666667\\\\0\\\\4.375\\\\17.5\\\\0.000333333333333334\\\\0.0173333333333333\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[ 4.375],\n", - "[ 0],\n", - "[-0.00666666666666667],\n", - "[ 0],\n", - "[ 4.375],\n", - "[ 17.5],\n", - "[0.000333333333333334],\n", - "[ 0.0173333333333333]])" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\\left[\\begin{matrix}4.375\\\\0\\\\-0.00666666666666667\\\\0\\\\4.375\\\\17.5\\\\0.000333333333333334\\\\0.0173333333333333\\end{matrix}\\right]\n", - "\\left[\\begin{matrix}1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 4.375\\\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -0.00666666666666667\\\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 4.375\\\\0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 17.5\\\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0.000333333333333334\\\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0.0173333333333333\\end{matrix}\\right]\n" - ] - } - ], - "source": [ - "import sympy as sym\n", - "\n", - "A_sym = sym.Matrix(A)\n", - "b_sym = sym.Matrix(b)\n", - "\n", - "sol_sym = A_sym.LUsolve(b_sym)\n", - "\n", - "display(sol_sym)\n", - "\n", - "print(sym.latex(sol_sym))\n", - "\n", - "identity = sym.eye(sol_sym.rows)\n", - "rr_augmented = identity.row_join(sol_sym)\n", - "print(sym.latex(rr_augmented))" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "C_1 = 35/8 ≈ 4.37500000000000\n", - "C_2 = 0 ≈ 0\n", - "C_3 = -1/150 ≈ -0.00666666666666667\n", - "C_4 = 0 ≈ 0\n", - "C_5 = 35/8 ≈ 4.37500000000000\n", - "C_6 = 35/2 ≈ 17.5000000000000\n", - "C_7 = 1/3000 ≈ 0.000333333333333333\n", - "C_8 = 13/750 ≈ 0.0173333333333333\n" - ] - } - ], - "source": [ - "import sympy as sym\n", - "sym.init_printing()\n", - "\n", - "x = sym.symbols('x')\n", - "\n", - "q = 10 \n", - "EI = 5000 \n", - "EA = 20000 \n", - "F = 150\n", - "\n", - "q_AC = 0\n", - "q_BC = q\n", - "\n", - "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", - "C_5, C_6, C_7, C_8 = sym.symbols('C_5 C_6 C_7 C_8')\n", - "\n", - "V_AC = -sym.integrate(q_AC, x) + C_1\n", - "M_AC = sym.integrate(V_AC, x) + C_2\n", - "kappa_AC = M_AC/EI\n", - "phi_AC = sym.integrate(kappa_AC, x) + C_3\n", - "w_AC = -sym.integrate(phi_AC, x) + C_4\n", - "\n", - "V_BC = -sym.integrate(q_BC, x) + C_5\n", - "M_BC = sym.integrate(V_BC, x) + C_6\n", - "kappa_BC = M_BC/EI\n", - "phi_BC = sym.integrate(kappa_BC, x) + C_7\n", - "w_BC = -sym.integrate(phi_BC, x) + C_8\n", - "\n", - "eq1 = sym.Eq(w_AC.subs(x,0),0)\n", - "eq2 = sym.Eq(M_AC.subs(x,0),0)\n", - "eq3 = sym.Eq(w_BC.subs(x,4),0)\n", - "eq4 = sym.Eq(phi_BC.subs(x,4),0)\n", - "eq5 = sym.Eq(w_AC.subs(x,4)-w_BC.subs(x,0),0)\n", - "eq6 = sym.Eq(phi_AC.subs(x,4)-phi_BC.subs(x,0),0)\n", - "eq7 = sym.Eq(M_AC.subs(x,4) - M_BC.subs(x,0),0)\n", - "eq8 = sym.Eq(V_AC.subs(x,4) - V_BC.subs(x,0),0)\n", - "\n", - "sol = sym.solve([eq1,eq2,eq3,eq4,eq5,eq6,eq7,eq8],(C_1,C_2,C_3,C_4,C_5,C_6,C_7,C_8))\n", - "for k, v in sol.items():\n", - " print(f\"{k} = {v} ≈ {v.evalf()}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "::::::{prf:example-end}\n", - "::::::" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Meer voorbeelden\n", - "Het voorbeeld in hoofdstuk 2.7.3 van het boek Mechanica, spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013` richt zich op extensie. Voorbeeld 3b in hoofdstuk 8.2 is een buigingsprobleem.\n", - "\n", - "## Instructies in collegevorm\n", - "\n", - "Dit onderwerp is [in les 3](https://collegerama.tudelft.nl/Mediasite/Channel/public-ceg-ctb2210/watch/757766716fcb45718fca678dadaa396d1d?sortBy=most-recent) gepresenteerd in collegevorm van 0:40:00 tot 0:48:30\n", - "\n", - "## Opgaves\n", - "\n", - "- Opgaves 2.48 en 2.50 in hoofdstuk 2.9 van het boek Mechanica: spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013`, antwoorden zijn beschikbaar op [deze website](https://icozct.tudelft.nl/TUD_CT/boekantwoorden/vol2/Chapter2/).\n", - "- Opgaves 8.7, 8.10, 8.11 in hoofdstuk 8.6 van het boek Mechanica: spanningen, vervormingen en verplaatsingen {cite:p}`Hartsuijker2013`, antwoorden zijn beschikbaar op [deze website](https://icozct.tudelft.nl/TUD_CT/boekantwoorden/vol2/Chapter8/)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.11" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/book/intro.md b/book/intro.md index fae52ac..165c9f7 100644 --- a/book/intro.md +++ b/book/intro.md @@ -1,210 +1,5 @@ ---- -file_format: mystnb -kernelspec: - name: python3 ---- - # TeachBooks Manual -## Nesting inside of a start-directive - -### Different directives - -::::{prf:theorem-start} The parent theorem -:label: parent-theorem-label - -This is a parent theorem. This text is inside the parent theorem. - -:::{prf:axiom-start} A child axiom -:label: child-axiom-label - -This is a child axiom. This text is inside the child directive. -::: - -This is text after the child-start, before the child-end, inside the parent theorem. - -:::{prf:axiom-end} -Text inside the end. This text will not be rendered. -::: - -Finally some text after the entire child, inside the theorem start. - -:::: - -Some text after the entire parent theorem start, but before the parent theorem end. - -:::{prf:theorem-end} -::: - -### Same directives - -::::{prf:theorem-start} The parent theorem -:label: parent-theorem-label2 - -This is a parent theorem. This text is inside the parent theorem. - -:::{prf:theorem-start} A child theorem -:label: child-theorem-label - -This is a child theorem. This text is inside the child directive. -::: - -This is text after the child-start, before the child-end, inside the parent theorem. - -:::{prf:theorem-end} -::: - -Finally some text after the entire child, inside the theorem start. - -:::: - -Some text after the entire parent theorem start, but before the parent theorem end. - -:::{prf:theorem-end} -::: - -## Nesting outside of a start-directive - -### Different directives - -::::{prf:theorem-start} The parent theorem -:label: parent-theorem-label3 - -This is a parent theorem. This text is inside the parent theorem. -:::: - -Some text outside the parent theorem start, before the child start directive. - -:::{exercise-start} A child exercise -:label: child-exercise-label2 - -This is a child exercise. This text is inside the child directive. -::: - -This is text after the child-start, before the child-end. - -:::{exercise-end} -::: - -Finally some text after the entire child, outside the theorem start, before the end. - -:::{prf:theorem-end} -::: - -:::{exercise} This is an exercise outside any theorem. -:label: exercise-outside-theorem - -Solve this exercise. -::: - -### Same directives - -::::{prf:theorem-start} The parent theorem -:label: parent-theorem-label4 - -This is a parent theorem. This text is inside the parent theorem. -:::: - -Some text outside the parent theorem start, before the child start directive. - -:::{prf:theorem-start} A child theorem -:label: child-theorem-label5 - -This is a child theorem. This text is inside the child directive. -::: - -This is text after the child-start, before the child-end. - -:::{prf:theorem-end} -::: - -Finally some text after the entire child, outside the theorem start, before the end. - -:::{prf:theorem-end} -::: - -### Nested exercise directives - -:::{exercise-start} An outer exercise with an inner exercise between start and end -:label: outer-exercise-label -This is an outer exercise. This text is inside the outer exercise. -::: - -:::{exercise-start} An inner exercise -:label: inner-exercise-label -This is an inner exercise. This text is inside the inner exercise. -::: -This is text after the inner exercise start, before the inner exercise end. - -:::{exercise-end} -::: - -Finally some text after the entire inner exercise, inside the outer exercise. - -:::{exercise-end} -::: - -## Examples with code - -### Block directive with also a figure - -:::{prf:theorem-start} A title -:label: theorem-label - -This is a theorem. This text is inside the directive. -::: - -Now some extra text that should come inside the theorem. - -:::{figure} images/sphinx-logo.svg -:alt: Sphinx logo -:width: 200px -:align: center - -Sphinx is a great tool for documentation! This figure should be inside the theorem. -::: - -```{code-cell} ipython3 -a = "This is some" -b = "Python code" -c = "that should be inside the theorem." -print(f"{a} {b} {c}") -``` - -:::{prf:theorem-end} -::: - -### Figure directive with nothing with also another figure - -:::{figure-start} images/nothing.svg -:name: figure-label -:alt: Nothing -:align: center - -This is a figure. This text is inside the caption. -::: - -```{code-cell} ipython3 -a = "This is some" -b = "Python code" -c = "that should be inside the figure," -d = "above the caption." -print(f"{a} {b} {c} {d}") -``` - -Now some extra text that should come inside the figure, above the caption. - -:::{figure} images/sphinx-logo.svg -:alt: Sphinx logo -:width: 200px -:align: center - -Sphinx is a great tool for documentation! This figure should be inside the parent figure, above the parent caption. -::: - -:::{figure-end} -::: - This manual is primarily designed for and by teachers for use in education, but should be a useful resource for anyone interested in creating and collaborating on a TeachBook: a Jupyter book v1 v1 using the Sphinx logo Sphinx backend with additional editing tools and book features. Our aim is to provide a simple way to start book-making for new users (it only takes 10 clicks!), ease the editing process for anyone, and provide additional features developed for education-purposes. We hope you find this resource useful and refer back to it often. TeachBooks originated at Delft University of Technology in the Netherlands, and some of the material in this Manual reflects tools and resources specific to TU Delft. With the exception of a few tools for which we have educational licenses at Delft, everything in this Manual is open source. Despite this, we are happy to grow our open source community beyond Delft and welcome contributions from all users. diff --git a/book/lesoefeningen.ipynb b/book/lesoefeningen.ipynb deleted file mode 100644 index b6e6d48..0000000 --- a/book/lesoefeningen.ipynb +++ /dev/null @@ -1,316 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "44f13f99", - "metadata": {}, - "source": [ - "````{margin}\n", - "```{attributiongrey} Bronvermelding\n", - ":class: attribution\n", - "\n", - "Deze oefening is aangepast van https://oit.tudelft.nl/CT1000/2024/week_3/session_1/intro.html\n", - "\n", - "% Figures from https://github.com/TUDelft-books/CT1000/blob/2025/book/week_3/session_1/intro_data/Tekening1.vsdx\n", - "\n", - "```\n", - "```` \n", - "\n", - "# Begeleide oefening 1_oud\n", - "\n", - "Gegeven is de volgende constructie:\n", - "\n", - "```{figure} lesoefeningen_data/figure2.svg\n", - "---\n", - "align: center\n", - "---\n", - "Constructie, $EI = 6400 \\ \\rm{kNm^2}$\n", - "```\n", - "\n", - ":::::{exercise}\n", - ":label: ODE_3_1\n", - ":nonumber: true\n", - "\n", - "Bepaal de segmenten en teken de vrijlichaamsschema's.\n", - "\n", - "```{h5p} https://tudelft.h5p.com/content/1292630673009985967/embed\n", - "```\n", - "\n", - ":::::\n", - "\n", - "% solution_start\n", - "\n", - "::::{admonition} Solution\n", - ":class: solution, dropdown\n", - "\n", - "$q_z = -12 \\cdot x + 0$\n", - "\n", - "::::\n", - "\n", - "% solution_end\n", - "\n", - ":::::{exercise}\n", - ":label: ODE_3_2\n", - ":nonumber: true\n", - "\n", - "Bepaal de relaties van de krachtsgrootheden en verplaatsingen.\n", - "\n", - "```{h5p} https://tudelft.h5p.com/content/1292630677998825487/embed\n", - "```\n", - "\n", - ":::::\n", - "\n", - "% solution_start\n", - "\n", - "::::{admonition} Solution\n", - ":class: solution, dropdown\n", - "\n", - "- $ w \\left( 0\\right) = 0 $\n", - "- $ M \\left( 0\\right) = 0$\n", - "- $ w \\left( 8\\right) = 0$\n", - "- $ \\varphi \\left( 8 \\right) = 0$\n", - "\n", - "::::\n", - "\n", - "% solution_end\n", - "\n", - ":::::{exercise-start}\n", - ":label: ODE_3_3\n", - ":nonumber: true\n", - "\n", - "Los de integratieconstanten op. Je kan gebruik maken van de volgende code cellen. (Klik op {fa}`rocket` --> {guilabel}`Live Code` om live python code te activeren op deze pagina.)\n", - "\n", - "```{h5p} https://tudelft.h5p.com/content/1292630704310133517/embed\n", - "```\n", - "\n", - ":::::\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91dc34be", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "A = np.array([\n", - " [ , , , ],\n", - " [ , , , ],\n", - " [ , , , ],\n", - " [ , , , ],\n", - "])\n", - "\n", - "b = np.array([\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - "])\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce6f1792", - "metadata": {}, - "outputs": [], - "source": [ - "np.linalg.solve(A,b)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9e466305", - "metadata": {}, - "outputs": [], - "source": [ - "import sympy as sym\n", - "sym.init_printing()\n", - "\n", - "x = sym.symbols('x')\n", - "\n", - "q = \n", - "EI = 6400\n", - "\n", - "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", - "\n", - "V = -sym.integrate(q, x) + C_1\n", - "M = sym.integrate(V, x) + C_2\n", - "kappa = M/EI\n", - "phi = sym.integrate(kappa, x) + C_3\n", - "w = -sym.integrate(phi, x) + C_4\n", - "\n", - "eq1 = sym.Eq(w.subs(x,0), )\n", - "eq2 = sym.Eq( .subs(x,0), )\n", - "eq3 = sym.Eq(w.subs(x,8), )\n", - "eq4 = sym.Eq( .subs(x,8),0)\n", - "\n", - "sol = sym.solve([eq1,eq2,eq3,eq4],(C_1,C_2,C_3,C_4))\n", - "for k, v in sol.items():\n", - " print(f\"{k} = {v} ≈ {v.evalf()}\")" - ] - }, - { - "cell_type": "markdown", - "id": "94270e4f", - "metadata": {}, - "source": [ - ":::::{exercise-end}\n", - ":::::\n", - "\n", - "% solution_start\n", - "\n", - "::::{solution-start} ODE_3_3\n", - ":class: dropdown\n", - "::::\n", - "\n", - "$ w = - \\cfrac{x^{5}}{10} + \\cfrac{64 x^{3}}{5} - \\cfrac{2048 x}{5} = - 0.1 x^{5} + 12.8 x^{3} - 409.6 x $\n", - "% solution_end" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "f46e4efd", - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "A = np.array([\n", - " [ 0 , 0 , 0,1],\n", - " [ 0 , 1 , 0,0],\n", - " [-1/75 ,-1/200,-8,1],\n", - " [ 1/200, 1/800, 1,0],\n", - "])\n", - "\n", - "b = np.array([\n", - " 0,\n", - " 0,\n", - " 64/125,\n", - " -8/25,\n", - "])\n" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "300cd851", - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "array([-7.68e+01, 0.00e+00, 6.40e-02, 0.00e+00])" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.linalg.solve(A,b)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "96516034", - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle - 0.1 x^{5} + 12.8 x^{3} - 409.6 x$" - ], - "text/plain": [ - " 5 3 \n", - "- 0.1⋅x + 12.8⋅x - 409.6⋅x" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import sympy as sym\n", - "sym.init_printing()\n", - "\n", - "x = sym.symbols('x')\n", - "\n", - "q = -12 * x\n", - "EI = 6400\n", - "\n", - "C_1, C_2, C_3, C_4 = sym.symbols('C_1 C_2 C_3 C_4')\n", - "\n", - "V = -sym.integrate(q, x) + C_1\n", - "M = sym.integrate(V, x) + C_2\n", - "kappa = M/EI\n", - "phi = sym.integrate(kappa, x) + C_3\n", - "w = -sym.integrate(phi, x) + C_4\n", - "\n", - "eq1 = sym.Eq(w.subs(x,0),0)\n", - "eq2 = sym.Eq(M.subs(x,0),0)\n", - "eq3 = sym.Eq(w.subs(x,8),0)\n", - "eq4 = sym.Eq(phi.subs(x,8),0)\n", - "\n", - "sol = sym.solve([eq1,eq2,eq3,eq4],(C_1,C_2,C_3,C_4))\n", - "\n", - "display((w.subs(sol)*EI).evalf())\n", - "\n", - "A,b = sym.linear_eq_to_matrix((eq1,eq2,eq3,eq4), (C_1,C_2,C_3,C_4))" - ] - }, - { - "cell_type": "markdown", - "id": "b3a4c9d4", - "metadata": {}, - "source": [ - "% solution_start\n", - "\n", - "::::{solution-end}\n", - "::::\n", - "\n", - "% solution_end" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.11" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 68cf7ca75696d9fe5fdca54f9886094d392baf71 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 17:41:29 +0100 Subject: [PATCH 060/110] Add extension to remove YAML front matter from includes Introduced a custom Sphinx extension 'include_remove_yaml' to strip YAML front matter from included files. Updated _config.yml to register the extension, and added YAML front matter to intro.md for demonstration. --- book/_config.yml | 2 ++ book/_ext/include_remove_yaml/__init__.py | 33 +++++++++++++++++++++++ book/intro.md | 5 ++++ 3 files changed, 40 insertions(+) create mode 100644 book/_ext/include_remove_yaml/__init__.py diff --git a/book/_config.yml b/book/_config.yml index 02e26d1..99ea80d 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -11,6 +11,8 @@ html: baseurl : "https://teachbooks.io/manual/" sphinx: + local_extensions: + include_remove_yaml: _ext/ extra_extensions: - sphinx_inline_tabs - sphinx.ext.imgconverter diff --git a/book/_ext/include_remove_yaml/__init__.py b/book/_ext/include_remove_yaml/__init__.py new file mode 100644 index 0000000..a6181f5 --- /dev/null +++ b/book/_ext/include_remove_yaml/__init__.py @@ -0,0 +1,33 @@ +from __future__ import annotations +from sphinx.util import logging +logger = logging.getLogger(__name__) + +def _strip_yaml(lines: list[str]) -> list[str]: + + if not lines: + return lines + for ix,lines_set in enumerate(lines): + new_lines = lines_set.splitlines() + if new_lines[0].strip() != "---": + continue + # yaml front matter detected + # find closing delimiter + index_end = 1 + for i in range(1, len(new_lines)): + tok = new_lines[i].strip() + if tok == "---": + index_end = i + break + new_lines = new_lines[index_end+1 :] + lines[ix] = "\n".join(new_lines) + return lines # no closing delimiter -> leave unchanged + +def on_include_read(app, docname, path, content): + # content is a list[str]; modify in-place + new = _strip_yaml(content) + if new is not content: + content[:] = new + +def setup(app): + app.connect("include-read", on_include_read) + return {} diff --git a/book/intro.md b/book/intro.md index 165c9f7..c2739e3 100644 --- a/book/intro.md +++ b/book/intro.md @@ -1,3 +1,8 @@ +--- +file_format: mystnb +kernelspec: + name: python3 +--- # TeachBooks Manual This manual is primarily designed for and by teachers for use in education, but should be a useful resource for anyone interested in creating and collaborating on a TeachBook: a Jupyter book v1 v1 using the Sphinx logo Sphinx backend with additional editing tools and book features. Our aim is to provide a simple way to start book-making for new users (it only takes 10 clicks!), ease the editing process for anyone, and provide additional features developed for education-purposes. We hope you find this resource useful and refer back to it often. From ee8777516e7a6b1e8cd8cd5252fc0c92d275779f Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 17:53:12 +0100 Subject: [PATCH 061/110] Remove custom YAML extension and update requirements Deleted the custom 'include_remove_yaml' Sphinx extension and its configuration. Cleaned up YAML front matter from intro.md. Updated requirements.txt to use released teachbooks package, added sphinx-gated-directives, and removed duplicate or outdated dependencies. --- book/_config.yml | 2 -- book/_ext/include_remove_yaml/__init__.py | 33 ----------------------- book/intro.md | 5 ---- requirements.txt | 10 +++---- 4 files changed, 3 insertions(+), 47 deletions(-) delete mode 100644 book/_ext/include_remove_yaml/__init__.py diff --git a/book/_config.yml b/book/_config.yml index 99ea80d..02e26d1 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -11,8 +11,6 @@ html: baseurl : "https://teachbooks.io/manual/" sphinx: - local_extensions: - include_remove_yaml: _ext/ extra_extensions: - sphinx_inline_tabs - sphinx.ext.imgconverter diff --git a/book/_ext/include_remove_yaml/__init__.py b/book/_ext/include_remove_yaml/__init__.py deleted file mode 100644 index a6181f5..0000000 --- a/book/_ext/include_remove_yaml/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -from __future__ import annotations -from sphinx.util import logging -logger = logging.getLogger(__name__) - -def _strip_yaml(lines: list[str]) -> list[str]: - - if not lines: - return lines - for ix,lines_set in enumerate(lines): - new_lines = lines_set.splitlines() - if new_lines[0].strip() != "---": - continue - # yaml front matter detected - # find closing delimiter - index_end = 1 - for i in range(1, len(new_lines)): - tok = new_lines[i].strip() - if tok == "---": - index_end = i - break - new_lines = new_lines[index_end+1 :] - lines[ix] = "\n".join(new_lines) - return lines # no closing delimiter -> leave unchanged - -def on_include_read(app, docname, path, content): - # content is a list[str]; modify in-place - new = _strip_yaml(content) - if new is not content: - content[:] = new - -def setup(app): - app.connect("include-read", on_include_read) - return {} diff --git a/book/intro.md b/book/intro.md index c2739e3..165c9f7 100644 --- a/book/intro.md +++ b/book/intro.md @@ -1,8 +1,3 @@ ---- -file_format: mystnb -kernelspec: - name: python3 ---- # TeachBooks Manual This manual is primarily designed for and by teachers for use in education, but should be a useful resource for anyone interested in creating and collaborating on a TeachBook: a Jupyter book v1 v1 using the Sphinx logo Sphinx backend with additional editing tools and book features. Our aim is to provide a simple way to start book-making for new users (it only takes 10 clicks!), ease the editing process for anyone, and provide additional features developed for education-purposes. We hope you find this resource useful and refer back to it often. diff --git a/requirements.txt b/requirements.txt index 946f15a..c7b9259 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -# teachbooks == 0.2.3 -git+https://github.com/TeachBooks/TeachBooks@issue-127 +teachbooks == 0.2.3 sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites +sphinx-gated-directives teachbooks-sphinx-grasple @@ -11,8 +11,4 @@ sphinx-apa-references # For executing Jupyter Notebooks myst_nb numpy -matplotlib - -sphinx-tudelft-theme == 1.2.1 - -git+https://github.com/TeachBooks/Sphinx-Gated-Directives \ No newline at end of file +matplotlib \ No newline at end of file From c7f7917fe2affa846325df2350bf5ddad06409ca Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 17:54:12 +0100 Subject: [PATCH 062/110] Remove sphinx_tudelft_theme from Sphinx extensions The sphinx_tudelft_theme extension has been removed from the list of Sphinx extensions in the configuration file, possibly because it is no longer needed or has been replaced. --- book/_config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/book/_config.yml b/book/_config.yml index 02e26d1..9a6affb 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -17,7 +17,6 @@ sphinx: - teachbooks_favourites - teachbooks_sphinx_grasple - sphinx_apa_references - - sphinx_tudelft_theme - sphinx_gated_directives config: sphinx_gated_directives: From 46d70c1578bbf21ddb40bdcacc978d909c14135d Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 17:56:08 +0100 Subject: [PATCH 063/110] Remove unused Sphinx config options Cleaned up book/_config.yml by removing unused or unnecessary Sphinx configuration options related to sphinx_gated_directives and sphinx_codex. This helps simplify the configuration file. --- book/_config.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/book/_config.yml b/book/_config.yml index 9a6affb..82c2340 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -19,8 +19,6 @@ sphinx: - sphinx_apa_references - sphinx_gated_directives config: - sphinx_gated_directives: - override_existing: ['exercise'] language: en html_js_files: - https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js @@ -55,8 +53,6 @@ sphinx: summaries: false individual: false nb_execution_includepatterns: "**/MANUAL.ipynb" - sphinx_codex_name: "Voorbeeld" - sphinx_codex_merge_with_proof: true # default value teachbooks: attribution_location: margin From aacc7368e2eda56d1160da6b7a5849439cc11bec Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Sun, 4 Jan 2026 18:03:01 +0100 Subject: [PATCH 064/110] Update teachbooks dependency source Switched teachbooks dependency to use a specific Git branch (issue-127) instead of the released version. This allows for testing or using unreleased changes from the repository. --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c7b9259..239e2ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ -teachbooks == 0.2.3 +# teachbooks == 0.2.3 +git+https://github.com/TeachBooks/TeachBooks@issue-127 sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites From 684b9c84a4dceb90d51e6bf70d65679c24cf48c3 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 5 Jan 2026 09:15:20 +0100 Subject: [PATCH 065/110] Fix matplotlib entry in requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 239e2ff..a244d27 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,4 @@ sphinx-apa-references # For executing Jupyter Notebooks myst_nb numpy -matplotlib \ No newline at end of file +matplotlib From aa5843df88ef278e386ab125efc16bf1b9edfc28 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 5 Jan 2026 09:27:10 +0100 Subject: [PATCH 066/110] Remove sphinx-gated-directives from requirements --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a244d27..2285009 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,6 @@ git+https://github.com/TeachBooks/TeachBooks@issue-127 sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites -sphinx-gated-directives teachbooks-sphinx-grasple From fca8533e97a501c82123c4a95f09a0b5363d6aad Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Mon, 5 Jan 2026 16:14:59 +0100 Subject: [PATCH 067/110] Update teachbooks to version 0.2.4 in requirements Replaces the previous git-based install of teachbooks with the released version 0.2.4 in requirements.txt for improved stability and reproducibility. --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 2285009..bddce43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ -# teachbooks == 0.2.3 -git+https://github.com/TeachBooks/TeachBooks@issue-127 +teachbooks == 0.2.4 sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites From a639f14b941ca5626c623be869414187a180ea35 Mon Sep 17 00:00:00 2001 From: Frans van der Meer Date: Mon, 5 Jan 2026 20:16:03 +0100 Subject: [PATCH 068/110] Update plotly HTML instructions --- book/features/plotly.ipynb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/book/features/plotly.ipynb b/book/features/plotly.ipynb index 8f81598..7f92684 100644 --- a/book/features/plotly.ipynb +++ b/book/features/plotly.ipynb @@ -32,16 +32,12 @@ "metadata": {}, "outputs": [], "source": [ - "from IPython import get_ipython\n", + "import os\n", "from IPython.display import HTML\n", "\n", "def show_plotly(fig):\n", - " ip = get_ipython()\n", - " if ip is None:\n", - " return fig\n", - "\n", - " # Sphinx / Jupyter Book execution\n", - " if \"sphinx\" in ip.config:\n", + " # Use HTML when building book in CI environment\n", + " if os.environ.get(\"CI\") == \"true\":\n", " return HTML(fig.to_html(include_plotlyjs=\"cdn\"))\n", "\n", " # Local execution in Jupyter Notebook / JupyterLab / VS Code\n", @@ -70,7 +66,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "When using Plotly graphs, make sure the notebook is executed in Jupyter Lab / Jupyter Notebook for the figures to be shown in the book. Running the code in VS code might break the result in the book, although the output is visible in VS code. Alternatively, add the following lines of code to your notebook to have a valid output in the book as well:\n", + "Alternatively, you can run the notebook locally before building the book. This is not recommended for the combination with git because you will be committing binary output to the repository. When pre-generating Plotly graphs, make sure the notebook is executed in Jupyter Lab / Jupyter Notebook for the figures to be shown in the book. Running the code in VS code might break the result in the book, although the output is visible in VS code. Add the following lines of code to your notebook to have a valid output in the book as well:\n", "\n", "```python\n", "import plotly.io as pio\n", From d257d56838b35686140bb357f45618e4af6810a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:51:02 +0000 Subject: [PATCH 069/110] Bump book/external/JupyterBook-Patches from `c5cb27a` to `99aeda4` Bumps [book/external/JupyterBook-Patches](https://github.com/TeachBooks/JupyterBook-Patches) from `c5cb27a` to `99aeda4`. - [Release notes](https://github.com/TeachBooks/JupyterBook-Patches/releases) - [Commits](https://github.com/TeachBooks/JupyterBook-Patches/compare/c5cb27a87b193228c45edb95580f9ee2d82b27df...99aeda40ae0cfa06eb290ba5c3a6b9b81eb3992d) --- updated-dependencies: - dependency-name: book/external/JupyterBook-Patches dependency-version: 99aeda40ae0cfa06eb290ba5c3a6b9b81eb3992d dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- book/external/JupyterBook-Patches | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/external/JupyterBook-Patches b/book/external/JupyterBook-Patches index c5cb27a..99aeda4 160000 --- a/book/external/JupyterBook-Patches +++ b/book/external/JupyterBook-Patches @@ -1 +1 @@ -Subproject commit c5cb27a87b193228c45edb95580f9ee2d82b27df +Subproject commit 99aeda40ae0cfa06eb290ba5c3a6b9b81eb3992d From 6f44de51c06cf7a7397cfd6e2f06320898cd4da3 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 9 Jan 2026 11:29:35 +0100 Subject: [PATCH 070/110] Update versions_URLs.md --- book/installation-and-setup/versions_URLs.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/book/installation-and-setup/versions_URLs.md b/book/installation-and-setup/versions_URLs.md index d948409..4561c1d 100644 --- a/book/installation-and-setup/versions_URLs.md +++ b/book/installation-and-setup/versions_URLs.md @@ -6,8 +6,10 @@ If you plan on maintaining only one public version, it is advisable to set `BEHA To share the built book / website of old versions for your book on GitHub you have a few options: - Create a branch for each version. When doing this, [the GitHub workflow](../external/deploy-book-workflow/README.md) will build it on GitHub pages. Here's a few tips: - - It's advised to use the version as branch name. In case of versions per academic year, you can just name each branch to the current academic year, this leads to the URL with the same academic year.. - - It is recommended to update the primary branch as the `PRIMARY BRANCH` when using the [GitHub workflow](gh-workflow-settings) whenever a new version is considered to be the most primary one. This ensures that readers are redirected to a consistent URL, even when new versions of the book are added later. + - It's advised to use the version as branch name, making it very clear which branch to which website. In case of versions per academic year, you can just name each branch to the current academic year, this leads to the URL with the same academic year. In case of book which are more stable over year, you could consider a simpler v1.1. See the page on [TeachBooks versioning](./versioning_changelog.md) for more information about how to name versions (and thus branches). + - You might consider a draft version for each version, in which you collect contributions leading up to a new release of the non-draft versoin. It's advised to name the draft branches so that the link with the non-draft version is obvious. Furthermore, you might consider the [Draft-Release Workflow](../features/draft-release.md) + - Whenever a new version is considered to be the most primary one, it is recommended to update the branch `PRIMARY BRANCH` when using the [GitHub workflow](gh-workflow-settings). This ensures that readers which have visited your book before are redirected to a consistent URL, even when new versions of the book are added later. Furthermore, it revert new readers to the most primary one. + - Set the primary branch (or its draft branch) as the default branch in git, so that that branch is directly visible when people visit your repository. Furthermore, this is probably the branch where you'd like contributers to start from when forking / opening a pull request. - Eventually, you can add old branches to the list of `BRANCHES_ARCHIVED` when using the [GitHub workflow](gh-workflow-settings) to include a banner on the page indicating its archived state. Alternatively, you can add a banner manually to `_config.yml`, as explained [here](../basic-features/banner.md). - If you're using tags (as will be explained in [later](./versioning_changelog.md)), you can create a branch from a tag locally by running: `git branch `. - If you have many version of the book, at some point you might reach the 1 GB GitHub Pages limit. This is only expected for extremely large books with a lot of non-text-based (binary) content. To prevent going over that limit, store large content not used for building the website (like images) on an external server. This can be another GitHub repository or a (paid) object store. From c51586746c0f6ea3560b4217dc08b65aafb35300 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 12 Jan 2026 13:23:56 +0100 Subject: [PATCH 071/110] Create sphinx-autobuild.sh --- sphinx-autobuild.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 sphinx-autobuild.sh diff --git a/sphinx-autobuild.sh b/sphinx-autobuild.sh new file mode 100644 index 0000000..2820105 --- /dev/null +++ b/sphinx-autobuild.sh @@ -0,0 +1,27 @@ +# Deactivate any active conda environment +conda deactivate 2>/dev/null || true + +# Clear conda environment variables +unset CONDA_DEFAULT_ENV CONDA_PROMPT_MODIFIER 2>/dev/null || true + +# Create a Python virtual environment +python -m venv venv + +# Activate the virtual environment +source venv/Scripts/activate + +# Install required packages from requirements.txt and sphinx-autobuild +pip install -r requirements.txt sphinx-autobuild + +# Initialize Jupyter Book configuration for the book directory +jupyter-book config sphinx book/ + +# Disable display of all git authors in Sphinx documentation +# by changing 'git_show_all_authors' from True to False in conf.py +sed -i 's/git_show_all_authors = True/git_show_all_authors = False/' book/conf.py + +sed -i "s/external_toc_path = '_toc.yml'/external_toc_path = '_toc_with_local_paths.yml'/" book/conf.py + +# Build and serve the Sphinx documentation with auto-reload +# Opens browser automatically and ignores build artifacts and Python files +sphinx-autobuild book book/_build/html --open-browser --ignore "book/_build/**" --pre-build "teachbooks build book/ --process-only" \ No newline at end of file From a9170a5011a296063cdfacf02dbaf40fbe125901 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 12 Jan 2026 13:27:11 +0100 Subject: [PATCH 072/110] Update .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bb960ab..646bdab 100644 --- a/.gitignore +++ b/.gitignore @@ -139,4 +139,5 @@ book/.jupyterlite.doit.db # TeachBooks **.teachbooks/ book/_toc_with_local_paths.yml -book/_git/ \ No newline at end of file +book/_git/ +book/conf.py \ No newline at end of file From 1a4518f6c1bc613028bd97b64fc56349551bff56 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 12 Jan 2026 13:36:57 +0100 Subject: [PATCH 073/110] added all authors --- book/_config.yml | 1 + requirements.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/book/_config.yml b/book/_config.yml index 82c2340..fd4cab6 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -53,6 +53,7 @@ sphinx: summaries: false individual: false nb_execution_includepatterns: "**/MANUAL.ipynb" + git_show_all_authors: true teachbooks: attribution_location: margin diff --git a/requirements.txt b/requirements.txt index bddce43..517b212 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.4 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites +git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors teachbooks-sphinx-grasple From 2f1e088d029d579729ed749b770c6374ae5593c4 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 12 Jan 2026 13:37:40 +0100 Subject: [PATCH 074/110] Create remove_author.css --- book/_static/remove_author.css | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 book/_static/remove_author.css diff --git a/book/_static/remove_author.css b/book/_static/remove_author.css new file mode 100644 index 0000000..a99acdb --- /dev/null +++ b/book/_static/remove_author.css @@ -0,0 +1,4 @@ +/* Hide the default Jupyter Book author footer */ +.component-author { + display: none; +} From e3c0583a13acfb305edd6145c788a66ebbc0edb1 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 12 Jan 2026 15:51:48 +0100 Subject: [PATCH 075/110] Update sphinx-autobuild.sh --- sphinx-autobuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx-autobuild.sh b/sphinx-autobuild.sh index 2820105..708e580 100644 --- a/sphinx-autobuild.sh +++ b/sphinx-autobuild.sh @@ -24,4 +24,4 @@ sed -i "s/external_toc_path = '_toc.yml'/external_toc_path = '_toc_with_local_pa # Build and serve the Sphinx documentation with auto-reload # Opens browser automatically and ignores build artifacts and Python files -sphinx-autobuild book book/_build/html --open-browser --ignore "book/_build/**" --pre-build "teachbooks build book/ --process-only" \ No newline at end of file +sphinx-autobuild book book/_build/html --open-browser --ignore "book/_build/**" --ignore "*.py" --ignore "book/references.bib" --ignore "book/_toc_with_local_paths.yml" --pre-build "teachbooks build book/ --process-only" \ No newline at end of file From ff6367f5aff0da0aa66bd62232614c51ec1863a0 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Tue, 13 Jan 2026 09:19:36 +0100 Subject: [PATCH 076/110] Annotate external link with '#BUMP' Added a comment '#BUMP' to the external link for Sphinx-Gated-Directives. --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 6441842..b9af3e5 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -89,7 +89,7 @@ parts: - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb # BUMP - - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md + - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md #BUMP - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md From 9f99a7cc4b3fd5152b3072e8d5398b7272da0ce1 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 14 Jan 2026 14:00:07 +0100 Subject: [PATCH 077/110] Update links to Sphinx exercises and contributions --- book/features/favourites.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/book/features/favourites.md b/book/features/favourites.md index d06158c..fb32fcb 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -30,20 +30,20 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Download link replacer](../external/Download-Link-Replacer/README.md) - [Sphinx image inverter](../external/Sphinx-Image-Inverter/README.md) - [Sphinx iframes](../external/sphinx-iframes/README.md) -- [Sphinx exercise (including TeachBooks contributions)](https://ebp-sphinx-exercise.readthedocs.io/en/latest/) +- [Sphinx exercise (from Executable Books including TeachBooks contributions)](https://ebp-sphinx-exercise.readthedocs.io/en/latest/) - [Teachbooks Sphinx tippy](../external/teachbooks-sphinx-tippy/README.md) - [Sphinx named colors](../external/Sphinx-Named-Colors/README.md) - [Sphinx dropdown toggle](../_git/github.com_TeachBooks_Sphinx-Dropdown-Toggle/main/MANUAL.md) -- [Sphinx proof (including TeachBooks contributions)](https://sphinx-proof.readthedocs.io/en/latest/) +- [Sphinx proof (from Executable Books including TeachBooks contributions)](https://sphinx-proof.readthedocs.io/en/latest/) - [Sphinx code examples](../_git/github.com_TeachBooks_sphinx-code-examples/main/MANUAL.ipynb) - [Sphinx accessibility](../_git/github.com_TeachBooks_Sphinx-Accessibility/manual/README.md) -- [Sphinx toggle button (TeachBooks contribution to the original)](https://sphinx-togglebutton.readthedocs.io/en/latest/) +- [Sphinx toggle button (from Executable Books including TeachBooks contributions)](https://sphinx-togglebutton.readthedocs.io/en/latest/) - [Notebook execution patterns](../_git/github.com_TeachBooks_Sphinx-NB-Execution-Patterns/Manual/README.md) - [Sphinx Launch Buttons](../external/Sphinx-launch-buttons/README.md) -- [Sphinx External ToC (TeachBooks contribution to the original)](https://github.com/TeachBooks/sphinx-external-toc/blob/main/README.md) +- [Sphinx External ToC (from Executable Books, TeachBooks version of the original)](https://github.com/TeachBooks/sphinx-external-toc/blob/main/README.md) - [Sphinx GitHub Alerts](../_git/github.com_TeachBooks_Sphinx-GitHub-Alerts/main/README.md) - [Sphinx Metadata Figure](../_git/github.com_TeachBooks_Sphinx-Metadata-Figure/main/MANUAL.ipynb) -- [Sphinx last updated by git](https://github.com/TeachBooks/sphinx-last-updated-by-git) +- [Sphinx last updated by git (from Matthias Geier, TeachBooks version of the original)](https://github.com/TeachBooks/sphinx-last-updated-by-git) The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. From 59865009f1050521a71bfb52cac8e2bd9be8bc14 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 16 Jan 2026 14:35:15 +0100 Subject: [PATCH 078/110] Remove Sphinx External ToC link from favourites Deleted the reference to Sphinx External ToC from the list of related resources in the favourites documentation. --- book/features/favourites.md | 1 - 1 file changed, 1 deletion(-) diff --git a/book/features/favourites.md b/book/features/favourites.md index fb32fcb..860f6aa 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -40,7 +40,6 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Sphinx toggle button (from Executable Books including TeachBooks contributions)](https://sphinx-togglebutton.readthedocs.io/en/latest/) - [Notebook execution patterns](../_git/github.com_TeachBooks_Sphinx-NB-Execution-Patterns/Manual/README.md) - [Sphinx Launch Buttons](../external/Sphinx-launch-buttons/README.md) -- [Sphinx External ToC (from Executable Books, TeachBooks version of the original)](https://github.com/TeachBooks/sphinx-external-toc/blob/main/README.md) - [Sphinx GitHub Alerts](../_git/github.com_TeachBooks_Sphinx-GitHub-Alerts/main/README.md) - [Sphinx Metadata Figure](../_git/github.com_TeachBooks_Sphinx-Metadata-Figure/main/MANUAL.ipynb) - [Sphinx last updated by git (from Matthias Geier, TeachBooks version of the original)](https://github.com/TeachBooks/sphinx-last-updated-by-git) From 79f62e3008eb9c52604c4de4de852ae7af8f051a Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst <49307154+douden@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:49:02 +0100 Subject: [PATCH 079/110] Bump TeachBooks-Favourites dependency version Updated the TeachBooks-Favourites dependency to the latest version. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 517b212..af7e02f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.4 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors +git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors #bump teachbooks-sphinx-grasple From 0242cf27eecfbf16b9234d71a4fd633c79e61d04 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Sat, 28 Feb 2026 13:38:24 +0100 Subject: [PATCH 080/110] Fix formatting of git dependency in requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index af7e02f..517b212 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.4 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors #bump +git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors teachbooks-sphinx-grasple From 5537db2ec5e330ae1231d0d2fc0d792f2823e442 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Sat, 28 Feb 2026 13:44:22 +0100 Subject: [PATCH 081/110] Update TeachBooks-Favourites dependency with comment Updated dependency to include a comment for version bump. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 517b212..272fd34 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.4 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors +git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors #BUMP28-2 teachbooks-sphinx-grasple From deea65c2b6d75ba5d912f7fa94dba3ad8fd0cfe5 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Fri, 13 Mar 2026 09:32:59 +0100 Subject: [PATCH 082/110] Add TeachBooks-Questions and update favourites Add TeachBooks-Questions to the book TOC and TeachBooks Favourites list, and include Sphinx Gated Directives and TeachBooks Zoomies in the favourites page. Also tidy requirements.txt by removing an inline bump comment from the TeachBooks-Favourites git dependency. Changes touch book/_toc.yml, book/features/favourites.md, and requirements.txt to surface the new/manual links and clean up metadata. --- book/_toc.yml | 1 + book/features/favourites.md | 4 ++++ requirements.txt | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index b9af3e5..be8903b 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -90,6 +90,7 @@ parts: - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb # BUMP - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md #BUMP + - external: https://github.com/TeachBooks/TeachBooks-Questions/blob/main/MANUAL.md - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md diff --git a/book/features/favourites.md b/book/features/favourites.md index 860f6aa..34e5e54 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -43,6 +43,10 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Sphinx GitHub Alerts](../_git/github.com_TeachBooks_Sphinx-GitHub-Alerts/main/README.md) - [Sphinx Metadata Figure](../_git/github.com_TeachBooks_Sphinx-Metadata-Figure/main/MANUAL.ipynb) - [Sphinx last updated by git (from Matthias Geier, TeachBooks version of the original)](https://github.com/TeachBooks/sphinx-last-updated-by-git) +- [Sphinx Gated Directives](../_git/github.com_TeachBooks_Sphinx-Gated-Directives/main/MANUAL.md) +- [Teachbooks Zoomies](https://github.com/TeachBooks/TeachBooks-Zoomies/) +- [TeachBooks Questions](../_git/github.com_TeachBooks_TeachBooks-Questions/main/MANUAL.md) + The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. diff --git a/requirements.txt b/requirements.txt index 272fd34..517b212 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.4 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors #BUMP28-2 +git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors teachbooks-sphinx-grasple From 622296fd07670e72dc233c105b684f94a13e12cd Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 16 Mar 2026 15:16:43 +0100 Subject: [PATCH 083/110] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 517b212..2a532ad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.4 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors +git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors #BUMP teachbooks-sphinx-grasple From 3a5d610f0f2a53bc669c40dac7d86553e0e773b4 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 07:44:44 +0100 Subject: [PATCH 084/110] Add external link to Sphinx-Sticky-Margin manual --- book/_toc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/book/_toc.yml b/book/_toc.yml index be8903b..3e64aeb 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -101,6 +101,7 @@ parts: - file: features/apa - file: external/Sphinx-Named-Colors/README.md - external: https://github.com/TeachBooks/Sphinx-Dropdown-Toggle/blob/main/MANUAL.md + - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md - file: features/students sections: - file: external/annotater/README.md From 4b4e66abf6c4f5f723e8e5a98f0c11200de8b785 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 07:45:25 +0100 Subject: [PATCH 085/110] Update requirements.txt --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index 2a532ad..142b1fe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,5 @@ sphinx-apa-references myst_nb numpy matplotlib + +git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps From 1cb1e16d515f89040ea19fa9e8cfa798a37f51e8 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 07:45:41 +0100 Subject: [PATCH 086/110] Add sphinx_sticky_margin to configuration --- book/_config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/book/_config.yml b/book/_config.yml index fd4cab6..7ae925d 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -18,6 +18,7 @@ sphinx: - teachbooks_sphinx_grasple - sphinx_apa_references - sphinx_gated_directives + - sphinx_sticky_margin config: language: en html_js_files: From 860cad0375dbc33208c6e359cac7e91da33534c8 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 08:02:55 +0100 Subject: [PATCH 087/110] Update _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 3e64aeb..9d2d6b4 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -101,7 +101,7 @@ parts: - file: features/apa - file: external/Sphinx-Named-Colors/README.md - external: https://github.com/TeachBooks/Sphinx-Dropdown-Toggle/blob/main/MANUAL.md - - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md + - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md #BUMP - file: features/students sections: - file: external/annotater/README.md From ccf0330cdb48be37cb139d47391244d4bdc47ba1 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 08:29:05 +0100 Subject: [PATCH 088/110] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 142b1fe..dcd2d32 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,4 @@ myst_nb numpy matplotlib -git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps +git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@test-manual From 49fa68ec0f715259704685044f129855469206e5 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 08:45:41 +0100 Subject: [PATCH 089/110] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index dcd2d32..034a2e5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,4 @@ myst_nb numpy matplotlib -git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@test-manual +git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps #BUMP From ff071b7ce5a94a04f43f18e63eca52e6e27f2897 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 08:53:21 +0100 Subject: [PATCH 090/110] Update external link comment in _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 9d2d6b4..ad8a1fd 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -101,7 +101,7 @@ parts: - file: features/apa - file: external/Sphinx-Named-Colors/README.md - external: https://github.com/TeachBooks/Sphinx-Dropdown-Toggle/blob/main/MANUAL.md - - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md #BUMP + - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md #BUMPBUMP - file: features/students sections: - file: external/annotater/README.md From a35f111abfdbcf1f540c3af009822016adc5f884 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 14:02:38 +0100 Subject: [PATCH 091/110] Update _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index ad8a1fd..8287b72 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -101,7 +101,7 @@ parts: - file: features/apa - file: external/Sphinx-Named-Colors/README.md - external: https://github.com/TeachBooks/Sphinx-Dropdown-Toggle/blob/main/MANUAL.md - - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md #BUMPBUMP + - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md #BUMPBUMPBUMP - file: features/students sections: - file: external/annotater/README.md From 3a801249573bd54d851700dee2dd9bd259aa8bd7 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 14:05:20 +0100 Subject: [PATCH 092/110] Update _toc.yml --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 8287b72..be2e252 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -101,7 +101,7 @@ parts: - file: features/apa - file: external/Sphinx-Named-Colors/README.md - external: https://github.com/TeachBooks/Sphinx-Dropdown-Toggle/blob/main/MANUAL.md - - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md #BUMPBUMPBUMP + - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md #BUMPBUMPBUMPBUMP - file: features/students sections: - file: external/annotater/README.md From e11ca55ef3dee9128fd1cae3eb7cf3d29444c8f0 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 14:22:22 +0100 Subject: [PATCH 093/110] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 034a2e5..6e663ba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,4 @@ myst_nb numpy matplotlib -git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps #BUMP +git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps #BUMPBUMP2 From 4f3bf5ef0156a456590596bb115f09c368f5fb5e Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 14:36:35 +0100 Subject: [PATCH 094/110] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6e663ba..3c12ca2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,4 @@ myst_nb numpy matplotlib -git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps #BUMPBUMP2 +git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps #BUMPBUMP2BUMP From 9f10e241b39aae9562f03452a6e4072893f37c9f Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Wed, 25 Mar 2026 15:54:14 +0100 Subject: [PATCH 095/110] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3c12ca2..c5d46ee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,4 @@ myst_nb numpy matplotlib -git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps #BUMPBUMP2BUMP +git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps #BUMPBUMP2BUMPBUMP From 12ae94d2dbaa4a334a407a53f4b9694e455b7980 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 30 Mar 2026 09:21:55 +0200 Subject: [PATCH 096/110] Remove Sphinx-Sticky-Margin from requirements Removed git dependency for Sphinx-Sticky-Margin. --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index c5d46ee..2a532ad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,5 +11,3 @@ sphinx-apa-references myst_nb numpy matplotlib - -git+https://github.com/TeachBooks/Sphinx-Sticky-Margin@first-steps #BUMPBUMP2BUMPBUMP From 41e456bf7fe3d5fa2944110c5ef6d329d3931a4d Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 30 Mar 2026 09:27:49 +0200 Subject: [PATCH 097/110] Fix external link for Sphinx-Sticky-Margin Updated external link to Sphinx-Sticky-Margin manual. --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index be2e252..d2d5176 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -101,7 +101,7 @@ parts: - file: features/apa - file: external/Sphinx-Named-Colors/README.md - external: https://github.com/TeachBooks/Sphinx-Dropdown-Toggle/blob/main/MANUAL.md - - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/first-steps/MANUAL.md #BUMPBUMPBUMPBUMP + - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/main/MANUAL.md - file: features/students sections: - file: external/annotater/README.md From 033ec8a566b42fc6fd873f8d7a788f684f40c818 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 30 Mar 2026 09:30:04 +0200 Subject: [PATCH 098/110] Remove unused Sphinx extensions Removed unused Sphinx extensions from the configuration. --- book/_config.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/book/_config.yml b/book/_config.yml index 7ae925d..7df42ac 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -17,8 +17,6 @@ sphinx: - teachbooks_favourites - teachbooks_sphinx_grasple - sphinx_apa_references - - sphinx_gated_directives - - sphinx_sticky_margin config: language: en html_js_files: From 1f7947bdc7b4d61a640b31a6bfc7af07ae2fb1ca Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 30 Mar 2026 09:33:15 +0200 Subject: [PATCH 099/110] Clean up external links in _toc.yml Removed comments from external links in the table of contents. --- book/_toc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/_toc.yml b/book/_toc.yml index d2d5176..9b8e757 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -88,8 +88,8 @@ parts: - file: features/exercise.md - external: https://github.com/TeachBooks/Sphinx-ref-graph/blob/manual/README.md - external: https://github.com/TeachBooks/Sphinx-GitHub-Alerts/blob/main/README.md - - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb # BUMP - - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md #BUMP + - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb + - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md - external: https://github.com/TeachBooks/TeachBooks-Questions/blob/main/MANUAL.md - file: features/visuals.md sections: From 470472294b582c30cf891daacf7ac15f3a0a67b9 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 30 Mar 2026 09:42:02 +0200 Subject: [PATCH 100/110] Add Sphinx Sticky Margin to favourites list Added Sphinx Sticky Margin to the list of features. --- book/features/favourites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/features/favourites.md b/book/features/favourites.md index 34e5e54..58557d9 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -46,7 +46,7 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Sphinx Gated Directives](../_git/github.com_TeachBooks_Sphinx-Gated-Directives/main/MANUAL.md) - [Teachbooks Zoomies](https://github.com/TeachBooks/TeachBooks-Zoomies/) - [TeachBooks Questions](../_git/github.com_TeachBooks_TeachBooks-Questions/main/MANUAL.md) - +- [Sphinx Sticky Margin](../_git/github.com_TeachBooks_Sphinx-Sticky-Margin/main/MANUAL.md) The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. From 93a15a64a0f36e9c35f8e544652eba25f2e1c028 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst <49307154+douden@users.noreply.github.com> Date: Thu, 7 May 2026 16:12:45 +0200 Subject: [PATCH 101/110] Fix formatting for TeachBooks-Favourites dependency --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2a532ad..517b212 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ teachbooks == 0.2.4 sphinx-inline-tabs -git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors #BUMP +git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors teachbooks-sphinx-grasple From 7b1b7dfe1cf2f783583611a127bf4645a8f04a75 Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Wed, 13 May 2026 11:22:42 +0200 Subject: [PATCH 102/110] Add TeachBooks-Fetch links to docs Include TeachBooks-Fetch in the documentation and favourites list: add its MANUAL external link to book/_toc.yml and add a favourites entry in book/features/favourites.md so the extension is discoverable from the docs. --- book/_toc.yml | 1 + book/features/favourites.md | 1 + 2 files changed, 2 insertions(+) diff --git a/book/_toc.yml b/book/_toc.yml index 9b8e757..250c643 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -102,6 +102,7 @@ parts: - file: external/Sphinx-Named-Colors/README.md - external: https://github.com/TeachBooks/Sphinx-Dropdown-Toggle/blob/main/MANUAL.md - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/main/MANUAL.md + - external: https://github.com/TeachBooks/TeachBooks-Fetch/blob/main/MANUAL.md - file: features/students sections: - file: external/annotater/README.md diff --git a/book/features/favourites.md b/book/features/favourites.md index 58557d9..8f72b75 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -47,6 +47,7 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [Teachbooks Zoomies](https://github.com/TeachBooks/TeachBooks-Zoomies/) - [TeachBooks Questions](../_git/github.com_TeachBooks_TeachBooks-Questions/main/MANUAL.md) - [Sphinx Sticky Margin](../_git/github.com_TeachBooks_Sphinx-Sticky-Margin/main/MANUAL.md) +- [TeachBooks Fetch](../_git/github.com_TeachBooks_TeachBooks-Fetch/main/MANUAL.md) The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. From 8d147d71f8415e444f79c2437e542831d60c152b Mon Sep 17 00:00:00 2001 From: Dennis den Ouden-van der Horst Date: Wed, 13 May 2026 11:30:02 +0200 Subject: [PATCH 103/110] Reorder TeachBooks-Fetch entry in book TOC Update book/_toc.yml to move the TeachBooks-Fetch MANUAL.md external entry into the features/visuals section and remove the duplicate entry later in the file. This tidies the table of contents and ensures the Fetch manual is grouped with the visuals-related externals. --- book/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/_toc.yml b/book/_toc.yml index 250c643..6122b8d 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -91,6 +91,7 @@ parts: - external: https://github.com/TeachBooks/Sphinx-Metadata-Figure/blob/main/MANUAL.ipynb - external: https://github.com/TeachBooks/Sphinx-Gated-Directives/blob/main/MANUAL.md - external: https://github.com/TeachBooks/TeachBooks-Questions/blob/main/MANUAL.md + - external: https://github.com/TeachBooks/TeachBooks-Fetch/blob/main/MANUAL.md - file: features/visuals.md sections: - external: https://github.com/TeachBooks/Sphinx-Accessibility/blob/manual/README.md @@ -102,7 +103,6 @@ parts: - file: external/Sphinx-Named-Colors/README.md - external: https://github.com/TeachBooks/Sphinx-Dropdown-Toggle/blob/main/MANUAL.md - external: https://github.com/TeachBooks/Sphinx-Sticky-Margin/blob/main/MANUAL.md - - external: https://github.com/TeachBooks/TeachBooks-Fetch/blob/main/MANUAL.md - file: features/students sections: - file: external/annotater/README.md From 454b78682c0cb5b83be5946bc1972109cf87c00b Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Fri, 19 Jun 2026 09:59:18 +0200 Subject: [PATCH 104/110] Fix link formatting for Sphinx to do extension --- book/features/favourites.md | 1 + 1 file changed, 1 insertion(+) diff --git a/book/features/favourites.md b/book/features/favourites.md index 8f72b75..5e62bb2 100644 --- a/book/features/favourites.md +++ b/book/features/favourites.md @@ -48,6 +48,7 @@ TeachBooks Favourites is a Sphinx extension which collects all of TeachBooks' fa - [TeachBooks Questions](../_git/github.com_TeachBooks_TeachBooks-Questions/main/MANUAL.md) - [Sphinx Sticky Margin](../_git/github.com_TeachBooks_Sphinx-Sticky-Margin/main/MANUAL.md) - [TeachBooks Fetch](../_git/github.com_TeachBooks_TeachBooks-Fetch/main/MANUAL.md) +- [Sphinx to do (from core sphinx](https://www.sphinx-doc.org/en/master/usage/extensions/todo.html) The extension [Open in new tab](https://pypi.org/project/sphinx-new-tab-link/) is nice, but is not compatible with all setups (dependency clash) so is not included in TeachBooks-Favourites. From 989cc196f0fd698fba2c3a975d04370b2e0c7ab2 Mon Sep 17 00:00:00 2001 From: Freek Pols <55780866+FreekPols@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:18:09 +0200 Subject: [PATCH 105/110] Fix typos Corrected typos and improved clarity in the tools documentation. --- book/installation-and-setup/tools.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/book/installation-and-setup/tools.md b/book/installation-and-setup/tools.md index 0e83db0..537fe63 100644 --- a/book/installation-and-setup/tools.md +++ b/book/installation-and-setup/tools.md @@ -9,26 +9,26 @@ This page is useful for user type 4-5. The setup of tools and URLs is dependent on agreements you've made on [collaboration](./collab.md). -Choosing between GitHub and GitLab depends on multiple criteria. GitHub provides more functionalities, but you might prefer the TU Delft-closed GitLab system if you're a TU Delft employee. +Choosing between GitHub and GitLab depends on multiple criteria. GitHub provides more functionalities, but you might prefer the TU Delft(-closed) GitLab system if you're a TU Delft employee. ## Account GitHub is owned by Microsoft and anyone can make an account. This allows anyone to interact with the source code of your book by posting issues, forking (duplicating while allowing to sync) your book and suggesting changes with pull requests. -For the TU-Delft closed GitLab system only TU Delft account holders can interact with the source code your book, making it not as open as GitHub: collaboration and reuse is inly pissible with manual exports of the source code. Individual external accounts can be requested for. +For the TU-Delft closed GitLab system, only TU Delft account holders can interact with the source code your book, making it not as open as GitHub: collaboration and reuse is only possible with manual exports of the source code. Individual external accounts can be requested for. ## Book URL Github allows you to host your book on the GitHub server using GitHub pages (to be recognized by the `.github.io/` url, for example the [template book](https://teachbooks.github.io/template/)), which takes all the steps of hosting out of your hands. Next to GitHub-provided URLs, you can set up a custom owned URL, although this requires some additional skills on a domain which you should own. -If you're part of TU Delft, you can put your book in the [TUDelft-Book organisation](https://github.com/tudelft-books), which allows you to host your book at `oit.tudelft.nl/`. If you've a private book which is part of the [GitHub Enterprise TU Delft](https://github.com/enterprises/tudelft) and is using SSO, a random url is generated `.github.io/`. For courses we advise you to create a organization with the course name so that the URL represent that course. +If you're part of TU Delft, you can put your book in the [TUDelft-Book organisation](https://github.com/tudelft-books), which allows you to host your book at `oit.tudelft.nl/`. If you've a private book which is part of the [GitHub Enterprise TU Delft](https://github.com/enterprises/tudelft) and is using SSO, a random url is generated `.github.io/`. For courses we advise you to create an organization with the course name so that the URL represent that course. On TU Delft's GitLab you need a webserver, which was offered by TeachBooks in the past (to be recognized by the url `teachbooks.tudelft.nl/`), and is still offered by the TU Delft OIT team (to be recognized by the url `interactivetextbooks.tudelft.nl/`). ## Real-time editing book -Editing the book can happen both locally as online on GitHub/GitLab. If done locally, the book can be generated and viewed locally too (typically takes around 1 minute) but this requires you to be at least user type 4 or 5 depending on the book content. The built book can also be viewed online separate from the released version. +Editing the book can be done both locally and online on GitHub/GitLab. If done locally, the book can be generated and viewed locally too (typically takes around 1 minute) but this requires you to be at least user type 4 or 5 depending on the book content. The built book can also be viewed online separate from the released version. -On GitHub we developed a [automatic process which builds the book and publishes it online](../external/deploy-book-workflow/README.md) in a very flexible way (publication of multiple version of the book, insights in book building errors, parallel so fast build, custom urls in subdirectories). For a private repository, there is an extensive but limited amount of actions-minutes required for published your book. If this proves to be a limit, consider applying for [Teacher benefits](https://docs.github.com/en/education/explore-the-benefits-of-teaching-and-learning-with-github-education/github-education-for-teachers/about-github-education-for-teachers#github-education-features-for-teachers) or joining the [GitHub Enterprise of TU Delft](https://github.com/enterprises/tudelft). +On GitHub we developed an [automatic process which builds the book and publishes it online](../external/deploy-book-workflow/README.md) in a very flexible way (publication of multiple version of the book, insights in book building errors, parallel so fast build, custom urls in subdirectories). For a private repository, there is an extensive but limited amount of actions-minutes required for publishing your book. If this proves to be a limit, consider applying for [Teacher benefits](https://docs.github.com/en/education/explore-the-benefits-of-teaching-and-learning-with-github-education/github-education-for-teachers/about-github-education-for-teachers#github-education-features-for-teachers) or joining the [GitHub Enterprise of TU Delft](https://github.com/enterprises/tudelft). -On GitLab a webserver is required to process book-changes online. Both we and other people at TU Delft have a simplistic workflow which can be used when you're set up on those Git environments and webservers. This simplistic workflow doesn't build all branches, is not easily adaptable, doesn't cache environments, doesn't give a visual summary, and doesn't allow for parallel processes (for every build a runner needs to be assigned for which there's typically only one available). If you want to use GitLab but still want to make use of the GitHub workflow, you can [mirror your repository to GitHub](https://docs.gitlab.com/ee/user/project/repository/mirror/push.html#set-up-a-push-mirror-from-gitlab-to-github). For the TU Delft OIT webserver you’re required to publish your book more officially, it cannot be used for viewing your book online in an active editing-phase since constant copyright checks have to be performed. The amount of computing power available is dependent on how you set the server yourself. +For GitLab a webserver is required, if GitLab pages is not enabled, to process book-changes online. Both we and other people at TU Delft have a simplistic workflow which can be used when you're set up on those Git environments and webservers. This simplistic workflow doesn't build all branches, is not easily adaptable, doesn't cache environments, doesn't give a visual summary, and doesn't allow for parallel processes (for every build a runner needs to be assigned for which there's typically only one available). If you want to use GitLab but still want to make use of the GitHub workflow, you can [mirror your repository to GitHub](https://docs.gitlab.com/ee/user/project/repository/mirror/push.html#set-up-a-push-mirror-from-gitlab-to-github). For the TU Delft OIT webserver you’re required to publish your book more officially, it cannot be used for viewing your book online in an active editing-phase since constant copyright checks have to be performed. The amount of computing power available is dependent on how you set the server yourself. ## Setting up book repository and website On GitHub you can start right away with a git environment and online book using our [template](../external/template/README.md) without the need for any webserver setup! From 1caadbdee81945ddf346f66db291ad924f89cc82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Jul 2026 23:02:54 +0000 Subject: [PATCH 106/110] Bump teachbooks from 0.2.4 to 0.2.5 Bumps [teachbooks](https://github.com/teachbooks/teachbooks) from 0.2.4 to 0.2.5. - [Release notes](https://github.com/teachbooks/teachbooks/releases) - [Changelog](https://github.com/TeachBooks/TeachBooks/blob/develop/CHANGELOG.md) - [Commits](https://github.com/teachbooks/teachbooks/compare/v0.2.4...v0.2.5) --- updated-dependencies: - dependency-name: teachbooks dependency-version: 0.2.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 517b212..9b21af9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -teachbooks == 0.2.4 +teachbooks == 0.2.5 sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors From ab43185bb2867191a1e1ad48383b9781f0e798d0 Mon Sep 17 00:00:00 2001 From: FreekPols Date: Fri, 28 Aug 2026 22:38:10 +0200 Subject: [PATCH 107/110] first description of pixi incl pixi.toml file --- .gitattributes | 2 + .gitignore | 4 +- book/_toc.yml | 1 + book/installation-and-setup/overview.md | 4 +- book/installation-and-setup/pixi.md | 21 + pixi.lock | 4309 +++++++++++++++++++++++ pixi.toml | 23 + 7 files changed, 4361 insertions(+), 3 deletions(-) create mode 100644 .gitattributes create mode 100644 book/installation-and-setup/pixi.md create mode 100644 pixi.lock create mode 100644 pixi.toml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..997504b --- /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 diff --git a/.gitignore b/.gitignore index 646bdab..24e0c54 100644 --- a/.gitignore +++ b/.gitignore @@ -140,4 +140,6 @@ book/.jupyterlite.doit.db **.teachbooks/ book/_toc_with_local_paths.yml book/_git/ -book/conf.py \ No newline at end of file +book/conf.py# pixi environments +.pixi/* +!.pixi/config.toml diff --git a/book/_toc.yml b/book/_toc.yml index 6122b8d..94c31a5 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -17,6 +17,7 @@ parts: - file: installation-and-setup/overview.md sections: - file: installation-and-setup/vscode-setup.md + - file: installation-and-setup/pixi.md - file: installation-and-setup/git-setup_local.md - file: installation-and-setup/anaconda.md - file: installation-and-setup/git_bash_conda_vs-code.md diff --git a/book/installation-and-setup/overview.md b/book/installation-and-setup/overview.md index a99389e..1564c78 100644 --- a/book/installation-and-setup/overview.md +++ b/book/installation-and-setup/overview.md @@ -15,5 +15,5 @@ The following table will link the relevant installation and setup steps for you. |:---:|:---|:---| | Type 1
Type 2 | Review book | No software needed! Just open your interactive book online and give a review in the way you're asked to | | Type 3 | Edit single files online | No software needed! But you'll interact with Git, which might be a new thing for you | -| Type 4 | Editing text
Git| VS Code
GitHub Desktop / Git in VS Code | -| Type 5 | Editing text
Git
Managing code-related software
Build your book | VS Code
GitHub Desktop / Git in VS Code
Anaconda
Jupyter Book/Sphinx | +| Type 4 | Editing text
Git| VS Code _or_ Jupyterlab
GitHub Desktop / Git in VS Code | +| Type 5 | Editing text
Git
Managing code-related software
Build your book | VS Code_or_ Jupyterlab
GitHub Desktop / Git in VS Code
Anaconda
Jupyter Book/Sphinx | diff --git a/book/installation-and-setup/pixi.md b/book/installation-and-setup/pixi.md new file mode 100644 index 0000000..17043ce --- /dev/null +++ b/book/installation-and-setup/pixi.md @@ -0,0 +1,21 @@ +# Installing and running with Pixi + +- Install pixi + +In the root file of the TB: + +- run `pixi install` + +This will install teachbooks and the most common dependecies. + +three tasks: +- `pixi run editor` this will start jupyterlab as the editor for both markdown and jupyternotebooks +- `pixi run serve` starts a server +- `pixi run teachbooks` builds the book (equivalent to `teachbooks build book` as described here) + + + + + +## Editing with Jupyter lab +Something about Jupyter lab \ No newline at end of file diff --git a/pixi.lock b/pixi.lock new file mode 100644 index 0000000..38940d5 --- /dev/null +++ b/pixi.lock @@ -0,0 +1,4309 @@ +version: 6 +environments: + default: + 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/win-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-26.1.0-py314h5a2d7ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.7.0-py314h680f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.15.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.4.0-hac0b51c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-hc8c2fe1_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hd477307_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py314h85cf176_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-2.0.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-2.0.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.1.1-py314h5a2d7ad_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.5.1-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/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py314hf309875_4.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.7-py314hd8ed1ab_101.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.21-py314hb98de8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_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/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.18.3-hd47e2ca_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonttools-4.63.0-pyh7db6752_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.15-h5112557_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-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/win-64/icu-78.3-h5112557_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.19-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.3.0-pyh6dadd2b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.17.0-pyhe2676ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.20.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.15.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-builder-1.2.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.21.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.1-py314hf309875_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h719d79b_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19.1-hf2c6c5f_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.2.0-hd936e49_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-9_h8455456_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hf02afa3_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-h84f9c24_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-he2a975b_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-9_h2a3cdd5_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-23.1.0-default_hacd6ee9_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h1a1d4e4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-16.2.0-h110b43a_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.3-he810d59_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-16.2.0-h8ee18e1_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libharfbuzz-14.4.0-h03b5201_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.13.0-default_h049141e_1000.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-9_hf9ab0e9_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-hdc8cecf_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpython-3.14.7-h4f90d01_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libraqm-0.11.0-h50d6d30_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.22-h6a83c73_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.2-h8f73337_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.357.0-h477610d_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_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/libxcb-1.17.0-h874e120_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-23.1.0-h49e36cd_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py314h2359020_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.11.1-py314h30c6bc1_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.11.1-py314h2061cd4_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.3.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2026.1.0-hac47afa_235.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.11.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.11.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio2-1.7.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.5.2-py314h02f10f6_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-h8466c1e_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-12.3.0-py314h61b30b5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.11.5-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.26.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.53-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py314hc5dbbe4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-hba3369d_1003.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.21.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.2-py314h447aaf0_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.14.7-h53f6dd8_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.22.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.7-h4df99d1_101.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-4.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.3-pyhd8ed1ab_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/pywin32-312-py314hf700ef7_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-3.0.5-py314h51f0985_0.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/pyzmq-27.2.0-py312h343a6d4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.2-pl5321hfcac499_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-2026.6.3-py314h9f07db2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.9.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2023.0.0-hd3d4ead_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.8-py314h5a2d7ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.16.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.16.0-h69aa097_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.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/unicodedata2-17.0.1-py314h5a2d7ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_41.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-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/winpty-0.4.3-4.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_2.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/zeromq-4.3.5-h3a581c9_11.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda + - pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b8/8f/6f7273a7adb8d73fc8d21ede4376a3e475e52f98435c6007f69100dec8ca/bracex-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/2e/bfe6b05463f5f95b831c43a4754c403bb4d8376ba5bb57d53839217fdd4c/download_link_replacer-1.0.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/3d/5cc9701117ea4dc0eb7bf1f4f9b7888a6e2e5277ddfae095805ace50f2b6/greenlet-3.5.5-cp314-cp314-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/01/f9/575c8d760eae1fc99651b7cc5efd96ad5379ca4d6b53750b0fb4fe983f34/imagesize-2.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/77/3781f65cafe55480b56914def99022a5d2965a4bb269655c89ef2f1de3cd/importlib-1.0.4.zip + - pypi: https://files.pythonhosted.org/packages/37/86/d45756beaeb4b9b06125599b429451f8640b5db6f019d606f33c85743fd4/jupyter_book-1.0.4.post1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/6b/67b87da9d36bff9df7d0efbd1a325fa372a43be7158effaf43ed7b22341d/jupyter_cache-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/54/af203c61a0550c232ed5e859d2c98f3fe80d1248b6ea1c4d4d5621fa08c9/jupyterbook_patches-1.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/40/23569737873cc9637fd488606347e9dd92b9fa37ba4fcda1f98ee5219a97/latexcodec-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/3d/e34b19cd144071c583317268c4feb2c59c03ac57eef69753410c7abb11c0/linkify_it_py-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-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/94/93/0a378b48488879a1d925b42a804edfc6e0cd0ef854220f2dce738a46e7e9/myst_nb-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/f6/775eb92e865b28cdb4ad1f2bed7a5446197516f76b58a950faa3be3fd08d/pybtex-0.26.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/b1/ce1f4596211efb5410e178a803f08e59b20bedb66837dcf41e21c54f9ec1/pybtex_docutils-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/0d/8ba33fa83a7dcde13eb3c1c2a0c1cc29950a048bfed6d9b0d8b6bd710b4c/pydata_sphinx_theme-0.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4c/07/2ebca9b11fb9be7340a818d8d6f63feaebb146be2c4afbd6061701d6df6e/snowballstemmer-3.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl + - pypi: git+https://github.com/TeachBooks/sphinx-last-updated-by-git#986142bb958d2e0f18da6755c551be865aa512ff + - pypi: git+https://github.com/TeachBooks/Sphinx-Thebe#1f3a80969622b7d63f48f05d8769f5cb933202a0 + - pypi: https://files.pythonhosted.org/packages/5c/60/6bf80661f1fc2573c6485819dc6daafa9e80b26fc60559e3cdba7552716d/sphinx_accessibility-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cc/6e/b152dee1988fb4125b2fd882c63330d89706bccdf661c55230e5ed456c67/sphinx_apa_references-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/bf/6f506a37c7f8ecc4576caf9486e303c7af249f6d70447bb51dde9d78cb99/sphinx_book_theme-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/9e/e9d545c5c699cd6fa35912b487cde2910e4c5fcf7e4f52fced2f31dd8cdc/sphinx_code_examples-1.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/97/a5c39f619375d4f81d5422377fb027075898efa6b6202c1ccf1e5bb38a32/sphinx_comments-0.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/cf/45dd359f6ca0c3762ce0490f681da242f0530c49c81050c035c016bfdd3a/sphinx_design-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/1c/6f22279218e978b08d6d301a8991547a585c3699942a33740de81843bdc5/sphinx_dropdown_toggle-1.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/95/af014c5eb8e804103471bcf3204ebfe6a674d8bae07e5c2b691c09183b9f/sphinx_exercise-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/80/1704c9179012e289dee2178354e385277ea51f4fa827c4bf7e36c77b0f4b/sphinx_external_toc-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a1/09/58a0b9ba3a3624b8d940f73651c9dd0430255f616b76df18958816717bc8/sphinx_gated_directives-1.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/a5/ec4c322063caff100c15415a48facc1501083e81ebf7a01426c1167d63bc/sphinx_github_alerts-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/42/08/2ea6aadc6edeb09784ea94448ecd451b7f79710b4c660dc377e2dd044a3b/sphinx_iframes-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/57/9eae17f1c0e2790ec2e2e8e914de1790cf7c28c59a275b9a4e0cc474344b/sphinx_image_inverter-1.1.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/2b/e64e7de34663cff1df029ba4f05a86124315bd9eba3d3b78e64904bea7e0/sphinx_inline_tabs-2025.12.21.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/70/1f/1d4ecaf58b17fe61497644655f40b04d84a88348e41a6f0c6392394d95e4/sphinx_jupyterbook_latex-1.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/99/9ad0c2c2e75d4e99b5023f6e12c77984875b1adab5bbc17e863c17cc1ba0/sphinx_launch_buttons-1.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/e0/ae934d06e31c67164145ada3ab8efec7a588a8f8f71cb3b54431935f0d76/sphinx_metadata_figure-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/9f/902f2030674cd9473fdbe5a2c2dec2618c27ec853484c35f82cf8df40ece/sphinx_multitoc_numbering-0.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/d8/9c2ad1764a9f6736ec65134ef5fbee8c0d1f148cff260fef3afa38479998/sphinx_named_colors-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/24/a4bbc812400aae41072d7b42f99c8787a097618a1084e7439aa03de3c73d/sphinx_nb_execution_patterns-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a6/7a/d3397a28c21cc3981de5fb26910b1f0b8821152dcfdba1737388edbe7864/sphinx_proof-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/38/53f6735ac5392534218e6832aa749501a188a9f052a9f5b7de195bb6a7ea/sphinx_sticky_margin-1.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/2e/3dd55564928c5d61f92827d4b91307dde7911a40fbe0000645d73202eea9/sphinx_togglebutton-0.4.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/c0/d28e62407f4733bbe0169287bc012f0ac3b4a2021066b285570654119c8b/sphinxcontrib_bibtex-2.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/85/5a61ac88dc21df340a5999ca3ab94edaf58287010c62020be426703b8dd3/sphinxcontrib_video-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e3/13/62ff9dadfe0c70203e8d5f38635955bbd41b48ff916788a22fc033232348/sphinxnotes_comboroles-1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ac/e7/992d469644baa4408e2d0be36e07aa727fe0a2dea40dc9c150ca10c8c5ad/teachbooks-0.2.5-py3-none-any.whl + - pypi: git+https://github.com/TeachBooks/TeachBooks-Favourites.git#ad0f301f83effb9322a5460f444d88878b30a75b + - pypi: https://files.pythonhosted.org/packages/7f/24/77b78c112c60e2ddb16351e77f9a108628a6c3c18a618815112d79d374a2/teachbooks_fetch-0.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/d0/99a7a3e3cce5d83566567c484cce9f2c5874c22da4cf2d420647233dbc81/teachbooks_questions-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/05/77/8c5a7237bc99221408f12b629210b8f2176bcccfca916c09edfa8eb048e3/teachbooks_sphinx_tippy-1.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/24/74/f356db22f82eba6fd559128ae31222564f1e9e1e8b46a6ff93262621a9a2/teachbooks_zoomies-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/61/73/d21edf5b204d1467e06500080a50f79d49ef2b997c79123a536d4a17d97c/uc_micro_py-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/45/563267247f0b6f7c0f8028ab92bf1664da26179a630f863933033d74ab75/wcmatch-8.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/29/69cfbb602cd91690c55d38ba9fe53e6a7e76a6fa647bf38f19c138d25449/wheel-0.48.0-py3-none-any.whl +packages: +- conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 8a1cee28bd0ee7451ada1cd50b64720e57e17ff994fc62dd8329bef570d382e4 + md5: 1626967b574d1784b578b52eaeb071e7 + depends: + - libgomp >=7.5.0 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - openmp_impl <0.0a0 + - msys2-conda-epoch <0.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 52252 + timestamp: 1770943776666 +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_3.conda + sha256: 2a7204314663eeda5dec482a956f0e2eaf289bd5b9953eaaaad0e81aa64638f2 + md5: 3845f3d75991bae0fb90884662f4327c + depends: + - cpython + - python-gil + license: MIT + license_family: MIT + purls: [] + size: 8144 + timestamp: 1784221492234 +- pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl + name: accessible-pygments + version: 0.0.5 + sha256: 88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7 + requires_dist: + - pygments>=1.5 + - pillow ; extra == 'dev' + - pkginfo>=1.10 ; extra == 'dev' + - playwright ; extra == 'dev' + - pre-commit ; extra == 'dev' + - setuptools ; extra == 'dev' + - twine>=5.0 ; extra == 'dev' + - hypothesis ; extra == 'tests' + - pytest ; extra == 'tests' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl + name: alabaster + version: 0.7.16 + sha256: b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.2-pyhcf101f3_0.conda + sha256: e36998c5e860e26b22e5dbcd5726dd0c4eabad949c84d383cad8512757bbf6a1 + md5: fb568fbae6908ba86a090a85a089d11f + depends: + - exceptiongroup >=1.0.2 + - idna >=2.8 + - python >=3.10 + - typing_extensions >=4.5 + - python + constrains: + - trio >=0.32.0 + - uvloop >=0.22.1 + - winloop >=0.2.3 + license: MIT + license_family: MIT + purls: + - pkg:pypi/anyio?source=hash-mapping + size: 164465 + timestamp: 1783889660383 +- conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + sha256: bea62005badcb98b1ae1796ec5d70ea0fc9539e7d59708ac4e7d41e2f4bb0bad + md5: 8ac12aff0860280ee0cff7fa2cf63f3b + depends: + - argon2-cffi-bindings + - python >=3.9 + - typing-extensions + constrains: + - argon2_cffi ==999 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi?source=hash-mapping + size: 18715 + timestamp: 1749017288144 +- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-26.1.0-py314h5a2d7ad_0.conda + sha256: 47917aa31232191136b40f3055d4b469c0a71475aea396c2413d753be014b7dc + md5: 6c4598c60f92421a0f9926a0f4b36dd0 + depends: + - cffi >=2.0.0b1 + - 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/argon2-cffi-bindings?source=compressed-mapping + size: 33526 + timestamp: 1787248062135 +- conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + sha256: 792da8131b1b53ff667bd6fc617ea9087b570305ccb9913deb36b8e12b3b5141 + md5: 85c4f19f377424eafc4ed7911b291642 + depends: + - python >=3.10 + - python-dateutil >=2.7.0 + - python-tzdata + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/arrow?source=hash-mapping + size: 113854 + timestamp: 1760831179410 +- conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.2-pyhd8ed1ab_0.conda + sha256: fbbd8ce60cbd5c16f3fe559eb644551f94285caff30985ea961ff851c1cf25ac + md5: 89d495168582cb00428dad699d149624 + depends: + - python >=3.10 + constrains: + - astroid >=2,<5 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/asttokens?source=hash-mapping + size: 34639 + timestamp: 1783975742052 +- conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + sha256: ea8486637cfb89dc26dc9559921640cd1d5fd37e5e02c33d85c94572139f2efe + md5: b85e84cb64c762569cc1a760c2327e0a + depends: + - python >=3.10 + - typing_extensions >=4.0.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/async-lru?source=hash-mapping + size: 22949 + timestamp: 1773926359134 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab + md5: c6b0543676ecb1fb2d7643941fe375f2 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/attrs?source=hash-mapping + size: 64927 + timestamp: 1773935801332 +- conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + sha256: a14a9ad02101aab25570543a59c5193043b73dc311a25650134ed9e6cb691770 + md5: f1976ce927373500cc19d3c0b2c85177 + depends: + - python >=3.10 + - python + constrains: + - pytz >=2015.7 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/babel?source=hash-mapping + size: 7684321 + timestamp: 1772555330347 +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.7.0-py314h680f03e_0.conda + noarch: generic + sha256: 19514d89d1e725e44b0650d31a4d43da8e070e4e93e4131e3b16bd139404f2b2 + md5: 92adf685875ab717f68ad4172ef6de27 + depends: + - python >=3.14 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: [] + size: 7541 + timestamp: 1786861415851 +- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.15.0-pyha770c72_0.conda + sha256: aed4b9dcf68ec2a75e5645fed14d77fd884d38d2e52bfa6ef4b278d90cd88781 + md5: 3b261da3fe9b4168738712832410b022 + depends: + - python >=3.10 + - soupsieve >=1.2 + - typing-extensions + license: MIT + license_family: MIT + purls: + - pkg:pypi/beautifulsoup4?source=hash-mapping + size: 92704 + timestamp: 1780853175566 +- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.4.0-pyhcf101f3_0.conda + sha256: 0c786f3e571bd58ac73d730d06314716663884d848ae320de0b438fae5e0bea9 + md5: 93009c29cdd6f2500468f2502fff9209 + depends: + - python >=3.10 + - webencodings + - python + constrains: + - tinycss2 >=1.1.0,<1.5 + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/bleach?source=hash-mapping + size: 142246 + timestamp: 1780675823953 +- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.4.0-hac0b51c_0.conda + sha256: ede77e412304cd080e23967352a7904932207d0167ecdccd6a9e210530942be6 + md5: 5f710eab1f3c4e773c75686f5e8e6481 + depends: + - bleach ==6.4.0 pyhcf101f3_0 + - tinycss2 + license: Apache-2.0 AND MIT + purls: [] + size: 4406 + timestamp: 1780675823953 +- pypi: https://files.pythonhosted.org/packages/b8/8f/6f7273a7adb8d73fc8d21ede4376a3e475e52f98435c6007f69100dec8ca/bracex-3.0.1-py3-none-any.whl + name: bracex + version: 3.0.1 + sha256: 6523ad83aeb5098a4ee597cff0f964442ff74e460bd3fafaffab6a013ff2288c + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-hc8c2fe1_3.conda + sha256: 85e12348d058791aabd6eeb6abc1d7ab44b8f6308f91c8475f44f778f2a158af + md5: 9eba56a007c44dc32d0b9d0a820871ea + depends: + - brotli-bin 1.2.0 hd477307_3 + - libbrotlidec 1.2.0 h84f9c24_3 + - libbrotlienc 1.2.0 he2a975b_3 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 20954 + timestamp: 1786622876247 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hd477307_3.conda + sha256: 5328e0576c729813d28efc15613f4be94d029d77c4fe5afda16cab0b8d0c9d05 + md5: dc04f7b3d82c6fb3fdf4d93e45b6ea2a + depends: + - libbrotlidec 1.2.0 h84f9c24_3 + - libbrotlienc 1.2.0 he2a975b_3 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 23119 + timestamp: 1786622866096 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py314h85cf176_3.conda + sha256: f96c411313beb92a6a9066b823f7e8ea085f3e3889219b44306c44d59f99e611 + md5: b1ff58c1f0deedd3f25c103e37049cee + 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 hf02afa3_3 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 336902 + timestamp: 1786623039339 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda + sha256: 04767466ee9227c9c57ab2c6503e0149177d34111c7418d2f420297acb1eb229 + md5: c3301c058362f340100d91cd8be0393f + 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: 55919 + timestamp: 1785906343696 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda + sha256: 95e8e74062a5fe5f870ac8c90302b6e89945165fdaed7810606e84ddee6aac12 + md5: e27d2ac27b096dc51fedfcf775a53f9b + depends: + - __win + license: ISC + purls: [] + size: 132136 + timestamp: 1784754918886 +- conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-2.0.1-pyhcf101f3_0.conda + sha256: 39358005c3cc44d8315ed79789b18a960d69365be979970cc6bae8f7a6177703 + md5: 70e764e549c6c25de5e429d6e4a28b39 + depends: + - cached_property >=2.0.1,<2.0.2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/cached-property?source=compressed-mapping + size: 3720 + timestamp: 1787678456483 +- conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-2.0.1-pyhcf101f3_0.conda + sha256: 4bd96dab5a434e4ee59fb6910cae704d4c5b453907d4886272a9943d37e42b6f + md5: 256d863ded0f79464391a075944d24a6 + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/cached-property?source=compressed-mapping + size: 16597 + timestamp: 1787678456483 +- conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_2.conda + sha256: 9128dfc6a864e369ee7b1c9bd4b3875de9d06890925760aec932cf3cc67bcb24 + md5: 601e2ec8ae0ed934d8788000f984ff18 + depends: + - fontconfig >=2.18.3,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.3,<79.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libglib >=2.88.3,<3.0a0 + - libpng >=1.6.58,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - pixman >=0.46.4,<1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-only or MPL-1.1 + purls: [] + size: 1540051 + timestamp: 1787926241225 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda + sha256: fb167de4388e64e52aa3907ed099afab944c1fa6e5f74b281a312dae1bcf7f3b + md5: 37e13edbe3b48f1095a9d085ef9cd83b + depends: + - python >=3.10 + license: ISC + purls: + - pkg:pypi/certifi?source=hash-mapping + size: 137015 + timestamp: 1784717699092 +- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.1.1-py314h5a2d7ad_2.conda + sha256: e0e10d676eb67a8a4c8991cec89fb6f150f919eb1266a1b39253a857b3dc0454 + md5: 672d6ff72c6265b25eeef94ce21e71ac + 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=compressed-mapping + size: 346657 + timestamp: 1786775160153 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.5.1-pyhd8ed1ab_0.conda + sha256: cb60ef3e0631c8bacb4f7057196dee4496091a22baa3bb4b9bccb12c7e1c921b + md5: e0ac3accc64e23e40969d660e5f58ac8 + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/charset-normalizer?source=compressed-mapping + size: 64487 + timestamp: 1786835648298 +- pypi: https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl + name: click + version: 8.5.0 + sha256: 255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360 + requires_python: '>=3.10' +- 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/noarch/comm-0.2.3-pyhe01879c_0.conda + sha256: 576a44729314ad9e4e5ebe055fbf48beb8116b60e58f9070278985b2b634f212 + md5: 2da13f2b299d8e1995bafbbe9689a2f7 + depends: + - python >=3.9 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/comm?source=hash-mapping + size: 14690 + timestamp: 1753453984907 +- conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py314hf309875_4.conda + sha256: f141bcbf8e490b49b2f53f517173d13a64d75e43cfae170e0d931cb0b66f4bce + md5: c26934035616f7d578f9da0491aed3d8 + depends: + - numpy >=1.25 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/contourpy?source=hash-mapping + size: 247437 + timestamp: 1769155978556 +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.7-py314hd8ed1ab_101.conda + noarch: generic + sha256: 57a6f69c77cec9726b91e8bb4f4e93979dfad65277ef2acba8ef31ffc9939187 + md5: 5656db6c2bbe5923be509b769c843ed9 + depends: + - python >=3.14,<3.15.0a0 + - python_abi * *_cp314 + license: Python-2.0 + purls: [] + size: 50513 + timestamp: 1787780089142 +- conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda + sha256: bb47aec5338695ff8efbddbc669064a3b10fe34ad881fb8ad5d64fbfa6910ed1 + md5: 4c2a8fef270f6c69591889b93f9f55c1 + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/cycler?source=hash-mapping + size: 14778 + timestamp: 1764466758386 +- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.21-py314hb98de8c_0.conda + sha256: daa9397ffba6722f27c21b2f0a02b197f3ba9baedb484a155539743ec5ea3ac3 + md5: 945786ac874b8e821a675fbdd885f844 + 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/debugpy?source=hash-mapping + size: 4022782 + timestamp: 1780390190830 +- conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + sha256: 9717a059677553562a8f38ff07f3b9f61727bd614f505658b0a5ecbcf8df89be + md5: 961b3a227b437d82ad7054484cfa71b2 + depends: + - python >=3.6 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/defusedxml?source=hash-mapping + size: 24062 + timestamp: 1615232388757 +- pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl + name: docutils + version: 0.21.2 + sha256: dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda + sha256: 09e30a170e0da3e9847d449b594b5e55e6ae2852edd3a3680e05753a5e015605 + md5: 3d3caf4ccc6415023640af4b1b33060a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 70943 + timestamp: 1765193243911 +- pypi: https://files.pythonhosted.org/packages/fe/2e/bfe6b05463f5f95b831c43a4754c403bb4d8376ba5bb57d53839217fdd4c/download_link_replacer-1.0.6-py3-none-any.whl + name: download-link-replacer + version: 1.0.6 + sha256: a4bf385f69b1a5488a76ea1cfbd51955bfc39154b9ae450a7cdc1f421d9f5642 + requires_dist: + - sphinx + - importlib + requires_python: '>=3.9' +- 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/executing-2.2.1-pyhd8ed1ab_0.conda + sha256: 210c8165a58fdbf16e626aac93cc4c14dbd551a01d1516be5ecad795d2422cad + md5: ff9efb7f7469aed3c4a8106ffa29593c + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/executing?source=hash-mapping + size: 30753 + timestamp: 1756729456476 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b + md5: 0c96522c6bdaed4b1566d11387caaf45 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 397370 + timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c + md5: 34893075a5c9e55cdafac56607368fc6 + license: OFL-1.1 + license_family: Other + purls: [] + size: 96530 + timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 + md5: 4d59c254e01d9cde7957100457e2d5fb + license: OFL-1.1 + license_family: Other + purls: [] + size: 700814 + timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 + md5: 49023d73832ef61042f6a237cb2687e7 + license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 + license_family: Other + purls: [] + size: 1620504 + timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.18.3-hd47e2ca_1.conda + sha256: f26139e3c774a6434c8a73381c08e3d2a4c2f9d9ef9587c66aab8836211ee2ec + md5: ed95670fed91b091fe34ba6cae6677d7 + depends: + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libiconv >=1.18,<2.0a0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 217988 + timestamp: 1786667461139 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 + md5: fee5683a3f04bd15cbd8318b096a27ab + depends: + - fonts-conda-forge + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 3667 + timestamp: 1566974674465 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 + md5: a7970cd949a077b7cb9696379d338681 + depends: + - font-ttf-ubuntu + - font-ttf-inconsolata + - font-ttf-dejavu-sans-mono + - font-ttf-source-code-pro + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 4059 + timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonttools-4.63.0-pyh7db6752_0.conda + sha256: c9752235f1ff7061d834e5e4a3d0adf71ebeeff2b3fad82dab607edce7f70c91 + md5: 0509ee74d95e5b98eb6fe2a47760e399 + depends: + - brotli + - munkres + - python >=3.10 + - unicodedata2 >=15.1.0 + track_features: + - fonttools_no_compile + license: MIT + license_family: MIT + purls: + - pkg:pypi/fonttools?source=hash-mapping + size: 846038 + timestamp: 1778770337113 +- conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + sha256: 2509992ec2fd38ab27c7cdb42cf6cadc566a1cc0d1021a2673475d9fa87c6276 + md5: d3549fd50d450b6d9e7dddff25dd2110 + depends: + - cached-property >=1.3.0 + - python >=3.9,<4 + license: MPL-2.0 + license_family: MOZILLA + purls: + - pkg:pypi/fqdn?source=hash-mapping + size: 16705 + timestamp: 1733327494780 +- conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_2.conda + sha256: 32f7dd8ffe62fd485e9e6570e871f5be45af74c84fde62241a2417046a373efd + md5: 6fc6c09c05a099d58efd9b2e96598e41 + depends: + - libfreetype 2.14.3 h57928b3_2 + - libfreetype6 2.14.3 hdbac1cb_2 + - zlib + license: GPL-2.0-only OR FTL + purls: [] + size: 186945 + timestamp: 1786641050416 +- conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_1.conda + sha256: 274b3e4ae5dff527062039d1dcb5cfdd9f91fa7d8eaf61358c09450b361385de + md5: 66f5ce9d0d618332023619a899ceb26f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-or-later + purls: [] + size: 65318 + timestamp: 1785912637725 +- conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.15-h5112557_1.conda + sha256: 93a59bdf944fb6f947bd7ad2f293d5d80db3a90f8ff8dfabc591e3752141e46f + md5: 79538e7a7bc024084eda5989f73fde35 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 98064 + timestamp: 1786118492029 +- pypi: https://files.pythonhosted.org/packages/2e/3d/5cc9701117ea4dc0eb7bf1f4f9b7888a6e2e5277ddfae095805ace50f2b6/greenlet-3.5.5-cp314-cp314-win_amd64.whl + name: greenlet + version: 3.5.5 + sha256: 7dffc5c859fe6059974df1e37d7923d654a83e2ae18fdd616994270e001115e1 + requires_dist: + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + - objgraph ; extra == 'test' + - psutil ; extra == 'test' + - setuptools ; extra == 'test' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + sha256: 96cac6573fd35ae151f4d6979bab6fbc90cb6b1fb99054ba19eb075da9822fcb + md5: b8993c19b0c32a2f7b66cbb58ca27069 + depends: + - python >=3.10 + - typing_extensions + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/h11?source=hash-mapping + size: 39069 + timestamp: 1767729720872 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.4.1-pyhcf101f3_0.conda + sha256: 307dd6ec90140c3cf4171071b0e5e870abec314f4565c1edd5bc433e942cdcc0 + md5: e652ac7756069c456d0da2a922cd7df5 + depends: + - python >=3.10 + - hyperframe >=6.1,<7 + - hpack >=4.2,<5 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/h2?source=hash-mapping + size: 100789 + timestamp: 1785796355216 +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.2.0-pyhd8ed1ab_0.conda + sha256: fdcea5d7cb314485d3907192ef024c704311548c5b0cbeb390cd1951051e29d2 + md5: b395909221b9bd1df066e5930e18855b + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/hpack?source=hash-mapping + size: 32884 + timestamp: 1782283986153 +- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + sha256: 04d49cb3c42714ce533a8553986e1642d0549a05dc5cc48e0d43ff5be6679a5b + md5: 4f14640d58e2cc0aa0819d9d8ba125bb + depends: + - python >=3.9 + - h11 >=0.16 + - h2 >=3,<5 + - sniffio 1.* + - anyio >=4.0,<5.0 + - certifi + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/httpcore?source=hash-mapping + size: 49483 + timestamp: 1745602916758 +- conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + sha256: cd0f1de3697b252df95f98383e9edb1d00386bfdd03fdf607fa42fe5fcb09950 + md5: d6989ead454181f4f9bc987d3dc4e285 + depends: + - anyio + - certifi + - httpcore 1.* + - idna + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/httpx?source=hash-mapping + size: 63082 + timestamp: 1733663449209 +- 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/win-64/icu-78.3-h5112557_2.conda + sha256: 75c549b55b673e15de8785a8e5dd85bca7eb612eee0ff4dc8d7bdaa15eacbdbb + md5: e596942e8ee6ee17fdcf1e6a77757a66 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 16835644 + timestamp: 1784916416303 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.19-pyhcf101f3_0.conda + sha256: 1c35a59c1545ad0fdaddf1fbde7bcfa6ef41a8d68c3a2b0b4a291be00676163e + md5: a39ae05027e9b707742e41b30d296b75 + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/idna?source=compressed-mapping + size: 177433 + timestamp: 1787059857580 +- pypi: https://files.pythonhosted.org/packages/01/f9/575c8d760eae1fc99651b7cc5efd96ad5379ca4d6b53750b0fb4fe983f34/imagesize-2.0.1-py3-none-any.whl + name: imagesize + version: 2.0.1 + sha256: ea0c9a0384df69ed86a943a15cde37d0360b82491b3910dc2215e202e62b5b02 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/31/77/3781f65cafe55480b56914def99022a5d2965a4bb269655c89ef2f1de3cd/importlib-1.0.4.zip + name: importlib + version: 1.0.4 + sha256: b6ee7066fea66e35f8d0acee24d98006de1a0a8a94a8ce6efe73a9a23c8d9826 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.1-pyhcf101f3_0.conda + sha256: 95a074a7d3f58b3494c068d4789c364dcb591c56b70ca6b12f149a540f9aeea4 + md5: 77ec68e0aa61c3fff9ecbf840f93d64e + depends: + - python >=3.10 + - zipp >=3.20 + - python + license: Apache-2.0 + purls: + - pkg:pypi/importlib-metadata?source=compressed-mapping + size: 34920 + timestamp: 1787943971257 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.3.0-pyh6dadd2b_0.conda + sha256: e3ff0b3d5db5c31830030406f50ac2c9a5c31b86f1c2cef87a6042f0a4c77eb7 + md5: dd5c51d5c42381ba4a2e0ce32e02ba17 + depends: + - __win + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.9.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio2 >=1.7.0 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipykernel?source=hash-mapping + size: 138046 + timestamp: 1781101760172 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.17.0-pyhe2676ad_0.conda + sha256: de5052db34cd414d5993dc7330c7f9ce422fadd6e5f3c1422d48040e0319c633 + md5: c2cf78253e434f1283cfd276ec9abd2f + depends: + - __win + - ipython_pygments_lexers >=1.0.0 + - jedi >=0.18.2 + - matplotlib-inline >=0.1.6 + - prompt-toolkit >=3.0.41,<3.1.0 + - psutil >=7 + - pygments >=2.14.0 + - python >=3.11 + - stack_data >=0.6.0 + - traitlets >=5.13.0 + - typing_extensions >=4.6 + - colorama >=0.4.4 + - python + license: BSD-3-Clause + purls: + - pkg:pypi/ipython?source=compressed-mapping + size: 729408 + timestamp: 1787921907454 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + sha256: 894682a42a7d659ae12878dbcb274516a7031bbea9104e92f8e88c1f2765a104 + md5: bd80ba060603cc228d9d81c257093119 + depends: + - pygments + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipython-pygments-lexers?source=hash-mapping + size: 13993 + timestamp: 1737123723464 +- conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + sha256: 08e838d29c134a7684bca0468401d26840f41c92267c4126d7b43a6b533b0aed + md5: 0b0154421989637d424ccf0f104be51a + depends: + - arrow >=0.15.0 + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/isoduration?source=hash-mapping + size: 19832 + timestamp: 1733493720346 +- conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.20.0-pyhcf101f3_0.conda + sha256: 744143551c1c7b528b82533fb641b9d7db20b2203abc4c2635c387fa6c089fc3 + md5: c2b3d37aa1411031126036ee76a8a861 + depends: + - python >=3.10 + - parso >=0.8.6,<0.9.0 + - python + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/jedi?source=hash-mapping + size: 2715215 + timestamp: 1782251948616 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b + md5: 04558c96691bed63104678757beb4f8d + depends: + - markupsafe >=2.0 + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jinja2?source=hash-mapping + size: 120685 + timestamp: 1764517220861 +- conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.15.0-pyhd8ed1ab_0.conda + sha256: 637400a4174880463985c7a5b6e3e0bea0aa9d0892a6c06a3a8aa2cf1208c35a + md5: 761a4a6b9cba303c66a97ca642447171 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/json5?source=hash-mapping + size: 39373 + timestamp: 1781926894833 +- 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=hash-mapping + size: 14190 + timestamp: 1774311356147 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_1.conda + sha256: 328756a4555941d57af4a5f553e5d8598e9f3b37db028f557e30f9f0b3086db6 + md5: 204b5ca91eba7738790ecc333facbbbe + depends: + - attrs >=22.2.0 + - jsonschema-specifications >=2023.3.6 + - python >=3.10 + - referencing >=0.28.4 + - rpds-py >=0.25.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/jsonschema?source=compressed-mapping + size: 82084 + timestamp: 1787579299493 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 + md5: 439cd0f567d697b20a8f45cb70a1005a + depends: + - python >=3.10 + - referencing >=0.31.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/jsonschema-specifications?source=hash-mapping + size: 19236 + timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_1.conda + sha256: 1b8ed25276ceae973e21d269fbe11f08d0b5f73c7ac9584e2d6a9dd763b8707a + md5: ae36c895b9e25a127d2acbdbaa87e301 + depends: + - jsonschema >=4.26.0,<4.26.1.0a0 + - fqdn + - idna + - isoduration + - jsonpointer >1.13 + - rfc3339-validator + - rfc3986-validator >0.1.0 + - rfc3987-syntax >=1.1.0 + - uri-template + - webcolors >=24.6.0 + license: MIT + license_family: MIT + purls: [] + size: 4809 + timestamp: 1787579299493 +- pypi: https://files.pythonhosted.org/packages/37/86/d45756beaeb4b9b06125599b429451f8640b5db6f019d606f33c85743fd4/jupyter_book-1.0.4.post1-py3-none-any.whl + name: jupyter-book + version: 1.0.4.post1 + sha256: 3a27a6b2581f1894ffe8f347d1a3432f06fc616997547919c42cd41c54db625d + requires_dist: + - click>=7.1,<9 + - jinja2 + - jsonschema<5 + - linkify-it-py>=2,<3 + - myst-nb~=1.0 + - myst-parser~=3.0 + - pyyaml + - sphinx-book-theme~=1.1 + - sphinx-comments~=0.0 + - sphinx-copybutton~=0.5 + - sphinx-design~=0.6 + - sphinx-external-toc~=1.0 + - sphinx-jupyterbook-latex~=1.0 + - sphinx-multitoc-numbering~=0.1 + - sphinx-thebe~=0.3 + - sphinx-togglebutton~=0.3 + - sphinxcontrib-bibtex~=2.5 + - sphinx~=7.0 + - pre-commit~=3.1 ; extra == 'code-style' + - playwright ; extra == 'pdfhtml' + - altair ; extra == 'sphinx' + - bokeh ; extra == 'sphinx' + - folium ; extra == 'sphinx' + - ipywidgets ; extra == 'sphinx' + - jupytext ; extra == 'sphinx' + - matplotlib ; extra == 'sphinx' + - nbclient ; extra == 'sphinx' + - numpy>=2 ; extra == 'sphinx' + - pandas ; extra == 'sphinx' + - plotly ; extra == 'sphinx' + - sphinx-click ; extra == 'sphinx' + - sphinx-examples ; extra == 'sphinx' + - sphinx-inline-tabs ; extra == 'sphinx' + - sphinx-proof ; extra == 'sphinx' + - sphinxext-rediraffe~=0.2.3 ; extra == 'sphinx' + - sympy ; extra == 'sphinx' + - altair ; extra == 'testing' + - beautifulsoup4 ; extra == 'testing' + - cookiecutter ; extra == 'testing' + - coverage ; extra == 'testing' + - jupytext ; extra == 'testing' + - matplotlib ; extra == 'testing' + - numpy>=2 ; extra == 'testing' + - pandas ; extra == 'testing' + - playwright ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest-timeout ; extra == 'testing' + - pytest-xdist ; extra == 'testing' + - pytest>=6.2.4 ; extra == 'testing' + - sphinx-click ; extra == 'testing' + - sphinx-inline-tabs ; extra == 'testing' + - texsoup ; extra == 'testing' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-builder-1.2.2-pyhcf101f3_0.conda + sha256: 46777dd25ae623f960ec9ed9eae44cc7f96f371f3bc96f85d3ebf95737bd4e88 + md5: 9672806e67ea8b09a61408597a418e20 + depends: + - jupyter_core + - python >=3.10 + - tomli + - traitlets + - python + constrains: + - nodejs >=22 + license: BSD-3-Clause AND MIT AND ISC + purls: + - pkg:pypi/jupyter-builder?source=compressed-mapping + size: 862197 + timestamp: 1786385602872 +- pypi: https://files.pythonhosted.org/packages/64/6b/67b87da9d36bff9df7d0efbd1a325fa372a43be7158effaf43ed7b22341d/jupyter_cache-1.0.1-py3-none-any.whl + name: jupyter-cache + version: 1.0.1 + sha256: 9c3cafd825ba7da8b5830485343091143dff903e4d8c69db9349b728b140abf6 + requires_dist: + - attrs + - click + - importlib-metadata + - nbclient>=0.2 + - nbformat + - pyyaml + - sqlalchemy>=1.3.12,<3 + - tabulate + - click-log ; extra == 'cli' + - pre-commit>=2.12 ; extra == 'code-style' + - nbdime ; extra == 'rtd' + - ipykernel ; extra == 'rtd' + - jupytext ; extra == 'rtd' + - myst-nb ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - nbdime ; extra == 'testing' + - coverage ; extra == 'testing' + - ipykernel ; extra == 'testing' + - jupytext ; extra == 'testing' + - matplotlib ; extra == 'testing' + - nbformat>=5.1 ; extra == 'testing' + - numpy ; extra == 'testing' + - pandas ; extra == 'testing' + - pytest>=6 ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - sympy ; extra == 'testing' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + sha256: 3766e2ae59641c172cec8a821528bfa6bf9543ffaaeb8b358bfd5259dcf18e4e + md5: 0c3b465ceee138b9c39279cc02e5c4a0 + depends: + - importlib-metadata >=4.8.3 + - jupyter_server >=1.1.2 + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-lsp?source=hash-mapping + size: 61633 + timestamp: 1775136333147 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.10.0-pyhcf101f3_0.conda + sha256: 94f11bbdbac51a68415fb0a8bb441fb3475c0138e778664a3fb48f5698688ebf + md5: 85130259a26c023f53108dc9ab1cfb44 + depends: + - jupyter_core >=5.1 + - python >=3.10 + - python-dateutil >=2.8.2 + - pyzmq >=25.0 + - tornado >=6.4.1 + - traitlets >=5.3 + - typing_extensions >=4.13.0 + - python + license: BSD-3-Clause + purls: + - pkg:pypi/jupyter-client?source=compressed-mapping + size: 118962 + timestamp: 1787929615607 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + sha256: ed709a6c25b731e01563521ef338b93986cd14b5bc17f35e9382000864872ccc + md5: a8db462b01221e9f5135be466faeb3e0 + depends: + - __win + - pywin32 + - platformdirs >=2.5 + - python >=3.10 + - traitlets >=5.3 + - python + constrains: + - pywin32 >=300 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-core?source=hash-mapping + size: 64679 + timestamp: 1760643889625 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + sha256: c7edb5682c6316a95ad781dccb1b6589cd2ec0bf94f23c21152974eb0363b5d7 + md5: bf42ee94c750c0b2e7e998b79ac299ea + depends: + - jsonschema-with-format-nongpl >=4.18.0 + - packaging + - python >=3.10 + - python-json-logger >=2.0.4 + - pyyaml >=5.3 + - referencing + - rfc3339-validator + - rfc3986-validator >=0.1.1 + - traitlets >=5.3 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-events?source=hash-mapping + size: 24002 + timestamp: 1776861872237 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.21.0-pyhcf101f3_0.conda + sha256: fa26acd3777095662c34cbbcfacad163a3a17c90a935f9357fe511c975c8241f + md5: b6163da641d1f178977dd36aebced0d5 + depends: + - anyio >=3.1.0 + - argon2-cffi >=21.1 + - jinja2 >=3.0.3 + - jupyter_client >=7.4.4 + - jupyter_core >=4.12,!=5.0.* + - jupyter_events >=0.11.0 + - jupyter_server_terminals >=0.4.4 + - nbconvert-core >=6.4.4 + - nbformat >=5.3.0 + - overrides >=5.0 + - packaging >=22.0 + - prometheus_client >=0.9 + - python >=3.10 + - pyzmq >=24 + - send2trash >=1.8.2 + - terminado >=0.8.3 + - tornado >=6.2.0 + - traitlets >=5.6.0 + - websocket-client >=1.7 + - python + license: BSD-3-Clause + purls: + - pkg:pypi/jupyter-server?source=compressed-mapping + size: 365818 + timestamp: 1787864637286 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + sha256: 5eda79ed9f53f590031d29346abd183051263227dd9ee667b5ca1133ce297654 + md5: 7b8bace4943e0dc345fc45938826f2b8 + depends: + - python >=3.10 + - terminado >=0.8.3 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-server-terminals?source=hash-mapping + size: 22052 + timestamp: 1768574057200 +- pypi: https://files.pythonhosted.org/packages/f6/54/af203c61a0550c232ed5e859d2c98f3fe80d1248b6ea1c4d4d5621fa08c9/jupyterbook_patches-1.15.0-py3-none-any.whl + name: jupyterbook-patches + version: 1.15.0 + sha256: 87da7e97fa0e1f3e8de87c6dba6c1c69f8a7940aa19faa1aa16c78656ad90107 + requires_dist: + - pyyaml + - sphinx + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.6.3-pyhd8ed1ab_0.conda + sha256: dabfff705b000188a9f67c9af68bb607cdb2e46fd7c6283307a502994c2af46f + md5: e5527f195a1a1925b9207e9d47752480 + depends: + - async-lru >=1.0.0 + - httpx >=0.25.0,<1 + - ipykernel >=6.5.0,!=6.30.0 + - jinja2 >=3.0.3 + - jupyter-builder >=1.0.2 + - jupyter-lsp >=2.0.0 + - jupyter_core + - jupyter_server >=2.19.0,<3 + - jupyterlab_server >=2.28.0,<3 + - notebook-shim >=0.2 + - packaging >=23.2 + - python >=3.10 + - tomli >=1.2.2 + - tornado >=6.2.0 + - traitlets + - typing_extensions >=4.4.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab?source=compressed-mapping + size: 13178193 + timestamp: 1786398793317 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + sha256: dc24b900742fdaf1e077d9a3458fd865711de80bca95fe3c6d46610c532c6ef0 + md5: fd312693df06da3578383232528c468d + depends: + - pygments >=2.4.1,<3 + - python >=3.9 + constrains: + - jupyterlab >=4.0.8,<5.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab-pygments?source=hash-mapping + size: 18711 + timestamp: 1733328194037 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + sha256: 381d2d6a259a3be5f38a69463e0f6c5dcf1844ae113058007b51c3bef13a7cee + md5: a63877cb23de826b1620d3adfccc4014 + depends: + - babel >=2.10 + - jinja2 >=3.0.3 + - json5 >=0.9.0 + - jsonschema >=4.18 + - jupyter_server >=1.21,<3 + - packaging >=21.3 + - python >=3.10 + - requests >=2.31 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab-server?source=hash-mapping + size: 51621 + timestamp: 1761145478692 +- conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.1-py314hf309875_0.conda + sha256: b34910eacb872a9b9b55318fd12332954e64b42dbc710f6a384e0500a58a2d7a + md5: 842f2582140b5567bcad1defbbd9b948 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + purls: + - pkg:pypi/kiwisolver?source=compressed-mapping + size: 73212 + timestamp: 1787938458524 +- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h719d79b_2.conda + sha256: 63ff03324e903eb01a715ccf357df56d66224e61952fd6615d86490ebefb3285 + md5: 93f5a01dec294a2228f757fe2f3432d4 + depends: + - openssl >=3.5.7,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 753425 + timestamp: 1786762169034 +- conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + sha256: 49570840fb15f5df5d4b4464db8ee43a6d643031a2bc70ef52120a52e3809699 + md5: 9b965c999135d43a3d0f7bd7d024e26a + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/lark?source=hash-mapping + size: 94312 + timestamp: 1761596921009 +- pypi: https://files.pythonhosted.org/packages/b5/40/23569737873cc9637fd488606347e9dd92b9fa37ba4fcda1f98ee5219a97/latexcodec-3.0.1-py3-none-any.whl + name: latexcodec + version: 3.0.1 + sha256: a9eb8200bff693f0437a69581f7579eb6bca25c4193515c09900ce76451e452e + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19.1-hf2c6c5f_1.conda + sha256: 5ed63a32639a130564a870becb679fd52dfb816666a61ed3c023917389010480 + md5: 1df4012c8a2478699d07bc26af66d41e + depends: + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 523194 + timestamp: 1780211799997 +- conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.2.0-hd936e49_0.conda + sha256: 93d666f63f284ef77b87b0b1f77b70f7d36d315a132f9afa64bc0012d937ba39 + md5: add59e2b60ac9d4299d17c938185c75a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 175297 + timestamp: 1785036247761 +- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-9_h8455456_mkl.conda + build_number: 9 + sha256: a99c640f10a3f77efe5c6605676ddc8d365d020eec4fdf1c803d34bdaf49b357 + md5: 17b26a4ad064259983bec1eaa36f40d3 + depends: + - mkl >=2026.1.0,<2027.0a0 + constrains: + - blas 2.309 mkl + - libcblas 3.11.0 9*_mkl + - liblapack 3.11.0 9*_mkl + - liblapacke 3.11.0 9*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 67235 + timestamp: 1786059219098 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hf02afa3_3.conda + sha256: c739589318a1f8a88cd1b66d385176fd1ec2c4609e9f90d23d748be94b547e4e + md5: 8ef4beb3cb18e1a876b9af9a757cc1a5 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 82655 + timestamp: 1786622832371 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-h84f9c24_3.conda + sha256: f4bdb7ec97c3122e531fc867efae5ec928b649d047aa70d42893f0d8eb110fd9 + md5: 10c479888ee4e960587967b2d0c8143a + depends: + - libbrotlicommon 1.2.0 hf02afa3_3 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 34788 + timestamp: 1786622843818 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-he2a975b_3.conda + sha256: c5e638ea9704c94b316238b425a3439ba38d4d8fba81682842e6d7d464472848 + md5: cb5d08dc81f52e87c27914b5636cd995 + depends: + - libbrotlicommon 1.2.0 hf02afa3_3 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 253894 + timestamp: 1786622854214 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-9_h2a3cdd5_mkl.conda + build_number: 9 + sha256: 8c20714bbb85c8a109e9002e76c32be64a82d9867beb1a35a20c85258cc2b535 + md5: 9d1d0c22e9ed8c31ec2efc0d063d6f48 + depends: + - libblas 3.11.0 9_h8455456_mkl + constrains: + - blas 2.309 mkl + - liblapack 3.11.0 9*_mkl + - liblapacke 3.11.0 9*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 67587 + timestamp: 1786059232952 +- conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-23.1.0-default_hacd6ee9_0.conda + sha256: f81e6a24e7eb670cf216c44028f789426b732ce68731b349cae98dec3a59f573 + md5: 88280be6f61caad069624d936b719641 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - llvm-openmp >=23.1.0 + - libxml2 + - libxml2-16 >=2.15.3 + - libzlib >=1.3.2,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + purls: [] + size: 37510825 + timestamp: 1787735065635 +- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h1a1d4e4_1.conda + sha256: af1cda21d4653f594fbef20aa4e1ff158a546902b3307ef8af9a9b44b43862d2 + md5: e4e122e124676a49eebf241399ad8393 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 157828 + timestamp: 1785908793271 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda + sha256: 1a54d874addda73b6f7164d5f3905821277a1831bcc05edd74b3085391688571 + md5: ccc490c81ffe14181861beac0e8f3169 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + purls: [] + size: 71631 + timestamp: 1781203724164 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda + sha256: 613e8077c5cca5df7fe84ade7d5050301bee3c6c4c450ffe61d34a349ab4f11c + md5: ceb38b0ba900847d8da4289c3c8e5708 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 49992 + timestamp: 1787753517346 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_2.conda + sha256: d794d7fddb6eea50e18a62fa27ab3819f40d51bad00b90cf4ca591fb0d4006c2 + md5: 740f99c3c91079c03874b809fedace1b + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + size: 8742 + timestamp: 1786641045882 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_2.conda + sha256: cbc650854003e434d4ff6c7b1a2667e38a4242ad8a391a1c5ff89721624065ce + md5: 8157483eb7ed3fcba71aad3b50a97131 + depends: + - libpng >=1.6.58,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + size: 340385 + timestamp: 1786641044865 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-16.2.0-h110b43a_4.conda + sha256: 32c0d1adcc96835d5f681c7e72b7f5e2e30088149239e002b8a6f581a072e1d2 + md5: 02793cf48b68687fee158a48c92850a6 + depends: + - _openmp_mutex >=4.5 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - libgcc-ng ==16.2.0=*_4 + - libgomp 16.2.0 h8ee18e1_4 + - msys2-conda-epoch <0.0a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 826694 + timestamp: 1787625780171 +- conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.3-he810d59_2.conda + sha256: 001620bac27dbf6daa25e5cd52970749fe2bc02a26649b0ad516d26609f6bcae + md5: e40bcfee79dbfda3eff751ed098b6ad3 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - pcre2 >=10.47,<10.48.0a0 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - libffi >=3.7.0,<3.8.0a0 + - libintl >=0.22.5,<1.0a0 + constrains: + - glib >2.66 + license: LGPL-2.1-or-later + purls: [] + size: 4519014 + timestamp: 1787884093942 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-16.2.0-h8ee18e1_4.conda + sha256: 9ef1a22fb50b31fbf9c01cf709e8f55b60fd3c02401d150be4a55943f9e3832f + md5: 91189f0bc9ff21f385fcda6232346612 + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - msys2-conda-epoch <0.0a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 688168 + timestamp: 1787625720312 +- conda: https://conda.anaconda.org/conda-forge/win-64/libharfbuzz-14.4.0-h03b5201_0.conda + sha256: 08713208fd7e2e6f2ccde1fc09765f2585d5cc809d187865fd9190ddad271f3d + md5: 4618efa4303fdda115da50b8090d73c6 + depends: + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.15,<2.0a0 + - icu >=78.3,<79.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libglib >=2.88.3,<3.0a0 + - libpng >=1.6.58,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 1053822 + timestamp: 1787795353946 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.13.0-default_h049141e_1000.conda + sha256: 2ee12e37223dfcd0acd050c80a91150c482b6e2899198521e1800dce66662467 + md5: 6a01c986e30292c715038d2788aa1385 + 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: 2396128 + timestamp: 1770954127918 +- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_3.conda + sha256: 35e04e3ddac7720fc7c550a1c9f998604299d6a7bd1f3ec9b2825d825061daa2 + md5: a8a2abdf0f901bc4779d9b7be0845921 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-only + purls: [] + size: 694899 + timestamp: 1787033851701 +- conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_4.conda + sha256: 85b50be2209f3b8a873830ec9894477d260f4c7ba9540e65959f5812bf7219f8 + md5: 36d6e0045173974521fabd42bd5033d6 + depends: + - libiconv >=1.18,<2.0a0 + license: LGPL-2.1-or-later + purls: [] + size: 96669 + timestamp: 1787841116808 +- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.2.0-hfd05255_1.conda + sha256: df78ab4c0eecb3dd9331898f96baeed8e5ca1c363346332517abeb0b614b9a53 + md5: fc2c23bacefd1e733f1e1d6cd3b2aaeb + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + purls: [] + size: 990125 + timestamp: 1785896494014 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-9_hf9ab0e9_mkl.conda + build_number: 9 + sha256: 62d0a7a70ee13c554d5d7ff94a2ba758c4111439822dcc81324dd4cfaf576071 + md5: bee6f13ab945c4034bdd0f722ad14dd5 + depends: + - libblas 3.11.0 9_h8455456_mkl + constrains: + - blas 2.309 mkl + - libcblas 3.11.0 9*_mkl + - liblapacke 3.11.0 9*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 79963 + timestamp: 1786059243440 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda + sha256: d36c4a1e1f80fd08e18a407e03622ff2f34dfdd022da6488ad19603dea19e6d5 + md5: 880a0c8549479b198af21ba5dc49b109 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 105809 + timestamp: 1786348717883 +- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda + sha256: f07e451de3db1836b87f7aedf95c8e65cdb06c0e6105329ba24bb5f7b5c75e2a + md5: 5ae92fd6614edd024576e14069d7ad4c + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 89109 + timestamp: 1786650384519 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-hdc8cecf_1.conda + sha256: 8c49c32adf3ba2c59783630b82377f54ab72204ea99e2bafc90a47a8e25c1032 + md5: 5aa7348e73691187c81d51616f17e48a + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + purls: [] + size: 385462 + timestamp: 1786616543374 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpython-3.14.7-h4f90d01_101_cp314.conda + build_number: 101 + sha256: 9c9056d4eaf2dee22584e9565248bc07e2e8177e0dd36263d4e21c3a17033fe9 + md5: cfc9859a0f5b5a45bc6abbed2560bdfc + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Python-2.0 + purls: [] + size: 51243 + timestamp: 1787780843281 +- conda: https://conda.anaconda.org/conda-forge/win-64/libraqm-0.11.0-h50d6d30_0.conda + sha256: 1bc52f781355e233411a7aaebbb155d9fd53efa2a1fc6c621250833d80cc5ab1 + md5: df92be5685f712989830bdb7ee39383a + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libharfbuzz >=14.2.1 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - fribidi >=1.0.16,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 33471 + timestamp: 1784850324004 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.22-h6a83c73_2.conda + sha256: 7dc8d243cc8bcd12d1666640664288822eda5d30411a0b22ff05090bbac4c32b + md5: 2a001157df8205a7785ea69dd3270a8f + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: ISC + purls: [] + size: 280204 + timestamp: 1787225747847 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda + sha256: 0a45d7c0f20146fff787a106f8fa187872e309c70975ff8f0936e188914c26ad + md5: a72d495965b144bb7da033642d389047 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + purls: [] + size: 1314919 + timestamp: 1787051140039 +- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.2-h8f73337_1.conda + sha256: 3575a092e3e52625a1767804a4ebd321becaadf61b63dcd6735ebb88c0b3c359 + md5: 970dbe48f843e7fbd179a9b6c22f865a + depends: + - lerc >=4.2.0,<5.0a0 + - libdeflate >=1.25,<1.26.0a0 + - libjpeg-turbo >=3.2.0,<4.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + purls: [] + size: 1014211 + timestamp: 1787755773611 +- conda: https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.357.0-h477610d_2.conda + sha256: 4b094443126c5fc38d200eb0ea335b67e64d966d7aa737bb3141217a787b0c73 + md5: aaeed7feddbfd7454f8853a5eae8d902 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + constrains: + - libvulkan-headers 1.4.357.0.* + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 288787 + timestamp: 1787491929908 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_1.conda + sha256: 4470d98d3178b0d45492eed4808afe421d2e7808352b8d06c2dc29166b75d94d + md5: 35a9475e4cc999d52921f57c181979fc + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 278886 + timestamp: 1785954716703 +- 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/win-64/libxcb-1.17.0-h874e120_2.conda + sha256: f5932cbcadb67bef9374ee864fed72411af29e88690435c6c7fc5633c89dabee + md5: 3658b0201b32da9607ea5e3c1c463c1f + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - pthread-stubs + - ucrt >=10.0.20348.0 + - xorg-libxau >=1.0.12,<2.0a0 + - xorg-libxdmcp >=1.1.5,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 1215534 + timestamp: 1787886015478 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_1.conda + sha256: a83e9adcf7c50f20289dc6890707c8e4e84151b4204b0f7344998138807458d1 + md5: 45a5a1c709a69f14cf176220788d18a9 + depends: + - icu >=78.3,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libxml2-16 2.15.3 h3cfd58e_1 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 43610 + timestamp: 1787237661577 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_1.conda + sha256: 8163de24a7ddb4ebf9587c3a45ba950caf3690b9646b76f007ca15e6e52b5881 + md5: 6e7dadff3f3bde2d29d29a3ec34f2d58 + depends: + - icu >=78.3,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libxml2 2.15.3 + license: MIT + license_family: MIT + purls: [] + size: 519962 + timestamp: 1787237653321 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda + sha256: 13da38939c2c20e7112d683ab6c9f304bfaf06230a2c6a7cf00359da1a003ec7 + md5: 46034d9d983edc21e84c0b36f1b4ba61 + depends: + - libxml2 + - libxml2-16 >=2.14.6 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 420223 + timestamp: 1757963935611 +- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda + sha256: 0629c2cc0404d3bb29d6baa7b4ba62da80797015e86de050db81ea5a07050527 + md5: 5d2ff29d465097458cc3ff6569151991 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - zlib 1.3.2 *_3 + license: Zlib + license_family: Other + purls: [] + size: 58529 + timestamp: 1785276664143 +- pypi: https://files.pythonhosted.org/packages/eb/3d/e34b19cd144071c583317268c4feb2c59c03ac57eef69753410c7abb11c0/linkify_it_py-2.1.1-py3-none-any.whl + name: linkify-it-py + version: 2.1.1 + sha256: 8539a6b470efce90ba9b69e39b848e5b15b7ad89f7f98ca17d3532c243f987dc + requires_dist: + - uc-micro-py + - pytest ; extra == 'test' + - coverage ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pre-commit ; extra == 'dev' + - isort ; extra == 'dev' + - flake8 ; extra == 'dev' + - black ; extra == 'dev' + - pyproject-flake8 ; extra == 'dev' + - pytest ; extra == 'benchmark' + - pytest-benchmark ; extra == 'benchmark' + - sphinx ; extra == 'doc' + - sphinx-book-theme ; extra == 'doc' + - myst-parser ; extra == 'doc' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-23.1.0-h49e36cd_0.conda + sha256: f9658ec83a6744f38e2b8188c76e1c2dea2614f5aa0e14d9d274b19f60646b8c + md5: 79055ec79e1b43749763122cead30976 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - intel-openmp <0.0a0 + - openmp 23.1.0|23.1.0.* + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + purls: [] + size: 342468 + timestamp: 1787722783678 +- pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl + name: markdown-it-py + version: 3.0.0 + sha256: 355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 + requires_dist: + - mdurl~=0.1 + - psutil ; extra == 'benchmarking' + - pytest ; extra == 'benchmarking' + - pytest-benchmark ; extra == 'benchmarking' + - pre-commit~=3.0 ; extra == 'code-style' + - commonmark~=0.9 ; extra == 'compare' + - markdown~=3.4 ; extra == 'compare' + - mistletoe~=1.0 ; extra == 'compare' + - mistune~=2.0 ; extra == 'compare' + - panflute~=2.3 ; extra == 'compare' + - linkify-it-py>=1,<3 ; extra == 'linkify' + - mdit-py-plugins ; extra == 'plugins' + - gprof2dot ; extra == 'profiling' + - mdit-py-plugins ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - pyyaml ; extra == 'rtd' + - sphinx ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - jupyter-sphinx ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py314h2359020_1.conda + sha256: 02805a0f3cd168dbf13afc5e4aed75cc00fe538ce143527a6471485b36f5887c + md5: 8de7b40f8b30a8fcaa423c2537fe4199 + 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: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 30022 + timestamp: 1772445159549 +- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.11.1-py314h30c6bc1_2.conda + sha256: 3599b3ae70c4fd210e83d3e04920b70e763a3c3cc6a589f7a46776a339cf79c0 + md5: d8f7f4bb221698dda04dd955eb6f7e52 + depends: + - matplotlib-base >=3.11.1,<3.11.2.0a0 + - pyside6 >=6.7.2 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + - tornado >=5 + license: PSF-2.0 + license_family: PSF + purls: [] + size: 15333 + timestamp: 1785211311397 +- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.11.1-py314h2061cd4_2.conda + sha256: b3f19b71ea556c79b67a599929a4c05618fd4ae03d7412e65adc95ec627670c5 + md5: 88c095cee1bcd48178328c93920870a2 + depends: + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.28.2 + - freetype + - kiwisolver >=1.3.1 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libraqm >=0.11.0,<0.12.0a0 + - numpy >=1.25 + - numpy >=1.25,<3 + - packaging >=20.0 + - pillow >=9 + - pyparsing >=3 + - python >=3.14,<3.15.0a0 + - python-dateutil >=2.7 + - python_abi 3.14.* *_cp314 + - qhull >=2020.2,<2020.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/matplotlib?source=hash-mapping + size: 8810362 + timestamp: 1785211292854 +- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.2-pyhd8ed1ab_0.conda + sha256: 35b43d7343f74452307fd018a1cca92b8f68961ff8e2ab6a81ce0a703c9a3764 + md5: 9acc1c385be401d533ff70ef5b50dae6 + depends: + - python >=3.10 + - traitlets + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/matplotlib-inline?source=hash-mapping + size: 15725 + timestamp: 1778264403247 +- pypi: https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-py3-none-any.whl + name: mdit-py-plugins + version: 0.6.1 + sha256: 214c82fb2ac524472ab6a5bcab1de80f73b50443e187f401bfd77efbc7c6481d + requires_dist: + - markdown-it-py>=2.0.0,<5.0.0 + - pre-commit ; extra == 'code-style' + - myst-parser ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest-timeout ; 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/noarch/mistune-3.3.4-pyhcf101f3_0.conda + sha256: 306af633cb4ac85d04024d7c243ac2031c488bf5b0912207e7304c27a5d65a85 + md5: 1c0ebec41ef9214160da1ee6a0880fce + depends: + - python >=3.10 + - typing_extensions + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/mistune?source=hash-mapping + size: 93811 + timestamp: 1784722859728 +- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2026.1.0-hac47afa_235.conda + sha256: bb8abe071f73765446df62924031e6599577e8ac9003264dc4569e78c0fea16d + md5: ace316c48c178d7faa403dee51e30c7b + depends: + - llvm-openmp >=22.1.8 + - tbb >=2023.0.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LicenseRef-IntelSimplifiedSoftwareOct2022 + license_family: Proprietary + purls: [] + size: 114686732 + timestamp: 1787725739779 +- conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda + sha256: d09c47c2cf456de5c09fa66d2c3c5035aa1fa228a1983a433c47b876aa16ce90 + md5: 37293a85a0f4f77bbd9cf7aaefc62609 + depends: + - python >=3.9 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/munkres?source=hash-mapping + size: 15851 + timestamp: 1749895533014 +- pypi: https://files.pythonhosted.org/packages/94/93/0a378b48488879a1d925b42a804edfc6e0cd0ef854220f2dce738a46e7e9/myst_nb-1.4.0-py3-none-any.whl + name: myst-nb + version: 1.4.0 + sha256: 0e2c86e7d3b82c3aa51383f82d6268f7714f3b772c23a796ab09538a8e68b4e4 + requires_dist: + - importlib-metadata + - ipython + - jupyter-cache>=0.5 + - nbclient + - myst-parser>=1.0.0 + - nbformat>=5.0 + - pyyaml + - sphinx>=5 + - typing-extensions + - ipykernel + - pre-commit ; extra == 'code-style' + - alabaster ; extra == 'rtd' + - altair ; extra == 'rtd' + - bokeh ; extra == 'rtd' + - coconut>=1.4.3 ; extra == 'rtd' + - ipykernel>=5.5 ; extra == 'rtd' + - ipywidgets ; extra == 'rtd' + - jupytext>=1.11.2 ; extra == 'rtd' + - matplotlib ; extra == 'rtd' + - numpy ; extra == 'rtd' + - pandas ; extra == 'rtd' + - plotly ; extra == 'rtd' + - sphinx-book-theme>=0.3 ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinxcontrib-bibtex ; extra == 'rtd' + - sympy ; extra == 'rtd' + - sphinx-autodoc-typehints ; extra == 'rtd' + - coverage>=6.4 ; extra == 'testing' + - beautifulsoup4 ; extra == 'testing' + - ipykernel>=5.5 ; extra == 'testing' + - ipython!=8.1.0 ; extra == 'testing' + - ipywidgets>=8 ; extra == 'testing' + - jupytext>=1.11.2 ; extra == 'testing' + - matplotlib==3.10.7 ; extra == 'testing' + - nbdime ; extra == 'testing' + - numpy ; extra == 'testing' + - pandas ; extra == 'testing' + - pyarrow ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov>=3 ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest-param-files ; extra == 'testing' + - sympy>=1.10.1 ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl + name: myst-parser + version: 3.0.1 + sha256: 6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1 + requires_dist: + - docutils>=0.18,<0.22 + - jinja2 + - markdown-it-py~=3.0 + - mdit-py-plugins~=0.4 + - pyyaml + - sphinx>=6,<8 + - pre-commit~=3.0 ; extra == 'code-style' + - linkify-it-py~=2.0 ; extra == 'linkify' + - sphinx>=7 ; extra == 'rtd' + - ipython ; extra == 'rtd' + - sphinx-book-theme~=1.1 ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinxext-rediraffe~=0.2.7 ; extra == 'rtd' + - sphinxext-opengraph~=0.9.0 ; extra == 'rtd' + - sphinx-pyscript ; extra == 'rtd' + - sphinx-tippy>=0.4.3 ; extra == 'rtd' + - sphinx-autodoc2~=0.5.0 ; extra == 'rtd' + - sphinx-togglebutton ; extra == 'rtd' + - beautifulsoup4 ; extra == 'testing' + - coverage[toml] ; extra == 'testing' + - defusedxml ; extra == 'testing' + - pytest>=8,<9 ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest-param-files~=0.6.0 ; extra == 'testing' + - sphinx-pytest ; extra == 'testing' + - pygments ; extra == 'testing-docutils' + - pytest>=8,<9 ; extra == 'testing-docutils' + - pytest-param-files~=0.6.0 ; extra == 'testing-docutils' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.11.0-pyhd8ed1ab_0.conda + sha256: eceb424236fbbb9b337a857fe5448307b57a2a3fb2db389ae37e7a8b8cdca2ab + md5: cf01a81d7960ad9c829bf2e794fcee9a + depends: + - jupyter_client >=7.0.0 + - jupyter_core >=5.4 + - nbformat >=5.2.0 + - python >=3.10 + - traitlets >=5.13 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbclient?source=hash-mapping + size: 29138 + timestamp: 1780661039538 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + sha256: ab2ac79c5892c5434d50b3542d96645bdaa06d025b6e03734be29200de248ac2 + md5: 2bce0d047658a91b99441390b9b27045 + depends: + - beautifulsoup4 + - bleach-with-css !=5.0.0 + - defusedxml + - importlib-metadata >=3.6 + - jinja2 >=3.0 + - jupyter_core >=4.7 + - jupyterlab_pygments + - markupsafe >=2.0 + - mistune >=2.0.3,<4 + - nbclient >=0.5.0 + - nbformat >=5.7 + - packaging + - pandocfilters >=1.4.1 + - pygments >=2.4.1 + - python >=3.10 + - traitlets >=5.1 + - python + constrains: + - pandoc >=2.9.2,<4.0.0 + - nbconvert ==7.17.1 *_0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbconvert?source=hash-mapping + size: 202229 + timestamp: 1775615493260 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.11.1-pyhcf101f3_0.conda + sha256: d85d76827ff732e1639f50f45e4d7d3387a27abd857b194dcbb5bb4166c2a7c2 + md5: 2fbbf92e1173ae024f0b12759c1e64a1 + depends: + - jsonschema >=2.6 + - jupyter_core >=4.12,!=5.0.* + - python >=3.10 + - python-fastjsonschema >=2.15 + - traitlets >=5.1 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbformat?source=compressed-mapping + size: 107750 + timestamp: 1787133512599 +- conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio2-1.7.2-pyhcf101f3_0.conda + sha256: e6768ceef038f4d7e083de7e393f5dd7d672b937e2bda570b740f6399b686689 + md5: fcd832bfd4749e9b246112b6894f97fc + depends: + - python >=3.10 + - python + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/nest-asyncio2?source=hash-mapping + size: 15903 + timestamp: 1770973502283 +- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + sha256: 7b920e46b9f7a2d2aa6434222e5c8d739021dbc5cc75f32d124a8191d86f9056 + md5: e7f89ea5f7ea9401642758ff50a2d9c1 + depends: + - jupyter_server >=1.8,<3 + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/notebook-shim?source=hash-mapping + size: 16817 + timestamp: 1733408419340 +- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.5.2-py314h02f10f6_0.conda + sha256: 14067f2c7628320708f73531c98c16753ee3991230c6ae32873baed911771b09 + md5: bd342de8875a168535a553191b405821 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libcblas >=3.9.0,<4.0a0 + - libblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - python_abi 3.14.* *_cp314 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=hash-mapping + size: 7462504 + timestamp: 1786330617237 +- conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda + sha256: 24342dee891a49a9ba92e2018ec0bde56cc07fdaec95275f7a55b96f03ea4252 + md5: e723ab7cc2794c954e1b22fde51c16e4 + depends: + - libpng >=1.6.55,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 245594 + timestamp: 1772624841727 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda + sha256: 9dddb559ba49744d5d94092d8d13cb0567f5c3b3f439f3acf28433d1f4256acc + md5: 73cb1783f47c452be4c309430fbef89f + 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: 9474879 + timestamp: 1787699876495 +- conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + sha256: 1840bd90d25d4930d60f57b4f38d4e0ae3f5b8db2819638709c36098c6ba770c + md5: e51f1e4089cad105b6cac64bd8166587 + depends: + - python >=3.9 + - typing_utils + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/overrides?source=hash-mapping + size: 30139 + timestamp: 1734587755455 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + sha256: c432626b16768b8dab228bfb706f7060c2d462a21c516d240f68f2f902b5a044 + md5: 936687ed80f295a1f5dbcf8bd34c252c + depends: + - python >=3.9 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/packaging?source=hash-mapping + size: 116363 + timestamp: 1785888127370 +- conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f + md5: 457c2c8c08e54905d6954e79cb5b5db9 + depends: + - python !=3.0,!=3.1,!=3.2,!=3.3 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandocfilters?source=hash-mapping + size: 11627 + timestamp: 1631603397334 +- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + sha256: 611882f7944b467281c46644ffde6c5145d1a7730388bcde26e7e86819b0998e + md5: 39894c952938276405a1bd30e4ce2caf + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/parso?source=hash-mapping + size: 82472 + timestamp: 1777722955579 +- conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-h8466c1e_1.conda + sha256: d8e9ea26b52a09d880d1e5371830c8dd5b4c099a6db64dbdf8236440744b7499 + md5: 009af999dbe2d1db36a37187a4ca4eb4 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 993241 + timestamp: 1787294653206 +- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-12.3.0-py314h61b30b5_0.conda + sha256: c9dc3212ed0021974541072ee3765a5097a0721191c34ee485d7d7e94449648f + md5: 09b8e6ac8f4a257b59e5d3025f3c9c1d + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.14.* *_cp314 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libwebp-base >=1.6.0,<2.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - openjpeg >=2.5.4,<3.0a0 + - lcms2 >=2.19.1,<3.0a0 + - libxcb >=1.17.0,<2.0a0 + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - tk >=8.6.13,<8.7.0a0 + - zlib-ng >=2.3.3,<2.4.0a0 + license: HPND + purls: + - pkg:pypi/pillow?source=hash-mapping + size: 989058 + timestamp: 1782912129930 +- conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_3.conda + sha256: cad8b94c2b00264a15d469eed6dc53aac1c59c6d46f27ad1d91bfaf227cf136a + md5: 27c5be39d9e4d25fe85b89a069360d1e + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 257473 + timestamp: 1786106677325 +- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.11.5-pyhcf101f3_0.conda + sha256: 4496a7e0b584a388b3580ab594a4f384696ab7d702282588fd33a7ee38af983c + md5: 152ec36401f710145a7db03475594410 + depends: + - python >=3.10 + - python + license: MIT + purls: + - pkg:pypi/platformdirs?source=compressed-mapping + size: 27461 + timestamp: 1787881635603 +- conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.26.0-pyhd8ed1ab_0.conda + sha256: 794eec057361b41db1b06a9677eb8632adc0de81f7dcfe113bca8f0b04a23553 + md5: 3aa7e2d85645e61627c98082747dfdfe + depends: + - python >=3.10 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/prometheus-client?source=hash-mapping + size: 61554 + timestamp: 1785016068982 +- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.53-pyha770c72_0.conda + sha256: efe8def2c93aa34cd8d3c9af1dc4c7d312791cf769d8b2b615e32733e6df6051 + md5: 39c92a39517316e5001d645ae63d9ab9 + depends: + - python >=3.10 + - wcwidth + constrains: + - prompt_toolkit 3.0.53 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/prompt-toolkit?source=hash-mapping + size: 276081 + timestamp: 1785160613307 +- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py314hc5dbbe4_1.conda + sha256: c975e08da7627e95d1f0b70ef9787e9153118e67bb5b31f5530c5c3827d9afe8 + md5: deeef9494cfffa58f5fd20bc6eb57664 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 249966 + timestamp: 1787417377436 +- conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-hba3369d_1003.conda + sha256: 5546927a2e337d2903d6cdb028fb33723cdbcc45bf9abe1770fbde2c4ea8bce6 + md5: bc97d497656c9c661ffd3043aca90aa4 + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 10120 + timestamp: 1786067833280 +- conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + sha256: 71bd24600d14bb171a6321d523486f6a06f855e75e547fa0cb2a0953b02047f0 + md5: 3bfdfb8dbcdc4af1ae3f9a8eb3948f04 + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pure-eval?source=hash-mapping + size: 16668 + timestamp: 1733569518868 +- pypi: https://files.pythonhosted.org/packages/44/f6/775eb92e865b28cdb4ad1f2bed7a5446197516f76b58a950faa3be3fd08d/pybtex-0.26.1-py3-none-any.whl + name: pybtex + version: 0.26.1 + sha256: e26c0412cc54f5f21b2a6d9d175762a2d2af9ccf3a8f651cdb89ec035db77aa1 + requires_dist: + - importlib-metadata ; python_full_version < '3.10' + - latexcodec>=1.0.4 + - pyyaml>=3.1 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/11/b1/ce1f4596211efb5410e178a803f08e59b20bedb66837dcf41e21c54f9ec1/pybtex_docutils-1.0.3-py3-none-any.whl + name: pybtex-docutils + version: 1.0.3 + sha256: 8fd290d2ae48e32fcb54d86b0efb8d573198653c7e2447d5bec5847095f430b9 + requires_dist: + - docutils>=0.14 + - pybtex>=0.16 + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-3.0-pyhcf101f3_0.conda + sha256: e27e0473fc6723311a0bd48b89b616fa1b996a2f7a2b555338cbbcfb9c640568 + md5: 9c5491066224083c41b6d5635ed7107b + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pycparser?source=hash-mapping + size: 55886 + timestamp: 1779293633166 +- pypi: https://files.pythonhosted.org/packages/e2/0d/8ba33fa83a7dcde13eb3c1c2a0c1cc29950a048bfed6d9b0d8b6bd710b4c/pydata_sphinx_theme-0.16.1-py3-none-any.whl + name: pydata-sphinx-theme + version: 0.16.1 + sha256: 225331e8ac4b32682c18fcac5a57a6f717c4e632cea5dd0e247b55155faeccde + requires_dist: + - sphinx>=6.1 + - beautifulsoup4 + - docutils!=0.17.0 + - babel + - pygments>=2.7 + - accessible-pygments + - typing-extensions + - numpydoc ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - rich ; extra == 'doc' + - sphinxext-rediraffe ; extra == 'doc' + - sphinx-sitemap ; extra == 'doc' + - sphinx-autoapi>=3.0.0 ; extra == 'doc' + - myst-parser ; extra == 'doc' + - ablog>=0.11.8 ; extra == 'doc' + - jupyter-sphinx ; extra == 'doc' + - pandas ; extra == 'doc' + - plotly ; extra == 'doc' + - matplotlib ; extra == 'doc' + - numpy ; extra == 'doc' + - xarray ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - sphinx-togglebutton ; extra == 'doc' + - jupyterlite-sphinx ; extra == 'doc' + - sphinxcontrib-youtube>=1.4.1 ; extra == 'doc' + - sphinx-favicon>=1.0.1 ; extra == 'doc' + - ipykernel ; extra == 'doc' + - nbsphinx ; extra == 'doc' + - ipyleaflet ; extra == 'doc' + - colorama ; extra == 'doc' + - ipywidgets ; extra == 'doc' + - graphviz ; extra == 'doc' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-regressions ; extra == 'test' + - sphinx[test] ; extra == 'test' + - pyyaml ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydata-sphinx-theme[doc,test] ; extra == 'dev' + - tox ; extra == 'dev' + - pandoc ; extra == 'dev' + - sphinx-theme-builder[cli] ; extra == 'dev' + - pytest-playwright ; extra == 'a11y' + - babel ; extra == 'i18n' + - jinja2 ; extra == 'i18n' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.21.0-pyhcf101f3_0.conda + sha256: f5f015ff1bc3e1b7fc08eee096b1865234189ae0b82bebdb86a5369116e42fa0 + md5: 2882dee445dfa45b0c5afce3ffb7730a + depends: + - python >=3.10 + - python + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/pygments?source=compressed-mapping + size: 959376 + timestamp: 1786995678795 +- conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda + sha256: 417fba4783e528ee732afa82999300859b065dc59927344b4859c64aae7182de + md5: 3687cc0b82a8b4c17e1f0eb7e47163d5 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyparsing?source=hash-mapping + size: 110893 + timestamp: 1769003998136 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.2-py314h447aaf0_0.conda + sha256: bf1553eebc31e8ba04689639e8ce235c3df5317414f0c4a11417f238297f1b17 + md5: 7c3ccff96dbc9f8e3c40142c7594ec34 + depends: + - python + - qt6-main 6.11.2.* + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libxml2 + - libxml2-16 >=2.14.6 + - libclang13 >=22.1.8 + - qt6-main >=6.11.2,<7.0a0 + - python_abi 3.14.* *_cp314 + - libvulkan-loader >=1.4.357.0,<2.0a0 + - libxslt >=1.1.43,<2.0a0 + license: LGPL-3.0-only + license_family: LGPL + purls: + - pkg:pypi/pyside6?source=hash-mapping + - pkg:pypi/shiboken6?source=hash-mapping + size: 11552286 + timestamp: 1787219450026 +- 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/win-64/python-3.14.7-h53f6dd8_101_cp314.conda + build_number: 101 + sha256: 6a23a13d3ec5c48903bb2ad19a29c4346598481c276400f9954c76742d7822a5 + md5: 93dfbaa716a52edcdcb95dd4d6b209c8 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.8.1,<3.0a0 + - libffi >=3.7.0,<3.8.0a0 + - liblzma >=5.8.3,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libpython 3.14.7 h4f90d01_101_cp314 + - libsqlite >=3.53.4,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.8,<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: 18557864 + timestamp: 1787780948104 + python_site_packages_path: Lib/site-packages +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 + md5: 5b8d21249ff20967101ffa321cab24e8 + depends: + - python >=3.9 + - six >=1.5 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/python-dateutil?source=hash-mapping + size: 233310 + timestamp: 1751104122689 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.22.2-pyhcf101f3_0.conda + sha256: fc4a704822df22defce49d0fb811fdc036a1fd3b579aeaa601228e9cfd198b3d + md5: aa75b7f096d17621bc307b3025b29461 + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/fastjsonschema?source=compressed-mapping + size: 254446 + timestamp: 1786892280524 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.7-h4df99d1_101.conda + sha256: c39431bdbf23eff2eaa1591b438e5fd7e7db2fb635262b6eefd658dfa2f19c7c + md5: 35bb169c9d712dfc590b88f28f852157 + depends: + - cpython 3.14.7.* + - python_abi * *_cp314 + license: Python-2.0 + purls: [] + size: 50521 + timestamp: 1787780107541 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-4.2.0-pyhd8ed1ab_0.conda + sha256: 4f8ecadbd9d282b0208d6e84640573fcb6ab462307d737eedd28341964e18cc6 + md5: e5407c82510aab6a4baa31fcd4249655 + depends: + - python >=3.10 + - typing_extensions + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/python-json-logger?source=compressed-mapping + size: 19367 + timestamp: 1786872772907 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.3-pyhd8ed1ab_0.conda + sha256: 3f05db78cf8be33cf6dbc469664b8e3a01f3980d61d6d6bef48669b171896d8a + md5: eefc8d916bd2e708d76d40398ef9a1ee + depends: + - python >=3.10 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/tzdata?source=hash-mapping + size: 146862 + timestamp: 1783704822814 +- 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 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-312-py314hf700ef7_1.conda + sha256: 5a6ddd03a8441c2312a09f998dccb0bdeb1b906b45c9b8cd5e9f5a7965b0a604 + md5: 57992821d70e28562192fa29cff08260 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.14.* *_cp314 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/pywin32?source=hash-mapping + size: 4473050 + timestamp: 1787374336870 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-3.0.5-py314h51f0985_0.conda + sha256: 025a42fa3df042590f9f5efdf8473e98e654672871c9db029436f32e021cb900 + md5: 9f34ac4f934a5e6bdffa81db44b3ce82 + depends: + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - winpty + license: MIT + license_family: MIT + purls: + - pkg:pypi/pywinpty?source=hash-mapping + size: 731340 + timestamp: 1785742446062 +- 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=hash-mapping + size: 181257 + timestamp: 1770223460931 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.2.0-py312h343a6d4_0.conda + noarch: python + sha256: 56d33fdddf6fb7ffb86120b8e2f1398cc406d0d3e85e5647d3a72cad05c17509 + md5: 58bcf20b110e99aa69ab892a6ced10f5 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - _python_abi3_support 1.* + - cpython >=3.12 + - zeromq >=4.3.5,<4.3.6.0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=compressed-mapping + size: 187939 + timestamp: 1787300948668 +- conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda + sha256: 887d53486a37bd870da62b8fa2ebe3993f912ad04bd755e7ed7c47ced97cbaa8 + md5: 854fbdff64b572b5c0b470f334d34c11 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LicenseRef-Qhull + purls: [] + size: 1377020 + timestamp: 1720814433486 +- conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.2-pl5321hfcac499_0.conda + sha256: 042c94a5a7a89b0b28a24f6ae6a2d3d609751edab78454057973ec5cc3e77d7d + md5: d98a163070d05c6ed4421432ee1bafb8 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libvulkan-loader >=1.4.357.0,<2.0a0 + - icu >=78.3,<79.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libharfbuzz >=14.3.1 + - libzlib >=1.3.2,<2.0a0 + - double-conversion >=3.4.0,<3.5.0a0 + - libglib >=2.88.3,<3.0a0 + - krb5 >=1.22.2,<1.23.0a0 + - pcre2 >=10.47,<10.48.0a0 + - libpng >=1.6.58,<1.7.0a0 + - zstd >=1.5.7,<1.6.0a0 + - libsqlite >=3.53.4,<4.0a0 + - openssl >=3.5.7,<4.0a0 + - libjpeg-turbo >=3.2.0,<4.0a0 + - libtiff >=4.7.2,<4.8.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libwebp-base >=1.6.0,<2.0a0 + constrains: + - qt ==6.11.2 + license: LGPL-3.0-only + license_family: LGPL + purls: [] + size: 89682645 + timestamp: 1787049046883 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 + md5: 870293df500ca7e18bedefa5838a22ab + depends: + - attrs >=22.2.0 + - python >=3.10 + - rpds-py >=0.7.0 + - typing_extensions >=4.4.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/referencing?source=hash-mapping + size: 51788 + timestamp: 1760379115194 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda + sha256: 1715246b19c9f85ee022933b4845f2fc14ac9184981b7b7d9b728bec8e9588da + md5: 4a85203c1d80c1059086ae860836ffb9 + 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,<8 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/requests?source=hash-mapping + size: 68709 + timestamp: 1778851103479 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + sha256: 2e4372f600490a6e0b3bac60717278448e323cab1c0fecd5f43f7c56535a99c5 + md5: 36de09a8d3e5d5e6f4ee63af49e59706 + depends: + - python >=3.9 + - six + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3339-validator?source=hash-mapping + size: 10209 + timestamp: 1733600040800 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + sha256: 2a5b495a1de0f60f24d8a74578ebc23b24aa53279b1ad583755f223097c41c37 + md5: 912a71cc01012ee38e6b90ddd561e36f + depends: + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3986-validator?source=hash-mapping + size: 7818 + timestamp: 1598024297745 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + sha256: 70001ac24ee62058557783d9c5a7bbcfd97bd4911ef5440e3f7a576f9e43bc92 + md5: 7234f99325263a5af6d4cd195035e8f2 + depends: + - python >=3.9 + - lark >=1.2.2 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3987-syntax?source=hash-mapping + size: 22913 + timestamp: 1752876729969 +- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-2026.6.3-py314h9f07db2_0.conda + sha256: d297e7ef5f062194cf76dcf7a2e0449af24012b895a06aa942805f2933a0256c + md5: 07602f253d1ad9436bcac564c9fe183f + 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/rpds-py?source=compressed-mapping + size: 218916 + timestamp: 1787344535083 +- pypi: https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl + name: ruamel-yaml + version: 0.19.1 + sha256: 27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93 + requires_dist: + - ruamel-yaml-clib ; platform_python_implementation == 'CPython' and extra == 'oldlibyaml' + - ruamel-yaml-clibz>=0.3.7 ; platform_python_implementation == 'CPython' and extra == 'libyaml' + - ruamel-yaml-jinja2>=0.2 ; extra == 'jinja2' + - ryd ; extra == 'docs' + - mercurial>5.7 ; extra == 'docs' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda + sha256: 305446a0b018f285351300463653d3d3457687270e20eda37417b12ee386ef76 + md5: 6ac53f3fff2c416d63511843a04646fa + depends: + - __win + - pywin32 + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/send2trash?source=hash-mapping + size: 22864 + timestamp: 1770937641143 +- pypi: https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl + name: setuptools + version: 84.0.0 + sha256: 51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670 + requires_dist: + - pytest>=6,!=8.1.* ; extra == 'test' + - virtualenv>=13.0.0 ; extra == 'test' + - wheel>=0.44.0 ; extra == 'test' + - pip>=19.1 ; extra == 'test' + - packaging>=24.2 ; extra == 'test' + - jaraco-envs>=2.2 ; extra == 'test' + - pytest-xdist>=3 ; extra == 'test' + - jaraco-path>=3.7.2 ; extra == 'test' + - build[virtualenv]>=1.0.3 ; extra == 'test' + - filelock>=3.4.0 ; extra == 'test' + - ini2toml[lite]>=0.14 ; extra == 'test' + - tomli-w>=1.0.0 ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-perf ; sys_platform != 'cygwin' and extra == 'test' + - jaraco-develop>=7.21 ; python_full_version >= '3.9' and sys_platform != 'cygwin' and extra == 'test' + - pytest-home>=0.5 ; extra == 'test' + - pytest-subprocess ; extra == 'test' + - pyproject-hooks!=1.1 ; extra == 'test' + - jaraco-test>=5.5 ; 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' + - pygments-github-lexers==0.0.5 ; extra == 'doc' + - sphinx-favicon ; extra == 'doc' + - sphinx-inline-tabs ; extra == 'doc' + - sphinx-reredirects ; extra == 'doc' + - sphinxcontrib-towncrier ; extra == 'doc' + - sphinx-notfound-page>=1,<2 ; extra == 'doc' + - pyproject-hooks!=1.1 ; extra == 'doc' + - towncrier<24.7 ; extra == 'doc' + - packaging>=24.2 ; extra == 'core' + - more-itertools>=8.8 ; extra == 'core' + - jaraco-text>=3.7 ; extra == 'core' + - importlib-metadata>=6 ; python_full_version < '3.10' and extra == 'core' + - tomli>=2.0.1 ; python_full_version < '3.11' and extra == 'core' + - wheel>=0.43.0 ; extra == 'core' + - jaraco-functools>=4 ; extra == 'core' + - more-itertools ; extra == 'core' + - pytest-checkdocs>=2.14 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - ruff>=0.13.0 ; 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' + - mypy==1.18.* ; extra == 'type' + - importlib-metadata>=7.0.2 ; python_full_version < '3.10' and extra == 'type' + - jaraco-develop>=7.21 ; sys_platform != 'cygwin' and extra == 'type' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d + md5: 3339e3b65d58accf4ca4fb8748ab16b3 + depends: + - python >=3.9 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/six?source=hash-mapping + size: 18455 + timestamp: 1753199211006 +- conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + sha256: dce518f45e24cd03f401cb0616917773159a210c19d601c5f2d4e0e5879d30ad + md5: 03fe290994c5e4ec17293cfb6bdce520 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/sniffio?source=hash-mapping + size: 15698 + timestamp: 1762941572482 +- pypi: https://files.pythonhosted.org/packages/4c/07/2ebca9b11fb9be7340a818d8d6f63feaebb146be2c4afbd6061701d6df6e/snowballstemmer-3.1.1-py3-none-any.whl + name: snowballstemmer + version: 3.1.1 + sha256: 7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752 + requires_python: '>=3.3' +- conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.9.2-pyhd8ed1ab_0.conda + sha256: 056d7a2e91e303a9ee37e580f6dde0511fc3fb72476581cc337aacf2cc747613 + md5: ba33e6c8a46ee373fdf6dd8665212778 + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/soupsieve?source=compressed-mapping + size: 39439 + timestamp: 1786202135509 +- pypi: https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl + name: sphinx + version: 7.4.7 + sha256: c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239 + requires_dist: + - sphinxcontrib-applehelp + - sphinxcontrib-devhelp + - sphinxcontrib-jsmath + - sphinxcontrib-htmlhelp>=2.0.0 + - sphinxcontrib-serializinghtml>=1.1.9 + - sphinxcontrib-qthelp + - jinja2>=3.1 + - pygments>=2.17 + - docutils>=0.20,<0.22 + - snowballstemmer>=2.2 + - babel>=2.13 + - alabaster~=0.7.14 + - imagesize>=1.3 + - requests>=2.30.0 + - packaging>=23.0 + - importlib-metadata>=6.0 ; python_full_version < '3.10' + - tomli>=2 ; python_full_version < '3.11' + - colorama>=0.4.6 ; sys_platform == 'win32' + - sphinxcontrib-websupport ; extra == 'docs' + - flake8>=6.0 ; extra == 'lint' + - ruff==0.5.2 ; extra == 'lint' + - mypy==1.10.1 ; extra == 'lint' + - sphinx-lint>=0.9 ; extra == 'lint' + - types-docutils==0.21.0.20240711 ; extra == 'lint' + - types-requests>=2.30.0 ; extra == 'lint' + - importlib-metadata>=6.0 ; extra == 'lint' + - tomli>=2 ; extra == 'lint' + - pytest>=6.0 ; extra == 'lint' + - pytest>=8.0 ; extra == 'test' + - defusedxml>=0.7.1 ; extra == 'test' + - cython>=3.0 ; extra == 'test' + - setuptools>=70.0 ; extra == 'test' + - typing-extensions>=4.9 ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5c/60/6bf80661f1fc2573c6485819dc6daafa9e80b26fc60559e3cdba7552716d/sphinx_accessibility-1.0.1-py3-none-any.whl + name: sphinx-accessibility + version: 1.0.1 + sha256: d58d65c821e3854b31b35ae9fb90fd88ec1ced3943bdf2c5070e1930b96d03d0 + requires_dist: + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/cc/6e/b152dee1988fb4125b2fd882c63330d89706bccdf661c55230e5ed456c67/sphinx_apa_references-1.0.1-py3-none-any.whl + name: sphinx-apa-references + version: 1.0.1 + sha256: 234d31c748f1f4660784d4f34666e0d28da180c8ab292d0578b0b8ad6df0c87f + requires_dist: + - pybtex + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/02/bf/6f506a37c7f8ecc4576caf9486e303c7af249f6d70447bb51dde9d78cb99/sphinx_book_theme-1.2.0-py3-none-any.whl + name: sphinx-book-theme + version: 1.2.0 + sha256: 709605d308e1991c5ef0cf19c481dbe9084b62852e317fafab74382a0ee7ccfa + requires_dist: + - sphinx>=7.0 + - pydata-sphinx-theme==0.16.1 + - pre-commit ; extra == 'code-style' + - ablog>=0.11.13 ; extra == 'doc' + - ipywidgets ; extra == 'doc' + - folium ; extra == 'doc' + - numpy ; extra == 'doc' + - matplotlib ; extra == 'doc' + - numpydoc ; extra == 'doc' + - myst-nb ; extra == 'doc' + - nbclient ; extra == 'doc' + - pandas ; extra == 'doc' + - plotly ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - sphinx-examples ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-tabs ; extra == 'doc' + - sphinx-togglebutton ; extra == 'doc' + - sphinx-thebe ; extra == 'doc' + - sphinxcontrib-bibtex ; extra == 'doc' + - sphinxcontrib-youtube ; extra == 'doc' + - sphinxext-opengraph ; extra == 'doc' + - beautifulsoup4 ; extra == 'test' + - coverage ; extra == 'test' + - defusedxml ; extra == 'test' + - myst-nb ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-regressions ; extra == 'test' + - sphinx-thebe ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/b0/9e/e9d545c5c699cd6fa35912b487cde2910e4c5fcf7e4f52fced2f31dd8cdc/sphinx_code_examples-1.2.3-py3-none-any.whl + name: sphinx-code-examples + version: 1.2.3 + sha256: f2f25cd5fecc0e666fcbbd41016a6545bee0a7ae4d19c8c68ad70fac1171c596 + requires_dist: + - sphinx + - sphinx-iframes>=1.0.7 + - sphinx-proof + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/26/97/a5c39f619375d4f81d5422377fb027075898efa6b6202c1ccf1e5bb38a32/sphinx_comments-0.0.3-py3-none-any.whl + name: sphinx-comments + version: 0.0.3 + sha256: 1e879b4e9bfa641467f83e3441ac4629225fc57c29995177d043252530c21d00 + requires_dist: + - sphinx>=1.8 + - flake8>=3.7.0,<3.8.0 ; extra == 'code-style' + - black ; extra == 'code-style' + - pre-commit==1.17.0 ; extra == 'code-style' + - sphinx>=2 ; extra == 'sphinx' + - sphinx-book-theme ; extra == 'sphinx' + - myst-parser ; extra == 'sphinx' + - beautifulsoup4 ; extra == 'testing' + - myst-parser ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - sphinx>=2 ; extra == 'testing' + - sphinx-book-theme ; extra == 'testing' +- pypi: https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl + name: sphinx-copybutton + version: 0.5.2 + sha256: fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e + requires_dist: + - sphinx>=1.8 + - pre-commit==2.12.1 ; extra == 'code-style' + - sphinx ; extra == 'rtd' + - ipython ; extra == 'rtd' + - myst-nb ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - sphinx-examples ; extra == 'rtd' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/30/cf/45dd359f6ca0c3762ce0490f681da242f0530c49c81050c035c016bfdd3a/sphinx_design-0.7.0-py3-none-any.whl + name: sphinx-design + version: 0.7.0 + sha256: f82bf179951d58f55dca78ab3706aeafa496b741a91b1911d371441127d64282 + requires_dist: + - sphinx>=7,<10 + - pre-commit>=3,<4 ; extra == 'code-style' + - myst-parser>=4,<6 ; extra == 'rtd' + - myst-parser>=4,<6 ; extra == 'testing' + - pytest~=8.3 ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - defusedxml ; extra == 'testing' + - pytest~=8.3 ; extra == 'testing-no-myst' + - pytest-cov ; extra == 'testing-no-myst' + - pytest-regressions ; extra == 'testing-no-myst' + - defusedxml ; extra == 'testing-no-myst' + - furo~=2024.7.18 ; extra == 'theme-furo' + - sphinx-immaterial~=0.12.2 ; extra == 'theme-im' + - pydata-sphinx-theme~=0.15.2 ; extra == 'theme-pydata' + - sphinx-rtd-theme~=2.0 ; extra == 'theme-rtd' + - sphinx-book-theme~=1.1 ; extra == 'theme-sbt' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/bb/1c/6f22279218e978b08d6d301a8991547a585c3699942a33740de81843bdc5/sphinx_dropdown_toggle-1.3.3-py3-none-any.whl + name: sphinx-dropdown-toggle + version: 1.3.3 + sha256: 182182ba0fe4c515555a73d6d856cfa6e922eb4b4b574a7b19bd007fac78d242 + requires_dist: + - jupyterbook-patches>=1.13.1 + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/4d/95/af014c5eb8e804103471bcf3204ebfe6a674d8bae07e5c2b691c09183b9f/sphinx_exercise-1.2.1-py3-none-any.whl + name: sphinx-exercise + version: 1.2.1 + sha256: c8e5e470f5a3654a52f74528de5fade87df055bd0eacf4f607d355ea2558ff04 + requires_dist: + - sphinx-book-theme + - sphinx>=6.1 + - beautifulsoup4 ; extra == 'all' + - black ; extra == 'all' + - coverage ; extra == 'all' + - defusedxml ; extra == 'all' + - flake8>=3.7.0,<3.8.0 ; extra == 'all' + - matplotlib>=3.8 ; extra == 'all' + - myst-nb>=1.1.0 ; extra == 'all' + - pre-commit ; extra == 'all' + - pytest-cov ; extra == 'all' + - pytest-regressions ; extra == 'all' + - pytest>=8.0 ; extra == 'all' + - sphinx-book-theme ; extra == 'all' + - sphinx-togglebutton ; extra == 'all' + - sphinx>=6.1,<9 ; extra == 'all' + - texsoup ; extra == 'all' + - black ; extra == 'code-style' + - flake8>=3.7.0,<3.8.0 ; extra == 'code-style' + - pre-commit ; extra == 'code-style' + - myst-nb>=1.1.0 ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - sphinx-togglebutton ; extra == 'rtd' + - sphinx>=6.1,<9 ; extra == 'rtd' + - beautifulsoup4 ; extra == 'testing' + - coverage ; extra == 'testing' + - defusedxml ; extra == 'testing' + - matplotlib>=3.8 ; extra == 'testing' + - myst-nb>=1.1.0 ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest>=8.0 ; extra == 'testing' + - sphinx>=6.1,<9 ; extra == 'testing' + - texsoup ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9f/80/1704c9179012e289dee2178354e385277ea51f4fa827c4bf7e36c77b0f4b/sphinx_external_toc-1.1.0-py3-none-any.whl + name: sphinx-external-toc + version: 1.1.0 + sha256: 26c390b8d85aa641366fed2d3674910ec6820f48b91027affef485a2655ad7d0 + requires_dist: + - click>=7.1 + - pyyaml + - sphinx>=5 + - sphinx-multitoc-numbering>=0.1.3 + - pre-commit>=2.12 ; extra == 'code-style' + - myst-parser>=1.0.0 ; extra == 'rtd' + - sphinx-book-theme>=1.0.0 ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest>=7.1 ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a1/09/58a0b9ba3a3624b8d940f73651c9dd0430255f616b76df18958816717bc8/sphinx_gated_directives-1.1.2-py3-none-any.whl + name: sphinx-gated-directives + version: 1.1.2 + sha256: d375408ea8701184bf3264f7507e648801b29480f932dcb881814471bc8eb318 + requires_dist: + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/19/a5/ec4c322063caff100c15415a48facc1501083e81ebf7a01426c1167d63bc/sphinx_github_alerts-1.1-py3-none-any.whl + name: sphinx-github-alerts + version: '1.1' + sha256: 57ff740d461c1670386c40aa4dd1e42794b5b7d48eabb6889b680ef1a17a1602 + requires_dist: + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/42/08/2ea6aadc6edeb09784ea94448ecd451b7f79710b4c660dc377e2dd044a3b/sphinx_iframes-1.2.0-py3-none-any.whl + name: sphinx-iframes + version: 1.2.0 + sha256: 0275574aaa0977b8a92ca247d7b9fe389d4a0ed6476165eb9975cad703d1d690 + requires_dist: + - sphinx + - sphinx-metadata-figure>=1.1.1 + - sphinxcontrib-video + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7a/57/9eae17f1c0e2790ec2e2e8e914de1790cf7c28c59a275b9a4e0cc474344b/sphinx_image_inverter-1.1.11-py3-none-any.whl + name: sphinx-image-inverter + version: 1.1.11 + sha256: 991efdddaa5e6a51bf6b135f6d70b85355dd8b886aca3f65880cb074235a5a49 + requires_dist: + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/02/2b/e64e7de34663cff1df029ba4f05a86124315bd9eba3d3b78e64904bea7e0/sphinx_inline_tabs-2025.12.21.14-py3-none-any.whl + name: sphinx-inline-tabs + version: 2025.12.21.14 + sha256: e685c782b58d4e01490bcc4e2367cf7135ec28e7283a05e89095394e4ca6e81a + requires_dist: + - sphinx>=3 + - myst-parser ; extra == 'doc' + - furo ; extra == 'doc' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-xdist ; extra == 'test' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/70/1f/1d4ecaf58b17fe61497644655f40b04d84a88348e41a6f0c6392394d95e4/sphinx_jupyterbook_latex-1.0.0-py3-none-any.whl + name: sphinx-jupyterbook-latex + version: 1.0.0 + sha256: e0cd3e9e1c5af69136434e21a533343fdf013475c410a414d5b7b4922b4f3891 + requires_dist: + - sphinx>=5 + - packaging + - pre-commit~=2.12 ; extra == 'code-style' + - myst-nb>=1.0.0 ; extra == 'myst' + - myst-parser ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-jupyterbook-latex ; extra == 'rtd' + - coverage>=6.0 ; extra == 'testing' + - myst-nb>=1.0.0 ; extra == 'testing' + - pytest-cov>=3 ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest>=7.1 ; extra == 'testing' + - sphinx-external-toc>=1.0.0 ; extra == 'testing' + - sphinxcontrib-bibtex>=2.6.0 ; extra == 'testing' + - texsoup ; extra == 'testing' + requires_python: '>=3.9' +- pypi: git+https://github.com/TeachBooks/sphinx-last-updated-by-git#986142bb958d2e0f18da6755c551be865aa512ff + name: sphinx-last-updated-by-git + version: 0.3.8 + requires_dist: + - sphinx>=1.8 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/d5/99/9ad0c2c2e75d4e99b5023f6e12c77984875b1adab5bbc17e863c17cc1ba0/sphinx_launch_buttons-1.0.7-py3-none-any.whl + name: sphinx-launch-buttons + version: 1.0.7 + sha256: 8c1748e9038ea2dfbe90ffbcc603aa6e82df0a13b632fdd6cfbc350767703f19 + requires_dist: + - sphinx + - ruamel-yaml + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/e2/e0/ae934d06e31c67164145ada3ab8efec7a588a8f8f71cb3b54431935f0d76/sphinx_metadata_figure-1.5.1-py3-none-any.whl + name: sphinx-metadata-figure + version: 1.5.1 + sha256: 29b1b890cdcb9fb39ea2e62fd1fe8d9c56224d8c3b0e761845e7dc0bc3c0e664 + requires_dist: + - myst-nb>=0.17 + - sphinx>=5.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ec/9f/902f2030674cd9473fdbe5a2c2dec2618c27ec853484c35f82cf8df40ece/sphinx_multitoc_numbering-0.1.3-py3-none-any.whl + name: sphinx-multitoc-numbering + version: 0.1.3 + sha256: 33d2e707a9b2b8ad636b3d4302e658a008025106fe0474046c651144c26d8514 + requires_dist: + - sphinx>=3 + - flake8>=3.7.0,<3.8.0 ; extra == 'code-style' + - black ; extra == 'code-style' + - pre-commit==1.17.0 ; extra == 'code-style' + - sphinx>=3.0 ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - pytest~=5.4 ; extra == 'testing' + - pytest-cov~=2.8 ; extra == 'testing' + - coverage<5.0 ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - jupyter-book ; extra == 'testing' +- pypi: https://files.pythonhosted.org/packages/7a/d8/9c2ad1764a9f6736ec65134ef5fbee8c0d1f148cff260fef3afa38479998/sphinx_named_colors-1.0.3-py3-none-any.whl + name: sphinx-named-colors + version: 1.0.3 + sha256: b72e2291f7bf1252d399c88122b67ea4375c0e85b131ad7d72aba4dc3d8a45f3 + requires_dist: + - numpy + - sphinx + - sphinxnotes-comboroles + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ef/24/a4bbc812400aae41072d7b42f99c8787a097618a1084e7439aa03de3c73d/sphinx_nb_execution_patterns-1.1.0-py3-none-any.whl + name: sphinx-nb-execution-patterns + version: 1.1.0 + sha256: 2cc93535c5ffeccb70126fc5f3234bda8b9c78f99bd9cf416ea9d4ea7dd62db8 + requires_dist: + - jupyterbook-patches>=1.12.1 + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a6/7a/d3397a28c21cc3981de5fb26910b1f0b8821152dcfdba1737388edbe7864/sphinx_proof-0.4.0-py3-none-any.whl + name: sphinx-proof + version: 0.4.0 + sha256: 7781d533a56a6fa5cf4b1d79564b0a0f05493e45dedfcfa5de1ae5a7bd0c9ecd + requires_dist: + - docutils>=0.15 + - sphinx + - sphinx-book-theme + - flake8 ; extra == 'code-style' + - black ; extra == 'code-style' + - pre-commit ; extra == 'code-style' + - coverage ; extra == 'testing' + - pytest~=7.1 ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - beautifulsoup4 ; extra == 'testing' + - myst-parser ; extra == 'testing' + - texsoup ; extra == 'testing' + - defusedxml ; extra == 'testing' + - sphinx>=5.0 ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - sphinxcontrib-bibtex ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - sphinx-togglebutton ; extra == 'rtd' + - sphinxcontrib-bibtex ; extra == 'all' + - defusedxml ; extra == 'all' + - pytest~=7.1 ; extra == 'all' + - coverage ; extra == 'all' + - pytest-cov ; extra == 'all' + - beautifulsoup4 ; extra == 'all' + - pytest-regressions ; extra == 'all' + - texsoup ; extra == 'all' + - flake8 ; extra == 'all' + - pre-commit ; extra == 'all' + - sphinx>=5.0 ; extra == 'all' + - sphinx-book-theme ; extra == 'all' + - black ; extra == 'all' + - myst-parser ; extra == 'all' + - sphinx-togglebutton ; extra == 'all' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/ab/38/53f6735ac5392534218e6832aa749501a188a9f052a9f5b7de195bb6a7ea/sphinx_sticky_margin-1.1.4-py3-none-any.whl + name: sphinx-sticky-margin + version: 1.1.4 + sha256: 6bd9e012dfafa4b05bd0d43842a51bdacc16164facc6da9dd062243d257b8469 + requires_dist: + - sphinx>=5.0 + requires_python: '>=3.10' +- pypi: git+https://github.com/TeachBooks/Sphinx-Thebe#1f3a80969622b7d63f48f05d8769f5cb933202a0 + name: sphinx-thebe + version: 0.3.1 + requires_dist: + - sphinx>=4 + - wcmatch==8.5 + - myst-nb ; extra == 'sphinx' + - sphinx-book-theme ; extra == 'sphinx' + - sphinx-copybutton ; extra == 'sphinx' + - sphinx-design ; extra == 'sphinx' + - myst-nb>=1.0.0rc0 ; extra == 'testing' + - sphinx-copybutton ; extra == 'testing' + - sphinx-design ; extra == 'testing' + - matplotlib ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - beautifulsoup4 ; extra == 'testing' + - sphinx-thebe[testing] ; extra == 'dev' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/d8/2e/3dd55564928c5d61f92827d4b91307dde7911a40fbe0000645d73202eea9/sphinx_togglebutton-0.4.5-py3-none-any.whl + name: sphinx-togglebutton + version: 0.4.5 + sha256: 74eac6d2426110c3e1e6f989a98e07d7823141a335df1ad8a9d637bdf6a7af62 + requires_dist: + - setuptools + - wheel + - sphinx + - docutils + - matplotlib ; extra == 'sphinx' + - numpy ; extra == 'sphinx' + - myst-nb ; extra == 'sphinx' + - sphinx-book-theme ; extra == 'sphinx' + - sphinx-design ; extra == 'sphinx' + - sphinx-examples ; extra == 'sphinx' +- pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl + name: sphinxcontrib-applehelp + version: 2.0.0 + sha256: 4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 + requires_dist: + - ruff==0.5.5 ; extra == 'lint' + - mypy ; extra == 'lint' + - types-docutils ; extra == 'lint' + - sphinx>=5 ; extra == 'standalone' + - pytest ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/52/c0/d28e62407f4733bbe0169287bc012f0ac3b4a2021066b285570654119c8b/sphinxcontrib_bibtex-2.7.0-py3-none-any.whl + name: sphinxcontrib-bibtex + version: 2.7.0 + sha256: 28cf0ec7a957d1c7548d5749317ed472ce877e1b629f430f88e3789aa51f87b1 + requires_dist: + - sphinx>=7.4 + - docutils>=0.20 + - pybtex>=0.25 + - pybtex-docutils>=1.0.2 + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - sphinx-autoapi ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl + name: sphinxcontrib-devhelp + version: 2.0.0 + sha256: aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 + requires_dist: + - ruff==0.5.5 ; extra == 'lint' + - mypy ; extra == 'lint' + - types-docutils ; extra == 'lint' + - sphinx>=5 ; extra == 'standalone' + - pytest ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl + name: sphinxcontrib-htmlhelp + version: 2.1.0 + sha256: 166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 + requires_dist: + - ruff==0.5.5 ; extra == 'lint' + - mypy ; extra == 'lint' + - types-docutils ; extra == 'lint' + - sphinx>=5 ; extra == 'standalone' + - pytest ; extra == 'test' + - html5lib ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl + name: sphinxcontrib-jsmath + version: 1.0.1 + sha256: 2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 + requires_dist: + - pytest ; extra == 'test' + - flake8 ; extra == 'test' + - mypy ; extra == 'test' + requires_python: '>=3.5' +- pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl + name: sphinxcontrib-qthelp + version: 2.0.0 + sha256: b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb + requires_dist: + - ruff==0.5.5 ; extra == 'lint' + - mypy ; extra == 'lint' + - types-docutils ; extra == 'lint' + - sphinx>=5 ; extra == 'standalone' + - pytest ; extra == 'test' + - defusedxml>=0.7.1 ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl + name: sphinxcontrib-serializinghtml + version: 2.0.0 + sha256: 6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 + requires_dist: + - ruff==0.5.5 ; extra == 'lint' + - mypy ; extra == 'lint' + - types-docutils ; extra == 'lint' + - sphinx>=5 ; extra == 'standalone' + - pytest ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0b/85/5a61ac88dc21df340a5999ca3ab94edaf58287010c62020be426703b8dd3/sphinxcontrib_video-0.4.2-py3-none-any.whl + name: sphinxcontrib-video + version: 0.4.2 + sha256: 7dfd01e5e2025de39536457854052b18723575d6213d96ca35f83e3154dc0315 + requires_dist: + - sphinx + - nox ; extra == 'dev' + - pre-commit ; extra == 'dev' + - mypy ; extra == 'dev' + - pytest ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - pytest-regressions ; extra == 'test' + - pytest-cov ; extra == 'test' + - defusedxml ; extra == 'test' + - pydata-sphinx-theme ; extra == 'doc' + - sphinx-design ; extra == 'doc' + requires_python: '>=3.9.0' +- pypi: https://files.pythonhosted.org/packages/e3/13/62ff9dadfe0c70203e8d5f38635955bbd41b48ff916788a22fc033232348/sphinxnotes_comboroles-1.0-py3-none-any.whl + name: sphinxnotes-comboroles + version: '1.0' + sha256: c016b0d6ad1db0f91c6da203e3b10d18fcf2869e6833fecc48bc8bc45149f496 + requires_dist: + - sphinx>=4 + - build ; extra == 'dev' + - twine ; extra == 'dev' + - cruft ; extra == 'dev' + - furo ; extra == 'docs' + - sphinxnotes-any ; extra == 'docs' + - sphinx-design ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinxcontrib-gtagjs ; extra == 'docs' + - sphinxnotes-strike ; extra == 'docs' + - pytest ; extra == 'test' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl + name: sqlalchemy + version: 2.0.52 + sha256: a593db51b3bae75db17a5738ad5f992244b3a03863f83c28117ee482c6a3f76d + requires_dist: + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.12 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + sha256: 570da295d421661af487f1595045760526964f41471021056e993e73089e9c41 + md5: b1b505328da7a6b246787df4b5a49fbc + depends: + - asttokens + - executing + - pure_eval + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/stack-data?source=hash-mapping + size: 26988 + timestamp: 1733569565672 +- pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + name: tabulate + version: 0.10.0 + sha256: f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 + requires_dist: + - wcwidth ; extra == 'widechars' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2023.0.0-hd3d4ead_2.conda + sha256: 8a4053839b8e997a5965e2dff7d6cf3c77be62d82c0e48c8a04a5ed2d2e73035 + md5: 8ee01a693aecff5432069eaaf1183c45 + depends: + - libhwloc >=2.13.0,<2.13.1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 156515 + timestamp: 1778673901757 +- pypi: https://files.pythonhosted.org/packages/ac/e7/992d469644baa4408e2d0be36e07aa727fe0a2dea40dc9c150ca10c8c5ad/teachbooks-0.2.5-py3-none-any.whl + name: teachbooks + version: 0.2.5 + sha256: 285edf1f75275463a970b25c4bf312ff77f834304ff5c21417bcf6fb9de17235 + requires_dist: + - jupyter-book~=1.0 + - click + - psutil + - sphinx-book-theme==1.2.0 ; python_full_version >= '3.11' + - sphinx-book-theme==1.1.4 ; python_full_version < '3.11' + - pytest ; extra == 'testing' + - flaky ; extra == 'testing' + - ruff ; extra == 'lint' + - furo ; extra == 'docs' + - numpydoc ; extra == 'docs' + - sphinxcontrib-apidoc ; extra == 'docs' + - sphinx-click ; extra == 'docs' + - teachbooks[docs,lint,testing] ; extra == 'dev' + requires_python: '>=3.10' +- pypi: git+https://github.com/TeachBooks/TeachBooks-Favourites.git#ad0f301f83effb9322a5460f444d88878b30a75b + name: teachbooks-favourites + version: 1.15.1.dev1+gad0f301f8 + requires_dist: + - download-link-replacer==1.0.6 + - jupyterbook-patches==1.15.0 + - sphinx + - sphinx-accessibility==1.0.1 + - sphinx-code-examples==1.2.3 + - sphinx-dropdown-toggle==1.3.3 + - sphinx-exercise==1.2.1 + - sphinx-gated-directives==1.1.2 + - sphinx-github-alerts==1.1 + - sphinx-iframes==1.2.0 + - sphinx-image-inverter==1.1.11 + - sphinx-last-updated-by-git @ git+https://github.com/TeachBooks/sphinx-last-updated-by-git@986142b + - sphinx-launch-buttons==1.0.7 + - sphinx-metadata-figure==1.5.1 + - sphinx-named-colors==1.0.3 + - sphinx-nb-execution-patterns==1.1.0 + - sphinx-proof==0.4.0 + - sphinx-sticky-margin==1.1.4 + - sphinx-thebe @ git+https://github.com/TeachBooks/Sphinx-Thebe@1f3a809 + - sphinx-togglebutton==0.4.5 + - teachbooks-fetch==0.0.1 + - teachbooks-questions==0.2.1 + - teachbooks-sphinx-tippy==1.0.15 + - teachbooks-zoomies==0.2.4 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7f/24/77b78c112c60e2ddb16351e77f9a108628a6c3c18a618815112d79d374a2/teachbooks_fetch-0.0.1-py3-none-any.whl + name: teachbooks-fetch + version: 0.0.1 + sha256: 4233c2fdcbc6f8bb8e897e1c0fc9cdf4a9f79a2bbef8fa7c98688eebc0d28dc6 + requires_dist: + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/01/d0/99a7a3e3cce5d83566567c484cce9f2c5874c22da4cf2d420647233dbc81/teachbooks_questions-0.2.1-py3-none-any.whl + name: teachbooks-questions + version: 0.2.1 + sha256: 9e0e3f74adf62a0f13046cee9d20dde11f53161c10ba4c2b57d1548dcf9cf846 + requires_dist: + - sphinx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/05/77/8c5a7237bc99221408f12b629210b8f2176bcccfca916c09edfa8eb048e3/teachbooks_sphinx_tippy-1.0.15-py3-none-any.whl + name: teachbooks-sphinx-tippy + version: 1.0.15 + sha256: eca60b7f99005861d161db76b2ab65349e61022c219f5fe781779fc91c1d7a99 + requires_dist: + - sphinx>4 + - beautifulsoup4 + - jinja2 + - requests + - pytest ; extra == 'testing' + - sphinx-pytest ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - myst-parser ; extra == 'docs' + - furo ; extra == 'docs' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/24/74/f356db22f82eba6fd559128ae31222564f1e9e1e8b46a6ff93262621a9a2/teachbooks_zoomies-0.2.4-py3-none-any.whl + name: teachbooks-zoomies + version: 0.2.4 + sha256: 254a69e3352b9466c067a72b089cd3e5038ee62d5b1c62ff7666635cd978779e + requires_dist: + - sphinx + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda + sha256: b375e8df0d5710717c31e7c8e93c025c37fa3504aea325c7a55509f64e5d4340 + md5: e43ca10d61e55d0a8ec5d8c62474ec9e + depends: + - __win + - pywinpty >=1.1.0 + - python >=3.10 + - tornado >=6.1.0 + - python + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/terminado?source=hash-mapping + size: 23665 + timestamp: 1766513806974 +- conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + sha256: cad582d6f978276522f84bd209a5ddac824742fe2d452af6acf900f8650a73a2 + md5: f1acf5fdefa8300de697982bcb1761c9 + depends: + - python >=3.5 + - webencodings >=0.4 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/tinycss2?source=hash-mapping + size: 28285 + timestamp: 1729802975370 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda + sha256: f19618a3a82cc483dacf1c70a30367ee7b0c7e71b90f1f80e14feff44fbd3688 + md5: dd9eb33c99d352b6356f86964d6040f7 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: TCL + purls: [] + size: 3782376 + timestamp: 1787272860855 +- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + sha256: 91cafdb64268e43e0e10d30bd1bef5af392e69f00edd34dfaf909f69ab2da6bd + md5: b5325cf06a000c5b14970462ff5e4d58 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/tomli?source=hash-mapping + size: 21561 + timestamp: 1774492402955 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.8-py314h5a2d7ad_0.conda + sha256: 1cac25c190b60a4b6fbe2853c4989a4ce086564ee5f995c17d4b32885993068d + md5: 94dfb208db7d79437cfe9b4390706b5c + 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/tornado?source=hash-mapping + size: 925990 + timestamp: 1786226866739 +- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.16.1-pyhcf101f3_0.conda + sha256: 03dba5917f944c6684ab44c81daacac1624cd148e4b2cae215dcec594a210c48 + md5: a79bf97561232a31447b6246c2153ab5 + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/traitlets?source=hash-mapping + size: 116935 + timestamp: 1785761789772 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.16.0-h69aa097_0.conda + sha256: b141933ece3518f6d7b75dfb59451e2f26b405a44c18e2518a83e9a02e09315c + md5: c680b5747e8c4c8f23dca0bb7042a8fc + depends: + - typing_extensions ==4.16.0 pyhcf101f3_0 + license: PSF-2.0 + license_family: PSF + purls: [] + size: 94080 + timestamp: 1783002732887 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda + sha256: 2d888f90af0686044882c74193ec80a90ec1943145d94a7b1b048958acda1848 + md5: c70ad746c22219b9700931707482992c + depends: + - python >=3.10 + - python + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/typing-extensions?source=hash-mapping + size: 52631 + timestamp: 1783002732887 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + sha256: 3088d5d873411a56bf988eee774559335749aed6f6c28e07bf933256afb9eb6c + md5: f6d7aa696c67756a650e91e15e88223c + depends: + - python >=3.9 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/typing-utils?source=hash-mapping + size: 15183 + timestamp: 1733331395943 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda + sha256: b928c30ddcb0e3f544c6eade8352737e6e610e263276b90232db6a578ef899d8 + md5: fcb489df604d100968b737f2cb6076c6 + license: LicenseRef-Public-Domain + purls: [] + size: 118849 + timestamp: 1784250406640 +- pypi: https://files.pythonhosted.org/packages/61/73/d21edf5b204d1467e06500080a50f79d49ef2b997c79123a536d4a17d97c/uc_micro_py-2.0.0-py3-none-any.whl + name: uc-micro-py + version: 2.0.0 + sha256: 3603a3859af53e5a39bc7677713c78ea6589ff188d70f4fee165db88e22b242c + requires_dist: + - pytest ; extra == 'test' + - coverage ; extra == 'test' + - pytest-cov ; extra == 'test' + requires_python: '>=3.10' +- 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/win-64/unicodedata2-17.0.1-py314h5a2d7ad_0.conda + sha256: 9041e463044944460f73f9528f2ec491180f0ffe857e3555aa8160b81050b8d9 + md5: d6b580a13384df5155c6ca19ee66854e + 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/unicodedata2?source=hash-mapping + size: 406126 + timestamp: 1770909191618 +- conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + sha256: e0eb6c8daf892b3056f08416a96d68b0a358b7c46b99c8a50481b22631a4dfc0 + md5: e7cb0f5745e4c5035a460248334af7eb + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/uri-template?source=hash-mapping + size: 23990 + timestamp: 1733323714454 +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda + sha256: feff959a816f7988a0893201aa9727bbb7ee1e9cec2c4f0428269b489eb93fb4 + md5: cbb88288f74dbe6ada1c6c7d0a97223e + 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: 103560 + timestamp: 1778188657149 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_41.conda + sha256: 35444c55a92e2f7f7ba26bc70f81e56e52344f7d064c0fd4b40a46a58517b79c + md5: aa805b5522c2a98fa286e551a1f48546 + depends: + - vc14_runtime >=14.51.36247 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 21383 + timestamp: 1785359368566 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda + sha256: 4e4cb599cdc41bf2109d1464c127b5bcbddf548ce3e322e612afb691338b48f8 + md5: ac5333bb3d429361f23adf704cc49a78 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.51.36247 habf1de7_41 + constrains: + - vs2015_runtime 14.51.36247.* *_41 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 767955 + timestamp: 1785359364369 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda + sha256: 731e043390c9457299484d39e427221fc868a9249540a498a5a4f6456c7744d1 + md5: 350bb67a5c8e5f1c53347ac544ab6600 + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.51.36247.* *_41 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 155910 + timestamp: 1785359349999 +- pypi: https://files.pythonhosted.org/packages/6d/45/563267247f0b6f7c0f8028ab92bf1664da26179a630f863933033d74ab75/wcmatch-8.5-py3-none-any.whl + name: wcmatch + version: '8.5' + sha256: 14554e409b142edeefab901dc68ad570b30a72a8ab9a79106c5d5e9a6d241bd5 + requires_dist: + - bracex>=2.1.1 + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.2-pyhd8ed1ab_0.conda + sha256: 4acf845da404e84cef1acccc66cc0156af1b83a5b5d7077b2ca19b705c561e57 + md5: 99f7755ec8648a042b0dbe906234f888 + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/wcwidth?source=hash-mapping + size: 132415 + timestamp: 1782771807703 +- conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + sha256: 21f6c8a20fe050d09bfda3fb0a9c3493936ce7d6e1b3b5f8b01319ee46d6c6f6 + md5: 6639b6b0d8b5a284f027a2003669aa65 + depends: + - python >=3.10 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/webcolors?source=hash-mapping + size: 18987 + timestamp: 1761899393153 +- conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + sha256: 19ff205e138bb056a46f9e3839935a2e60bd1cf01c8241a5e172a422fed4f9c6 + md5: 2841eb5bfc75ce15e9a0054b98dcd64d + depends: + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/webencodings?source=hash-mapping + size: 15496 + timestamp: 1733236131358 +- conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + sha256: 42a2b61e393e61cdf75ced1f5f324a64af25f347d16c60b14117393a98656397 + md5: 2f1ed718fcd829c184a6d4f0f2e07409 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/websocket-client?source=hash-mapping + size: 61391 + timestamp: 1759928175142 +- pypi: https://files.pythonhosted.org/packages/2e/29/69cfbb602cd91690c55d38ba9fe53e6a7e76a6fa647bf38f19c138d25449/wheel-0.48.0-py3-none-any.whl + name: wheel + version: 0.48.0 + sha256: 3217dcc807155e45db462d7ef2431f5ddda0d7273b700d05a67b271ceb1287ab + requires_dist: + - packaging>=24.0 + requires_python: '>=3.9' +- 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/win-64/winpty-0.4.3-4.tar.bz2 + sha256: 9df10c5b607dd30e05ba08cbd940009305c75db242476f4e845ea06008b0a283 + md5: 1cee351bf20b830d991dbe0bc8cd7dfe + license: MIT + license_family: MIT + purls: [] + size: 1176306 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_2.conda + sha256: 892ad69b1a9ecc3903ed5a1b18fa097013eaf462eeed3c6ff31bf5c12e71e84b + md5: 87aee04978ab77bf4c0f42b983c216cc + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 110446 + timestamp: 1786381242485 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_2.conda + sha256: 21b11bb98c41ece4ce6069d86d826b50b3d73020fb631b97e59a0521dd9d08a1 + md5: 0e21a45f1bb429b6e35e82631e60554a + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 71362 + timestamp: 1786381239727 +- 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/win-64/zeromq-4.3.5-h3a581c9_11.conda + sha256: c3e279cb309b153152fcdd6ee6d039ad996d563c849f06be39d85b8e3351df25 + md5: f016c0c5f9c01549b259146614786192 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libsodium >=1.0.22,<1.0.23.0a0 + - krb5 >=1.22.2,<1.23.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 265717 + timestamp: 1779124031378 +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda + sha256: 210bd31c22bb88f5e2a167df24c95bb5f152b2ada7502f9b8c49d1f5366db423 + md5: ba3dcdc8584155c97c648ae9c044b7a3 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/zipp?source=hash-mapping + size: 24190 + timestamp: 1779159948016 +- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_3.conda + sha256: 5a0b55df66ff07b4342e04967cef69f8bf348f6a0fb1cc1eca741c7b015dfe77 + md5: 945092a9bc1d0f250f7d5ecf51ecd471 + depends: + - libzlib 1.3.2 hfd05255_3 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Zlib + license_family: Other + purls: [] + size: 851288 + timestamp: 1785276674755 +- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda + sha256: 71332532332d13b5dbe57074ddcf82ae711bdc132affa5a2982a29ffa06dc234 + md5: 46a21c0a4e65f1a135251fc7c8663f83 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Zlib + license_family: Other + purls: [] + size: 124542 + timestamp: 1770167984883 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda + sha256: ca7daae4f218a11fab82cc2857f0ea518ec3f46acec60490485347a4c22c6b3e + md5: e4ac308c39d6d0e131154976da67cf3b + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.2,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 387535 + timestamp: 1786599623274 diff --git a/pixi.toml b/pixi.toml new file mode 100644 index 0000000..bb52dcb --- /dev/null +++ b/pixi.toml @@ -0,0 +1,23 @@ +[workspace] +authors = ["FreekPols "] +channels = ["conda-forge"] +name = "manual" +platforms = ["win-64"] +version = "0.1.0" + +[tasks] +teachbooks = "teachbooks build book" +server = "teachbooks serve" +editor = "jupyter lab" + +[dependencies] +python = ">=3.14.7,<3.15" +jupyterlab = ">=4.6.3,<5" +numpy = ">=2.5.2,<3" +matplotlib = ">=3.11.1,<4" + +[pypi-dependencies] +teachbooks = ">=0.2.5, <0.3" +teachbooks-favourites = { git = "https://github.com/TeachBooks/TeachBooks-Favourites.git" } +sphinx-inline-tabs = ">=2025.12.21.14, <2026" +sphinx-apa-references = ">=1.0.1, <2" From e5593f3734c65bc2553255962f8360f38a6d9143 Mon Sep 17 00:00:00 2001 From: FreekPols Date: Fri, 28 Aug 2026 22:47:42 +0200 Subject: [PATCH 108/110] Revert "first description of pixi incl pixi.toml file" This reverts commit ab43185bb2867191a1e1ad48383b9781f0e798d0. --- .gitattributes | 2 - .gitignore | 4 +- book/_toc.yml | 1 - book/installation-and-setup/overview.md | 4 +- book/installation-and-setup/pixi.md | 21 - pixi.lock | 4309 ----------------------- pixi.toml | 23 - 7 files changed, 3 insertions(+), 4361 deletions(-) delete mode 100644 .gitattributes delete mode 100644 book/installation-and-setup/pixi.md delete mode 100644 pixi.lock delete mode 100644 pixi.toml diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 997504b..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# SCM syntax highlighting & preventing 3-way merges -pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff diff --git a/.gitignore b/.gitignore index 24e0c54..646bdab 100644 --- a/.gitignore +++ b/.gitignore @@ -140,6 +140,4 @@ book/.jupyterlite.doit.db **.teachbooks/ book/_toc_with_local_paths.yml book/_git/ -book/conf.py# pixi environments -.pixi/* -!.pixi/config.toml +book/conf.py \ No newline at end of file diff --git a/book/_toc.yml b/book/_toc.yml index 94c31a5..6122b8d 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -17,7 +17,6 @@ parts: - file: installation-and-setup/overview.md sections: - file: installation-and-setup/vscode-setup.md - - file: installation-and-setup/pixi.md - file: installation-and-setup/git-setup_local.md - file: installation-and-setup/anaconda.md - file: installation-and-setup/git_bash_conda_vs-code.md diff --git a/book/installation-and-setup/overview.md b/book/installation-and-setup/overview.md index 1564c78..a99389e 100644 --- a/book/installation-and-setup/overview.md +++ b/book/installation-and-setup/overview.md @@ -15,5 +15,5 @@ The following table will link the relevant installation and setup steps for you. |:---:|:---|:---| | Type 1
Type 2 | Review book | No software needed! Just open your interactive book online and give a review in the way you're asked to | | Type 3 | Edit single files online | No software needed! But you'll interact with Git, which might be a new thing for you | -| Type 4 | Editing text
Git| VS Code _or_ Jupyterlab
GitHub Desktop / Git in VS Code | -| Type 5 | Editing text
Git
Managing code-related software
Build your book | VS Code_or_ Jupyterlab
GitHub Desktop / Git in VS Code
Anaconda
Jupyter Book/Sphinx | +| Type 4 | Editing text
Git| VS Code
GitHub Desktop / Git in VS Code | +| Type 5 | Editing text
Git
Managing code-related software
Build your book | VS Code
GitHub Desktop / Git in VS Code
Anaconda
Jupyter Book/Sphinx | diff --git a/book/installation-and-setup/pixi.md b/book/installation-and-setup/pixi.md deleted file mode 100644 index 17043ce..0000000 --- a/book/installation-and-setup/pixi.md +++ /dev/null @@ -1,21 +0,0 @@ -# Installing and running with Pixi - -- Install pixi - -In the root file of the TB: - -- run `pixi install` - -This will install teachbooks and the most common dependecies. - -three tasks: -- `pixi run editor` this will start jupyterlab as the editor for both markdown and jupyternotebooks -- `pixi run serve` starts a server -- `pixi run teachbooks` builds the book (equivalent to `teachbooks build book` as described here) - - - - - -## Editing with Jupyter lab -Something about Jupyter lab \ No newline at end of file diff --git a/pixi.lock b/pixi.lock deleted file mode 100644 index 38940d5..0000000 --- a/pixi.lock +++ /dev/null @@ -1,4309 +0,0 @@ -version: 6 -environments: - default: - 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/win-64/_openmp_mutex-4.5-20_gnu.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-26.1.0-py314h5a2d7ad_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.7.0-py314h680f03e_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.15.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.4.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.4.0-hac0b51c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-hc8c2fe1_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hd477307_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py314h85cf176_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-2.0.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-2.0.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.1.1-py314h5a2d7ad_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.5.1-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/noarch/comm-0.2.3-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py314hf309875_4.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.7-py314hd8ed1ab_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.21-py314hb98de8c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_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/executing-2.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.18.3-hd47e2ca_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fonttools-4.63.0-pyh7db6752_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.15-h5112557_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.2.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-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/win-64/icu-78.3-h5112557_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.19-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.3.0-pyh6dadd2b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.17.0-pyhe2676ad_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.20.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.15.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-builder-1.2.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.10.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.21.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.6.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.1-py314hf309875_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h719d79b_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19.1-hf2c6c5f_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.2.0-hd936e49_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-9_h8455456_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hf02afa3_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-h84f9c24_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-he2a975b_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-9_h2a3cdd5_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-23.1.0-default_hacd6ee9_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h1a1d4e4_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-16.2.0-h110b43a_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.3-he810d59_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-16.2.0-h8ee18e1_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libharfbuzz-14.4.0-h03b5201_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.13.0-default_h049141e_1000.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.2.0-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-9_hf9ab0e9_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-hdc8cecf_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libpython-3.14.7-h4f90d01_101_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libraqm-0.11.0-h50d6d30_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.22-h6a83c73_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.2-h8f73337_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.357.0-h477610d_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_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/libxcb-1.17.0-h874e120_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-23.1.0-h49e36cd_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py314h2359020_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.11.1-py314h30c6bc1_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.11.1-py314h2061cd4_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.3.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2026.1.0-hac47afa_235.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.11.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.11.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio2-1.7.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.5.2-py314h02f10f6_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-h8466c1e_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-12.3.0-py314h61b30b5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.11.5-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.26.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.53-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py314hc5dbbe4_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-hba3369d_1003.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-3.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.21.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.2-py314h447aaf0_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.14.7-h53f6dd8_101_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.22.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.7-h4df99d1_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-4.2.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.3-pyhd8ed1ab_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/pywin32-312-py314hf700ef7_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-3.0.5-py314h51f0985_0.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/pyzmq-27.2.0-py312h343a6d4_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.2-pl5321hfcac499_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-2026.6.3-py314h9f07db2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.9.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2023.0.0-hd3d4ead_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.8-py314h5a2d7ad_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.16.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.16.0-h69aa097_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.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/unicodedata2-17.0.1-py314h5a2d7ad_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_41.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-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/winpty-0.4.3-4.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_2.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/zeromq-4.3.5-h3a581c9_11.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda - - pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b8/8f/6f7273a7adb8d73fc8d21ede4376a3e475e52f98435c6007f69100dec8ca/bracex-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fe/2e/bfe6b05463f5f95b831c43a4754c403bb4d8376ba5bb57d53839217fdd4c/download_link_replacer-1.0.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2e/3d/5cc9701117ea4dc0eb7bf1f4f9b7888a6e2e5277ddfae095805ace50f2b6/greenlet-3.5.5-cp314-cp314-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/01/f9/575c8d760eae1fc99651b7cc5efd96ad5379ca4d6b53750b0fb4fe983f34/imagesize-2.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/77/3781f65cafe55480b56914def99022a5d2965a4bb269655c89ef2f1de3cd/importlib-1.0.4.zip - - pypi: https://files.pythonhosted.org/packages/37/86/d45756beaeb4b9b06125599b429451f8640b5db6f019d606f33c85743fd4/jupyter_book-1.0.4.post1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/64/6b/67b87da9d36bff9df7d0efbd1a325fa372a43be7158effaf43ed7b22341d/jupyter_cache-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f6/54/af203c61a0550c232ed5e859d2c98f3fe80d1248b6ea1c4d4d5621fa08c9/jupyterbook_patches-1.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/40/23569737873cc9637fd488606347e9dd92b9fa37ba4fcda1f98ee5219a97/latexcodec-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/3d/e34b19cd144071c583317268c4feb2c59c03ac57eef69753410c7abb11c0/linkify_it_py-2.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-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/94/93/0a378b48488879a1d925b42a804edfc6e0cd0ef854220f2dce738a46e7e9/myst_nb-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/44/f6/775eb92e865b28cdb4ad1f2bed7a5446197516f76b58a950faa3be3fd08d/pybtex-0.26.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/b1/ce1f4596211efb5410e178a803f08e59b20bedb66837dcf41e21c54f9ec1/pybtex_docutils-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e2/0d/8ba33fa83a7dcde13eb3c1c2a0c1cc29950a048bfed6d9b0d8b6bd710b4c/pydata_sphinx_theme-0.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4c/07/2ebca9b11fb9be7340a818d8d6f63feaebb146be2c4afbd6061701d6df6e/snowballstemmer-3.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl - - pypi: git+https://github.com/TeachBooks/sphinx-last-updated-by-git#986142bb958d2e0f18da6755c551be865aa512ff - - pypi: git+https://github.com/TeachBooks/Sphinx-Thebe#1f3a80969622b7d63f48f05d8769f5cb933202a0 - - pypi: https://files.pythonhosted.org/packages/5c/60/6bf80661f1fc2573c6485819dc6daafa9e80b26fc60559e3cdba7552716d/sphinx_accessibility-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/6e/b152dee1988fb4125b2fd882c63330d89706bccdf661c55230e5ed456c67/sphinx_apa_references-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/02/bf/6f506a37c7f8ecc4576caf9486e303c7af249f6d70447bb51dde9d78cb99/sphinx_book_theme-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/9e/e9d545c5c699cd6fa35912b487cde2910e4c5fcf7e4f52fced2f31dd8cdc/sphinx_code_examples-1.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/26/97/a5c39f619375d4f81d5422377fb027075898efa6b6202c1ccf1e5bb38a32/sphinx_comments-0.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/30/cf/45dd359f6ca0c3762ce0490f681da242f0530c49c81050c035c016bfdd3a/sphinx_design-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bb/1c/6f22279218e978b08d6d301a8991547a585c3699942a33740de81843bdc5/sphinx_dropdown_toggle-1.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4d/95/af014c5eb8e804103471bcf3204ebfe6a674d8bae07e5c2b691c09183b9f/sphinx_exercise-1.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9f/80/1704c9179012e289dee2178354e385277ea51f4fa827c4bf7e36c77b0f4b/sphinx_external_toc-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a1/09/58a0b9ba3a3624b8d940f73651c9dd0430255f616b76df18958816717bc8/sphinx_gated_directives-1.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/19/a5/ec4c322063caff100c15415a48facc1501083e81ebf7a01426c1167d63bc/sphinx_github_alerts-1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/08/2ea6aadc6edeb09784ea94448ecd451b7f79710b4c660dc377e2dd044a3b/sphinx_iframes-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/57/9eae17f1c0e2790ec2e2e8e914de1790cf7c28c59a275b9a4e0cc474344b/sphinx_image_inverter-1.1.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/02/2b/e64e7de34663cff1df029ba4f05a86124315bd9eba3d3b78e64904bea7e0/sphinx_inline_tabs-2025.12.21.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/70/1f/1d4ecaf58b17fe61497644655f40b04d84a88348e41a6f0c6392394d95e4/sphinx_jupyterbook_latex-1.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d5/99/9ad0c2c2e75d4e99b5023f6e12c77984875b1adab5bbc17e863c17cc1ba0/sphinx_launch_buttons-1.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e2/e0/ae934d06e31c67164145ada3ab8efec7a588a8f8f71cb3b54431935f0d76/sphinx_metadata_figure-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/9f/902f2030674cd9473fdbe5a2c2dec2618c27ec853484c35f82cf8df40ece/sphinx_multitoc_numbering-0.1.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/d8/9c2ad1764a9f6736ec65134ef5fbee8c0d1f148cff260fef3afa38479998/sphinx_named_colors-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/24/a4bbc812400aae41072d7b42f99c8787a097618a1084e7439aa03de3c73d/sphinx_nb_execution_patterns-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a6/7a/d3397a28c21cc3981de5fb26910b1f0b8821152dcfdba1737388edbe7864/sphinx_proof-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/38/53f6735ac5392534218e6832aa749501a188a9f052a9f5b7de195bb6a7ea/sphinx_sticky_margin-1.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/2e/3dd55564928c5d61f92827d4b91307dde7911a40fbe0000645d73202eea9/sphinx_togglebutton-0.4.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/c0/d28e62407f4733bbe0169287bc012f0ac3b4a2021066b285570654119c8b/sphinxcontrib_bibtex-2.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0b/85/5a61ac88dc21df340a5999ca3ab94edaf58287010c62020be426703b8dd3/sphinxcontrib_video-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e3/13/62ff9dadfe0c70203e8d5f38635955bbd41b48ff916788a22fc033232348/sphinxnotes_comboroles-1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ac/e7/992d469644baa4408e2d0be36e07aa727fe0a2dea40dc9c150ca10c8c5ad/teachbooks-0.2.5-py3-none-any.whl - - pypi: git+https://github.com/TeachBooks/TeachBooks-Favourites.git#ad0f301f83effb9322a5460f444d88878b30a75b - - pypi: https://files.pythonhosted.org/packages/7f/24/77b78c112c60e2ddb16351e77f9a108628a6c3c18a618815112d79d374a2/teachbooks_fetch-0.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/d0/99a7a3e3cce5d83566567c484cce9f2c5874c22da4cf2d420647233dbc81/teachbooks_questions-0.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/77/8c5a7237bc99221408f12b629210b8f2176bcccfca916c09edfa8eb048e3/teachbooks_sphinx_tippy-1.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/24/74/f356db22f82eba6fd559128ae31222564f1e9e1e8b46a6ff93262621a9a2/teachbooks_zoomies-0.2.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/61/73/d21edf5b204d1467e06500080a50f79d49ef2b997c79123a536d4a17d97c/uc_micro_py-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/45/563267247f0b6f7c0f8028ab92bf1664da26179a630f863933033d74ab75/wcmatch-8.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2e/29/69cfbb602cd91690c55d38ba9fe53e6a7e76a6fa647bf38f19c138d25449/wheel-0.48.0-py3-none-any.whl -packages: -- conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda - build_number: 20 - sha256: 8a1cee28bd0ee7451ada1cd50b64720e57e17ff994fc62dd8329bef570d382e4 - md5: 1626967b574d1784b578b52eaeb071e7 - depends: - - libgomp >=7.5.0 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - constrains: - - openmp_impl <0.0a0 - - msys2-conda-epoch <0.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 52252 - timestamp: 1770943776666 -- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_3.conda - sha256: 2a7204314663eeda5dec482a956f0e2eaf289bd5b9953eaaaad0e81aa64638f2 - md5: 3845f3d75991bae0fb90884662f4327c - depends: - - cpython - - python-gil - license: MIT - license_family: MIT - purls: [] - size: 8144 - timestamp: 1784221492234 -- pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl - name: accessible-pygments - version: 0.0.5 - sha256: 88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7 - requires_dist: - - pygments>=1.5 - - pillow ; extra == 'dev' - - pkginfo>=1.10 ; extra == 'dev' - - playwright ; extra == 'dev' - - pre-commit ; extra == 'dev' - - setuptools ; extra == 'dev' - - twine>=5.0 ; extra == 'dev' - - hypothesis ; extra == 'tests' - - pytest ; extra == 'tests' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl - name: alabaster - version: 0.7.16 - sha256: b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.2-pyhcf101f3_0.conda - sha256: e36998c5e860e26b22e5dbcd5726dd0c4eabad949c84d383cad8512757bbf6a1 - md5: fb568fbae6908ba86a090a85a089d11f - depends: - - exceptiongroup >=1.0.2 - - idna >=2.8 - - python >=3.10 - - typing_extensions >=4.5 - - python - constrains: - - trio >=0.32.0 - - uvloop >=0.22.1 - - winloop >=0.2.3 - license: MIT - license_family: MIT - purls: - - pkg:pypi/anyio?source=hash-mapping - size: 164465 - timestamp: 1783889660383 -- conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - sha256: bea62005badcb98b1ae1796ec5d70ea0fc9539e7d59708ac4e7d41e2f4bb0bad - md5: 8ac12aff0860280ee0cff7fa2cf63f3b - depends: - - argon2-cffi-bindings - - python >=3.9 - - typing-extensions - constrains: - - argon2_cffi ==999 - license: MIT - license_family: MIT - purls: - - pkg:pypi/argon2-cffi?source=hash-mapping - size: 18715 - timestamp: 1749017288144 -- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-26.1.0-py314h5a2d7ad_0.conda - sha256: 47917aa31232191136b40f3055d4b469c0a71475aea396c2413d753be014b7dc - md5: 6c4598c60f92421a0f9926a0f4b36dd0 - depends: - - cffi >=2.0.0b1 - - 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/argon2-cffi-bindings?source=compressed-mapping - size: 33526 - timestamp: 1787248062135 -- conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - sha256: 792da8131b1b53ff667bd6fc617ea9087b570305ccb9913deb36b8e12b3b5141 - md5: 85c4f19f377424eafc4ed7911b291642 - depends: - - python >=3.10 - - python-dateutil >=2.7.0 - - python-tzdata - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/arrow?source=hash-mapping - size: 113854 - timestamp: 1760831179410 -- conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.2-pyhd8ed1ab_0.conda - sha256: fbbd8ce60cbd5c16f3fe559eb644551f94285caff30985ea961ff851c1cf25ac - md5: 89d495168582cb00428dad699d149624 - depends: - - python >=3.10 - constrains: - - astroid >=2,<5 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/asttokens?source=hash-mapping - size: 34639 - timestamp: 1783975742052 -- conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - sha256: ea8486637cfb89dc26dc9559921640cd1d5fd37e5e02c33d85c94572139f2efe - md5: b85e84cb64c762569cc1a760c2327e0a - depends: - - python >=3.10 - - typing_extensions >=4.0.0 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/async-lru?source=hash-mapping - size: 22949 - timestamp: 1773926359134 -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab - md5: c6b0543676ecb1fb2d7643941fe375f2 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/attrs?source=hash-mapping - size: 64927 - timestamp: 1773935801332 -- conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - sha256: a14a9ad02101aab25570543a59c5193043b73dc311a25650134ed9e6cb691770 - md5: f1976ce927373500cc19d3c0b2c85177 - depends: - - python >=3.10 - - python - constrains: - - pytz >=2015.7 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/babel?source=hash-mapping - size: 7684321 - timestamp: 1772555330347 -- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.7.0-py314h680f03e_0.conda - noarch: generic - sha256: 19514d89d1e725e44b0650d31a4d43da8e070e4e93e4131e3b16bd139404f2b2 - md5: 92adf685875ab717f68ad4172ef6de27 - depends: - - python >=3.14 - license: BSD-3-Clause AND MIT AND EPL-2.0 - purls: [] - size: 7541 - timestamp: 1786861415851 -- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.15.0-pyha770c72_0.conda - sha256: aed4b9dcf68ec2a75e5645fed14d77fd884d38d2e52bfa6ef4b278d90cd88781 - md5: 3b261da3fe9b4168738712832410b022 - depends: - - python >=3.10 - - soupsieve >=1.2 - - typing-extensions - license: MIT - license_family: MIT - purls: - - pkg:pypi/beautifulsoup4?source=hash-mapping - size: 92704 - timestamp: 1780853175566 -- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.4.0-pyhcf101f3_0.conda - sha256: 0c786f3e571bd58ac73d730d06314716663884d848ae320de0b438fae5e0bea9 - md5: 93009c29cdd6f2500468f2502fff9209 - depends: - - python >=3.10 - - webencodings - - python - constrains: - - tinycss2 >=1.1.0,<1.5 - license: Apache-2.0 AND MIT - purls: - - pkg:pypi/bleach?source=hash-mapping - size: 142246 - timestamp: 1780675823953 -- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.4.0-hac0b51c_0.conda - sha256: ede77e412304cd080e23967352a7904932207d0167ecdccd6a9e210530942be6 - md5: 5f710eab1f3c4e773c75686f5e8e6481 - depends: - - bleach ==6.4.0 pyhcf101f3_0 - - tinycss2 - license: Apache-2.0 AND MIT - purls: [] - size: 4406 - timestamp: 1780675823953 -- pypi: https://files.pythonhosted.org/packages/b8/8f/6f7273a7adb8d73fc8d21ede4376a3e475e52f98435c6007f69100dec8ca/bracex-3.0.1-py3-none-any.whl - name: bracex - version: 3.0.1 - sha256: 6523ad83aeb5098a4ee597cff0f964442ff74e460bd3fafaffab6a013ff2288c - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-hc8c2fe1_3.conda - sha256: 85e12348d058791aabd6eeb6abc1d7ab44b8f6308f91c8475f44f778f2a158af - md5: 9eba56a007c44dc32d0b9d0a820871ea - depends: - - brotli-bin 1.2.0 hd477307_3 - - libbrotlidec 1.2.0 h84f9c24_3 - - libbrotlienc 1.2.0 he2a975b_3 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 20954 - timestamp: 1786622876247 -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hd477307_3.conda - sha256: 5328e0576c729813d28efc15613f4be94d029d77c4fe5afda16cab0b8d0c9d05 - md5: dc04f7b3d82c6fb3fdf4d93e45b6ea2a - depends: - - libbrotlidec 1.2.0 h84f9c24_3 - - libbrotlienc 1.2.0 he2a975b_3 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 23119 - timestamp: 1786622866096 -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py314h85cf176_3.conda - sha256: f96c411313beb92a6a9066b823f7e8ea085f3e3889219b44306c44d59f99e611 - md5: b1ff58c1f0deedd3f25c103e37049cee - 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 hf02afa3_3 - license: MIT - license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 336902 - timestamp: 1786623039339 -- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda - sha256: 04767466ee9227c9c57ab2c6503e0149177d34111c7418d2f420297acb1eb229 - md5: c3301c058362f340100d91cd8be0393f - 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: 55919 - timestamp: 1785906343696 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda - sha256: 95e8e74062a5fe5f870ac8c90302b6e89945165fdaed7810606e84ddee6aac12 - md5: e27d2ac27b096dc51fedfcf775a53f9b - depends: - - __win - license: ISC - purls: [] - size: 132136 - timestamp: 1784754918886 -- conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-2.0.1-pyhcf101f3_0.conda - sha256: 39358005c3cc44d8315ed79789b18a960d69365be979970cc6bae8f7a6177703 - md5: 70e764e549c6c25de5e429d6e4a28b39 - depends: - - cached_property >=2.0.1,<2.0.2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/cached-property?source=compressed-mapping - size: 3720 - timestamp: 1787678456483 -- conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-2.0.1-pyhcf101f3_0.conda - sha256: 4bd96dab5a434e4ee59fb6910cae704d4c5b453907d4886272a9943d37e42b6f - md5: 256d863ded0f79464391a075944d24a6 - depends: - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/cached-property?source=compressed-mapping - size: 16597 - timestamp: 1787678456483 -- conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_2.conda - sha256: 9128dfc6a864e369ee7b1c9bd4b3875de9d06890925760aec932cf3cc67bcb24 - md5: 601e2ec8ae0ed934d8788000f984ff18 - depends: - - fontconfig >=2.18.3,<3.0a0 - - fonts-conda-ecosystem - - icu >=78.3,<79.0a0 - - libexpat >=2.8.1,<3.0a0 - - libfreetype >=2.14.3 - - libfreetype6 >=2.14.3 - - libglib >=2.88.3,<3.0a0 - - libpng >=1.6.58,<1.7.0a0 - - libzlib >=1.3.2,<2.0a0 - - pixman >=0.46.4,<1.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: LGPL-2.1-only or MPL-1.1 - purls: [] - size: 1540051 - timestamp: 1787926241225 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda - sha256: fb167de4388e64e52aa3907ed099afab944c1fa6e5f74b281a312dae1bcf7f3b - md5: 37e13edbe3b48f1095a9d085ef9cd83b - depends: - - python >=3.10 - license: ISC - purls: - - pkg:pypi/certifi?source=hash-mapping - size: 137015 - timestamp: 1784717699092 -- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.1.1-py314h5a2d7ad_2.conda - sha256: e0e10d676eb67a8a4c8991cec89fb6f150f919eb1266a1b39253a857b3dc0454 - md5: 672d6ff72c6265b25eeef94ce21e71ac - 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=compressed-mapping - size: 346657 - timestamp: 1786775160153 -- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.5.1-pyhd8ed1ab_0.conda - sha256: cb60ef3e0631c8bacb4f7057196dee4496091a22baa3bb4b9bccb12c7e1c921b - md5: e0ac3accc64e23e40969d660e5f58ac8 - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/charset-normalizer?source=compressed-mapping - size: 64487 - timestamp: 1786835648298 -- pypi: https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl - name: click - version: 8.5.0 - sha256: 255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360 - requires_python: '>=3.10' -- 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/noarch/comm-0.2.3-pyhe01879c_0.conda - sha256: 576a44729314ad9e4e5ebe055fbf48beb8116b60e58f9070278985b2b634f212 - md5: 2da13f2b299d8e1995bafbbe9689a2f7 - depends: - - python >=3.9 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/comm?source=hash-mapping - size: 14690 - timestamp: 1753453984907 -- conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py314hf309875_4.conda - sha256: f141bcbf8e490b49b2f53f517173d13a64d75e43cfae170e0d931cb0b66f4bce - md5: c26934035616f7d578f9da0491aed3d8 - depends: - - numpy >=1.25 - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.14.* *_cp314 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/contourpy?source=hash-mapping - size: 247437 - timestamp: 1769155978556 -- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.7-py314hd8ed1ab_101.conda - noarch: generic - sha256: 57a6f69c77cec9726b91e8bb4f4e93979dfad65277ef2acba8ef31ffc9939187 - md5: 5656db6c2bbe5923be509b769c843ed9 - depends: - - python >=3.14,<3.15.0a0 - - python_abi * *_cp314 - license: Python-2.0 - purls: [] - size: 50513 - timestamp: 1787780089142 -- conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda - sha256: bb47aec5338695ff8efbddbc669064a3b10fe34ad881fb8ad5d64fbfa6910ed1 - md5: 4c2a8fef270f6c69591889b93f9f55c1 - depends: - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/cycler?source=hash-mapping - size: 14778 - timestamp: 1764466758386 -- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.21-py314hb98de8c_0.conda - sha256: daa9397ffba6722f27c21b2f0a02b197f3ba9baedb484a155539743ec5ea3ac3 - md5: 945786ac874b8e821a675fbdd885f844 - 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/debugpy?source=hash-mapping - size: 4022782 - timestamp: 1780390190830 -- conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - sha256: 9717a059677553562a8f38ff07f3b9f61727bd614f505658b0a5ecbcf8df89be - md5: 961b3a227b437d82ad7054484cfa71b2 - depends: - - python >=3.6 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/defusedxml?source=hash-mapping - size: 24062 - timestamp: 1615232388757 -- pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - name: docutils - version: 0.21.2 - sha256: dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda - sha256: 09e30a170e0da3e9847d449b594b5e55e6ae2852edd3a3680e05753a5e015605 - md5: 3d3caf4ccc6415023640af4b1b33060a - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 70943 - timestamp: 1765193243911 -- pypi: https://files.pythonhosted.org/packages/fe/2e/bfe6b05463f5f95b831c43a4754c403bb4d8376ba5bb57d53839217fdd4c/download_link_replacer-1.0.6-py3-none-any.whl - name: download-link-replacer - version: 1.0.6 - sha256: a4bf385f69b1a5488a76ea1cfbd51955bfc39154b9ae450a7cdc1f421d9f5642 - requires_dist: - - sphinx - - importlib - requires_python: '>=3.9' -- 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/executing-2.2.1-pyhd8ed1ab_0.conda - sha256: 210c8165a58fdbf16e626aac93cc4c14dbd551a01d1516be5ecad795d2422cad - md5: ff9efb7f7469aed3c4a8106ffa29593c - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/executing?source=hash-mapping - size: 30753 - timestamp: 1756729456476 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 - sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b - md5: 0c96522c6bdaed4b1566d11387caaf45 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 397370 - timestamp: 1566932522327 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 - sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c - md5: 34893075a5c9e55cdafac56607368fc6 - license: OFL-1.1 - license_family: Other - purls: [] - size: 96530 - timestamp: 1620479909603 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 - sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 - md5: 4d59c254e01d9cde7957100457e2d5fb - license: OFL-1.1 - license_family: Other - purls: [] - size: 700814 - timestamp: 1620479612257 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda - sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 - md5: 49023d73832ef61042f6a237cb2687e7 - license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 - license_family: Other - purls: [] - size: 1620504 - timestamp: 1727511233259 -- conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.18.3-hd47e2ca_1.conda - sha256: f26139e3c774a6434c8a73381c08e3d2a4c2f9d9ef9587c66aab8836211ee2ec - md5: ed95670fed91b091fe34ba6cae6677d7 - depends: - - libexpat >=2.8.1,<3.0a0 - - libfreetype >=2.14.3 - - libfreetype6 >=2.14.3 - - libiconv >=1.18,<2.0a0 - - libintl >=0.22.5,<1.0a0 - - libzlib >=1.3.2,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 217988 - timestamp: 1786667461139 -- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 - md5: fee5683a3f04bd15cbd8318b096a27ab - depends: - - fonts-conda-forge - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 3667 - timestamp: 1566974674465 -- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda - sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 - md5: a7970cd949a077b7cb9696379d338681 - depends: - - font-ttf-ubuntu - - font-ttf-inconsolata - - font-ttf-dejavu-sans-mono - - font-ttf-source-code-pro - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 4059 - timestamp: 1762351264405 -- conda: https://conda.anaconda.org/conda-forge/noarch/fonttools-4.63.0-pyh7db6752_0.conda - sha256: c9752235f1ff7061d834e5e4a3d0adf71ebeeff2b3fad82dab607edce7f70c91 - md5: 0509ee74d95e5b98eb6fe2a47760e399 - depends: - - brotli - - munkres - - python >=3.10 - - unicodedata2 >=15.1.0 - track_features: - - fonttools_no_compile - license: MIT - license_family: MIT - purls: - - pkg:pypi/fonttools?source=hash-mapping - size: 846038 - timestamp: 1778770337113 -- conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - sha256: 2509992ec2fd38ab27c7cdb42cf6cadc566a1cc0d1021a2673475d9fa87c6276 - md5: d3549fd50d450b6d9e7dddff25dd2110 - depends: - - cached-property >=1.3.0 - - python >=3.9,<4 - license: MPL-2.0 - license_family: MOZILLA - purls: - - pkg:pypi/fqdn?source=hash-mapping - size: 16705 - timestamp: 1733327494780 -- conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_2.conda - sha256: 32f7dd8ffe62fd485e9e6570e871f5be45af74c84fde62241a2417046a373efd - md5: 6fc6c09c05a099d58efd9b2e96598e41 - depends: - - libfreetype 2.14.3 h57928b3_2 - - libfreetype6 2.14.3 hdbac1cb_2 - - zlib - license: GPL-2.0-only OR FTL - purls: [] - size: 186945 - timestamp: 1786641050416 -- conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_1.conda - sha256: 274b3e4ae5dff527062039d1dcb5cfdd9f91fa7d8eaf61358c09450b361385de - md5: 66f5ce9d0d618332023619a899ceb26f - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: LGPL-2.1-or-later - purls: [] - size: 65318 - timestamp: 1785912637725 -- conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.15-h5112557_1.conda - sha256: 93a59bdf944fb6f947bd7ad2f293d5d80db3a90f8ff8dfabc591e3752141e46f - md5: 79538e7a7bc024084eda5989f73fde35 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: LGPL-2.0-or-later - license_family: LGPL - purls: [] - size: 98064 - timestamp: 1786118492029 -- pypi: https://files.pythonhosted.org/packages/2e/3d/5cc9701117ea4dc0eb7bf1f4f9b7888a6e2e5277ddfae095805ace50f2b6/greenlet-3.5.5-cp314-cp314-win_amd64.whl - name: greenlet - version: 3.5.5 - sha256: 7dffc5c859fe6059974df1e37d7923d654a83e2ae18fdd616994270e001115e1 - requires_dist: - - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - - objgraph ; extra == 'test' - - psutil ; extra == 'test' - - setuptools ; extra == 'test' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda - sha256: 96cac6573fd35ae151f4d6979bab6fbc90cb6b1fb99054ba19eb075da9822fcb - md5: b8993c19b0c32a2f7b66cbb58ca27069 - depends: - - python >=3.10 - - typing_extensions - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/h11?source=hash-mapping - size: 39069 - timestamp: 1767729720872 -- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.4.1-pyhcf101f3_0.conda - sha256: 307dd6ec90140c3cf4171071b0e5e870abec314f4565c1edd5bc433e942cdcc0 - md5: e652ac7756069c456d0da2a922cd7df5 - depends: - - python >=3.10 - - hyperframe >=6.1,<7 - - hpack >=4.2,<5 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/h2?source=hash-mapping - size: 100789 - timestamp: 1785796355216 -- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.2.0-pyhd8ed1ab_0.conda - sha256: fdcea5d7cb314485d3907192ef024c704311548c5b0cbeb390cd1951051e29d2 - md5: b395909221b9bd1df066e5930e18855b - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/hpack?source=hash-mapping - size: 32884 - timestamp: 1782283986153 -- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - sha256: 04d49cb3c42714ce533a8553986e1642d0549a05dc5cc48e0d43ff5be6679a5b - md5: 4f14640d58e2cc0aa0819d9d8ba125bb - depends: - - python >=3.9 - - h11 >=0.16 - - h2 >=3,<5 - - sniffio 1.* - - anyio >=4.0,<5.0 - - certifi - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/httpcore?source=hash-mapping - size: 49483 - timestamp: 1745602916758 -- conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - sha256: cd0f1de3697b252df95f98383e9edb1d00386bfdd03fdf607fa42fe5fcb09950 - md5: d6989ead454181f4f9bc987d3dc4e285 - depends: - - anyio - - certifi - - httpcore 1.* - - idna - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/httpx?source=hash-mapping - size: 63082 - timestamp: 1733663449209 -- 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/win-64/icu-78.3-h5112557_2.conda - sha256: 75c549b55b673e15de8785a8e5dd85bca7eb612eee0ff4dc8d7bdaa15eacbdbb - md5: e596942e8ee6ee17fdcf1e6a77757a66 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 16835644 - timestamp: 1784916416303 -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.19-pyhcf101f3_0.conda - sha256: 1c35a59c1545ad0fdaddf1fbde7bcfa6ef41a8d68c3a2b0b4a291be00676163e - md5: a39ae05027e9b707742e41b30d296b75 - depends: - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/idna?source=compressed-mapping - size: 177433 - timestamp: 1787059857580 -- pypi: https://files.pythonhosted.org/packages/01/f9/575c8d760eae1fc99651b7cc5efd96ad5379ca4d6b53750b0fb4fe983f34/imagesize-2.0.1-py3-none-any.whl - name: imagesize - version: 2.0.1 - sha256: ea0c9a0384df69ed86a943a15cde37d0360b82491b3910dc2215e202e62b5b02 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/31/77/3781f65cafe55480b56914def99022a5d2965a4bb269655c89ef2f1de3cd/importlib-1.0.4.zip - name: importlib - version: 1.0.4 - sha256: b6ee7066fea66e35f8d0acee24d98006de1a0a8a94a8ce6efe73a9a23c8d9826 -- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.1-pyhcf101f3_0.conda - sha256: 95a074a7d3f58b3494c068d4789c364dcb591c56b70ca6b12f149a540f9aeea4 - md5: 77ec68e0aa61c3fff9ecbf840f93d64e - depends: - - python >=3.10 - - zipp >=3.20 - - python - license: Apache-2.0 - purls: - - pkg:pypi/importlib-metadata?source=compressed-mapping - size: 34920 - timestamp: 1787943971257 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.3.0-pyh6dadd2b_0.conda - sha256: e3ff0b3d5db5c31830030406f50ac2c9a5c31b86f1c2cef87a6042f0a4c77eb7 - md5: dd5c51d5c42381ba4a2e0ce32e02ba17 - depends: - - __win - - comm >=0.1.1 - - debugpy >=1.6.5 - - ipython >=7.23.1 - - jupyter_client >=8.9.0 - - jupyter_core >=5.1,!=6.0.* - - matplotlib-inline >=0.1 - - nest-asyncio2 >=1.7.0 - - packaging >=22 - - psutil >=5.7 - - python >=3.10 - - pyzmq >=25 - - tornado >=6.4.1 - - traitlets >=5.4.0 - - python - constrains: - - appnope >=0.1.2 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipykernel?source=hash-mapping - size: 138046 - timestamp: 1781101760172 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.17.0-pyhe2676ad_0.conda - sha256: de5052db34cd414d5993dc7330c7f9ce422fadd6e5f3c1422d48040e0319c633 - md5: c2cf78253e434f1283cfd276ec9abd2f - depends: - - __win - - ipython_pygments_lexers >=1.0.0 - - jedi >=0.18.2 - - matplotlib-inline >=0.1.6 - - prompt-toolkit >=3.0.41,<3.1.0 - - psutil >=7 - - pygments >=2.14.0 - - python >=3.11 - - stack_data >=0.6.0 - - traitlets >=5.13.0 - - typing_extensions >=4.6 - - colorama >=0.4.4 - - python - license: BSD-3-Clause - purls: - - pkg:pypi/ipython?source=compressed-mapping - size: 729408 - timestamp: 1787921907454 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - sha256: 894682a42a7d659ae12878dbcb274516a7031bbea9104e92f8e88c1f2765a104 - md5: bd80ba060603cc228d9d81c257093119 - depends: - - pygments - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipython-pygments-lexers?source=hash-mapping - size: 13993 - timestamp: 1737123723464 -- conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda - sha256: 08e838d29c134a7684bca0468401d26840f41c92267c4126d7b43a6b533b0aed - md5: 0b0154421989637d424ccf0f104be51a - depends: - - arrow >=0.15.0 - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/isoduration?source=hash-mapping - size: 19832 - timestamp: 1733493720346 -- conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.20.0-pyhcf101f3_0.conda - sha256: 744143551c1c7b528b82533fb641b9d7db20b2203abc4c2635c387fa6c089fc3 - md5: c2b3d37aa1411031126036ee76a8a861 - depends: - - python >=3.10 - - parso >=0.8.6,<0.9.0 - - python - license: Apache-2.0 AND MIT - purls: - - pkg:pypi/jedi?source=hash-mapping - size: 2715215 - timestamp: 1782251948616 -- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda - sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b - md5: 04558c96691bed63104678757beb4f8d - depends: - - markupsafe >=2.0 - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jinja2?source=hash-mapping - size: 120685 - timestamp: 1764517220861 -- conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.15.0-pyhd8ed1ab_0.conda - sha256: 637400a4174880463985c7a5b6e3e0bea0aa9d0892a6c06a3a8aa2cf1208c35a - md5: 761a4a6b9cba303c66a97ca642447171 - depends: - - python >=3.10 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/json5?source=hash-mapping - size: 39373 - timestamp: 1781926894833 -- 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=hash-mapping - size: 14190 - timestamp: 1774311356147 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_1.conda - sha256: 328756a4555941d57af4a5f553e5d8598e9f3b37db028f557e30f9f0b3086db6 - md5: 204b5ca91eba7738790ecc333facbbbe - depends: - - attrs >=22.2.0 - - jsonschema-specifications >=2023.3.6 - - python >=3.10 - - referencing >=0.28.4 - - rpds-py >=0.25.0 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/jsonschema?source=compressed-mapping - size: 82084 - timestamp: 1787579299493 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda - sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 - md5: 439cd0f567d697b20a8f45cb70a1005a - depends: - - python >=3.10 - - referencing >=0.31.0 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/jsonschema-specifications?source=hash-mapping - size: 19236 - timestamp: 1757335715225 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_1.conda - sha256: 1b8ed25276ceae973e21d269fbe11f08d0b5f73c7ac9584e2d6a9dd763b8707a - md5: ae36c895b9e25a127d2acbdbaa87e301 - depends: - - jsonschema >=4.26.0,<4.26.1.0a0 - - fqdn - - idna - - isoduration - - jsonpointer >1.13 - - rfc3339-validator - - rfc3986-validator >0.1.0 - - rfc3987-syntax >=1.1.0 - - uri-template - - webcolors >=24.6.0 - license: MIT - license_family: MIT - purls: [] - size: 4809 - timestamp: 1787579299493 -- pypi: https://files.pythonhosted.org/packages/37/86/d45756beaeb4b9b06125599b429451f8640b5db6f019d606f33c85743fd4/jupyter_book-1.0.4.post1-py3-none-any.whl - name: jupyter-book - version: 1.0.4.post1 - sha256: 3a27a6b2581f1894ffe8f347d1a3432f06fc616997547919c42cd41c54db625d - requires_dist: - - click>=7.1,<9 - - jinja2 - - jsonschema<5 - - linkify-it-py>=2,<3 - - myst-nb~=1.0 - - myst-parser~=3.0 - - pyyaml - - sphinx-book-theme~=1.1 - - sphinx-comments~=0.0 - - sphinx-copybutton~=0.5 - - sphinx-design~=0.6 - - sphinx-external-toc~=1.0 - - sphinx-jupyterbook-latex~=1.0 - - sphinx-multitoc-numbering~=0.1 - - sphinx-thebe~=0.3 - - sphinx-togglebutton~=0.3 - - sphinxcontrib-bibtex~=2.5 - - sphinx~=7.0 - - pre-commit~=3.1 ; extra == 'code-style' - - playwright ; extra == 'pdfhtml' - - altair ; extra == 'sphinx' - - bokeh ; extra == 'sphinx' - - folium ; extra == 'sphinx' - - ipywidgets ; extra == 'sphinx' - - jupytext ; extra == 'sphinx' - - matplotlib ; extra == 'sphinx' - - nbclient ; extra == 'sphinx' - - numpy>=2 ; extra == 'sphinx' - - pandas ; extra == 'sphinx' - - plotly ; extra == 'sphinx' - - sphinx-click ; extra == 'sphinx' - - sphinx-examples ; extra == 'sphinx' - - sphinx-inline-tabs ; extra == 'sphinx' - - sphinx-proof ; extra == 'sphinx' - - sphinxext-rediraffe~=0.2.3 ; extra == 'sphinx' - - sympy ; extra == 'sphinx' - - altair ; extra == 'testing' - - beautifulsoup4 ; extra == 'testing' - - cookiecutter ; extra == 'testing' - - coverage ; extra == 'testing' - - jupytext ; extra == 'testing' - - matplotlib ; extra == 'testing' - - numpy>=2 ; extra == 'testing' - - pandas ; extra == 'testing' - - playwright ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - pytest-timeout ; extra == 'testing' - - pytest-xdist ; extra == 'testing' - - pytest>=6.2.4 ; extra == 'testing' - - sphinx-click ; extra == 'testing' - - sphinx-inline-tabs ; extra == 'testing' - - texsoup ; extra == 'testing' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-builder-1.2.2-pyhcf101f3_0.conda - sha256: 46777dd25ae623f960ec9ed9eae44cc7f96f371f3bc96f85d3ebf95737bd4e88 - md5: 9672806e67ea8b09a61408597a418e20 - depends: - - jupyter_core - - python >=3.10 - - tomli - - traitlets - - python - constrains: - - nodejs >=22 - license: BSD-3-Clause AND MIT AND ISC - purls: - - pkg:pypi/jupyter-builder?source=compressed-mapping - size: 862197 - timestamp: 1786385602872 -- pypi: https://files.pythonhosted.org/packages/64/6b/67b87da9d36bff9df7d0efbd1a325fa372a43be7158effaf43ed7b22341d/jupyter_cache-1.0.1-py3-none-any.whl - name: jupyter-cache - version: 1.0.1 - sha256: 9c3cafd825ba7da8b5830485343091143dff903e4d8c69db9349b728b140abf6 - requires_dist: - - attrs - - click - - importlib-metadata - - nbclient>=0.2 - - nbformat - - pyyaml - - sqlalchemy>=1.3.12,<3 - - tabulate - - click-log ; extra == 'cli' - - pre-commit>=2.12 ; extra == 'code-style' - - nbdime ; extra == 'rtd' - - ipykernel ; extra == 'rtd' - - jupytext ; extra == 'rtd' - - myst-nb ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - sphinx-copybutton ; extra == 'rtd' - - nbdime ; extra == 'testing' - - coverage ; extra == 'testing' - - ipykernel ; extra == 'testing' - - jupytext ; extra == 'testing' - - matplotlib ; extra == 'testing' - - nbformat>=5.1 ; extra == 'testing' - - numpy ; extra == 'testing' - - pandas ; extra == 'testing' - - pytest>=6 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - sympy ; extra == 'testing' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda - sha256: 3766e2ae59641c172cec8a821528bfa6bf9543ffaaeb8b358bfd5259dcf18e4e - md5: 0c3b465ceee138b9c39279cc02e5c4a0 - depends: - - importlib-metadata >=4.8.3 - - jupyter_server >=1.1.2 - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyter-lsp?source=hash-mapping - size: 61633 - timestamp: 1775136333147 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.10.0-pyhcf101f3_0.conda - sha256: 94f11bbdbac51a68415fb0a8bb441fb3475c0138e778664a3fb48f5698688ebf - md5: 85130259a26c023f53108dc9ab1cfb44 - depends: - - jupyter_core >=5.1 - - python >=3.10 - - python-dateutil >=2.8.2 - - pyzmq >=25.0 - - tornado >=6.4.1 - - traitlets >=5.3 - - typing_extensions >=4.13.0 - - python - license: BSD-3-Clause - purls: - - pkg:pypi/jupyter-client?source=compressed-mapping - size: 118962 - timestamp: 1787929615607 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda - sha256: ed709a6c25b731e01563521ef338b93986cd14b5bc17f35e9382000864872ccc - md5: a8db462b01221e9f5135be466faeb3e0 - depends: - - __win - - pywin32 - - platformdirs >=2.5 - - python >=3.10 - - traitlets >=5.3 - - python - constrains: - - pywin32 >=300 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyter-core?source=hash-mapping - size: 64679 - timestamp: 1760643889625 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda - sha256: c7edb5682c6316a95ad781dccb1b6589cd2ec0bf94f23c21152974eb0363b5d7 - md5: bf42ee94c750c0b2e7e998b79ac299ea - depends: - - jsonschema-with-format-nongpl >=4.18.0 - - packaging - - python >=3.10 - - python-json-logger >=2.0.4 - - pyyaml >=5.3 - - referencing - - rfc3339-validator - - rfc3986-validator >=0.1.1 - - traitlets >=5.3 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyter-events?source=hash-mapping - size: 24002 - timestamp: 1776861872237 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.21.0-pyhcf101f3_0.conda - sha256: fa26acd3777095662c34cbbcfacad163a3a17c90a935f9357fe511c975c8241f - md5: b6163da641d1f178977dd36aebced0d5 - depends: - - anyio >=3.1.0 - - argon2-cffi >=21.1 - - jinja2 >=3.0.3 - - jupyter_client >=7.4.4 - - jupyter_core >=4.12,!=5.0.* - - jupyter_events >=0.11.0 - - jupyter_server_terminals >=0.4.4 - - nbconvert-core >=6.4.4 - - nbformat >=5.3.0 - - overrides >=5.0 - - packaging >=22.0 - - prometheus_client >=0.9 - - python >=3.10 - - pyzmq >=24 - - send2trash >=1.8.2 - - terminado >=0.8.3 - - tornado >=6.2.0 - - traitlets >=5.6.0 - - websocket-client >=1.7 - - python - license: BSD-3-Clause - purls: - - pkg:pypi/jupyter-server?source=compressed-mapping - size: 365818 - timestamp: 1787864637286 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda - sha256: 5eda79ed9f53f590031d29346abd183051263227dd9ee667b5ca1133ce297654 - md5: 7b8bace4943e0dc345fc45938826f2b8 - depends: - - python >=3.10 - - terminado >=0.8.3 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyter-server-terminals?source=hash-mapping - size: 22052 - timestamp: 1768574057200 -- pypi: https://files.pythonhosted.org/packages/f6/54/af203c61a0550c232ed5e859d2c98f3fe80d1248b6ea1c4d4d5621fa08c9/jupyterbook_patches-1.15.0-py3-none-any.whl - name: jupyterbook-patches - version: 1.15.0 - sha256: 87da7e97fa0e1f3e8de87c6dba6c1c69f8a7940aa19faa1aa16c78656ad90107 - requires_dist: - - pyyaml - - sphinx - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.6.3-pyhd8ed1ab_0.conda - sha256: dabfff705b000188a9f67c9af68bb607cdb2e46fd7c6283307a502994c2af46f - md5: e5527f195a1a1925b9207e9d47752480 - depends: - - async-lru >=1.0.0 - - httpx >=0.25.0,<1 - - ipykernel >=6.5.0,!=6.30.0 - - jinja2 >=3.0.3 - - jupyter-builder >=1.0.2 - - jupyter-lsp >=2.0.0 - - jupyter_core - - jupyter_server >=2.19.0,<3 - - jupyterlab_server >=2.28.0,<3 - - notebook-shim >=0.2 - - packaging >=23.2 - - python >=3.10 - - tomli >=1.2.2 - - tornado >=6.2.0 - - traitlets - - typing_extensions >=4.4.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyterlab?source=compressed-mapping - size: 13178193 - timestamp: 1786398793317 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - sha256: dc24b900742fdaf1e077d9a3458fd865711de80bca95fe3c6d46610c532c6ef0 - md5: fd312693df06da3578383232528c468d - depends: - - pygments >=2.4.1,<3 - - python >=3.9 - constrains: - - jupyterlab >=4.0.8,<5.0.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyterlab-pygments?source=hash-mapping - size: 18711 - timestamp: 1733328194037 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - sha256: 381d2d6a259a3be5f38a69463e0f6c5dcf1844ae113058007b51c3bef13a7cee - md5: a63877cb23de826b1620d3adfccc4014 - depends: - - babel >=2.10 - - jinja2 >=3.0.3 - - json5 >=0.9.0 - - jsonschema >=4.18 - - jupyter_server >=1.21,<3 - - packaging >=21.3 - - python >=3.10 - - requests >=2.31 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyterlab-server?source=hash-mapping - size: 51621 - timestamp: 1761145478692 -- conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.1-py314hf309875_0.conda - sha256: b34910eacb872a9b9b55318fd12332954e64b42dbc710f6a384e0500a58a2d7a - md5: 842f2582140b5567bcad1defbbd9b948 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.14.* *_cp314 - license: BSD-3-Clause - purls: - - pkg:pypi/kiwisolver?source=compressed-mapping - size: 73212 - timestamp: 1787938458524 -- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h719d79b_2.conda - sha256: 63ff03324e903eb01a715ccf357df56d66224e61952fd6615d86490ebefb3285 - md5: 93f5a01dec294a2228f757fe2f3432d4 - depends: - - openssl >=3.5.7,<4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 753425 - timestamp: 1786762169034 -- conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - sha256: 49570840fb15f5df5d4b4464db8ee43a6d643031a2bc70ef52120a52e3809699 - md5: 9b965c999135d43a3d0f7bd7d024e26a - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/lark?source=hash-mapping - size: 94312 - timestamp: 1761596921009 -- pypi: https://files.pythonhosted.org/packages/b5/40/23569737873cc9637fd488606347e9dd92b9fa37ba4fcda1f98ee5219a97/latexcodec-3.0.1-py3-none-any.whl - name: latexcodec - version: 3.0.1 - sha256: a9eb8200bff693f0437a69581f7579eb6bca25c4193515c09900ce76451e452e - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19.1-hf2c6c5f_1.conda - sha256: 5ed63a32639a130564a870becb679fd52dfb816666a61ed3c023917389010480 - md5: 1df4012c8a2478699d07bc26af66d41e - depends: - - libjpeg-turbo >=3.1.4.1,<4.0a0 - - libtiff >=4.7.1,<4.8.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 523194 - timestamp: 1780211799997 -- conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.2.0-hd936e49_0.conda - sha256: 93d666f63f284ef77b87b0b1f77b70f7d36d315a132f9afa64bc0012d937ba39 - md5: add59e2b60ac9d4299d17c938185c75a - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 175297 - timestamp: 1785036247761 -- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-9_h8455456_mkl.conda - build_number: 9 - sha256: a99c640f10a3f77efe5c6605676ddc8d365d020eec4fdf1c803d34bdaf49b357 - md5: 17b26a4ad064259983bec1eaa36f40d3 - depends: - - mkl >=2026.1.0,<2027.0a0 - constrains: - - blas 2.309 mkl - - libcblas 3.11.0 9*_mkl - - liblapack 3.11.0 9*_mkl - - liblapacke 3.11.0 9*_mkl - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 67235 - timestamp: 1786059219098 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hf02afa3_3.conda - sha256: c739589318a1f8a88cd1b66d385176fd1ec2c4609e9f90d23d748be94b547e4e - md5: 8ef4beb3cb18e1a876b9af9a757cc1a5 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 82655 - timestamp: 1786622832371 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-h84f9c24_3.conda - sha256: f4bdb7ec97c3122e531fc867efae5ec928b649d047aa70d42893f0d8eb110fd9 - md5: 10c479888ee4e960587967b2d0c8143a - depends: - - libbrotlicommon 1.2.0 hf02afa3_3 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 34788 - timestamp: 1786622843818 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-he2a975b_3.conda - sha256: c5e638ea9704c94b316238b425a3439ba38d4d8fba81682842e6d7d464472848 - md5: cb5d08dc81f52e87c27914b5636cd995 - depends: - - libbrotlicommon 1.2.0 hf02afa3_3 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 253894 - timestamp: 1786622854214 -- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-9_h2a3cdd5_mkl.conda - build_number: 9 - sha256: 8c20714bbb85c8a109e9002e76c32be64a82d9867beb1a35a20c85258cc2b535 - md5: 9d1d0c22e9ed8c31ec2efc0d063d6f48 - depends: - - libblas 3.11.0 9_h8455456_mkl - constrains: - - blas 2.309 mkl - - liblapack 3.11.0 9*_mkl - - liblapacke 3.11.0 9*_mkl - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 67587 - timestamp: 1786059232952 -- conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-23.1.0-default_hacd6ee9_0.conda - sha256: f81e6a24e7eb670cf216c44028f789426b732ce68731b349cae98dec3a59f573 - md5: 88280be6f61caad069624d936b719641 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - llvm-openmp >=23.1.0 - - libxml2 - - libxml2-16 >=2.15.3 - - libzlib >=1.3.2,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: APACHE - purls: [] - size: 37510825 - timestamp: 1787735065635 -- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h1a1d4e4_1.conda - sha256: af1cda21d4653f594fbef20aa4e1ff158a546902b3307ef8af9a9b44b43862d2 - md5: e4e122e124676a49eebf241399ad8393 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 157828 - timestamp: 1785908793271 -- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda - sha256: 1a54d874addda73b6f7164d5f3905821277a1831bcc05edd74b3085391688571 - md5: ccc490c81ffe14181861beac0e8f3169 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - expat 2.8.1.* - license: MIT - license_family: MIT - purls: [] - size: 71631 - timestamp: 1781203724164 -- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda - sha256: 613e8077c5cca5df7fe84ade7d5050301bee3c6c4c450ffe61d34a349ab4f11c - md5: ceb38b0ba900847d8da4289c3c8e5708 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 49992 - timestamp: 1787753517346 -- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_2.conda - sha256: d794d7fddb6eea50e18a62fa27ab3819f40d51bad00b90cf4ca591fb0d4006c2 - md5: 740f99c3c91079c03874b809fedace1b - depends: - - libfreetype6 >=2.14.3 - license: GPL-2.0-only OR FTL - purls: [] - size: 8742 - timestamp: 1786641045882 -- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_2.conda - sha256: cbc650854003e434d4ff6c7b1a2667e38a4242ad8a391a1c5ff89721624065ce - md5: 8157483eb7ed3fcba71aad3b50a97131 - depends: - - libpng >=1.6.58,<1.7.0a0 - - libzlib >=1.3.2,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - freetype >=2.14.3 - license: GPL-2.0-only OR FTL - purls: [] - size: 340385 - timestamp: 1786641044865 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-16.2.0-h110b43a_4.conda - sha256: 32c0d1adcc96835d5f681c7e72b7f5e2e30088149239e002b8a6f581a072e1d2 - md5: 02793cf48b68687fee158a48c92850a6 - depends: - - _openmp_mutex >=4.5 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - constrains: - - libgcc-ng ==16.2.0=*_4 - - libgomp 16.2.0 h8ee18e1_4 - - msys2-conda-epoch <0.0a0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 826694 - timestamp: 1787625780171 -- conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.3-he810d59_2.conda - sha256: 001620bac27dbf6daa25e5cd52970749fe2bc02a26649b0ad516d26609f6bcae - md5: e40bcfee79dbfda3eff751ed098b6ad3 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - pcre2 >=10.47,<10.48.0a0 - - libiconv >=1.18,<2.0a0 - - libzlib >=1.3.2,<2.0a0 - - libffi >=3.7.0,<3.8.0a0 - - libintl >=0.22.5,<1.0a0 - constrains: - - glib >2.66 - license: LGPL-2.1-or-later - purls: [] - size: 4519014 - timestamp: 1787884093942 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-16.2.0-h8ee18e1_4.conda - sha256: 9ef1a22fb50b31fbf9c01cf709e8f55b60fd3c02401d150be4a55943f9e3832f - md5: 91189f0bc9ff21f385fcda6232346612 - depends: - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - constrains: - - msys2-conda-epoch <0.0a0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 688168 - timestamp: 1787625720312 -- conda: https://conda.anaconda.org/conda-forge/win-64/libharfbuzz-14.4.0-h03b5201_0.conda - sha256: 08713208fd7e2e6f2ccde1fc09765f2585d5cc809d187865fd9190ddad271f3d - md5: 4618efa4303fdda115da50b8090d73c6 - depends: - - cairo >=1.18.4,<2.0a0 - - graphite2 >=1.3.15,<2.0a0 - - icu >=78.3,<79.0a0 - - libexpat >=2.8.1,<3.0a0 - - libfreetype >=2.14.3 - - libfreetype6 >=2.14.3 - - libglib >=2.88.3,<3.0a0 - - libpng >=1.6.58,<1.7.0a0 - - libzlib >=1.3.2,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 1053822 - timestamp: 1787795353946 -- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.13.0-default_h049141e_1000.conda - sha256: 2ee12e37223dfcd0acd050c80a91150c482b6e2899198521e1800dce66662467 - md5: 6a01c986e30292c715038d2788aa1385 - 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: 2396128 - timestamp: 1770954127918 -- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_3.conda - sha256: 35e04e3ddac7720fc7c550a1c9f998604299d6a7bd1f3ec9b2825d825061daa2 - md5: a8a2abdf0f901bc4779d9b7be0845921 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: LGPL-2.1-only - purls: [] - size: 694899 - timestamp: 1787033851701 -- conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_4.conda - sha256: 85b50be2209f3b8a873830ec9894477d260f4c7ba9540e65959f5812bf7219f8 - md5: 36d6e0045173974521fabd42bd5033d6 - depends: - - libiconv >=1.18,<2.0a0 - license: LGPL-2.1-or-later - purls: [] - size: 96669 - timestamp: 1787841116808 -- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.2.0-hfd05255_1.conda - sha256: df78ab4c0eecb3dd9331898f96baeed8e5ca1c363346332517abeb0b614b9a53 - md5: fc2c23bacefd1e733f1e1d6cd3b2aaeb - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - jpeg <0.0.0a - license: IJG AND BSD-3-Clause AND Zlib - purls: [] - size: 990125 - timestamp: 1785896494014 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-9_hf9ab0e9_mkl.conda - build_number: 9 - sha256: 62d0a7a70ee13c554d5d7ff94a2ba758c4111439822dcc81324dd4cfaf576071 - md5: bee6f13ab945c4034bdd0f722ad14dd5 - depends: - - libblas 3.11.0 9_h8455456_mkl - constrains: - - blas 2.309 mkl - - libcblas 3.11.0 9*_mkl - - liblapacke 3.11.0 9*_mkl - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 79963 - timestamp: 1786059243440 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda - sha256: d36c4a1e1f80fd08e18a407e03622ff2f34dfdd022da6488ad19603dea19e6d5 - md5: 880a0c8549479b198af21ba5dc49b109 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - xz 5.8.3.* - license: 0BSD - purls: [] - size: 105809 - timestamp: 1786348717883 -- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda - sha256: f07e451de3db1836b87f7aedf95c8e65cdb06c0e6105329ba24bb5f7b5c75e2a - md5: 5ae92fd6614edd024576e14069d7ad4c - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 89109 - timestamp: 1786650384519 -- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-hdc8cecf_1.conda - sha256: 8c49c32adf3ba2c59783630b82377f54ab72204ea99e2bafc90a47a8e25c1032 - md5: 5aa7348e73691187c81d51616f17e48a - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libzlib >=1.3.2,<2.0a0 - license: zlib-acknowledgement - purls: [] - size: 385462 - timestamp: 1786616543374 -- conda: https://conda.anaconda.org/conda-forge/win-64/libpython-3.14.7-h4f90d01_101_cp314.conda - build_number: 101 - sha256: 9c9056d4eaf2dee22584e9565248bc07e2e8177e0dd36263d4e21c3a17033fe9 - md5: cfc9859a0f5b5a45bc6abbed2560bdfc - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Python-2.0 - purls: [] - size: 51243 - timestamp: 1787780843281 -- conda: https://conda.anaconda.org/conda-forge/win-64/libraqm-0.11.0-h50d6d30_0.conda - sha256: 1bc52f781355e233411a7aaebbb155d9fd53efa2a1fc6c621250833d80cc5ab1 - md5: df92be5685f712989830bdb7ee39383a - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libharfbuzz >=14.2.1 - - libfreetype >=2.14.3 - - libfreetype6 >=2.14.3 - - fribidi >=1.0.16,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 33471 - timestamp: 1784850324004 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.22-h6a83c73_2.conda - sha256: 7dc8d243cc8bcd12d1666640664288822eda5d30411a0b22ff05090bbac4c32b - md5: 2a001157df8205a7785ea69dd3270a8f - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: ISC - purls: [] - size: 280204 - timestamp: 1787225747847 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda - sha256: 0a45d7c0f20146fff787a106f8fa187872e309c70975ff8f0936e188914c26ad - md5: a72d495965b144bb7da033642d389047 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: blessing - purls: [] - size: 1314919 - timestamp: 1787051140039 -- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.2-h8f73337_1.conda - sha256: 3575a092e3e52625a1767804a4ebd321becaadf61b63dcd6735ebb88c0b3c359 - md5: 970dbe48f843e7fbd179a9b6c22f865a - depends: - - lerc >=4.2.0,<5.0a0 - - libdeflate >=1.25,<1.26.0a0 - - libjpeg-turbo >=3.2.0,<4.0a0 - - liblzma >=5.8.3,<6.0a0 - - libzlib >=1.3.2,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - zstd >=1.5.7,<1.6.0a0 - license: HPND - purls: [] - size: 1014211 - timestamp: 1787755773611 -- conda: https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.357.0-h477610d_2.conda - sha256: 4b094443126c5fc38d200eb0ea335b67e64d966d7aa737bb3141217a787b0c73 - md5: aaeed7feddbfd7454f8853a5eae8d902 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - constrains: - - libvulkan-headers 1.4.357.0.* - license: Apache-2.0 - license_family: APACHE - purls: [] - size: 288787 - timestamp: 1787491929908 -- conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_1.conda - sha256: 4470d98d3178b0d45492eed4808afe421d2e7808352b8d06c2dc29166b75d94d - md5: 35a9475e4cc999d52921f57c181979fc - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - libwebp 1.6.0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 278886 - timestamp: 1785954716703 -- 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/win-64/libxcb-1.17.0-h874e120_2.conda - sha256: f5932cbcadb67bef9374ee864fed72411af29e88690435c6c7fc5633c89dabee - md5: 3658b0201b32da9607ea5e3c1c463c1f - depends: - - libgcc >=13 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - pthread-stubs - - ucrt >=10.0.20348.0 - - xorg-libxau >=1.0.12,<2.0a0 - - xorg-libxdmcp >=1.1.5,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 1215534 - timestamp: 1787886015478 -- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_1.conda - sha256: a83e9adcf7c50f20289dc6890707c8e4e84151b4204b0f7344998138807458d1 - md5: 45a5a1c709a69f14cf176220788d18a9 - depends: - - icu >=78.3,<79.0a0 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.3,<6.0a0 - - libxml2-16 2.15.3 h3cfd58e_1 - - libzlib >=1.3.2,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 43610 - timestamp: 1787237661577 -- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_1.conda - sha256: 8163de24a7ddb4ebf9587c3a45ba950caf3690b9646b76f007ca15e6e52b5881 - md5: 6e7dadff3f3bde2d29d29a3ec34f2d58 - depends: - - icu >=78.3,<79.0a0 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.3,<6.0a0 - - libzlib >=1.3.2,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - libxml2 2.15.3 - license: MIT - license_family: MIT - purls: [] - size: 519962 - timestamp: 1787237653321 -- conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda - sha256: 13da38939c2c20e7112d683ab6c9f304bfaf06230a2c6a7cf00359da1a003ec7 - md5: 46034d9d983edc21e84c0b36f1b4ba61 - depends: - - libxml2 - - libxml2-16 >=2.14.6 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 420223 - timestamp: 1757963935611 -- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda - sha256: 0629c2cc0404d3bb29d6baa7b4ba62da80797015e86de050db81ea5a07050527 - md5: 5d2ff29d465097458cc3ff6569151991 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - zlib 1.3.2 *_3 - license: Zlib - license_family: Other - purls: [] - size: 58529 - timestamp: 1785276664143 -- pypi: https://files.pythonhosted.org/packages/eb/3d/e34b19cd144071c583317268c4feb2c59c03ac57eef69753410c7abb11c0/linkify_it_py-2.1.1-py3-none-any.whl - name: linkify-it-py - version: 2.1.1 - sha256: 8539a6b470efce90ba9b69e39b848e5b15b7ad89f7f98ca17d3532c243f987dc - requires_dist: - - uc-micro-py - - pytest ; extra == 'test' - - coverage ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pre-commit ; extra == 'dev' - - isort ; extra == 'dev' - - flake8 ; extra == 'dev' - - black ; extra == 'dev' - - pyproject-flake8 ; extra == 'dev' - - pytest ; extra == 'benchmark' - - pytest-benchmark ; extra == 'benchmark' - - sphinx ; extra == 'doc' - - sphinx-book-theme ; extra == 'doc' - - myst-parser ; extra == 'doc' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-23.1.0-h49e36cd_0.conda - sha256: f9658ec83a6744f38e2b8188c76e1c2dea2614f5aa0e14d9d274b19f60646b8c - md5: 79055ec79e1b43749763122cead30976 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - intel-openmp <0.0a0 - - openmp 23.1.0|23.1.0.* - license: Apache-2.0 WITH LLVM-exception - license_family: APACHE - purls: [] - size: 342468 - timestamp: 1787722783678 -- pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - name: markdown-it-py - version: 3.0.0 - sha256: 355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 - requires_dist: - - mdurl~=0.1 - - psutil ; extra == 'benchmarking' - - pytest ; extra == 'benchmarking' - - pytest-benchmark ; extra == 'benchmarking' - - pre-commit~=3.0 ; extra == 'code-style' - - commonmark~=0.9 ; extra == 'compare' - - markdown~=3.4 ; extra == 'compare' - - mistletoe~=1.0 ; extra == 'compare' - - mistune~=2.0 ; extra == 'compare' - - panflute~=2.3 ; extra == 'compare' - - linkify-it-py>=1,<3 ; extra == 'linkify' - - mdit-py-plugins ; extra == 'plugins' - - gprof2dot ; extra == 'profiling' - - mdit-py-plugins ; extra == 'rtd' - - myst-parser ; extra == 'rtd' - - pyyaml ; extra == 'rtd' - - sphinx ; extra == 'rtd' - - sphinx-copybutton ; extra == 'rtd' - - sphinx-design ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - jupyter-sphinx ; extra == 'rtd' - - coverage ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py314h2359020_1.conda - sha256: 02805a0f3cd168dbf13afc5e4aed75cc00fe538ce143527a6471485b36f5887c - md5: 8de7b40f8b30a8fcaa423c2537fe4199 - 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: - - jinja2 >=3.0.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 30022 - timestamp: 1772445159549 -- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.11.1-py314h30c6bc1_2.conda - sha256: 3599b3ae70c4fd210e83d3e04920b70e763a3c3cc6a589f7a46776a339cf79c0 - md5: d8f7f4bb221698dda04dd955eb6f7e52 - depends: - - matplotlib-base >=3.11.1,<3.11.2.0a0 - - pyside6 >=6.7.2 - - python >=3.14,<3.15.0a0 - - python_abi 3.14.* *_cp314 - - tornado >=5 - license: PSF-2.0 - license_family: PSF - purls: [] - size: 15333 - timestamp: 1785211311397 -- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.11.1-py314h2061cd4_2.conda - sha256: b3f19b71ea556c79b67a599929a4c05618fd4ae03d7412e65adc95ec627670c5 - md5: 88c095cee1bcd48178328c93920870a2 - depends: - - contourpy >=1.0.1 - - cycler >=0.10 - - fonttools >=4.28.2 - - freetype - - kiwisolver >=1.3.1 - - libfreetype >=2.14.3 - - libfreetype6 >=2.14.3 - - libraqm >=0.11.0,<0.12.0a0 - - numpy >=1.25 - - numpy >=1.25,<3 - - packaging >=20.0 - - pillow >=9 - - pyparsing >=3 - - python >=3.14,<3.15.0a0 - - python-dateutil >=2.7 - - python_abi 3.14.* *_cp314 - - qhull >=2020.2,<2020.3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/matplotlib?source=hash-mapping - size: 8810362 - timestamp: 1785211292854 -- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.2-pyhd8ed1ab_0.conda - sha256: 35b43d7343f74452307fd018a1cca92b8f68961ff8e2ab6a81ce0a703c9a3764 - md5: 9acc1c385be401d533ff70ef5b50dae6 - depends: - - python >=3.10 - - traitlets - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/matplotlib-inline?source=hash-mapping - size: 15725 - timestamp: 1778264403247 -- pypi: https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-py3-none-any.whl - name: mdit-py-plugins - version: 0.6.1 - sha256: 214c82fb2ac524472ab6a5bcab1de80f73b50443e187f401bfd77efbc7c6481d - requires_dist: - - markdown-it-py>=2.0.0,<5.0.0 - - pre-commit ; extra == 'code-style' - - myst-parser ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - coverage ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - pytest-timeout ; 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/noarch/mistune-3.3.4-pyhcf101f3_0.conda - sha256: 306af633cb4ac85d04024d7c243ac2031c488bf5b0912207e7304c27a5d65a85 - md5: 1c0ebec41ef9214160da1ee6a0880fce - depends: - - python >=3.10 - - typing_extensions - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/mistune?source=hash-mapping - size: 93811 - timestamp: 1784722859728 -- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2026.1.0-hac47afa_235.conda - sha256: bb8abe071f73765446df62924031e6599577e8ac9003264dc4569e78c0fea16d - md5: ace316c48c178d7faa403dee51e30c7b - depends: - - llvm-openmp >=22.1.8 - - tbb >=2023.0.0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: LicenseRef-IntelSimplifiedSoftwareOct2022 - license_family: Proprietary - purls: [] - size: 114686732 - timestamp: 1787725739779 -- conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - sha256: d09c47c2cf456de5c09fa66d2c3c5035aa1fa228a1983a433c47b876aa16ce90 - md5: 37293a85a0f4f77bbd9cf7aaefc62609 - depends: - - python >=3.9 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/munkres?source=hash-mapping - size: 15851 - timestamp: 1749895533014 -- pypi: https://files.pythonhosted.org/packages/94/93/0a378b48488879a1d925b42a804edfc6e0cd0ef854220f2dce738a46e7e9/myst_nb-1.4.0-py3-none-any.whl - name: myst-nb - version: 1.4.0 - sha256: 0e2c86e7d3b82c3aa51383f82d6268f7714f3b772c23a796ab09538a8e68b4e4 - requires_dist: - - importlib-metadata - - ipython - - jupyter-cache>=0.5 - - nbclient - - myst-parser>=1.0.0 - - nbformat>=5.0 - - pyyaml - - sphinx>=5 - - typing-extensions - - ipykernel - - pre-commit ; extra == 'code-style' - - alabaster ; extra == 'rtd' - - altair ; extra == 'rtd' - - bokeh ; extra == 'rtd' - - coconut>=1.4.3 ; extra == 'rtd' - - ipykernel>=5.5 ; extra == 'rtd' - - ipywidgets ; extra == 'rtd' - - jupytext>=1.11.2 ; extra == 'rtd' - - matplotlib ; extra == 'rtd' - - numpy ; extra == 'rtd' - - pandas ; extra == 'rtd' - - plotly ; extra == 'rtd' - - sphinx-book-theme>=0.3 ; extra == 'rtd' - - sphinx-copybutton ; extra == 'rtd' - - sphinx-design ; extra == 'rtd' - - sphinxcontrib-bibtex ; extra == 'rtd' - - sympy ; extra == 'rtd' - - sphinx-autodoc-typehints ; extra == 'rtd' - - coverage>=6.4 ; extra == 'testing' - - beautifulsoup4 ; extra == 'testing' - - ipykernel>=5.5 ; extra == 'testing' - - ipython!=8.1.0 ; extra == 'testing' - - ipywidgets>=8 ; extra == 'testing' - - jupytext>=1.11.2 ; extra == 'testing' - - matplotlib==3.10.7 ; extra == 'testing' - - nbdime ; extra == 'testing' - - numpy ; extra == 'testing' - - pandas ; extra == 'testing' - - pyarrow ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov>=3 ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - pytest-param-files ; extra == 'testing' - - sympy>=1.10.1 ; extra == 'testing' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl - name: myst-parser - version: 3.0.1 - sha256: 6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1 - requires_dist: - - docutils>=0.18,<0.22 - - jinja2 - - markdown-it-py~=3.0 - - mdit-py-plugins~=0.4 - - pyyaml - - sphinx>=6,<8 - - pre-commit~=3.0 ; extra == 'code-style' - - linkify-it-py~=2.0 ; extra == 'linkify' - - sphinx>=7 ; extra == 'rtd' - - ipython ; extra == 'rtd' - - sphinx-book-theme~=1.1 ; extra == 'rtd' - - sphinx-design ; extra == 'rtd' - - sphinx-copybutton ; extra == 'rtd' - - sphinxext-rediraffe~=0.2.7 ; extra == 'rtd' - - sphinxext-opengraph~=0.9.0 ; extra == 'rtd' - - sphinx-pyscript ; extra == 'rtd' - - sphinx-tippy>=0.4.3 ; extra == 'rtd' - - sphinx-autodoc2~=0.5.0 ; extra == 'rtd' - - sphinx-togglebutton ; extra == 'rtd' - - beautifulsoup4 ; extra == 'testing' - - coverage[toml] ; extra == 'testing' - - defusedxml ; extra == 'testing' - - pytest>=8,<9 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - pytest-param-files~=0.6.0 ; extra == 'testing' - - sphinx-pytest ; extra == 'testing' - - pygments ; extra == 'testing-docutils' - - pytest>=8,<9 ; extra == 'testing-docutils' - - pytest-param-files~=0.6.0 ; extra == 'testing-docutils' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.11.0-pyhd8ed1ab_0.conda - sha256: eceb424236fbbb9b337a857fe5448307b57a2a3fb2db389ae37e7a8b8cdca2ab - md5: cf01a81d7960ad9c829bf2e794fcee9a - depends: - - jupyter_client >=7.0.0 - - jupyter_core >=5.4 - - nbformat >=5.2.0 - - python >=3.10 - - traitlets >=5.13 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/nbclient?source=hash-mapping - size: 29138 - timestamp: 1780661039538 -- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - sha256: ab2ac79c5892c5434d50b3542d96645bdaa06d025b6e03734be29200de248ac2 - md5: 2bce0d047658a91b99441390b9b27045 - depends: - - beautifulsoup4 - - bleach-with-css !=5.0.0 - - defusedxml - - importlib-metadata >=3.6 - - jinja2 >=3.0 - - jupyter_core >=4.7 - - jupyterlab_pygments - - markupsafe >=2.0 - - mistune >=2.0.3,<4 - - nbclient >=0.5.0 - - nbformat >=5.7 - - packaging - - pandocfilters >=1.4.1 - - pygments >=2.4.1 - - python >=3.10 - - traitlets >=5.1 - - python - constrains: - - pandoc >=2.9.2,<4.0.0 - - nbconvert ==7.17.1 *_0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/nbconvert?source=hash-mapping - size: 202229 - timestamp: 1775615493260 -- conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.11.1-pyhcf101f3_0.conda - sha256: d85d76827ff732e1639f50f45e4d7d3387a27abd857b194dcbb5bb4166c2a7c2 - md5: 2fbbf92e1173ae024f0b12759c1e64a1 - depends: - - jsonschema >=2.6 - - jupyter_core >=4.12,!=5.0.* - - python >=3.10 - - python-fastjsonschema >=2.15 - - traitlets >=5.1 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/nbformat?source=compressed-mapping - size: 107750 - timestamp: 1787133512599 -- conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio2-1.7.2-pyhcf101f3_0.conda - sha256: e6768ceef038f4d7e083de7e393f5dd7d672b937e2bda570b740f6399b686689 - md5: fcd832bfd4749e9b246112b6894f97fc - depends: - - python >=3.10 - - python - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/nest-asyncio2?source=hash-mapping - size: 15903 - timestamp: 1770973502283 -- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - sha256: 7b920e46b9f7a2d2aa6434222e5c8d739021dbc5cc75f32d124a8191d86f9056 - md5: e7f89ea5f7ea9401642758ff50a2d9c1 - depends: - - jupyter_server >=1.8,<3 - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/notebook-shim?source=hash-mapping - size: 16817 - timestamp: 1733408419340 -- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.5.2-py314h02f10f6_0.conda - sha256: 14067f2c7628320708f73531c98c16753ee3991230c6ae32873baed911771b09 - md5: bd342de8875a168535a553191b405821 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libcblas >=3.9.0,<4.0a0 - - libblas >=3.9.0,<4.0a0 - - liblapack >=3.9.0,<4.0a0 - - python_abi 3.14.* *_cp314 - constrains: - - numpy-base <0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/numpy?source=hash-mapping - size: 7462504 - timestamp: 1786330617237 -- conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda - sha256: 24342dee891a49a9ba92e2018ec0bde56cc07fdaec95275f7a55b96f03ea4252 - md5: e723ab7cc2794c954e1b22fde51c16e4 - depends: - - libpng >=1.6.55,<1.7.0a0 - - libtiff >=4.7.1,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 245594 - timestamp: 1772624841727 -- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda - sha256: 9dddb559ba49744d5d94092d8d13cb0567f5c3b3f439f3acf28433d1f4256acc - md5: 73cb1783f47c452be4c309430fbef89f - 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: 9474879 - timestamp: 1787699876495 -- conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - sha256: 1840bd90d25d4930d60f57b4f38d4e0ae3f5b8db2819638709c36098c6ba770c - md5: e51f1e4089cad105b6cac64bd8166587 - depends: - - python >=3.9 - - typing_utils - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/overrides?source=hash-mapping - size: 30139 - timestamp: 1734587755455 -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda - sha256: c432626b16768b8dab228bfb706f7060c2d462a21c516d240f68f2f902b5a044 - md5: 936687ed80f295a1f5dbcf8bd34c252c - depends: - - python >=3.9 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/packaging?source=hash-mapping - size: 116363 - timestamp: 1785888127370 -- conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f - md5: 457c2c8c08e54905d6954e79cb5b5db9 - depends: - - python !=3.0,!=3.1,!=3.2,!=3.3 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pandocfilters?source=hash-mapping - size: 11627 - timestamp: 1631603397334 -- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda - sha256: 611882f7944b467281c46644ffde6c5145d1a7730388bcde26e7e86819b0998e - md5: 39894c952938276405a1bd30e4ce2caf - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/parso?source=hash-mapping - size: 82472 - timestamp: 1777722955579 -- conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-h8466c1e_1.conda - sha256: d8e9ea26b52a09d880d1e5371830c8dd5b4c099a6db64dbdf8236440744b7499 - md5: 009af999dbe2d1db36a37187a4ca4eb4 - depends: - - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.3.2,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 993241 - timestamp: 1787294653206 -- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-12.3.0-py314h61b30b5_0.conda - sha256: c9dc3212ed0021974541072ee3765a5097a0721191c34ee485d7d7e94449648f - md5: 09b8e6ac8f4a257b59e5d3025f3c9c1d - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.14.* *_cp314 - - libfreetype >=2.14.3 - - libfreetype6 >=2.14.3 - - libwebp-base >=1.6.0,<2.0a0 - - libtiff >=4.7.1,<4.8.0a0 - - openjpeg >=2.5.4,<3.0a0 - - lcms2 >=2.19.1,<3.0a0 - - libxcb >=1.17.0,<2.0a0 - - libjpeg-turbo >=3.1.4.1,<4.0a0 - - tk >=8.6.13,<8.7.0a0 - - zlib-ng >=2.3.3,<2.4.0a0 - license: HPND - purls: - - pkg:pypi/pillow?source=hash-mapping - size: 989058 - timestamp: 1782912129930 -- conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_3.conda - sha256: cad8b94c2b00264a15d469eed6dc53aac1c59c6d46f27ad1d91bfaf227cf136a - md5: 27c5be39d9e4d25fe85b89a069360d1e - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 257473 - timestamp: 1786106677325 -- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.11.5-pyhcf101f3_0.conda - sha256: 4496a7e0b584a388b3580ab594a4f384696ab7d702282588fd33a7ee38af983c - md5: 152ec36401f710145a7db03475594410 - depends: - - python >=3.10 - - python - license: MIT - purls: - - pkg:pypi/platformdirs?source=compressed-mapping - size: 27461 - timestamp: 1787881635603 -- conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.26.0-pyhd8ed1ab_0.conda - sha256: 794eec057361b41db1b06a9677eb8632adc0de81f7dcfe113bca8f0b04a23553 - md5: 3aa7e2d85645e61627c98082747dfdfe - depends: - - python >=3.10 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/prometheus-client?source=hash-mapping - size: 61554 - timestamp: 1785016068982 -- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.53-pyha770c72_0.conda - sha256: efe8def2c93aa34cd8d3c9af1dc4c7d312791cf769d8b2b615e32733e6df6051 - md5: 39c92a39517316e5001d645ae63d9ab9 - depends: - - python >=3.10 - - wcwidth - constrains: - - prompt_toolkit 3.0.53 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/prompt-toolkit?source=hash-mapping - size: 276081 - timestamp: 1785160613307 -- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py314hc5dbbe4_1.conda - sha256: c975e08da7627e95d1f0b70ef9787e9153118e67bb5b31f5530c5c3827d9afe8 - md5: deeef9494cfffa58f5fd20bc6eb57664 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.14.* *_cp314 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 249966 - timestamp: 1787417377436 -- conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-hba3369d_1003.conda - sha256: 5546927a2e337d2903d6cdb028fb33723cdbcc45bf9abe1770fbde2c4ea8bce6 - md5: bc97d497656c9c661ffd3043aca90aa4 - depends: - - libgcc >=14 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 10120 - timestamp: 1786067833280 -- conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - sha256: 71bd24600d14bb171a6321d523486f6a06f855e75e547fa0cb2a0953b02047f0 - md5: 3bfdfb8dbcdc4af1ae3f9a8eb3948f04 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pure-eval?source=hash-mapping - size: 16668 - timestamp: 1733569518868 -- pypi: https://files.pythonhosted.org/packages/44/f6/775eb92e865b28cdb4ad1f2bed7a5446197516f76b58a950faa3be3fd08d/pybtex-0.26.1-py3-none-any.whl - name: pybtex - version: 0.26.1 - sha256: e26c0412cc54f5f21b2a6d9d175762a2d2af9ccf3a8f651cdb89ec035db77aa1 - requires_dist: - - importlib-metadata ; python_full_version < '3.10' - - latexcodec>=1.0.4 - - pyyaml>=3.1 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/11/b1/ce1f4596211efb5410e178a803f08e59b20bedb66837dcf41e21c54f9ec1/pybtex_docutils-1.0.3-py3-none-any.whl - name: pybtex-docutils - version: 1.0.3 - sha256: 8fd290d2ae48e32fcb54d86b0efb8d573198653c7e2447d5bec5847095f430b9 - requires_dist: - - docutils>=0.14 - - pybtex>=0.16 - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-3.0-pyhcf101f3_0.conda - sha256: e27e0473fc6723311a0bd48b89b616fa1b996a2f7a2b555338cbbcfb9c640568 - md5: 9c5491066224083c41b6d5635ed7107b - depends: - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pycparser?source=hash-mapping - size: 55886 - timestamp: 1779293633166 -- pypi: https://files.pythonhosted.org/packages/e2/0d/8ba33fa83a7dcde13eb3c1c2a0c1cc29950a048bfed6d9b0d8b6bd710b4c/pydata_sphinx_theme-0.16.1-py3-none-any.whl - name: pydata-sphinx-theme - version: 0.16.1 - sha256: 225331e8ac4b32682c18fcac5a57a6f717c4e632cea5dd0e247b55155faeccde - requires_dist: - - sphinx>=6.1 - - beautifulsoup4 - - docutils!=0.17.0 - - babel - - pygments>=2.7 - - accessible-pygments - - typing-extensions - - numpydoc ; extra == 'doc' - - linkify-it-py ; extra == 'doc' - - rich ; extra == 'doc' - - sphinxext-rediraffe ; extra == 'doc' - - sphinx-sitemap ; extra == 'doc' - - sphinx-autoapi>=3.0.0 ; extra == 'doc' - - myst-parser ; extra == 'doc' - - ablog>=0.11.8 ; extra == 'doc' - - jupyter-sphinx ; extra == 'doc' - - pandas ; extra == 'doc' - - plotly ; extra == 'doc' - - matplotlib ; extra == 'doc' - - numpy ; extra == 'doc' - - xarray ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - sphinx-togglebutton ; extra == 'doc' - - jupyterlite-sphinx ; extra == 'doc' - - sphinxcontrib-youtube>=1.4.1 ; extra == 'doc' - - sphinx-favicon>=1.0.1 ; extra == 'doc' - - ipykernel ; extra == 'doc' - - nbsphinx ; extra == 'doc' - - ipyleaflet ; extra == 'doc' - - colorama ; extra == 'doc' - - ipywidgets ; extra == 'doc' - - graphviz ; extra == 'doc' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-regressions ; extra == 'test' - - sphinx[test] ; extra == 'test' - - pyyaml ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pydata-sphinx-theme[doc,test] ; extra == 'dev' - - tox ; extra == 'dev' - - pandoc ; extra == 'dev' - - sphinx-theme-builder[cli] ; extra == 'dev' - - pytest-playwright ; extra == 'a11y' - - babel ; extra == 'i18n' - - jinja2 ; extra == 'i18n' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.21.0-pyhcf101f3_0.conda - sha256: f5f015ff1bc3e1b7fc08eee096b1865234189ae0b82bebdb86a5369116e42fa0 - md5: 2882dee445dfa45b0c5afce3ffb7730a - depends: - - python >=3.10 - - python - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/pygments?source=compressed-mapping - size: 959376 - timestamp: 1786995678795 -- conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda - sha256: 417fba4783e528ee732afa82999300859b065dc59927344b4859c64aae7182de - md5: 3687cc0b82a8b4c17e1f0eb7e47163d5 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyparsing?source=hash-mapping - size: 110893 - timestamp: 1769003998136 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.2-py314h447aaf0_0.conda - sha256: bf1553eebc31e8ba04689639e8ce235c3df5317414f0c4a11417f238297f1b17 - md5: 7c3ccff96dbc9f8e3c40142c7594ec34 - depends: - - python - - qt6-main 6.11.2.* - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libxml2 - - libxml2-16 >=2.14.6 - - libclang13 >=22.1.8 - - qt6-main >=6.11.2,<7.0a0 - - python_abi 3.14.* *_cp314 - - libvulkan-loader >=1.4.357.0,<2.0a0 - - libxslt >=1.1.43,<2.0a0 - license: LGPL-3.0-only - license_family: LGPL - purls: - - pkg:pypi/pyside6?source=hash-mapping - - pkg:pypi/shiboken6?source=hash-mapping - size: 11552286 - timestamp: 1787219450026 -- 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/win-64/python-3.14.7-h53f6dd8_101_cp314.conda - build_number: 101 - sha256: 6a23a13d3ec5c48903bb2ad19a29c4346598481c276400f9954c76742d7822a5 - md5: 93dfbaa716a52edcdcb95dd4d6b209c8 - depends: - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.8.1,<3.0a0 - - libffi >=3.7.0,<3.8.0a0 - - liblzma >=5.8.3,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libpython 3.14.7 h4f90d01_101_cp314 - - libsqlite >=3.53.4,<4.0a0 - - libzlib >=1.3.2,<2.0a0 - - openssl >=3.5.8,<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: 18557864 - timestamp: 1787780948104 - python_site_packages_path: Lib/site-packages -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 - md5: 5b8d21249ff20967101ffa321cab24e8 - depends: - - python >=3.9 - - six >=1.5 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/python-dateutil?source=hash-mapping - size: 233310 - timestamp: 1751104122689 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.22.2-pyhcf101f3_0.conda - sha256: fc4a704822df22defce49d0fb811fdc036a1fd3b579aeaa601228e9cfd198b3d - md5: aa75b7f096d17621bc307b3025b29461 - depends: - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/fastjsonschema?source=compressed-mapping - size: 254446 - timestamp: 1786892280524 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.7-h4df99d1_101.conda - sha256: c39431bdbf23eff2eaa1591b438e5fd7e7db2fb635262b6eefd658dfa2f19c7c - md5: 35bb169c9d712dfc590b88f28f852157 - depends: - - cpython 3.14.7.* - - python_abi * *_cp314 - license: Python-2.0 - purls: [] - size: 50521 - timestamp: 1787780107541 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-4.2.0-pyhd8ed1ab_0.conda - sha256: 4f8ecadbd9d282b0208d6e84640573fcb6ab462307d737eedd28341964e18cc6 - md5: e5407c82510aab6a4baa31fcd4249655 - depends: - - python >=3.10 - - typing_extensions - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/python-json-logger?source=compressed-mapping - size: 19367 - timestamp: 1786872772907 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.3-pyhd8ed1ab_0.conda - sha256: 3f05db78cf8be33cf6dbc469664b8e3a01f3980d61d6d6bef48669b171896d8a - md5: eefc8d916bd2e708d76d40398ef9a1ee - depends: - - python >=3.10 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/tzdata?source=hash-mapping - size: 146862 - timestamp: 1783704822814 -- 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 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-312-py314hf700ef7_1.conda - sha256: 5a6ddd03a8441c2312a09f998dccb0bdeb1b906b45c9b8cd5e9f5a7965b0a604 - md5: 57992821d70e28562192fa29cff08260 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.14.* *_cp314 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/pywin32?source=hash-mapping - size: 4473050 - timestamp: 1787374336870 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-3.0.5-py314h51f0985_0.conda - sha256: 025a42fa3df042590f9f5efdf8473e98e654672871c9db029436f32e021cb900 - md5: 9f34ac4f934a5e6bdffa81db44b3ce82 - depends: - - python >=3.14,<3.15.0a0 - - python_abi 3.14.* *_cp314 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - winpty - license: MIT - license_family: MIT - purls: - - pkg:pypi/pywinpty?source=hash-mapping - size: 731340 - timestamp: 1785742446062 -- 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=hash-mapping - size: 181257 - timestamp: 1770223460931 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.2.0-py312h343a6d4_0.conda - noarch: python - sha256: 56d33fdddf6fb7ffb86120b8e2f1398cc406d0d3e85e5647d3a72cad05c17509 - md5: 58bcf20b110e99aa69ab892a6ced10f5 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - _python_abi3_support 1.* - - cpython >=3.12 - - zeromq >=4.3.5,<4.3.6.0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=compressed-mapping - size: 187939 - timestamp: 1787300948668 -- conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda - sha256: 887d53486a37bd870da62b8fa2ebe3993f912ad04bd755e7ed7c47ced97cbaa8 - md5: 854fbdff64b572b5c0b470f334d34c11 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: LicenseRef-Qhull - purls: [] - size: 1377020 - timestamp: 1720814433486 -- conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.2-pl5321hfcac499_0.conda - sha256: 042c94a5a7a89b0b28a24f6ae6a2d3d609751edab78454057973ec5cc3e77d7d - md5: d98a163070d05c6ed4421432ee1bafb8 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libvulkan-loader >=1.4.357.0,<2.0a0 - - icu >=78.3,<79.0a0 - - libfreetype >=2.14.3 - - libfreetype6 >=2.14.3 - - libharfbuzz >=14.3.1 - - libzlib >=1.3.2,<2.0a0 - - double-conversion >=3.4.0,<3.5.0a0 - - libglib >=2.88.3,<3.0a0 - - krb5 >=1.22.2,<1.23.0a0 - - pcre2 >=10.47,<10.48.0a0 - - libpng >=1.6.58,<1.7.0a0 - - zstd >=1.5.7,<1.6.0a0 - - libsqlite >=3.53.4,<4.0a0 - - openssl >=3.5.7,<4.0a0 - - libjpeg-turbo >=3.2.0,<4.0a0 - - libtiff >=4.7.2,<4.8.0a0 - - libbrotlicommon >=1.2.0,<1.3.0a0 - - libbrotlienc >=1.2.0,<1.3.0a0 - - libbrotlidec >=1.2.0,<1.3.0a0 - - libwebp-base >=1.6.0,<2.0a0 - constrains: - - qt ==6.11.2 - license: LGPL-3.0-only - license_family: LGPL - purls: [] - size: 89682645 - timestamp: 1787049046883 -- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 - md5: 870293df500ca7e18bedefa5838a22ab - depends: - - attrs >=22.2.0 - - python >=3.10 - - rpds-py >=0.7.0 - - typing_extensions >=4.4.0 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/referencing?source=hash-mapping - size: 51788 - timestamp: 1760379115194 -- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda - sha256: 1715246b19c9f85ee022933b4845f2fc14ac9184981b7b7d9b728bec8e9588da - md5: 4a85203c1d80c1059086ae860836ffb9 - 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,<8 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/requests?source=hash-mapping - size: 68709 - timestamp: 1778851103479 -- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - sha256: 2e4372f600490a6e0b3bac60717278448e323cab1c0fecd5f43f7c56535a99c5 - md5: 36de09a8d3e5d5e6f4ee63af49e59706 - depends: - - python >=3.9 - - six - license: MIT - license_family: MIT - purls: - - pkg:pypi/rfc3339-validator?source=hash-mapping - size: 10209 - timestamp: 1733600040800 -- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - sha256: 2a5b495a1de0f60f24d8a74578ebc23b24aa53279b1ad583755f223097c41c37 - md5: 912a71cc01012ee38e6b90ddd561e36f - depends: - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/rfc3986-validator?source=hash-mapping - size: 7818 - timestamp: 1598024297745 -- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - sha256: 70001ac24ee62058557783d9c5a7bbcfd97bd4911ef5440e3f7a576f9e43bc92 - md5: 7234f99325263a5af6d4cd195035e8f2 - depends: - - python >=3.9 - - lark >=1.2.2 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/rfc3987-syntax?source=hash-mapping - size: 22913 - timestamp: 1752876729969 -- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-2026.6.3-py314h9f07db2_0.conda - sha256: d297e7ef5f062194cf76dcf7a2e0449af24012b895a06aa942805f2933a0256c - md5: 07602f253d1ad9436bcac564c9fe183f - 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/rpds-py?source=compressed-mapping - size: 218916 - timestamp: 1787344535083 -- pypi: https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl - name: ruamel-yaml - version: 0.19.1 - sha256: 27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93 - requires_dist: - - ruamel-yaml-clib ; platform_python_implementation == 'CPython' and extra == 'oldlibyaml' - - ruamel-yaml-clibz>=0.3.7 ; platform_python_implementation == 'CPython' and extra == 'libyaml' - - ruamel-yaml-jinja2>=0.2 ; extra == 'jinja2' - - ryd ; extra == 'docs' - - mercurial>5.7 ; extra == 'docs' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda - sha256: 305446a0b018f285351300463653d3d3457687270e20eda37417b12ee386ef76 - md5: 6ac53f3fff2c416d63511843a04646fa - depends: - - __win - - pywin32 - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/send2trash?source=hash-mapping - size: 22864 - timestamp: 1770937641143 -- pypi: https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl - name: setuptools - version: 84.0.0 - sha256: 51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670 - requires_dist: - - pytest>=6,!=8.1.* ; extra == 'test' - - virtualenv>=13.0.0 ; extra == 'test' - - wheel>=0.44.0 ; extra == 'test' - - pip>=19.1 ; extra == 'test' - - packaging>=24.2 ; extra == 'test' - - jaraco-envs>=2.2 ; extra == 'test' - - pytest-xdist>=3 ; extra == 'test' - - jaraco-path>=3.7.2 ; extra == 'test' - - build[virtualenv]>=1.0.3 ; extra == 'test' - - filelock>=3.4.0 ; extra == 'test' - - ini2toml[lite]>=0.14 ; extra == 'test' - - tomli-w>=1.0.0 ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-perf ; sys_platform != 'cygwin' and extra == 'test' - - jaraco-develop>=7.21 ; python_full_version >= '3.9' and sys_platform != 'cygwin' and extra == 'test' - - pytest-home>=0.5 ; extra == 'test' - - pytest-subprocess ; extra == 'test' - - pyproject-hooks!=1.1 ; extra == 'test' - - jaraco-test>=5.5 ; 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' - - pygments-github-lexers==0.0.5 ; extra == 'doc' - - sphinx-favicon ; extra == 'doc' - - sphinx-inline-tabs ; extra == 'doc' - - sphinx-reredirects ; extra == 'doc' - - sphinxcontrib-towncrier ; extra == 'doc' - - sphinx-notfound-page>=1,<2 ; extra == 'doc' - - pyproject-hooks!=1.1 ; extra == 'doc' - - towncrier<24.7 ; extra == 'doc' - - packaging>=24.2 ; extra == 'core' - - more-itertools>=8.8 ; extra == 'core' - - jaraco-text>=3.7 ; extra == 'core' - - importlib-metadata>=6 ; python_full_version < '3.10' and extra == 'core' - - tomli>=2.0.1 ; python_full_version < '3.11' and extra == 'core' - - wheel>=0.43.0 ; extra == 'core' - - jaraco-functools>=4 ; extra == 'core' - - more-itertools ; extra == 'core' - - pytest-checkdocs>=2.14 ; extra == 'check' - - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - - ruff>=0.13.0 ; 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' - - mypy==1.18.* ; extra == 'type' - - importlib-metadata>=7.0.2 ; python_full_version < '3.10' and extra == 'type' - - jaraco-develop>=7.21 ; sys_platform != 'cygwin' and extra == 'type' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d - md5: 3339e3b65d58accf4ca4fb8748ab16b3 - depends: - - python >=3.9 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/six?source=hash-mapping - size: 18455 - timestamp: 1753199211006 -- conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda - sha256: dce518f45e24cd03f401cb0616917773159a210c19d601c5f2d4e0e5879d30ad - md5: 03fe290994c5e4ec17293cfb6bdce520 - depends: - - python >=3.10 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/sniffio?source=hash-mapping - size: 15698 - timestamp: 1762941572482 -- pypi: https://files.pythonhosted.org/packages/4c/07/2ebca9b11fb9be7340a818d8d6f63feaebb146be2c4afbd6061701d6df6e/snowballstemmer-3.1.1-py3-none-any.whl - name: snowballstemmer - version: 3.1.1 - sha256: 7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752 - requires_python: '>=3.3' -- conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.9.2-pyhd8ed1ab_0.conda - sha256: 056d7a2e91e303a9ee37e580f6dde0511fc3fb72476581cc337aacf2cc747613 - md5: ba33e6c8a46ee373fdf6dd8665212778 - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/soupsieve?source=compressed-mapping - size: 39439 - timestamp: 1786202135509 -- pypi: https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl - name: sphinx - version: 7.4.7 - sha256: c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239 - requires_dist: - - sphinxcontrib-applehelp - - sphinxcontrib-devhelp - - sphinxcontrib-jsmath - - sphinxcontrib-htmlhelp>=2.0.0 - - sphinxcontrib-serializinghtml>=1.1.9 - - sphinxcontrib-qthelp - - jinja2>=3.1 - - pygments>=2.17 - - docutils>=0.20,<0.22 - - snowballstemmer>=2.2 - - babel>=2.13 - - alabaster~=0.7.14 - - imagesize>=1.3 - - requests>=2.30.0 - - packaging>=23.0 - - importlib-metadata>=6.0 ; python_full_version < '3.10' - - tomli>=2 ; python_full_version < '3.11' - - colorama>=0.4.6 ; sys_platform == 'win32' - - sphinxcontrib-websupport ; extra == 'docs' - - flake8>=6.0 ; extra == 'lint' - - ruff==0.5.2 ; extra == 'lint' - - mypy==1.10.1 ; extra == 'lint' - - sphinx-lint>=0.9 ; extra == 'lint' - - types-docutils==0.21.0.20240711 ; extra == 'lint' - - types-requests>=2.30.0 ; extra == 'lint' - - importlib-metadata>=6.0 ; extra == 'lint' - - tomli>=2 ; extra == 'lint' - - pytest>=6.0 ; extra == 'lint' - - pytest>=8.0 ; extra == 'test' - - defusedxml>=0.7.1 ; extra == 'test' - - cython>=3.0 ; extra == 'test' - - setuptools>=70.0 ; extra == 'test' - - typing-extensions>=4.9 ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5c/60/6bf80661f1fc2573c6485819dc6daafa9e80b26fc60559e3cdba7552716d/sphinx_accessibility-1.0.1-py3-none-any.whl - name: sphinx-accessibility - version: 1.0.1 - sha256: d58d65c821e3854b31b35ae9fb90fd88ec1ced3943bdf2c5070e1930b96d03d0 - requires_dist: - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/cc/6e/b152dee1988fb4125b2fd882c63330d89706bccdf661c55230e5ed456c67/sphinx_apa_references-1.0.1-py3-none-any.whl - name: sphinx-apa-references - version: 1.0.1 - sha256: 234d31c748f1f4660784d4f34666e0d28da180c8ab292d0578b0b8ad6df0c87f - requires_dist: - - pybtex - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/02/bf/6f506a37c7f8ecc4576caf9486e303c7af249f6d70447bb51dde9d78cb99/sphinx_book_theme-1.2.0-py3-none-any.whl - name: sphinx-book-theme - version: 1.2.0 - sha256: 709605d308e1991c5ef0cf19c481dbe9084b62852e317fafab74382a0ee7ccfa - requires_dist: - - sphinx>=7.0 - - pydata-sphinx-theme==0.16.1 - - pre-commit ; extra == 'code-style' - - ablog>=0.11.13 ; extra == 'doc' - - ipywidgets ; extra == 'doc' - - folium ; extra == 'doc' - - numpy ; extra == 'doc' - - matplotlib ; extra == 'doc' - - numpydoc ; extra == 'doc' - - myst-nb ; extra == 'doc' - - nbclient ; extra == 'doc' - - pandas ; extra == 'doc' - - plotly ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - sphinx-examples ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-tabs ; extra == 'doc' - - sphinx-togglebutton ; extra == 'doc' - - sphinx-thebe ; extra == 'doc' - - sphinxcontrib-bibtex ; extra == 'doc' - - sphinxcontrib-youtube ; extra == 'doc' - - sphinxext-opengraph ; extra == 'doc' - - beautifulsoup4 ; extra == 'test' - - coverage ; extra == 'test' - - defusedxml ; extra == 'test' - - myst-nb ; extra == 'test' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-regressions ; extra == 'test' - - sphinx-thebe ; extra == 'test' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/b0/9e/e9d545c5c699cd6fa35912b487cde2910e4c5fcf7e4f52fced2f31dd8cdc/sphinx_code_examples-1.2.3-py3-none-any.whl - name: sphinx-code-examples - version: 1.2.3 - sha256: f2f25cd5fecc0e666fcbbd41016a6545bee0a7ae4d19c8c68ad70fac1171c596 - requires_dist: - - sphinx - - sphinx-iframes>=1.0.7 - - sphinx-proof - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/26/97/a5c39f619375d4f81d5422377fb027075898efa6b6202c1ccf1e5bb38a32/sphinx_comments-0.0.3-py3-none-any.whl - name: sphinx-comments - version: 0.0.3 - sha256: 1e879b4e9bfa641467f83e3441ac4629225fc57c29995177d043252530c21d00 - requires_dist: - - sphinx>=1.8 - - flake8>=3.7.0,<3.8.0 ; extra == 'code-style' - - black ; extra == 'code-style' - - pre-commit==1.17.0 ; extra == 'code-style' - - sphinx>=2 ; extra == 'sphinx' - - sphinx-book-theme ; extra == 'sphinx' - - myst-parser ; extra == 'sphinx' - - beautifulsoup4 ; extra == 'testing' - - myst-parser ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - sphinx>=2 ; extra == 'testing' - - sphinx-book-theme ; extra == 'testing' -- pypi: https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl - name: sphinx-copybutton - version: 0.5.2 - sha256: fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e - requires_dist: - - sphinx>=1.8 - - pre-commit==2.12.1 ; extra == 'code-style' - - sphinx ; extra == 'rtd' - - ipython ; extra == 'rtd' - - myst-nb ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - sphinx-examples ; extra == 'rtd' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/30/cf/45dd359f6ca0c3762ce0490f681da242f0530c49c81050c035c016bfdd3a/sphinx_design-0.7.0-py3-none-any.whl - name: sphinx-design - version: 0.7.0 - sha256: f82bf179951d58f55dca78ab3706aeafa496b741a91b1911d371441127d64282 - requires_dist: - - sphinx>=7,<10 - - pre-commit>=3,<4 ; extra == 'code-style' - - myst-parser>=4,<6 ; extra == 'rtd' - - myst-parser>=4,<6 ; extra == 'testing' - - pytest~=8.3 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - defusedxml ; extra == 'testing' - - pytest~=8.3 ; extra == 'testing-no-myst' - - pytest-cov ; extra == 'testing-no-myst' - - pytest-regressions ; extra == 'testing-no-myst' - - defusedxml ; extra == 'testing-no-myst' - - furo~=2024.7.18 ; extra == 'theme-furo' - - sphinx-immaterial~=0.12.2 ; extra == 'theme-im' - - pydata-sphinx-theme~=0.15.2 ; extra == 'theme-pydata' - - sphinx-rtd-theme~=2.0 ; extra == 'theme-rtd' - - sphinx-book-theme~=1.1 ; extra == 'theme-sbt' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/bb/1c/6f22279218e978b08d6d301a8991547a585c3699942a33740de81843bdc5/sphinx_dropdown_toggle-1.3.3-py3-none-any.whl - name: sphinx-dropdown-toggle - version: 1.3.3 - sha256: 182182ba0fe4c515555a73d6d856cfa6e922eb4b4b574a7b19bd007fac78d242 - requires_dist: - - jupyterbook-patches>=1.13.1 - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/4d/95/af014c5eb8e804103471bcf3204ebfe6a674d8bae07e5c2b691c09183b9f/sphinx_exercise-1.2.1-py3-none-any.whl - name: sphinx-exercise - version: 1.2.1 - sha256: c8e5e470f5a3654a52f74528de5fade87df055bd0eacf4f607d355ea2558ff04 - requires_dist: - - sphinx-book-theme - - sphinx>=6.1 - - beautifulsoup4 ; extra == 'all' - - black ; extra == 'all' - - coverage ; extra == 'all' - - defusedxml ; extra == 'all' - - flake8>=3.7.0,<3.8.0 ; extra == 'all' - - matplotlib>=3.8 ; extra == 'all' - - myst-nb>=1.1.0 ; extra == 'all' - - pre-commit ; extra == 'all' - - pytest-cov ; extra == 'all' - - pytest-regressions ; extra == 'all' - - pytest>=8.0 ; extra == 'all' - - sphinx-book-theme ; extra == 'all' - - sphinx-togglebutton ; extra == 'all' - - sphinx>=6.1,<9 ; extra == 'all' - - texsoup ; extra == 'all' - - black ; extra == 'code-style' - - flake8>=3.7.0,<3.8.0 ; extra == 'code-style' - - pre-commit ; extra == 'code-style' - - myst-nb>=1.1.0 ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - sphinx-togglebutton ; extra == 'rtd' - - sphinx>=6.1,<9 ; extra == 'rtd' - - beautifulsoup4 ; extra == 'testing' - - coverage ; extra == 'testing' - - defusedxml ; extra == 'testing' - - matplotlib>=3.8 ; extra == 'testing' - - myst-nb>=1.1.0 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - pytest>=8.0 ; extra == 'testing' - - sphinx>=6.1,<9 ; extra == 'testing' - - texsoup ; extra == 'testing' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/9f/80/1704c9179012e289dee2178354e385277ea51f4fa827c4bf7e36c77b0f4b/sphinx_external_toc-1.1.0-py3-none-any.whl - name: sphinx-external-toc - version: 1.1.0 - sha256: 26c390b8d85aa641366fed2d3674910ec6820f48b91027affef485a2655ad7d0 - requires_dist: - - click>=7.1 - - pyyaml - - sphinx>=5 - - sphinx-multitoc-numbering>=0.1.3 - - pre-commit>=2.12 ; extra == 'code-style' - - myst-parser>=1.0.0 ; extra == 'rtd' - - sphinx-book-theme>=1.0.0 ; extra == 'rtd' - - coverage ; extra == 'testing' - - pytest>=7.1 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a1/09/58a0b9ba3a3624b8d940f73651c9dd0430255f616b76df18958816717bc8/sphinx_gated_directives-1.1.2-py3-none-any.whl - name: sphinx-gated-directives - version: 1.1.2 - sha256: d375408ea8701184bf3264f7507e648801b29480f932dcb881814471bc8eb318 - requires_dist: - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/19/a5/ec4c322063caff100c15415a48facc1501083e81ebf7a01426c1167d63bc/sphinx_github_alerts-1.1-py3-none-any.whl - name: sphinx-github-alerts - version: '1.1' - sha256: 57ff740d461c1670386c40aa4dd1e42794b5b7d48eabb6889b680ef1a17a1602 - requires_dist: - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/42/08/2ea6aadc6edeb09784ea94448ecd451b7f79710b4c660dc377e2dd044a3b/sphinx_iframes-1.2.0-py3-none-any.whl - name: sphinx-iframes - version: 1.2.0 - sha256: 0275574aaa0977b8a92ca247d7b9fe389d4a0ed6476165eb9975cad703d1d690 - requires_dist: - - sphinx - - sphinx-metadata-figure>=1.1.1 - - sphinxcontrib-video - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/7a/57/9eae17f1c0e2790ec2e2e8e914de1790cf7c28c59a275b9a4e0cc474344b/sphinx_image_inverter-1.1.11-py3-none-any.whl - name: sphinx-image-inverter - version: 1.1.11 - sha256: 991efdddaa5e6a51bf6b135f6d70b85355dd8b886aca3f65880cb074235a5a49 - requires_dist: - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/02/2b/e64e7de34663cff1df029ba4f05a86124315bd9eba3d3b78e64904bea7e0/sphinx_inline_tabs-2025.12.21.14-py3-none-any.whl - name: sphinx-inline-tabs - version: 2025.12.21.14 - sha256: e685c782b58d4e01490bcc4e2367cf7135ec28e7283a05e89095394e4ca6e81a - requires_dist: - - sphinx>=3 - - myst-parser ; extra == 'doc' - - furo ; extra == 'doc' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-xdist ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/70/1f/1d4ecaf58b17fe61497644655f40b04d84a88348e41a6f0c6392394d95e4/sphinx_jupyterbook_latex-1.0.0-py3-none-any.whl - name: sphinx-jupyterbook-latex - version: 1.0.0 - sha256: e0cd3e9e1c5af69136434e21a533343fdf013475c410a414d5b7b4922b4f3891 - requires_dist: - - sphinx>=5 - - packaging - - pre-commit~=2.12 ; extra == 'code-style' - - myst-nb>=1.0.0 ; extra == 'myst' - - myst-parser ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - sphinx-design ; extra == 'rtd' - - sphinx-jupyterbook-latex ; extra == 'rtd' - - coverage>=6.0 ; extra == 'testing' - - myst-nb>=1.0.0 ; extra == 'testing' - - pytest-cov>=3 ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - pytest>=7.1 ; extra == 'testing' - - sphinx-external-toc>=1.0.0 ; extra == 'testing' - - sphinxcontrib-bibtex>=2.6.0 ; extra == 'testing' - - texsoup ; extra == 'testing' - requires_python: '>=3.9' -- pypi: git+https://github.com/TeachBooks/sphinx-last-updated-by-git#986142bb958d2e0f18da6755c551be865aa512ff - name: sphinx-last-updated-by-git - version: 0.3.8 - requires_dist: - - sphinx>=1.8 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/d5/99/9ad0c2c2e75d4e99b5023f6e12c77984875b1adab5bbc17e863c17cc1ba0/sphinx_launch_buttons-1.0.7-py3-none-any.whl - name: sphinx-launch-buttons - version: 1.0.7 - sha256: 8c1748e9038ea2dfbe90ffbcc603aa6e82df0a13b632fdd6cfbc350767703f19 - requires_dist: - - sphinx - - ruamel-yaml - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e2/e0/ae934d06e31c67164145ada3ab8efec7a588a8f8f71cb3b54431935f0d76/sphinx_metadata_figure-1.5.1-py3-none-any.whl - name: sphinx-metadata-figure - version: 1.5.1 - sha256: 29b1b890cdcb9fb39ea2e62fd1fe8d9c56224d8c3b0e761845e7dc0bc3c0e664 - requires_dist: - - myst-nb>=0.17 - - sphinx>=5.0 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ec/9f/902f2030674cd9473fdbe5a2c2dec2618c27ec853484c35f82cf8df40ece/sphinx_multitoc_numbering-0.1.3-py3-none-any.whl - name: sphinx-multitoc-numbering - version: 0.1.3 - sha256: 33d2e707a9b2b8ad636b3d4302e658a008025106fe0474046c651144c26d8514 - requires_dist: - - sphinx>=3 - - flake8>=3.7.0,<3.8.0 ; extra == 'code-style' - - black ; extra == 'code-style' - - pre-commit==1.17.0 ; extra == 'code-style' - - sphinx>=3.0 ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - myst-parser ; extra == 'rtd' - - pytest~=5.4 ; extra == 'testing' - - pytest-cov~=2.8 ; extra == 'testing' - - coverage<5.0 ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - jupyter-book ; extra == 'testing' -- pypi: https://files.pythonhosted.org/packages/7a/d8/9c2ad1764a9f6736ec65134ef5fbee8c0d1f148cff260fef3afa38479998/sphinx_named_colors-1.0.3-py3-none-any.whl - name: sphinx-named-colors - version: 1.0.3 - sha256: b72e2291f7bf1252d399c88122b67ea4375c0e85b131ad7d72aba4dc3d8a45f3 - requires_dist: - - numpy - - sphinx - - sphinxnotes-comboroles - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ef/24/a4bbc812400aae41072d7b42f99c8787a097618a1084e7439aa03de3c73d/sphinx_nb_execution_patterns-1.1.0-py3-none-any.whl - name: sphinx-nb-execution-patterns - version: 1.1.0 - sha256: 2cc93535c5ffeccb70126fc5f3234bda8b9c78f99bd9cf416ea9d4ea7dd62db8 - requires_dist: - - jupyterbook-patches>=1.12.1 - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/a6/7a/d3397a28c21cc3981de5fb26910b1f0b8821152dcfdba1737388edbe7864/sphinx_proof-0.4.0-py3-none-any.whl - name: sphinx-proof - version: 0.4.0 - sha256: 7781d533a56a6fa5cf4b1d79564b0a0f05493e45dedfcfa5de1ae5a7bd0c9ecd - requires_dist: - - docutils>=0.15 - - sphinx - - sphinx-book-theme - - flake8 ; extra == 'code-style' - - black ; extra == 'code-style' - - pre-commit ; extra == 'code-style' - - coverage ; extra == 'testing' - - pytest~=7.1 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - beautifulsoup4 ; extra == 'testing' - - myst-parser ; extra == 'testing' - - texsoup ; extra == 'testing' - - defusedxml ; extra == 'testing' - - sphinx>=5.0 ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - sphinxcontrib-bibtex ; extra == 'rtd' - - myst-parser ; extra == 'rtd' - - sphinx-togglebutton ; extra == 'rtd' - - sphinxcontrib-bibtex ; extra == 'all' - - defusedxml ; extra == 'all' - - pytest~=7.1 ; extra == 'all' - - coverage ; extra == 'all' - - pytest-cov ; extra == 'all' - - beautifulsoup4 ; extra == 'all' - - pytest-regressions ; extra == 'all' - - texsoup ; extra == 'all' - - flake8 ; extra == 'all' - - pre-commit ; extra == 'all' - - sphinx>=5.0 ; extra == 'all' - - sphinx-book-theme ; extra == 'all' - - black ; extra == 'all' - - myst-parser ; extra == 'all' - - sphinx-togglebutton ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ab/38/53f6735ac5392534218e6832aa749501a188a9f052a9f5b7de195bb6a7ea/sphinx_sticky_margin-1.1.4-py3-none-any.whl - name: sphinx-sticky-margin - version: 1.1.4 - sha256: 6bd9e012dfafa4b05bd0d43842a51bdacc16164facc6da9dd062243d257b8469 - requires_dist: - - sphinx>=5.0 - requires_python: '>=3.10' -- pypi: git+https://github.com/TeachBooks/Sphinx-Thebe#1f3a80969622b7d63f48f05d8769f5cb933202a0 - name: sphinx-thebe - version: 0.3.1 - requires_dist: - - sphinx>=4 - - wcmatch==8.5 - - myst-nb ; extra == 'sphinx' - - sphinx-book-theme ; extra == 'sphinx' - - sphinx-copybutton ; extra == 'sphinx' - - sphinx-design ; extra == 'sphinx' - - myst-nb>=1.0.0rc0 ; extra == 'testing' - - sphinx-copybutton ; extra == 'testing' - - sphinx-design ; extra == 'testing' - - matplotlib ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - beautifulsoup4 ; extra == 'testing' - - sphinx-thebe[testing] ; extra == 'dev' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/d8/2e/3dd55564928c5d61f92827d4b91307dde7911a40fbe0000645d73202eea9/sphinx_togglebutton-0.4.5-py3-none-any.whl - name: sphinx-togglebutton - version: 0.4.5 - sha256: 74eac6d2426110c3e1e6f989a98e07d7823141a335df1ad8a9d637bdf6a7af62 - requires_dist: - - setuptools - - wheel - - sphinx - - docutils - - matplotlib ; extra == 'sphinx' - - numpy ; extra == 'sphinx' - - myst-nb ; extra == 'sphinx' - - sphinx-book-theme ; extra == 'sphinx' - - sphinx-design ; extra == 'sphinx' - - sphinx-examples ; extra == 'sphinx' -- pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl - name: sphinxcontrib-applehelp - version: 2.0.0 - sha256: 4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/52/c0/d28e62407f4733bbe0169287bc012f0ac3b4a2021066b285570654119c8b/sphinxcontrib_bibtex-2.7.0-py3-none-any.whl - name: sphinxcontrib-bibtex - version: 2.7.0 - sha256: 28cf0ec7a957d1c7548d5749317ed472ce877e1b629f430f88e3789aa51f87b1 - requires_dist: - - sphinx>=7.4 - - docutils>=0.20 - - pybtex>=0.25 - - pybtex-docutils>=1.0.2 - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - sphinx-autoapi ; extra == 'test' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl - name: sphinxcontrib-devhelp - version: 2.0.0 - sha256: aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl - name: sphinxcontrib-htmlhelp - version: 2.1.0 - sha256: 166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - - html5lib ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl - name: sphinxcontrib-jsmath - version: 1.0.1 - sha256: 2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 - requires_dist: - - pytest ; extra == 'test' - - flake8 ; extra == 'test' - - mypy ; extra == 'test' - requires_python: '>=3.5' -- pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl - name: sphinxcontrib-qthelp - version: 2.0.0 - sha256: b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - - defusedxml>=0.7.1 ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl - name: sphinxcontrib-serializinghtml - version: 2.0.0 - sha256: 6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0b/85/5a61ac88dc21df340a5999ca3ab94edaf58287010c62020be426703b8dd3/sphinxcontrib_video-0.4.2-py3-none-any.whl - name: sphinxcontrib-video - version: 0.4.2 - sha256: 7dfd01e5e2025de39536457854052b18723575d6213d96ca35f83e3154dc0315 - requires_dist: - - sphinx - - nox ; extra == 'dev' - - pre-commit ; extra == 'dev' - - mypy ; extra == 'dev' - - pytest ; extra == 'test' - - beautifulsoup4 ; extra == 'test' - - pytest-regressions ; extra == 'test' - - pytest-cov ; extra == 'test' - - defusedxml ; extra == 'test' - - pydata-sphinx-theme ; extra == 'doc' - - sphinx-design ; extra == 'doc' - requires_python: '>=3.9.0' -- pypi: https://files.pythonhosted.org/packages/e3/13/62ff9dadfe0c70203e8d5f38635955bbd41b48ff916788a22fc033232348/sphinxnotes_comboroles-1.0-py3-none-any.whl - name: sphinxnotes-comboroles - version: '1.0' - sha256: c016b0d6ad1db0f91c6da203e3b10d18fcf2869e6833fecc48bc8bc45149f496 - requires_dist: - - sphinx>=4 - - build ; extra == 'dev' - - twine ; extra == 'dev' - - cruft ; extra == 'dev' - - furo ; extra == 'docs' - - sphinxnotes-any ; extra == 'docs' - - sphinx-design ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinxcontrib-gtagjs ; extra == 'docs' - - sphinxnotes-strike ; extra == 'docs' - - pytest ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl - name: sqlalchemy - version: 2.0.52 - sha256: a593db51b3bae75db17a5738ad5f992244b3a03863f83c28117ee482c6a3f76d - requires_dist: - - importlib-metadata ; python_full_version < '3.8' - - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' - - typing-extensions>=4.6.0 - - greenlet>=1 ; extra == 'asyncio' - - mypy>=0.910 ; extra == 'mypy' - - pyodbc ; extra == 'mssql' - - pymssql ; extra == 'mssql-pymssql' - - pyodbc ; extra == 'mssql-pyodbc' - - mysqlclient>=1.4.0 ; extra == 'mysql' - - mysql-connector-python ; extra == 'mysql-connector' - - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' - - cx-oracle>=8 ; extra == 'oracle' - - oracledb>=1.0.1 ; extra == 'oracle-oracledb' - - psycopg2>=2.7 ; extra == 'postgresql' - - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' - - greenlet>=1 ; extra == 'postgresql-asyncpg' - - asyncpg ; extra == 'postgresql-asyncpg' - - psycopg2-binary ; extra == 'postgresql-psycopg2binary' - - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' - - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' - - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' - - pymysql ; extra == 'pymysql' - - greenlet>=1 ; extra == 'aiomysql' - - aiomysql>=0.2.0 ; extra == 'aiomysql' - - greenlet>=1 ; extra == 'aioodbc' - - aioodbc ; extra == 'aioodbc' - - greenlet>=1 ; extra == 'asyncmy' - - asyncmy>=0.2.12 ; extra == 'asyncmy' - - greenlet>=1 ; extra == 'aiosqlite' - - aiosqlite ; extra == 'aiosqlite' - - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - - sqlcipher3-binary ; extra == 'sqlcipher' - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - sha256: 570da295d421661af487f1595045760526964f41471021056e993e73089e9c41 - md5: b1b505328da7a6b246787df4b5a49fbc - depends: - - asttokens - - executing - - pure_eval - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/stack-data?source=hash-mapping - size: 26988 - timestamp: 1733569565672 -- pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - name: tabulate - version: 0.10.0 - sha256: f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 - requires_dist: - - wcwidth ; extra == 'widechars' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2023.0.0-hd3d4ead_2.conda - sha256: 8a4053839b8e997a5965e2dff7d6cf3c77be62d82c0e48c8a04a5ed2d2e73035 - md5: 8ee01a693aecff5432069eaaf1183c45 - depends: - - libhwloc >=2.13.0,<2.13.1.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: APACHE - purls: [] - size: 156515 - timestamp: 1778673901757 -- pypi: https://files.pythonhosted.org/packages/ac/e7/992d469644baa4408e2d0be36e07aa727fe0a2dea40dc9c150ca10c8c5ad/teachbooks-0.2.5-py3-none-any.whl - name: teachbooks - version: 0.2.5 - sha256: 285edf1f75275463a970b25c4bf312ff77f834304ff5c21417bcf6fb9de17235 - requires_dist: - - jupyter-book~=1.0 - - click - - psutil - - sphinx-book-theme==1.2.0 ; python_full_version >= '3.11' - - sphinx-book-theme==1.1.4 ; python_full_version < '3.11' - - pytest ; extra == 'testing' - - flaky ; extra == 'testing' - - ruff ; extra == 'lint' - - furo ; extra == 'docs' - - numpydoc ; extra == 'docs' - - sphinxcontrib-apidoc ; extra == 'docs' - - sphinx-click ; extra == 'docs' - - teachbooks[docs,lint,testing] ; extra == 'dev' - requires_python: '>=3.10' -- pypi: git+https://github.com/TeachBooks/TeachBooks-Favourites.git#ad0f301f83effb9322a5460f444d88878b30a75b - name: teachbooks-favourites - version: 1.15.1.dev1+gad0f301f8 - requires_dist: - - download-link-replacer==1.0.6 - - jupyterbook-patches==1.15.0 - - sphinx - - sphinx-accessibility==1.0.1 - - sphinx-code-examples==1.2.3 - - sphinx-dropdown-toggle==1.3.3 - - sphinx-exercise==1.2.1 - - sphinx-gated-directives==1.1.2 - - sphinx-github-alerts==1.1 - - sphinx-iframes==1.2.0 - - sphinx-image-inverter==1.1.11 - - sphinx-last-updated-by-git @ git+https://github.com/TeachBooks/sphinx-last-updated-by-git@986142b - - sphinx-launch-buttons==1.0.7 - - sphinx-metadata-figure==1.5.1 - - sphinx-named-colors==1.0.3 - - sphinx-nb-execution-patterns==1.1.0 - - sphinx-proof==0.4.0 - - sphinx-sticky-margin==1.1.4 - - sphinx-thebe @ git+https://github.com/TeachBooks/Sphinx-Thebe@1f3a809 - - sphinx-togglebutton==0.4.5 - - teachbooks-fetch==0.0.1 - - teachbooks-questions==0.2.1 - - teachbooks-sphinx-tippy==1.0.15 - - teachbooks-zoomies==0.2.4 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/7f/24/77b78c112c60e2ddb16351e77f9a108628a6c3c18a618815112d79d374a2/teachbooks_fetch-0.0.1-py3-none-any.whl - name: teachbooks-fetch - version: 0.0.1 - sha256: 4233c2fdcbc6f8bb8e897e1c0fc9cdf4a9f79a2bbef8fa7c98688eebc0d28dc6 - requires_dist: - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/01/d0/99a7a3e3cce5d83566567c484cce9f2c5874c22da4cf2d420647233dbc81/teachbooks_questions-0.2.1-py3-none-any.whl - name: teachbooks-questions - version: 0.2.1 - sha256: 9e0e3f74adf62a0f13046cee9d20dde11f53161c10ba4c2b57d1548dcf9cf846 - requires_dist: - - sphinx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/05/77/8c5a7237bc99221408f12b629210b8f2176bcccfca916c09edfa8eb048e3/teachbooks_sphinx_tippy-1.0.15-py3-none-any.whl - name: teachbooks-sphinx-tippy - version: 1.0.15 - sha256: eca60b7f99005861d161db76b2ab65349e61022c219f5fe781779fc91c1d7a99 - requires_dist: - - sphinx>4 - - beautifulsoup4 - - jinja2 - - requests - - pytest ; extra == 'testing' - - sphinx-pytest ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - myst-parser ; extra == 'docs' - - furo ; extra == 'docs' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/24/74/f356db22f82eba6fd559128ae31222564f1e9e1e8b46a6ff93262621a9a2/teachbooks_zoomies-0.2.4-py3-none-any.whl - name: teachbooks-zoomies - version: 0.2.4 - sha256: 254a69e3352b9466c067a72b089cd3e5038ee62d5b1c62ff7666635cd978779e - requires_dist: - - sphinx - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda - sha256: b375e8df0d5710717c31e7c8e93c025c37fa3504aea325c7a55509f64e5d4340 - md5: e43ca10d61e55d0a8ec5d8c62474ec9e - depends: - - __win - - pywinpty >=1.1.0 - - python >=3.10 - - tornado >=6.1.0 - - python - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/terminado?source=hash-mapping - size: 23665 - timestamp: 1766513806974 -- conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - sha256: cad582d6f978276522f84bd209a5ddac824742fe2d452af6acf900f8650a73a2 - md5: f1acf5fdefa8300de697982bcb1761c9 - depends: - - python >=3.5 - - webencodings >=0.4 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/tinycss2?source=hash-mapping - size: 28285 - timestamp: 1729802975370 -- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda - sha256: f19618a3a82cc483dacf1c70a30367ee7b0c7e71b90f1f80e14feff44fbd3688 - md5: dd9eb33c99d352b6356f86964d6040f7 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: TCL - purls: [] - size: 3782376 - timestamp: 1787272860855 -- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - sha256: 91cafdb64268e43e0e10d30bd1bef5af392e69f00edd34dfaf909f69ab2da6bd - md5: b5325cf06a000c5b14970462ff5e4d58 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/tomli?source=hash-mapping - size: 21561 - timestamp: 1774492402955 -- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.8-py314h5a2d7ad_0.conda - sha256: 1cac25c190b60a4b6fbe2853c4989a4ce086564ee5f995c17d4b32885993068d - md5: 94dfb208db7d79437cfe9b4390706b5c - 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/tornado?source=hash-mapping - size: 925990 - timestamp: 1786226866739 -- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.16.1-pyhcf101f3_0.conda - sha256: 03dba5917f944c6684ab44c81daacac1624cd148e4b2cae215dcec594a210c48 - md5: a79bf97561232a31447b6246c2153ab5 - depends: - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/traitlets?source=hash-mapping - size: 116935 - timestamp: 1785761789772 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.16.0-h69aa097_0.conda - sha256: b141933ece3518f6d7b75dfb59451e2f26b405a44c18e2518a83e9a02e09315c - md5: c680b5747e8c4c8f23dca0bb7042a8fc - depends: - - typing_extensions ==4.16.0 pyhcf101f3_0 - license: PSF-2.0 - license_family: PSF - purls: [] - size: 94080 - timestamp: 1783002732887 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda - sha256: 2d888f90af0686044882c74193ec80a90ec1943145d94a7b1b048958acda1848 - md5: c70ad746c22219b9700931707482992c - depends: - - python >=3.10 - - python - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/typing-extensions?source=hash-mapping - size: 52631 - timestamp: 1783002732887 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - sha256: 3088d5d873411a56bf988eee774559335749aed6f6c28e07bf933256afb9eb6c - md5: f6d7aa696c67756a650e91e15e88223c - depends: - - python >=3.9 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/typing-utils?source=hash-mapping - size: 15183 - timestamp: 1733331395943 -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - sha256: b928c30ddcb0e3f544c6eade8352737e6e610e263276b90232db6a578ef899d8 - md5: fcb489df604d100968b737f2cb6076c6 - license: LicenseRef-Public-Domain - purls: [] - size: 118849 - timestamp: 1784250406640 -- pypi: https://files.pythonhosted.org/packages/61/73/d21edf5b204d1467e06500080a50f79d49ef2b997c79123a536d4a17d97c/uc_micro_py-2.0.0-py3-none-any.whl - name: uc-micro-py - version: 2.0.0 - sha256: 3603a3859af53e5a39bc7677713c78ea6589ff188d70f4fee165db88e22b242c - requires_dist: - - pytest ; extra == 'test' - - coverage ; extra == 'test' - - pytest-cov ; extra == 'test' - requires_python: '>=3.10' -- 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/win-64/unicodedata2-17.0.1-py314h5a2d7ad_0.conda - sha256: 9041e463044944460f73f9528f2ec491180f0ffe857e3555aa8160b81050b8d9 - md5: d6b580a13384df5155c6ca19ee66854e - 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/unicodedata2?source=hash-mapping - size: 406126 - timestamp: 1770909191618 -- conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - sha256: e0eb6c8daf892b3056f08416a96d68b0a358b7c46b99c8a50481b22631a4dfc0 - md5: e7cb0f5745e4c5035a460248334af7eb - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/uri-template?source=hash-mapping - size: 23990 - timestamp: 1733323714454 -- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda - sha256: feff959a816f7988a0893201aa9727bbb7ee1e9cec2c4f0428269b489eb93fb4 - md5: cbb88288f74dbe6ada1c6c7d0a97223e - 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: 103560 - timestamp: 1778188657149 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_41.conda - sha256: 35444c55a92e2f7f7ba26bc70f81e56e52344f7d064c0fd4b40a46a58517b79c - md5: aa805b5522c2a98fa286e551a1f48546 - depends: - - vc14_runtime >=14.51.36247 - track_features: - - vc14 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 21383 - timestamp: 1785359368566 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda - sha256: 4e4cb599cdc41bf2109d1464c127b5bcbddf548ce3e322e612afb691338b48f8 - md5: ac5333bb3d429361f23adf704cc49a78 - depends: - - ucrt >=10.0.20348.0 - - vcomp14 14.51.36247 habf1de7_41 - constrains: - - vs2015_runtime 14.51.36247.* *_41 - license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime - license_family: Proprietary - purls: [] - size: 767955 - timestamp: 1785359364369 -- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda - sha256: 731e043390c9457299484d39e427221fc868a9249540a498a5a4f6456c7744d1 - md5: 350bb67a5c8e5f1c53347ac544ab6600 - depends: - - ucrt >=10.0.20348.0 - constrains: - - vs2015_runtime 14.51.36247.* *_41 - license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime - license_family: Proprietary - purls: [] - size: 155910 - timestamp: 1785359349999 -- pypi: https://files.pythonhosted.org/packages/6d/45/563267247f0b6f7c0f8028ab92bf1664da26179a630f863933033d74ab75/wcmatch-8.5-py3-none-any.whl - name: wcmatch - version: '8.5' - sha256: 14554e409b142edeefab901dc68ad570b30a72a8ab9a79106c5d5e9a6d241bd5 - requires_dist: - - bracex>=2.1.1 - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.2-pyhd8ed1ab_0.conda - sha256: 4acf845da404e84cef1acccc66cc0156af1b83a5b5d7077b2ca19b705c561e57 - md5: 99f7755ec8648a042b0dbe906234f888 - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/wcwidth?source=hash-mapping - size: 132415 - timestamp: 1782771807703 -- conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - sha256: 21f6c8a20fe050d09bfda3fb0a9c3493936ce7d6e1b3b5f8b01319ee46d6c6f6 - md5: 6639b6b0d8b5a284f027a2003669aa65 - depends: - - python >=3.10 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/webcolors?source=hash-mapping - size: 18987 - timestamp: 1761899393153 -- conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - sha256: 19ff205e138bb056a46f9e3839935a2e60bd1cf01c8241a5e172a422fed4f9c6 - md5: 2841eb5bfc75ce15e9a0054b98dcd64d - depends: - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/webencodings?source=hash-mapping - size: 15496 - timestamp: 1733236131358 -- conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - sha256: 42a2b61e393e61cdf75ced1f5f324a64af25f347d16c60b14117393a98656397 - md5: 2f1ed718fcd829c184a6d4f0f2e07409 - depends: - - python >=3.10 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/websocket-client?source=hash-mapping - size: 61391 - timestamp: 1759928175142 -- pypi: https://files.pythonhosted.org/packages/2e/29/69cfbb602cd91690c55d38ba9fe53e6a7e76a6fa647bf38f19c138d25449/wheel-0.48.0-py3-none-any.whl - name: wheel - version: 0.48.0 - sha256: 3217dcc807155e45db462d7ef2431f5ddda0d7273b700d05a67b271ceb1287ab - requires_dist: - - packaging>=24.0 - requires_python: '>=3.9' -- 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/win-64/winpty-0.4.3-4.tar.bz2 - sha256: 9df10c5b607dd30e05ba08cbd940009305c75db242476f4e845ea06008b0a283 - md5: 1cee351bf20b830d991dbe0bc8cd7dfe - license: MIT - license_family: MIT - purls: [] - size: 1176306 -- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_2.conda - sha256: 892ad69b1a9ecc3903ed5a1b18fa097013eaf462eeed3c6ff31bf5c12e71e84b - md5: 87aee04978ab77bf4c0f42b983c216cc - depends: - - libgcc >=14 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 110446 - timestamp: 1786381242485 -- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_2.conda - sha256: 21b11bb98c41ece4ce6069d86d826b50b3d73020fb631b97e59a0521dd9d08a1 - md5: 0e21a45f1bb429b6e35e82631e60554a - depends: - - libgcc >=14 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 71362 - timestamp: 1786381239727 -- 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/win-64/zeromq-4.3.5-h3a581c9_11.conda - sha256: c3e279cb309b153152fcdd6ee6d039ad996d563c849f06be39d85b8e3351df25 - md5: f016c0c5f9c01549b259146614786192 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libsodium >=1.0.22,<1.0.23.0a0 - - krb5 >=1.22.2,<1.23.0a0 - license: MPL-2.0 - license_family: MOZILLA - purls: [] - size: 265717 - timestamp: 1779124031378 -- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda - sha256: 210bd31c22bb88f5e2a167df24c95bb5f152b2ada7502f9b8c49d1f5366db423 - md5: ba3dcdc8584155c97c648ae9c044b7a3 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/zipp?source=hash-mapping - size: 24190 - timestamp: 1779159948016 -- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_3.conda - sha256: 5a0b55df66ff07b4342e04967cef69f8bf348f6a0fb1cc1eca741c7b015dfe77 - md5: 945092a9bc1d0f250f7d5ecf51ecd471 - depends: - - libzlib 1.3.2 hfd05255_3 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Zlib - license_family: Other - purls: [] - size: 851288 - timestamp: 1785276674755 -- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda - sha256: 71332532332d13b5dbe57074ddcf82ae711bdc132affa5a2982a29ffa06dc234 - md5: 46a21c0a4e65f1a135251fc7c8663f83 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Zlib - license_family: Other - purls: [] - size: 124542 - timestamp: 1770167984883 -- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda - sha256: ca7daae4f218a11fab82cc2857f0ea518ec3f46acec60490485347a4c22c6b3e - md5: e4ac308c39d6d0e131154976da67cf3b - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libzlib >=1.3.2,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 387535 - timestamp: 1786599623274 diff --git a/pixi.toml b/pixi.toml deleted file mode 100644 index bb52dcb..0000000 --- a/pixi.toml +++ /dev/null @@ -1,23 +0,0 @@ -[workspace] -authors = ["FreekPols "] -channels = ["conda-forge"] -name = "manual" -platforms = ["win-64"] -version = "0.1.0" - -[tasks] -teachbooks = "teachbooks build book" -server = "teachbooks serve" -editor = "jupyter lab" - -[dependencies] -python = ">=3.14.7,<3.15" -jupyterlab = ">=4.6.3,<5" -numpy = ">=2.5.2,<3" -matplotlib = ">=3.11.1,<4" - -[pypi-dependencies] -teachbooks = ">=0.2.5, <0.3" -teachbooks-favourites = { git = "https://github.com/TeachBooks/TeachBooks-Favourites.git" } -sphinx-inline-tabs = ">=2025.12.21.14, <2026" -sphinx-apa-references = ">=1.0.1, <2" From bc0bf4bdbf47bf2cae40db80625a481f0e0874ca Mon Sep 17 00:00:00 2001 From: Robert Lanzafame Date: Tue, 1 Sep 2026 10:16:07 -0700 Subject: [PATCH 109/110] typo in link `book/features/draft-release.md` --- book/features/draft-release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/features/draft-release.md b/book/features/draft-release.md index 9ce1d4c..ebf5fa4 100644 --- a/book/features/draft-release.md +++ b/book/features/draft-release.md @@ -28,7 +28,7 @@ This page is useful for user type 3-5. (draft-release)= # Draft-Release Workflow -Often it is necessary to prepare, review and edit materials in parallel to material that is currently being used by students, or another target audience. This workflow enables an author to easily maintain separate versions of a book without having to repeatedly comment out lines of a table of contents or page when building different versions. It is also easy to implement in CI/CD settings (it is already implemented in the {ref}Deploy Book Workflow `, which builds our TeachBooks). +Often it is necessary to prepare, review and edit materials in parallel to material that is currently being used by students, or another target audience. This workflow enables an author to easily maintain separate versions of a book without having to repeatedly comment out lines of a table of contents or page when building different versions. It is also easy to implement in CI/CD settings (it is already implemented in the {ref}`Deploy Book Workflow `, which builds our TeachBooks). ```{admonition} Why is this useful? :class: tip From 56d1e0c5b38f8aacc10c5880646ec89c57aa128f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Nov 2026 23:02:30 +0000 Subject: [PATCH 110/110] Bump teachbooks from 0.2.5 to 0.2.7 Bumps [teachbooks](https://github.com/teachbooks/teachbooks) from 0.2.5 to 0.2.7. - [Release notes](https://github.com/teachbooks/teachbooks/releases) - [Changelog](https://github.com/TeachBooks/TeachBooks/blob/develop/CHANGELOG.md) - [Commits](https://github.com/teachbooks/teachbooks/compare/v0.2.5...v0.2.7) --- updated-dependencies: - dependency-name: teachbooks dependency-version: 0.2.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9b21af9..2efadd0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -teachbooks == 0.2.5 +teachbooks == 0.2.7 sphinx-inline-tabs git+https://github.com/TeachBooks/TeachBooks-Favourites@all_authors