From c02d82eb2020e5793239a267bb290925fc2ea9d9 Mon Sep 17 00:00:00 2001 From: Eike Waldt Date: Tue, 7 Apr 2026 17:00:51 +0200 Subject: [PATCH] docs: add release docs Signed-off-by: Eike Waldt On-behalf-of: SAP --- .custom_wordlist.txt | 1 + docs/.vitepress/config.mts | 16 +- docs/.vitepress/theme/index.ts | 29 +- docs/index.md | 6 + docs/tutorials/index.md | 20 + package.json | 1 + pnpm-lock.yaml | 1259 ++++++++++++++++++++++++++---- repos-config.json | 13 + repos-config.local.json | 8 + requirements.txt | 1 + src/aggregate.py | 14 + src/aggregation/__init__.py | 3 + src/aggregation/constants.py | 40 + src/aggregation/release_notes.py | 194 +++++ src/aggregation/releases.py | 287 +++++++ src/aggregation/transformer.py | 82 ++ 16 files changed, 1816 insertions(+), 158 deletions(-) create mode 100644 src/aggregation/constants.py create mode 100644 src/aggregation/release_notes.py create mode 100644 src/aggregation/releases.py diff --git a/.custom_wordlist.txt b/.custom_wordlist.txt index e464644..bdb9b7c 100644 --- a/.custom_wordlist.txt +++ b/.custom_wordlist.txt @@ -1,2 +1,3 @@ cna hda +passt diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index eb882f7..a90ef76 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -23,6 +23,12 @@ export default defineConfig({ /\/explanation\/index$/, /\/reference\/index$/, /\/contributing\/index$/, + // Ignore specific release notes pages that don't exist + /release-notes\/1592-17/, + /release-notes\/1877-11/, + /release-notes\/1877-12/, + // Ignore LICENSE files (e.g. from aggregated repos) + /LICENSE$/, ], head: [ [ @@ -112,14 +118,18 @@ export default defineConfig({ editLink: { pattern: ({ filePath, frontmatter }) => { // If page has GitHub metadata from aggregated content, use it - if (frontmatter.github_org && frontmatter.github_repo && frontmatter.github_source_path) { - const branch = frontmatter.github_branch || 'main'; + if ( + frontmatter.github_org && + frontmatter.github_repo && + frontmatter.github_source_path + ) { + const branch = frontmatter.github_branch || "main"; return `https://github.com/${frontmatter.github_org}/${frontmatter.github_repo}/edit/${branch}/${frontmatter.github_source_path}`; } // Fallback for pages native to docs-ng (no GitHub metadata) return `https://github.com/gardenlinux/docs-ng/edit/main/docs/${filePath}`; }, - text: 'Edit this page on GitHub' + text: "Edit this page on GitHub", }, search: { diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 80dbe5b..d34c3cb 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -1,10 +1,35 @@ +import { h, nextTick, watch } from 'vue' +import type { Theme } from 'vitepress' import DefaultTheme from 'vitepress/theme' +import { useData } from 'vitepress' +import { createMermaidRenderer } from 'vitepress-mermaid-renderer' import './style.css' import SectionIndex from './components/SectionIndex.vue' export default { extends: DefaultTheme, + Layout: () => { + const { isDark } = useData() + + const initMermaid = () => { + createMermaidRenderer({ + // Use base theme; colors are set inline per diagram + theme: isDark.value ? 'dark' : 'default', + }) + } + + nextTick(() => initMermaid()) + + watch( + () => isDark.value, + () => { + initMermaid() + } + ) + + return h(DefaultTheme.Layout) + }, enhanceApp({ app }) { app.component('SectionIndex', SectionIndex) - } -} + }, +} satisfies Theme diff --git a/docs/index.md b/docs/index.md index 1a04e68..86c4d7b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,6 +13,9 @@ hero: - theme: alt text: Browse Documentation link: /overview/ + - theme: alt + text: Releases + link: /reference/releases/ image: src: /gardenlinux-logo.svg alt: Garden Linux Logo @@ -33,6 +36,9 @@ features: - title: Contributing details: Guides for contributing to Garden Linux documentation and development link: /contributing/ + - title: Releases + details: Overiew which Graden Linux Releases are available + link: /reference/releases/ # - title: Legacy Documentation # details: Aggregated documentation from source repositories (being migrated) # link: /projects/gardenlinux/introduction/index diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md index 13944fa..3c1f80b 100644 --- a/docs/tutorials/index.md +++ b/docs/tutorials/index.md @@ -23,6 +23,26 @@ Want to try Garden Linux right now with zero setup cost? All three tutorials run entirely on your workstation in under 5 minutes. ::: +:::danger Recommended First Tutorial +Want to try Garden Linux right now with zero setup cost? + +- **Linux**: [First Boot on KVM](./local/first-boot-kvm.md) or [First Boot on Lima](./local/first-boot-lima.md) +- **macOS**: [First Boot on Lima](./local/first-boot-lima.md) +- **Any OS with Container Engine**: [First Boot as OCI Container](./container/first-boot-oci.md) + +All three tutorials run entirely on your workstation in under 5 minutes. +::: + +:::warning Recommended First Tutorial +Want to try Garden Linux right now with zero setup cost? + +- **Linux**: [First Boot on KVM](./local/first-boot-kvm.md) or [First Boot on Lima](./local/first-boot-lima.md) +- **macOS**: [First Boot on Lima](./local/first-boot-lima.md) +- **Any OS with Container Engine**: [First Boot as OCI Container](./container/first-boot-oci.md) + +All three tutorials run entirely on your workstation in under 5 minutes. +::: + ## About Tutorials diff --git a/package.json b/package.json index 42dde72..d10edf4 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "js-yaml": "4.1.1", "lodash-es": "4.18.1", "vitepress": "1.6.3", + "vitepress-mermaid-renderer": "^1.1.20", "vitepress-sidebar": "1.31.1", "vue": "3.5.16" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce4e1f8..c380ba1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,10 @@ importers: version: 4.18.1 vitepress: specifier: 1.6.3 - version: 1.6.3(@algolia/client-search@5.50.0)(@types/node@20.11.27)(postcss@8.5.8)(search-insights@2.17.3) + version: 1.6.3(@algolia/client-search@5.50.1)(@types/node@20.11.27)(postcss@8.5.8)(search-insights@2.17.3) + vitepress-mermaid-renderer: + specifier: ^1.1.20 + version: 1.1.20(mermaid@11.14.0)(vue@3.5.16) vitepress-sidebar: specifier: 1.31.1 version: 1.31.1 @@ -48,8 +51,8 @@ importers: packages: - '@algolia/abtesting@1.16.0': - resolution: {integrity: sha512-alHFZ68/i9qLC/muEB07VQ9r7cB8AvCcGX6dVQi2PNHhc/ZQRmmFAv8KK1ay4UiseGSFr7f0nXBKsZ/jRg7e4g==} + '@algolia/abtesting@1.16.1': + resolution: {integrity: sha512-Xxk4l00pYI+jE0PNw8y0MvsQWh5278WRtZQav8/BMMi3HKi2xmeuqe11WJ3y8/6nuBHdv39w76OpJb09TMfAVQ==} engines: {node: '>= 14.0.0'} '@algolia/autocomplete-core@1.17.7': @@ -72,58 +75,61 @@ packages: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/client-abtesting@5.50.0': - resolution: {integrity: sha512-mfgUdLQNxOAvCZUGzPQxjahEWEPuQkKlV0ZtGmePOa9ZxIQZlk31vRBNbM6ScU8jTH41SCYE77G/lCifDr1SVw==} + '@algolia/client-abtesting@5.50.1': + resolution: {integrity: sha512-4peZlPXMwTOey9q1rQKMdCnwZb/E95/1e+7KujXpLLSh0FawJzg//U2NM+r4AiJy4+naT2MTBhj0K30yshnVTA==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.50.0': - resolution: {integrity: sha512-5mjokeKYyPaP3Q8IYJEnutI+O4dW/Ixxx5IgsSxT04pCfGqPXxTOH311hTQxyNpcGGEOGrMv8n8Z+UMTPamioQ==} + '@algolia/client-analytics@5.50.1': + resolution: {integrity: sha512-i+aWHHG8NZvGFHtPeMZkxL2Loc6Fm7iaRo15lYSMx8gFL+at9vgdWxhka7mD1fqxkrxXsQstUBCIsSY8FvkEOw==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.50.0': - resolution: {integrity: sha512-emtOvR6dl3rX3sBJXXbofMNHU1qMQqQSWu319RMrNL5BWoBqyiq7y0Zn6cjJm7aGHV/Qbf+KCCYeWNKEMPI3BQ==} + '@algolia/client-common@5.50.1': + resolution: {integrity: sha512-Hw52Fwapyk/7hMSV/fI4+s3H9MGZEUcRh4VphyXLAk2oLYdndVUkc6KBi0zwHSzwPAr+ZBwFPe2x6naUt9mZGw==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.50.0': - resolution: {integrity: sha512-IerGH2/hcj/6bwkpQg/HHRqmlGN1XwygQWythAk0gZFBrghs9danJaYuSS3ShzLSVoIVth4jY5GDPX9Lbw5cgg==} + '@algolia/client-insights@5.50.1': + resolution: {integrity: sha512-Bn/wtwhJ7p1OD/6pY+Zzn+zlu2N/SJnH46md/PAbvqIzmjVuwjNwD4y0vV5Ov8naeukXdd7UU9v550+v8+mtlg==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.50.0': - resolution: {integrity: sha512-3idPJeXn5L0MmgP9jk9JJqblrQ/SguN93dNK9z9gfgyupBhHnJMOEjrRYcVgTIfvG13Y04wO+Q0FxE2Ut8PVbA==} + '@algolia/client-personalization@5.50.1': + resolution: {integrity: sha512-0V4Tu0RWR8YxkgI9EPVOZHGE4K5pEIhkLNN0CTkP/rnPsqaaSQpNMYW3/mGWdiKOWbX0iVmwLB9QESk3H0jS5g==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.50.0': - resolution: {integrity: sha512-q7qRoWrQK1a8m5EFQEmPlo7+pg9mVQ8X5jsChtChERre0uS2pdYEDixBBl0ydBSGkdGbLUDufcACIhH/077E4g==} + '@algolia/client-query-suggestions@5.50.1': + resolution: {integrity: sha512-jofcWNYMXJDDr87Z2eivlWY6o71Zn7F7aOvQCXSDAo9QTlyf7BhXEsZymLUvF0O1yU9Q9wvrjAWn8uVHYnAvgw==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.50.0': - resolution: {integrity: sha512-Jc360x4yqb3eEg4OY4KEIdGePBxZogivKI+OGIU8aLXgAYPTECvzeOBc90312yHA1hr3AeRlAFl0rIc8lQaIrQ==} + '@algolia/client-search@5.50.1': + resolution: {integrity: sha512-OteRb8WubcmEvU0YlMJwCXs3Q6xrdkb0v50/qZBJP1TF0CvujFZQM++9BjEkTER/Jr9wbPHvjSFKnbMta0b4dQ==} engines: {node: '>= 14.0.0'} - '@algolia/ingestion@1.50.0': - resolution: {integrity: sha512-OS3/Viao+NPpyBbEY3tf6hLewppG+UclD+9i0ju56mq2DrdMJFCkEky6Sk9S5VPcbLzxzg3BqBX6u9Q35w19aQ==} + '@algolia/ingestion@1.50.1': + resolution: {integrity: sha512-0GmfSgDQK6oiIVXnJvGxtNFOfosBspRTR7csCOYCTL1P8QtxX2vDCIKwTM7xdSAEbJaZ43QlWg25q0Qdsndz8Q==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.50.0': - resolution: {integrity: sha512-/znwgSiGufpbJVIoDmeQaHtTq+OMdDawFRbMSJVv+12n79hW+qdQXS8/Uu3BD3yn0BzgVFJEvrsHrCsInZKdhw==} + '@algolia/monitoring@1.50.1': + resolution: {integrity: sha512-ySuigKEe4YjYV3si8NVk9BHQpFj/1B+ON7DhhvTvbrZJseHQQloxzq0yHwKmznSdlO6C956fx4pcfOKkZClsyg==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.50.0': - resolution: {integrity: sha512-dHjUfu4jfjdQiKDpCpAnM7LP5yfG0oNShtfpF5rMCel6/4HIoqJ4DC4h5GKDzgrvJYtgAhblo0AYBmOM00T+lQ==} + '@algolia/recommend@5.50.1': + resolution: {integrity: sha512-Cp8T/B0gVmjFlzzp6eP47hwKh5FGyeqQp1N48/ANDdvdiQkPqLyFHQVDwLBH0LddfIPQE+yqmZIgmKc82haF4A==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.50.0': - resolution: {integrity: sha512-bffIbUljAWnh/Ctu5uScORajuUavqmZ0ACYd1fQQeSSYA9NNN83ynO26pSc2dZRXpSK0fkc1//qSSFXMKGu+aw==} + '@algolia/requester-browser-xhr@5.50.1': + resolution: {integrity: sha512-XKdGGLikfrlK66ZSXh/vWcXZZ8Vg3byDFbJD8pwEvN1FoBRGxhxya476IY2ohoTymLa4qB5LBRlIa+2TLHx3Uw==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.50.0': - resolution: {integrity: sha512-y0EwNvPGvkM+yTAqqO6Gpt9wVGm3CLDtpLvNEiB3VGvN3WzfkjZGtLUsG/ru2kVJIIU7QcV0puuYgEpBeFxcJg==} + '@algolia/requester-fetch@5.50.1': + resolution: {integrity: sha512-mBAU6WyVsDwhHyGM+nodt1/oebHxgvuLlOAoMGbj/1i6LygDHZWDgL1t5JEs37x9Aywv7ZGhqbM1GsfZ54sU6g==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.50.0': - resolution: {integrity: sha512-xpwefe4fCOWnZgXCbkGpqQY6jgBSCf2hmgnySbyzZIccrv3SoashHKGPE4x6vVG+gdHrGciMTAcDo9HOZwH22Q==} + '@algolia/requester-node-http@5.50.1': + resolution: {integrity: sha512-qmo1LXrNKLHvJE6mdQbLnsZAoZvj7VyF2ft4xmbSGWI2WWm87fx/CjUX4kEExt4y0a6T6nEts6ofpUfH5TEE1A==} engines: {node: '>= 14.0.0'} + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -141,6 +147,24 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} + '@braintree/sanitize-url@7.1.2': + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} + + '@chevrotain/cst-dts-gen@12.0.0': + resolution: {integrity: sha512-fSL4KXjTl7cDgf0B5Rip9Q05BOrYvkJV/RrBTE/bKDN096E4hN/ySpcBK5B24T76dlQ2i32Zc3PAE27jFnFrKg==} + + '@chevrotain/gast@12.0.0': + resolution: {integrity: sha512-1ne/m3XsIT8aEdrvT33so0GUC+wkctpUPK6zU9IlOyJLUbR0rg4G7ZiApiJbggpgPir9ERy3FRjT6T7lpgetnQ==} + + '@chevrotain/regexp-to-ast@12.0.0': + resolution: {integrity: sha512-p+EW9MaJwgaHguhoqwOtx/FwuGr+DnNn857sXWOi/mClXIkPGl3rn7hGNWvo31HA3vyeQxjqe+H36yZJwYU8cA==} + + '@chevrotain/types@12.0.0': + resolution: {integrity: sha512-S+04vjFQKeuYw0/eW3U52LkAHQsB1ASxsPGsLPUyQgrZ2iNNibQrsidruDzjEX2JYfespXMG0eZmXlhA6z7nWA==} + + '@chevrotain/utils@12.0.0': + resolution: {integrity: sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA==} + '@docsearch/css@3.8.2': resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==} @@ -302,12 +326,15 @@ packages: cpu: [x64] os: [win32] - '@iconify-json/simple-icons@1.2.76': - resolution: {integrity: sha512-lLRlA8yaf+1L5VCPRvR9lynoSklsddKHEylchmZJKdj/q2xVQ1ZAEJ8SCQlv9cbgtMefnlyM98U+8Si2aoFZPA==} + '@iconify-json/simple-icons@1.2.77': + resolution: {integrity: sha512-oaENvo6C3BkAEWMlcQA3XemxU9v2SFOTlApSUCODAkIu1haeLCjzrmH3HgmGqjRnJjM+LevO8sA+MgdMHBFBDA==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + '@iconify/utils@3.1.0': + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -315,6 +342,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@mermaid-js/parser@1.1.0': + resolution: {integrity: sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -468,9 +498,105 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.8': + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} @@ -501,6 +627,9 @@ packages: '@types/node@20.11.27': resolution: {integrity: sha512-qyUZfMnCg1KEz57r7pzFtSGt49f6RPkPBis3Vo4PbS7roQEDn22hiHzl/Lo1q4i4hDEgBJmBF/NTNg2XR0HbFg==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -510,6 +639,9 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@upsetjs/venn.js@2.0.0': + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} + '@vitejs/plugin-vue@5.2.4': resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -555,8 +687,8 @@ packages: '@vue/shared@3.5.16': resolution: {integrity: sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==} - '@vue/shared@3.5.31': - resolution: {integrity: sha512-nBxuiuS9Lj5bPkPbWogPUnjxxWpkRniX7e5UBQDWl6Fsf4roq9wwV+cR7ezQ4zXswNvPIlsdj1slcLB7XCsRAw==} + '@vue/shared@3.5.32': + resolution: {integrity: sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==} '@vueuse/core@12.8.2': resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==} @@ -608,8 +740,13 @@ packages: '@vueuse/shared@12.8.2': resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} - algoliasearch@5.50.0: - resolution: {integrity: sha512-yE5I83Q2s8euVou8Y3feXK08wyZInJWLYXgWO6Xti9jBUEZAGUahyeQ7wSZWkifLWVnQVKEz5RAmBlXG5nqxog==} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + algoliasearch@5.50.1: + resolution: {integrity: sha512-/bwdue1/8LWELn/DBalGRfuLsXBLXULJo/yOeavJtDu8rBwxIzC6/Rz9Jg19S21VkJvRuZO1k8CZXBMS73mYbA==} engines: {node: '>= 14.0.0'} ansi-regex@5.0.1: @@ -644,8 +781,8 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - baseline-browser-mapping@2.10.13: - resolution: {integrity: sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw==} + baseline-browser-mapping@2.10.16: + resolution: {integrity: sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==} engines: {node: '>=6.0.0'} hasBin: true @@ -660,8 +797,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - caniuse-lite@1.0.30001784: - resolution: {integrity: sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw==} + caniuse-lite@1.0.30001786: + resolution: {integrity: sha512-4oxTZEvqmLLrERwxO76yfKM7acZo310U+v4kqexI2TL1DkkUEMT8UijrxxcnVdxR3qkVf5awGRX+4Z6aPHVKrA==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -672,6 +809,15 @@ packages: character-entities-legacy@3.0.0: resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + chevrotain-allstar@0.4.1: + resolution: {integrity: sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA==} + peerDependencies: + chevrotain: ^12.0.0 + + chevrotain@12.0.0: + resolution: {integrity: sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ==} + engines: {node: '>=22.0.0'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -682,6 +828,17 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + copy-anything@4.0.5: resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} engines: {node: '>=18'} @@ -691,6 +848,12 @@ packages: engines: {node: ^20.10.0 || ^22.11.0 || >=24.0.0} hasBin: true + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -698,6 +861,168 @@ packages: csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.33.2: + resolution: {integrity: sha512-sj4HXd3DokGhzZAdjDejGvTPLqlt84vNFN8m7bGsOzDY5DyVcxIb2ejIXat2Iy7HxWhdT/N1oKyheJ5YdpsGuw==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.14: + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} + + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} + + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -705,11 +1030,14 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dompurify@3.3.3: + resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.330: - resolution: {integrity: sha512-jFNydB5kFtYUobh4IkWUnXeyDbjf/r9gcUEXe1xcrcUxIGfTdzPXA+ld6zBRbwvgIGVzDll/LTIiDztEtckSnA==} + electron-to-chromium@1.5.332: + resolution: {integrity: sha512-7OOtytmh/rINMLwaFTbcMVvYXO3AUm029X0LcyfYk0B557RlPkdpTpnH9+htMlfu5dKwOmT0+Zs2Aw+lnn6TeQ==} emoji-regex-xs@1.0.0: resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} @@ -769,6 +1097,9 @@ packages: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + hast-util-to-html@9.0.5: resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} @@ -781,6 +1112,17 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -807,10 +1149,27 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + katex@0.16.45: + resolution: {integrity: sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==} + hasBin: true + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} + langium@4.2.2: + resolution: {integrity: sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + lodash-es@4.18.1: resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} @@ -823,9 +1182,17 @@ packages: mark.js@8.11.1: resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + marked@16.4.2: + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + engines: {node: '>= 20'} + hasBin: true + mdast-util-to-hast@13.2.1: resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + mermaid@11.14.0: + resolution: {integrity: sha512-GSGloRsBs+JINmmhl0JDwjpuezCsHB4WGI4NASHxL3fHo3o/BRXTxhDLKnln8/Q0lRFRyDdEjmk1/d5Sn1Xz8g==} + micromark-util-character@2.1.1: resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} @@ -855,13 +1222,16 @@ packages: mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - node-releases@2.0.36: - resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} normalize-range@0.1.2: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} @@ -873,6 +1243,12 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -881,12 +1257,24 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -894,8 +1282,8 @@ packages: resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} - preact@10.29.0: - resolution: {integrity: sha512-wSAGyk2bYR1c7t3SZ3jHcM6xy0lcBcDel6lODcs9ME6Th++Dx2KU+6D3HD8wMMKGA8Wpw7OMd3/4RGzYRpzwRg==} + preact@10.29.1: + resolution: {integrity: sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg==} property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} @@ -916,11 +1304,23 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + rollup@4.60.1: resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + search-insights@2.17.3: resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} @@ -980,6 +1380,9 @@ packages: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + superjson@2.2.6: resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} engines: {node: '>=16'} @@ -987,9 +1390,20 @@ packages: tabbable@6.4.0: resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + tinyexec@1.1.1: + resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + engines: {node: '>=18'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -1014,6 +1428,10 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} @@ -1051,6 +1469,13 @@ packages: terser: optional: true + vitepress-mermaid-renderer@1.1.20: + resolution: {integrity: sha512-lBe0KBkrTtXZIczNlwlVm7JVcrmCjSR7n5J3hEBg2K4/v5U12oW3MJ1hqh9cpY2avLKL66YBqxn3fJjey3zqWw==} + engines: {node: '>=16.0.0'} + peerDependencies: + mermaid: ^11.0.0 + vue: ^3.0.0 + vitepress-sidebar@1.31.1: resolution: {integrity: sha512-Hx10z5le87jIIXVfKq4AtRrVqVJJ/1cQsZhmwT+ghVR/j4Yor9FjNMszyigJ54ktrEtoxSLO6C9tvuLauT4lZA==} engines: {node: '>=18.0.0'} @@ -1067,6 +1492,26 @@ packages: postcss: optional: true + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + vue@3.5.16: resolution: {integrity: sha512-rjOV2ecxMd5SiAmof2xzh2WxntRcigkX/He4YFJ6WdRvVUrbt6DxC1Iujh10XLl8xCDRDtGKMeO3D+pRQ1PP9w==} peerDependencies: @@ -1093,117 +1538,122 @@ packages: snapshots: - '@algolia/abtesting@1.16.0': + '@algolia/abtesting@1.16.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)': + '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)': dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0) - '@algolia/client-search': 5.50.0 - algoliasearch: 5.50.0 + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) + '@algolia/client-search': 5.50.1 + algoliasearch: 5.50.1 - '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)': + '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)': dependencies: - '@algolia/client-search': 5.50.0 - algoliasearch: 5.50.0 + '@algolia/client-search': 5.50.1 + algoliasearch: 5.50.1 - '@algolia/client-abtesting@5.50.0': + '@algolia/client-abtesting@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/client-analytics@5.50.0': + '@algolia/client-analytics@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/client-common@5.50.0': {} + '@algolia/client-common@5.50.1': {} - '@algolia/client-insights@5.50.0': + '@algolia/client-insights@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/client-personalization@5.50.0': + '@algolia/client-personalization@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/client-query-suggestions@5.50.0': + '@algolia/client-query-suggestions@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/client-search@5.50.0': + '@algolia/client-search@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/ingestion@1.50.0': + '@algolia/ingestion@1.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/monitoring@1.50.0': + '@algolia/monitoring@1.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/recommend@5.50.0': + '@algolia/recommend@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 - '@algolia/requester-browser-xhr@5.50.0': + '@algolia/requester-browser-xhr@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 + '@algolia/client-common': 5.50.1 - '@algolia/requester-fetch@5.50.0': + '@algolia/requester-fetch@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 + '@algolia/client-common': 5.50.1 - '@algolia/requester-node-http@5.50.0': + '@algolia/requester-node-http@5.50.1': dependencies: - '@algolia/client-common': 5.50.0 + '@algolia/client-common': 5.50.1 + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.1.1 '@babel/helper-string-parser@7.27.1': {} @@ -1218,12 +1668,29 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@braintree/sanitize-url@7.1.2': {} + + '@chevrotain/cst-dts-gen@12.0.0': + dependencies: + '@chevrotain/gast': 12.0.0 + '@chevrotain/types': 12.0.0 + + '@chevrotain/gast@12.0.0': + dependencies: + '@chevrotain/types': 12.0.0 + + '@chevrotain/regexp-to-ast@12.0.0': {} + + '@chevrotain/types@12.0.0': {} + + '@chevrotain/utils@12.0.0': {} + '@docsearch/css@3.8.2': {} - '@docsearch/js@3.8.2(@algolia/client-search@5.50.0)(search-insights@2.17.3)': + '@docsearch/js@3.8.2(@algolia/client-search@5.50.1)(search-insights@2.17.3)': dependencies: - '@docsearch/react': 3.8.2(@algolia/client-search@5.50.0)(search-insights@2.17.3) - preact: 10.29.0 + '@docsearch/react': 3.8.2(@algolia/client-search@5.50.1)(search-insights@2.17.3) + preact: 10.29.1 transitivePeerDependencies: - '@algolia/client-search' - '@types/react' @@ -1231,12 +1698,12 @@ snapshots: - react-dom - search-insights - '@docsearch/react@3.8.2(@algolia/client-search@5.50.0)(search-insights@2.17.3)': + '@docsearch/react@3.8.2(@algolia/client-search@5.50.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)(search-insights@2.17.3) - '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0) + '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) '@docsearch/css': 3.8.2 - algoliasearch: 5.50.0 + algoliasearch: 5.50.1 optionalDependencies: search-insights: 2.17.3 transitivePeerDependencies: @@ -1311,12 +1778,18 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true - '@iconify-json/simple-icons@1.2.76': + '@iconify-json/simple-icons@1.2.77': dependencies: '@iconify/types': 2.0.0 '@iconify/types@2.0.0': {} + '@iconify/utils@3.1.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + mlly: 1.8.2 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -1328,6 +1801,10 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} + '@mermaid-js/parser@1.1.0': + dependencies: + langium: 4.2.2 + '@pkgjs/parseargs@0.11.0': optional: true @@ -1446,8 +1923,127 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@types/d3-array@3.2.2': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.2 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.8': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.7 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.8 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + '@types/estree@1.0.8': {} + '@types/geojson@7946.0.16': {} + '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 @@ -1482,12 +2078,20 @@ snapshots: dependencies: undici-types: 5.26.5 + '@types/trusted-types@2.0.7': + optional: true + '@types/unist@3.0.3': {} '@types/web-bluetooth@0.0.21': {} '@ungap/structured-clone@1.3.0': {} + '@upsetjs/venn.js@2.0.0': + optionalDependencies: + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@20.11.27))(vue@3.5.16)': dependencies: vite: 5.4.21(@types/node@20.11.27) @@ -1565,7 +2169,7 @@ snapshots: '@vue/shared@3.5.16': {} - '@vue/shared@3.5.31': {} + '@vue/shared@3.5.32': {} '@vueuse/core@12.8.2': dependencies: @@ -1594,22 +2198,24 @@ snapshots: transitivePeerDependencies: - typescript - algoliasearch@5.50.0: - dependencies: - '@algolia/abtesting': 1.16.0 - '@algolia/client-abtesting': 5.50.0 - '@algolia/client-analytics': 5.50.0 - '@algolia/client-common': 5.50.0 - '@algolia/client-insights': 5.50.0 - '@algolia/client-personalization': 5.50.0 - '@algolia/client-query-suggestions': 5.50.0 - '@algolia/client-search': 5.50.0 - '@algolia/ingestion': 1.50.0 - '@algolia/monitoring': 1.50.0 - '@algolia/recommend': 5.50.0 - '@algolia/requester-browser-xhr': 5.50.0 - '@algolia/requester-fetch': 5.50.0 - '@algolia/requester-node-http': 5.50.0 + acorn@8.16.0: {} + + algoliasearch@5.50.1: + dependencies: + '@algolia/abtesting': 1.16.1 + '@algolia/client-abtesting': 5.50.1 + '@algolia/client-analytics': 5.50.1 + '@algolia/client-common': 5.50.1 + '@algolia/client-insights': 5.50.1 + '@algolia/client-personalization': 5.50.1 + '@algolia/client-query-suggestions': 5.50.1 + '@algolia/client-search': 5.50.1 + '@algolia/ingestion': 1.50.1 + '@algolia/monitoring': 1.50.1 + '@algolia/recommend': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 ansi-regex@5.0.1: {} @@ -1630,7 +2236,7 @@ snapshots: autoprefixer@10.4.0(postcss@8.5.8): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001784 + caniuse-lite: 1.0.30001786 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -1639,7 +2245,7 @@ snapshots: balanced-match@1.0.2: {} - baseline-browser-mapping@2.10.13: {} + baseline-browser-mapping@2.10.16: {} birpc@2.9.0: {} @@ -1649,13 +2255,13 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.13 - caniuse-lite: 1.0.30001784 - electron-to-chromium: 1.5.330 - node-releases: 2.0.36 + baseline-browser-mapping: 2.10.16 + caniuse-lite: 1.0.30001786 + electron-to-chromium: 1.5.332 + node-releases: 2.0.37 update-browserslist-db: 1.2.3(browserslist@4.28.2) - caniuse-lite@1.0.30001784: {} + caniuse-lite@1.0.30001786: {} ccount@2.0.1: {} @@ -1663,6 +2269,19 @@ snapshots: character-entities-legacy@3.0.0: {} + chevrotain-allstar@0.4.1(chevrotain@12.0.0): + dependencies: + chevrotain: 12.0.0 + lodash-es: 4.18.1 + + chevrotain@12.0.0: + dependencies: + '@chevrotain/cst-dts-gen': 12.0.0 + '@chevrotain/gast': 12.0.0 + '@chevrotain/regexp-to-ast': 12.0.0 + '@chevrotain/types': 12.0.0 + '@chevrotain/utils': 12.0.0 + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -1671,12 +2290,26 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@7.2.0: {} + + commander@8.3.0: {} + + confbox@0.1.8: {} + copy-anything@4.0.5: dependencies: is-what: 5.5.0 corepack@0.34.6: {} + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -1685,15 +2318,209 @@ snapshots: csstype@3.2.3: {} + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.2): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.33.2 + + cytoscape-fcose@2.2.0(cytoscape@3.33.2): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.33.2 + + cytoscape@3.33.2: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.1.0 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.2: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.2 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.14: + dependencies: + d3: 7.9.0 + lodash-es: 4.18.1 + + dayjs@1.11.20: {} + + delaunator@5.1.0: + dependencies: + robust-predicates: 3.0.3 + dequal@2.0.3: {} devlop@1.1.0: dependencies: dequal: 2.0.3 + dompurify@3.3.3: + optionalDependencies: + '@types/trusted-types': 2.0.7 + eastasianwidth@0.2.0: {} - electron-to-chromium@1.5.330: {} + electron-to-chromium@1.5.332: {} emoji-regex-xs@1.0.0: {} @@ -1769,6 +2596,8 @@ snapshots: section-matter: 1.0.0 strip-bom-string: 1.0.0 + hachure-fill@0.5.2: {} + hast-util-to-html@9.0.5: dependencies: '@types/hast': 3.0.4 @@ -1791,6 +2620,14 @@ snapshots: html-void-elements@3.0.0: {} + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + internmap@1.0.1: {} + + internmap@2.0.3: {} + is-extendable@0.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -1814,8 +2651,27 @@ snapshots: dependencies: argparse: 2.0.1 + katex@0.16.45: + dependencies: + commander: 8.3.0 + + khroma@2.1.0: {} + kind-of@6.0.3: {} + langium@4.2.2: + dependencies: + '@chevrotain/regexp-to-ast': 12.0.0 + chevrotain: 12.0.0 + chevrotain-allstar: 0.4.1(chevrotain@12.0.0) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + lodash-es@4.18.1: {} lru-cache@10.4.3: {} @@ -1826,6 +2682,8 @@ snapshots: mark.js@8.11.1: {} + marked@16.4.2: {} + mdast-util-to-hast@13.2.1: dependencies: '@types/hast': 3.0.4 @@ -1838,6 +2696,30 @@ snapshots: unist-util-visit: 5.1.0 vfile: 6.0.3 + mermaid@11.14.0: + dependencies: + '@braintree/sanitize-url': 7.1.2 + '@iconify/utils': 3.1.0 + '@mermaid-js/parser': 1.1.0 + '@types/d3': 7.4.3 + '@upsetjs/venn.js': 2.0.0 + cytoscape: 3.33.2 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.2) + cytoscape-fcose: 2.2.0(cytoscape@3.33.2) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.14 + dayjs: 1.11.20 + dompurify: 3.3.3 + katex: 0.16.45 + khroma: 2.1.0 + lodash-es: 4.18.1 + marked: 16.4.2 + roughjs: 4.6.6 + stylis: 4.3.6 + ts-dedent: 2.2.0 + uuid: 11.1.0 + micromark-util-character@2.1.1: dependencies: micromark-util-symbol: 2.0.1 @@ -1865,9 +2747,16 @@ snapshots: mitt@3.0.1: {} + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + nanoid@3.3.11: {} - node-releases@2.0.36: {} + node-releases@2.0.37: {} normalize-range@0.1.2: {} @@ -1879,6 +2768,10 @@ snapshots: package-json-from-dist@1.0.1: {} + package-manager-detector@1.6.0: {} + + path-data-parser@0.1.0: {} + path-key@3.1.1: {} path-scurry@1.11.1: @@ -1886,10 +2779,25 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.3 + pathe@2.0.3: {} + perfect-debounce@1.0.0: {} picocolors@1.1.1: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + postcss-value-parser@4.2.0: {} postcss@8.5.8: @@ -1898,7 +2806,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - preact@10.29.0: {} + preact@10.29.1: {} property-information@7.1.0: {} @@ -1916,6 +2824,8 @@ snapshots: rfdc@1.4.1: {} + robust-predicates@3.0.3: {} + rollup@4.60.1: dependencies: '@types/estree': 1.0.8 @@ -1947,6 +2857,17 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.60.1 fsevents: 2.3.3 + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + + rw@1.3.3: {} + + safer-buffer@2.1.2: {} + search-insights@2.17.3: {} section-matter@1.0.0: @@ -2008,14 +2929,22 @@ snapshots: strip-bom-string@1.0.0: {} + stylis@4.3.6: {} + superjson@2.2.6: dependencies: copy-anything: 4.0.5 tabbable@6.4.0: {} + tinyexec@1.1.1: {} + trim-lines@3.0.1: {} + ts-dedent@2.2.0: {} + + ufo@1.6.3: {} + undici-types@5.26.5: {} unist-util-is@6.0.1: @@ -2047,6 +2976,8 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + uuid@11.1.0: {} + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 @@ -2066,24 +2997,29 @@ snapshots: '@types/node': 20.11.27 fsevents: 2.3.3 + vitepress-mermaid-renderer@1.1.20(mermaid@11.14.0)(vue@3.5.16): + dependencies: + mermaid: 11.14.0 + vue: 3.5.16 + vitepress-sidebar@1.31.1: dependencies: glob: 10.4.5 gray-matter: 4.0.3 qsu: 1.11.5 - vitepress@1.6.3(@algolia/client-search@5.50.0)(@types/node@20.11.27)(postcss@8.5.8)(search-insights@2.17.3): + vitepress@1.6.3(@algolia/client-search@5.50.1)(@types/node@20.11.27)(postcss@8.5.8)(search-insights@2.17.3): dependencies: '@docsearch/css': 3.8.2 - '@docsearch/js': 3.8.2(@algolia/client-search@5.50.0)(search-insights@2.17.3) - '@iconify-json/simple-icons': 1.2.76 + '@docsearch/js': 3.8.2(@algolia/client-search@5.50.1)(search-insights@2.17.3) + '@iconify-json/simple-icons': 1.2.77 '@shikijs/core': 2.5.0 '@shikijs/transformers': 2.5.0 '@shikijs/types': 2.5.0 '@types/markdown-it': 14.1.2 '@vitejs/plugin-vue': 5.2.4(vite@5.4.21(@types/node@20.11.27))(vue@3.5.16) '@vue/devtools-api': 7.7.9 - '@vue/shared': 3.5.31 + '@vue/shared': 3.5.32 '@vueuse/core': 12.8.2 '@vueuse/integrations': 12.8.2(focus-trap@7.8.0) focus-trap: 7.8.0 @@ -2121,6 +3057,23 @@ snapshots: - typescript - universal-cookie + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-uri@3.1.0: {} + vue@3.5.16: dependencies: '@vue/compiler-dom': 3.5.16 diff --git a/repos-config.json b/repos-config.json index 4bc1ff6..476f8bf 100644 --- a/repos-config.json +++ b/repos-config.json @@ -63,6 +63,19 @@ "assets", "_static" ] + }, + { + "name": "glrd", + "url": "https://github.com/gardenlinux/glrd", + "docs_path": "docs", + "target_path": "projects/glrd", + "ref": "docs-ng", + "commit": "c444721b728c0be0de2c19a0bc328928a0091d65", + "media_directories": [ + ".media", + "assets", + "_static" + ] } ] } diff --git a/repos-config.local.json b/repos-config.local.json index 3b27fd1..55f8022 100644 --- a/repos-config.local.json +++ b/repos-config.local.json @@ -39,6 +39,14 @@ "target_path": "projects/package-linux", "structure": "flat", "media_directories": [".media", "assets", "_static"] + }, + { + "name": "glrd", + "url": "file://../glrd", + "docs_path": "docs", + "target_path": "projects/glrd", + "structure": "flat", + "media_directories": [".media", "assets", "_static"] } ] } diff --git a/requirements.txt b/requirements.txt index a6cec20..90ebdb4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ codespell==2.4.2 pytest +glrd @ git+https://github.com/gardenlinux/glrd.git@main diff --git a/src/aggregate.py b/src/aggregate.py index 5d439db..40cf389 100755 --- a/src/aggregate.py +++ b/src/aggregate.py @@ -19,6 +19,8 @@ copy_targeted_docs, process_all_markdown, ) +from aggregation.releases import generate_release_docs +from aggregation.release_notes import generate_release_notes_docs def transform_repo_docs( @@ -214,6 +216,18 @@ def main() -> int: save_config(str(config_path), repos) print(f"\n✓ Config updated: {config_path}") + # Generate release documentation from GLRD + print(f"\n{'='*60}") + print("Generating release documentation...") + print(f"{'='*60}\n") + generate_release_docs(docs_dir) + + # Generate release notes from GitHub + print(f"\n{'='*60}") + print("Fetching release notes from GitHub...") + print(f"{'='*60}\n") + generate_release_notes_docs(docs_dir) + # Summary print(f"\n{'='*60}") print("Documentation aggregation complete!") diff --git a/src/aggregation/__init__.py b/src/aggregation/__init__.py index 98390e9..48fc13c 100644 --- a/src/aggregation/__init__.py +++ b/src/aggregation/__init__.py @@ -16,6 +16,7 @@ copy_targeted_docs, process_all_markdown, ) +from .releases import generate_release_docs __all__ = [ # Models @@ -35,4 +36,6 @@ "transform_directory_structure", "copy_targeted_docs", "process_all_markdown", + # Releases + "generate_release_docs", ] \ No newline at end of file diff --git a/src/aggregation/constants.py b/src/aggregation/constants.py new file mode 100644 index 0000000..fc210ce --- /dev/null +++ b/src/aggregation/constants.py @@ -0,0 +1,40 @@ +"""Constants and configuration for release documentation generation.""" + +# Garden Linux color palette for Mermaid Gantt charts +GANTT_THEME = """%%{init: {'theme':'base', 'themeVariables': { + 'primaryColor':'#30a46c', + 'primaryTextColor':'#fff', + 'primaryBorderColor':'#18794e', + 'lineColor':'#30a46c', + 'gridColor':'#30a46c', + 'textColor':'#009f76', + 'taskTextOutsideColor':'#009f76', + 'taskTextLightColor':'#fff', + 'taskTextDarkColor':'#fff', + 'labelTextColor':'#009f76', + 'todayLineColor':'#009f76', + 'sectionBkgColor':'#30a46c', + 'sectionBkgColor2':'#299764', + 'altSectionBkgColor':'#18794e', + 'taskBkgColor':'#30a46c', + 'taskBorderColor':'#18794e', + 'taskTextColor':'#fff', + 'activeTaskBkgColor':'#30a46c', + 'activeTaskBorderColor':'#18794e', + 'critBkgColor':'#087254', + 'critBorderColor':'#065a41', + 'doneTaskBkgColor':'#009f76', + 'doneTaskBorderColor':'#087254' +}}}%%""" + +# GitHub URLs +GITHUB_BASE_URL = "https://github.com/gardenlinux/gardenlinux" +RELEASES_TAG_URL = f"{GITHUB_BASE_URL}/releases/tag" +COMMITS_URL = f"{GITHUB_BASE_URL}/commit" + +# Lifecycle documentation anchor links +LIFECYCLE_LINKS = { + "standard": "release-lifecycle.md#standard-maintenance", + "extended": "release-lifecycle.md#extended-maintenance", + "eol": "release-lifecycle.md#end-of-maintenance", +} diff --git a/src/aggregation/release_notes.py b/src/aggregation/release_notes.py new file mode 100644 index 0000000..9e84ab9 --- /dev/null +++ b/src/aggregation/release_notes.py @@ -0,0 +1,194 @@ +"""Fetch and format release notes from GitHub.""" + +import json +import re +import subprocess +import sys +from datetime import datetime +from pathlib import Path + +from .transformer import cleanup_github_markdown + +GITHUB_API_URL = "https://api.github.com/repos/gardenlinux/gardenlinux/releases" +GITHUB_RELEASES_URL = "https://github.com/gardenlinux/gardenlinux/releases/tag" +GITHUB_COMMITS_URL = "https://github.com/gardenlinux/gardenlinux/commit" + +# Configuration +MAX_RELEASES = 200 # Include up to 200 recent releases + + +def parse_version(tag: str) -> tuple: + """Parse version string into comparable tuple for semantic versioning. + + Examples: + 2150.1.0 -> (2150, 1, 0) + 1877 -> (1877, 0, 0) + 1592.18.0 -> (1592, 18, 0) + """ + # Remove leading 'v' if present + tag = tag.lstrip('v') + + # Split by dots and convert to integers + parts = tag.split('.') + version_nums = [] + for part in parts: + # Extract numeric part (handle cases like 2150.1.0, 576.3.0) + match = re.match(r'(\d+)', part) + if match: + version_nums.append(int(match.group(1))) + else: + version_nums.append(0) + + # Pad with zeros for versions with fewer parts + while len(version_nums) < 3: + version_nums.append(0) + + return tuple(version_nums[:3]) # Take first 3 parts + + +def sort_by_version(releases: list) -> list: + """Sort releases by semantic version (highest first).""" + return sorted( + releases, + key=lambda r: parse_version(r.get("tag_name", "0")), + reverse=True + ) + + +def fetch_github_releases(per_page: int = 100) -> list: + """Fetch releases from GitHub API using curl with pagination.""" + all_releases = [] + page = 1 + max_pages = (MAX_RELEASES // per_page) + 2 # Fetch enough pages + + while page <= max_pages and len(all_releases) < MAX_RELEASES: + try: + result = subprocess.run( + ["curl", "-s", "-L", f"{GITHUB_API_URL}?per_page={per_page}&page={page}"], + capture_output=True, + text=True, + check=False, + ) + if result.returncode == 0: + page_releases = json.loads(result.stdout) + if not page_releases: + break + all_releases.extend(page_releases) + else: + break + except (json.JSONDecodeError, Exception): + break + page += 1 + + return all_releases[:MAX_RELEASES] + + +def format_release_date(date_str: str) -> str: + """Format ISO date to readable format.""" + if not date_str: + return "Unknown" + try: + dt = datetime.fromisoformat(date_str.replace("Z", "+00:00")) + return dt.strftime("%B %d, %Y") + except (ValueError, TypeError): + return date_str + + +def format_release_entry(release: dict) -> str: + """Format a single release as markdown with full content.""" + tag_name = release.get("tag_name", "Unknown") + name = release.get("name") or tag_name + body = release.get("body", "*No release notes provided*") + published_at = release.get("published_at", "") + html_url = release.get("html_url", f"{GITHUB_RELEASES_URL}/{tag_name}") + prerelease = release.get("prerelease", False) + + # Extract commit hash and create GitHub link + target = release.get("target_commitish", "") + commit_short = target[:8] if target else "" + commit_url = f"{GITHUB_COMMITS_URL}/{target}" if target else "" + + date_str = format_release_date(published_at) + + # Clean up GitHub markdown for VitePress compatibility + body = cleanup_github_markdown(body) + + # Header with Published, Commit, and GitHub Release + header = f"## {name}\n" + if prerelease: + header += "*Pre-release*\n\n" + header += f"**Published:** {date_str}\n\n" + header += f"**Commit:** [{commit_short}]({commit_url})\n\n" + header += f"**GitHub Release:** [{tag_name}]({html_url})\n\n" + + return f"{header}{body.strip()}\n" + + +def generate_release_notes_docs(docs_dir: Path) -> bool: + """Fetch GitHub release notes and generate release-notes as individual files.""" + releases_dir = docs_dir / "reference" / "releases" / "release-notes" + releases_dir.mkdir(parents=True, exist_ok=True) + + print("Fetching release notes from GitHub...") + releases = fetch_github_releases() + + if not releases: + print("Warning: No releases fetched from GitHub", file=sys.stderr) + return False + + # Filter releases (skip drafts) + filtered = [] + for release in releases: + if release.get("draft", False): + continue + filtered.append(release) + + # Sort by semantic version (highest first) + filtered = sort_by_version(filtered) + + # Limit + filtered = filtered[:MAX_RELEASES] + + # Generate individual files for each release + release_list = [] + for idx, release in enumerate(filtered): + tag_name = release.get("tag_name", "Unknown") + name = release.get("name") or tag_name + + content = format_release_entry(release) + date = format_release_date(release.get("published_at", "")) + + # Make version heading h1 (replace ## VersionName with # VersionName) + content = re.sub(r'^##\s+' + re.escape(name) + r'$', '# ' + name, content, flags=re.MULTILINE) + + # Order: highest version = 1, second = 2, etc. + release_order = idx + 1 + + page_content = f"""--- +title: "Release {tag_name}" +description: "Release notes for Garden Linux {tag_name}, published at {date}." +order: {release_order} +--- + +{content} + +## Other Releases + +- [All Releases Index](../release-notes/index.md) +""" + + # Create filename from tag + filename = tag_name.replace(".", "-") + ".md" + filepath = releases_dir / filename + filepath.write_text(page_content) + + release_list.append({ + "tag": tag_name, + "name": name, + "filename": filename, + "date": format_release_date(release.get("published_at", "")), + }) + print(f" Created: {filepath.relative_to(docs_dir)}") + + print("Release notes generation complete.") + return True diff --git a/src/aggregation/releases.py b/src/aggregation/releases.py new file mode 100644 index 0000000..4e7f5b0 --- /dev/null +++ b/src/aggregation/releases.py @@ -0,0 +1,287 @@ +"""Generate release documentation from GLRD.""" + +import json +import subprocess +import sys +from pathlib import Path +from typing import Optional + +from .constants import ( + GANTT_THEME, + RELEASES_TAG_URL, + COMMITS_URL, + LIFECYCLE_LINKS, +) + + +def run_glrd_json(args: list[str]) -> Optional[dict]: + """Run glrd command with JSON output and return parsed data.""" + try: + result = subprocess.run( + ["glrd"] + args + ["--output-format", "json"], + capture_output=True, + text=True, + check=False, + ) + if result.returncode == 0: + return json.loads(result.stdout) + print(f"glrd command failed: {result.stderr}", file=sys.stderr) + return None + except FileNotFoundError: + print("glrd not found - install with: pip install glrd", file=sys.stderr) + return None + except (json.JSONDecodeError, Exception) as e: + print(f"Error running glrd: {e}", file=sys.stderr) + return None + + +def format_version(release: dict) -> tuple[str, str]: + """Extract version string and link from release data. + + Returns: + Tuple of (version_string, version_link) + - Minor releases: link to release notes page + - Major releases: no link (just plain text) + """ + version_obj = release.get("version", {}) + + has_minor = "minor" in version_obj + + if "major" in version_obj and "minor" in version_obj: + if "patch" in version_obj: + version_str = f"{version_obj['major']}.{version_obj['minor']}.{version_obj['patch']}" + else: + version_str = f"{version_obj['major']}.{version_obj['minor']}" + elif "major" in version_obj: + version_str = str(version_obj["major"]) + else: + return "N/A", "N/A" + + # Only link minor releases to release notes; major releases have no link + if has_minor: + version_link = f"[{version_str}](release-notes/{version_str.replace('.', '-')}.html)" + else: + version_link = version_str # Major release - no link + + return version_str, version_link + + +def format_commit(release: dict) -> str: + """Extract commit info and create GitHub link from release data.""" + git_info = release.get("git", {}) + commit_short = git_info.get("commit_short", "") + commit_full = git_info.get("commit", "") + + if commit_short and commit_full: + return f"[`{commit_short}`]({COMMITS_URL}/{commit_full})" + elif commit_short: + return f"`{commit_short}`" + return "—" + + +def format_lifecycle_date(lifecycle: dict, key: str) -> str: + """Extract and format lifecycle date with link.""" + date_obj = lifecycle.get(key, {}) + isodate = date_obj.get("isodate", "") + + if not isodate: + return "—" + + # Map keys to LIFECYCLE_LINKS + link_key = key + if key == "released": + link_key = "standard" # released = start of standard maintenance + + anchor = LIFECYCLE_LINKS.get(link_key, "") + return f"[{isodate}]({anchor})" if anchor else isodate + + +def generate_mermaid_gantt(releases_data: dict) -> str: + """Generate Mermaid Gantt chart from GLRD JSON data.""" + if not releases_data or "releases" not in releases_data: + return "" + + releases = releases_data.get("releases", []) + major_releases = [r for r in releases if r.get("type") == "major"] + + if not major_releases: + return "" + + gantt = GANTT_THEME + """ +gantt + title Garden Linux Release Maintenance Phases + dateFormat YYYY-MM-DD + axisFormat %m/%y +""" + for release in major_releases: + version = release.get("version", {}).get("major") + if not version: + continue + + lifecycle = release.get("lifecycle", {}) + released = lifecycle.get("released", {}) + extended = lifecycle.get("extended", {}) + eol = lifecycle.get("eol", {}) + + if not released or not eol: + continue + + released_date = released.get("isodate", "") + extended_date = extended.get("isodate", "") if extended else "" + eol_date = eol.get("isodate", "") + + if not released_date or not eol_date: + continue + + gantt += f" section {version}\n" + + if extended_date: + gantt += f" SMaint :active, sm{version}, {released_date}, {extended_date}\n" + gantt += f" ExtMaint :crit, em{version}, {extended_date}, {eol_date}\n" + else: + gantt += f" SMaint :active, sm{version}, {released_date}, {eol_date}\n" + + gantt += f" EoMaint :milestone, eom{version}, {eol_date}, 0d\n" + + return gantt + + +def generate_release_table(releases_data: dict) -> str: + """Generate markdown table from GLRD JSON data.""" + if not releases_data or "releases" not in releases_data: + return "*No releases found*" + + releases = releases_data.get("releases", []) + if not releases: + return "*No releases found*" + + table = "| Version | Commit | Standard Maintenance | Extended Maintenance | End of Maintenance |\n" + table += "|:--------|:-------|:---------------------|:---------------------|:-------------------|\n" + + for release in releases: + _, version_link = format_version(release) + commit_link = format_commit(release) + + lifecycle = release.get("lifecycle", {}) + standard_maint = format_lifecycle_date(lifecycle, "released") + extended_maint = format_lifecycle_date(lifecycle, "extended") + eol_date = format_lifecycle_date(lifecycle, "eol") + + table += f"| {version_link} | {commit_link} | {standard_maint} | {extended_maint} | {eol_date} |\n" + + return table + + +def get_timeline_section(gantt_chart: str, title: str) -> str: + """Build timeline section with Gantt chart and legend.""" + if not gantt_chart: + return "" + + return f""" + +## {title} + +```mermaid +{gantt_chart} +``` + +**Legend:** +- **SMaint** = [Standard Maintenance]({LIFECYCLE_LINKS['standard']}) — Active maintenance with regular updates +- **ExtMaint** = [Extended Maintenance]({LIFECYCLE_LINKS['extended']}) — Critical CVE fixes only (CVSS ≥7.0) +- **EoMaint** = [End of Maintenance]({LIFECYCLE_LINKS['eol']}) — No further updates +""" + + +def build_release_page(title: str, intro: str, table: str, timeline: str, page_type: str = "maintained") -> str: + """Build release page content with frontmatter and sections.""" + descriptions = { + "maintained": "Currently maintained Garden Linux releases with support dates and timelines.", + "archived": "Garden Linux releases that have reached end of maintenance and are no longer supported.", + } + orders = { + "maintained": 2, + "archived": 3, + } + + further_reading = f""" + +## Further Reading + +- [Release Lifecycle](release-lifecycle.md) — Understanding Garden Linux release phases +- [Maintained Releases](maintained-releases.md) — Currently supported releases +- [Archived Releases](archived-releases.md) — Past releases no longer maintained +- [Release Notes](release-notes/) — Detailed release-specific notes +""" + + description = descriptions.get(page_type, "") + order = orders.get(page_type, 2) + + return f"""--- +title: "{title}" +description: "{description}" +order: {order} +--- + +# {title} + +{intro} + +:::tip All data is sourced from [GLRD](../../how-to/glrd.html) +::: + +{table}{timeline} + +{further_reading} + +""" + + +def generate_release_docs(docs_dir: Path) -> bool: + """Fetch release data from GLRD and generate release documentation pages.""" + releases_dir = docs_dir / "reference" / "releases" + releases_dir.mkdir(parents=True, exist_ok=True) + + print("Generating release documentation from GLRD...") + + active_data = run_glrd_json(["--active"]) + archived_data = run_glrd_json(["--archived"]) + + if active_data is None: + print("Warning: Could not fetch active releases - skipping generation", file=sys.stderr) + return False + + active_table = generate_release_table(active_data) + active_gantt = generate_mermaid_gantt(active_data) + active_timeline = get_timeline_section(active_gantt, "Release Timeline") + + active_content = build_release_page( + "Maintained Releases", + "The table below provides the current list of actively maintained Garden Linux releases. For details about the release lifecycle phases, see [Release Lifecycle](release-lifecycle.md).", + f"## Active Releases\n\n{active_table}", + active_timeline, + "maintained", + ) + + (releases_dir / "maintained-releases.md").write_text(active_content) + print(f" Created: {releases_dir / 'maintained-releases.md'}") + + if archived_data is not None: + archived_table = generate_release_table(archived_data) + archived_gantt = generate_mermaid_gantt(archived_data) + archived_timeline = get_timeline_section(archived_gantt, "Archived Releases Timeline") + + archived_content = build_release_page( + "Archived Releases", + "The table below lists releases that have reached their end of maintenance and are no longer actively supported. If you use one of these versions, migrate to the latest maintained release as soon as possible. For details about the release lifecycle, see [Release Lifecycle](release-lifecycle.md).", + f"## Out of Maintenance Releases\n\n{archived_table}", + archived_timeline, + "archived", + ) + + (releases_dir / "archived-releases.md").write_text(archived_content) + print(f" Created: {releases_dir / 'archived-releases.md'}") + else: + print("Warning: Could not fetch archived releases", file=sys.stderr) + + print("Release documentation generation complete.") + return True diff --git a/src/aggregation/transformer.py b/src/aggregation/transformer.py index dad2c47..902a59d 100644 --- a/src/aggregation/transformer.py +++ b/src/aggregation/transformer.py @@ -329,3 +329,85 @@ def check_and_fix_link(match): content = re.sub(r"\[([^\]]+)\]\(([^)]+)\)", check_and_fix_link, content) return content + + +def cleanup_github_markdown(content: str) -> str: + """ + Clean up GitHub release notes markdown for VitePress compatibility. + + Handles common issues in GitHub release notes that cause VitePress parsing errors: + - Orphaned code fences followed by headers + - Empty code blocks + - Inconsistent fence markers + - Windows line endings + - Content followed by fence on same line + + Args: + content: Raw markdown from GitHub release notes + + Returns: + Cleaned markdown safe for VitePress rendering + """ + if not content: + return content + + # Fix Windows line endings first + content = content.replace("\r\n", "\n").replace("\r", "\n") + + # Remove or fix HTML details/summary tags that cause parsing issues + # Replace
contentcontent
with just content + content = re.sub(r'
([^<]*)', r'\1', content) + content = re.sub(r'
', '', content) + content = re.sub(r'
', '', content) + content = re.sub(r'', '', content) + content = re.sub(r'', '', content) + + # Fix patterns where content is followed by fence on same line + # e.g., "tag```" or "content````" should become "tag\n```" or "content\n```" + content = re.sub(r'([^`])````', r'\1\n```', content) + content = re.sub(r'([^`])```$', r'\1\n```', content, flags=re.MULTILINE) + content = re.sub(r'`````', '```', content) # Fix five backticks + content = re.sub(r'````', '```', content) # Fix four backticks + + lines = content.split('\n') + cleaned = [] + i = 0 + + while i < len(lines): + line = lines[i] + stripped = line.strip() + + # Detect code fence + is_fence_start = stripped in ("```", "````", "`````") + + # Handle orphan fence followed by header (add blank line) + if is_fence_start and i + 1 < len(lines): + next_line = lines[i + 1].strip() + if next_line.startswith("##") or next_line.startswith("# "): + cleaned.append(line) + cleaned.append("") # Add blank line before header + i += 1 + continue + + # Handle empty code block (fence followed immediately by another fence) + if is_fence_start and i + 1 < len(lines): + next_stripped = lines[i + 1].strip() + if next_stripped in ("```", "````", "`````"): + # Skip this empty block + i += 2 + continue + + # Normalize fence markers (```` or ````` -> ```) + if stripped == "````" or stripped == "`````": + cleaned.append("```") + i += 1 + continue + + cleaned.append(line) + i += 1 + + # Join and fix multiple blank lines + content = "\n".join(cleaned) + content = re.sub(r"\n{4,}", "\n\n\n", content) + + return content