From 33bcc21dd3e0187fc9154f3d7405a0a9dc9c9a56 Mon Sep 17 00:00:00 2001 From: Denys Kuchma Date: Fri, 13 Mar 2026 17:16:14 +0200 Subject: [PATCH 1/8] finish documentation section --- .claude/settings.local.json | 11 + .github/workflows/build-docs.yml | 4 + .github/workflows/deployment.yml | 4 + astro.config.mjs | 40 +- package-lock.json | 8954 ++++++++++++++ package.json | 6 +- scripts/generate-unified-api.mjs | 282 + src/components/Links.astro | 28 +- src/components/PageFrame.astro | 31 +- src/components/PageSidebar.astro | 8 + src/components/PageTitle.astro | 25 +- src/components/Search.astro | 2 - src/content.config.ts | 8 +- src/content/docs/advanced.md | 20 +- src/content/docs/ai.md | 22 +- src/content/docs/angular.md | 28 +- src/content/docs/api.md | 38 +- src/content/docs/basics.md | 30 +- src/content/docs/bootstrap.md | 4 +- src/content/docs/commands.md | 292 + ...y-helpers.md => community-helpers-page.md} | 7 +- src/content/docs/configuration.md | 198 + src/content/docs/custom-helpers.md | 18 +- src/content/docs/data.md | 18 +- src/content/docs/detox.md | 2 +- src/content/docs/effects.md | 109 + src/content/docs/els.md | 296 + src/content/docs/helpers/appium.md | 12 +- src/content/docs/helpers/detox.md | 2 +- src/content/docs/helpers/playwright.md | 8 +- src/content/docs/helpers/protractor.md | 1764 +++ src/content/docs/helpers/puppeteer-firefox.md | 93 + src/content/docs/helpers/puppeteer.md | 62 +- src/content/docs/helpers/web-driver.md | 32 +- src/content/docs/mobile-api.md | 2767 +++++ .../docs/mobile-react-native-locators.md | 77 + src/content/docs/mobile.md | 25 +- src/content/docs/playwright.md | 24 +- src/content/docs/plugins.md | 902 ++ src/content/docs/puppeteer.md | 18 +- src/content/docs/quickstart.md | 51 +- src/content/docs/shadow.md | 69 + src/content/docs/testcafe.md | 6 +- src/content/docs/translation.md | 10 +- src/content/docs/typescript.md | 8 +- src/content/docs/visual.md | 6 +- src/content/docs/vue.md | 111 +- src/content/docs/web-api.md | 10130 ++++++++++++++++ src/content/docs/webdriver.md | 36 +- src/pages/404.astro | 73 + .../home/components/community/index.astro | 4 +- src/pages/home/components/hero/index.astro | 6 +- .../home/components/testomatio/index.astro | 6 +- src/pages/home/components/trusted/index.astro | 12 +- src/pages/home/index.astro | 4 +- 55 files changed, 26424 insertions(+), 379 deletions(-) create mode 100644 .claude/settings.local.json create mode 100644 package-lock.json create mode 100644 scripts/generate-unified-api.mjs create mode 100644 src/components/PageSidebar.astro create mode 100644 src/content/docs/commands.md rename src/content/docs/{community-helpers.md => community-helpers-page.md} (98%) create mode 100644 src/content/docs/configuration.md create mode 100644 src/content/docs/effects.md create mode 100644 src/content/docs/els.md create mode 100644 src/content/docs/helpers/protractor.md create mode 100644 src/content/docs/helpers/puppeteer-firefox.md create mode 100644 src/content/docs/mobile-api.md create mode 100644 src/content/docs/mobile-react-native-locators.md create mode 100644 src/content/docs/plugins.md create mode 100644 src/content/docs/shadow.md create mode 100644 src/content/docs/web-api.md create mode 100644 src/pages/404.astro diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 00000000..d6c957a1 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,11 @@ +{ + "permissions": { + "allow": [ + "Bash(git rm:*)", + "Bash(git add:*)", + "Bash(git config:*)" + ], + "deny": [], + "ask": [] + } +} diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 2c406e83..7b7e2e00 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -13,6 +13,8 @@ on: jobs: publish-npm: runs-on: ubuntu-latest + env: + PUBLIC_MEILISEARCH_KEY: ${{ secrets.PUBLIC_MEILISEARCH_KEY }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -23,6 +25,8 @@ jobs: - run: git config --global user.email "github-cd-bot@example.com" - name: Install deps run: npm i + - name: Generate unified API docs + run: npm run generate:unified-api - name: Build docs run: npm run build env: diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index c88f00d9..04afdc91 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -3,6 +3,8 @@ name: Publish website jobs: publish-npm: runs-on: ubuntu-latest + env: + PUBLIC_MEILISEARCH_KEY: ${{ secrets.PUBLIC_MEILISEARCH_KEY }} steps: - uses: actions/checkout@v4 with: @@ -13,6 +15,8 @@ jobs: registry-url: https://registry.npmjs.org/ - name: Install deps run: npm i + - name: Generate unified API docs + run: npm run generate:unified-api - name: deployment run: ./runok.js publish env: diff --git a/astro.config.mjs b/astro.config.mjs index 86510888..ca1c3973 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,11 +1,10 @@ -import {defineConfig} from 'astro/config'; +๏ปฟimport {defineConfig} from 'astro/config'; import starlight from '@astrojs/starlight'; import tailwindcss from '@tailwindcss/vite'; import starlightSidebarTopics from 'starlight-sidebar-topics'; import starlightImageZoom from 'starlight-image-zoom'; import rehypeAstroRelativeMarkdownLinks from "astro-rehype-relative-markdown-links"; import starlightScrollToTop from 'starlight-scroll-to-top'; -import starlightBlog from 'starlight-blog'; const options = { collectionBase: false, @@ -17,6 +16,7 @@ export default defineConfig({ expressiveCode: { themes: ['github-dark', 'dracula'], }, + disable404Route: true, title: '', favicon: '/favicon.svg', social: [ @@ -26,6 +26,7 @@ export default defineConfig({ Head: "./src/components/Head.astro", PageFrame: "./src/components/PageFrame.astro", PageTitle: './src/components/PageTitle.astro', + PageSidebar: './src/components/PageSidebar.astro', Footer: './src/components/Footer.astro', SiteTitle: './src/components/SiteTitle.astro', Search: './src/components/Search.astro', @@ -37,21 +38,19 @@ export default defineConfig({ ], plugins: [ starlightImageZoom(), - starlightBlog(), starlightSidebarTopics([ { + id: 'documentation', label: 'Documentation', link: 'quickstart', items: [ { label: 'Web Testing', items: [ - {label: 'Getting Started', link: 'basics'}, - {label: 'CodeceptUI', link: 'ui'}, + {label: 'Web Basics', link: 'basics'}, {label: 'Testing with Playwright', link: 'playwright'}, {label: 'Testing with WebDriver', link: 'webdriver'}, {label: 'Testing with Puppeteer', link: 'puppeteer'}, - {label: 'API Testing', link: 'api'}, {label: 'Testing with TestCafe', link: 'testcafe'}, ], }, @@ -71,14 +70,28 @@ export default defineConfig({ {label: 'Behavior Driven Development', link: 'bdd'}, {label: 'Locators', link: 'locators'}, {label: 'Translation', link: 'translation'}, - {label: 'Custom Helpers', link: 'custom-helpers'}, {label: 'Best Practices', link: 'best'}, ], }, + { + label: 'API Reference', + items: [ + {label: 'Web API (Unified)', link: 'web-api'}, + {label: 'Mobile API (Unified)', link: 'mobile-api'}, + {label: 'API Testing', link: 'api'}, + {label: 'Commands', link: 'commands'}, + {label: 'Configuration', link: 'configuration'}, + {label: 'Plugins', link: 'plugins'}, + {label: 'Effects', link: 'effects'}, + {label: 'Element Access (els)', link: 'els'}, + {label: 'Shadow DOM', link: 'shadow'}, + ], + }, { label: 'Advanced Usage', items: [ {label: 'Advanced Usage', link: 'advanced'}, + {label: 'CodeceptUI', link: 'ui'}, {label: 'Bootstrap', link: 'bootstrap'}, {label: 'Reporters', link: 'reports'}, {label: 'Continuous Integration', link: 'continuous-integration'}, @@ -107,7 +120,9 @@ export default defineConfig({ items: [ {label: 'WebDriver', link: 'helpers/web-driver'}, {label: 'Puppeteer', link: 'helpers/puppeteer'}, + {label: 'Puppeteer Firefox', link: 'helpers/puppeteer-firefox'}, {label: 'TestCafe', link: 'helpers/test-cafe'}, + {label: 'Protractor (Legacy)', link: 'helpers/protractor'}, ], }, { @@ -136,7 +151,8 @@ export default defineConfig({ {label: 'Expect', link: 'helpers/expect'}, {label: 'SoftExpectHelper', link: 'helpers/soft-expect-helper'}, {label: 'MockServer', link: 'helpers/mock-server'}, - {label: 'Community Helpers', link: 'community-helpers'}, + {label: 'Custom Helpers', link: 'custom-helpers'}, + {label: 'Community Helpers', link: 'helpers/community-helpers'}, ], }, ] @@ -155,7 +171,12 @@ export default defineConfig({ {label: 'blog', autogenerate: {directory: 'blog/'}}, ], }, - ]), + ], { + exclude: ['/404'], + topics: { + documentation: ['/mobile-react-native-locators'], + }, + }), starlightScrollToTop({ position: 'right', tooltipText: 'Back to top', @@ -183,3 +204,4 @@ export default defineConfig({ ], }, }); + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..df7dadbb --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8954 @@ +{ + "name": "CodeceptJS", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "CodeceptJS", + "version": "0.0.1", + "dependencies": { + "@astrojs/markdown-remark": "^6.3.10", + "@astrojs/starlight": "^0.37.1", + "@astrojs/starlight-tailwind": "^4.0.2", + "@tailwindcss/vite": "^4.1.18", + "astro": "^5.16.5", + "astro-breadcrumbs": "^3.3.1", + "astro-rehype-relative-markdown-links": "0.18.1", + "astro-vtbot": "^2.1.9", + "meilisearch-docsearch": "^0.8.0", + "schema-dts": "^1.1.5", + "sharp": "^0.34.5", + "starlight-blog": "^0.25.2", + "starlight-image-zoom": "^0.13.2", + "starlight-scroll-to-top": "^0.4.0", + "starlight-sidebar-topics": "^0.6.2", + "swiper": "^12.0.3", + "tailwind-merge": "^3.4.0", + "tailwindcss": "^4.1.18" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz", + "integrity": "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==", + "license": "MIT" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.5.tgz", + "integrity": "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==", + "license": "MIT" + }, + "node_modules/@astrojs/markdown-remark": { + "version": "6.3.10", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.10.tgz", + "integrity": "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/prism": "3.3.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "shiki": "^3.19.0", + "smol-toml": "^1.5.2", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/@astrojs/markdown-remark/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@astrojs/mdx": { + "version": "4.3.13", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.3.13.tgz", + "integrity": "sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "6.3.10", + "@mdx-js/mdx": "^3.1.1", + "acorn": "^8.15.0", + "es-module-lexer": "^1.7.0", + "estree-util-visit": "^2.0.0", + "hast-util-to-html": "^9.0.5", + "piccolore": "^0.1.3", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.1", + "remark-smartypants": "^3.0.2", + "source-map": "^0.7.6", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.3" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + }, + "peerDependencies": { + "astro": "^5.0.0" + } + }, + "node_modules/@astrojs/mdx/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", + "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/rss": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-4.0.16.tgz", + "integrity": "sha512-sx++ezc+2WSu48032XGoqjrJ+bXwYyMtBx8pyuLeSlppn+fjioP8INC30sS8MEbKHCK7HfiwsEsnGyXoafxkww==", + "license": "MIT", + "dependencies": { + "fast-xml-parser": "^5.4.1", + "piccolore": "^0.1.3", + "zod": "^4.3.6" + } + }, + "node_modules/@astrojs/sitemap": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.1.tgz", + "integrity": "sha512-IzQqdTeskaMX+QDZCzMuJIp8A8C1vgzMBp/NmHNnadepHYNHcxQdGLQZYfkbd2EbRXUfOS+UDIKx8sKg0oWVdw==", + "license": "MIT", + "dependencies": { + "sitemap": "^9.0.0", + "stream-replace-string": "^2.0.0", + "zod": "^4.3.6" + } + }, + "node_modules/@astrojs/sitemap/node_modules/@types/node": { + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", + "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@astrojs/sitemap/node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/@astrojs/sitemap/node_modules/sitemap": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.1.tgz", + "integrity": "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^24.9.2", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.4.1" + }, + "bin": { + "sitemap": "dist/esm/cli.js" + }, + "engines": { + "node": ">=20.19.5", + "npm": ">=10.8.2" + } + }, + "node_modules/@astrojs/sitemap/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/@astrojs/starlight": { + "version": "0.37.7", + "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.37.7.tgz", + "integrity": "sha512-KyBnou8aKIlPJUSNx6a1SN7XyH22oj/VAvTGC+Edld4Bnei1A//pmCRTBvSrSeoGrdUjK0ErFUfaEhhO1bPfDg==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "^6.3.1", + "@astrojs/mdx": "^4.2.3", + "@astrojs/sitemap": "^3.3.0", + "@pagefind/default-ui": "^1.3.0", + "@types/hast": "^3.0.4", + "@types/js-yaml": "^4.0.9", + "@types/mdast": "^4.0.4", + "astro-expressive-code": "^0.41.1", + "bcp-47": "^2.1.0", + "hast-util-from-html": "^2.0.1", + "hast-util-select": "^6.0.2", + "hast-util-to-string": "^3.0.0", + "hastscript": "^9.0.0", + "i18next": "^23.11.5", + "js-yaml": "^4.1.0", + "klona": "^2.0.6", + "magic-string": "^0.30.17", + "mdast-util-directive": "^3.0.0", + "mdast-util-to-markdown": "^2.1.0", + "mdast-util-to-string": "^4.0.0", + "pagefind": "^1.3.0", + "rehype": "^13.0.1", + "rehype-format": "^5.0.0", + "remark-directive": "^3.0.0", + "ultrahtml": "^1.6.0", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.2" + }, + "peerDependencies": { + "astro": "^5.5.0" + } + }, + "node_modules/@astrojs/starlight-tailwind": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@astrojs/starlight-tailwind/-/starlight-tailwind-4.0.2.tgz", + "integrity": "sha512-SYN/6zq6hJO5tWqbQ2tWT9/jd8ubUkzkBCcF94vByC/ZJ20Mi5GPjFvAh89Yky/aIM+jXxT6W5q4p6l58GKHiQ==", + "license": "MIT", + "peerDependencies": { + "@astrojs/starlight": ">=0.34.0", + "tailwindcss": "^4.0.0" + } + }, + "node_modules/@astrojs/starlight/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/@astrojs/starlight/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", + "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.2.0", + "debug": "^4.4.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "is-docker": "^3.0.0", + "is-wsl": "^3.1.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/telemetry/node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@astrojs/telemetry/node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@capsizecss/unpack": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.0.tgz", + "integrity": "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", + "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@expressive-code/core": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.41.7.tgz", + "integrity": "sha512-ck92uZYZ9Wba2zxkiZLsZGi9N54pMSAVdrI9uW3Oo9AtLglD5RmrdTwbYPCT2S/jC36JGB2i+pnQtBm/Ib2+dg==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^4.0.4", + "hast-util-select": "^6.0.2", + "hast-util-to-html": "^9.0.1", + "hast-util-to-text": "^4.0.1", + "hastscript": "^9.0.0", + "postcss": "^8.4.38", + "postcss-nested": "^6.0.1", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1" + } + }, + "node_modules/@expressive-code/plugin-frames": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.41.7.tgz", + "integrity": "sha512-diKtxjQw/979cTglRFaMCY/sR6hWF0kSMg8jsKLXaZBSfGS0I/Hoe7Qds3vVEgeoW+GHHQzMcwvgx/MOIXhrTA==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.7" + } + }, + "node_modules/@expressive-code/plugin-shiki": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.41.7.tgz", + "integrity": "sha512-DL605bLrUOgqTdZ0Ot5MlTaWzppRkzzqzeGEu7ODnHF39IkEBbFdsC7pbl3LbUQ1DFtnfx6rD54k/cdofbW6KQ==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.7", + "shiki": "^3.2.2" + } + }, + "node_modules/@expressive-code/plugin-text-markers": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.41.7.tgz", + "integrity": "sha512-Ewpwuc5t6eFdZmWlFyeuy3e1PTQC0jFvw2Q+2bpcWXbOZhPLsT7+h8lsSIJxb5mS7wZko7cKyQ2RLYDyK6Fpmw==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.7" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@mdx-js/mdx/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@pagefind/darwin-arm64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.4.0.tgz", + "integrity": "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/darwin-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.4.0.tgz", + "integrity": "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/default-ui": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.4.0.tgz", + "integrity": "sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==", + "license": "MIT" + }, + "node_modules/@pagefind/freebsd-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.4.0.tgz", + "integrity": "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@pagefind/linux-arm64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.4.0.tgz", + "integrity": "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/linux-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.4.0.tgz", + "integrity": "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/windows-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.4.0.tgz", + "integrity": "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@parcel/watcher": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", + "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.4.1", + "@parcel/watcher-darwin-arm64": "2.4.1", + "@parcel/watcher-darwin-x64": "2.4.1", + "@parcel/watcher-freebsd-x64": "2.4.1", + "@parcel/watcher-linux-arm-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-musl": "2.4.1", + "@parcel/watcher-linux-x64-glibc": "2.4.1", + "@parcel/watcher-linux-x64-musl": "2.4.1", + "@parcel/watcher-win32-arm64": "2.4.1", + "@parcel/watcher-win32-ia32": "2.4.1", + "@parcel/watcher-win32-x64": "2.4.1" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", + "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz", + "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz", + "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.31.1", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.1" + } + }, + "node_modules/@tailwindcss/node/node_modules/enhanced-resolve": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@tailwindcss/node/node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "tailwindcss": "4.2.1" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/node": { + "version": "25.4.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.4.0.tgz", + "integrity": "sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@vtbag/cam-shaft": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@vtbag/cam-shaft/-/cam-shaft-1.0.6.tgz", + "integrity": "sha512-Xy1bmJJLXuCqxmY2agwPfhGNv1XZViqh54H0VGK4mouGsItFsh8Mz/wWAP6mZwAOEuu9bEOJ1mJ+oNoaczZ1zw==", + "license": "ISC", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/martrapp" + } + }, + "node_modules/@vtbag/element-crossing": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vtbag/element-crossing/-/element-crossing-1.1.0.tgz", + "integrity": "sha512-1YL609KPwhHUKRrVNfoogQCVJPfFrE5DubOLcCJZLHVCjWZ2ZAPcaq1wR2OP6nXD0Ok9JLX41YsEtYBYzw6CxQ==", + "license": "ISC", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/martrapp" + } + }, + "node_modules/@vtbag/inspection-chamber": { + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/@vtbag/inspection-chamber/-/inspection-chamber-1.0.24.tgz", + "integrity": "sha512-L6CrMbzJ0gdG/P5WnGyVgRxHVeLhlQgXh3mp+OI4JdJjFiwIhh9+sG/FXM2DneBs5HQvaWUq4qf6NiSlgVbyvQ==", + "license": "ISC", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/martrapp" + } + }, + "node_modules/@vtbag/turn-signal": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vtbag/turn-signal/-/turn-signal-1.3.1.tgz", + "integrity": "sha512-6rWkG+ik3U+KQGI94yNOrOh5QedB9zmP/8H51X5WQwrJz8m2MAU5YwGRRcweO/dJ6wW/Bn7OsgC1vRURnwrvCg==", + "license": "ISC", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/martrapp" + } + }, + "node_modules/@vtbag/utensil-drawer": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/@vtbag/utensil-drawer/-/utensil-drawer-1.2.16.tgz", + "integrity": "sha512-RSahZXk4NAFTF3zDYQH1x4qv8gFLcWus7qD//D0b58zoZIeqa2uKePLMy4lSHagYdkwBlKXKlfcDSrqUvWmxnw==", + "license": "ISC", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/martrapp" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/astro": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.18.0.tgz", + "integrity": "sha512-CHiohwJIS4L0G6/IzE1Fx3dgWqXBCXus/od0eGUfxrZJD2um2pE7ehclMmgL/fXqbU7NfE1Ze2pq34h2QaA6iQ==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.0", + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/markdown-remark": "6.3.10", + "@astrojs/telemetry": "3.3.0", + "@capsizecss/unpack": "^4.0.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "acorn": "^8.15.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.3.1", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^1.1.1", + "cssesc": "^3.0.0", + "debug": "^4.4.3", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.6.2", + "diff": "^8.0.3", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.7.0", + "esbuild": "^0.27.3", + "estree-walker": "^3.0.3", + "flattie": "^1.1.1", + "fontace": "~0.4.0", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "p-limit": "^6.2.0", + "p-queue": "^8.1.1", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.3", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.7.3", + "shiki": "^3.21.0", + "smol-toml": "^1.6.0", + "svgo": "^4.0.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tsconfck": "^3.1.6", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.3", + "unist-util-visit": "^5.0.0", + "unstorage": "^1.17.4", + "vfile": "^6.0.3", + "vite": "^6.4.1", + "vitefu": "^1.1.1", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "yocto-spinner": "^0.2.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.25.1", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" + } + }, + "node_modules/astro-breadcrumbs": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/astro-breadcrumbs/-/astro-breadcrumbs-3.3.3.tgz", + "integrity": "sha512-Fs1EGNQWwDXGwWd4aGhLhUUPik0GcxqjgGMS8yLve2DeMO1JNb1j/Oz81VIo4xzx9H9b987T+pJYJ7x+ojxGFw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/felix-berlin" + }, + { + "type": "Ko-fi", + "url": "https://ko-fi.com/felixberlin" + }, + { + "type": "PayPal", + "url": "https://paypal.me/FelixScholze" + }, + { + "type": "Buy me a coffee", + "url": "https://www.buymeacoffee.com/felixberlin" + } + ], + "license": "GPL-3.0", + "workspaces": [ + "demo", + "docs" + ], + "peerDependencies": { + "astro": "^2.0.0-beta.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/astro-expressive-code": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.41.7.tgz", + "integrity": "sha512-hUpogGc6DdAd+I7pPXsctyYPRBJDK7Q7d06s4cyP0Vz3OcbziP3FNzN0jZci1BpCvLn9675DvS7B9ctKKX64JQ==", + "license": "MIT", + "dependencies": { + "rehype-expressive-code": "^0.41.7" + }, + "peerDependencies": { + "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" + } + }, + "node_modules/astro-rehype-relative-markdown-links": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/astro-rehype-relative-markdown-links/-/astro-rehype-relative-markdown-links-0.18.1.tgz", + "integrity": "sha512-PA2oLXs8+8CX+/cDEeHo4UJfMPKXazIJM8BgnQloR/vGXRnW3KjbLI3nqSoNVmq91YaFv2UHfHKoetEcfwieUw==", + "license": "MIT", + "dependencies": { + "catch-unknown": "^2.0.0", + "debug": "^4.4.0", + "github-slugger": "^2.0.0", + "gray-matter": "^4.0.3", + "is-absolute-url": "^4.0.1", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0", + "zod": "^3.23.8" + }, + "peerDependencies": { + "astro": ">=2 <6" + } + }, + "node_modules/astro-rehype-relative-markdown-links/node_modules/is-absolute-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro-rehype-relative-markdown-links/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/astro-remote": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/astro-remote/-/astro-remote-0.3.4.tgz", + "integrity": "sha512-jL5skNQLA0YBc1R3bVGXyHew3FqGqsT7AgLzWAVeTLzFkwVMUYvs4/lKJSmS7ygcF1GnHnoKG6++8GL9VtWwGQ==", + "license": "MIT", + "dependencies": { + "entities": "^4.5.0", + "marked": "^12.0.0", + "marked-footnote": "^1.2.2", + "marked-smartypants": "^1.1.6", + "ultrahtml": "^1.5.3" + }, + "engines": { + "node": ">=18.14.1" + } + }, + "node_modules/astro-remote/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/astro-remote/node_modules/marked": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/astro-vtbot": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/astro-vtbot/-/astro-vtbot-2.1.11.tgz", + "integrity": "sha512-M0b2y2Kh4BcHryfY2dP+xrZOH2zYHEYM+x+1NFvCoK+g8iGRE/va6DxPN/zJ07IwWYjGl9PizLA0ZLJJl0a2sg==", + "license": "ISC", + "dependencies": { + "@vtbag/cam-shaft": "^1.0.6", + "@vtbag/element-crossing": "^1.1.0", + "@vtbag/inspection-chamber": "^1.0.24", + "@vtbag/turn-signal": "^1.3.1", + "@vtbag/utensil-drawer": "^1.2.15" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/martrapp" + } + }, + "node_modules/astro/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/astro/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/astro/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/astro/node_modules/boxen": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", + "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-boxes": "^3.0.0", + "string-width": "^7.2.0", + "type-fest": "^4.21.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro/node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/astro/node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/astro/node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/astro/node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/astro/node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/astro/node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/astro/node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/astro/node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/astro/node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/astro/node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/astro/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/astro/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/astro/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/astro/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/astro/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/astro/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/astro/node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/astro/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/astro/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/astro/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/astro/node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "license": "CC0-1.0" + }, + "node_modules/astro/node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/astro/node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/astro/node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/astro/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/astro/node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/astro/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro/node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/vite/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/astro/node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/astro/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/astro/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/astro/node_modules/zod-to-ts": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", + "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", + "peerDependencies": { + "typescript": "^4.9.4 || ^5.0.2", + "zod": "^3" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "optional": true, + "peer": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "optional": true, + "peer": true + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "optional": true, + "peer": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "optional": true, + "peer": true + }, + "node_modules/catch-unknown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/catch-unknown/-/catch-unknown-2.0.0.tgz", + "integrity": "sha512-4ELowf+Fp6Qwv77ZvRDto9oJMsOalEk8IYvS5KsmIhRZQWbfArlIhIOONJtmCzOeeqpip6JzYqAYaNR9sIyLVQ==", + "license": "ISC" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "optional": true, + "peer": true + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "optional": true, + "peer": true + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha512-UNIFik2RgSbiTwIW1IsFwXWn6vs+bYdq83LKTSOsx7NJR7WII9dxewkHLltfTLVppoUApHV0118a4RZRI9FLwA==", + "optional": true, + "peer": true, + "dependencies": { + "css": "^2.0.0" + } + }, + "node_modules/css-selector-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.3.0.tgz", + "integrity": "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "optional": true, + "peer": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.3.tgz", + "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "license": "MIT", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/expressive-code": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.41.7.tgz", + "integrity": "sha512-2wZjC8OQ3TaVEMcBtYY4Va3lo6J+Ai9jf3d4dbhURMJcU4Pbqe6EcHe424MIZI0VHUA1bR6xdpoHYi3yxokWqA==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.7", + "@expressive-code/plugin-frames": "^0.41.7", + "@expressive-code/plugin-shiki": "^0.41.7", + "@expressive-code/plugin-text-markers": "^0.41.7" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-xml-builder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", + "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/fast-xml-parser": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.2.tgz", + "integrity": "sha512-pw/6pIl4k0CSpElPEJhDppLzaixDEuWui2CUQQBH/ECDf7+y6YwA4Gf7Tyb0Rfe4DIMuZipYj4AEL0nACKglvQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "fast-xml-builder": "^1.0.0", + "strnum": "^2.1.2" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "optional": true, + "peer": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fontace": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.4.1.tgz", + "integrity": "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.2" + } + }, + "node_modules/fontkitten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fontkitten/-/fontkitten-1.0.3.tgz", + "integrity": "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==", + "license": "MIT", + "dependencies": { + "tiny-inflate": "^1.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "optional": true, + "peer": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "optional": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/h3": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.6.tgz", + "integrity": "sha512-oi15ESLW5LRthZ+qPCi5GNasY/gvynSKUQxgiovrY63bPAtG59wtM+LSrlcwvOHAXzGrXVLnI97brbkdPF9WoQ==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.5", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.4", + "radix3": "^1.1.2", + "ufo": "^1.6.3", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hast-util-embedded": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz", + "integrity": "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-is-element": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-format": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hast-util-format/-/hast-util-format-1.1.0.tgz", + "integrity": "sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-minify-whitespace": "^1.0.0", + "hast-util-phrasing": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "html-whitespace-sensitive-tag-names": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-body-ok-link": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-3.0.1.tgz", + "integrity": "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-minify-whitespace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hast-util-minify-whitespace/-/hast-util-minify-whitespace-1.0.1.tgz", + "integrity": "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-phrasing/-/hast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-is-body-ok-link": "^3.0.0", + "hast-util-is-element": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-6.0.4.tgz", + "integrity": "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^3.0.0", + "devlop": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "nth-check": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-whitespace-sensitive-tag-names": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-whitespace-sensitive-tag-names/-/html-whitespace-sensitive-tag-names-3.0.1.tgz", + "integrity": "sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/i18next": { + "version": "23.16.8", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz", + "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "optional": true, + "peer": true + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "optional": true, + "peer": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "optional": true, + "peer": true + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "optional": true, + "peer": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/lightningcss": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", + "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.31.1", + "lightningcss-darwin-arm64": "1.31.1", + "lightningcss-darwin-x64": "1.31.1", + "lightningcss-freebsd-x64": "1.31.1", + "lightningcss-linux-arm-gnueabihf": "1.31.1", + "lightningcss-linux-arm64-gnu": "1.31.1", + "lightningcss-linux-arm64-musl": "1.31.1", + "lightningcss-linux-x64-gnu": "1.31.1", + "lightningcss-linux-x64-musl": "1.31.1", + "lightningcss-win32-arm64-msvc": "1.31.1", + "lightningcss-win32-x64-msvc": "1.31.1" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", + "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz", + "integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-footnote": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/marked-footnote/-/marked-footnote-1.4.0.tgz", + "integrity": "sha512-fZTxAhI1TcLEs5UOjCfYfTHpyKGaWQevbxaGTEA68B51l7i87SctPFtHETYqPkEN0ka5opvy4Dy1l/yXVC+hmg==", + "license": "MIT", + "peerDependencies": { + "marked": ">=7.0.0" + } + }, + "node_modules/marked-plaintify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/marked-plaintify/-/marked-plaintify-1.1.1.tgz", + "integrity": "sha512-r3kMKArhfo2H3lD4ctFq/OJTzM0uNvXHh7FBTI1hMDpf4Ac1djjtq4g8NfTBWMxWLmaEz3KL1jCkLygik3gExA==", + "license": "MIT", + "peerDependencies": { + "marked": ">=13.0.0" + } + }, + "node_modules/marked-smartypants": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/marked-smartypants/-/marked-smartypants-1.1.11.tgz", + "integrity": "sha512-Jt0eq/6rf9oXDfEKPzQ0z7UzVWcEAK3L6QBBQzbwV8bT304OvPVLTqpH3yvkSung9foOM4s120TMHEHP76Metg==", + "license": "MIT", + "dependencies": { + "smartypants": "^0.2.2" + }, + "peerDependencies": { + "marked": ">=4 <18" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/meilisearch": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/meilisearch/-/meilisearch-0.50.0.tgz", + "integrity": "sha512-9IzIkobvnuS18Eg4dq/eJB9W+eXqeLZjNRgq/kKMswSmVYYSQsXqGgSuCA0JkF+o5RwJlwIsieQee6rh313VhA==", + "license": "MIT" + }, + "node_modules/meilisearch-docsearch": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/meilisearch-docsearch/-/meilisearch-docsearch-0.8.0.tgz", + "integrity": "sha512-I0sd0z7CRSyn83ACDKbDD4PQNFCe/oZxN4pWgJbqLgLwOEICQMZLMlFVmQPQzzSb9ZkvjjJnaNPxVpZ4yi7upw==", + "license": "MIT or Apache-2.0", + "dependencies": { + "meilisearch": "0.50.0", + "solid-js": "1.9.5" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "optional": true, + "peer": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "optional": true, + "peer": true + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz", + "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "optional": true, + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", + "integrity": "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, + "node_modules/pagefind": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.4.0.tgz", + "integrity": "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==", + "license": "MIT", + "bin": { + "pagefind": "lib/runner/bin.cjs" + }, + "optionalDependencies": { + "@pagefind/darwin-arm64": "1.4.0", + "@pagefind/darwin-x64": "1.4.0", + "@pagefind/freebsd-x64": "1.4.0", + "@pagefind/linux-arm64": "1.4.0", + "@pagefind/linux-x64": "1.4.0", + "@pagefind/windows-x64": "1.4.0" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/piccolore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", + "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-expressive-code": { + "version": "0.41.7", + "resolved": "https://registry.npmjs.org/rehype-expressive-code/-/rehype-expressive-code-0.41.7.tgz", + "integrity": "sha512-25f8ZMSF1d9CMscX7Cft0TSQIqdwjce2gDOvQ+d/w0FovsMwrSt3ODP4P3Z7wO1jsIJ4eYyaDRnIR/27bd/EMQ==", + "license": "MIT", + "dependencies": { + "expressive-code": "^0.41.7" + } + }, + "node_modules/rehype-format": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rehype-format/-/rehype-format-5.0.1.tgz", + "integrity": "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-format": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", + "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "optional": true, + "peer": true + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "optional": true, + "peer": true + }, + "node_modules/sass": { + "version": "1.83.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.1.tgz", + "integrity": "sha512-EVJbDaEs4Rr3F0glJzFSOvtg2/oy2V/YrGFPqPY24UqcLDWcI9ZY5sN+qyO3c/QCZwzgfirvhXvINiJCE/OLcA==", + "optional": true, + "peer": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.1.tgz", + "integrity": "sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "optional": true, + "peer": true + }, + "node_modules/schema-dts": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz", + "integrity": "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==", + "license": "Apache-2.0" + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/seroval": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.5.1.tgz", + "integrity": "sha512-OwrZRZAfhHww0WEnKHDY8OM0U/Qs8OTfIDWhUD4BLpNJUfXK4cGmjiagGze086m+mhI+V2nD0gfbHEnJjb9STA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/seroval-plugins": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.5.1.tgz", + "integrity": "sha512-4FbuZ/TMl02sqv0RTFexu0SP6V+ywaIe5bAWCCEik0fk17BhALgwvUDVF7e3Uvf9pxmwCEJsRPmlkUE6HdzLAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "seroval": "^1.0" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/sharp/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.23.0.tgz", + "integrity": "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.23.0", + "@shikijs/engine-javascript": "3.23.0", + "@shikijs/engine-oniguruma": "3.23.0", + "@shikijs/langs": "3.23.0", + "@shikijs/themes": "3.23.0", + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/smartypants": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/smartypants/-/smartypants-0.2.2.tgz", + "integrity": "sha512-TzobUYoEft/xBtb2voRPryAUIvYguG0V7Tt3de79I1WfXgCwelqVsGuZSnu3GFGRZhXR90AeEYIM+icuB/S06Q==", + "license": "BSD-3-Clause", + "bin": { + "smartypants": "bin/smartypants.js", + "smartypantsu": "bin/smartypantsu.js" + } + }, + "node_modules/smol-toml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz", + "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/solid-js": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.5.tgz", + "integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.0", + "seroval": "^1.1.0", + "seroval-plugins": "^1.1.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "optional": true, + "peer": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "optional": true, + "peer": true + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/starlight-blog": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/starlight-blog/-/starlight-blog-0.25.3.tgz", + "integrity": "sha512-U0+CYgeJhbXz/6Rcr2vXCUiMq5HyQUq9gP0Nj3Ii2A8GKaDoZTdgHD2HnWJBK4NbXRCJqM7N1BcyeLHS0+O7Aw==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "^6.3.1", + "@astrojs/mdx": "^4.0.8", + "@astrojs/rss": "^4.0.11", + "astro-remote": "^0.3.4", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-html": "^9.0.5", + "hast-util-to-string": "^3.0.1", + "marked": "^15.0.4", + "marked-plaintify": "^1.1.1", + "mdast-util-mdx-expression": "^2.0.1", + "unist-util-is": "^6.0.0", + "unist-util-remove": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=18.20.8" + }, + "peerDependencies": { + "@astrojs/starlight": ">=0.33.0" + } + }, + "node_modules/starlight-image-zoom": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/starlight-image-zoom/-/starlight-image-zoom-0.13.2.tgz", + "integrity": "sha512-fDJrx+UZXhkbhEeXKoRogTKAYtrYVJPw6wmSUI3nHUTA0vuRM6EI//2Z8bzv3Ecvz0pHKD1vAxtS01mLyessBA==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx-jsx": "^3.1.3", + "rehype-raw": "^7.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@astrojs/starlight": ">=0.32.0" + } + }, + "node_modules/starlight-scroll-to-top": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/starlight-scroll-to-top/-/starlight-scroll-to-top-0.4.0.tgz", + "integrity": "sha512-lxsW5Sv+oKCI8CYZQ6Ue957cExiHMozK73LmmbsvpBKWryW+AKU4OXmX/1bTQNx+mVLZcpm2qTwKa1KX5VdEaQ==", + "license": "MIT", + "engines": { + "node": "^18.17.1 || ^20.3.0 || >=21.0.0" + }, + "peerDependencies": { + "@astrojs/starlight": ">=0.35" + } + }, + "node_modules/starlight-sidebar-topics": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/starlight-sidebar-topics/-/starlight-sidebar-topics-0.6.2.tgz", + "integrity": "sha512-SNCTUZS/hcVor0ZcaXbaSVU37+V+qtvzNirkvnOg3Mqu/awuGpthkH5+uKpiZqWxLffp6TrOlsv5E5QsxrndNg==", + "license": "MIT", + "dependencies": { + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@astrojs/starlight": ">=0.32.0" + } + }, + "node_modules/starlight-sidebar-topics/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/stream-replace-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz", + "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strnum": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz", + "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/stylus": { + "version": "0.54.8", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", + "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", + "optional": true, + "peer": true, + "dependencies": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.6", + "mkdirp": "~1.0.4", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.3.0", + "source-map": "^0.7.3" + }, + "bin": { + "stylus": "bin/stylus" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stylus/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/stylus/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylus/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "optional": true, + "peer": true + }, + "node_modules/stylus/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/stylus/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "optional": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/swiper": { + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-12.1.2.tgz", + "integrity": "sha512-4gILrI3vXZqoZh71I1PALqukCFgk+gpOwe1tOvz5uE9kHtl2gTDzmYflYCwWvR4LOvCrJi6UEEU+gnuW5BtkgQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "license": "MIT", + "engines": { + "node": ">= 4.7.0" + } + }, + "node_modules/tailwind-merge": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz", + "integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", + "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", + "license": "MIT" + }, + "node_modules/terser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "optional": true, + "peer": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unifont": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.7.4.tgz", + "integrity": "sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.1.0", + "ofetch": "^1.5.1", + "ohash": "^2.0.11" + } + }, + "node_modules/unifont/node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/unifont/node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "license": "CC0-1.0" + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-4.0.0.tgz", + "integrity": "sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unstorage": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.4.tgz", + "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^5.0.0", + "destr": "^2.0.5", + "h3": "^1.15.5", + "lru-cache": "^11.2.0", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.1", + "ufo": "^1.6.3" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1 || ^2 || ^3", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/unstorage/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/unstorage/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "optional": true, + "peer": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitefu": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.2.tgz", + "integrity": "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "optional": true, + "peer": true + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-spinner": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-0.2.3.tgz", + "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", + "license": "MIT", + "dependencies": { + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json index 30bd3fb2..b341d042 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,15 @@ "type": "module", "version": "0.0.1", "scripts": { + "predev": "npm run generate:unified-api", "dev": "astro dev", "start": "astro dev", + "prebuild": "npm run generate:unified-api", "build": "astro build", "preview": "astro preview", - "astro": "astro" + "astro": "astro", + "generate:unified-api": "node scripts/generate-unified-api.mjs", + "generate:unified-api:check": "node scripts/generate-unified-api.mjs --check" }, "dependencies": { "@astrojs/markdown-remark": "^6.3.10", diff --git a/scripts/generate-unified-api.mjs b/scripts/generate-unified-api.mjs new file mode 100644 index 00000000..c2a14337 --- /dev/null +++ b/scripts/generate-unified-api.mjs @@ -0,0 +1,282 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +const ROOT = process.cwd(); +const DOCS_DIR = path.join(ROOT, 'src', 'content', 'docs'); +const HELPERS_DIR = path.join(DOCS_DIR, 'helpers'); +const WEBAPI_DIR = path.join(DOCS_DIR, 'webapi'); + +const WEB_HELPERS = { + Playwright: path.join(HELPERS_DIR, 'playwright.md'), + WebDriver: path.join(HELPERS_DIR, 'web-driver.md'), + Puppeteer: path.join(HELPERS_DIR, 'puppeteer.md'), + TestCafe: path.join(HELPERS_DIR, 'test-cafe.md'), +}; +const WEB_HELPER_NAMES = Object.keys(WEB_HELPERS); + +const MOBILE_HELPERS = { + Appium: path.join(HELPERS_DIR, 'appium.md'), + Detox: path.join(HELPERS_DIR, 'detox.md'), +}; + +const WEB_OUTPUT = path.join(DOCS_DIR, 'web-api.md'); +const MOBILE_OUTPUT = path.join(DOCS_DIR, 'mobile-api.md'); +const CHECK_MODE = process.argv.includes('--check'); + +const WEB_METHOD_OVERRIDES = { + click: { + notes: [ + 'ARIA locators are supported. Update examples to include the new locator type where relevant.', + '`I.click({ aria: "Select" });`', + '`I.click("Select");`', + ], + helperPrefix: { + WebDriver: + 'In WebDriver, click can only happen on an actionable element. Use specific locators and wait for element readiness when needed.', + }, + }, +}; + +function readFile(filePath) { + return fs.readFileSync(filePath, 'utf8').replace(/\r\n/g, '\n'); +} + +function normalizeForFile(content) { + return content.replace(/\n/g, '\r\n'); +} + +function writeFile(filePath, content) { + fs.writeFileSync(filePath, normalizeForFile(content), 'utf8'); +} + +function escRegExp(text) { + return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +function extractMethods(helperContent) { + const methods = []; + const seen = new Set(); + const re = /^###\s+([A-Za-z][A-Za-z0-9_]*)\s*$/gm; + let match; + + while ((match = re.exec(helperContent)) !== null) { + const method = match[1]; + if (!method.startsWith('_') && !seen.has(method)) { + seen.add(method); + methods.push(method); + } + } + + return methods; +} + +function extractMethodDoc(helperContent, method) { + const heading = new RegExp(`^###\\s+${escRegExp(method)}\\s*$`, 'm'); + const start = helperContent.search(heading); + if (start === -1) return null; + + const fromHeading = helperContent.slice(start); + const firstLineBreak = fromHeading.indexOf('\n'); + if (firstLineBreak === -1) return ''; + + const afterHeading = fromHeading.slice(firstLineBreak + 1); + const nextHeadingIdx = afterHeading.search(/^###\s+/m); + const section = + nextHeadingIdx === -1 ? afterHeading : afterHeading.slice(0, nextHeadingIdx); + + return section.trim(); +} + +function availability(exists) { + return exists ? 'Supported' : 'Not supported'; +} + +function generateWebApiContent() { + for (const [helperName, filePath] of Object.entries(WEB_HELPERS)) { + if (!fs.existsSync(filePath)) { + throw new Error( + `Missing helper source for ${helperName}: ${path.relative(ROOT, filePath)}`, + ); + } + } + + const helperDocs = Object.fromEntries( + Object.entries(WEB_HELPERS).map(([name, file]) => [name, readFile(file)]), + ); + + const helperMethods = Object.fromEntries( + Object.entries(helperDocs).map(([name, content]) => [name, new Set(extractMethods(content))]), + ); + + for (const helperName of WEB_HELPER_NAMES) { + if (helperMethods[helperName].size === 0) { + throw new Error( + `No public methods were extracted for ${helperName}. Check heading format in ${path.relative( + ROOT, + WEB_HELPERS[helperName], + )}.`, + ); + } + } + + const webapiFiles = fs + .readdirSync(WEBAPI_DIR) + .filter((name) => name.endsWith('.mustache')) + .sort((a, b) => a.localeCompare(b)); + + const lines = [ + '---', + 'title: Web API (Unified)', + '---', + '', + '# Web API (Unified)', + '', + '', + '', + 'This page is generated from `docs/webapi` and helper docblocks.', + '', + ]; + + for (const fileName of webapiFiles) { + const method = path.basename(fileName, '.mustache'); + const methodCall = `I.${method}()`; + const sharedBlock = readFile(path.join(WEBAPI_DIR, fileName)).trim(); + + lines.push(`## ${method}`); + lines.push(''); + lines.push(`| Availability | ${WEB_HELPER_NAMES.join(' | ')} |`); + lines.push(`| ${Array(WEB_HELPER_NAMES.length + 1).fill('---').join(' | ')} |`); + lines.push( + `| \`${methodCall}\` | ${WEB_HELPER_NAMES.map((name) => + availability(helperMethods[name].has(method)), + ).join(' | ')} |`, + ); + lines.push(''); + lines.push('### Shared'); + lines.push(''); + lines.push(sharedBlock || '_No shared snippet found._'); + lines.push(''); + + const override = WEB_METHOD_OVERRIDES[method]; + if (override?.notes?.length) { + lines.push('### Notes'); + lines.push(''); + for (const note of override.notes) { + lines.push(`- ${note}`); + } + lines.push(''); + } + + for (const helperName of WEB_HELPER_NAMES) { + const content = helperDocs[helperName]; + const methodDoc = extractMethodDoc(content, method); + lines.push(`### In ${helperName}`); + lines.push(''); + const prefix = override?.helperPrefix?.[helperName]; + if (prefix) { + lines.push(prefix); + lines.push(''); + } + if (methodDoc) { + lines.push(methodDoc); + } else { + lines.push('_Not available in this helper._'); + } + lines.push(''); + } + } + + return lines.join('\n').trimEnd() + '\n'; +} + +function generateMobileApiContent() { + const helperDocs = Object.fromEntries( + Object.entries(MOBILE_HELPERS).map(([name, file]) => [name, readFile(file)]), + ); + + const appiumMethods = extractMethods(helperDocs.Appium); + const detoxMethods = extractMethods(helperDocs.Detox); + const allMethods = Array.from(new Set([...appiumMethods, ...detoxMethods])).sort((a, b) => + a.localeCompare(b), + ); + + const hasMethod = { + Appium: new Set(appiumMethods), + Detox: new Set(detoxMethods), + }; + + const lines = [ + '---', + 'title: Mobile API (Unified)', + '---', + '', + '# Mobile API (Unified)', + '', + '', + '', + 'This page is generated from Appium and Detox helper docblocks.', + '', + ]; + + for (const method of allMethods) { + const methodCall = `I.${method}()`; + lines.push(`## ${method}`); + lines.push(''); + lines.push('| Availability | Appium | Detox |'); + lines.push('| --- | --- | --- |'); + lines.push( + `| \`${methodCall}\` | ${availability(hasMethod.Appium.has(method))} | ${availability( + hasMethod.Detox.has(method), + )} |`, + ); + lines.push(''); + + for (const helperName of ['Appium', 'Detox']) { + const methodDoc = extractMethodDoc(helperDocs[helperName], method); + lines.push(`### In ${helperName}`); + lines.push(''); + if (methodDoc) { + lines.push(methodDoc); + } else { + lines.push('_Not available in this helper._'); + } + lines.push(''); + } + } + + return lines.join('\n').trimEnd() + '\n'; +} + +function isFileUpToDate(filePath, generatedContent) { + if (!fs.existsSync(filePath)) return false; + const existing = fs.readFileSync(filePath, 'utf8'); + return existing === normalizeForFile(generatedContent); +} + +function main() { + const webContent = generateWebApiContent(); + const mobileContent = generateMobileApiContent(); + + if (CHECK_MODE) { + const webOk = isFileUpToDate(WEB_OUTPUT, webContent); + const mobileOk = isFileUpToDate(MOBILE_OUTPUT, mobileContent); + + if (webOk && mobileOk) { + console.log('Unified API docs are up to date.'); + return; + } + + const outdated = []; + if (!webOk) outdated.push(path.relative(ROOT, WEB_OUTPUT)); + if (!mobileOk) outdated.push(path.relative(ROOT, MOBILE_OUTPUT)); + console.error(`Unified API docs are outdated: ${outdated.join(', ')}`); + console.error('Run: npm run generate:unified-api'); + process.exit(1); + } + + writeFile(WEB_OUTPUT, webContent); + writeFile(MOBILE_OUTPUT, mobileContent); + console.log('Generated:', path.relative(ROOT, WEB_OUTPUT), path.relative(ROOT, MOBILE_OUTPUT)); +} + +main(); diff --git a/src/components/Links.astro b/src/components/Links.astro index 8814cc33..5330b31a 100644 --- a/src/components/Links.astro +++ b/src/components/Links.astro @@ -9,20 +9,16 @@
@@ -168,4 +168,4 @@
- \ No newline at end of file + diff --git a/src/pages/home/components/testomatio/index.astro b/src/pages/home/components/testomatio/index.astro index 75fb1611..cd808d3b 100644 --- a/src/pages/home/components/testomatio/index.astro +++ b/src/pages/home/components/testomatio/index.astro @@ -80,7 +80,9 @@ View Integration Guide @@ -209,4 +211,4 @@ - \ No newline at end of file + diff --git a/src/pages/home/components/trusted/index.astro b/src/pages/home/components/trusted/index.astro index 43115592..6c2b3f0e 100644 --- a/src/pages/home/components/trusted/index.astro +++ b/src/pages/home/components/trusted/index.astro @@ -30,9 +30,17 @@ import "swiper/css/pagination";
{ - [BC_LogoScreen_C, doxyme, gen3, isotipo, kiabi, mynd, zenitech].map((data) => + [ + { image: BC_LogoScreen_C, alt: "BC logo" }, + { image: doxyme, alt: "Doxy.me logo" }, + { image: gen3, alt: "Gen3 logo" }, + { image: isotipo, alt: "Isotipo logo" }, + { image: kiabi, alt: "Kiabi logo" }, + { image: mynd, alt: "Mynd logo" }, + { image: zenitech, alt: "Zenitech logo" }, + ].map((item) =>
- + {item.alt}
) } diff --git a/src/pages/home/index.astro b/src/pages/home/index.astro index 0098fbc0..ef58bfbf 100644 --- a/src/pages/home/index.astro +++ b/src/pages/home/index.astro @@ -26,7 +26,7 @@ import Ai from './components/ai/index.astro' document.addEventListener('astro:before-swap', e=>{ const classList = document.querySelector("div.page > header")!.classList; const isHome = e.to.pathname === "/"; - classList.toggle("home-header header", isHome); + classList.toggle("home-header", isHome); classList.toggle("header", !isHome); }) - \ No newline at end of file + From 163380796a69217a3f8401fe0fbb06f1cba39da0 Mon Sep 17 00:00:00 2001 From: Denys Kuchma Date: Fri, 13 Mar 2026 17:16:14 +0200 Subject: [PATCH 2/8] add final refactor --- .github/workflows/build-docs.yml | 2 + .github/workflows/deployment.yml | 26 + astro.config.mjs | 57 +- docsearch.json | 4 +- package.json | 1 + scripts/generate-unified-api.mjs | 244 +- scripts/sync-changelog.mjs | 75 + src/components/Footer.astro | 4 +- src/components/Links.astro | 2 +- src/components/PageFrame.astro | 24 + src/components/Search.astro | 100 +- src/content/docs/advanced.md | 13 +- src/content/docs/ai.md | 65 +- src/content/docs/angular.md | 324 - src/content/docs/api.md | 33 +- src/content/docs/basics.md | 5 +- src/content/docs/bdd.md | 4 +- src/content/docs/best.md | 108 +- src/content/docs/blog/my-first-blog-post.md | 21 +- .../docs/{wiki/books-&-posts.md => books.md} | 5 +- src/content/docs/bootstrap.md | 7 +- src/content/docs/changelog.md | 678 + src/content/docs/commands.md | 9 +- src/content/docs/community-helpers-page.md | 3 +- src/content/docs/configuration.md | 17 +- src/content/docs/continuous-integration.md | 3 +- src/content/docs/custom-helpers.md | 16 +- src/content/docs/data.md | 34 +- src/content/docs/detox.md | 8 +- src/content/docs/docker.md | 140 + src/content/docs/effects.md | 8 +- src/content/docs/els.md | 6 +- src/content/docs/email.md | 5 +- src/content/docs/esm-migration.md | 242 + src/content/docs/examples.md | 67 + src/content/docs/heal.md | 9 +- src/content/docs/helpers/ai.md | 104 + src/content/docs/helpers/api-data-factory.md | 23 +- src/content/docs/helpers/appium.md | 31 +- src/content/docs/helpers/detox.md | 34 +- src/content/docs/helpers/expect.md | 6 +- src/content/docs/helpers/file-system.md | 9 +- .../docs/helpers/graph-ql-data-factory.md | 23 +- src/content/docs/helpers/graph-ql.md | 15 +- src/content/docs/helpers/json-response.md | 15 +- src/content/docs/helpers/mochawesome.md | 10 + src/content/docs/helpers/mock-request.md | 45 +- src/content/docs/helpers/mock-server.md | 17 +- src/content/docs/helpers/open-ai.md | 15 +- src/content/docs/helpers/playwright.md | 27 +- src/content/docs/helpers/polly.md | 45 + src/content/docs/helpers/protractor.md | 27 +- src/content/docs/helpers/puppeteer-firefox.md | 14 +- src/content/docs/helpers/puppeteer.md | 23 +- src/content/docs/helpers/rest.md | 9 +- .../docs/helpers/soft-expect-helper.md | 12 +- src/content/docs/helpers/test-cafe.md | 1318 -- src/content/docs/helpers/web-driver.md | 31 +- src/content/docs/hooks.md | 251 +- .../docs/images/angular-protractor.png | Bin 8597 -> 0 bytes src/content/docs/installation.md | 79 + src/content/docs/internal-api.md | 25 +- src/content/docs/internal-test-server.md | 92 + src/content/docs/locators.md | 41 +- src/content/docs/mcp.md | 548 + src/content/docs/mobile-api.md | 1635 ++- .../docs/mobile-react-native-locators.md | 6 + src/content/docs/mobile.md | 11 +- src/content/docs/pageobjects.md | 13 +- src/content/docs/parallel.md | 8 +- src/content/docs/playwright.md | 27 +- src/content/docs/plugins.md | 78 +- src/content/docs/puppeteer.md | 17 +- src/content/docs/quickstart.md | 28 +- src/content/docs/react.md | 3 +- src/content/docs/reports.md | 15 +- src/content/docs/retry.md | 377 + src/content/docs/secrets.md | 6 +- src/content/docs/shadow.md | 4 +- src/content/docs/shared/react.mustache | 2 +- src/content/docs/testcafe.md | 175 - src/content/docs/translation.md | 1 - src/content/docs/tutorial.md | 128 + src/content/docs/typescript.md | 7 +- src/content/docs/ui.md | 5 +- src/content/docs/{wiki => }/videos.md | 5 +- src/content/docs/visual.md | 15 +- src/content/docs/vue.md | 108 +- src/content/docs/web-api.md | 10745 +++++----------- src/content/docs/web-element.md | 255 + src/content/docs/webapi/appendField.mustache | 7 +- src/content/docs/webapi/attachFile.mustache | 7 +- src/content/docs/webapi/blur.mustache | 7 +- src/content/docs/webapi/checkOption.mustache | 9 +- src/content/docs/webapi/clearField.mustache | 7 +- src/content/docs/webapi/click.mustache | 7 +- src/content/docs/webapi/clickLink.mustache | 7 +- src/content/docs/webapi/dontSee.mustache | 7 +- .../webapi/dontSeeCheckboxIsChecked.mustache | 7 +- .../docs/webapi/dontSeeElement.mustache | 2 + .../docs/webapi/dontSeeElementInDOM.mustache | 2 + .../docs/webapi/dontSeeInField.mustache | 7 +- src/content/docs/webapi/doubleClick.mustache | 7 +- src/content/docs/webapi/downloadFile.mustache | 7 +- src/content/docs/webapi/dragAndDrop.mustache | 9 +- src/content/docs/webapi/dragSlider.mustache | 7 +- src/content/docs/webapi/fillField.mustache | 7 +- src/content/docs/webapi/focus.mustache | 7 +- src/content/docs/webapi/forceClick.mustache | 7 +- .../docs/webapi/forceRightClick.mustache | 7 +- .../docs/webapi/grabAttributeFrom.mustache | 7 +- .../docs/webapi/grabAttributeFromAll.mustache | 7 +- .../docs/webapi/grabCssPropertyFrom.mustache | 7 +- .../webapi/grabCssPropertyFromAll.mustache | 7 +- .../webapi/grabElementBoundingRect.mustache | 7 +- src/content/docs/webapi/grabHTMLFrom.mustache | 7 +- .../docs/webapi/grabHTMLFromAll.mustache | 7 +- .../grabNumberOfVisibleElements.mustache | 8 +- src/content/docs/webapi/grabTextFrom.mustache | 7 +- .../docs/webapi/grabTextFromAll.mustache | 7 +- .../docs/webapi/grabValueFrom.mustache | 7 +- .../docs/webapi/grabValueFromAll.mustache | 7 +- .../docs/webapi/grabWebElement.mustache | 7 +- .../docs/webapi/grabWebElements.mustache | 7 +- src/content/docs/webapi/moveCursorTo.mustache | 7 +- src/content/docs/webapi/pressKey.mustache | 2 +- src/content/docs/webapi/pressKeyDown.mustache | 2 +- src/content/docs/webapi/pressKeyUp.mustache | 2 +- .../pressKeyWithKeyNormalization.mustache | 2 +- src/content/docs/webapi/rightClick.mustache | 9 +- .../webapi/saveElementScreenshot.mustache | 7 +- .../docs/webapi/scrollIntoView.mustache | 7 +- src/content/docs/webapi/scrollTo.mustache | 7 +- src/content/docs/webapi/see.mustache | 7 +- .../webapi/seeAttributesOnElements.mustache | 7 +- .../docs/webapi/seeCheckboxIsChecked.mustache | 7 +- .../seeCssPropertiesOnElements.mustache | 7 +- src/content/docs/webapi/seeElement.mustache | 7 +- .../docs/webapi/seeElementInDOM.mustache | 7 +- src/content/docs/webapi/seeInField.mustache | 7 +- .../docs/webapi/seeNumberOfElements.mustache | 7 +- .../seeNumberOfVisibleElements.mustache | 7 +- .../docs/webapi/seeTextEquals.mustache | 7 +- src/content/docs/webapi/selectOption.mustache | 7 +- src/content/docs/webapi/switchTo.mustache | 7 +- src/content/docs/webapi/type.mustache | 2 +- .../docs/webapi/uncheckOption.mustache | 9 +- .../docs/webapi/waitForClickable.mustache | 7 +- .../docs/webapi/waitForDetached.mustache | 7 +- .../docs/webapi/waitForDisabled.mustache | 5 +- .../docs/webapi/waitForElement.mustache | 7 +- .../docs/webapi/waitForEnabled.mustache | 5 +- .../docs/webapi/waitForInvisible.mustache | 7 +- src/content/docs/webapi/waitForText.mustache | 7 +- src/content/docs/webapi/waitForValue.mustache | 2 + .../docs/webapi/waitForVisible.mustache | 7 +- .../waitNumberOfVisibleElements.mustache | 7 +- src/content/docs/webapi/waitToHide.mustache | 7 +- src/content/docs/webdriver.md | 35 +- .../docs/wiki/community-helpers-&-plugins.md | 58 - src/content/docs/wiki/community-helpers.md | 49 - ...verting-playwright-to-istanbul-coverage.md | 101 - src/content/docs/wiki/examples.md | 149 - .../wiki/google-summer-of-code-(gsoc)-2020.md | 72 - src/content/docs/wiki/home.md | 20 - .../migration-to-appium-v2---codeceptjs.md | 87 - src/content/docs/wiki/release-process.md | 28 - src/content/docs/wiki/roadmap.md | 27 - src/content/docs/wiki/tests.md | 1397 -- .../docs/wiki/upgrading-to-codeceptjs-3.md | 157 - src/pages/home/index.astro | 9 - 171 files changed, 7892 insertions(+), 13670 deletions(-) create mode 100644 scripts/sync-changelog.mjs delete mode 100644 src/content/docs/angular.md rename src/content/docs/{wiki/books-&-posts.md => books.md} (90%) create mode 100644 src/content/docs/changelog.md create mode 100644 src/content/docs/docker.md create mode 100644 src/content/docs/esm-migration.md create mode 100644 src/content/docs/examples.md create mode 100644 src/content/docs/helpers/ai.md create mode 100644 src/content/docs/helpers/mochawesome.md create mode 100644 src/content/docs/helpers/polly.md delete mode 100644 src/content/docs/helpers/test-cafe.md delete mode 100644 src/content/docs/images/angular-protractor.png create mode 100644 src/content/docs/installation.md create mode 100644 src/content/docs/internal-test-server.md create mode 100644 src/content/docs/mcp.md create mode 100644 src/content/docs/retry.md delete mode 100644 src/content/docs/testcafe.md create mode 100644 src/content/docs/tutorial.md rename src/content/docs/{wiki => }/videos.md (79%) create mode 100644 src/content/docs/web-element.md delete mode 100644 src/content/docs/wiki/community-helpers-&-plugins.md delete mode 100644 src/content/docs/wiki/community-helpers.md delete mode 100644 src/content/docs/wiki/converting-playwright-to-istanbul-coverage.md delete mode 100644 src/content/docs/wiki/examples.md delete mode 100644 src/content/docs/wiki/google-summer-of-code-(gsoc)-2020.md delete mode 100644 src/content/docs/wiki/home.md delete mode 100644 src/content/docs/wiki/migration-to-appium-v2---codeceptjs.md delete mode 100644 src/content/docs/wiki/release-process.md delete mode 100644 src/content/docs/wiki/roadmap.md delete mode 100644 src/content/docs/wiki/tests.md delete mode 100644 src/content/docs/wiki/upgrading-to-codeceptjs-3.md diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 7b7e2e00..64e7bb19 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -25,6 +25,8 @@ jobs: - run: git config --global user.email "github-cd-bot@example.com" - name: Install deps run: npm i + - name: Sync changelog from CodeceptJS 4.x + run: npm run sync:changelog - name: Generate unified API docs run: npm run generate:unified-api - name: Build docs diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 04afdc91..e3ab82a5 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -1,5 +1,12 @@ name: Publish website +on: + push: + branches: + - main + - master + workflow_dispatch: + jobs: publish-npm: runs-on: ubuntu-latest @@ -15,9 +22,28 @@ jobs: registry-url: https://registry.npmjs.org/ - name: Install deps run: npm i + - name: Sync changelog from CodeceptJS 4.x + run: npm run sync:changelog - name: Generate unified API docs run: npm run generate:unified-api - name: deployment run: ./runok.js publish env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + run-search-scraper: + name: Run Search Scraper + runs-on: ubuntu-latest + needs: publish-npm + steps: + - uses: actions/checkout@v4 + - name: Index docs in Meilisearch + env: + MEILISEARCH_HOST_URL: ${{ secrets.MEILISEARCH_HOST_URL }} + MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_API_KEY }} + run: | + docker run -t --rm \ + -e MEILISEARCH_HOST_URL=$MEILISEARCH_HOST_URL \ + -e MEILISEARCH_API_KEY=$MEILISEARCH_API_KEY \ + -v $PWD/docsearch.json:/docs-scraper/docsearch.json \ + getmeili/docs-scraper:latest pipenv run ./docs_scraper docsearch.json diff --git a/astro.config.mjs b/astro.config.mjs index ca1c3973..bf07a8c1 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -11,6 +11,7 @@ const options = { }; export default defineConfig({ + site: 'https://codecept.io', integrations: [ starlight({ expressiveCode: { @@ -51,7 +52,8 @@ export default defineConfig({ {label: 'Testing with Playwright', link: 'playwright'}, {label: 'Testing with WebDriver', link: 'webdriver'}, {label: 'Testing with Puppeteer', link: 'puppeteer'}, - {label: 'Testing with TestCafe', link: 'testcafe'}, + {label: 'Testing React Applications', link: 'react'}, + {label: 'Testing Vue Apps', link: 'vue'}, ], }, { @@ -65,10 +67,10 @@ export default defineConfig({ label: 'Organizing Tests', items: [ {label: 'Page Objects', link: 'pageobjects'}, - {label: 'TypeScript', link: 'typescript'}, {label: 'Data Management', link: 'data'}, {label: 'Behavior Driven Development', link: 'bdd'}, {label: 'Locators', link: 'locators'}, + {label: 'Shadow DOM', link: 'shadow'}, {label: 'Translation', link: 'translation'}, {label: 'Best Practices', link: 'best'}, ], @@ -84,45 +86,56 @@ export default defineConfig({ {label: 'Plugins', link: 'plugins'}, {label: 'Effects', link: 'effects'}, {label: 'Element Access (els)', link: 'els'}, - {label: 'Shadow DOM', link: 'shadow'}, + {label: 'WebElement API', link: 'web-element'}, ], }, { label: 'Advanced Usage', items: [ {label: 'Advanced Usage', link: 'advanced'}, + {label: 'TypeScript', link: 'typescript'}, + {label: 'ESM Migration', link: 'esm-migration'}, {label: 'CodeceptUI', link: 'ui'}, {label: 'Bootstrap', link: 'bootstrap'}, {label: 'Reporters', link: 'reports'}, - {label: 'Continuous Integration', link: 'continuous-integration'}, + {label: 'Docker', link: 'docker'}, {label: 'Parallel Execution', link: 'parallel'}, + {label: 'Retry Mechanisms', link: 'retry'}, {label: 'Visual Testing', link: 'visual'}, {label: 'Email Testing', link: 'email'}, {label: 'Secrets', link: 'secrets'}, {label: 'Extending', link: 'hooks'}, {label: 'Concepts', link: 'internal-api'}, - {label: 'Testing React Applications', link: 'react'}, {label: 'Testing with AI', link: 'ai'}, + {label: 'MCP Server', link: 'mcp'}, {label: 'Self-Healing Tests', link: 'heal'}, - {label: 'Testing with Protractor', link: 'angular'}, - {label: 'Testing Vue Apps', link: 'vue'}, + ], + }, + { + label: 'Resources', + items: [ + {label: 'Tutorial', link: 'tutorial'}, + {label: 'Examples', link: 'examples'}, + {label: 'Videos', link: 'videos'}, + {label: 'Books & Posts', link: 'books'}, + {label: 'Community Helpers', link: 'helpers/community-helpers'}, + {label: 'Changelog', link: 'changelog'}, ], }, ], }, { + id: 'helpers', label: 'Helpers', link: '/helpers/playwright/', items: [ { label: 'Web Testing', items: [ + {label: 'Playwright', link: 'helpers/playwright'}, {label: 'WebDriver', link: 'helpers/web-driver'}, {label: 'Puppeteer', link: 'helpers/puppeteer'}, - {label: 'Puppeteer Firefox', link: 'helpers/puppeteer-firefox'}, - {label: 'TestCafe', link: 'helpers/test-cafe'}, - {label: 'Protractor (Legacy)', link: 'helpers/protractor'}, ], }, { @@ -140,41 +153,38 @@ export default defineConfig({ {label: 'GraphQL', link: 'helpers/graph-ql'}, {label: 'GraphQLDataFactory', link: 'helpers/graph-ql-data-factory'}, {label: 'JSONResponse', link: 'helpers/json-response'}, - {label: 'MockRequest', link: 'helpers/mock-request'}, ], }, { label: 'Other Helpers', items: [ {label: 'OpenAI', link: 'helpers/open-ai'}, + {label: 'AI', link: 'helpers/ai'}, {label: 'FileSystem', link: 'helpers/file-system'}, {label: 'Expect', link: 'helpers/expect'}, {label: 'SoftExpectHelper', link: 'helpers/soft-expect-helper'}, + {label: 'MockRequest', link: 'helpers/mock-request'}, {label: 'MockServer', link: 'helpers/mock-server'}, + {label: 'Polly', link: 'helpers/polly'}, + {label: 'Mochawesome', link: 'helpers/mochawesome'}, {label: 'Custom Helpers', link: 'custom-helpers'}, - {label: 'Community Helpers', link: 'helpers/community-helpers'}, ], }, ] }, { - label: 'Wiki', - link: '/wiki/home/', + id: 'blog', + label: 'Blog', + link: '/blog/my-first-blog-post/', items: [ - {label: 'Wiki', autogenerate: {directory: 'wiki/'}}, - ], - }, - { - label: 'blog', - link: '/blog', - items: [ - {label: 'blog', autogenerate: {directory: 'blog/'}}, + {label: 'Blog', autogenerate: {directory: 'blog/'}}, ], }, ], { exclude: ['/404'], topics: { - documentation: ['/mobile-react-native-locators'], + documentation: ['/mobile-react-native-locators', '/installation', '/continuous-integration', '/internal-test-server'], + helpers: ['/helpers/puppeteer-firefox', '/helpers/protractor'], }, }), starlightScrollToTop({ @@ -205,3 +215,4 @@ export default defineConfig({ }, }); + diff --git a/docsearch.json b/docsearch.json index 32f16db0..351e2868 100644 --- a/docsearch.json +++ b/docsearch.json @@ -2,7 +2,7 @@ "start_urls": [ "https://codecept.io/" ], - "index_uid": "docs", + "index_uid": "codeceptjs", "selectors": { "default": { "lvl0": "main h1", @@ -13,4 +13,4 @@ "text": "main p" } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index b341d042..8cf6e093 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "build": "astro build", "preview": "astro preview", "astro": "astro", + "sync:changelog": "node scripts/sync-changelog.mjs", "generate:unified-api": "node scripts/generate-unified-api.mjs", "generate:unified-api:check": "node scripts/generate-unified-api.mjs --check" }, diff --git a/scripts/generate-unified-api.mjs b/scripts/generate-unified-api.mjs index c2a14337..4ff764a5 100644 --- a/scripts/generate-unified-api.mjs +++ b/scripts/generate-unified-api.mjs @@ -10,7 +10,6 @@ const WEB_HELPERS = { Playwright: path.join(HELPERS_DIR, 'playwright.md'), WebDriver: path.join(HELPERS_DIR, 'web-driver.md'), Puppeteer: path.join(HELPERS_DIR, 'puppeteer.md'), - TestCafe: path.join(HELPERS_DIR, 'test-cafe.md'), }; const WEB_HELPER_NAMES = Object.keys(WEB_HELPERS); @@ -25,6 +24,7 @@ const CHECK_MODE = process.argv.includes('--check'); const WEB_METHOD_OVERRIDES = { click: { + compactDifferences: true, notes: [ 'ARIA locators are supported. Update examples to include the new locator type where relevant.', '`I.click({ aria: "Select" });`', @@ -61,6 +61,8 @@ function extractMethods(helperContent) { while ((match = re.exec(helperContent)) !== null) { const method = match[1]; + // API methods are declared as lowerCamelCase headings. + if (!/^[a-z][A-Za-z0-9_]*$/.test(method)) continue; if (!method.startsWith('_') && !seen.has(method)) { seen.add(method); methods.push(method); @@ -91,6 +93,126 @@ function availability(exists) { return exists ? 'Supported' : 'Not supported'; } +function normalizeDocForDiff(content) { + return content + .replace(/\r\n/g, '\n') + .replace(/\[\d+\]/g, '[]') + .replace(/[ \t]+/g, ' ') + .replace(/\n{3,}/g, '\n\n') + .trim(); +} + +function renderAvailabilityTable(headers, row) { + const th = headers + .map((h) => `${h}`) + .join(''); + const td = row + .map((c) => `${c}`) + .join(''); + + return [ + '', + ` ${th}`, + ` ${td}`, + '
', + ]; +} + +function normalizeWebUnifiedAnchors(content) { + return content + .replace(/#fillfield\b/g, '#ifillfield') + .replace(/#click\b/g, '#iclick') + .replace(/\/webdriver#testing-with-webdriver\b/g, '/webdriver#what-is-selenium-webdriver'); +} + +function normalizeMobileUnifiedAnchors(content) { + return content + .replace(/#tap\b/g, '#itap') + .replace(/#relaunchApp\b/g, '#irelaunchapp') + .replace(/#relaunchapp\b/g, '#irelaunchapp') + .replace(/#click\b/g, '#iclick'); +} + +function parseJSDocParam(line) { + const match = line.match(/^@param\s+\{([^}]+)\}\s+(\[[^\]]+\]|[^\s]+)\s*(.*)$/); + if (!match) return null; + return { + type: match[1].trim(), + name: match[2].trim(), + description: match[3].trim(), + }; +} + +function parseJSDocReturn(line) { + const match = line.match(/^@returns?\s+\{([^}]+)\}\s*(.*)$/); + if (!match) return null; + return { + type: match[1].trim(), + description: match[2].trim(), + }; +} + +function formatSharedBlock(content) { + const lines = content.split('\n'); + const body = []; + const params = []; + const returns = []; + + for (const line of lines) { + const trimmed = line.trim(); + if (trimmed.startsWith('@param ')) { + const param = parseJSDocParam(trimmed); + if (param) { + params.push(param); + continue; + } + } + if (/^@returns?\s+/.test(trimmed)) { + const ret = parseJSDocReturn(trimmed); + if (ret) { + returns.push(ret); + continue; + } + } + body.push(line); + } + + while (body.length && body[body.length - 1].trim() === '') { + body.pop(); + } + + const out = [...body]; + + if (params.length) { + out.push(''); + out.push('**Parameters**'); + out.push(''); + for (const param of params) { + const desc = param.description ? ` - ${param.description}` : ''; + out.push(`- \`${param.name}\` \`${param.type}\`${desc}`); + } + } + + if (returns.length) { + out.push(''); + out.push('**Returns**'); + out.push(''); + for (const ret of returns) { + const desc = ret.description ? ` - ${ret.description}` : ''; + out.push(`- \`${ret.type}\`${desc}`); + } + } + + return out.join('\n').trim(); +} + +function normalizeMethodDocHeadings(content) { + if (!content) return content; + return content + .replace(/^#{4,5}\s+Parameters\s*$/gm, '**Parameters**') + .replace(/^#{4,5}\s+Returns?\s*$/gm, '**Returns**'); +} + function generateWebApiContent() { for (const [helperName, filePath] of Object.entries(WEB_HELPERS)) { if (!fs.existsSync(filePath)) { @@ -129,37 +251,38 @@ function generateWebApiContent() { 'title: Web API (Unified)', '---', '', - '# Web API (Unified)', - '', '', '', 'This page is generated from `docs/webapi` and helper docblocks.', '', + '## Methods', + '', ]; for (const fileName of webapiFiles) { const method = path.basename(fileName, '.mustache'); const methodCall = `I.${method}()`; - const sharedBlock = readFile(path.join(WEBAPI_DIR, fileName)).trim(); + const sharedBlock = formatSharedBlock(readFile(path.join(WEBAPI_DIR, fileName)).trim()); - lines.push(`## ${method}`); + lines.push(`### \`${methodCall}\``); lines.push(''); - lines.push(`| Availability | ${WEB_HELPER_NAMES.join(' | ')} |`); - lines.push(`| ${Array(WEB_HELPER_NAMES.length + 1).fill('---').join(' | ')} |`); lines.push( - `| \`${methodCall}\` | ${WEB_HELPER_NAMES.map((name) => - availability(helperMethods[name].has(method)), - ).join(' | ')} |`, + ...renderAvailabilityTable( + ['Method', ...WEB_HELPER_NAMES], + [`${methodCall}`, ...WEB_HELPER_NAMES.map((name) => + availability(helperMethods[name].has(method)), + )], + ), ); lines.push(''); - lines.push('### Shared'); + lines.push('#### Common Behavior'); lines.push(''); lines.push(sharedBlock || '_No shared snippet found._'); lines.push(''); const override = WEB_METHOD_OVERRIDES[method]; if (override?.notes?.length) { - lines.push('### Notes'); + lines.push('#### Notes'); lines.push(''); for (const note of override.notes) { lines.push(`- ${note}`); @@ -167,26 +290,69 @@ function generateWebApiContent() { lines.push(''); } - for (const helperName of WEB_HELPER_NAMES) { - const content = helperDocs[helperName]; - const methodDoc = extractMethodDoc(content, method); - lines.push(`### In ${helperName}`); + const helperDocsByMethod = WEB_HELPER_NAMES.map((helperName) => { + const methodDoc = extractMethodDoc(helperDocs[helperName], method); + const prefix = override?.helperPrefix?.[helperName] || ''; + return { + helperName, + supported: helperMethods[helperName].has(method), + methodDoc, + prefix, + normalized: methodDoc ? normalizeDocForDiff(methodDoc) : '', + }; + }); + + const supportedWithDocs = helperDocsByMethod.filter((item) => item.supported && item.methodDoc); + const uniqueGroups = new Map(); + for (const item of supportedWithDocs) { + const key = item.normalized; + if (!uniqueGroups.has(key)) uniqueGroups.set(key, []); + uniqueGroups.get(key).push(item.helperName); + } + + const hasHelperPrefixOverrides = helperDocsByMethod.some((item) => item.prefix); + + const compactDifferences = method === 'click' || Boolean(override?.compactDifferences); + if (uniqueGroups.size > 1 || hasHelperPrefixOverrides) { + lines.push('#### Helper-Specific Differences'); lines.push(''); - const prefix = override?.helperPrefix?.[helperName]; - if (prefix) { - lines.push(prefix); - lines.push(''); + + if (compactDifferences) { + for (const item of helperDocsByMethod) { + if (!item.prefix) continue; + lines.push(`**${item.helperName}**`); + lines.push(''); + lines.push(item.prefix); + lines.push(''); + } + continue; } - if (methodDoc) { - lines.push(methodDoc); - } else { - lines.push('_Not available in this helper._'); + + let baselineGroup = []; + for (const names of uniqueGroups.values()) { + if (names.length > baselineGroup.length) baselineGroup = names; + } + const hideBaseline = baselineGroup.length > 1; + + for (const item of helperDocsByMethod) { + if (!item.supported || !item.methodDoc) continue; + const differsFromBaseline = !baselineGroup.includes(item.helperName); + const forceInclude = Boolean(item.prefix); + if (hideBaseline && !differsFromBaseline && !forceInclude) continue; + + lines.push(`**${item.helperName}**`); + lines.push(''); + if (item.prefix) { + lines.push(item.prefix); + lines.push(''); + } + lines.push(normalizeMethodDocHeadings(item.methodDoc)); + lines.push(''); } - lines.push(''); } } - return lines.join('\n').trimEnd() + '\n'; + return normalizeWebUnifiedAnchors(lines.join('\n').trimEnd() + '\n'); } function generateMobileApiContent() { @@ -210,33 +376,37 @@ function generateMobileApiContent() { 'title: Mobile API (Unified)', '---', '', - '# Mobile API (Unified)', - '', '', '', 'This page is generated from Appium and Detox helper docblocks.', + 'For hybrid/mobile webview flows, ARIA locators such as `{ aria: "Sign in" }` are available in web helpers.', + '', + '## Methods', '', ]; for (const method of allMethods) { const methodCall = `I.${method}()`; - lines.push(`## ${method}`); + lines.push(`### \`${methodCall}\``); lines.push(''); - lines.push('| Availability | Appium | Detox |'); - lines.push('| --- | --- | --- |'); lines.push( - `| \`${methodCall}\` | ${availability(hasMethod.Appium.has(method))} | ${availability( - hasMethod.Detox.has(method), - )} |`, + ...renderAvailabilityTable( + ['Method', 'Appium', 'Detox'], + [ + `${methodCall}`, + availability(hasMethod.Appium.has(method)), + availability(hasMethod.Detox.has(method)), + ], + ), ); lines.push(''); for (const helperName of ['Appium', 'Detox']) { const methodDoc = extractMethodDoc(helperDocs[helperName], method); - lines.push(`### In ${helperName}`); + lines.push(`**${helperName}**`); lines.push(''); if (methodDoc) { - lines.push(methodDoc); + lines.push(normalizeMethodDocHeadings(methodDoc)); } else { lines.push('_Not available in this helper._'); } @@ -244,7 +414,7 @@ function generateMobileApiContent() { } } - return lines.join('\n').trimEnd() + '\n'; + return normalizeMobileUnifiedAnchors(lines.join('\n').trimEnd() + '\n'); } function isFileUpToDate(filePath, generatedContent) { diff --git a/scripts/sync-changelog.mjs b/scripts/sync-changelog.mjs new file mode 100644 index 00000000..a5babb2a --- /dev/null +++ b/scripts/sync-changelog.mjs @@ -0,0 +1,75 @@ +import https from 'node:https'; +import fs from 'node:fs'; +import path from 'node:path'; + +const CHANGELOG_URL = + process.env.CODECEPTJS_CHANGELOG_URL || + 'https://raw.githubusercontent.com/codeceptjs/CodeceptJS/4.x/docs/changelog.md'; +const OUTPUT_FILE = path.join(process.cwd(), 'src', 'content', 'docs', 'changelog.md'); +const MAX_RELEASES = Number(process.env.CODECEPTJS_CHANGELOG_MAX_RELEASES || 10); + +function fetchText(url) { + return new Promise((resolve, reject) => { + https + .get(url, (res) => { + if (res.statusCode !== 200) { + reject(new Error(`Failed to fetch changelog: HTTP ${res.statusCode}`)); + res.resume(); + return; + } + + res.setEncoding('utf8'); + let data = ''; + res.on('data', (chunk) => { + data += chunk; + }); + res.on('end', () => resolve(data)); + }) + .on('error', reject); + }); +} + +function normalizeFrontmatter(content) { + const normalized = content.replace(/\r\n/g, '\n'); + const fmMatch = normalized.match(/^---\n([\s\S]*?)\n---\n?/); + + let body = normalized; + let title = 'Releases'; + + if (fmMatch) { + body = normalized.slice(fmMatch[0].length); + const titleMatch = fmMatch[1].match(/^title:\s*(.+)$/m); + if (titleMatch) title = titleMatch[1].trim(); + } + + const frontmatter = ['---', `title: ${title}`, 'slug: changelog', '---', ''].join('\n'); + return `${frontmatter}${trimToLatestReleases(body).trimStart()}`; +} + +function trimToLatestReleases(content) { + const lines = content.replace(/\r\n/g, '\n').split('\n'); + const sectionStarts = []; + + for (let i = 0; i < lines.length; i += 1) { + if (/^##\s+/.test(lines[i])) sectionStarts.push(i); + } + + if (sectionStarts.length <= MAX_RELEASES) { + return lines.join('\n'); + } + + const cutoff = sectionStarts[MAX_RELEASES]; + return lines.slice(0, cutoff).join('\n').trimEnd() + '\n'; +} + +async function main() { + const upstream = await fetchText(CHANGELOG_URL); + const output = normalizeFrontmatter(upstream); + fs.writeFileSync(OUTPUT_FILE, output, 'utf8'); + console.log(`Synced changelog from ${CHANGELOG_URL}`); +} + +main().catch((err) => { + console.error(err.message); + process.exit(1); +}); diff --git a/src/components/Footer.astro b/src/components/Footer.astro index ef971ef0..865d8f0f 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -180,7 +180,7 @@ const isHomepage = Astro.locals.starlightRoute.id === '';
@@ -203,4 +203,4 @@ const isHomepage = Astro.locals.starlightRoute.id === ''; a { text-decoration: none; } - \ No newline at end of file + diff --git a/src/components/Links.astro b/src/components/Links.astro index 5330b31a..60e43303 100644 --- a/src/components/Links.astro +++ b/src/components/Links.astro @@ -46,7 +46,7 @@ Slack
- + Contributing diff --git a/src/components/PageFrame.astro b/src/components/PageFrame.astro index 296b8422..c58ae5fb 100644 --- a/src/components/PageFrame.astro +++ b/src/components/PageFrame.astro @@ -132,6 +132,29 @@ const shouldRenderSidebar = hasSidebar && !is404Page; const activeClass = 'scrolled'; const homeClass = 'home-page'; let header; + const sidebarSelector = '#starlight__sidebar .sidebar-content a'; + + function normalizePath(pathname) { + if (!pathname || pathname === '/') return '/'; + return pathname.endsWith('/') ? pathname.slice(0, -1) : pathname; + } + + function syncSidebarCurrentLink() { + const links = document.querySelectorAll(sidebarSelector); + if (!links.length) return; + + const currentPath = normalizePath(window.location.pathname); + let matched = null; + + links.forEach((link) => { + if (!(link instanceof HTMLAnchorElement)) return; + link.removeAttribute('aria-current'); + const linkPath = normalizePath(new URL(link.href, window.location.origin).pathname); + if (linkPath === currentPath) matched = link; + }); + + if (matched) matched.setAttribute('aria-current', 'page'); + } function update() { if (!header) return; @@ -160,6 +183,7 @@ const shouldRenderSidebar = hasSidebar && !is404Page; // Non-home pages update(); + syncSidebarCurrentLink(); // Prevent duplicate listeners window.removeEventListener('scroll', update); diff --git a/src/components/Search.astro b/src/components/Search.astro index 2ec39b24..8d08325a 100644 --- a/src/components/Search.astro +++ b/src/components/Search.astro @@ -1,23 +1,115 @@ --- import "meilisearch-docsearch/css"; const apiKey = import.meta.env.PUBLIC_MEILISEARCH_KEY; +const searchHost = import.meta.env.PUBLIC_MEILISEARCH_HOST || 'https://search.testomat.io'; +const indexUid = import.meta.env.PUBLIC_MEILISEARCH_INDEX || 'codeceptjs'; ---
- diff --git a/src/content/docs/advanced.md b/src/content/docs/advanced.md index 55ac3a78..df771eac 100644 --- a/src/content/docs/advanced.md +++ b/src/content/docs/advanced.md @@ -1,8 +1,14 @@ ---- +๏ปฟ--- title: Advanced Usage --- -# Advanced Usage + +This page collects advanced runtime patterns. + +For command syntax and flags, use [Commands](/commands). +For retry policy and precedence, use [Retry Mechanisms](/retry). +For config structure and profiles, use [Configuration](/configuration). +For plugin extension internals, use [Extending](/hooks) and [Concepts](/internal-api). ## Data Driven Tests @@ -235,7 +241,7 @@ A timeout for a group of tests can be set on Feature level via options. Feature('flaky tests', { timeout: 30 }) ``` -### Timeout Confguration +### Timeout Configuration @@ -308,6 +314,7 @@ npx codeceptjs run --no-timeouts Helpers can be reconfigured per scenario or per feature. This might be useful when some tests should be executed with different settings than others. In order to reconfigure tests use `.config()` method of `Scenario` or `Feature`. +For base config structure and profile-level patterns, see [Configuration](/configuration). ```js Scenario('should be executed in firefox', ({ I }) => { diff --git a/src/content/docs/ai.md b/src/content/docs/ai.md index 54450d24..5d64d94f 100644 --- a/src/content/docs/ai.md +++ b/src/content/docs/ai.md @@ -1,8 +1,7 @@ ---- +๏ปฟ--- title: Testing with AI --- -# Testing with AI **CodeceptJS is the first open-source test automation framework with AI** features to improve the testing experience. CodeceptJS uses AI provider like OpenAI or Anthropic to auto-heal failing tests, assist in writing tests, and more... @@ -68,7 +67,7 @@ npx codeceptjs run --ai Below we list sample configuration for popular AI providers -#### OpenAI GPT +### OpenAI GPT Prerequisite: @@ -94,7 +93,7 @@ ai: { } ``` -#### Mixtral +### Mixtral Mixtral is opensource and can be used via Cloudflare, Google Cloud, Azure or installed locally. @@ -122,7 +121,7 @@ ai: { > Groq also provides access to other opensource models like llama or gemma -#### Anthropic Claude +### Anthropic Claude Prerequisite: @@ -149,7 +148,7 @@ ai: { } ``` -#### Azure OpenAI +### Azure OpenAI When your setup using Azure API key @@ -305,55 +304,10 @@ Please keep in mind that GPT can't react to page changes and operates with stati ## Self-Healing Tests -In large test suites, the cost of maintaining tests goes exponentially. That's why any effort that can improve the stability of tests pays itself. That's why CodeceptJS has concept of [heal recipes](./heal), functions that can be executed on a test failure. Those functions can try to revive the test and continue execution. When combined with AI, heal recipe can ask AI provider how to fix the test. It will provide error message, step being executed and HTML context of a page. Based on this information AI can suggest the code to be executed to fix the failing test. - - -AI healing can solve exactly one problem: if a locator of an element has changed, and an action can't be performed, **it matches a new locator, tries a command again, and continues executing a test**. For instance, if the "Sign in" button was renamed to "Login" or changed its class, it will detect a new locator of the button and will retry execution. - -> You can define your own [heal recipes](./heal) that won't use AI to revive failing tests. - -Heal actions work only on actions like `click`, `fillField`, etc, and will not work on assertions, waiters, grabbers, etc. Assertions cannot be guessed by AI, the same way as grabbers, as this may lead to unpredictable results. - -If Heal plugin successfully fixes the step, it will print a suggested change at the end of execution. Take it as actionable advice and use it to update the codebase. Heal plugin is supposed to be used on CI, and works automatically without human assistance. - - -To start, make sure [AI provider is connected](#set-up-ai-provider), and [heal recipes were created](/heal#how-to-start-healing) by running this command: - -``` -npx codeceptjs generate:heal -``` - -Heal recipes should be included into `codecept.conf.js` or `codecept.conf.ts` config file: - -```js - -require('./heal') - -exports.config = { - // ... your codeceptjs config -``` - -Then enable `heal` plugin: - -```js -plugins: { - heal: { - enabled: true - } -} -``` - -If you run tests in AI mode and a test fails, a request to AI provider will be sent - -``` -npx codeceptjs run --ai -``` - -![](./images/heal.png) - -When execution finishes, you will receive information on token usage and code suggestions proposed by AI. -By evaluating this information you will be able to check how effective AI can be for your case. +Self-healing is documented in [Self-Healing Tests](/heal). +Use this page as canonical for AI provider setup and copilot workflows. +Use `/heal` as canonical for healing concepts, recipe structure (`heal.addRecipe`), and `heal` plugin configuration. ## Arbitrary Prompts @@ -559,7 +513,7 @@ console.log(result); ``` Tune the options until you are satisfied with the results and use this as `html` config for `ai` section inside `codecept.conf` file. -It is also recommended to check the source of [removeNonInteractiveElements](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/html.js) and if needed propose improvements to it. +It is also recommended to check the source of [removeNonInteractiveElements](https://github.com/codeceptjs/CodeceptJS/blob/4.x/lib/html.js) and if needed propose improvements to it. For instance, if you use `data-qa` attributes to specify locators and you want to include them in HTML, use the following config: @@ -589,3 +543,4 @@ or if you run it in shell mode: ``` DEBUG="codeceptjs:ai" npx codeceptjs shell --ai ``` + diff --git a/src/content/docs/angular.md b/src/content/docs/angular.md deleted file mode 100644 index f68092aa..00000000 --- a/src/content/docs/angular.md +++ /dev/null @@ -1,324 +0,0 @@ ---- -title: Testing with Protractor ---- - -# Protractor Testing with CodeceptJS - -## Introduction - -CodeceptJS is an acceptance testing framework. In the diversified world of JavaScript testing libraries, it aims to create a unified high-level API for end-to-end testing, powered by a variety of backends. -CodeceptJS allows you to write a test and switch the execution driver via config: whether it's *webdriverio*, *puppeteer*, or *protractor* depends on you. -This way you aren't bound to a specific implementation, and your acceptance tests will work no matter what framework is running them. - -[Protractor](http://www.protractortest.org/#/) is an official tool for testing AngularJS applications. -CodeceptJS should not be considered as alternative to Protractor, but rather a testing framework that leverages this powerful library. - -![angular-protractor](./images/angular-protractor.png) - -There is no magic in testing of AngularJS application in CodeceptJS. -You just execute regular Protractor commands, packaged into a simple, high-level API. - -![todo-mvc](./images/todo.png) - -As an example, we will use the popular [TodoMVC application](http://todomvc.com/examples/angularjs/#/). -How would we test creating a new todo item using CodeceptJS? - -```js -Scenario('create todo item', ({ I }) => { - I.amOnPage('/'); - I.dontSeeElement('#todo-count'); - I.fillField({model: 'newTodo'}, 'Write a guide'); - I.pressKey('Enter'); - I.see('Write a guide', {repeater: "todo in todos"}); - I.see('1 item left', '#todo-count'); -}); -``` - -A similar test written using Protractor's native syntax (inherited from selenium-webdriver) would look like this: - -```js -it('should create todo item', (I) => { - browser.get("http://todomvc.com/examples/angularjs/#/"); - expect(element(by.css("#todo-count")).isPresent()).toBeFalsy(); - var inputField = element(by.model("newTodo")); - inputField.sendKeys("Write a guide"); - inputField.sendKeys(protractor.Key.ENTER); - var todos = element.all(by.repeater("todo in todos")); - expect(todos.last().getText()).toEqual("Write a guide")); - element(by.css("#todo-count")).getText()).toContain('1 items left'); -}); -``` - -Compared to the API proposed by CodeceptJS, the Protractor code looks more complicated. -Even more important, it's harder to read and follow the logic of the Protractor test. -Readability is a crucial part of acceptance testing. -Tests should be easy to modify when there are changes in the specification or design. -If the test is written in Protractor, it would likely require someone familiar with Protractor to make the change, whereas CodeceptJS allows anyone to understand and modify the test. -CodeceptJS provides scenario-driven approach, so a test is just a step-by-step representation of real user actions. -This means you can easily read and understand the steps in a test scenario, and edit the steps when the test needs to be changed. - -In this way, CodeceptJS is similar to Cucumber. If you run a test with `--steps` option you will see this output: - -```bash -TodoMvc -- - create todo item - - I am on page "/" - - I dont see element "#todo-count" - - I fill field {"model":"newTodo"}, "Write a guide" - - I press key "Enter" - - I see "Write a guide", {"repeater":"todo in todos"} - - I see "1 item left", "#todo-count" - OK in 968ms -``` - -Unlike Cucumber, CodeceptJS is not about writing test scenarios to satisfy business rules or requirements. -Instead, its **goal is to provide standard action steps you can use for testing applications**. -Although it can't cover 100% of use cases, CodeceptJS aims for 90%. For the remainder, you can write your own steps inside a [custom Helper](/custom-helpers) using Protractor's API. - -### Setting up CodeceptJS with Protractor - -To start using CodeceptJS you will need to install it via NPM and initialize it in a directory with tests. - -```bash -npm install codeceptjs --save -npx codeceptjs init -``` - -You will be asked questions about the initial configuration, make sure you select the Protractor helper. -If your project didn't already have the Protractor library, it **will be installed** as part of this process. -Please agree to extend steps, and use `http://todomvc.com/examples/angularjs/` as the url for Protractor helper. - -For TodoMVC application, you will have following config created in the `codecept.conf.js` file: - -```js -exports.config = { tests: './*_test.js', - timeout: 10000, - output: './output', - helpers: - { Protractor: - { url: 'http://todomvc.com/examples/angularjs/', - driver: 'hosted', - browser: 'chrome', - rootElement: 'body' } }, - include: { I: './steps_file.js' }, - bootstrap: false, - mocha: {}, - name: 'todoangular' -} -``` - -Your first test can be generated with the `gt` command: - -```bash -npx codeceptjs gt -``` - -After that, you can start writing your first CodeceptJS/Angular tests. -Please refer to the [Protractor helper](/helpers/protractor) documentation for a list of all available actions. -You can also run the `list` command to see methods of I: - -```bash -npx codeceptjs list -``` - -## Starting Selenium Server - -Protractor requires Selenium Server to be started and running. To start and stop Selenium automatically install `@wdio/selenium-standalone-service`. - -``` -npm i @wdio/selenium-standalone-service --save -``` - -Enable it in the `codecept.conf.js` file, inside the plugins section: - -```js -exports.config = { - // ... - // inside codecept.conf.js - plugins: { - wdio: { - enabled: true, - services: ['selenium-standalone'] - } - } -} -``` - -## Testing non-Angular Applications - -Protractor can also be used to test applications built without AngularJS. In this case, you need to disable the angular synchronization feature inside the config: - -```js -helpers: { - Protractor: { - url: "http://todomvc.com/examples/angularjs/", - driver: "hosted", - browser: "firefox", - angular: false - } -} -``` - -## Writing Your First Test - -Your test scenario should always use the `I` object to execute commands. -This is important, as all methods of `I` are running in the global promise chain. This way, CodeceptJS makes sure everything is executed in right order. -To start with opening a webpage, use the `amOnPage` command for. Since we already specified the full URL to the TodoMVC app, we can pass the relative path for our url, instead of the absolute url: - -```js -Feature('Todo MVC'); - -Scenario('create todo item', ({ I }) => { - I.amOnPage('/'); -}); -``` - -All scenarios should describe actions on the site, with assertions at the end. In CodeceptJS, assertion commands have the `see` or `dontSee` prefix: - -```js -Feature('Todo MVC'); - -Scenario('create todo item', ({ I }) => { - I.amOnPage('/'); - I.dontSeeElement('#todo-count'); -}); -``` - -A test can be executed with the `run` command, we recommend using the `--steps` option to print out the step-by-step execution: - -```sh -npx codeceptjs run --steps -``` - -``` -Test root is assumed to be /home/davert/demos/todoangular -Using the selenium server at http://localhost:4444/wd/hub - -TodoMvc -- - create todo item - - I am on page "/" - - I dont see element "#todo-count" -``` - -## Running Several Scenarios - -By now, you should have a test similar to the one shown in the beginning of this guide. We probably want to have multiple tests though, like testing the editing of todo items, checking todo items, etc. - -Let's prepare our test to contain multiple scenarios. All of our test scenarios will need to to start with with the main page of application open, so `amOnPage` can be moved into the `Before` hook: -Our scenarios will also probably deal with created todo items, so we can move the logic of creating a new todo into a function. - -```js -Feature('TodoMvc'); - -Before(({ I }) => { - I.amOnPage('/'); -}); - -const createTodo = function (I, name) { - I.fillField({model: 'newTodo'}, name); - I.pressKey('Enter'); -} - -Scenario('create todo item', ({ I }) => { - I.dontSeeElement('#todo-count'); - createTodo(I, 'Write a guide'); - I.see('Write a guide', {repeater: "todo in todos"}); - I.see('1 item left', '#todo-count'); -}); -``` - -and now we can add even more tests! - -```js -Scenario('edit todo', ({ I }) => { - createTodo(I, 'write a review'); - I.see('write a review', {repeater: "todo in todos"}); - I.doubleClick('write a review'); - I.pressKey(['Control', 'a']); - I.pressKey('write old review'); - I.pressKey('Enter'); - I.see('write old review', {repeater: "todo in todos"}); -}); - -Scenario('check todo item', ({ I }) => { - createTodo(I, 'my new item'); - I.see('1 item left', '#todo-count'); - I.checkOption({model: 'todo.completed'}); - I.see('0 items left', '#todo-count'); -}); -``` - -> This example is [available on GitHub](https://github.com/DavertMik/codeceptjs-angular-todomvc). - - -## Locators - -You may have noticed that CodeceptJS doesn't use `by.*` locators which are common in Protractor or Selenium Webdriver. -Instead, most methods expect you to pass valid CSS selectors or XPath. If you don't want CodeceptJS to guess the locator type, then you can specify the type using *strict locators*. This is the CodeceptJS version of `by`, so you can also reuse your angular specific locators (like models, repeaters, bindings, etc): - -```sh -{css: 'button'} -{repeater: "todo in todos"} -{binding: 'latest'} -``` - -When dealing with clicks, we can specify a text value. CodeceptJS will use that value to search the web page for a valid clickable element containing our specified text. -This enables us to search for links and buttons by their text. - -The same is true for form fields: they can be searched by field name, label, and so on. - -Using smart locators makes tests easier to write, however searching an element by text is slower than searching via CSS|XPath, and is much slower than using strict locators. - -## Refactoring - -In the previous examples, we moved actions into the `createTodo` function. Is there a more elegant way of refactoring? -Can we instead write a function like `I.createTodo()` which we can reuse? In fact, we can do so by editing the `steps_file.js` file created by the init command. - -```js -// in this file you can append custom step methods to 'I' object - -module.exports = function() { - return actor({ - createTodo: function(title) { - this.fillField({model: 'newTodo'}, title); - this.pressKey('Enter'); - } - }); -} -``` - -That's it, our method is now available to use as `I.createTodo(title)`: - -```js -Scenario('create todo item', ({ I }) => { - I.dontSeeElement('#todo-count'); - I.createTodo('Write a guide'); - I.see('Write a guide', {repeater: "todo in todos"}); - I.see('1 item left', '#todo-count'); -}); -``` - -To learn more about refactoring options in CodeceptJS read [PageObjects guide](/pageobjects/). - - -## Extending - -What if CodeceptJS doesn't provide some specific Protractor functionality you need? If you don't know how to do something with CodeceptJS, you can simply revert back to using Protractor syntax! - -Create a custom helper, define methods for it, and use it inside the I object. Your Helper can access `browser` from Protractor -by accessing the Protractor helper: - -```js -let browser = this.helpers['Protractor'].browser; -``` - -or use global `element` and `by` variables to locate elements: - -```js -element.all(by.repeater('result in memory')); -``` - -This is the recommended way to implement all custom logic using low-level Protractor syntax in order to reuse it inside of test scenarios. -For more information, see an [example of such a helper](/custom-helpers#helper-examples). - - diff --git a/src/content/docs/api.md b/src/content/docs/api.md index 5aff3829..f6b8a5af 100644 --- a/src/content/docs/api.md +++ b/src/content/docs/api.md @@ -2,10 +2,11 @@ title: API Testing --- -## API Testing - CodeceptJS provides a way to write tests in declarative manner for REST and GraphQL APIs. +> Use this page when your goal is to **test API behavior** (status, payload, schema, assertions). +> If your goal is to **prepare test data** for UI/e2e scenarios, use [Data Management](/data). + Take a look: ```js @@ -31,7 +32,7 @@ In this code we checked API request for: These are the things you should generally test your APIs for. -> ๐Ÿค“ It is recommended to check only invariant parts of responses. Check required fields and only values you control. For instance, it is not recommended to check ID fields or date fields, as they can change frequently. +> Note: It is recommended to check only invariant parts of responses. Check required fields and only values you control. For instance, it is not recommended to check ID fields or date fields, as they can change frequently. ## Installation @@ -83,7 +84,7 @@ They were used to perform API requests for browser tests. As so, they lack asser [`JSONResponse`](/helpers/json-response) helper adds response assertions. -> ๐Ÿ’ก In CodeceptJS assertions start with the `see` prefix. Learn more in the [JSONResponse helper reference](/helpers/json-response). +> Note: In CodeceptJS assertions start with the `see` prefix. Learn more in the [JSONResponse helper reference](/helpers/json-response). Generate TypeScript definitions to get auto-completions for JSONResponse: @@ -142,12 +143,12 @@ exports.config = { REST helper can send GET/POST/PATCH/etc requests to REST API endpoint: -* [`I.sendGetRequest()`](/helpers/rest#sendGetRequest) -* [`I.sendPostRequest()`](/helpers/rest#sendPostRequest) -* [`I.sendPutRequest()`](/helpers/rest#sendPutRequest) -* [`I.sendPatchRequest()`](/helpers/rest#sendPatchRequest) -* [`I.sendDeleteRequest()`](/helpers/rest#sendDeleteRequest) -* [`I.sendDeleteRequestWithPayload()`](/helpers/rest#sendDeleteRequestWithPayload) +* [`I.sendGetRequest()`](/helpers/rest#sendgetrequest) +* [`I.sendPostRequest()`](/helpers/rest#sendpostrequest) +* [`I.sendPutRequest()`](/helpers/rest#sendputrequest) +* [`I.sendPatchRequest()`](/helpers/rest#sendpatchrequest) +* [`I.sendDeleteRequest()`](/helpers/rest#senddeleterequest) +* [`I.sendDeleteRequestWithPayload()`](/helpers/rest#senddeleterequestwithpayload) * ... Authentication headers can be set in [helper configuration](/helpers/rest#configuration) or per test with headers or special methods like `I.amBearerAuthenticated`. @@ -208,8 +209,8 @@ Scenario('get user by query', ({ I }) => { GraphQL helper has two methods available: -* [`I.sendQuery()`](/helpers/graph-ql#sendQuery) -* [`I.sendMutation()`](/helpers/graph-ql#sendMutation) +* [`I.sendQuery()`](/helpers/graph-ql#sendquery) +* [`I.sendMutation()`](/helpers/graph-ql#sendmutation) ## Assertions @@ -256,14 +257,14 @@ I.seeResponseCodeIsServerError(); ### Structure -The most basic thing to check in a response is the existence of keys in a JSON object. Use [`I.seeResponseContainsKeys()`](/helpers/json-response#seeResponseContainsKeys) method for it: +The most basic thing to check in a response is the existence of keys in a JSON object. Use [`I.seeResponseContainsKeys()`](/helpers/json-response#seeresponsecontainskeys) method for it: ```js // response is { "name": "joe", "email": "joe@joe.com" } I.seeResponseContainsKeys(['name', 'email']); ``` -> โ„น๏ธ If response is an array, it checks that every element in the array has the provided keys. +> Note: If response is an array, it checks that every element in the array has the provided keys. However, this is a very naive approach. It won't work for arrays or nested objects. To check complex JSON structures `JSONResponse` helper uses [`joi`](https://joi.dev) library. @@ -298,7 +299,7 @@ I.seeResponseContainsJson({ }) ``` -> โ„น๏ธ If response is an array, it checks that at least one element in the array matches JSON. +> Note: If response is an array, it checks that at least one element in the array matches JSON. To perform arbitrary assertions on a response object use `seeResponseValidByCallback`. It allows you to do any kind of assertions by using `expect` from [`chai`](https://www.chaijs.com) library. @@ -321,3 +322,5 @@ makeSomeCustomAssertion() { const response = this.helpers.JSONResponse.response; } ``` + +> For factory-based data setup and automatic cleanup (`have`, `haveMultiple`, `mutateData`, `mutateMultiple`), see [Data Management](/data). diff --git a/src/content/docs/basics.md b/src/content/docs/basics.md index 61d54f1c..6401c16c 100644 --- a/src/content/docs/basics.md +++ b/src/content/docs/basics.md @@ -38,7 +38,6 @@ Refer to following guides to more information on: * [โ–ถ Playwright](/playwright) * [โ–ถ WebDriver](/webdriver) * [โ–ถ Puppeteer](/puppeteer) -* [โ–ถ TestCafe](/testcafe) > โ„น Depending on a helper selected a list of available actions may change. @@ -293,7 +292,7 @@ Tests are written in a synchronous way. This improves the readability and mainta While writing tests you should not think about promises, and instead should focus on the test scenario. However, behind the scenes **all actions are wrapped in promises**, inside of the `I` object. -[Global promise](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/recorder.js) chain is initialized before each test and all `I.*` calls will be appended to it, as well as setup and teardown. +[Global promise](https://github.com/codeceptjs/CodeceptJS/blob/4.x/lib/recorder.js) chain is initialized before each test and all `I.*` calls will be appended to it, as well as setup and teardown. > ๐Ÿ“บ [Learn how CodeceptJS](https://www.youtube.com/watch?v=MDLLpHAwy_s) works with promises by watching video on YouTube @@ -434,7 +433,7 @@ const { setHeadlessWhen, setWindowSize } = require('@codeceptjs/configure'); // run headless when CI environment variable set setHeadlessWhen(process.env.CI); -// set window size for any helper: Puppeteer, WebDriver, TestCafe +// set window size for any helper: Puppeteer, WebDriver, Playwright setWindowSize(1600, 1200); exports.config = { diff --git a/src/content/docs/bdd.md b/src/content/docs/bdd.md index 3ddeb791..d00cc693 100644 --- a/src/content/docs/bdd.md +++ b/src/content/docs/bdd.md @@ -1,8 +1,7 @@ ---- +๏ปฟ--- title: Behavior Driven Development --- -# Behavior Driven Development Behavior Driven Development (BDD) is a popular software development methodology. BDD is considered an extension of TDD, and is greatly inspired by [Agile](https://agilemanifesto.org/) practices. The primary reason to choose BDD as your development process is to break down communication barriers between business and technical teams. BDD encourages the use of automated testing to verify all documented features of a project from the very beginning. This is why it is common to talk about BDD in the context of test frameworks (like CodeceptJS). The BDD approach, however, is about much more than testing - it is a common language for all team members to use during the development process. @@ -160,6 +159,7 @@ Given(/I have product with \$(\d+) price/, (price) => { I.amOnPage('/products'); productPage.create({ price }); I.click('Add to cart'); + I.click({ aria: 'Add to cart' }); }); // or a simple string diff --git a/src/content/docs/best.md b/src/content/docs/best.md index 55224829..975b3fcb 100644 --- a/src/content/docs/best.md +++ b/src/content/docs/best.md @@ -1,8 +1,7 @@ ---- +๏ปฟ--- title: Best Practices --- -# Best Practices ## Focus on Readability @@ -16,6 +15,8 @@ Take a look into the next example: I.click({css: 'nav.user .user-login'}); // can be better I.click('Login', 'nav.user'); +// or by ARIA label +I.click({ aria: 'Login' }); ``` If we replace raw CSS selector with a button title we can improve readability of such test. @@ -37,7 +38,7 @@ To write simpler and effective tests we encourage to use short cuts. Make test be focused on one feature and try to simplify everything that is not related directly to test. * If data is required for a test, try to create that data via API. See how to do it in [Data Management](/data) chapter. -* If user login is required, use [autoLogin plugin](/plugins#autoLogin) instead of putting login steps inside a test. +* If user login is required, use [auth plugin](/plugins#auth) instead of putting login steps inside a test. * Break a long test into few. Long test can be fragile and complicated to follow and update. * Use [custom steps and page objects](/pageobjects) to hide steps which are not relevant to current test. @@ -45,7 +46,7 @@ Make test as simple as: ```js Scenario('editing a metric', async ({ I, loginAs, metricPage }) => { - // login via autoLogin + // login via auth plugin loginAs('admin'); // create data with ApiDataFactory const metric = await I.have('metric', { type: 'memory', duration: 'day' }) @@ -61,94 +62,36 @@ Scenario('editing a metric', async ({ I, loginAs, metricPage }) => { ``` ## Locators -* If you don't use multi-lingual website or you don't update texts often it is OK to click on links by their texts or match fields by their placeholders. -* If you don't want to rely on guessing locators, specify them manually with `{ css: 'button' }` or `{ xpath: '//button' }`. We call them strict locators. Those locators will be faster but less readable. -* Even better if you have a convention on active elements with special attributes like `data-test` or `data-qa`. Use `customLocator` plugin to easily add them to tests. -* Keep tests readable which will make them maintainable. - -## Page Objects - -When a project is growing and more and more tests are required, it's time to think about reusing test code across the tests. Some common actions should be moved from tests to other files so to be accessible from different tests. - -Here is a recommended strategy what to store where: - -* Move site-wide actions into an **Actor** file (`custom_steps.js` file). Such actions like `login`, using site-wide common controls, like drop-downs, rich text editors, calendars. -* Move page-based actions and selectors into **Page Object**. All activities made on that page can go into methods of page object. If you test Single Page Application a PageObject should represent a screen of your application. -* When site-wide widgets are used, interactions with them should be placed in **Page Fragments**. This should be applied to global navigation, modals, widgets. -* A custom action that requires some low-level driver access, should be placed into a **Helper**. For instance, database connections, complex mouse actions, email testing, filesystem, services access. - -> [Learn more](/pageobjects) about different refactoring options - -However, it's recommended to not overengineer and keep tests simple. If a test code doesn't require reusage at this point it should not be transformed to use page objects. - +Keep this section as a checklist and use [Locators](/locators) as a full reference: -* use page objects to store common actions -* don't make page objects for every page! Only for pages shared across different tests and suites. -* use classes for page objects, this allows inheritace. Export instance of that classes. -* if a page object is focused around a form with multiple fields in it, use a flexible set of arguments in it: - -```js -class CheckoutForm { - - fillBillingInformation(data = {}) { - // take data in a flexible format - // iterate over fields to fill them all - for (let key of Object.keys(data)) { - I.fillField(key, data[key]); // like this one - } - } - -} -module.exports = new CheckoutForm(); -module.exports.CheckoutForm = CheckoutForm; // for inheritance -``` +* Prefer readable semantic locators first (text, labels, ARIA). +* Use strict locators (`{ css: '...' }`, `{ xpath: '...' }`) when you need precision and speed. +* For accessibility-aware UIs, prefer ARIA locators, e.g. `{ aria: 'Submit' }`. +* If your app uses stable test attributes (`data-test`, `data-qa`), configure [customLocator plugin](/plugins#customlocator). +* Keep locator strategy consistent across the project. -* for components that are repeated accross a website (widgets) but don't belong to any page, use component objects. They are the same as page objects but focused only aroung one element: - -```js -class DropDownComponent { - - selectFirstItem(locator) { - I.click(locator); - I.click('#dropdown-items li'); - } - - selectItemByName(locator, name) { - I.click(locator); - I.click(locate('li').withText(name), '#dropdown-items'); - } -} -``` -* another good example is datepicker component: -```js -const { I } = inject(); - -/** - * Calendar works - */ -class DatePicker { +## Page Objects - selectToday(locator) { - I.click(locator); - I.click('.currentDate', '.date-picker'); - } +When a project grows, move reusable actions out of scenarios. +This page keeps only the rules of thumb. Full patterns and examples are in [Page Objects](/pageobjects). - selectInNextMonth(locator, date = '15') { - I.click(locator); - I.click('show next month', '.date-picker') - I.click(date, '.date-picker') - } +Recommended split: -} +* Move site-wide actions into Actor (`custom_steps.*`), e.g. login or common widgets. +* Move page-level actions and selectors into page objects. +* Move reusable widgets (modals, nav, dropdowns) into page fragments/components. +* Keep low-level driver/service operations in custom helpers. +Practical rules: -module.exports = new DatePicker(); -module.exports.DatePicker = DatePicker; // for inheritance -``` +* Use page objects to store common actions only. +* Do not create page objects for every page by default. +* Prefer classes for page objects/fragments when inheritance is needed. +* Avoid overengineering: if a flow is used once, keep it in the test. ## Configuration -* create multiple config files for different setups/enrionments: +* create multiple config files for different setups/environments: * `codecept.conf.js` - default one * `codecept.ci.conf.js` - for CI * `codecept.windows.conf.js` - for Windows, etc @@ -180,7 +123,6 @@ include them like this: ``` * move long helpers configuration into `config/plugins.js` and export them -* move long configuration into `config/plugins.js` and export them * inside config files import the exact helpers or plugins needed for this setup & environment * to pass in data from config to a test use a container: diff --git a/src/content/docs/blog/my-first-blog-post.md b/src/content/docs/blog/my-first-blog-post.md index 2ebd21bd..95e4af3a 100644 --- a/src/content/docs/blog/my-first-blog-post.md +++ b/src/content/docs/blog/my-first-blog-post.md @@ -1,8 +1,21 @@ --- -title: My first blog post -date: 2023-07-24 +title: Developer Updates Are Coming Soon +date: 2026-03-12 --- -## Hello +Thanks for checking out the new blog section. -Hello world! \ No newline at end of file +We are preparing regular updates from the CodeceptJS team: + +- Release notes and migration tips +- New helpers and plugin improvements +- Real-world testing patterns from the community + +## Try CodeceptJS Right Now + +While we prepare new posts, you can start with: + +- [Quickstart guide](/quickstart/) +- [CodeceptJS on GitHub](https://github.com/codeceptjs/CodeceptJS) + +More posts are coming very soon. diff --git a/src/content/docs/wiki/books-&-posts.md b/src/content/docs/books.md similarity index 90% rename from src/content/docs/wiki/books-&-posts.md rename to src/content/docs/books.md index 34c86e13..a05aac36 100644 --- a/src/content/docs/wiki/books-&-posts.md +++ b/src/content/docs/books.md @@ -2,6 +2,7 @@ title: Books & Posts --- +> Add your own books or posts by opening a PR to this page. ### [Practical End 2 End Testing with CodeceptJS](https://leanpub.com/codeceptjs/) A book by **Paul Vincent Beigang** @@ -16,7 +17,7 @@ A book by **Paul Vincent Beigang** 1. Run Your First CodeceptJS Test Locally 1. Run Test on BrowserStack Against with the Safari Browser 1. How to Debug & Fix a Failing E2E Test -1. Run a CodeceptJS Test in GitLabยดs Continuous Integration (CI) Environment +1. Run a CodeceptJS Test in GitLab's Continuous Integration (CI) Environment 1. Delicious Test Reports With Allure ### Posts @@ -28,4 +29,4 @@ A list of good educational posts about CodeceptJS * [Customizing CodeceptJS Skeleton](https://medium.com/@successivetech/codeceptjs-skeleton-9ba86d3b45ec) * [Running End to End tests as Google Cloud Functions](https://hackernoon.com/running-end-to-end-tests-as-google-cloud-functions-f5e34ffc3984) * [End-To-End Testing With CodeceptJS](https://www.monterail.com/blog/end-to-end-testing-with-codeceptjs) by Piotr Michalski -* [Getting started with CodeceptJS and Selenium WebDriver](https://medium.com/@garrettvorce/getting-started-with-selenium-and-codeceptjs-c0698e8df677) \ No newline at end of file +* [Getting started with CodeceptJS and Selenium WebDriver](https://medium.com/@garrettvorce/getting-started-with-selenium-and-codeceptjs-c0698e8df677) diff --git a/src/content/docs/bootstrap.md b/src/content/docs/bootstrap.md index 6fc89dc8..5797bfec 100644 --- a/src/content/docs/bootstrap.md +++ b/src/content/docs/bootstrap.md @@ -1,18 +1,17 @@ ---- +๏ปฟ--- title: Bootstrap --- -# Bootstrap In case you need to execute arbitrary code before or after the tests, you can use the `bootstrap` and `teardown` config. Use it to start and stop a webserver, Selenium, etc. -When using the [parallel execution](/parallel) mode, there are two additional hooks available; `bootstrapAll` and `teardownAll`. See [bootstrapAll & teardownAll](#bootstrapall-teardownall) for more information. +When using the [parallel execution](/parallel) mode, there are two additional hooks available; `bootstrapAll` and `teardownAll`. See [bootstrapAll & teardownAll](#bootstrapall--teardownall) for more information. > Note: In CodeceptJS 2, `bootstrap` could be set as a function with `done` parameter. This async pattern was replaced with native async functions in CodeceptJS 3. -### Example: Bootstrap & Teardown +## Example: Bootstrap & Teardown If you are using JavaScript-style config `codecept.conf.js`, bootstrap and teardown functions can be placed inside of it: diff --git a/src/content/docs/changelog.md b/src/content/docs/changelog.md new file mode 100644 index 00000000..a706daf7 --- /dev/null +++ b/src/content/docs/changelog.md @@ -0,0 +1,678 @@ +๏ปฟ--- +title: Releases +slug: changelog +--- + +## 3.7.4 + +ะฒัœยคะฟั‘ะ Thanks all to those who contributed to make this release! ะฒัœยคะฟั‘ะ + +ั€ัŸโ€บยฉะฟั‘ะ _Features_ + +- **Test Suite Shuffling**: Randomize test execution order to discover test dependencies and improve test isolation ([#5051](https://github.com/codeceptjs/CodeceptJS/issues/5051)) - by **[NivYarmus](https://github.com/NivYarmus)** + + ```bash + # Shuffle tests to find order-dependent failures using lodash.shuffle algorithm + npx codeceptjs run --shuffle + + # Combined with grep and other options + npx codeceptjs run --shuffle --grep "@smoke" --steps + ``` + +- **Enhanced Interactive Debugging**: Better logging for `I.grab*` methods in live interactive mode for clearer debugging output ([#4986](https://github.com/codeceptjs/CodeceptJS/issues/4986)) - by **[owenizedd](https://github.com/owenizedd)** + + ```js + // Interactive pause() now shows detailed grab results with JSON formatting + I.amOnPage('/checkout') + pause() // Interactive shell started + > I.grabTextFrom('.price') + Result $res= "Grabbed text: $29.99" // Pretty-printed JSON output + > I.grabValueFrom('input[name="email"]') + {"value":"user@example.com"} // Structured JSON response + ``` + + ั€ัŸั’โ€บ _Bug Fixes_ + +- **Playwright Session Traces**: Fixed trace file naming convention and improved error handling for multi-session test scenarios ([#5073](https://github.com/codeceptjs/CodeceptJS/issues/5073)) - by **[julien-ft-64](https://github.com/julien-ft-64)** **[kobenguyent](https://github.com/kobenguyent)** + + ```js + // Example outputs: + // - a1b2c3d4-e5f6_checkout_login_test.failed.zip + // - b2c3d4e5-f6g7_admin_dashboard_test.failed.zip + ``` + + _Trace files use UUID prefixes with `sessionName_testTitle.status.zip` format_ + +- **Worker Data Injection**: Resolved proxy object serialization preventing data sharing between parallel test workers ([#5072](https://github.com/codeceptjs/CodeceptJS/issues/5072)) - by **[kobenguyent](https://github.com/kobenguyent)** + + ```js + // Fixed: Complex objects can now be properly shared and injected between workers + // Bootstrap data sharing in codecept.conf.js: + exports.config = { + bootstrap() { + share({ + userData: { id: 123, preferences: { theme: 'dark' } }, + apiConfig: { baseUrl: 'https://api.test.com', timeout: 5000 }, + }) + }, + } + + // In tests across different workers: + const testData = inject() + console.log(testData.userData.preferences.theme) // 'dark' - deep nesting works + console.log(Object.keys(testData)) // ['userData', 'apiConfig'] - key enumeration works + + // Dynamic sharing during test execution: + share({ newData: 'shared across workers' }) + ``` + +- **Hook Exit Codes**: Fixed improper exit codes when test hooks fail, ensuring CI/CD pipelines properly detect failures ([#5058](https://github.com/codeceptjs/CodeceptJS/issues/5058)) - by **[kobenguyent](https://github.com/kobenguyent)** + + ```bash + # Before: Exit code 0 even when beforeEach/afterEach failed + # After: Exit code 1 when any hook fails, properly failing CI builds + ``` + +- **TypeScript Effects Support**: Added complete TypeScript definitions for effects functionality ([#5027](https://github.com/codeceptjs/CodeceptJS/issues/5027)) - by **[kobenguyent](https://github.com/kobenguyent)** + + ```typescript + // Import effects with full TypeScript type definitions + import { tryTo, retryTo, within } from 'codeceptjs/effects' + + // tryTo returns Promise for conditional actions + const success: boolean = await tryTo(async () => { + await I.see('Cookie banner') + await I.click('Accept') + }) + + // retryTo with typed parameters for reliability + await retryTo(() => { + I.click('Submit') + I.see('Success') + }, 3) // retry up to 3 times + ``` + + _Note: Replaces deprecated global plugins - import from 'codeceptjs/effects' module_ + +- **Mochawesome Screenshot Uniqueness**: Fixed screenshot naming to prevent test failures from being overwritten when multiple tests run at the same time ([#4959](https://github.com/codeceptjs/CodeceptJS/issues/4959)) - by **[Lando1n](https://github.com/Lando1n)** + + ```js + // Problem: When tests run in parallel, screenshots had identical names + // This caused later test screenshots to overwrite earlier ones + + // Before: All failed tests saved as "screenshot.png" + // Result: Only the last failure screenshot was kept + + // After: Each screenshot gets a unique name with timestamp + // Examples: + // - "login_test_1645123456.failed.png" + // - "checkout_test_1645123789.failed.png" + // - "profile_test_1645124012.failed.png" + + // Configuration in codecept.conf.js: + helpers: { + Mochawesome: { + uniqueScreenshotNames: true // Enable unique naming + } + } + ``` + + _Ensures every failed test keeps its own screenshot for easier debugging_ + +ั€ัŸโ€œโ€“ _Documentation_ + +- Fixed Docker build issues and improved container deployment process ([#4980](https://github.com/codeceptjs/CodeceptJS/issues/4980)) - by **[thomashohn](https://github.com/thomashohn)** +- Updated dependency versions to maintain security and compatibility ([#4957](https://github.com/codeceptjs/CodeceptJS/issues/4957), [#4950](https://github.com/codeceptjs/CodeceptJS/issues/4950), [#4943](https://github.com/codeceptjs/CodeceptJS/issues/4943)) - by **[thomashohn](https://github.com/thomashohn)** +- Fixed automatic documentation generation system for custom plugins ([#4973](https://github.com/codeceptjs/CodeceptJS/issues/4973)) - by **[Lando1n](https://github.com/Lando1n)** + +## 3.7.3 + +ะฒัœยคะฟั‘ะ Thanks all to those who contributed to make this release! ะฒัœยคะฟั‘ะ + +ั€ัŸโ€บยฉะฟั‘ะ _Features_ + +- feat(cli): improve info command to return installed browsers ([#4890](https://github.com/codeceptjs/CodeceptJS/issues/4890)) - by **[kobenguyent](https://github.com/kobenguyent)** + +``` +ะฒั›ัš helloworld npx codeceptjs info +Environment information: + +codeceptVersion: "3.7.2" +nodeInfo: 18.19.0 +osInfo: macOS 14.4 +cpuInfo: (8) x64 Apple M1 Pro +osBrowsers: "chrome: 133.0.6943.143, edge: 133.0.3065.92, firefox: not installed, safari: 17.4" +playwrightBrowsers: "chromium: 133.0.6943.16, firefox: 134.0, webkit: 18.2" +helpers: { +"Playwright": { +"url": "http://localhost", +... +``` + +ั€ัŸั’โ€บ _Bug Fixes_ + +- fix: resolving path inconsistency in container.js and appium.js ([#4866](https://github.com/codeceptjs/CodeceptJS/issues/4866)) - by **[mjalav](https://github.com/mjalav)** +- fix: broken screenshot links in mochawesome reports ([#4889](https://github.com/codeceptjs/CodeceptJS/issues/4889)) - by **[kobenguyent](https://github.com/kobenguyent)** +- some internal fixes to make UTs more stable by **[thomashohn](https://github.com/thomashohn)** +- dependencies upgrades by **[thomashohn](https://github.com/thomashohn)** + +## 3.7.2 + +ะฒัœยคะฟั‘ะ Thanks all to those who contributed to make this release! ะฒัœยคะฟั‘ะ + +ั€ัŸโ€บยฉะฟั‘ะ _Features_ + +- feat(playwright): Clear cookie by name ([#4693](https://github.com/codeceptjs/CodeceptJS/issues/4693)) - by **[ngraf](https://github.com/ngraf)** + +ั€ัŸั’โ€บ _Bug Fixes_ + +- fix(stepByStepReport): no records html is generated when running with run-workers ([#4638](https://github.com/codeceptjs/CodeceptJS/issues/4638)) +- fix(webdriver): bidi error in log with webdriver ([#4850](https://github.com/codeceptjs/CodeceptJS/issues/4850)) +- fix(types): TS types of methods (Feature|Scenario)Config.config ([#4851](https://github.com/codeceptjs/CodeceptJS/issues/4851)) +- fix: redundant popup log ([#4830](https://github.com/codeceptjs/CodeceptJS/issues/4830)) +- fix(webdriver): grab browser logs using bidi protocol ([#4754](https://github.com/codeceptjs/CodeceptJS/issues/4754)) +- fix(webdriver): screenshots for sessions ([#4748](https://github.com/codeceptjs/CodeceptJS/issues/4748)) + +ั€ัŸโ€œโ€“ _Documentation_ + +- fix(docs): mask sensitive data ([#4636](https://github.com/codeceptjs/CodeceptJS/issues/4636)) - by **[gkushang](https://github.com/gkushang)** + +## 3.7.1 + +- Fixed `reading charAt` error in `asyncWrapper.js` + +## 3.7.0 + +This release introduces major new features and internal refactoring. It is an important step toward the 4.0 release planned soon, which will remove all deprecations introduced in 3.7. + +ั€ัŸโ€บยฉะฟั‘ะ _Features_ + +### ั€ัŸโ€า **Native Element Functions** + +A new [Els API](/els) for direct element interactions has been introduced. This API provides low-level element manipulation functions for more granular control over element interactions and assertions: + +- `element()` - perform custom operations on first matching element +- `eachElement()` - iterate and perform operations on each matching element +- `expectElement()` - assert condition on first matching element +- `expectAnyElement()` - assert condition matches at least one element +- `expectAllElements()` - assert condition matches all elements + +Example using all element functions: + +```js +const { element, eachElement, expectElement, expectAnyElement, expectAllElements } = require('codeceptjs/els') + +// ... + +Scenario('element functions demo', async ({ I }) => { + // Get attribute of first button + const attr = await element('.button', async el => await el.getAttribute('data-test')) + + // Log text of each list item + await eachElement('.list-item', async (el, idx) => { + console.log(`Item ${idx}: ${await el.getText()}`) + }) + + // Assert first submit button is enabled + await expectElement('.submit', async el => await el.isEnabled()) + + // Assert at least one product is in stock + await expectAnyElement('.product', async el => { + return (await el.getAttribute('data-status')) === 'in-stock' + }) + + // Assert all required fields have required attribute + await expectAllElements('.required', async el => { + return (await el.getAttribute('required')) !== null + }) +}) +``` + +[Els](/els) functions expose the native API of Playwright, WebDriver, and Puppeteer helpers. The actual `el` API will differ depending on which helper is used, which affects test code interoperability. + +### ั€ัŸโ€ยฎ **Effects introduced** + +[Effects](/effects) is a new concept that encompasses all functions that can modify scenario flow. These functions are now part of a single module. Previously, they were used via plugins like `tryTo` and `retryTo`. Now, it is recommended to import them directly: + +```js +const { tryTo, retryTo } = require('codeceptjs/effects') + +Scenario(..., ({ I }) => { + I.amOnPage('/') + // tryTo returns boolean if code in function fails + // use it to execute actions that may fail but not affect the test flow + // for instance, for accepting cookie banners + const isItWorking = tryTo(() => I.see('It works')) + + // run multiple steps and retry on failure + retryTo(() => { + I.click('Start Working!'); + I.see('It works') + }, 5); +}) +``` + +Previously `tryTo` and `retryTo` were available globally via plugins. This behavior is deprecated as of 3.7 and will be removed in 4.0. Import these functions via effects instead. Similarly, `within` will be moved to `effects` in 4.0. + +### ะฒัšโ€ฆ `check` command added + +``` +npx codeceptjs check +``` + +This command can be executed locally or in CI environments to verify that tests can be executed correctly. + +It checks: + +- configuration +- tests +- helpers + +And will attempt to open and close a browser if a corresponding helper is enabled. If something goes wrong, the command will fail with a message. Run `npx codeceptjs check` on CI before actual tests to ensure everything is set up correctly and all services and browsers are accessible. + +For GitHub Actions, add this command: + +```yaml +steps: + # ... + - name: check configuration and browser + run: npx codeceptjs check + + - name: run codeceptjs tests + run: npx codeceptjs run-workers 4 +``` + +### ั€ัŸโ€˜ะะฒะ‚ะŒั€ัŸโ€ยฌ **analyze plugin introduced** + +This [AI plugin](/plugins#analyze) analyzes failures in test runs and provides brief summaries. For more than 5 failures, it performs cluster analysis and aggregates failures into groups, attempting to find common causes. It is recommended to use Deepseek R1 model or OpenAI o3 for better reasoning on clustering: + +```js +ะฒะ‚ัž SUMMARY The test failed because the expected text "Sign in" was not found on the page, indicating a possible issue with HTML elements or their visibility. +ะฒะ‚ัž ERROR expected web application to include "Sign in" +ะฒะ‚ัž CATEGORY HTML / page elements (not found, not visible, etc) +ะฒะ‚ัž URL http://127.0.0.1:3000/users/sign_in +``` + +For fewer than 5 failures, they are analyzed individually. If a visual recognition model is connected, AI will also scan screenshots to suggest potential failure causes (missing button, missing text, etc). + +This plugin should be paired with the newly added [`pageInfo` plugin](/plugins#pageinfo) which stores important information like URL, console logs, and error classes for further analysis. + +### ั€ัŸโ€˜ะะฒะ‚ะŒั€ัŸโ€™ั˜ **autoLogin plugin** renamed to **auth plugin** + +[`auth`](/plugins#auth) is the new name for the autoLogin plugin and aims to solve common authorization issues. In 3.7 it can use Playwright's storage state to load authorization cookies in a browser on start. So if a user is already authorized, a browser session starts with cookies already loaded for this user. If you use Playwright, you can enable this behavior using the `loginAs` method inside a `BeforeSuite` hook: + +```js +BeforeSuite(({ loginAs }) => loginAs('user')) +``` + +The previous behavior where `loginAs` was called from a `Before` hook also works. However, cookie loading and authorization checking is performed after the browser starts. + +#### Metadata introduced + +Meta information in key-value format can be attached to Scenarios to provide more context when reporting tests: + +```js +// add Jira issue to scenario +Scenario('...', () => { + // ... +}).meta('JIRA', 'TST-123') + +// or pass meta info in the beginning of scenario: +Scenario('my test linked to Jira', meta: { issue: 'TST-123' }, () => { + // ... +}) +``` + +By default, Playwright helpers add browser and window size as meta information to tests. + +### ั€ัŸโ€˜ัž Custom Steps API + +Custom Steps or Sections API introduced to group steps into sections: + +```js +const { Section } = require('codeceptjs/steps'); + +Scenario({ I } => { + I.amOnPage('/projects'); + + // start section "Create project" + Section('Create a project'); + I.click('Create'); + I.fillField('title', 'Project 123') + I.click('Save') + I.see('Project created') + // calling Section with empty param closes previous section + Section() + + // previous section automatically closes + // when new section starts + Section('open project') + // ... +}); +``` + +To hide steps inside a section from output use `Section().hidden()` call: + +```js +Section('Create a project').hidden() +// next steps are not printed: +I.click('Create') +I.fillField('title', 'Project 123') +Section() +``` + +Alternative syntax for closing section: `EndSection`: + +```js +const { Section, EndSection } = require('codeceptjs/steps'); + +// ... +Scenario(..., ({ I }) => // ... + + Section('Create a project').hidden() + // next steps are not printed: + I.click('Create'); + I.fillField('title', 'Project 123') + EndSection() +``` + +Also available BDD-style pre-defined sections: + +```js +const { Given, When, Then } = require('codeceptjs/steps'); + +// ... +Scenario(..., ({ I }) => // ... + + Given('I have a project') + // next steps are not printed: + I.click('Create'); + I.fillField('title', 'Project 123') + + When('I open project'); + // ... + + Then('I should see analytics in a project') + //.... +``` + +### ั€ัŸาั• Step Options + +Better syntax to set general step options for specific tests. + +Use it to set timeout or retries for specific steps: + +```js +const step = require('codeceptjs/steps'); + +Scenario(..., ({ I }) => // ... + I.click('Create', step.timeout(10).retry(2)); + //.... +``` + +Alternative syntax: + +```js +const { stepTimeout, stepRetry } = require('codeceptjs/steps'); + +Scenario(..., ({ I }) => // ... + I.click('Create', stepTimeout(10)); + I.see('Created', stepRetry(2)); + //.... +``` + +This change deprecates previous syntax: + +- `I.limitTime().act(...)` => replaced with `I.act(..., stepTimeout())` +- `I.retry().act(...)` => replaced with `I.act(..., stepRetry())` + +Step options should be passed as the very last argument to `I.action()` call. + +Step options can be used to pass additional options to currently existing methods: + +```js +const { stepOpts } = require('codeceptjs/steps') + +I.see('SIGN IN', stepOpts({ ignoreCase: true })) +``` + +Currently this works only on `see` and only with `ignoreCase` param. +However, this syntax will be extended in next versions. + +### Test object can be injected into Scenario + +API for direct access to test object inside Scenario or hooks to add metadata or artifacts: + +```js +BeforeSuite(({ suite }) => { + // no test object here, test is not created yet +}) + +Before(({ test }) => { + // add artifact to test + test.artifacts.myScreenshot = 'screenshot' +}) + +Scenario('test store-test-and-suite test', ({ test }) => { + // add custom meta data + test.meta.browser = 'chrome' +}) + +After(({ test }) => {}) +``` + +Object for `suite` is also injected for all Scenario and hooks. + +### Notable changes + +- Load official Gherkin translations into CodeceptJS. See [#4784](https://github.com/codeceptjs/CodeceptJS/issues/4784) by **[ebo-zig](https://github.com/ebo-zig)** +- ั€ัŸโ€กั–ั€ัŸโ€กยฑ `NL` translation introduced by **[ebo-zig](https://github.com/ebo-zig)** in [#4784](https://github.com/codeceptjs/CodeceptJS/issues/4784): +- **[Playwright]** Improved experience to highlight and print elements in debug mode +- `codeceptjs run` fails on CI if no tests were executed. This helps to avoid false positive checks. Use `DONT_FAIL_ON_EMPTY_RUN` env variable to disable this behavior +- Various console output improvements +- AI suggested fixes from `heal` plugin (which heals failing tests on the fly) shown in `run-workers` command +- `plugin/standatdActingHelpers` replaced with `Container.STANDARD_ACTING_HELPERS` + +### ั€ัŸั’โ€บ _Bug Fixes_ + +- Fixed timeouts for `BeforeSuite` and `AfterSuite` +- Fixed stucking process on session switch + +### ั€ัŸะ‹โ€ก Internal Refactoring + +This section is listed briefly. A new dedicated page for internal API concepts will be added to documentation + +- File structure changed: + - mocha classes moved to `lib/mocha` + - step is split to multiple classes and moved to `lib/step` +- Extended and exposed to public API classes for Test, Suite, Hook + - [Test](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/mocha/test.js) + - [Suite](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/mocha/suite.js) + - [Hook](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/mocha/hooks.js) (Before, After, BeforeSuite, AfterSuite) +- Container: + - refactored to be prepared for async imports in ESM. + - added proxy classes to resolve circular dependencies +- Step + - added different step types [`HelperStep`](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/step/helper.js), [`MetaStep`](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/step/meta.js), [`FuncStep`](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/step/func.js), [`CommentStep`](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/step/comment.js) + - added `step.addToRecorder()` to schedule test execution as part of global promise chain +- [Result object](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/result.js) added + - `event.all.result` now sends Result object with all failures and stats included +- `run-workers` refactored to use `Result` to send results from workers to main process +- Timeouts refactored `listener/timeout` => [`globalTimeout`](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/listener/globalTimeout.js) +- Reduced usages of global variables, more attributes added to [`store`](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/store.js) to share data on current state between different parts of system +- `events` API improved + - Hook class is sent as param for `event.hook.passed`, `event.hook.finished` + - `event.test.failed`, `event.test.finished` always sends Test. If test has failed in `Before` or `BeforeSuite` hook, event for all failed test in this suite will be sent + - if a test has failed in a hook, a hook name is sent as 3rd arg to `event.test.failed` + +--- + +## 3.6.10 + +ะฒัœยคะฟั‘ะ Thanks all to those who contributed to make this release! ะฒัœยคะฟั‘ะ + +ั€ัŸั’โ€บ _Bug Fixes_ +fix(cli): missing failure counts when there is failedHooks ([#4633](https://github.com/codeceptjs/CodeceptJS/issues/4633)) - by **[kobenguyent](https://github.com/kobenguyent)** + +## 3.6.9 + +ะฒัœยคะฟั‘ะ Thanks all to those who contributed to make this release! ะฒัœยคะฟั‘ะ + +ั€ัŸั’โ€บ _Hot Fixes_ +fix: could not run tests due to missing `invisi-data` lib - by **[kobenguyent](https://github.com/kobenguyent)** + +## 3.6.8 + +ะฒัœยคะฟั‘ะ Thanks all to those who contributed to make this release! ะฒัœยคะฟั‘ะ + +ั€ัŸโ€บยฉะฟั‘ะ _Features_ + +- feat(cli): mask sensitive data in logs ([#4630](https://github.com/codeceptjs/CodeceptJS/issues/4630)) - by **[kobenguyent](https://github.com/kobenguyent)** + +``` +export const config: CodeceptJS.MainConfig = { + tests: '**/*.e2e.test.ts', + retry: 4, + output: './output', + maskSensitiveData: true, + emptyOutputFolder: true, +... + + I login {"username":"helloworld@test.com","password": "****"} + I send post request "https://localhost:8000/login", {"username":"helloworld@test.com","password": "****"} + ะฒะ‚ั” **[Request]** {"baseURL":"https://localhost:8000/login","method":"POST","data":{"username":"helloworld@test.com","password": "****"},"headers":{}} + ะฒะ‚ั” **[Response]** {"access-token": "****"} +``` + +- feat(REST): DELETE request supports payload ([#4493](https://github.com/codeceptjs/CodeceptJS/issues/4493)) - by **[schaudhary111](https://github.com/schaudhary111)** + +```js +I.sendDeleteRequestWithPayload('/api/users/1', { author: 'john' }) +``` + +ั€ัŸั’โ€บ _Bug Fixes_ + +- fix(playwright): Different behavior of see* and waitFor* when used in within ([#4557](https://github.com/codeceptjs/CodeceptJS/issues/4557)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix(cli): dry run returns no tests when using a regex grep ([#4608](https://github.com/codeceptjs/CodeceptJS/issues/4608)) - by **[kobenguyent](https://github.com/kobenguyent)** + +```bash +> codeceptjs dry-run --steps --grep "(?=.*Checkout process)" +``` + +- fix: Replace deprecated faker.name with faker.person ([#4581](https://github.com/codeceptjs/CodeceptJS/issues/4581)) - by **[thomashohn](https://github.com/thomashohn)** +- fix(wdio): Remove dependency to devtools ([#4563](https://github.com/codeceptjs/CodeceptJS/issues/4563)) - by **[thomashohn](https://github.com/thomashohn)** +- fix(typings): wrong defineParameterType ([#4548](https://github.com/codeceptjs/CodeceptJS/issues/4548)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix(typing): `Locator.build` complains the empty locator ([#4543](https://github.com/codeceptjs/CodeceptJS/issues/4543)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix: add hint to `I.seeEmailAttachment` treats parameter as regular expression ([#4629](https://github.com/codeceptjs/CodeceptJS/issues/4629)) - by **[ngraf](https://github.com/ngraf)** + +``` +Add hint to "I.seeEmailAttachment" that under the hood parameter is treated as RegExp. +When you don't know it, it can cause a lot of pain, wondering why your test fails with I.seeEmailAttachment('Attachment(1).pdf') although it looks just fine, but actually I.seeEmailAttachment('Attachment\\(1\\).pdf is required to make the test green, in case the attachment is called "Attachment(1).pdf" with special character in it. +``` + +- fix(playwright): waitForText fails when text contains double quotes ([#4528](https://github.com/codeceptjs/CodeceptJS/issues/4528)) - by **[DavertMik](https://github.com/DavertMik)** +- fix(mock-server-helper): move to stand-alone package: https://www.npmjs.com/package/@codeceptjs/mock-server-helper ([#4536](https://github.com/codeceptjs/CodeceptJS/issues/4536)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix(appium): issue with async on runOnIos and runOnAndroid ([#4525](https://github.com/codeceptjs/CodeceptJS/issues/4525)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix: push ws messages to array ([#4513](https://github.com/codeceptjs/CodeceptJS/issues/4513)) - by **[kobenguyent](https://github.com/kobenguyent)** + +ั€ัŸโ€œโ€“ _Documentation_ + +- fix(docs): typo in ai.md ([#4501](https://github.com/codeceptjs/CodeceptJS/issues/4501)) - by **[tomaculum](https://github.com/tomaculum)** + +## 3.6.6 + +ะฒัœยคะฟั‘ะ Thanks all to those who contributed to make this release! ะฒัœยคะฟั‘ะ + +ั€ัŸโ€บยฉะฟั‘ะ _Features_ + +- feat(locator): add withAttrEndsWith, withAttrStartsWith, withAttrContains ([#4334](https://github.com/codeceptjs/CodeceptJS/issues/4334)) - by **[Maksym-Artemenko](https://github.com/Maksym-Artemenko)** +- feat: soft assert ([#4473](https://github.com/codeceptjs/CodeceptJS/issues/4473)) - by **[kobenguyent](https://github.com/kobenguyent)** + - Soft assert + +Zero-configuration when paired with other helpers like REST, Playwright: + +```js +// inside codecept.conf.js +{ + helpers: { + Playwright: {...}, + SoftExpectHelper: {}, + } +} +``` + +```js +// in scenario +I.softExpectEqual('a', 'b') +I.flushSoftAssertions() // Throws an error if any soft assertions have failed. The error message contains all the accumulated failures. +``` + +- feat(cli): print failed hooks ([#4476](https://github.com/codeceptjs/CodeceptJS/issues/4476)) - by **[kobenguyent](https://github.com/kobenguyent)** + - run command + ![Screenshot 2024-09-02 at 15 25 20](https://github.com/user-attachments/assets/625c6b54-03f6-41c6-9d0c-cd699582404a) + + - run workers command + ![Screenshot 2024-09-02 at 15 24 53](https://github.com/user-attachments/assets/efff0312-1229-44b6-a94f-c9b9370b9a64) + +ั€ัŸั’โ€บ _Bug Fixes_ + +- fix(AI): minor AI improvements - by **[DavertMik](https://github.com/DavertMik)** +- fix(AI): add missing await in AI.js ([#4486](https://github.com/codeceptjs/CodeceptJS/issues/4486)) - by **[tomaculum](https://github.com/tomaculum)** +- fix(playwright): no async save video page ([#4472](https://github.com/codeceptjs/CodeceptJS/issues/4472)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix(rest): httpAgent condition ([#4484](https://github.com/codeceptjs/CodeceptJS/issues/4484)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix: DataCloneError error when `I.executeScript` command is used with `run-workers` ([#4483](https://github.com/codeceptjs/CodeceptJS/issues/4483)) - by **[code4muktesh](https://github.com/code4muktesh)** +- fix: no error thrown from rerun script ([#4494](https://github.com/codeceptjs/CodeceptJS/issues/4494)) - by **[lin-brian-l](https://github.com/lin-brian-l)** + +```js +// fix the validation of httpAgent config. we could now pass ca, instead of key/cert. +{ + helpers: { + REST: { + endpoint: 'http://site.com/api', + prettyPrintJson: true, + httpAgent: { + ca: fs.readFileSync(__dirname + '/path/to/ca.pem'), + rejectUnauthorized: false, + keepAlive: true + } + } + } +} +``` + +ั€ัŸโ€œโ€“ _Documentation_ + +- doc(AI): minor AI improvements - by **[DavertMik](https://github.com/DavertMik)** + +## 3.6.5 + +ะฒัœยคะฟั‘ะ Thanks all to those who contributed to make this release! ะฒัœยคะฟั‘ะ + +ั€ัŸโ€บยฉะฟั‘ะ _Features_ + +- feat(helper): playwright > wait for disabled ([#4412](https://github.com/codeceptjs/CodeceptJS/issues/4412)) - by **[kobenguyent](https://github.com/kobenguyent)** + +``` +it('should wait for input text field to be disabled', () => + I.amOnPage('/form/wait_disabled').then(() => I.waitForDisabled('#text', 1))) + + it('should wait for input text field to be enabled by xpath', () => + I.amOnPage('/form/wait_disabled').then(() => I.waitForDisabled("//*[@name = 'test']", 1))) + + it('should wait for a button to be disabled', () => + I.amOnPage('/form/wait_disabled').then(() => I.waitForDisabled('#text', 1))) + +Waits for element to become disabled (by default waits for 1sec). +Element can be located by CSS or XPath. + **[param](https://github.com/param)** {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator. **[param](https://github.com/param)** {number} [sec=1] (optional) time in seconds to wait, 1 by default. **[returns](https://github.com/returns)** {void} automatically synchronized promise through #recorder +``` + +ั€ัŸั’โ€บ _Bug Fixes_ + +- fix(AI): AI is not triggered ([#4422](https://github.com/codeceptjs/CodeceptJS/issues/4422)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix(plugin): stepByStep > report doesn't sync properly ([#4413](https://github.com/codeceptjs/CodeceptJS/issues/4413)) - by **[kobenguyent](https://github.com/kobenguyent)** +- fix: Locator > Unsupported pseudo selector 'has' ([#4448](https://github.com/codeceptjs/CodeceptJS/issues/4448)) - by **[anils92](https://github.com/anils92)** + +ั€ัŸโ€œโ€“ _Documentation_ + +- docs: setup azure open ai using bearer token ([#4434](https://github.com/codeceptjs/CodeceptJS/issues/4434)) - by **[kobenguyent](https://github.com/kobenguyent)** diff --git a/src/content/docs/commands.md b/src/content/docs/commands.md index fbaf8b17..6756c249 100644 --- a/src/content/docs/commands.md +++ b/src/content/docs/commands.md @@ -1,9 +1,8 @@ ---- +๏ปฟ--- title: Commands slug: commands --- -# Commands ## Run @@ -80,7 +79,7 @@ npx codeceptjs run --reporter xunit Use any of [Mocha reporters](https://github.com/mochajs/mocha/tree/master/lib/reporters) used. -#### Debugging +### Debugging Run single test in debug mode @@ -198,10 +197,10 @@ npx codeceptjs dry-run --steps --bootstrap ## Run Multiple -> โš ๏ธ Prefer using `run-workers` instead. +> Warning: prefer using `run-workers` instead. Run multiple suites. Unlike `run-workers` spawns processes to execute tests. -[Requires additional configuration](/advanced#multiple-browsers-execution) and can be used to execute tests in multiple browsers. +[Requires additional configuration](/parallel#parallel-execution-by-workers-on-multiple-browsers) and can be used to execute tests in multiple browsers. ```sh npx codeceptjs run-multiple smoke:chrome regression:firefox diff --git a/src/content/docs/community-helpers-page.md b/src/content/docs/community-helpers-page.md index 82e2e51b..b2bd77f9 100644 --- a/src/content/docs/community-helpers-page.md +++ b/src/content/docs/community-helpers-page.md @@ -3,8 +3,7 @@ title: Community Helpers slug: helpers/community-helpers --- -# Community Helpers -> Share your helpers at our [Wiki Page](https://github.com/codeceptjs/CodeceptJS/wiki/Community-Helpers) +> Share your helpers by opening a PR to this page. Here is the list of helpers created by our community. Please **add your own** by editing this page. diff --git a/src/content/docs/configuration.md b/src/content/docs/configuration.md index ddff4d9a..de9fb1f4 100644 --- a/src/content/docs/configuration.md +++ b/src/content/docs/configuration.md @@ -1,9 +1,8 @@ ---- +๏ปฟ--- title: Configuration slug: configuration --- -# Configuration CodeceptJS configuration is set in `codecept.conf.js` file. @@ -12,7 +11,7 @@ After running `codeceptjs init` it should be saved in test root. | Name | Type | Description | | :------------------- | :----------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `bootstrap?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute code before](/bootstrap/) tests are run. Can be either JS module file or async function: `bootstrap: async () => server.launch(), ` or `bootstrap: 'bootstrap.js', ` | -| `bootstrapAll?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute code before launching tests in parallel mode](/bootstrap/#bootstrapall-teardownall) | +| `bootstrapAll?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute code before launching tests in parallel mode](/bootstrap/#bootstrapall--teardownall) | | `gherkin?` | { `features`: `string` \| `string`[] ; `steps`: `string`[] } | Enable [BDD features](/bdd/#configuration). Sample configuration: `gherkin: { features: "./features/*.feature", steps: ["./step_definitions/steps.js"] } ` | | `gherkin.features` | `string` \| `string`[] | load feature files by pattern. Multiple patterns can be specified as array | | `gherkin.steps` | `string`[] | load step definitions from JS files | @@ -25,7 +24,7 @@ After running `codeceptjs init` it should be saved in test root. | `plugins?` | `any` | Enable CodeceptJS plugins. Example: `plugins: { autoDelay: { enabled: true } } ` | | `require?` | `string`[] | [Require additional JS modules](/configuration/#require) Example: `require: ["should"]` | | `teardown?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute code after tests](/bootstrap/) finished. Can be either JS module file or async function: `teardown: async () => server.stop(), ` or `teardown: 'teardown.js', ` | -| `teardownAll?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute JS code after finishing tests in parallel mode](/bootstrap/#bootstrapall-teardownall) | +| `teardownAll?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute JS code after finishing tests in parallel mode](/bootstrap/#bootstrapall--teardownall) | | `tests` | `string` | Pattern to locate CodeceptJS tests. Allows to enter glob pattern or an Array of patterns to match tests / test file names. For tests in JavaScript: `tests: 'tests/**.test.js' ` For tests in TypeScript: `tests: 'tests/**.test.ts' ` | | `timeout?` | `number` | Set default tests timeout in seconds. Tests will be killed on no response after timeout. `timeout: 20, ` | | `translation?` | `string` | Enable [localized test commands](/translation/) | @@ -51,7 +50,7 @@ Use modern loaders that support ES Modules: // codecept.conf.ts export const config = { tests: './**/*_test.ts', - require: ['tsx/cjs'], // โ† Modern TypeScript loader + require: ['tsx/cjs'], // <- Modern TypeScript loader helpers: {}, include: {}, } @@ -63,7 +62,7 @@ export const config = { // codecept.conf.ts export const config = { tests: './**/*_test.ts', - require: ['ts-node/esm'], // โ† Established TypeScript loader + require: ['ts-node/esm'], // <- Established TypeScript loader helpers: {}, include: {}, } @@ -71,7 +70,7 @@ export const config = { > **Note:** For ts-node/esm, you need a tsconfig.json with ESM configuration. See [TypeScript documentation](/typescript) for details. -#### For CommonJS Projects (CodeceptJS 3.x) +#### For CommonJS Projects Use the CommonJS loader: @@ -79,7 +78,7 @@ Use the CommonJS loader: // codecept.conf.js exports.config = { tests: './*_test.ts', - require: ['ts-node/register'], // โ† CommonJS TypeScript loader + require: ['ts-node/register'], // <- CommonJS TypeScript loader helpers: {}, include: {}, } @@ -156,7 +155,7 @@ codeceptjs run --config=./path/to/my/config.js ## Common Configuration Patterns -> ๐Ÿ“บ [Watch this material](https://www.youtube.com/watch?v=onBnfo_rJa4&t=4s) on YouTube +> [Watch this material](https://www.youtube.com/watch?v=onBnfo_rJa4&t=4s) on YouTube [`@codeceptjs/configure` package](https://github.com/codeceptjs/configure) contains shared recipes for common configuration patterns. This allows to set meta-configuration, independent from a current helper enabled. diff --git a/src/content/docs/continuous-integration.md b/src/content/docs/continuous-integration.md index 67e6f2f1..689c1183 100644 --- a/src/content/docs/continuous-integration.md +++ b/src/content/docs/continuous-integration.md @@ -1,10 +1,9 @@ ---- +๏ปฟ--- title: Continuous Integration --- -# Continuous Integration > Help us improve this article. [Write how did you set up CodeceptJS for CI](https://codecept.discourse.group/c/CodeceptJS-issues-in-general/ci/9) and see your post listed here! diff --git a/src/content/docs/custom-helpers.md b/src/content/docs/custom-helpers.md index 066fbb0a..dd5d5b75 100644 --- a/src/content/docs/custom-helpers.md +++ b/src/content/docs/custom-helpers.md @@ -1,4 +1,4 @@ ---- +๏ปฟ--- title: Custom Helpers --- @@ -29,7 +29,7 @@ helpers: { } ``` -Helpers are classes inherited from [corresponding abstract class](https://github.com/codeceptjs/helper). +Helpers are classes inherited from [corresponding abstract class](https://github.com/codeceptjs/CodeceptJS/blob/4.x/lib/helper.js). Created helper file should look like this: ```js @@ -86,7 +86,8 @@ For instance, to perform a click with Playwright helper, do it like this: ```js doAwesomeThingsWithPlaywright() { const { Playwright } = this.helpers; - Playwright.click('Awesome'); + Playwright.click('Awesome'); + Playwright.click({ aria: 'Awesome' }); } ``` @@ -140,9 +141,9 @@ async clickOnEveryElement(locator) { } ``` -In this case `el` will be an instance of [ElementHandle](https://playwright.dev/#version=master&path=docs%2Fapi.md&q=class-elementhandle) which is similar for Playwright & [Puppeteer](https://pptr.dev/#?product=Puppeteer&version=master&show=api-class-elementhandle). +In this case `el` will be an instance of [ElementHandle](https://playwright.dev/docs/api/class-elementhandle), which is similar for Playwright and [Puppeteer](https://pptr.dev/api/puppeteer.elementhandle). -> โ„น There are more `_locate*` methods in each helper. Take a look on documentation of a helper you use to see which exact method it exposes. +> Note: There are more `_locate*` methods in each helper. Take a look at the documentation of a helper you use to see which exact method it exposes. ## Configuration @@ -283,9 +284,9 @@ module.exports = MyHelper; ### Puppeteer Example -Puppeteer has [nice and elegant API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md) which you can use inside helpers. Accessing `page` instance via `this.helpers.Puppeteer.page` from inside a helper. +Puppeteer has a [well-documented API](https://pptr.dev/api) that you can use inside helpers. Access `page` instance via `this.helpers.Puppeteer.page` from inside a helper. -Let's see how we can use [emulate](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageemulateoptions) function to emulate iPhone browser in a test. +Let's see how we can use [emulate](https://pptr.dev/api/puppeteer.page.emulate) function to emulate iPhone browser in a test. ```js const Helper = require('@codeceptjs/helper'); @@ -303,3 +304,4 @@ class MyHelper extends Helper { module.exports = MyHelper; ``` + diff --git a/src/content/docs/data.md b/src/content/docs/data.md index 48fc943b..e76be38c 100644 --- a/src/content/docs/data.md +++ b/src/content/docs/data.md @@ -1,10 +1,12 @@ ---- +๏ปฟ--- title: Data Management --- -# Data Management > This chapter describes data management for external sources. If you are looking for using Data Sets in tests, see [Data Driven Tests](/advanced#data-driven-tests) section. +> +> Use this page when your goal is to **prepare and clean up test data** for scenarios. +> If your goal is to **validate API responses** (codes, JSON structure, schema assertions), use [API Testing](/api). Managing data for tests is always a tricky issue. How isolate data between tests, how to prepare data for different tests, etc. There are different approaches to solve it: @@ -22,7 +24,7 @@ API is supposed to be a stable interface and it can be used by acceptance tests. ## REST [REST helper](/helpers/rest) allows sending raw HTTP requests to application. -This is a tool to make shortcuts and create your data pragmatically via API. However, it doesn't provide tools for testing APIs, so it should be paired with Playwright or WebDriver helper for browser testing. +This is a tool to make shortcuts and create your data pragmatically via API. However, it doesn't provide response assertion tools out of the box, so it should be paired with Playwright or WebDriver helper for browser testing. Enable REST helper in the config. It is recommended to set `endpoint`, a base URL for all API requests. If you need some authorization you can optionally set default headers too. @@ -88,12 +90,14 @@ I.sendPostRequest('/update-status', {}, { http_x_requested_with: 'xmlhttprequest ``` > See complete reference on [REST](/helpers/rest) helper +> +> For API response assertions, see [API Testing](/api) and [JSONResponse](/helpers/json-response). ## GraphQL [GraphQL helper](/helpers/graph-ql) allows sending GraphQL queries and mutations to application, over HTTP. -This tool allows you to create shortcuts and manage your data pragmatically via a GraphQL endpoint. However, it does not include tools for testing the endpoint, so it should be used in conjunction with WebDriver helpers for browser testing. +This tool allows you to create shortcuts and manage your data pragmatically via a GraphQL endpoint. However, it does not include response assertion tools by default, so it should be used in conjunction with WebDriver helpers for browser testing. Enable GraphQL helper in the config. It is recommended to set `endpoint`, the URL to which the requests go to. If you need some authorization you can optionally set default headers too. @@ -162,6 +166,8 @@ After(({ I }) => { ``` > See complete reference on [GraphQL](/helpers/graph-ql) helper +> +> For API response assertions, see [API Testing](/api) and [JSONResponse](/helpers/json-response). ## Data Generation with Factories @@ -175,13 +181,13 @@ Just define how many items of any kind you need and the data factory helper will To make this work some preparations are required. -At first, you need data generation libraries which are [Rosie](https://github.com/rosiejs/rosie) and [Faker](https://www.npmjs.com/package/faker). Faker can generate random names, emails, texts, and Rosie uses them +At first, you need data generation libraries which are [Rosie](https://github.com/rosiejs/rosie) and [@faker-js/faker](https://www.npmjs.com/package/@faker-js/faker). Faker can generate random names, emails, texts, and Rosie uses them to generate objects using factories. Install rosie and faker to create a first factory: ```js -npm i rosie faker --save-dev +npm i rosie @faker-js/faker --save-dev ``` Then create a module which will export a factory for an entity. @@ -206,11 +212,11 @@ See the example providing a factory for User generation: ```js // factories/post.js -var Factory = require('rosie').Factory; -var faker = require('@faker-js/faker'); +const { Factory } = require('rosie'); +const { faker } = require('@faker-js/faker'); module.exports = new Factory() - .attr('name', () => faker.person.findName()) + .attr('name', () => faker.person.fullName()) .attr('email', () => faker.internet.email()); ``` @@ -236,7 +242,7 @@ Then, calling `I.have('user')` inside a test will create a new user for you. This is done by sending POST request to `/api/users` URL. Response is returned and can be used in tests. At the end of a test ApiDataFactory will clean up created record for you. This is done by collecting -ids from crated records and running `DELETE /api/users/{id}` requests at the end of a test. +ids from created records and running `DELETE /api/users/{id}` requests at the end of a test. This rules can be customized in helper configuration. > See complete reference on [ApiDataFactory](/helpers/api-data-factory) helper @@ -262,15 +268,15 @@ See the example providing a factory for User generation: ```js // factories/post.js -var Factory = require('rosie').Factory; -var faker = require('@faker-js/faker'); +const { Factory } = require('rosie'); +const { faker } = require('@faker-js/faker'); module.exports = new Factory((buildObj) => { return { input: { ...buildObj }, } }) - .attr('name', () => faker.person.findName()) + .attr('name', () => faker.person.fullName()) .attr('email', () => faker.internet.email()); ``` @@ -300,7 +306,7 @@ Then, calling `I.mutateData('createUser')` inside a test will create a new user This is done by sending a GraphQL mutation request over Http to `/graphql` endpoint. Response is returned and can be used in tests. At the end of a test GraphQLDataFactory will clean up created record for you. This is done by collecting -data from crated records, creating deletion mutation objects by passing the data to the `revert` function provided, and sending deletion mutation objects as requests at the end of a test. +data from created records, creating deletion mutation objects by passing the data to the `revert` function provided, and sending deletion mutation objects as requests at the end of a test. This behavior is according the `revert` function be customized in helper configuration. The revert function returns an object, that contains the query for deletion, and the variables object to go along with it. diff --git a/src/content/docs/detox.md b/src/content/docs/detox.md index 491fbb7d..64f8686b 100644 --- a/src/content/docs/detox.md +++ b/src/content/docs/detox.md @@ -59,7 +59,7 @@ As you see, CodeceptJS test is shorter and easier to follow. By simplifying the ## Setup -It is important to follow [Detox guide](https://github.com/wix/Detox/blob/master/docs/Introduction.GettingStarted.md) to build an application with Detox test instrouments included. +It is important to follow [Detox guide](https://wix.github.io/Detox/docs/introduction/getting-started) to build an application with Detox test instrouments included. After you install Detox, create configuration and build an application using `detox build` command, you are ready to integrate Detox with CodeceptJS. @@ -118,13 +118,15 @@ There are also common assertions: * `seeElement` - to check visibility of element * `seeElementExists` - to check that element exists -> For more details on actions refer to the [API reference of Detox helper](/helpers/detox#api). +> For more details on actions refer to the [API reference of Detox helper](/helpers/detox). ## Locators To write a test you need to learn about available locators in Detox. Unlike, Appium there are no XPath locators. Possible locators limited to `text`, `id`, `accessibility id`, and element `type`. Thus, again, an application should be prepared for testing, to ensure that all active elements are accessible. +For hybrid apps with WebView content, you can switch to web context in Appium and use web locators, including ARIA locators like `{ aria: 'Submit' }`. + Let's see how they can be used: * For **ID locators** use `#` prefix (same as in CSS). Example: @@ -231,4 +233,4 @@ If you want to use detox configuration other than is set in `codecept.conf.js` u npx codeceptjs run --configuration android.test.ci ``` -You can also pass all [other arguments that Detox CLI supports](https://github.com/wix/Detox/blob/master/docs/APIRef.DetoxCLI.md#test). +You can also pass all [other arguments that Detox CLI supports](https://wix.github.io/Detox/docs/api/detox-cli/#test). diff --git a/src/content/docs/docker.md b/src/content/docs/docker.md new file mode 100644 index 00000000..aad45dd3 --- /dev/null +++ b/src/content/docs/docker.md @@ -0,0 +1,140 @@ +--- +title: Docker +--- + +# Codeceptjs Docker + +CodeceptJS has an [official docker image](https://hub.docker.com/r/codeceptjs/codeceptjs) based on Playwright image. Image supports Playwright, Puppeteer, and WebDriver engines. + +## How to Use + +This image comes with the necessary dependencies and packages to execute CodeceptJS tests. +Mount in your CodeceptJS config directory into the `/tests` directory in the docker container. + +Sample mount: `-v path/to/codecept.conf.js:/tests` + +CodeceptJS runner is available inside container as `codeceptjs`. + +### Locally + +You can execute CodeceptJS with Puppeteer locally with no extra configuration. + +```sh +docker run --net=host -v $PWD:/tests codeceptjs/codeceptjs +``` + +To customize execution call `codeceptjs` command: + +```sh +# run tests with steps +docker run --net=host -v $PWD:/tests codeceptjs/codeceptjs codeceptjs run --steps + +# run tests with @user in a name +docker run --net=host -v $PWD:/tests codeceptjs/codeceptjs codeceptjs run --grep "@user" +``` + + +### Docker Compose + +```yaml +version: '2' +services: + codeceptjs: + image: codeceptjs/codeceptjs + depends_on: + - firefox + - web + volumes: + - .:/tests + web: + image: node + command: node app/server.js + volumes: + - .:/app + firefox: + image: selenium/standalone-firefox-debug:2.53.0 + ports: + - '4444' + - '5900' +``` + +### Linking Containers + +If using the WebDriver driver, link the container with a Selenium Standalone docker container with an alias of `selenium`. Additionally, make sure your `codeceptjs.conf.js` contains the following to allow CodeceptJS to identify where Selenium is running. + +```javascript + ... + helpers: { + WebDriver: { + ... + host: process.env.HOST + ... + } + } + ... +``` + +```sh +$ docker run -d -P --name selenium-chrome selenium/standalone-chrome + +# Alternatively, selenium/standalone-firefox can be used + +$ docker run -it --rm -v //:/tests/ --link selenium-chrome:selenium codeceptjs/codeceptjs +``` + +You may run use `-v $(pwd)/:tests/` if running this from the root of your CodeceptJS tests directory. +_Note: The output of your test run will appear in your local directory if your output path is `./output` in the CodeceptJS config_ + +### Build + +To build this image: + +```sh +docker build -t codeceptjs/codeceptjs . +``` + +* this directory will be added as `/codecept` insde container +* tests directory is expected to be mounted as `/tests` +* `codeceptjs` is a synlink to `/codecept/bin/codecept.js` + +To build this image with your desired Node version: + +```sh +docker build -t codeceptjs/codeceptjs . --build-arg NODE_VERSION=12.10.0 +``` + +### Passing Options + +Options can be passed by calling `codeceptjs`: + +``` +docker run -v $PWD:/tests codeceptjs/codeceptjs codeceptjs run --debug +``` + +Alternatively arguments to `codecept run` command can be passed via `CODECEPT_ARGS` environment variable. For example to run your tests with debug +output: + +```yaml +version: '2' +services: + codeceptjs: + image: codeceptjs/codeceptjs + environment: + - CODECEPT_ARGS=--debug + volumes: + - .:/tests +``` + +You can also use `run-workers`to run tests by passing `NO_OF_WORKERS`, additionally, you can pass more params like showing the debug info as the following example: + +```yaml +version: '2' +services: + codeceptjs: + image: codeceptjs/codeceptjs + environment: + - NO_OF_WORKERS=3 + - CODECEPT_ARGS=--debug + volumes: + - .:/tests +``` diff --git a/src/content/docs/effects.md b/src/content/docs/effects.md index e0ca1dea..f9d2f7ab 100644 --- a/src/content/docs/effects.md +++ b/src/content/docs/effects.md @@ -1,9 +1,8 @@ ---- +๏ปฟ--- title: Effects slug: effects --- -# Effects Effects are functions that can modify scenario flow. They provide ways to handle conditional steps, retries, and test flow control. @@ -15,7 +14,7 @@ Effects can be imported directly from CodeceptJS: const { tryTo, retryTo, within } = require('codeceptjs/effects') ``` -> Note: Prior to v3.7, `tryTo` and `retryTo` were available globally via plugins. This behavior is deprecated and will be removed in v4.0. +> Note: Prior to v3.7, `tryTo` and `retryTo` were available globally via plugins. In v4.x, import them from `codeceptjs/effects`. ## tryTo @@ -29,6 +28,7 @@ const success = await tryTo(() => { // These steps may fail but won't stop the test I.see('Cookie banner') I.click('Accept cookies') + I.click({ aria: 'Accept cookies' }) }) if (!success) { @@ -91,6 +91,8 @@ within('.modal', () => { }) ``` +For classic `within` usage details (including frames and session interaction notes), see [Basics: Within](/basics#within). + ## Usage with TypeScript Effects are fully typed and work well with TypeScript: diff --git a/src/content/docs/els.md b/src/content/docs/els.md index 73286729..df4370e7 100644 --- a/src/content/docs/els.md +++ b/src/content/docs/els.md @@ -7,7 +7,7 @@ slug: els The `els` module provides low-level element manipulation functions for CodeceptJS tests, allowing more granular control over element interactions and assertions. However, because element representation differs between frameworks, tests using element functions are not portable between helpers. So if you choose Playwright, you won't be able to switch to WebDriver with one config change in CodeceptJS. -### Usage +## Usage Import the els functions in your test file: @@ -155,6 +155,10 @@ await expectElement('.submit-button', async el => { return await el.isEnabled(); }); +await expectElement({ aria: 'Submit' }, async el => { + return await el.isVisible(); +}); + // Verify element has specific text content await expectElement('.header', async el => { const text = await el.getText(); diff --git a/src/content/docs/email.md b/src/content/docs/email.md index 01d3d815..01204186 100644 --- a/src/content/docs/email.md +++ b/src/content/docs/email.md @@ -2,8 +2,6 @@ title: Email Testing --- -# Email Testing - In End 2 End testing we need to interact with emails. Email delivery can't be tested locally or mocked while testing. That's why for an end to end test you need real emails to be sent and real email address to receive that emails. @@ -125,6 +123,7 @@ const email = await I.waitForLatestEmail(); const url = email.body.match(/http(s):\/\/(.*?)\s/)[0]; // open URL I.amOnPage(url); +I.click({ aria: 'Reset password' }); ``` ## Assertions @@ -159,7 +158,7 @@ I.seeEmailAttachment('Attachment_1.pdf'); // Regular expression. Escape special I.seeEmailAttachment('Attachment_2.pdf'); ``` -> More methods are listed in [helper's API reference](https://github.com/codeceptjs/mailslurp-helper/blob/master/README.md#api) +> More methods are listed in [helper's API reference](https://github.com/codeceptjs/mailslurp-helper#api) ## Listing All Emails diff --git a/src/content/docs/esm-migration.md b/src/content/docs/esm-migration.md new file mode 100644 index 00000000..6bf5f685 --- /dev/null +++ b/src/content/docs/esm-migration.md @@ -0,0 +1,242 @@ +๏ปฟ--- +title: ESM Migration Guide +--- + + +This guide covers the migration to ECMAScript Modules (ESM) format in CodeceptJS v4.x, including important changes in execution behavior and how to adapt your tests. + +## Overview + +CodeceptJS v4.x introduces support for ECMAScript Modules (ESM), which brings modern JavaScript module syntax and better compatibility with the Node.js ecosystem. While most tests will continue working without changes, there are some behavioral differences to be aware of. + +## Quick Migration + +For most users, migrating to ESM is straightforward: + +1. **Add `"type": "module"` to your `package.json`:** + +```json +{ + "name": "your-project", + "type": "module", + "dependencies": { + "codeceptjs": "^4.0.0" + } +} +``` + +2. **Update import syntax in configuration files:** + +```js +// Before (CommonJS) +const { setHeadlessWhen, setCommonPlugins } = require('@codeceptjs/configure') + +// After (ESM) +import { setHeadlessWhen, setCommonPlugins } from '@codeceptjs/configure' +``` + +3. **Update helper imports:** + +```js +// Before (CommonJS) +const Helper = require('@codeceptjs/helper') + +// After (ESM) +import Helper from '@codeceptjs/helper' +``` + +## Known Changes + +### Session and Within Block Execution Order + +**Important:** ESM migration has changed the execution timing of `session()` and `within()` blocks. + +#### What Changed + +In CommonJS, session and within blocks executed synchronously, interleaved with main test steps: + +```js +// CommonJS execution order +Scenario('test', ({ I }) => { + I.do('step1') // <- Executes first + session('user', () => { + I.do('session-step') // <- Executes second + }) + I.do('step2') // <- Executes third +}) +``` + +In ESM, session and within blocks execute after the main flow completes: + +```js +// ESM execution order +Scenario('test', ({ I }) => { + I.do('step1') // <- Executes first + session('user', () => { + I.do('session-step') // <- Executes third (after step2) + }) + I.do('step2') // <- Executes second +}) +``` + +#### Impact on Your Tests + +**ะฒัšโ€ฆ No Impact (99% of cases):** Most tests will continue working correctly because: + +- All steps still execute completely +- Browser interactions work as expected +- Session isolation is maintained +- Test assertions pass/fail correctly +- Final test state is identical + +**Potential Issues (rare edge cases):** + +1. **Cross-session dependencies on immediate state:** + +```js +// POTENTIALLY PROBLEMATIC +I.createUser('alice') +session('alice', () => { + I.login('alice') // May execute before user creation completes +}) +``` + +2. **Within blocks depending on immediate DOM changes:** + +```js +// POTENTIALLY PROBLEMATIC +I.click('Show Advanced Form') +within('.advanced-form', () => { + I.fillField('setting', 'value') // May execute before form appears + I.click({ aria: 'Save settings' }) +}) +``` + +#### Migration Solutions + +If you encounter timing-related issues in edge cases: + +1. **Use explicit waits for dependent operations:** + +```js +// RECOMMENDED FIX +I.createUser('alice') +session('alice', () => { + I.waitForElement('.login-form') // Ensure UI is ready + I.login('alice') +}) +``` + +2. **Add explicit synchronization:** + +```js +// RECOMMENDED FIX +I.click('Show Advanced Form') +I.waitForElement('.advanced-form') // Wait for form to appear +within('.advanced-form', () => { + I.fillField('setting', 'value') +}) +``` + +3. **Use async/await for complex flows:** + +```js +// RECOMMENDED FIX +await I.createUser('alice') +await session('alice', async () => { + await I.login('alice') +}) +``` + +## Best Practices for ESM + +### 1. File Extensions + +Use `.js` extension for ESM files (not `.mjs` unless specifically needed): + +```js +// codecept.conf.js (ESM format) +export default { + tests: './*_test.js', + // ... +} +``` + +### 2. Dynamic Imports + +For conditional imports, use dynamic import syntax: + +```js +// Instead of require() conditions +let helper +if (condition) { + helper = await import('./CustomHelper.js') +} +``` + +### 3. Configuration Export + +Use default export for configuration: + +```js +// codecept.conf.js +export default { + tests: './*_test.js', + output: './output', + helpers: { + Playwright: { + url: 'http://localhost', + }, + }, +} +``` + +### 4. Helper Classes + +Export helper classes as default: + +```js +// CustomHelper.js +import { Helper } from 'codeceptjs' + +class CustomHelper extends Helper { + // helper methods +} + +export default CustomHelper +``` + +## Troubleshooting + +### Common Issues + +1. **Module not found errors:** + - Ensure `"type": "module"` is in package.json + - Use complete file paths with extensions: `import './helper.js'` + +2. **Configuration not loading:** + - Check that config uses `export default {}` + - Verify all imports use ESM syntax + +3. **Timing issues in sessions/within:** + - Add explicit waits as shown in the migration solutions above + - Consider using async/await for complex flows + +4. **Plugin compatibility:** + - Ensure all plugins support ESM + - Update plugin imports to use ESM syntax + +### Getting Help + +If you encounter issues during ESM migration: + +1. Check the [example-esm](https://github.com/codeceptjs/CodeceptJS/tree/4.x/example-esm) directory for working examples +2. Review error messages for import/export syntax issues +3. Consider the execution order changes for session/within blocks +4. Join the [CodeceptJS community](https://codecept.io/community/) for support + +## Conclusion + +ESM migration brings CodeceptJS into alignment with modern JavaScript standards while maintaining backward compatibility for most use cases. The execution order changes in sessions and within blocks represent internal timing adjustments that rarely affect real-world test functionality. + +The vast majority of CodeceptJS users will experience seamless migration with no functional differences in their tests. diff --git a/src/content/docs/examples.md b/src/content/docs/examples.md new file mode 100644 index 00000000..197acf4f --- /dev/null +++ b/src/content/docs/examples.md @@ -0,0 +1,67 @@ +๏ปฟ--- +title: Examples +--- + +> Add your own examples by opening a PR to this page. + +## Official + +### [CodeceptJS Examples Repository](https://github.com/codecept-js/examples) + +Playground repository with sample projects for different helpers and patterns. + +### [CodeceptJS Core Examples (4.x)](https://github.com/codeceptjs/CodeceptJS/tree/4.x/examples) + +Examples maintained inside the main CodeceptJS repository. + +## Community (Active) + +### [CodeceptJS Cucumber E2E Framework](https://github.com/gkushang/codeceptjs-e2e) + +Includes Cucumber integration, SauceLabs setup, cross-browser execution, and reporting. + +### [Enterprise Grade Tests (Gen3)](https://github.com/uc-cdis/gen3-qa) + +Large-scale test suite with mixed DSL + BDD style and CI integration. + +### [Practical E2E Tests](https://gitlab.com/paulvincent/codeceptjs-e2e-testing) + +Examples from the book *Practical End 2 End Testing with CodeceptJS*. + +### [Amazon Tests v2](https://gitlab.com/thanhnguyendh/codeceptjs-wdio-services) + +WebDriver-focused example with parallel execution and CI setup. + +### [Tests with Docker Compose](https://github.com/mathesouza/codeceptjs-docker-compose) + +Docker-based execution setup for CodeceptJS tests. + +### [REST Example Tests](https://github.com/PeterNgTr/codeceptjs-rest-demo) + +Small REST helper example. + +### [Automation Starter](https://github.com/sjorrillo/automation-starter) + +Starter project with linting, page objects, and mixed test styles. + +### [Puppeteer + Gherkin + Allure + Parallel](https://github.com/SchnuckySchuster/codeceptJSExample) + +Ready-to-run sample that combines BDD and CodeceptJS DSL tests. + +### [Advanced REST API Testing Stack](https://github.com/EgorBodnar/rest-axios-codeceptjs-allure-docker-test-example) + +TypeScript + Axios + Docker + Allure sample focused on API testing patterns. + +### [Playwright Fun with CodeceptJS](https://github.com/PeterNgTr/codeceptjs-playwright-fun) + +TypeScript setup with GitHub Actions and POM examples. + +## Archived / Legacy + +### [Testing Single Page Application](https://github.com/bugiratracker/codeceptjs-demo) + +Marked as offline by maintainer. Keep as historical reference. + +## How To + +- Create a plugin with TypeScript: [example link](https://github.com/reutenkoivan/codeceptjs-plugins/tree/main/packages/html-snapshot-on-fail) diff --git a/src/content/docs/heal.md b/src/content/docs/heal.md index b752b19d..5b315312 100644 --- a/src/content/docs/heal.md +++ b/src/content/docs/heal.md @@ -1,8 +1,7 @@ ---- +๏ปฟ--- title: Self-Healing Tests --- -# Self-Healing Tests Browser and Mobile tests can fail for vareity of reasons. However, on a big projects there are about 5-10 causes of flaky tests. The more you work and understand your end-to-end tests the more you learn patterns of failure. And after the research you understand how a test could have been fixed: to reload a page, to click that button once again, restart API request. If by looking into a failure you understand what, as a user, you would do to fix that error, then maybe you could teach your tests to heal themselves. @@ -65,7 +64,7 @@ or npx codeceptjs gr ``` -this will generate `recipes.js` (or `recipes.ts`) in the root directory. Provided default recipe include [AI healing](#ai-healing) and `clickAndType` recipe that replaces `fillField` with `click`+`type`. Use them as examples to write your own heal recipes that will fit for application you are testing. +this will generate `recipes.js` (or `recipes.ts`) in the root directory. Provided default recipe include [AI healing](#ai-healing-recipe) and `clickAndType` recipe that replaces `fillField` with `click`+`type`. Use them as examples to write your own heal recipes that will fit for application you are testing. Require `recipes` file and add `heal` plugin to `codecept.conf` file: @@ -153,7 +152,7 @@ Let's briefly sum up the properties of a recipe: * `fn` - a function to be applied for healing. It takes all context params: `test`, `step`, `error`, `prevSteps` and returns return either a function or a markdown text with recipes (used by AI healers). If no recipes match the context should not return anything; -## AI Healing +## AI Healing Recipe AI can be used to heal failed tests. Large Language Models can analyze HTML of a failed test and provide a suggestion what actions should be performed instead. This can be helpful when running tests on CI as AI can make basic decisions to stabilize failing tests. @@ -185,6 +184,6 @@ heal.addRecipe('ai', { As you use, it will be activated on failed steps and will use HTML of a page as additional information. The prompt, error, and the HTML will be sent to AI provider you configured. -Learn more how you can [configure AI provider](./ai). +Provider setup is documented in [Testing with AI](/ai#set-up-ai-provider). To activate the AI healer don't forget to run tests with `--ai` flag. diff --git a/src/content/docs/helpers/ai.md b/src/content/docs/helpers/ai.md new file mode 100644 index 00000000..069c3093 --- /dev/null +++ b/src/content/docs/helpers/ai.md @@ -0,0 +1,104 @@ +๏ปฟ--- +title: AI +--- + + +> Note: ARIA locators like `{ aria: 'Sign in' }` are available in web helpers (Playwright, WebDriver, Puppeteer) when you combine UI steps with this helper. + + + + + +**Extends Helper** + +AI Helper for CodeceptJS. + +This helper class provides integration with the AI GPT-3.5 or 4 language model for generating responses to questions or prompts within the context of web pages. It allows you to interact with the GPT-3.5 model to obtain intelligent responses based on HTML fragments or general prompts. +This helper should be enabled with any web helpers like Playwright or Puppeteer or WebDriver to ensure the HTML context is available. + +Use it only in development mode. It is recommended to run it only inside pause() mode. + +## Configuration + +This helper should be configured in codecept.conf.{js|ts} + +* `chunkSize`: - The maximum number of characters to send to the AI API at once. We split HTML fragments by 8000 chars to not exceed token limit. Increase this value if you use GPT-4. + +### Parameters + +* `config` + +### askForPageObject + +Generates PageObject for current page using AI. + +It saves the PageObject to the output directory. You can review the page object and adjust it as needed and move to pages directory. +Prompt can be customized in a global config file. + +```js +// create page object for whole page +I.askForPageObject('home'); + +// create page object with extra prompt +I.askForPageObject('home', 'implement signIn(username, password) method'); + +// create page object for a specific element +I.askForPageObject('home', null, '.detail'); +``` + +Asks for a page object based on the provided page name, locator, and extra prompt. + +#### Parameters + +* `pageName` **[string][1]** The name of the page to retrieve the object for. +* `extraPrompt` **([string][1] | null)** An optional extra prompt for additional context or information. +* `locator` **([string][1] | null)** An optional locator to find a specific element on the page. + +Returns **[Promise][2]<[Object][3]>** A promise that resolves to the requested page object. + +### askGptGeneralPrompt + +Send a general request to AI and return response. + +#### Parameters + +* `prompt` **[string][1]** + +Returns **[Promise][2]<[string][1]>** A Promise that resolves to the generated response from the GPT model. + +### askGptOnPage + +Asks the AI GPT language model a question based on the provided prompt within the context of the current page's HTML. + +```js +I.askGptOnPage('what does this page do?'); +``` + +#### Parameters + +* `prompt` **[string][1]** The question or prompt to ask the GPT model. + +Returns **[Promise][2]<[string][1]>** A Promise that resolves to the generated responses from the GPT model, joined by newlines. + +### askGptOnPageFragment + +Asks the AI a question based on the provided prompt within the context of a specific HTML fragment on the current page. + +```js +I.askGptOnPageFragment('describe features of this screen', '.screen'); +``` + +#### Parameters + +* `prompt` **[string][1]** The question or prompt to ask the GPT-3.5 model. +* `locator` **[string][1]** The locator or selector used to identify the HTML fragment on the page. + +Returns **[Promise][2]<[string][1]>** A Promise that resolves to the generated response from the GPT model. + +[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String + +[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise + +[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object + + diff --git a/src/content/docs/helpers/api-data-factory.md b/src/content/docs/helpers/api-data-factory.md index aea5e4a3..68ad43be 100644 --- a/src/content/docs/helpers/api-data-factory.md +++ b/src/content/docs/helpers/api-data-factory.md @@ -1,10 +1,12 @@ ---- +๏ปฟ--- title: ApiDataFactory --- + + + -## ApiDataFactory **Extends Helper** @@ -16,12 +18,12 @@ This data will be saved on server via REST API and deleted in the end of a test. ## Use Case -Acceptance tests interact with a websites using UI and real browser. +Acceptance tests interact with websites using UI and a real browser. There is no way to create data for a specific test other than from user interface. That makes tests slow and fragile. Instead of testing a single feature you need to follow all creation/removal process. This helper solves this problem. -Most of web application have API, and it can be used to create and delete test records. +Most web applications have APIs, and they can be used to create and delete test records. By combining REST API with Factories you can easily create records for tests: ```js @@ -55,7 +57,7 @@ const { faker } = require('@faker-js/faker'); module.exports = new Factory() // no need to set id, it will be set by REST API - .attr('author', () => faker.person.findName()) + .attr('author', () => faker.person.fullName()) .attr('title', () => faker.lorem.sentence()) .attr('body', () => faker.lorem.paragraph()); ``` @@ -69,7 +71,7 @@ Then configure ApiDataHelper to match factories and REST API: ApiDataFactory has following config options: * `endpoint`: base URL for the API to send requests to. -* `cleanup` (default: true): should inserted records be deleted up after tests +* `cleanup` (default: true): should inserted records be deleted after tests * `factories`: list of defined factories * `returnId` (default: false): return id instead of a complete response when creating items. * `headers`: list of headers @@ -132,7 +134,7 @@ This behavior can be configured with following options: * `create`: override create options. Expected format: `{ method: uri }`. Example: `{ "post": "/users/create" }` * `delete`: override delete options. Expected format: `{ method: uri }`. Example: `{ "post": "/users/delete/{id}" }` -Requests can also be overridden with a function which returns [axois request config][4]. +Requests can also be overridden with a function which returns [axios request config][4]. ```js create: (data) => ({ method: 'post', url: '/posts', data }), @@ -255,10 +257,13 @@ I.haveMultiple('post', 3, { author: 'davert' }, { publish_date: '01.01.1997' }); [1]: https://github.com/rosiejs/rosie -[2]: https://www.npmjs.com/package/faker +[2]: https://www.npmjs.com/package/@faker-js/faker -[3]: http://codecept.io/helpers/REST/ +[3]: /helpers/rest [4]: https://github.com/axios/axios#request-config [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise + + + diff --git a/src/content/docs/helpers/appium.md b/src/content/docs/helpers/appium.md index c772c993..7724d318 100644 --- a/src/content/docs/helpers/appium.md +++ b/src/content/docs/helpers/appium.md @@ -1,10 +1,13 @@ ---- +๏ปฟ--- title: Appium --- + +> Note: ARIA locators like `{ aria: 'Sign in' }` are available in web helpers (Playwright, WebDriver, Puppeteer) when you combine UI steps with this helper. + + -## Appium **Extends Webdriver** @@ -140,7 +143,7 @@ helpers: { } ``` -Additional configuration params can be used from [https://github.com/appium/appium/blob/master/packages/appium/docs/en/guides/caps.md][4] +Additional configuration params can be used from [Appium capabilities guide][4] ## Access From Helpers @@ -180,7 +183,7 @@ Also capabilities can be checked by a function. ```js I.runOnAndroid((caps) => { - // caps is current config of desiredCapabiliites + // caps is current config of desiredCapabilities return caps.platformVersion >= 6 },() => { // ... @@ -216,7 +219,7 @@ In this case, code will be executed only on Android >= 6. ```js I.runOnAndroid((caps) => { - // caps is current config of desiredCapabiliites + // caps is current config of desiredCapabilities return caps.platformVersion >= 6 },() => { // ... @@ -557,7 +560,7 @@ Appium: support Android and iOS #### Parameters -* `strategy` **(`"tapOutside"` | `"pressKey"`)?** Desired strategy to close keyboard (โ€˜tapOutsideโ€™ or โ€˜pressKeyโ€™) +* `strategy` **(`"tapOutside"` | `"pressKey"`)?** Desired strategy to close keyboard (`tapOutside` or `pressKey`) * `key` **[string][5]?** Optional key ### sendDeviceKeyEvent @@ -861,7 +864,6 @@ I.touchId(false); // simulates invalid fingerprint * `match` Returns **[Promise][6]\** Appium: support only iOS -TODO: not tested ### closeApp @@ -1173,7 +1175,9 @@ I.scrollIntoView('#submit', { behavior: "smooth", block: "center", inline: "cent * `locator` **([string][5] | [object][11])** located by CSS|XPath|strict locator. * `scrollIntoViewOptions` **(ScrollIntoViewOptions | [boolean][7])** either alignToTop=true|false or scrollIntoViewOptions. See [https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView][17]. -Returns **void** automatically synchronized promise through #recorderSupported only for web testing +Returns **void** automatically synchronized promise through #recorder + +Supported only for web testing. ### seeCheckboxIsChecked @@ -1269,7 +1273,9 @@ I.selectOption('Which OS do you use?', ['Android', 'iOS']); * `select` **([string][5] | [object][11])** field located by label|name|CSS|XPath|strict locator. * `option` **([string][5] | [Array][8]\)** visible text or value of option. -Returns **void** automatically synchronized promise through #recorderSupported only for web testing +Returns **void** automatically synchronized promise through #recorder + +Supported only for web testing. ### waitForElement @@ -1345,7 +1351,7 @@ Returns **void** automatically synchronized promise through #recorder [3]: /mobile#setting-up -[4]: https://github.com/appium/appium/blob/master/packages/appium/docs/en/guides/caps.md +[4]: https://appium.io/docs/en/2.1/guides/caps/ [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String @@ -1372,3 +1378,8 @@ Returns **void** automatically synchronized promise through #recorder [16]: https://webdriver.io/docs/api/mobile/setImmediateValue [17]: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView + + + + + diff --git a/src/content/docs/helpers/detox.md b/src/content/docs/helpers/detox.md index 18da8e36..67877021 100644 --- a/src/content/docs/helpers/detox.md +++ b/src/content/docs/helpers/detox.md @@ -1,23 +1,25 @@ ---- +๏ปฟ--- title: Detox --- -# Detox + + +> Note: When combining these flows with web UI steps, ARIA locators like `{ aria: 'Sign in' }` are supported by web helpers (Playwright, WebDriver, Puppeteer). + -## Detox **Extends Helper** -This is a wrapper on top of [Detox][1] library, aimied to unify testing experience for CodeceptJS framework. -Detox provides a grey box testing for mobile applications, playing especially good for React Native apps. +This is a wrapper on top of [Detox][1] library, aimed to unify testing experience for the CodeceptJS framework. +Detox provides grey box testing for mobile applications and works especially well for React Native apps. Detox plays quite differently from Appium. To establish detox testing you need to build a mobile application in a special way to inject Detox code. -This why **Detox is grey box testing** solution, so you need access to application source code, and a way to build and execute it on emulator. +This is why **Detox is a grey box testing** solution: you need access to application source code and a way to build and execute it on an emulator. -Comparing to Appium, Detox runs faster and more stable but requires an additional setup for build. +Compared to Appium, Detox runs faster and is more stable but requires additional setup for builds. ### Setup @@ -31,7 +33,7 @@ Comparing to Appium, Detox runs faster and more stable but requires an additiona Detox configuration is required in `package.json` under `detox` section. -If you completed step 1 and step 2 you should have a configuration similar this: +If you completed step 1 and step 2, you should have a configuration similar to this: ```js "detox": { @@ -201,18 +203,18 @@ I.dontSeeElement('~edit', '#menu'); // element inside #menu ### dontSeeElementExists -Checks that element not exists. +Checks that an element does not exist. Use second parameter to narrow down the search. ```js -I.dontSeeElementExist('~edit'); // located by accessibility id -I.dontSeeElementExist('~edit', '#menu'); // element inside #menu +I.dontSeeElementExists('~edit'); // located by accessibility id +I.dontSeeElementExists('~edit', '#menu'); // element inside #menu ``` #### Parameters * `locator` **([string][5] | [object][6])** element to locate -* `context` **([string][5] | [object][6])** context element (optional, default `null`) +* `context` **([string][5] | [object][6] | null)** context element (optional, default `null`) ### fillField @@ -481,11 +483,11 @@ I.shakeDevice(); ### swipeDown -Performs a swipe up inside an element. +Performs a swipe right inside an element. Can be `slow` or `fast` swipe. ```js -I.swipeUp('#container'); +I.swipeRight('#container'); ``` #### Parameters @@ -656,8 +658,10 @@ I.waitToHide('#message', 2); // wait for 2 seconds [8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number -[9]: #relaunchApp +[9]: #relaunchapp [10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function [11]: #click + + diff --git a/src/content/docs/helpers/expect.md b/src/content/docs/helpers/expect.md index 0054bb96..f6225d72 100644 --- a/src/content/docs/helpers/expect.md +++ b/src/content/docs/helpers/expect.md @@ -1,10 +1,10 @@ ---- +๏ปฟ--- title: Expect --- + -## ExpectHelper This helper allows performing assertions based on Chai. @@ -270,3 +270,5 @@ expects a JSON object matches a provided pattern - `targetData` **any** - `customErrorMsg` **any?** + + diff --git a/src/content/docs/helpers/file-system.md b/src/content/docs/helpers/file-system.md index 012f338f..7860400e 100644 --- a/src/content/docs/helpers/file-system.md +++ b/src/content/docs/helpers/file-system.md @@ -1,10 +1,12 @@ ---- +๏ปฟ--- title: FileSystem --- + + + -## FileSystem **Extends Helper** @@ -147,3 +149,6 @@ Writes text to file [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number + + + diff --git a/src/content/docs/helpers/graph-ql-data-factory.md b/src/content/docs/helpers/graph-ql-data-factory.md index fac8e717..a1b3e477 100644 --- a/src/content/docs/helpers/graph-ql-data-factory.md +++ b/src/content/docs/helpers/graph-ql-data-factory.md @@ -1,10 +1,10 @@ ---- +๏ปฟ--- title: GraphQLDataFactory --- + -## GraphQLDataFactory **Extends Helper** @@ -16,7 +16,7 @@ This data will be saved on server via GraphQL queries and deleted in the end of ## Use Case -Acceptance tests interact with a websites using UI and real browser. +Acceptance tests interact with websites using UI and a real browser. There is no way to create data for a specific test other than from user interface. That makes tests slow and fragile. Instead of testing a single feature you need to follow all creation/removal process. @@ -50,7 +50,7 @@ See the example for Users factories: ```js // tests/factories/users.js -const { Factory } = require('rosie').Factory; +const { Factory } = require('rosie'); const { faker } = require('@faker-js/faker'); // Used with a constructor function passed to Factory, so that the final build @@ -58,9 +58,9 @@ const { faker } = require('@faker-js/faker'); module.exports = new Factory((buildObj) => ({ input: { ...buildObj }, })) - // 'attr'-id can be left out depending on the GraphQl resolvers - .attr('name', () => faker.person.findName()) - .attr('email', () => faker.interact.email()) + // 'attr'-id can be left out depending on the GraphQL resolvers + .attr('name', () => faker.person.fullName()) + .attr('email', () => faker.internet.email()) ``` For more options see [rosie documentation][1]. @@ -72,7 +72,7 @@ Then configure GraphQLDataHelper to match factories and GraphQL schema: GraphQLDataFactory has following config options: * `endpoint`: URL for the GraphQL server. -* `cleanup` (default: true): should inserted records be deleted up after tests +* `cleanup` (default: true): should inserted records be deleted after tests * `factories`: list of defined factories * `headers`: list of headers * `GraphQL`: configuration for GraphQL requests. @@ -126,7 +126,7 @@ Each operation must have the following: * `factory`: The path to factory file. The object built by the factory in this file will be passed as the 'variables' object to go along with the mutation. * `revert`: A function called with the data returned when an item is created. The object returned by - this function is will be used to later delete the items created. So, make sure RELEVANT DATA IS RETURNED + this function will be used later to delete the items created. So, make sure relevant data is returned when a record is created by a mutation. ### Requests @@ -214,10 +214,11 @@ I.mutateMultiple('createUser', 3, { age: 25 }); [1]: https://github.com/rosiejs/rosie -[2]: https://www.npmjs.com/package/faker +[2]: https://www.npmjs.com/package/@faker-js/faker -[3]: http://codecept.io/helpers/GraphQL/ +[3]: /helpers/graph-ql [4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number + diff --git a/src/content/docs/helpers/graph-ql.md b/src/content/docs/helpers/graph-ql.md index fe3b2c99..44c261f9 100644 --- a/src/content/docs/helpers/graph-ql.md +++ b/src/content/docs/helpers/graph-ql.md @@ -1,14 +1,14 @@ ---- +๏ปฟ--- title: GraphQL --- + -## GraphQL **Extends Helper** -GraphQL helper allows to send additional requests to a GraphQl endpoint during acceptance tests. +GraphQL helper allows sending additional requests to a GraphQL endpoint during acceptance tests. [Axios][1] library is used to perform requests. ## Configuration @@ -16,7 +16,7 @@ GraphQL helper allows to send additional requests to a GraphQl endpoint during a * endpoint: GraphQL base URL * timeout: timeout for requests in milliseconds. 10000ms by default * defaultHeaders: a list of default headers -* onRequest: a async function which can update request object. +* onRequest: an async function which can update request object. ## Example @@ -63,7 +63,7 @@ Prepares request for axios call * `operation` **[object][2]** * `headers` **[object][2]** -Returns **[object][2]** graphQLRequest +Returns **[object][2]** GraphQL request ### amBearerAuthenticated @@ -88,7 +88,7 @@ Sets request headers for all requests of this test ### sendMutation -Send query to GraphQL endpoint over http +Send mutation to GraphQL endpoint over HTTP ```js I.sendMutation(` @@ -119,7 +119,7 @@ Returns **any** Promise ### sendQuery -Send query to GraphQL endpoint over http. +Send query to GraphQL endpoint over HTTP. Returns a response as a promise. ```js @@ -147,3 +147,4 @@ Returns **any** Promise [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object [3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String + diff --git a/src/content/docs/helpers/json-response.md b/src/content/docs/helpers/json-response.md index 329d73b2..f25567c1 100644 --- a/src/content/docs/helpers/json-response.md +++ b/src/content/docs/helpers/json-response.md @@ -1,10 +1,12 @@ ---- +๏ปฟ--- title: JSONResponse --- + + + -## JSONResponse **Extends Helper** @@ -20,7 +22,7 @@ It can check status codes, response data, response structure. * `requestHelper` - a helper which will perform requests. `REST` by default, also `Playwright` or `GraphQL` can be used. Custom helpers must have `onResponse` hook in their config, which will be executed when request is performed. -### Examples +## Example Zero-configuration when paired with REST: @@ -214,8 +216,8 @@ const joi = require('joi'); I.seeResponseMatchesJsonSchema(joi.object({ name: joi.string(), - id: joi.number(); -}); + id: joi.number() +})); ``` #### Parameters @@ -249,3 +251,6 @@ I.seeResponseValidByCallback(({ data, status, expect }) => { [5]: https://joi.dev/api/ [6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function + + + diff --git a/src/content/docs/helpers/mochawesome.md b/src/content/docs/helpers/mochawesome.md new file mode 100644 index 00000000..e64569cf --- /dev/null +++ b/src/content/docs/helpers/mochawesome.md @@ -0,0 +1,10 @@ +๏ปฟ--- +title: Mochawesome +--- + +Mochawesome support is documented in the Reports guide. + +- Setup and configuration: [Reports](/reports#html) +- Add custom context: [addMochawesomeContext](/reports#addmochawesomecontext) + +Use this helper when you need Mochawesome HTML reports in CodeceptJS. diff --git a/src/content/docs/helpers/mock-request.md b/src/content/docs/helpers/mock-request.md index 2a7057c1..94a55631 100644 --- a/src/content/docs/helpers/mock-request.md +++ b/src/content/docs/helpers/mock-request.md @@ -1,13 +1,11 @@ ---- +๏ปฟ--- title: MockRequest --- -# MockRequest -## MockRequest This helper allows to **mock requests while running tests in Puppeteer or WebDriver**. For instance, you can block calls to 3rd-party services like Google Analytics, CDNs. @@ -15,7 +13,7 @@ Another way of using is to emulate requests from server by passing prepared data MockRequest helper works in these [modes][1]: -* passthrough (default) - mock prefefined HTTP requests +* passthrough (default) - mock predefined HTTP requests * record - record all requests into a file * replay - replay all recorded requests from a file @@ -37,7 +35,7 @@ I.amOnPage('/users'); I.stopMocking(); ``` -### Installations +### Installation npm i @codeceptjs/mock-request --save-dev @@ -67,12 +65,12 @@ helpers: { helpers: { MockRequestHelper: { require: '@codeceptjs/mock-request', - mode: record, + mode: 'record', recordIfMissing: true, recordFailedRequests: false, expiresIn: null, persisterOptions: { - keepUnusedRequests: false + keepUnusedRequests: false, fs: { recordingsDir: './data/requests', }, @@ -123,9 +121,9 @@ helpers: { ## Usage -### ๐Ÿ‘ป Mock Requests +### Mock Requests -To intercept API requests and mock them use following API +To intercept API requests and mock them, use the following API: * [startMocking()][4] - to enable request interception * [mockRequest()][5] - to define mock in a simple way @@ -145,19 +143,19 @@ I.mockServer(server => { intercept((req, res) => { res.status(200).json(users); }); }); -I.click('Get users); +I.click('Get users'); I.stopMocking(); ``` -### ๐Ÿ“ผ Record & Replay +### Record & Replay > At this moment works only with Puppeteer -Record & Replay mode allows you to record all xhr & fetch requests and save them to file. +Record & Replay mode allows you to record all XHR and fetch requests and save them to a file. On next runs those requests can be replayed. By default, it stores all passed requests, but this behavior can be customized with `I.mockServer` -Set mode via enironment variable, `replay` mode by default: +Set mode via environment variable, `replay` mode by default: ```js // enable replay mode @@ -184,7 +182,7 @@ Use `I.mockServer()` to customize which requests should be recorded and under wh ```js I.startMocking(); I.mockServer((server) => { - // mock request only from ap1.com and api2.com and + // mock request only from api1.com and api2.com and // store recording into two different files server.any('https://api1.com/*').passthrough(false).recordingName('api1'); server.any('https://api2.com/*').passthrough(false).recordingName('api2'); @@ -193,11 +191,11 @@ I.mockServer((server) => { To stop request recording/replaying use `I.stopMocking()`. -๐ŸŽฅ To record HTTP interactions execute tests with MOCK\_MODE environment variable set as "record": +To record HTTP interactions, execute tests with `MOCK_MODE` environment variable set as "record": MOCK_MODE=record npx codeceptjs run --debug -๐Ÿ“ผ To replay them launch tests without environment variable: +To replay them, launch tests without environment variable: npx codeceptjs run --debug @@ -320,7 +318,7 @@ I.stopMocking(); I.startMocking('login-page'); ``` -To update [PollyJS configuration][14] use secon argument: +To update [PollyJS configuration][14] use the second argument: ```js // change mode @@ -340,7 +338,7 @@ I.startMocking('users-loaded', { ### stopMocking Stops mocking requests. -Must be called to save recorded requests into faile. +Must be called to save recorded requests into file. ```js I.stopMocking(); @@ -352,13 +350,13 @@ I.stopMocking(); [3]: https://netflix.github.io/pollyjs/#/examples?id=rest-persister -[4]: #startMocking +[4]: #startmocking -[5]: #mockRequest +[5]: #mockrequest -[6]: #mockServer +[6]: #mockserver -[7]: #stopMocking +[7]: #stopmocking [8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String @@ -373,3 +371,6 @@ I.stopMocking(); [13]: https://netflix.github.io/pollyjs/#/api?id=recordingname [14]: https://netflix.github.io/pollyjs/#/configuration + + + diff --git a/src/content/docs/helpers/mock-server.md b/src/content/docs/helpers/mock-server.md index acbc0d97..cce18176 100644 --- a/src/content/docs/helpers/mock-server.md +++ b/src/content/docs/helpers/mock-server.md @@ -1,12 +1,14 @@ ---- +๏ปฟ--- title: MockServer --- - - ## MockServer -MockServer + + + + + The MockServer Helper in CodeceptJS empowers you to mock any server or service via HTTP or HTTPS, making it an excellent tool for simulating REST endpoints and other HTTP-based APIs. @@ -26,7 +28,7 @@ Type: [object][1] -#### Examples +### Examples You can seamlessly integrate MockServer with other helpers like REST or Playwright. Here's a configuration example inside the `codecept.conf.js` file: @@ -134,8 +136,6 @@ I.addInteractionToMockServer({ - POST to `/api/users` with the body containing `name` as 'john' will return a 200 status code. - POST to `/api/users` without the `name` property in the body will return a 404 status code. -Happy testing with MockServer in CodeceptJS! ๐Ÿš€ - ## Methods ### Parameters @@ -207,3 +207,6 @@ Returns **any** void [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number [3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String + + + diff --git a/src/content/docs/helpers/open-ai.md b/src/content/docs/helpers/open-ai.md index 06274797..dcb445ed 100644 --- a/src/content/docs/helpers/open-ai.md +++ b/src/content/docs/helpers/open-ai.md @@ -1,23 +1,26 @@ ---- +๏ปฟ--- title: OpenAI --- + +> Note: ARIA locators like `{ aria: 'Sign in' }` are available in web helpers (Playwright, WebDriver, Puppeteer) when you combine UI steps with this helper. + + -## OpenAI **Extends Helper** OpenAI Helper for CodeceptJS. -This helper class provides integration with the OpenAI GPT-3.5 or 4 language model for generating responses to questions or prompts within the context of web pages. It allows you to interact with the GPT-3.5 model to obtain intelligent responses based on HTML fragments or general prompts. -This helper should be enabled with any web helpers like Playwright or Puppeteer or WebDrvier to ensure the HTML context is available. +This helper class provides integration with OpenAI models for generating responses to questions or prompts within the context of web pages. It allows you to interact with the model to obtain intelligent responses based on HTML fragments or general prompts. +This helper should be enabled with web helpers like Playwright, Puppeteer, or WebDriver to ensure the HTML context is available. ## Configuration This helper should be configured in codecept.json or codecept.conf.js -- `chunkSize`: - The maximum number of characters to send to the OpenAI API at once. We split HTML fragments by 8000 chars to not exceed token limit. Increase this value if you use GPT-4. +- `chunkSize`: The maximum number of characters to send to the OpenAI API at once. We split HTML fragments into 8000-char chunks to avoid token limits. ### Parameters @@ -65,3 +68,5 @@ Returns **[Promise][2]<[string][1]>** A Promise that resolves to the generate [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise + + diff --git a/src/content/docs/helpers/playwright.md b/src/content/docs/helpers/playwright.md index 41476f02..f75b1f3d 100644 --- a/src/content/docs/helpers/playwright.md +++ b/src/content/docs/helpers/playwright.md @@ -1,10 +1,10 @@ ---- +๏ปฟ--- title: Playwright --- + -## Playwright **Extends Helper** @@ -515,7 +515,7 @@ Examples: I.checkOption('Agree', '.signup', { position: { x: 5, y: 5 } }) ``` -> ะ ะ†ะกโ„ขะ’ย ะ ั—ะกโ€˜ะ ะ To avoid flakiness, option `force: true` is set by default +> Note: To avoid flakiness, option `force: true` is set by default Selects a checkbox or radio button. Element is located by label or name or CSS or XPath. @@ -592,6 +592,8 @@ I.click('//form/*[@type=submit]'); I.click('Logout', '#nav'); // using strict locator I.click({css: 'nav a.login'}); +// ARIA locator +I.click({ aria: 'Select' }); ``` #### Parameters @@ -602,7 +604,6 @@ I.click({css: 'nav a.login'}); #### Examples -````javascript ```js // click on element at position I.click('canvas', '.model', { position: { x: 20, y: 40 } }) @@ -610,7 +611,6 @@ I.click('canvas', '.model', { position: { x: 20, y: 40 } }) // make ctrl-click I.click('.edit', null, { modifiers: ['Ctrl'] } ) ``` -```` Returns **void** automatically synchronized promise through #recorder @@ -974,6 +974,8 @@ I.forceClick('//form/*[@type=submit]'); I.forceClick('Logout', '#nav'); // using strict locator I.forceClick({css: 'nav a.login'}); +// ARIA locator +I.forceClick({ aria: 'Select' }); ``` #### Parameters @@ -2341,7 +2343,7 @@ Examples: I.uncheckOption('Agree', '.signup', { position: { x: 5, y: 5 } }) ``` -> ะ ะ†ะกโ„ขะ’ย ะ ั—ะกโ€˜ะ ะ To avoid flakiness, option `force: true` is set by default +> Note: To avoid flakiness, option `force: true` is set by default Unselects a checkbox or radio button. Element is located by label or name or CSS or XPath. @@ -2719,7 +2721,7 @@ Returns **void** automatically synchronized promise through #recorder [7]: https://playwright.dev/docs/api/class-browser#browser-new-context -[8]: http://jster.net/category/windows-modals-popups +[8]: https://developer.mozilla.org/en-US/docs/Web/API/Window/alert [9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String @@ -2767,7 +2769,7 @@ Returns **void** automatically synchronized promise through #recorder [31]: https://playwright.dev/docs/network#handle-requests -[32]: https://github.com/microsoft/playwright/blob/main/docs/api.md#browsernewpageoptions +[32]: https://playwright.dev/docs/api/class-browser#browser-new-page [33]: https://github.com/GoogleChrome/puppeteer/issues/1313 @@ -2779,11 +2781,11 @@ Returns **void** automatically synchronized promise through #recorder [37]: https://playwright.dev/docs/api/class-elementhandle#element-handle-uncheck -[38]: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md +[38]: https://playwright.dev/docs/api/class-page -[39]: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browsercontext.md +[39]: https://playwright.dev/docs/api/class-browsercontext -[40]: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browser.md +[40]: https://playwright.dev/docs/api/class-browser [41]: https://playwright.dev/docs/api/class-page?_highlight=waitfornavi#pagewaitfornavigationoptions @@ -2802,3 +2804,6 @@ Returns **void** automatically synchronized promise through #recorder [48]: https://playwright.dev/docs/api/class-consolemessage#console-message-type [49]: https://playwright.dev/docs/locators#locate-by-test-id + + + diff --git a/src/content/docs/helpers/polly.md b/src/content/docs/helpers/polly.md new file mode 100644 index 00000000..d57ca186 --- /dev/null +++ b/src/content/docs/helpers/polly.md @@ -0,0 +1,45 @@ +๏ปฟ--- +title: Polly +--- + + + + + +**Extends MockRequest** + +This helper works the same as MockRequest helper. It has been included for backwards compatibility +reasons. So use MockRequest helper instead of this. + +Please refer to MockRequest helper documentation for details. + +### Installation + +Requires [Polly.js][1] library by Netflix installed + + npm i @pollyjs/core @pollyjs/adapter-puppeteer --save-dev + +Requires Puppeteer helper or WebDriver helper enabled + +### Configuration + +Just enable helper in config file: + +```js +helpers: { + Puppeteer: { + // regular Puppeteer config here + }, + Polly: {} +} +``` + +The same can be done when using WebDriver helper.. + +### Usage + +Use `I.mockRequest` to intercept and mock requests. + +[1]: https://netflix.github.io/pollyjs/#/ + + diff --git a/src/content/docs/helpers/protractor.md b/src/content/docs/helpers/protractor.md index 0167fc7a..fc9a05f1 100644 --- a/src/content/docs/helpers/protractor.md +++ b/src/content/docs/helpers/protractor.md @@ -3,9 +3,14 @@ title: Protractor --- +> Legacy helper: Protractor is kept for existing projects only. +> For new 4.x projects, use [Playwright](/helpers/playwright), [WebDriver](/helpers/web-driver), or [Puppeteer](/helpers/puppeteer). +> +> Note: ARIA locators like `{ aria: 'Sign in' }` are available in web helpers (Playwright, WebDriver, Puppeteer) when you combine UI steps with this helper. + + -## Protractor **Extends Helper** @@ -1722,21 +1727,25 @@ I.waitUrlEquals('http://127.0.0.1:8000/info'); Returns **void** automatically synchronized promise through #recorder +## locator + +just press button if no selector is given + [1]: http://www.protractortest.org -[2]: http://codecept.io/quickstart/#prepare-selenium-server +[2]: /quickstart -[3]: http://codecept.io/acceptance/#smartwait +[3]: /webdriver#smartwait [4]: http://localhost:4444/wd/hub -[5]: https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities +[5]: https://www.selenium.dev/documentation/webdriver/drivers/options/ -[6]: https://github.com/angular/protractor/blob/master/docs/referenceConf.js +[6]: https://github.com/angular/protractor/blob/main/docs/referenceConf.js [7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number -[8]: http://jster.net/category/windows-modals-popups +[8]: https://developer.mozilla.org/en-US/docs/Web/API/Window/alert [9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String @@ -1752,9 +1761,9 @@ Returns **void** automatically synchronized promise through #recorder [15]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined -[16]: https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object +[16]: https://www.selenium.dev/documentation/webdriver/interactions/cookies/ -[17]: https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value +[17]: https://www.selenium.dev/documentation/webdriver/actions_api/keyboard/ [18]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean @@ -1762,3 +1771,5 @@ Returns **void** automatically synchronized promise through #recorder [20]: https://www.protractortest.org/#/api?view=ProtractorBrowser + + diff --git a/src/content/docs/helpers/puppeteer-firefox.md b/src/content/docs/helpers/puppeteer-firefox.md index e0e3ae7f..cbfe8a81 100644 --- a/src/content/docs/helpers/puppeteer-firefox.md +++ b/src/content/docs/helpers/puppeteer-firefox.md @@ -1,15 +1,14 @@ ---- -title: Puppeteer-firefox +๏ปฟ--- +title: Puppeteer Firefox slug: helpers/puppeteer-firefox --- -# Puppeteer-firefox Now you can use Puppeteer for Firefox (min version: Firefox/63.0.4) -[Repository](https://github.com/GoogleChrome/puppeteer/tree/master/experimental/puppeteer-firefox) +[Repository](https://github.com/puppeteer/puppeteer) -Some of Puppeteer API methods has not supported in firefox yet. You could check status of them at [Puppeteer API coverage status](https://aslushnikov.github.io/ispuppeteerfirefoxready/) +Some Puppeteer API methods are not supported in Firefox yet. You can check status at [Puppeteer API coverage status](https://aslushnikov.github.io/ispuppeteerfirefoxready/). ## Installation @@ -62,13 +61,13 @@ Example multiple section in codecept.conf.js: ## Puppeteer v2.1.0 onwards -Historically, Puppeteer supported Firefox indirectly through puppeteer-firefox, which relied on a custom, patched version of Firefox. This approach was also known as ะฒะ‚ัšJugglerะฒะ‚ัœ. After discussions with Mozilla, we collectively concluded that relying on custom patches was infeasible. Since then, we have been collaborating with Mozilla on supporting Puppeteer on ะฒะ‚ัšstockะฒะ‚ัœ Firefox. From Puppeteer v2.1.0 onwards, as an experimental feature, you can specify puppeteer.launch({product: 'firefox'}) to run your Puppeteer scripts in Firefox Nightly, without any additional custom patches. +Historically, Puppeteer supported Firefox indirectly through puppeteer-firefox, which relied on a custom patched version of Firefox. This approach was also known as "Juggler". After discussions with Mozilla, this model was dropped in favor of supporting stock Firefox. Since Puppeteer v2.1.0, you can specify `puppeteer.launch({ product: 'firefox' })` to run Puppeteer scripts in Firefox Nightly. ```sh npm i puppeteer@v2.1.0 ``` -If you want to try this expirement within CodeceptJS, you should add it in Puppeteer section in codecept.conf.js. +If you want to try this experiment in CodeceptJS, add it to the Puppeteer section in codecept.conf.js. - browser: 'chrome' OR 'firefox', 'chrome' is default value @@ -91,3 +90,4 @@ helpers: { ``` + diff --git a/src/content/docs/helpers/puppeteer.md b/src/content/docs/helpers/puppeteer.md index 3ad1cba5..e9cfc237 100644 --- a/src/content/docs/helpers/puppeteer.md +++ b/src/content/docs/helpers/puppeteer.md @@ -1,10 +1,10 @@ ---- +๏ปฟ--- title: Puppeteer --- + -## Puppeteer **Extends Helper** @@ -321,7 +321,7 @@ This action supports [React locators](/react#locators) ### attachFile -> ะ ย ะ โ€ ะ ะŽะฒโ€žัžะ โ€™ะ’ย  There is an [issue with file upload in Puppeteer 2.1.0 & 2.1.1][7], downgrade to 2.0.0 if you face it. +> There is an [issue with file upload in Puppeteer 2.1.0 & 2.1.1][7], downgrade to 2.0.0 if you face it. Attaches a file to element located by label, name, CSS or XPath Path to file is relative current codecept directory (where codecept.conf.ts or codecept.conf.js is located). @@ -442,6 +442,8 @@ I.click('//form/*[@type=submit]'); I.click('Logout', '#nav'); // using strict locator I.click({css: 'nav a.login'}); +// ARIA locator +I.click({ aria: 'Select' }); ``` #### Parameters @@ -884,6 +886,8 @@ I.forceClick('//form/*[@type=submit]'); I.forceClick('Logout', '#nav'); // using strict locator I.forceClick({css: 'nav a.login'}); +// ARIA locator +I.forceClick({ aria: 'Select' }); ``` #### Parameters @@ -2448,7 +2452,7 @@ Returns **void** automatically synchronized promise through #recorder [4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object -[5]: http://jster.net/category/windows-modals-popups +[5]: https://developer.mozilla.org/en-US/docs/Web/API/Window/alert [6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String @@ -2486,12 +2490,15 @@ Returns **void** automatically synchronized promise through #recorder [23]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean -[24]: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-page +[24]: https://pptr.dev/api/puppeteer.page -[25]: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-browser +[25]: https://pptr.dev/api/puppeteer.browser -[26]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions +[26]: https://pptr.dev/api/puppeteer.page.waitfornavigation [27]: https://pptr.dev/api/puppeteer.tracing -[28]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions +[28]: https://pptr.dev/api/puppeteer.launchoptions + + + diff --git a/src/content/docs/helpers/rest.md b/src/content/docs/helpers/rest.md index 9fe20489..3ab36ddf 100644 --- a/src/content/docs/helpers/rest.md +++ b/src/content/docs/helpers/rest.md @@ -1,10 +1,12 @@ ---- +๏ปฟ--- title: REST --- + + + -## REST **Extends Helper** @@ -269,3 +271,6 @@ I.setRequestTimeout(10000); // In milliseconds [6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean [7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function + + + diff --git a/src/content/docs/helpers/soft-expect-helper.md b/src/content/docs/helpers/soft-expect-helper.md index 8311d644..b3ff84df 100644 --- a/src/content/docs/helpers/soft-expect-helper.md +++ b/src/content/docs/helpers/soft-expect-helper.md @@ -1,14 +1,16 @@ ---- +๏ปฟ--- title: SoftExpectHelper --- + + + -## SoftAssertHelper **Extends ExpectHelper** -SoftAssertHelper is a utility class for performing soft assertions. +SoftExpectHelper is a utility class for performing soft assertions. Unlike traditional assertions that stop the execution on failure, soft assertions allow the execution to continue and report all failures at the end. @@ -352,3 +354,7 @@ Softly asserts that the target data is true. [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array [6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number + + + + diff --git a/src/content/docs/helpers/test-cafe.md b/src/content/docs/helpers/test-cafe.md deleted file mode 100644 index c302885c..00000000 --- a/src/content/docs/helpers/test-cafe.md +++ /dev/null @@ -1,1318 +0,0 @@ ---- -title: TestCafe ---- - - - -## TestCafe - -**Extends Helper** - -Uses [TestCafe][1] library to run cross-browser tests. -The browser version you want to use in tests must be installed on your system. - -Requires `testcafe` package to be installed. - - npm i testcafe --save-dev - -## Configuration - -This helper should be configured in codecept.conf.ts or codecept.conf.js - -* `url`: base url of website to be tested -* `show`: - show browser window. -* `windowSize`: (optional) - set browser window width and height -* `getPageTimeout` config option to set maximum navigation time in milliseconds. -* `waitForTimeout`: (optional) default wait* timeout in ms. Default: 5000. -* `browser`: - See [https://devexpress.github.io/testcafe/documentation/using-testcafe/common-concepts/browsers/browser-support.html][2] - -#### Example #1: Show chrome browser window - -```js -{ - helpers: { - TestCafe : { - url: "http://localhost", - waitForTimeout: 15000, - show: true, - browser: "chrome" - } - } -} -``` - -To use remote device you can provide 'remote' as browser parameter this will display a link with QR Code -See [https://devexpress.github.io/testcafe/documentation/recipes/test-on-remote-computers-and-mobile-devices.html][3] - -#### Example #2: Remote browser connection - -```js -{ - helpers: { - TestCafe : { - url: "http://localhost", - waitForTimeout: 15000, - browser: "remote" - } - } -} -``` - -## Access From Helpers - -Call Testcafe methods directly using the testcafe controller. - -```js -const testcafeTestController = this.helpers['TestCafe'].t; -const comboBox = Selector('.combo-box'); -await testcafeTestController - .hover(comboBox) // hover over combo box - .click('#i-prefer-both') // click some other element -``` - -## Methods - -### Parameters - -* `config` - -### _locate - -Get elements by different locator types, including strict locator -Should be used in custom helpers: - -```js -const elements = await this.helpers['TestCafe']._locate('.item'); -``` - -#### Parameters - -* `locator` - -### amOnPage - -Opens a web page in a browser. Requires relative or absolute url. -If url starts with `/`, opens a web page of a site defined in `url` config parameter. - -```js -I.amOnPage('/'); // opens main page of website -I.amOnPage('https://github.com'); // opens github -I.amOnPage('/login'); // opens a login page -``` - -#### Parameters - -* `url` **[string][4]** url path or global url. - -Returns **void** automatically synchronized promise through #recorder - -### appendField - -Appends text to a input field or textarea. -Field is located by name, label, CSS or XPath - -```js -I.appendField('#myTextField', 'appended'); -// typing secret -I.appendField('password', secret('123456')); -``` - -#### Parameters - -* `field` **([string][4] | [object][5])** located by label|name|CSS|XPath|strict locator -* `value` **[string][4]** text value to append. - -Returns **void** automatically synchronized promise through #recorder - -### attachFile - -Attaches a file to element located by label, name, CSS or XPath -Path to file is relative current codecept directory (where codecept.conf.ts or codecept.conf.js is located). -File will be uploaded to remote system (if tests are running remotely). - -```js -I.attachFile('Avatar', 'data/avatar.jpg'); -I.attachFile('form input[name=avatar]', 'data/avatar.jpg'); -``` - -#### Parameters - -* `field` -* `pathToFile` **[string][4]** local file path relative to codecept.conf.ts or codecept.conf.js config file. -* `locator` **([string][4] | [object][5])** field located by label|name|CSS|XPath|strict locator. - -Returns **void** automatically synchronized promise through #recorder - -### blur - -Remove focus from a text input, button, etc. -Calls [blur][6] on the element. - -Examples: - -```js -I.blur('.text-area') -``` - -```js -//element `#product-tile` is focused -I.see('#add-to-cart-btn'); -I.blur('#product-tile') -I.dontSee('#add-to-cart-btn'); -``` - -#### Parameters - -* `locator` **([string][4] | [object][5])** field located by label|name|CSS|XPath|strict locator. -* `options` **any?** Playwright only: [Additional options][7] for available options object as 2nd argument. - -Returns **void** automatically synchronized promise through #recorder - -### checkOption - -Selects a checkbox or radio button. -Element is located by label or name or CSS or XPath. - -The second parameter is a context (CSS or XPath locator) to narrow the search. - -```js -I.checkOption('#agree'); -I.checkOption('I Agree to Terms and Conditions'); -I.checkOption('agree', '//form'); -``` - -#### Parameters - -* `field` **([string][4] | [object][5])** checkbox located by label | name | CSS | XPath | strict locator. -* `context` **([string][4]? | [object][5])** (optional, `null` by default) element located by CSS | XPath | strict locator. - -Returns **void** automatically synchronized promise through #recorder - -### clearCookie - -Clears a cookie by name, -if none provided clears all cookies. - -```js -I.clearCookie(); -I.clearCookie('test'); // Playwright currently doesn't support clear a particular cookie name -``` - -#### Parameters - -* `cookieName` -* `cookie` **[string][4]?** (optional, `null` by default) cookie name - -### clearField - -Clears a `