diff --git a/.github/workflows/wasm_demos.yaml b/.github/workflows/wasm_demos.yaml index 7c887cb44..8bd530b89 100644 --- a/.github/workflows/wasm_demos.yaml +++ b/.github/workflows/wasm_demos.yaml @@ -46,7 +46,7 @@ jobs: - name: Remaining wasm demos if: ${{ inputs.build_artifacts }} run: | - for demo in demos/printerdemo/rust demos/usecases/rust examples/todo/rust examples/todo-mvc/rust examples/carousel/rust examples/slide_puzzle examples/memory examples/imagefilter/rust examples/plotter examples/opengl_underlay demos/home-automation/rust; do + for demo in demos/printerdemo/rust demos/usecases/rust examples/todo/rust examples/todo-mvc/rust examples/carousel/rust examples/slide_puzzle examples/memory examples/imagefilter/rust examples/plotter examples/opengl_underlay demos/home-automation/rust component-sets/material/examples/gallery; do pushd $demo sed -i "s/#wasm# //" Cargo.toml wasm-pack build --release --target web @@ -83,6 +83,7 @@ jobs: demos/home-automation/rust demos/weather-demo/ demos/usecases/rust + component-sets/material/examples/gallery/ !/**/.gitignore - name: Clean cache # Otherwise the cache is much too big run: | diff --git a/Cargo.toml b/Cargo.toml index e85484263..d730b67f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,6 +69,8 @@ members = [ 'tools/viewer', 'tools/tr-extractor', 'xtask', + 'component-sets/material', + 'component-sets/material/examples/gallery', ] default-members = [ diff --git a/REUSE.toml b/REUSE.toml index f51f9c6a8..8bb5e281f 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -185,6 +185,8 @@ SPDX-License-Identifier = "MIT" [[annotations]] path = [ "internal/compiler/widgets/material/_**.svg", + "component-sets/material/ui/icons/**.svg", + "component-sets/material/examples/gallery/ui/icons/**.svg", "examples/carousel/icons/**.svg", "internal/compiler/widgets/cupertino/_**.svg", "internal/compiler/widgets/qt/_**.svg", diff --git a/component-sets/material/Cargo.toml b/component-sets/material/Cargo.toml new file mode 100644 index 000000000..e28a7b66e --- /dev/null +++ b/component-sets/material/Cargo.toml @@ -0,0 +1,14 @@ +# Copyright Β© SixtyFPS GmbH +# SPDX-License-Identifier: MIT + +[package] +name = "slint-material" +authors.workspace = true +edition.workspace = true +repository.workspace = true +license = "MIT" +description = "Material Design 3 component set for Slint" +version.workspace = true +homepage = "https://slint.rs" +rust-version.workspace = true + diff --git a/component-sets/material/README.md b/component-sets/material/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/component-sets/material/docs/.gitignore b/component-sets/material/docs/.gitignore new file mode 100644 index 000000000..aabaeec4b --- /dev/null +++ b/component-sets/material/docs/.gitignore @@ -0,0 +1,29 @@ +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store + +# More to ignore +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +/src/assets/generated/ + diff --git a/component-sets/material/docs/README.md b/component-sets/material/docs/README.md new file mode 100644 index 000000000..2ffac05cc --- /dev/null +++ b/component-sets/material/docs/README.md @@ -0,0 +1,93 @@ + + +# Slint Material Component Documentation + + +## Prerequisites +- Rust +- Node.js +- pnpm + + +## πŸš€ Project Structure +The documentation site is built with [Astro Starlight](https://starlight.astro.build/) and reuses it's +project structure. + +``` +docs/ +β”œβ”€β”€ public/ +β”œβ”€β”€ src/ +β”‚ β”œβ”€β”€ assets/ +β”‚ β”œβ”€β”€ content/ +β”‚ β”‚ β”œβ”€β”€ docs/ +β”‚ β”‚ └── config.ts +β”‚ └── env.d.ts +β”œβ”€β”€ tests/ +β”œβ”€β”€ astro.config.mjs +β”œβ”€β”€ package.json +β”œβ”€β”€ tsconfig.json +└── +``` + +Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. + +Images can be added to `src/assets/` and embedded in Markdown with a relative link. They will be optimized +for download size and also their width and height will be extracted so the framework can render them without +ugly content shifts. + +Static assets, like favicons, can be placed in the `public/` directory. Note that images in this folder will +not be processed and optimized by Starlight. + +## Building the docs + +The docs use a lot of autogenerated content. First create all the screenshots which will be placed at `src/assets/generated/`. + +```bash +cargo run -p slint-docsnapper -- docs/astro/src/content --overwrite +``` + +Then generate the slint auto generated content. + +```bash +cargo xtask slintdocs +``` + +This xtask also installs the npm dependencies and builds the docs. The equivalent of: + +```bash +pnpm i +pnpm run build +``` + +This will build the site and place it in `dist/`. + +## Live edit the docs +To run the live hot reloading dev server run in the astro directory: + +```bash +cd docs/astro/ +pnpm start +``` + +This will start the dev server at [`localhost:4321/docs/`](http://localhost:4321/docs/). + + + +## 🧞 Commands + +All commands are run from the root of the project, from a terminal: + +| Command | Action | +| :------------------------ | :----------------------------------------------- | +| `pnpm i` | Installs dependencies | +| `pnpm start` | Starts local dev server at `localhost:4321` | +| `pnpm build` | Build your production site to `./dist/` | +| `pnpm preview` | Preview your build locally, before deploying | +| `pnpm run astro ...` | Run CLI commands like `astro add`, `astro check` | +| `npm run astro -- --help` | Get help using the Astro CLI | + + + +## πŸ‘€ Want to learn more about Astro and Starlight? + +Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). diff --git a/component-sets/material/docs/astro.config.mjs b/component-sets/material/docs/astro.config.mjs new file mode 100644 index 000000000..f6d904cb1 --- /dev/null +++ b/component-sets/material/docs/astro.config.mjs @@ -0,0 +1,65 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +// @ts-check +import { defineConfig } from "astro/config"; +import starlight from "@astrojs/starlight"; +import starlightLinksValidator from "starlight-links-validator"; +import rehypeExternalLinks from "rehype-external-links"; + +// https://astro.build/config +export default defineConfig({ + trailingSlash: "always", + markdown: { + rehypePlugins: [ + [ + rehypeExternalLinks, + { + content: { + type: "text", + value: " β†—", + }, + properties: { + target: "_blank", + }, + rel: ["noopener"], + }, + ], + ], + }, + integrations: [ + starlight({ + title: "Slint Docs", + logo: { + src: "./src/assets/slint-logo-small-light.svg", + }, + customCss: ["./src/styles/custom.css", "./src/styles/theme.css"], + + components: { + Footer: "./src/components/Footer.astro", + Header: "./src/components/Header.astro", + Banner: "./src/components/Banner.astro", + }, + sidebar: [ + { label: "Overview", link: "index" }, + { label: "Style", link: "style" }, + + { + label: "Basic Widgets", + autogenerate: { directory: "basic-widgets" }, + }, + ], + plugins: [ + starlightLinksValidator({ + errorOnLocalLinks: false, + }), + ], + social: { + github: "https://github.com/slint-ui/slint", + "x.com": "https://x.com/slint_ui", + linkedin: "https://www.linkedin.com/company/slint-ui/", + mastodon: "https://fosstodon.org/@slint", + }, + favicon: "favicon.svg", + }), + ], +}); diff --git a/component-sets/material/docs/biome.json b/component-sets/material/docs/biome.json new file mode 100644 index 000000000..200402900 --- /dev/null +++ b/component-sets/material/docs/biome.json @@ -0,0 +1,57 @@ +{ + "formatter": { + "ignore": ["archive/**", ".astro", "dist", "codemirror.js"], + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 4, + "lineEnding": "lf", + "attributePosition": "auto" + }, + "linter": { + "ignore": ["archive/**", ".astro", "dist", "codemirror.js"], + "rules": { + "recommended": false, + "complexity": { + "noBannedTypes": "warn", + "noUselessConstructor": "error" + }, + "style": { + "useBlockStatements": "warn", + "noUselessElse": "off", + "useConst": "error", + "useImportType": "error", + "useNodejsImportProtocol": "error" + }, + "suspicious": { + "noDoubleEquals": "error", + "noRedundantUseStrict": "warn", + "noImplicitAnyLet": "error" + } + } + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "semicolons": "always", + "bracketSpacing": true, + "bracketSameLine": false, + "quoteStyle": "double", + "attributePosition": "auto" + } + }, + "overrides": [ + { + "include": ["*.astro"], + "linter": { + "rules": { + "style": { + "useConst": "off", + "useImportType": "off" + } + } + } + } + ] +} diff --git a/component-sets/material/docs/ec.config.mjs b/component-sets/material/docs/ec.config.mjs new file mode 100644 index 000000000..3511e6de1 --- /dev/null +++ b/component-sets/material/docs/ec.config.mjs @@ -0,0 +1,199 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +/** @type {import('@astrojs/starlight/expressive-code').StarlightExpressiveCodeOptions} */ +import { definePlugin } from "@expressive-code/core"; +import { h } from "@expressive-code/core/hast"; +import fs from "node:fs"; +import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers"; + +function sideBorder() { + return definePlugin({ + name: "Adds side border to slint code blocks", + baseStyles: ` + + .sideBar { + position: absolute; + top: calc(var(--button-spacing) - 6px); + bottom: 0; + left: 0; + width: 100px; + border-left-width: 2px; + border-left-style: solid; + border-color: #2479f4; + border-top-left-radius: 0.4rem; + border-bottom-left-radius: 0.4rem; + pointer-events: none; + } + `, + hooks: { + postprocessRenderedBlock: async (context) => { + if ( + context.renderData.blockAst.children[1].properties + .dataLanguage !== "slint" + ) { + return; + } + const side = h("div.sideBar"); + + const ast = context.renderData.blockAst; + ast.children.push(side); + + context.renderData.blockAst = ast; + }, + }, + }); +} + +function remapLanguageIdentifiers(lang) { + switch (lang) { + case "cpp": { + return "C++"; + } + case "sh": { + return "bash"; + } + default: { + return lang; + } + } +} + +function languageLabel() { + return definePlugin({ + name: "Adds language label to code blocks", + baseStyles: ` + .language-label { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + inset-block-start: calc(var(--ec-brdWd) + var(--button-spacing)); + inset-inline-end: calc(var(--ec-brdWd) + var(--ec-uiPadInl) ); + direction: ltr; + font-size: 0.8rem; + color:rgb(169, 169, 169); + opacity: 1; + transition: opacity 0.3s; + } + div.expressive-code:hover .language-label, + .expressive-code:hover .language-label { + opacity: 0; + } + `, + hooks: { + postprocessRenderedBlock: async (context) => { + const language = + context.renderData.blockAst.children[1].properties + .dataLanguage; + + const label = h("div.language-label", {}, [ + remapLanguageIdentifiers(language), + ]); + + const ast = context.renderData.blockAst; + ast.children.push(label); + + context.renderData.blockAst = ast; + }, + }, + }); +} + +function workersPlaygroundButton() { + return definePlugin({ + name: "Adds 'Run in SlintPad' button to slint codeblocks", + baseStyles: ` + .run { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + inset-block-start: calc(var(--ec-brdWd) + var(--button-spacing)); + inset-inline-end: calc(var(--ec-brdWd) + var(--ec-uiPadInl) * 3); + direction: ltr; + unicode-bidi: isolate; + + background-color: color-mix(in srgb, var(--sl-color-accent) 50%, transparent); + color: var(--sl-color-white); + text-decoration: none; + width: 2rem; + height: 2rem; + border-radius: 50%; + opacity: 0; + font-size: 0; + transition: opacity 0.3s, background-color 0.3s; + + &:hover { + background-color: color-mix(in srgb, var(--sl-color-accent) 90%, transparent); + } + + &::before { + content: ''; + display: inline-block; + margin-left: 0.25rem; + border-style: solid; + border-width: 0.5rem 0 0.5rem 0.75rem; + border-color: transparent transparent transparent white; + } + } + div.expressive-code:hover .run, + .expressive-code:hover .run { + opacity: 1; + } + `, + hooks: { + postprocessRenderedBlock: async (context) => { + if (!context.codeBlock.meta.includes("playground")) { + return; + } + + const content = context.codeBlock.code; + const url = `https://slintpad.com?snippet=${encodeURIComponent(content)}`; + + const runButton = h( + "a.run", + { + href: url, + target: "__blank", + title: "Open in SlintPad", + }, + [], + ); + + const ast = context.renderData.blockAst; + ast.children.push(runButton); + + context.renderData.blockAst = ast; + }, + }, + }); +} + +export default { + plugins: [ + workersPlaygroundButton(), + sideBorder(), + languageLabel(), + pluginLineNumbers(), + ], + defaultProps: { + showLineNumbers: false, + }, + themes: ["dark-plus", "light-plus"], + styleOverrides: { + borderRadius: "0.4rem", + borderColor: "var(--slint-code-background)", + frames: { shadowColor: "transparent" }, + codeBackground: "var(--slint-code-background)", + }, + shiki: { + langs: [ + JSON.parse( + fs.readFileSync("src/misc/Slint-tmLanguage.json", "utf-8"), + ), + ], + }, + frames: { + extractFileNameFromCode: false, + }, +}; diff --git a/component-sets/material/docs/package.json b/component-sets/material/docs/package.json new file mode 100644 index 000000000..1e80af542 --- /dev/null +++ b/component-sets/material/docs/package.json @@ -0,0 +1,43 @@ +{ + "name": "slint-docs", + "type": "module", + "version": "1.11.0", + "scripts": { + "dev": "astro dev", + "start": "astro dev", + "build": "astro check && astro build", + "preview": "astro preview", + "astro": "astro", + "format": "biome format", + "format:fix": "biome format --write", + "lint": "biome lint", + "lint:fix": "biome lint --fix", + "spellcheck": "cspell --no-progress --gitignore --exclude 'archive/**' \"./**/*.{md,mdx}\"", + "type-check": "astro check", + "test": "playwright test", + "test:ui": "playwright test --ui" + }, + "dependencies": { + "@astrojs/check": "0.9.4", + "@astrojs/starlight": "0.32.4", + "@expressive-code/plugin-line-numbers": "0.40.2", + "@types/node": "20.16.10", + "astro": "5.5.5", + "astro-embed": "0.9.0", + "playwright": "1.51.1", + "playwright-ctrf-json-reporter": "0.0.19", + "rehype-external-links": "3.0.0", + "sharp": "0.33.5", + "starlight-links-validator": "0.14.3", + "typescript": "5.8.2" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.4", + "@expressive-code/core": "^0.40.2", + "@playwright/test": "1.51.1", + "cspell": "8.17.5" + }, + "pnpm": { + "onlyBuiltDependencies": ["@biomejs/biome", "esbuild", "sharp"] + } +} diff --git a/component-sets/material/docs/playwright.config.ts b/component-sets/material/docs/playwright.config.ts new file mode 100644 index 000000000..3a3b7845d --- /dev/null +++ b/component-sets/material/docs/playwright.config.ts @@ -0,0 +1,91 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import { defineConfig, devices } from "@playwright/test"; +import { BASE_PATH } from "./src/utils/site-config"; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// import dotenv from 'dotenv'; +// import path from 'path'; +// dotenv.config({ path: path.resolve(__dirname, '.env') }); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: "./tests", + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: [ + ["html"], // You can combine multiple reporters + [ + "playwright-ctrf-json-reporter", + { + outputFile: "ctrf-report.json", + outputDir: "playwright-report", + }, + ], + ], + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: `http://localhost:4321${BASE_PATH}`, + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] }, + }, + + { + name: "firefox", + use: { ...devices["Desktop Firefox"] }, + }, + + { + name: "webkit", + use: { ...devices["Desktop Safari"] }, + }, + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + /* Run your local dev server before starting the tests */ + webServer: { + command: "pnpm run preview", + url: `http://localhost:4321${BASE_PATH}`, + reuseExistingServer: !process.env.CI, + timeout: 120 * 1000, + }, +}); diff --git a/component-sets/material/docs/pnpm-lock.yaml b/component-sets/material/docs/pnpm-lock.yaml new file mode 100644 index 000000000..cc6c8fc2c --- /dev/null +++ b/component-sets/material/docs/pnpm-lock.yaml @@ -0,0 +1,5957 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@astrojs/check': + specifier: 0.9.4 + version: 0.9.4(typescript@5.8.2) + '@astrojs/starlight': + specifier: 0.32.4 + version: 0.32.4(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@expressive-code/plugin-line-numbers': + specifier: 0.40.2 + version: 0.40.2 + '@types/node': + specifier: 20.16.10 + version: 20.16.10 + astro: + specifier: 5.5.5 + version: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + astro-embed: + specifier: 0.9.0 + version: 0.9.0(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + playwright: + specifier: 1.51.1 + version: 1.51.1 + playwright-ctrf-json-reporter: + specifier: 0.0.19 + version: 0.0.19 + rehype-external-links: + specifier: 3.0.0 + version: 3.0.0 + sharp: + specifier: 0.33.5 + version: 0.33.5 + starlight-links-validator: + specifier: 0.14.3 + version: 0.14.3(@astrojs/starlight@0.32.4(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))) + typescript: + specifier: 5.8.2 + version: 5.8.2 + devDependencies: + '@biomejs/biome': + specifier: ^1.9.4 + version: 1.9.4 + '@expressive-code/core': + specifier: ^0.40.2 + version: 0.40.2 + '@playwright/test': + specifier: 1.51.1 + version: 1.51.1 + cspell: + specifier: 8.17.5 + version: 8.17.5 + +packages: + + '@astro-community/astro-embed-baseline-status@0.1.2': + resolution: {integrity: sha512-u+3BwXCSjBIVW29MGTbdusRhRBhqcjHyE6dgBCsUK/nZ0BohP1Nfih8dB7YltTVZxgECakKWQWoSHabDbYteyA==} + peerDependencies: + astro: ^4.0.0-beta || ^5.0.0-beta + + '@astro-community/astro-embed-bluesky@0.1.3': + resolution: {integrity: sha512-qOuIK2CYQfAjFePaxtko7yyS0rb94I3MgZ94kK02xqeonCzHNP95Q+jUCD/uelcvZK4u+VEh5zNkQ4BfjFm63w==} + peerDependencies: + astro: ^4.0.0 || ^5.0.0-beta.0 + + '@astro-community/astro-embed-integration@0.8.1': + resolution: {integrity: sha512-lI5oekRcmRdNI0AWluAZuM8ZyIV2S64KDPsOo/bbR6diF//Vic5Jy6Tz0gAPjcNMlZSSGMjXBKuUCQZS338e7w==} + peerDependencies: + astro: ^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta + + '@astro-community/astro-embed-link-preview@0.2.2': + resolution: {integrity: sha512-eZ/ORqtPCC3Z2cSH6UvOB1w9CBguEQUC4nFdyLmwHYIR3FhkutQgbaP7fgI1r+qUBDbXImpZjYxKS3RB4m/fOA==} + + '@astro-community/astro-embed-twitter@0.5.8': + resolution: {integrity: sha512-O2ptQPw+DfipukK8czjJcTcyVgDsrs3OmrHbc3YmWRglaUTOpSTImzPo076POyNBSWjLaRKloul81DFiAMNjTA==} + peerDependencies: + astro: ^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta + + '@astro-community/astro-embed-utils@0.1.3': + resolution: {integrity: sha512-eiMO+vfCdE9GtW6qE7X5Xl6YCKZDCoXJEWqRofQcoC3GHjqN2/WhJlnaxNVRq3demSO03UNtho57Em5p7o7AOA==} + + '@astro-community/astro-embed-vimeo@0.3.10': + resolution: {integrity: sha512-H7v8BozWXG+EhIOn1DcNKLRO6z3bNXZVESUR25mNFiDd3Ue8MEzp8mWkBeRd6Y2onV9acxR34ZhXN36fsSb8bA==} + peerDependencies: + astro: ^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta + + '@astro-community/astro-embed-youtube@0.5.6': + resolution: {integrity: sha512-/mRfCl/eTBUz0kmjD1psOy0qoDDBorVp0QumUacjFcIkBullYtbeFQ2ZGZ+3N/tA6cR/OIyzr2QA4dQXlY6USg==} + peerDependencies: + astro: ^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta + + '@astrojs/check@0.9.4': + resolution: {integrity: sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA==} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + + '@astrojs/compiler@2.11.0': + resolution: {integrity: sha512-zZOO7i+JhojO8qmlyR/URui6LyfHJY6m+L9nwyX5GiKD78YoRaZ5tzz6X0fkl+5bD3uwlDHayf6Oe8Fu36RKNg==} + + '@astrojs/internal-helpers@0.6.1': + resolution: {integrity: sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A==} + + '@astrojs/language-server@2.15.4': + resolution: {integrity: sha512-JivzASqTPR2bao9BWsSc/woPHH7OGSGc9aMxXL4U6egVTqBycB3ZHdBJPuOCVtcGLrzdWTosAqVPz1BVoxE0+A==} + hasBin: true + peerDependencies: + prettier: ^3.0.0 + prettier-plugin-astro: '>=0.11.0' + peerDependenciesMeta: + prettier: + optional: true + prettier-plugin-astro: + optional: true + + '@astrojs/markdown-remark@6.3.1': + resolution: {integrity: sha512-c5F5gGrkczUaTVgmMW9g1YMJGzOtRvjjhw6IfGuxarM6ct09MpwysP10US729dy07gg8y+ofVifezvP3BNsWZg==} + + '@astrojs/mdx@4.2.2': + resolution: {integrity: sha512-nWDvuCPenxoxbog3YK3yVWF3Jw7Lq1+ziWSAOc9fy6zAUbPDSr2bt3c6r6+oa1ll0miCQByj5UVts6eJvN/y+g==} + engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0} + peerDependencies: + astro: ^5.0.0 + + '@astrojs/prism@3.2.0': + resolution: {integrity: sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw==} + engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0} + + '@astrojs/sitemap@3.3.0': + resolution: {integrity: sha512-nYE4lKQtk+Kbrw/w0G0TTgT724co0jUsU4tPlHY9au5HmTBKbwiCLwO/15b1/y13aZ4Kr9ZbMeMHlXuwn0ty4Q==} + + '@astrojs/starlight@0.32.4': + resolution: {integrity: sha512-l6aHQ4wzFPdw2G2XPqft/SrzhOYWYBYPkIHlLdgFT09Lt3NUpHnHwdcomtDJfHPlvrAqBKt/C+aJqQjLBApu0Q==} + peerDependencies: + astro: ^5.1.5 + + '@astrojs/telemetry@3.2.0': + resolution: {integrity: sha512-wxhSKRfKugLwLlr4OFfcqovk+LIFtKwLyGPqMsv+9/ibqqnW3Gv7tBhtKEb0gAyUAC4G9BTVQeQahqnQAhd6IQ==} + engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0} + + '@astrojs/yaml2ts@0.2.2': + resolution: {integrity: sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==} + + '@atproto/api@0.13.35': + resolution: {integrity: sha512-vsEfBj0C333TLjDppvTdTE0IdKlXuljKSveAeI4PPx/l6eUKNnDTsYxvILtXUVzwUlTDmSRqy5O4Ryh78n1b7g==} + + '@atproto/common-web@0.4.0': + resolution: {integrity: sha512-ZYL0P9myHybNgwh/hBY0HaBzqiLR1B5/ie5bJpLQAg0whRzNA28t8/nU2vh99tbsWcAF0LOD29M8++LyENJLNQ==} + + '@atproto/lexicon@0.4.9': + resolution: {integrity: sha512-/tmEuHQFr51V2V7EAVJzaA40sqJ7ylAZpR962VbOsPtmcdOHvezbjVHYEMXgfb927hS+xqbVyzBTbu5w9v8prA==} + + '@atproto/syntax@0.3.4': + resolution: {integrity: sha512-8CNmi5DipOLaVeSMPggMe7FCksVag0aO6XZy9WflbduTKM4dFZVCs4686UeMLfGRXX+X966XgwECHoLYrovMMg==} + + '@atproto/syntax@0.4.0': + resolution: {integrity: sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA==} + + '@atproto/xrpc@0.6.11': + resolution: {integrity: sha512-J2cZP8FjoDN0UkyTYBlCvKvxwBbDm4dld47u6FQK30RJy9YpSiUkdxJJ10NYqpi7JVny3M0qWQgpWJDV94+PdA==} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.0': + resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/runtime@7.27.0': + resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.27.0': + resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} + engines: {node: '>=6.9.0'} + + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@cspell/cspell-bundled-dicts@8.17.5': + resolution: {integrity: sha512-b/Ntabar+g4gsRNwOct909cvatO/auHhNvBzJZfyFQzryI1nqHMaSFuDsrrtzbhQkGJ4GiMAKCXZC2EOdHMgmw==} + engines: {node: '>=18'} + + '@cspell/cspell-json-reporter@8.17.5': + resolution: {integrity: sha512-+eVFCdnda74Frv8hguHYwDtxvqDuJJ/luFRl4dC5oknPMRab0JCHM1DDYjp3NzsehTex0HmcxplxqVW6QoDosg==} + engines: {node: '>=18'} + + '@cspell/cspell-pipe@8.17.5': + resolution: {integrity: sha512-VOIfFdIo3FYQFcSpIyGkqHupOx0LgfBrWs79IKnTT1II27VUHPF+0oGq0WWf4c2Zpd8tzdHvS3IUhGarWZq69g==} + engines: {node: '>=18'} + + '@cspell/cspell-resolver@8.17.5': + resolution: {integrity: sha512-5MhYInligPbGctWxoklAKxtg+sxvtJCuRKGSQHHA0JlCOLSsducypl780P6zvpjLK59XmdfC+wtFONxSmRbsuA==} + engines: {node: '>=18'} + + '@cspell/cspell-service-bus@8.17.5': + resolution: {integrity: sha512-Ur3IK0R92G/2J6roopG9cU/EhoYAMOx2um7KYlq93cdrly8RBAK2NCcGCL7DbjQB6C9RYEAV60ueMUnQ45RrCQ==} + engines: {node: '>=18'} + + '@cspell/cspell-types@8.17.5': + resolution: {integrity: sha512-91y2+0teunRSRZj940ORDA3kdjyenrUiM+4j6nQQH24sAIAJdRmQl2LG3eUTmeaSReJGkZIpnToQ6DyU5cC88Q==} + engines: {node: '>=18'} + + '@cspell/dict-ada@4.1.0': + resolution: {integrity: sha512-7SvmhmX170gyPd+uHXrfmqJBY5qLcCX8kTGURPVeGxmt8XNXT75uu9rnZO+jwrfuU2EimNoArdVy5GZRGljGNg==} + + '@cspell/dict-al@1.1.0': + resolution: {integrity: sha512-PtNI1KLmYkELYltbzuoztBxfi11jcE9HXBHCpID2lou/J4VMYKJPNqe4ZjVzSI9NYbMnMnyG3gkbhIdx66VSXg==} + + '@cspell/dict-aws@4.0.9': + resolution: {integrity: sha512-bDYdnnJGwSkIZ4gzrauu7qzOs/ZAY/FnU4k11LgdMI8BhwMfsbsy2EI1iS+sD/BI5ZnNT9kU5YR3WADeNOmhRg==} + + '@cspell/dict-bash@4.2.0': + resolution: {integrity: sha512-HOyOS+4AbCArZHs/wMxX/apRkjxg6NDWdt0jF9i9XkvJQUltMwEhyA2TWYjQ0kssBsnof+9amax2lhiZnh3kCg==} + + '@cspell/dict-companies@3.1.14': + resolution: {integrity: sha512-iqo1Ce4L7h0l0GFSicm2wCLtfuymwkvgFGhmu9UHyuIcTbdFkDErH+m6lH3Ed+QuskJlpQ9dM7puMIGqUlVERw==} + + '@cspell/dict-cpp@6.0.6': + resolution: {integrity: sha512-HMV1chsExuZt5IL9rYBW7GmhNZDVdQJEd1WtFgOO6jqiNxbpTG3Is3Pkldl7FpusBQQZr4BdjMit5bnPpVRy3A==} + + '@cspell/dict-cryptocurrencies@5.0.4': + resolution: {integrity: sha512-6iFu7Abu+4Mgqq08YhTKHfH59mpMpGTwdzDB2Y8bbgiwnGFCeoiSkVkgLn1Kel2++hYcZ8vsAW/MJS9oXxuMag==} + + '@cspell/dict-csharp@4.0.6': + resolution: {integrity: sha512-w/+YsqOknjQXmIlWDRmkW+BHBPJZ/XDrfJhZRQnp0wzpPOGml7W0q1iae65P2AFRtTdPKYmvSz7AL5ZRkCnSIw==} + + '@cspell/dict-css@4.0.17': + resolution: {integrity: sha512-2EisRLHk6X/PdicybwlajLGKF5aJf4xnX2uuG5lexuYKt05xV/J/OiBADmi8q9obhxf1nesrMQbqAt+6CsHo/w==} + + '@cspell/dict-dart@2.3.0': + resolution: {integrity: sha512-1aY90lAicek8vYczGPDKr70pQSTQHwMFLbmWKTAI6iavmb1fisJBS1oTmMOKE4ximDf86MvVN6Ucwx3u/8HqLg==} + + '@cspell/dict-data-science@2.0.7': + resolution: {integrity: sha512-XhAkK+nSW6zmrnWzusmZ1BpYLc62AWYHZc2p17u4nE2Z9XG5DleG55PCZxXQTKz90pmwlhFM9AfpkJsYaBWATA==} + + '@cspell/dict-django@4.1.4': + resolution: {integrity: sha512-fX38eUoPvytZ/2GA+g4bbdUtCMGNFSLbdJJPKX2vbewIQGfgSFJKY56vvcHJKAvw7FopjvgyS/98Ta9WN1gckg==} + + '@cspell/dict-docker@1.1.12': + resolution: {integrity: sha512-6d25ZPBnYZaT9D9An/x6g/4mk542R8bR3ipnby3QFCxnfdd6xaWiTcwDPsCgwN2aQZIQ1jX/fil9KmBEqIK/qA==} + + '@cspell/dict-dotnet@5.0.9': + resolution: {integrity: sha512-JGD6RJW5sHtO5lfiJl11a5DpPN6eKSz5M1YBa1I76j4dDOIqgZB6rQexlDlK1DH9B06X4GdDQwdBfnpAB0r2uQ==} + + '@cspell/dict-elixir@4.0.7': + resolution: {integrity: sha512-MAUqlMw73mgtSdxvbAvyRlvc3bYnrDqXQrx5K9SwW8F7fRYf9V4vWYFULh+UWwwkqkhX9w03ZqFYRTdkFku6uA==} + + '@cspell/dict-en-common-misspellings@2.0.10': + resolution: {integrity: sha512-80mXJLtr0tVEtzowrI7ycVae/ULAYImZUlr0kUTpa8i57AUk7Zy3pYBs44EYIKW7ZC9AHu4Qjjfq4vriAtyTDQ==} + + '@cspell/dict-en-gb@1.1.33': + resolution: {integrity: sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==} + + '@cspell/dict-en_us@4.3.35': + resolution: {integrity: sha512-HF6QNyPHkxeo/SosaZXRQlnKDUTjIzrGKyqfbw/fPPlPYrXefAZZ40ofheb5HnbUicR7xqV/lsc/HQfqYshGIw==} + + '@cspell/dict-filetypes@3.0.11': + resolution: {integrity: sha512-bBtCHZLo7MiSRUqx5KEiPdGOmXIlDGY+L7SJEtRWZENpAKE+96rT7hj+TUUYWBbCzheqHr0OXZJFEKDgsG/uZg==} + + '@cspell/dict-flutter@1.1.0': + resolution: {integrity: sha512-3zDeS7zc2p8tr9YH9tfbOEYfopKY/srNsAa+kE3rfBTtQERAZeOhe5yxrnTPoufctXLyuUtcGMUTpxr3dO0iaA==} + + '@cspell/dict-fonts@4.0.4': + resolution: {integrity: sha512-cHFho4hjojBcHl6qxidl9CvUb492IuSk7xIf2G2wJzcHwGaCFa2o3gRcxmIg1j62guetAeDDFELizDaJlVRIOg==} + + '@cspell/dict-fsharp@1.1.0': + resolution: {integrity: sha512-oguWmHhGzgbgbEIBKtgKPrFSVAFtvGHaQS0oj+vacZqMObwkapcTGu7iwf4V3Bc2T3caf0QE6f6rQfIJFIAVsw==} + + '@cspell/dict-fullstack@3.2.6': + resolution: {integrity: sha512-cSaq9rz5RIU9j+0jcF2vnKPTQjxGXclntmoNp4XB7yFX2621PxJcekGjwf/lN5heJwVxGLL9toR0CBlGKwQBgA==} + + '@cspell/dict-gaming-terms@1.1.0': + resolution: {integrity: sha512-46AnDs9XkgJ2f1Sqol1WgfJ8gOqp60fojpc9Wxch7x+BA63g4JfMV5/M5x0sI0TLlLY8EBSglcr8wQF/7C80AQ==} + + '@cspell/dict-git@3.0.4': + resolution: {integrity: sha512-C44M+m56rYn6QCsLbiKiedyPTMZxlDdEYAsPwwlL5bhMDDzXZ3Ic8OCQIhMbiunhCOJJT+er4URmOmM+sllnjg==} + + '@cspell/dict-golang@6.0.19': + resolution: {integrity: sha512-VS+oinB2/CbgmHE06kMJlj52OVMZM0S2EEXph3oaroNTgTuclSwdFylQmOEjquZi55kW+n3FM9MyWXiitB7Dtg==} + + '@cspell/dict-google@1.0.8': + resolution: {integrity: sha512-BnMHgcEeaLyloPmBs8phCqprI+4r2Jb8rni011A8hE+7FNk7FmLE3kiwxLFrcZnnb7eqM0agW4zUaNoB0P+z8A==} + + '@cspell/dict-haskell@4.0.5': + resolution: {integrity: sha512-s4BG/4tlj2pPM9Ha7IZYMhUujXDnI0Eq1+38UTTCpatYLbQqDwRFf2KNPLRqkroU+a44yTUAe0rkkKbwy4yRtQ==} + + '@cspell/dict-html-symbol-entities@4.0.3': + resolution: {integrity: sha512-aABXX7dMLNFdSE8aY844X4+hvfK7977sOWgZXo4MTGAmOzR8524fjbJPswIBK7GaD3+SgFZ2yP2o0CFvXDGF+A==} + + '@cspell/dict-html@4.0.11': + resolution: {integrity: sha512-QR3b/PB972SRQ2xICR1Nw/M44IJ6rjypwzA4jn+GH8ydjAX9acFNfc+hLZVyNe0FqsE90Gw3evLCOIF0vy1vQw==} + + '@cspell/dict-java@5.0.11': + resolution: {integrity: sha512-T4t/1JqeH33Raa/QK/eQe26FE17eUCtWu+JsYcTLkQTci2dk1DfcIKo8YVHvZXBnuM43ATns9Xs0s+AlqDeH7w==} + + '@cspell/dict-julia@1.1.0': + resolution: {integrity: sha512-CPUiesiXwy3HRoBR3joUseTZ9giFPCydSKu2rkh6I2nVjXnl5vFHzOMLXpbF4HQ1tH2CNfnDbUndxD+I+7eL9w==} + + '@cspell/dict-k8s@1.0.10': + resolution: {integrity: sha512-313haTrX9prep1yWO7N6Xw4D6tvUJ0Xsx+YhCP+5YrrcIKoEw5Rtlg8R4PPzLqe6zibw6aJ+Eqq+y76Vx5BZkw==} + + '@cspell/dict-kotlin@1.1.0': + resolution: {integrity: sha512-vySaVw6atY7LdwvstQowSbdxjXG6jDhjkWVWSjg1XsUckyzH1JRHXe9VahZz1i7dpoFEUOWQrhIe5B9482UyJQ==} + + '@cspell/dict-latex@4.0.3': + resolution: {integrity: sha512-2KXBt9fSpymYHxHfvhUpjUFyzrmN4c4P8mwIzweLyvqntBT3k0YGZJSriOdjfUjwSygrfEwiuPI1EMrvgrOMJw==} + + '@cspell/dict-lorem-ipsum@4.0.4': + resolution: {integrity: sha512-+4f7vtY4dp2b9N5fn0za/UR0kwFq2zDtA62JCbWHbpjvO9wukkbl4rZg4YudHbBgkl73HRnXFgCiwNhdIA1JPw==} + + '@cspell/dict-lua@4.0.7': + resolution: {integrity: sha512-Wbr7YSQw+cLHhTYTKV6cAljgMgcY+EUAxVIZW3ljKswEe4OLxnVJ7lPqZF5JKjlXdgCjbPSimsHqyAbC5pQN/Q==} + + '@cspell/dict-makefile@1.0.4': + resolution: {integrity: sha512-E4hG/c0ekPqUBvlkrVvzSoAA+SsDA9bLi4xSV3AXHTVru7Y2bVVGMPtpfF+fI3zTkww/jwinprcU1LSohI3ylw==} + + '@cspell/dict-markdown@2.0.9': + resolution: {integrity: sha512-j2e6Eg18BlTb1mMP1DkyRFMM/FLS7qiZjltpURzDckB57zDZbUyskOFdl4VX7jItZZEeY0fe22bSPOycgS1Z5A==} + peerDependencies: + '@cspell/dict-css': ^4.0.17 + '@cspell/dict-html': ^4.0.11 + '@cspell/dict-html-symbol-entities': ^4.0.3 + '@cspell/dict-typescript': ^3.2.0 + + '@cspell/dict-monkeyc@1.0.10': + resolution: {integrity: sha512-7RTGyKsTIIVqzbvOtAu6Z/lwwxjGRtY5RkKPlXKHEoEAgIXwfDxb5EkVwzGQwQr8hF/D3HrdYbRT8MFBfsueZw==} + + '@cspell/dict-node@5.0.6': + resolution: {integrity: sha512-CEbhPCpxGvRNByGolSBTrXXW2rJA4bGqZuTx1KKO85mwR6aadeOmUE7xf/8jiCkXSy+qvr9aJeh+jlfXcsrziQ==} + + '@cspell/dict-npm@5.1.31': + resolution: {integrity: sha512-Oh9nrhgNV4UD1hlbgO3TFQqQRKziwc7qXKoQiC4oqOYIhMs2WL9Ezozku7FY1e7o5XbCIZX9nRH0ymNx/Rwj6w==} + + '@cspell/dict-php@4.0.14': + resolution: {integrity: sha512-7zur8pyncYZglxNmqsRycOZ6inpDoVd4yFfz1pQRe5xaRWMiK3Km4n0/X/1YMWhh3e3Sl/fQg5Axb2hlN68t1g==} + + '@cspell/dict-powershell@5.0.14': + resolution: {integrity: sha512-ktjjvtkIUIYmj/SoGBYbr3/+CsRGNXGpvVANrY0wlm/IoGlGywhoTUDYN0IsGwI2b8Vktx3DZmQkfb3Wo38jBA==} + + '@cspell/dict-public-licenses@2.0.13': + resolution: {integrity: sha512-1Wdp/XH1ieim7CadXYE7YLnUlW0pULEjVl9WEeziZw3EKCAw8ZI8Ih44m4bEa5VNBLnuP5TfqC4iDautAleQzQ==} + + '@cspell/dict-python@4.2.16': + resolution: {integrity: sha512-LkQssFt1hPOWXIQiD8ScTkz/41RL7Ti0V/2ytUzEW82dc0atIEksrBg8MuOjWXktp0Dk5tDwRLgmIvhV3CFFOA==} + + '@cspell/dict-r@2.1.0': + resolution: {integrity: sha512-k2512wgGG0lTpTYH9w5Wwco+lAMf3Vz7mhqV8+OnalIE7muA0RSuD9tWBjiqLcX8zPvEJr4LdgxVju8Gk3OKyA==} + + '@cspell/dict-ruby@5.0.8': + resolution: {integrity: sha512-ixuTneU0aH1cPQRbWJvtvOntMFfeQR2KxT8LuAv5jBKqQWIHSxzGlp+zX3SVyoeR0kOWiu64/O5Yn836A5yMcQ==} + + '@cspell/dict-rust@4.0.11': + resolution: {integrity: sha512-OGWDEEzm8HlkSmtD8fV3pEcO2XBpzG2XYjgMCJCRwb2gRKvR+XIm6Dlhs04N/K2kU+iH8bvrqNpM8fS/BFl0uw==} + + '@cspell/dict-scala@5.0.7': + resolution: {integrity: sha512-yatpSDW/GwulzO3t7hB5peoWwzo+Y3qTc0pO24Jf6f88jsEeKmDeKkfgPbYuCgbE4jisGR4vs4+jfQZDIYmXPA==} + + '@cspell/dict-shell@1.1.0': + resolution: {integrity: sha512-D/xHXX7T37BJxNRf5JJHsvziFDvh23IF/KvkZXNSh8VqcRdod3BAz9VGHZf6VDqcZXr1VRqIYR3mQ8DSvs3AVQ==} + + '@cspell/dict-software-terms@4.2.5': + resolution: {integrity: sha512-CaRzkWti3AgcXoxuRcMijaNG7YUk/MH1rHjB8VX34v3UdCxXXeqvRyElRKnxhFeVLB/robb2UdShqh/CpskxRg==} + + '@cspell/dict-sql@2.2.0': + resolution: {integrity: sha512-MUop+d1AHSzXpBvQgQkCiok8Ejzb+nrzyG16E8TvKL2MQeDwnIvMe3bv90eukP6E1HWb+V/MA/4pnq0pcJWKqQ==} + + '@cspell/dict-svelte@1.0.6': + resolution: {integrity: sha512-8LAJHSBdwHCoKCSy72PXXzz7ulGROD0rP1CQ0StOqXOOlTUeSFaJJlxNYjlONgd2c62XBQiN2wgLhtPN+1Zv7Q==} + + '@cspell/dict-swift@2.0.5': + resolution: {integrity: sha512-3lGzDCwUmnrfckv3Q4eVSW3sK3cHqqHlPprFJZD4nAqt23ot7fic5ALR7J4joHpvDz36nHX34TgcbZNNZOC/JA==} + + '@cspell/dict-terraform@1.1.1': + resolution: {integrity: sha512-07KFDwCU7EnKl4hOZLsLKlj6Zceq/IsQ3LRWUyIjvGFfZHdoGtFdCp3ZPVgnFaAcd/DKv+WVkrOzUBSYqHopQQ==} + + '@cspell/dict-typescript@3.2.0': + resolution: {integrity: sha512-Pk3zNePLT8qg51l0M4g1ISowYAEGxTuNfZlgkU5SvHa9Cu7x/BWoyYq9Fvc3kAyoisCjRPyvWF4uRYrPitPDFw==} + + '@cspell/dict-vue@3.0.4': + resolution: {integrity: sha512-0dPtI0lwHcAgSiQFx8CzvqjdoXROcH+1LyqgROCpBgppommWpVhbQ0eubnKotFEXgpUCONVkeZJ6Ql8NbTEu+w==} + + '@cspell/dynamic-import@8.17.5': + resolution: {integrity: sha512-tY+cVkRou+0VKvH+K1NXv8/R7mOlW3BDGSs9fcgvhatj0m00Yf8blFC7tE4VVI9Qh2bkC/KDFqM24IqZbuwXUQ==} + engines: {node: '>=18.0'} + + '@cspell/filetypes@8.17.5': + resolution: {integrity: sha512-Fj6py2Rl+FEnMiXhRQUM1A5QmyeCLxi6dY/vQ0qfH6tp6KSaBiaC8wuPUKhr8hKyTd3+8lkUbobDhUf6xtMEXg==} + engines: {node: '>=18'} + + '@cspell/strong-weak-map@8.17.5': + resolution: {integrity: sha512-Z4eo+rZJr1086wZWycBiIG/n7gGvVoqn28I7ZicS8xedRYu/4yp2loHgLn4NpxG3e46+dNWs4La6vinod+UydQ==} + engines: {node: '>=18'} + + '@cspell/url@8.17.5': + resolution: {integrity: sha512-GNQqST7zI85dAFVyao6oiTeg5rNhO9FH1ZAd397qQhvwfxrrniNfuoewu8gPXyP0R4XBiiaCwhBL7w9S/F5guw==} + engines: {node: '>=18.0'} + + '@ctrl/tinycolor@4.1.0': + resolution: {integrity: sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==} + engines: {node: '>=14'} + + '@emmetio/abbreviation@2.3.3': + resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==} + + '@emmetio/css-abbreviation@2.1.8': + resolution: {integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==} + + '@emmetio/css-parser@0.4.0': + resolution: {integrity: sha512-z7wkxRSZgrQHXVzObGkXG+Vmj3uRlpM11oCZ9pbaz0nFejvCDmAiNDpY75+wgXOcffKpj4rzGtwGaZxfJKsJxw==} + + '@emmetio/html-matcher@1.3.0': + resolution: {integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==} + + '@emmetio/scanner@1.0.4': + resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==} + + '@emmetio/stream-reader-utils@0.1.0': + resolution: {integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==} + + '@emmetio/stream-reader@2.2.0': + resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==} + + '@emnapi/runtime@1.3.1': + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + + '@esbuild/aix-ppc64@0.25.1': + resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.1': + resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.1': + resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.1': + resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.1': + resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.1': + resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.1': + resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.1': + resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.1': + resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.1': + resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.1': + resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.1': + resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.1': + resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.1': + resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.1': + resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.1': + resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.1': + resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.1': + resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.1': + resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.1': + resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.1': + resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.25.1': + resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.1': + resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.1': + resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.1': + resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@expressive-code/core@0.40.2': + resolution: {integrity: sha512-gXY3v7jbgz6nWKvRpoDxK4AHUPkZRuJsM79vHX/5uhV9/qX6Qnctp/U/dMHog/LCVXcuOps+5nRmf1uxQVPb3w==} + + '@expressive-code/plugin-frames@0.40.2': + resolution: {integrity: sha512-aLw5IlDlZWb10Jo/TTDCVsmJhKfZ7FJI83Zo9VDrV0OBlmHAg7klZqw68VDz7FlftIBVAmMby53/MNXPnMjTSQ==} + + '@expressive-code/plugin-line-numbers@0.40.2': + resolution: {integrity: sha512-YMLkn68n9a9DI/4fQW/f6QJ33uQUzHmGdV3pDl+f6fVTxv7rvhRja+UtPksm0ZJpft6vrrACV8wS2TaH77SBzw==} + + '@expressive-code/plugin-shiki@0.40.2': + resolution: {integrity: sha512-t2HMR5BO6GdDW1c1ISBTk66xO503e/Z8ecZdNcr6E4NpUfvY+MRje+LtrcvbBqMwWBBO8RpVKcam/Uy+1GxwKQ==} + + '@expressive-code/plugin-text-markers@0.40.2': + resolution: {integrity: sha512-/XoLjD67K9nfM4TgDlXAExzMJp6ewFKxNpfUw4F7q5Ecy+IU3/9zQQG/O70Zy+RxYTwKGw2MA9kd7yelsxnSmw==} + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@mdx-js/mdx@3.1.0': + resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@oslojs/encoding@1.1.0': + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + + '@pagefind/darwin-arm64@1.3.0': + resolution: {integrity: sha512-365BEGl6ChOsauRjyVpBjXybflXAOvoMROw3TucAROHIcdBvXk9/2AmEvGFU0r75+vdQI4LJdJdpH4Y6Yqaj4A==} + cpu: [arm64] + os: [darwin] + + '@pagefind/darwin-x64@1.3.0': + resolution: {integrity: sha512-zlGHA23uuXmS8z3XxEGmbHpWDxXfPZ47QS06tGUq0HDcZjXjXHeLG+cboOy828QIV5FXsm9MjfkP5e4ZNbOkow==} + cpu: [x64] + os: [darwin] + + '@pagefind/default-ui@1.3.0': + resolution: {integrity: sha512-CGKT9ccd3+oRK6STXGgfH+m0DbOKayX6QGlq38TfE1ZfUcPc5+ulTuzDbZUnMo+bubsEOIypm4Pl2iEyzZ1cNg==} + + '@pagefind/linux-arm64@1.3.0': + resolution: {integrity: sha512-8lsxNAiBRUk72JvetSBXs4WRpYrQrVJXjlRRnOL6UCdBN9Nlsz0t7hWstRk36+JqHpGWOKYiuHLzGYqYAqoOnQ==} + cpu: [arm64] + os: [linux] + + '@pagefind/linux-x64@1.3.0': + resolution: {integrity: sha512-hAvqdPJv7A20Ucb6FQGE6jhjqy+vZ6pf+s2tFMNtMBG+fzcdc91uTw7aP/1Vo5plD0dAOHwdxfkyw0ugal4kcQ==} + cpu: [x64] + os: [linux] + + '@pagefind/windows-x64@1.3.0': + resolution: {integrity: sha512-BR1bIRWOMqkf8IoU576YDhij1Wd/Zf2kX/kCI0b2qzCKC8wcc2GQJaaRMCpzvCCrmliO4vtJ6RITp/AnoYUUmQ==} + cpu: [x64] + os: [win32] + + '@playwright/test@1.51.1': + resolution: {integrity: sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==} + engines: {node: '>=18'} + hasBin: true + + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.37.0': + resolution: {integrity: sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.37.0': + resolution: {integrity: sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.37.0': + resolution: {integrity: sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.37.0': + resolution: {integrity: sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.37.0': + resolution: {integrity: sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.37.0': + resolution: {integrity: sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.37.0': + resolution: {integrity: sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.37.0': + resolution: {integrity: sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.37.0': + resolution: {integrity: sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.37.0': + resolution: {integrity: sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.37.0': + resolution: {integrity: sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.37.0': + resolution: {integrity: sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.37.0': + resolution: {integrity: sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.37.0': + resolution: {integrity: sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.37.0': + resolution: {integrity: sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.37.0': + resolution: {integrity: sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.37.0': + resolution: {integrity: sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.37.0': + resolution: {integrity: sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.37.0': + resolution: {integrity: sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.37.0': + resolution: {integrity: sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==} + cpu: [x64] + os: [win32] + + '@shikijs/core@1.29.2': + resolution: {integrity: sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ==} + + '@shikijs/core@3.2.1': + resolution: {integrity: sha512-FhsdxMWYu/C11sFisEp7FMGBtX/OSSbnXZDMBhGuUDBNTdsoZlMSgQv5f90rwvzWAdWIW6VobD+G3IrazxA6dQ==} + + '@shikijs/engine-javascript@1.29.2': + resolution: {integrity: sha512-iNEZv4IrLYPv64Q6k7EPpOCE/nuvGiKl7zxdq0WFuRPF5PAE9PRo2JGq/d8crLusM59BRemJ4eOqrFrC4wiQ+A==} + + '@shikijs/engine-javascript@3.2.1': + resolution: {integrity: sha512-eMdcUzN3FMQYxOmRf2rmU8frikzoSHbQDFH2hIuXsrMO+IBOCI9BeeRkCiBkcLDHeRKbOCtYMJK3D6U32ooU9Q==} + + '@shikijs/engine-oniguruma@1.29.2': + resolution: {integrity: sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==} + + '@shikijs/engine-oniguruma@3.2.1': + resolution: {integrity: sha512-wZZAkayEn6qu2+YjenEoFqj0OyQI64EWsNR6/71d1EkG4sxEOFooowKivsWPpaWNBu3sxAG+zPz5kzBL/SsreQ==} + + '@shikijs/langs@1.29.2': + resolution: {integrity: sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ==} + + '@shikijs/langs@3.2.1': + resolution: {integrity: sha512-If0iDHYRSGbihiA8+7uRsgb1er1Yj11pwpX1c6HLYnizDsKAw5iaT3JXj5ZpaimXSWky/IhxTm7C6nkiYVym+A==} + + '@shikijs/themes@1.29.2': + resolution: {integrity: sha512-i9TNZlsq4uoyqSbluIcZkmPL9Bfi3djVxRnofUHwvx/h6SRW3cwgBC5SML7vsDcWyukY0eCzVN980rqP6qNl9g==} + + '@shikijs/themes@3.2.1': + resolution: {integrity: sha512-k5DKJUT8IldBvAm8WcrDT5+7GA7se6lLksR+2E3SvyqGTyFMzU2F9Gb7rmD+t+Pga1MKrYFxDIeyWjMZWM6uBQ==} + + '@shikijs/types@1.29.2': + resolution: {integrity: sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==} + + '@shikijs/types@3.2.1': + resolution: {integrity: sha512-/NTWAk4KE2M8uac0RhOsIhYQf4pdU0OywQuYDGIGAJ6Mjunxl2cGiuLkvu4HLCMn+OTTLRWkjZITp+aYJv60yA==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + + '@types/node@17.0.45': + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + + '@types/node@18.19.83': + resolution: {integrity: sha512-D69JeR5SfFS5H6FLbUaS0vE4r1dGhmMBbG4Ed6BNS4wkDK8GZjsdCShT5LCN59vOHEUHnFCY9J4aclXlIphMkA==} + + '@types/node@20.16.10': + resolution: {integrity: sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==} + + '@types/picomatch@3.0.2': + resolution: {integrity: sha512-n0i8TD3UDB7paoMMxA3Y65vUncFJXjcUf7lQY7YyKGl6031FNjfsLs6pdLFCy2GNFxItPJG8GvvpbZc2skH7WA==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@volar/kit@2.4.12': + resolution: {integrity: sha512-f9JE8oy9C2rBcCWxUYKUF23hOXz4mwgVXFjk7nHhxzplaoVjEOsKpBm8NI2nBH7Cwu8DRxDwBsbIxMl/8wlLxw==} + peerDependencies: + typescript: '*' + + '@volar/language-core@2.4.12': + resolution: {integrity: sha512-RLrFdXEaQBWfSnYGVxvR2WrO6Bub0unkdHYIdC31HzIEqATIuuhRRzYu76iGPZ6OtA4Au1SnW0ZwIqPP217YhA==} + + '@volar/language-server@2.4.12': + resolution: {integrity: sha512-KC0YqTXCZMaImMWyAKC+dLB2BXjfz80kqesJkV6oXxJsGEQPfmdqug299idwtrT6FVSmZ7q5UrPfvgKwA0S3JA==} + + '@volar/language-service@2.4.12': + resolution: {integrity: sha512-nifOPGYYPnCmxja6/ML/Gl2EgFkUdw4gLbYqbh8FjqX3gSpXSZl/0ebqORjKo1KW56YWHWRZd1jFutEtCiRYhA==} + + '@volar/source-map@2.4.12': + resolution: {integrity: sha512-bUFIKvn2U0AWojOaqf63ER0N/iHIBYZPpNGogfLPQ68F5Eet6FnLlyho7BS0y2HJ1jFhSif7AcuTx1TqsCzRzw==} + + '@volar/typescript@2.4.12': + resolution: {integrity: sha512-HJB73OTJDgPc80K30wxi3if4fSsZZAOScbj2fcicMuOPoOkcf9NNAINb33o+DzhBdF9xTKC1gnPmIRDous5S0g==} + + '@vscode/emmet-helper@2.11.0': + resolution: {integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==} + + '@vscode/l10n@0.0.18': + resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + + array-timsort@1.0.3: + resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + astro-auto-import@0.4.4: + resolution: {integrity: sha512-tiYe1hp+VusdiyaD3INgZgbvXEPamDFiURnQR5Niz+E9fWa6IHYjJ99TwGlHh/evfaXE/U/86jp9MRKWTuJU1A==} + engines: {node: '>=16.0.0'} + peerDependencies: + astro: ^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta + + astro-embed@0.9.0: + resolution: {integrity: sha512-koBCZH8n1q7tyXW+s11mdwb5dFsv9kG8uMuF17CUIVFJWqwRxx7YCpa9o2P9PuPeWffsrwmdVJTl65kLLP2Uug==} + peerDependencies: + astro: ^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta + + astro-expressive-code@0.40.2: + resolution: {integrity: sha512-yJMQId0yXSAbW9I6yqvJ3FcjKzJ8zRL7elbJbllkv1ZJPlsI0NI83Pxn1YL1IapEM347EvOOkSW2GL+2+NO61w==} + peerDependencies: + astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 + + astro@5.5.5: + resolution: {integrity: sha512-fdnnK5dhWNIQT/cXzvaGs9il4T5noi4jafobdntbuNOrRxI1JnOxDfrtBadUo6cknCRCFhYrXh4VndCqj1a4Sg==} + engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + + await-lock@2.2.2: + resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + base-64@1.0.0: + resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + + bcp-47-match@2.0.3: + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + + bcp-47@2.1.0: + resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@8.0.1: + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} + engines: {node: '>=18'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk-template@1.1.0: + resolution: {integrity: sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==} + engines: {node: '>=14.16'} + + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + ci-info@4.2.0: + resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} + engines: {node: '>=8'} + + clear-module@4.1.2: + resolution: {integrity: sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==} + engines: {node: '>=8'} + + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + comment-json@4.2.5: + resolution: {integrity: sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==} + engines: {node: '>= 6'} + + common-ancestor-path@1.0.1: + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + crossws@0.3.4: + resolution: {integrity: sha512-uj0O1ETYX1Bh6uSgktfPvwDiPYGQ3aI4qVsaC/LWpkIzGj1nUYm5FK3K+t11oOlpN01lGbprFCH4wBlKdJjVgw==} + + cspell-config-lib@8.17.5: + resolution: {integrity: sha512-XDc+UJO5RZ9S9e2Ajz332XjT7dv6Og2UqCiSnAlvHt7t/MacLHSPARZFIivheObNkWZ7E1iWI681RxKoH4o40w==} + engines: {node: '>=18'} + + cspell-dictionary@8.17.5: + resolution: {integrity: sha512-O/Uuhv1RuDu+5WYQml0surudweaTvr+2YJSmPSdlihByUSiogCbpGqwrRow7wQv/C5p1W1FlFjotvUfoR0fxHA==} + engines: {node: '>=18'} + + cspell-gitignore@8.17.5: + resolution: {integrity: sha512-I27fgOUZzH14jeIYo65LooB60fZ42f6OJL1lOR9Mk6IrIlDyUtzherGR+xx5KshK2katYkX42Qu4zsVYM6VFPA==} + engines: {node: '>=18'} + hasBin: true + + cspell-glob@8.17.5: + resolution: {integrity: sha512-OXquou7UykInlGV5et5lNKYYrW0dwa28aEF995x1ocANND7o0bbHmFlbgyci/Lp4uFQai8sifmfFJbuIg2IC/A==} + engines: {node: '>=18'} + + cspell-grammar@8.17.5: + resolution: {integrity: sha512-st2n+FVw25MvMbsGb3TeJNRr6Oih4g14rjOd/UJN0qn+ceH360SAShUFqSd4kHHu2ADazI/TESFU6FRtMTPNOg==} + engines: {node: '>=18'} + hasBin: true + + cspell-io@8.17.5: + resolution: {integrity: sha512-oevM/8l0s6nc1NCYPqNFumrW50QSHoa6wqUT8cWs09gtZdE2AWG0U6bIE8ZEVz6e6FxS+6IenGKTdUUwP0+3fg==} + engines: {node: '>=18'} + + cspell-lib@8.17.5: + resolution: {integrity: sha512-S3KuOrcST1d2BYmTXA+hnbRdho5n3w5GUvEaCx3QZQBwAPfLpAwJbe2yig1TxBpyEJ5LqP02i/mDg1pUCOP0hQ==} + engines: {node: '>=18'} + + cspell-trie-lib@8.17.5: + resolution: {integrity: sha512-9hjI3nRQxtGEua6CgnLbK3sGHLx9dXR/BHwI/csRL4dN5GGRkE5X3CCoy1RJVL7iGFLIzi43+L10xeFRmWniKw==} + engines: {node: '>=18'} + + cspell@8.17.5: + resolution: {integrity: sha512-l3Cfp87d7Yrodem675irdxV6+7+OsdR+jNwYHe33Dgnd6ePEfooYrvmfGdXF9rlQrNLUQp/HqYgHJzSq19UEsg==} + engines: {node: '>=18'} + hasBin: true + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-selector-parser@1.4.1: + resolution: {integrity: sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==} + + css-selector-parser@3.1.1: + resolution: {integrity: sha512-Y+DuvJ7JAjpL1f4DeILe5sXCC3kRXMl0DxM4lAWbS8/jEZ29o3V0L5TL6zIifj4Csmj6c+jiF2ENjida2OVOGA==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.1.0: + resolution: {integrity: sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + deterministic-object-hash@2.0.2: + resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} + engines: {node: '>=18'} + + devalue@5.1.1: + resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + + direction@2.0.1: + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} + hasBin: true + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dset@3.1.4: + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} + engines: {node: '>=4'} + + emmet@2.4.11: + resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild@0.25.1: + resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + expressive-code@0.40.2: + resolution: {integrity: sha512-1zIda2rB0qiDZACawzw2rbdBQiWHBT56uBctS+ezFe5XMAaFaHLnnSYND/Kd+dVzO9HfCXRDpzH3d+3fvOWRcw==} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-equals@5.2.2: + resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==} + engines: {node: '>=6.0.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@9.1.0: + resolution: {integrity: sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==} + engines: {node: '>=18'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + flat-cache@5.0.0: + resolution: {integrity: sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==} + engines: {node: '>=18'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gensequence@7.0.0: + resolution: {integrity: sha512-47Frx13aZh01afHJTB3zTtKIlFI6vWY+MYCN9Qpew6i52rfKjnhCF/l1YlC8UmEMvvntZZ6z4PiCcmyuedR2aQ==} + engines: {node: '>=18'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.3.0: + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + engines: {node: '>=18'} + + get-stdin@9.0.0: + resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} + engines: {node: '>=12'} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + h3@1.15.1: + resolution: {integrity: sha512-+ORaOBttdUm1E2Uu/obAyCguiI7MbBvsLTndc3gyK3zU+SYLoZXlyCP9Xgy0gikkGufFLTZXCXD6+4BsufnmHA==} + + has-own-prop@2.0.0: + resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} + engines: {node: '>=8'} + + hast-util-embedded@3.0.0: + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + + hast-util-format@1.1.0: + resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} + + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + + hast-util-is-body-ok-link@3.0.1: + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-minify-whitespace@1.0.1: + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-phrasing@3.0.1: + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-select@6.0.4: + resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.0: + resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-whitespace-sensitive-tag-names@3.0.1: + resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + i18next@23.16.8: + resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-absolute-url@4.0.1: + resolution: {integrity: sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + iso-datestring-validator@2.2.2: + resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + jsonc-parser@2.3.1: + resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + + linkedom@0.14.26: + resolution: {integrity: sha512-mK6TrydfFA7phrnp+1j57ycBwFI5bGSW6YXlw9acHoqF+mP/y+FooEYYyniOt5Ot57FSKB3iwmnuQ1UUyNLm5A==} + + lite-youtube-embed@0.3.3: + resolution: {integrity: sha512-gFfVVnj6NRjxVfJKo3qoLtpi0v5mn3AcR4eKD45wrxQuxzveFJUb+7Cr6uV6n+DjO8X3p0UzPPquhGt0H/y+NA==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + mdast-util-definitions@6.0.0: + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + neotraverse@0.6.18: + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} + engines: {node: '>= 10'} + + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + + node-fetch-native@1.6.6: + resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} + + node-mock-http@1.0.0: + resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + + oniguruma-parser@0.5.4: + resolution: {integrity: sha512-yNxcQ8sKvURiTwP0mV6bLQCYE7NKfKRRWunhbZnXgxSmB1OXa1lHrN3o4DZd+0Si0kU5blidK7BcROO8qv5TZA==} + + oniguruma-to-es@2.3.0: + resolution: {integrity: sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==} + + oniguruma-to-es@4.1.0: + resolution: {integrity: sha512-SNwG909cSLo4vPyyPbU/VJkEc9WOXqu2ycBlfd1UCXLqk1IijcQktSBb2yRQ2UFPsDhpkaf+C1dtT3PkLK/yWA==} + + p-limit@6.2.0: + resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} + engines: {node: '>=18'} + + p-queue@8.1.0: + resolution: {integrity: sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==} + engines: {node: '>=18'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + package-manager-detector@1.1.0: + resolution: {integrity: sha512-Y8f9qUlBzW8qauJjd/eu6jlpJZsuPJm2ZAV0cDVd420o4EdpH5RPdoCv+60/TdJflGatr4sDfpAL6ArWZbM5tA==} + + pagefind@1.3.0: + resolution: {integrity: sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw==} + hasBin: true + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parent-module@2.0.0: + resolution: {integrity: sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==} + engines: {node: '>=8'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + playwright-core@1.51.1: + resolution: {integrity: sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==} + engines: {node: '>=18'} + hasBin: true + + playwright-ctrf-json-reporter@0.0.19: + resolution: {integrity: sha512-mUjqQJ8hxHj0Blb+8hn3dVFNb2zGSFF/iB+sQZYzKEM7puaJVbMrpaCdD0rCKKZc9lU1omggz5MLHlPKrL7XBA==} + + playwright@1.51.1: + resolution: {integrity: sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==} + engines: {node: '>=18'} + hasBin: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + prettier@2.8.7: + resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==} + engines: {node: '>=10.13.0'} + hasBin: true + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + property-information@7.0.0: + resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.0: + resolution: {integrity: sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==} + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regex-recursion@5.1.1: + resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@5.1.1: + resolution: {integrity: sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==} + + regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + + rehype-expressive-code@0.40.2: + resolution: {integrity: sha512-+kn+AMGCrGzvtH8Q5lC6Y5lnmTV/r33fdmi5QU/IH1KPHKobKr5UnLwJuqHv5jBTSN/0v2wLDS7RTM73FVzqmQ==} + + rehype-external-links@3.0.0: + resolution: {integrity: sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==} + + rehype-format@5.0.1: + resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} + + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + rehype-stringify@10.0.1: + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + + rehype@13.0.2: + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.0: + resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.1: + resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==} + + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + request-light@0.5.8: + resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==} + + request-light@0.7.0: + resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.37.0: + resolution: {integrity: sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shiki@1.29.2: + resolution: {integrity: sha512-njXuliz/cP+67jU2hukkxCNuH1yUi4QfdZZY+sMr5PPrIyXSu5iTb/qYC4BiWWB0vZ+7TbdvYUCeL23zpwCfbg==} + + shiki@3.2.1: + resolution: {integrity: sha512-VML/2o1/KGYkEf/stJJ+s9Ypn7jUKQPomGLGYso4JJFMFxVDyPNsjsI3MB3KLjlMOeH44gyaPdXC6rik2WXvUQ==} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + sitemap@8.0.0: + resolution: {integrity: sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==} + engines: {node: '>=14.0.0', npm: '>=6.0.0'} + hasBin: true + + smol-toml@1.3.1: + resolution: {integrity: sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==} + engines: {node: '>= 18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + starlight-links-validator@0.14.3: + resolution: {integrity: sha512-2CvQs0ZdIVExrEQ1bn0r2aFx4n+VSOb6vDWK+gTNb5N1c+nXJ7VjUbEsQhj+9Lb7XgY6Nxqz9JXUM9364hJ3ZA==} + engines: {node: '>=18.17.1'} + peerDependencies: + '@astrojs/starlight': '>=0.15.0' + + stream-replace-string@2.0.0: + resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + style-to-js@1.1.16: + resolution: {integrity: sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==} + + style-to-object@1.0.8: + resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + + tlds@1.256.0: + resolution: {integrity: sha512-ZmyVB9DAw+FFTmLElGYJgdZFsKLYd/I59Bg9NHkCGPwAbVZNRilFWDMAdX8UG+bHuv7kfursd5XGqo/9wi26lA==} + hasBin: true + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-pattern@5.6.2: + resolution: {integrity: sha512-d4IxJUXROL5NCa3amvMg6VQW2HVtZYmUTPfvVtO7zJWGYLJ+mry9v2OmYm+z67aniQoQ8/yFNadiEwtNS9qQiw==} + + tsconfck@3.1.5: + resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-fest@4.38.0: + resolution: {integrity: sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==} + engines: {node: '>=16'} + + typesafe-path@0.2.2: + resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==} + + typescript-auto-import-cache@0.3.5: + resolution: {integrity: sha512-fAIveQKsoYj55CozUiBoj4b/7WpN0i4o74wiGY5JVUEoD0XiqDk1tJqTEjgzL2/AizKQrXxyRosSebyDzBZKjw==} + + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + uhyphen@0.2.0: + resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} + + uint8arrays@3.0.0: + resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==} + + ultrahtml@1.5.3: + resolution: {integrity: sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-select@4.0.3: + resolution: {integrity: sha512-1074+K9VyR3NyUz3lgNtHKm7ln+jSZXtLJM4E22uVuoFn88a/Go2pX8dusrt/W+KWH1ncn8jcd8uCQuvXb/fXA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + unstorage@1.15.0: + resolution: {integrity: sha512-m40eHdGY/gA6xAPqo8eaxqXgBuzQTlAKfmB1iF7oCKXE1HfwHwzDJBywK+qQGn52dta+bPlZluPF7++yR3p/bg==} + 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.0.3 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/kv': ^1.0.1 + 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/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@6.2.3: + resolution: {integrity: sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + 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 + + vitefu@1.0.6: + resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + vite: + optional: true + + volar-service-css@0.0.62: + resolution: {integrity: sha512-JwNyKsH3F8PuzZYuqPf+2e+4CTU8YoyUHEHVnoXNlrLe7wy9U3biomZ56llN69Ris7TTy/+DEX41yVxQpM4qvg==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-emmet@0.0.62: + resolution: {integrity: sha512-U4dxWDBWz7Pi4plpbXf4J4Z/ss6kBO3TYrACxWNsE29abu75QzVS0paxDDhI6bhqpbDFXlpsDhZ9aXVFpnfGRQ==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-html@0.0.62: + resolution: {integrity: sha512-Zw01aJsZRh4GTGUjveyfEzEqpULQUdQH79KNEiKVYHZyuGtdBRYCHlrus1sueSNMxwwkuF5WnOHfvBzafs8yyQ==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-prettier@0.0.62: + resolution: {integrity: sha512-h2yk1RqRTE+vkYZaI9KYuwpDfOQRrTEMvoHol0yW4GFKc75wWQRrb5n/5abDrzMPrkQbSip8JH2AXbvrRtYh4w==} + peerDependencies: + '@volar/language-service': ~2.4.0 + prettier: ^2.2 || ^3.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + prettier: + optional: true + + volar-service-typescript-twoslash-queries@0.0.62: + resolution: {integrity: sha512-KxFt4zydyJYYI0kFAcWPTh4u0Ha36TASPZkAnNY784GtgajerUqM80nX/W1d0wVhmcOFfAxkVsf/Ed+tiYU7ng==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-typescript@0.0.62: + resolution: {integrity: sha512-p7MPi71q7KOsH0eAbZwPBiKPp9B2+qrdHAd6VY5oTo9BUXatsOAdakTm9Yf0DUj6uWBAaOT01BSeVOPwucMV1g==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-yaml@0.0.62: + resolution: {integrity: sha512-k7gvv7sk3wa+nGll3MaSKyjwQsJjIGCHFjVkl3wjaSP2nouKyn9aokGmqjrl39mi88Oy49giog2GkZH526wjig==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + vscode-css-languageservice@6.3.3: + resolution: {integrity: sha512-xXa+ftMPv6JxRgzkvPwZuDCafIdwDW3kyijGcfij1a2qBVScr2qli6MfgJzYm/AMYdbHq9I/4hdpKV0Thim2EA==} + + vscode-html-languageservice@5.3.3: + resolution: {integrity: sha512-AK/jJM0VIWRrlfqkDBMZxNMnxYT5I2uoMVRoNJ5ePSplnSaT9mbYjqJlxxeLvUrOW7MEH0vVIDzU48u44QZE0w==} + + vscode-json-languageservice@4.1.8: + resolution: {integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==} + engines: {npm: '>=7.0.0'} + + vscode-jsonrpc@6.0.0: + resolution: {integrity: sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==} + engines: {node: '>=8.0.0 || >=10.0.0'} + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.16.0: + resolution: {integrity: sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.16.0: + resolution: {integrity: sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@7.0.0: + resolution: {integrity: sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==} + hasBin: true + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-nls@5.2.0: + resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==} + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + which-pm-runs@1.1.0: + resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} + engines: {node: '>=4'} + + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml-language-server@1.15.0: + resolution: {integrity: sha512-N47AqBDCMQmh6mBLmI6oqxryHRzi33aPFPsJhYy3VTUGCdLHYjGh4FZzpUjRlphaADBBkDmnkM/++KNIOHi5Rw==} + hasBin: true + + yaml@2.2.2: + resolution: {integrity: sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==} + engines: {node: '>= 14'} + + yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@1.2.1: + resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} + engines: {node: '>=12.20'} + + yocto-spinner@0.2.1: + resolution: {integrity: sha512-lHHxjh0bXaLgdJy3cNnVb/F9myx3CkhrvSOEVTkaUgNMXnYFa2xYPVhtGnqhh3jErY2gParBOHallCbc7NrlZQ==} + engines: {node: '>=18.19'} + + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + + zod-to-json-schema@3.24.5: + resolution: {integrity: sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==} + peerDependencies: + zod: ^3.24.1 + + zod-to-ts@1.2.0: + resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} + peerDependencies: + typescript: ^4.9.4 || ^5.0.2 + zod: ^3 + + zod@3.24.2: + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@astro-community/astro-embed-baseline-status@0.1.2(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))': + dependencies: + '@astro-community/astro-embed-utils': 0.1.3 + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + + '@astro-community/astro-embed-bluesky@0.1.3(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))': + dependencies: + '@atproto/api': 0.13.35 + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + ts-pattern: 5.6.2 + + '@astro-community/astro-embed-integration@0.8.1(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))': + dependencies: + '@astro-community/astro-embed-bluesky': 0.1.3(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@astro-community/astro-embed-link-preview': 0.2.2 + '@astro-community/astro-embed-twitter': 0.5.8(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@astro-community/astro-embed-vimeo': 0.3.10(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@astro-community/astro-embed-youtube': 0.5.6(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@types/unist': 2.0.11 + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + astro-auto-import: 0.4.4(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + unist-util-select: 4.0.3 + + '@astro-community/astro-embed-link-preview@0.2.2': + dependencies: + '@astro-community/astro-embed-utils': 0.1.3 + + '@astro-community/astro-embed-twitter@0.5.8(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))': + dependencies: + '@astro-community/astro-embed-utils': 0.1.3 + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + + '@astro-community/astro-embed-utils@0.1.3': + dependencies: + linkedom: 0.14.26 + + '@astro-community/astro-embed-vimeo@0.3.10(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))': + dependencies: + '@astro-community/astro-embed-utils': 0.1.3 + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + + '@astro-community/astro-embed-youtube@0.5.6(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))': + dependencies: + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + lite-youtube-embed: 0.3.3 + + '@astrojs/check@0.9.4(typescript@5.8.2)': + dependencies: + '@astrojs/language-server': 2.15.4(typescript@5.8.2) + chokidar: 4.0.3 + kleur: 4.1.5 + typescript: 5.8.2 + yargs: 17.7.2 + transitivePeerDependencies: + - prettier + - prettier-plugin-astro + + '@astrojs/compiler@2.11.0': {} + + '@astrojs/internal-helpers@0.6.1': {} + + '@astrojs/language-server@2.15.4(typescript@5.8.2)': + dependencies: + '@astrojs/compiler': 2.11.0 + '@astrojs/yaml2ts': 0.2.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@volar/kit': 2.4.12(typescript@5.8.2) + '@volar/language-core': 2.4.12 + '@volar/language-server': 2.4.12 + '@volar/language-service': 2.4.12 + fast-glob: 3.3.3 + muggle-string: 0.4.1 + volar-service-css: 0.0.62(@volar/language-service@2.4.12) + volar-service-emmet: 0.0.62(@volar/language-service@2.4.12) + volar-service-html: 0.0.62(@volar/language-service@2.4.12) + volar-service-prettier: 0.0.62(@volar/language-service@2.4.12) + volar-service-typescript: 0.0.62(@volar/language-service@2.4.12) + volar-service-typescript-twoslash-queries: 0.0.62(@volar/language-service@2.4.12) + volar-service-yaml: 0.0.62(@volar/language-service@2.4.12) + vscode-html-languageservice: 5.3.3 + vscode-uri: 3.1.0 + transitivePeerDependencies: + - typescript + + '@astrojs/markdown-remark@6.3.1': + dependencies: + '@astrojs/internal-helpers': 0.6.1 + '@astrojs/prism': 3.2.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.1.0 + js-yaml: 4.1.0 + 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.1 + remark-smartypants: 3.0.2 + shiki: 3.2.1 + smol-toml: 1.3.1 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.1 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/mdx@4.2.2(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))': + dependencies: + '@astrojs/markdown-remark': 6.3.1 + '@mdx-js/mdx': 3.1.0(acorn@8.14.1) + acorn: 8.14.1 + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + es-module-lexer: 1.6.0 + estree-util-visit: 2.0.0 + hast-util-to-html: 9.0.5 + kleur: 4.1.5 + rehype-raw: 7.0.0 + remark-gfm: 4.0.1 + remark-smartypants: 3.0.2 + source-map: 0.7.4 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/prism@3.2.0': + dependencies: + prismjs: 1.30.0 + + '@astrojs/sitemap@3.3.0': + dependencies: + sitemap: 8.0.0 + stream-replace-string: 2.0.0 + zod: 3.24.2 + + '@astrojs/starlight@0.32.4(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))': + dependencies: + '@astrojs/mdx': 4.2.2(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@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: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + astro-expressive-code: 0.40.2(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + bcp-47: 2.1.0 + hast-util-from-html: 2.0.3 + hast-util-select: 6.0.4 + hast-util-to-string: 3.0.1 + hastscript: 9.0.1 + i18next: 23.16.8 + js-yaml: 4.1.0 + klona: 2.0.6 + mdast-util-directive: 3.1.0 + mdast-util-to-markdown: 2.1.2 + mdast-util-to-string: 4.0.0 + pagefind: 1.3.0 + rehype: 13.0.2 + rehype-format: 5.0.1 + remark-directive: 3.0.1 + unified: 11.0.5 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/telemetry@3.2.0': + 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 + transitivePeerDependencies: + - supports-color + + '@astrojs/yaml2ts@0.2.2': + dependencies: + yaml: 2.7.0 + + '@atproto/api@0.13.35': + dependencies: + '@atproto/common-web': 0.4.0 + '@atproto/lexicon': 0.4.9 + '@atproto/syntax': 0.3.4 + '@atproto/xrpc': 0.6.11 + await-lock: 2.2.2 + multiformats: 9.9.0 + tlds: 1.256.0 + zod: 3.24.2 + + '@atproto/common-web@0.4.0': + dependencies: + graphemer: 1.4.0 + multiformats: 9.9.0 + uint8arrays: 3.0.0 + zod: 3.24.2 + + '@atproto/lexicon@0.4.9': + dependencies: + '@atproto/common-web': 0.4.0 + '@atproto/syntax': 0.4.0 + iso-datestring-validator: 2.2.2 + multiformats: 9.9.0 + zod: 3.24.2 + + '@atproto/syntax@0.3.4': {} + + '@atproto/syntax@0.4.0': {} + + '@atproto/xrpc@0.6.11': + dependencies: + '@atproto/lexicon': 0.4.9 + zod: 3.24.2 + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.27.0': + dependencies: + '@babel/types': 7.27.0 + + '@babel/runtime@7.27.0': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/types@7.27.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@biomejs/biome@1.9.4': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 + + '@biomejs/cli-darwin-arm64@1.9.4': + optional: true + + '@biomejs/cli-darwin-x64@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64@1.9.4': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-x64@1.9.4': + optional: true + + '@biomejs/cli-win32-arm64@1.9.4': + optional: true + + '@biomejs/cli-win32-x64@1.9.4': + optional: true + + '@cspell/cspell-bundled-dicts@8.17.5': + dependencies: + '@cspell/dict-ada': 4.1.0 + '@cspell/dict-al': 1.1.0 + '@cspell/dict-aws': 4.0.9 + '@cspell/dict-bash': 4.2.0 + '@cspell/dict-companies': 3.1.14 + '@cspell/dict-cpp': 6.0.6 + '@cspell/dict-cryptocurrencies': 5.0.4 + '@cspell/dict-csharp': 4.0.6 + '@cspell/dict-css': 4.0.17 + '@cspell/dict-dart': 2.3.0 + '@cspell/dict-data-science': 2.0.7 + '@cspell/dict-django': 4.1.4 + '@cspell/dict-docker': 1.1.12 + '@cspell/dict-dotnet': 5.0.9 + '@cspell/dict-elixir': 4.0.7 + '@cspell/dict-en-common-misspellings': 2.0.10 + '@cspell/dict-en-gb': 1.1.33 + '@cspell/dict-en_us': 4.3.35 + '@cspell/dict-filetypes': 3.0.11 + '@cspell/dict-flutter': 1.1.0 + '@cspell/dict-fonts': 4.0.4 + '@cspell/dict-fsharp': 1.1.0 + '@cspell/dict-fullstack': 3.2.6 + '@cspell/dict-gaming-terms': 1.1.0 + '@cspell/dict-git': 3.0.4 + '@cspell/dict-golang': 6.0.19 + '@cspell/dict-google': 1.0.8 + '@cspell/dict-haskell': 4.0.5 + '@cspell/dict-html': 4.0.11 + '@cspell/dict-html-symbol-entities': 4.0.3 + '@cspell/dict-java': 5.0.11 + '@cspell/dict-julia': 1.1.0 + '@cspell/dict-k8s': 1.0.10 + '@cspell/dict-kotlin': 1.1.0 + '@cspell/dict-latex': 4.0.3 + '@cspell/dict-lorem-ipsum': 4.0.4 + '@cspell/dict-lua': 4.0.7 + '@cspell/dict-makefile': 1.0.4 + '@cspell/dict-markdown': 2.0.9(@cspell/dict-css@4.0.17)(@cspell/dict-html-symbol-entities@4.0.3)(@cspell/dict-html@4.0.11)(@cspell/dict-typescript@3.2.0) + '@cspell/dict-monkeyc': 1.0.10 + '@cspell/dict-node': 5.0.6 + '@cspell/dict-npm': 5.1.31 + '@cspell/dict-php': 4.0.14 + '@cspell/dict-powershell': 5.0.14 + '@cspell/dict-public-licenses': 2.0.13 + '@cspell/dict-python': 4.2.16 + '@cspell/dict-r': 2.1.0 + '@cspell/dict-ruby': 5.0.8 + '@cspell/dict-rust': 4.0.11 + '@cspell/dict-scala': 5.0.7 + '@cspell/dict-shell': 1.1.0 + '@cspell/dict-software-terms': 4.2.5 + '@cspell/dict-sql': 2.2.0 + '@cspell/dict-svelte': 1.0.6 + '@cspell/dict-swift': 2.0.5 + '@cspell/dict-terraform': 1.1.1 + '@cspell/dict-typescript': 3.2.0 + '@cspell/dict-vue': 3.0.4 + + '@cspell/cspell-json-reporter@8.17.5': + dependencies: + '@cspell/cspell-types': 8.17.5 + + '@cspell/cspell-pipe@8.17.5': {} + + '@cspell/cspell-resolver@8.17.5': + dependencies: + global-directory: 4.0.1 + + '@cspell/cspell-service-bus@8.17.5': {} + + '@cspell/cspell-types@8.17.5': {} + + '@cspell/dict-ada@4.1.0': {} + + '@cspell/dict-al@1.1.0': {} + + '@cspell/dict-aws@4.0.9': {} + + '@cspell/dict-bash@4.2.0': + dependencies: + '@cspell/dict-shell': 1.1.0 + + '@cspell/dict-companies@3.1.14': {} + + '@cspell/dict-cpp@6.0.6': {} + + '@cspell/dict-cryptocurrencies@5.0.4': {} + + '@cspell/dict-csharp@4.0.6': {} + + '@cspell/dict-css@4.0.17': {} + + '@cspell/dict-dart@2.3.0': {} + + '@cspell/dict-data-science@2.0.7': {} + + '@cspell/dict-django@4.1.4': {} + + '@cspell/dict-docker@1.1.12': {} + + '@cspell/dict-dotnet@5.0.9': {} + + '@cspell/dict-elixir@4.0.7': {} + + '@cspell/dict-en-common-misspellings@2.0.10': {} + + '@cspell/dict-en-gb@1.1.33': {} + + '@cspell/dict-en_us@4.3.35': {} + + '@cspell/dict-filetypes@3.0.11': {} + + '@cspell/dict-flutter@1.1.0': {} + + '@cspell/dict-fonts@4.0.4': {} + + '@cspell/dict-fsharp@1.1.0': {} + + '@cspell/dict-fullstack@3.2.6': {} + + '@cspell/dict-gaming-terms@1.1.0': {} + + '@cspell/dict-git@3.0.4': {} + + '@cspell/dict-golang@6.0.19': {} + + '@cspell/dict-google@1.0.8': {} + + '@cspell/dict-haskell@4.0.5': {} + + '@cspell/dict-html-symbol-entities@4.0.3': {} + + '@cspell/dict-html@4.0.11': {} + + '@cspell/dict-java@5.0.11': {} + + '@cspell/dict-julia@1.1.0': {} + + '@cspell/dict-k8s@1.0.10': {} + + '@cspell/dict-kotlin@1.1.0': {} + + '@cspell/dict-latex@4.0.3': {} + + '@cspell/dict-lorem-ipsum@4.0.4': {} + + '@cspell/dict-lua@4.0.7': {} + + '@cspell/dict-makefile@1.0.4': {} + + '@cspell/dict-markdown@2.0.9(@cspell/dict-css@4.0.17)(@cspell/dict-html-symbol-entities@4.0.3)(@cspell/dict-html@4.0.11)(@cspell/dict-typescript@3.2.0)': + dependencies: + '@cspell/dict-css': 4.0.17 + '@cspell/dict-html': 4.0.11 + '@cspell/dict-html-symbol-entities': 4.0.3 + '@cspell/dict-typescript': 3.2.0 + + '@cspell/dict-monkeyc@1.0.10': {} + + '@cspell/dict-node@5.0.6': {} + + '@cspell/dict-npm@5.1.31': {} + + '@cspell/dict-php@4.0.14': {} + + '@cspell/dict-powershell@5.0.14': {} + + '@cspell/dict-public-licenses@2.0.13': {} + + '@cspell/dict-python@4.2.16': + dependencies: + '@cspell/dict-data-science': 2.0.7 + + '@cspell/dict-r@2.1.0': {} + + '@cspell/dict-ruby@5.0.8': {} + + '@cspell/dict-rust@4.0.11': {} + + '@cspell/dict-scala@5.0.7': {} + + '@cspell/dict-shell@1.1.0': {} + + '@cspell/dict-software-terms@4.2.5': {} + + '@cspell/dict-sql@2.2.0': {} + + '@cspell/dict-svelte@1.0.6': {} + + '@cspell/dict-swift@2.0.5': {} + + '@cspell/dict-terraform@1.1.1': {} + + '@cspell/dict-typescript@3.2.0': {} + + '@cspell/dict-vue@3.0.4': {} + + '@cspell/dynamic-import@8.17.5': + dependencies: + '@cspell/url': 8.17.5 + import-meta-resolve: 4.1.0 + + '@cspell/filetypes@8.17.5': {} + + '@cspell/strong-weak-map@8.17.5': {} + + '@cspell/url@8.17.5': {} + + '@ctrl/tinycolor@4.1.0': {} + + '@emmetio/abbreviation@2.3.3': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/css-abbreviation@2.1.8': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/css-parser@0.4.0': + dependencies: + '@emmetio/stream-reader': 2.2.0 + '@emmetio/stream-reader-utils': 0.1.0 + + '@emmetio/html-matcher@1.3.0': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/scanner@1.0.4': {} + + '@emmetio/stream-reader-utils@0.1.0': {} + + '@emmetio/stream-reader@2.2.0': {} + + '@emnapi/runtime@1.3.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.25.1': + optional: true + + '@esbuild/android-arm64@0.25.1': + optional: true + + '@esbuild/android-arm@0.25.1': + optional: true + + '@esbuild/android-x64@0.25.1': + optional: true + + '@esbuild/darwin-arm64@0.25.1': + optional: true + + '@esbuild/darwin-x64@0.25.1': + optional: true + + '@esbuild/freebsd-arm64@0.25.1': + optional: true + + '@esbuild/freebsd-x64@0.25.1': + optional: true + + '@esbuild/linux-arm64@0.25.1': + optional: true + + '@esbuild/linux-arm@0.25.1': + optional: true + + '@esbuild/linux-ia32@0.25.1': + optional: true + + '@esbuild/linux-loong64@0.25.1': + optional: true + + '@esbuild/linux-mips64el@0.25.1': + optional: true + + '@esbuild/linux-ppc64@0.25.1': + optional: true + + '@esbuild/linux-riscv64@0.25.1': + optional: true + + '@esbuild/linux-s390x@0.25.1': + optional: true + + '@esbuild/linux-x64@0.25.1': + optional: true + + '@esbuild/netbsd-arm64@0.25.1': + optional: true + + '@esbuild/netbsd-x64@0.25.1': + optional: true + + '@esbuild/openbsd-arm64@0.25.1': + optional: true + + '@esbuild/openbsd-x64@0.25.1': + optional: true + + '@esbuild/sunos-x64@0.25.1': + optional: true + + '@esbuild/win32-arm64@0.25.1': + optional: true + + '@esbuild/win32-ia32@0.25.1': + optional: true + + '@esbuild/win32-x64@0.25.1': + optional: true + + '@expressive-code/core@0.40.2': + dependencies: + '@ctrl/tinycolor': 4.1.0 + hast-util-select: 6.0.4 + hast-util-to-html: 9.0.5 + hast-util-to-text: 4.0.2 + hastscript: 9.0.1 + postcss: 8.5.3 + postcss-nested: 6.2.0(postcss@8.5.3) + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.1 + + '@expressive-code/plugin-frames@0.40.2': + dependencies: + '@expressive-code/core': 0.40.2 + + '@expressive-code/plugin-line-numbers@0.40.2': + dependencies: + '@expressive-code/core': 0.40.2 + + '@expressive-code/plugin-shiki@0.40.2': + dependencies: + '@expressive-code/core': 0.40.2 + shiki: 1.29.2 + + '@expressive-code/plugin-text-markers@0.40.2': + dependencies: + '@expressive-code/core': 0.40.2 + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.3.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@mdx-js/mdx@3.1.0(acorn@8.14.1)': + dependencies: + '@types/estree': 1.0.7 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.0(acorn@8.14.1) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.0 + remark-parse: 11.0.0 + remark-rehype: 11.1.1 + source-map: 0.7.4 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - acorn + - supports-color + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@oslojs/encoding@1.1.0': {} + + '@pagefind/darwin-arm64@1.3.0': + optional: true + + '@pagefind/darwin-x64@1.3.0': + optional: true + + '@pagefind/default-ui@1.3.0': {} + + '@pagefind/linux-arm64@1.3.0': + optional: true + + '@pagefind/linux-x64@1.3.0': + optional: true + + '@pagefind/windows-x64@1.3.0': + optional: true + + '@playwright/test@1.51.1': + dependencies: + playwright: 1.51.1 + + '@rollup/pluginutils@5.1.4(rollup@4.37.0)': + dependencies: + '@types/estree': 1.0.7 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.37.0 + + '@rollup/rollup-android-arm-eabi@4.37.0': + optional: true + + '@rollup/rollup-android-arm64@4.37.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.37.0': + optional: true + + '@rollup/rollup-darwin-x64@4.37.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.37.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.37.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.37.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.37.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.37.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.37.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.37.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.37.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.37.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.37.0': + optional: true + + '@shikijs/core@1.29.2': + dependencies: + '@shikijs/engine-javascript': 1.29.2 + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/core@3.2.1': + dependencies: + '@shikijs/types': 3.2.1 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 2.3.0 + + '@shikijs/engine-javascript@3.2.1': + dependencies: + '@shikijs/types': 3.2.1 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.1.0 + + '@shikijs/engine-oniguruma@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/engine-oniguruma@3.2.1': + dependencies: + '@shikijs/types': 3.2.1 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + + '@shikijs/langs@3.2.1': + dependencies: + '@shikijs/types': 3.2.1 + + '@shikijs/themes@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + + '@shikijs/themes@3.2.1': + dependencies: + '@shikijs/types': 3.2.1 + + '@shikijs/types@1.29.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/types@3.2.1': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.7 + + '@types/estree@1.0.6': {} + + '@types/estree@1.0.7': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/js-yaml@4.0.9': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + + '@types/node@17.0.45': {} + + '@types/node@18.19.83': + dependencies: + undici-types: 5.26.5 + + '@types/node@20.16.10': + dependencies: + undici-types: 6.19.8 + + '@types/picomatch@3.0.2': {} + + '@types/sax@1.2.7': + dependencies: + '@types/node': 20.16.10 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.3.0': {} + + '@volar/kit@2.4.12(typescript@5.8.2)': + dependencies: + '@volar/language-service': 2.4.12 + '@volar/typescript': 2.4.12 + typesafe-path: 0.2.2 + typescript: 5.8.2 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + '@volar/language-core@2.4.12': + dependencies: + '@volar/source-map': 2.4.12 + + '@volar/language-server@2.4.12': + dependencies: + '@volar/language-core': 2.4.12 + '@volar/language-service': 2.4.12 + '@volar/typescript': 2.4.12 + path-browserify: 1.0.1 + request-light: 0.7.0 + vscode-languageserver: 9.0.1 + vscode-languageserver-protocol: 3.17.5 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + '@volar/language-service@2.4.12': + dependencies: + '@volar/language-core': 2.4.12 + vscode-languageserver-protocol: 3.17.5 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + '@volar/source-map@2.4.12': {} + + '@volar/typescript@2.4.12': + dependencies: + '@volar/language-core': 2.4.12 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vscode/emmet-helper@2.11.0': + dependencies: + emmet: 2.4.11 + jsonc-parser: 2.3.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-uri: 3.1.0 + + '@vscode/l10n@0.0.18': {} + + acorn-jsx@5.3.2(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn@8.14.1: {} + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-iterate@2.0.1: {} + + array-timsort@1.0.3: {} + + astring@1.9.0: {} + + astro-auto-import@0.4.4(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)): + dependencies: + '@types/node': 18.19.83 + acorn: 8.14.1 + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + + astro-embed@0.9.0(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)): + dependencies: + '@astro-community/astro-embed-baseline-status': 0.1.2(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@astro-community/astro-embed-bluesky': 0.1.3(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@astro-community/astro-embed-integration': 0.8.1(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@astro-community/astro-embed-link-preview': 0.2.2 + '@astro-community/astro-embed-twitter': 0.5.8(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@astro-community/astro-embed-vimeo': 0.3.10(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@astro-community/astro-embed-youtube': 0.5.6(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + + astro-expressive-code@0.40.2(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)): + dependencies: + astro: 5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0) + rehype-expressive-code: 0.40.2 + + astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0): + dependencies: + '@astrojs/compiler': 2.11.0 + '@astrojs/internal-helpers': 0.6.1 + '@astrojs/markdown-remark': 6.3.1 + '@astrojs/telemetry': 3.2.0 + '@oslojs/encoding': 1.1.0 + '@rollup/pluginutils': 5.1.4(rollup@4.37.0) + acorn: 8.14.1 + aria-query: 5.3.2 + axobject-query: 4.1.0 + boxen: 8.0.1 + ci-info: 4.2.0 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 1.0.2 + cssesc: 3.0.0 + debug: 4.4.0 + deterministic-object-hash: 2.0.2 + devalue: 5.1.1 + diff: 5.2.0 + dlv: 1.1.3 + dset: 3.1.4 + es-module-lexer: 1.6.0 + esbuild: 0.25.1 + estree-walker: 3.0.3 + flattie: 1.1.1 + github-slugger: 2.0.0 + html-escaper: 3.0.3 + http-cache-semantics: 4.1.1 + js-yaml: 4.1.0 + kleur: 4.1.5 + magic-string: 0.30.17 + magicast: 0.3.5 + mrmime: 2.0.1 + neotraverse: 0.6.18 + p-limit: 6.2.0 + p-queue: 8.1.0 + package-manager-detector: 1.1.0 + picomatch: 4.0.2 + prompts: 2.4.2 + rehype: 13.0.2 + semver: 7.7.1 + shiki: 3.2.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.12 + tsconfck: 3.1.5(typescript@5.8.2) + ultrahtml: 1.5.3 + unist-util-visit: 5.0.0 + unstorage: 1.15.0 + vfile: 6.0.3 + vite: 6.2.3(@types/node@20.16.10)(yaml@2.7.0) + vitefu: 1.0.6(vite@6.2.3(@types/node@20.16.10)(yaml@2.7.0)) + xxhash-wasm: 1.1.0 + yargs-parser: 21.1.1 + yocto-spinner: 0.2.1 + zod: 3.24.2 + zod-to-json-schema: 3.24.5(zod@3.24.2) + zod-to-ts: 1.2.0(typescript@5.8.2)(zod@3.24.2) + optionalDependencies: + sharp: 0.33.5 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@types/node' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - jiti + - less + - lightningcss + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - yaml + + await-lock@2.2.2: {} + + axobject-query@4.1.0: {} + + bail@2.0.2: {} + + base-64@1.0.0: {} + + bcp-47-match@2.0.3: {} + + bcp-47@2.1.0: + dependencies: + is-alphabetical: 2.0.1 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + + boolbase@1.0.0: {} + + boxen@8.0.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 8.0.0 + chalk: 5.4.1 + cli-boxes: 3.0.0 + string-width: 7.2.0 + type-fest: 4.38.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.0 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + callsites@3.1.0: {} + + camelcase@8.0.0: {} + + ccount@2.0.1: {} + + chalk-template@1.1.0: + dependencies: + chalk: 5.4.1 + + chalk@5.4.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + ci-info@4.2.0: {} + + clear-module@4.1.2: + dependencies: + parent-module: 2.0.0 + resolve-from: 5.0.0 + + cli-boxes@3.0.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clsx@2.1.1: {} + + collapse-white-space@2.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + comma-separated-tokens@2.0.3: {} + + commander@13.1.0: {} + + comment-json@4.2.5: + dependencies: + array-timsort: 1.0.3 + core-util-is: 1.0.3 + esprima: 4.0.1 + has-own-prop: 2.0.0 + repeat-string: 1.6.1 + + common-ancestor-path@1.0.1: {} + + cookie-es@1.2.2: {} + + cookie@1.0.2: {} + + core-util-is@1.0.3: {} + + crossws@0.3.4: + dependencies: + uncrypto: 0.1.3 + + cspell-config-lib@8.17.5: + dependencies: + '@cspell/cspell-types': 8.17.5 + comment-json: 4.2.5 + yaml: 2.7.0 + + cspell-dictionary@8.17.5: + dependencies: + '@cspell/cspell-pipe': 8.17.5 + '@cspell/cspell-types': 8.17.5 + cspell-trie-lib: 8.17.5 + fast-equals: 5.2.2 + + cspell-gitignore@8.17.5: + dependencies: + '@cspell/url': 8.17.5 + cspell-glob: 8.17.5 + cspell-io: 8.17.5 + find-up-simple: 1.0.1 + + cspell-glob@8.17.5: + dependencies: + '@cspell/url': 8.17.5 + micromatch: 4.0.8 + + cspell-grammar@8.17.5: + dependencies: + '@cspell/cspell-pipe': 8.17.5 + '@cspell/cspell-types': 8.17.5 + + cspell-io@8.17.5: + dependencies: + '@cspell/cspell-service-bus': 8.17.5 + '@cspell/url': 8.17.5 + + cspell-lib@8.17.5: + dependencies: + '@cspell/cspell-bundled-dicts': 8.17.5 + '@cspell/cspell-pipe': 8.17.5 + '@cspell/cspell-resolver': 8.17.5 + '@cspell/cspell-types': 8.17.5 + '@cspell/dynamic-import': 8.17.5 + '@cspell/filetypes': 8.17.5 + '@cspell/strong-weak-map': 8.17.5 + '@cspell/url': 8.17.5 + clear-module: 4.1.2 + comment-json: 4.2.5 + cspell-config-lib: 8.17.5 + cspell-dictionary: 8.17.5 + cspell-glob: 8.17.5 + cspell-grammar: 8.17.5 + cspell-io: 8.17.5 + cspell-trie-lib: 8.17.5 + env-paths: 3.0.0 + fast-equals: 5.2.2 + gensequence: 7.0.0 + import-fresh: 3.3.1 + resolve-from: 5.0.0 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + xdg-basedir: 5.1.0 + + cspell-trie-lib@8.17.5: + dependencies: + '@cspell/cspell-pipe': 8.17.5 + '@cspell/cspell-types': 8.17.5 + gensequence: 7.0.0 + + cspell@8.17.5: + dependencies: + '@cspell/cspell-json-reporter': 8.17.5 + '@cspell/cspell-pipe': 8.17.5 + '@cspell/cspell-types': 8.17.5 + '@cspell/dynamic-import': 8.17.5 + '@cspell/url': 8.17.5 + chalk: 5.4.1 + chalk-template: 1.1.0 + commander: 13.1.0 + cspell-dictionary: 8.17.5 + cspell-gitignore: 8.17.5 + cspell-glob: 8.17.5 + cspell-io: 8.17.5 + cspell-lib: 8.17.5 + fast-json-stable-stringify: 2.1.0 + file-entry-cache: 9.1.0 + get-stdin: 9.0.0 + semver: 7.7.1 + tinyglobby: 0.2.12 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-selector-parser@1.4.1: {} + + css-selector-parser@3.1.1: {} + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + cssom@0.5.0: {} + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.1.0: + dependencies: + character-entities: 2.0.2 + + defu@6.1.4: {} + + dequal@2.0.3: {} + + destr@2.0.3: {} + + detect-libc@2.0.3: {} + + deterministic-object-hash@2.0.2: + dependencies: + base-64: 1.0.0 + + devalue@5.1.1: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@5.2.0: {} + + direction@2.0.1: {} + + dlv@1.1.3: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dset@3.1.4: {} + + emmet@2.4.11: + dependencies: + '@emmetio/abbreviation': 2.3.3 + '@emmetio/css-abbreviation': 2.1.8 + + emoji-regex-xs@1.0.0: {} + + emoji-regex@10.4.0: {} + + emoji-regex@8.0.0: {} + + entities@4.5.0: {} + + env-paths@3.0.0: {} + + es-module-lexer@1.6.0: {} + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.14.1 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.2 + + esbuild@0.25.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.1 + '@esbuild/android-arm': 0.25.1 + '@esbuild/android-arm64': 0.25.1 + '@esbuild/android-x64': 0.25.1 + '@esbuild/darwin-arm64': 0.25.1 + '@esbuild/darwin-x64': 0.25.1 + '@esbuild/freebsd-arm64': 0.25.1 + '@esbuild/freebsd-x64': 0.25.1 + '@esbuild/linux-arm': 0.25.1 + '@esbuild/linux-arm64': 0.25.1 + '@esbuild/linux-ia32': 0.25.1 + '@esbuild/linux-loong64': 0.25.1 + '@esbuild/linux-mips64el': 0.25.1 + '@esbuild/linux-ppc64': 0.25.1 + '@esbuild/linux-riscv64': 0.25.1 + '@esbuild/linux-s390x': 0.25.1 + '@esbuild/linux-x64': 0.25.1 + '@esbuild/netbsd-arm64': 0.25.1 + '@esbuild/netbsd-x64': 0.25.1 + '@esbuild/openbsd-arm64': 0.25.1 + '@esbuild/openbsd-x64': 0.25.1 + '@esbuild/sunos-x64': 0.25.1 + '@esbuild/win32-arm64': 0.25.1 + '@esbuild/win32-ia32': 0.25.1 + '@esbuild/win32-x64': 0.25.1 + + escalade@3.2.0: {} + + escape-string-regexp@5.0.0: {} + + esprima@4.0.1: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.7 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.7 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.4 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.7 + + eventemitter3@5.0.1: {} + + expressive-code@0.40.2: + dependencies: + '@expressive-code/core': 0.40.2 + '@expressive-code/plugin-frames': 0.40.2 + '@expressive-code/plugin-shiki': 0.40.2 + '@expressive-code/plugin-text-markers': 0.40.2 + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-equals@5.2.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-uri@3.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + file-entry-cache@9.1.0: + dependencies: + flat-cache: 5.0.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up-simple@1.0.1: {} + + flat-cache@5.0.0: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + flattie@1.1.1: {} + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + gensequence@7.0.0: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.3.0: {} + + get-stdin@9.0.0: {} + + github-slugger@2.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + graphemer@1.4.0: {} + + h3@1.15.1: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.4 + defu: 6.1.4 + destr: 2.0.3 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.0 + radix3: 1.1.2 + ufo: 1.5.4 + uncrypto: 0.1.3 + + has-own-prop@2.0.0: {} + + hast-util-embedded@3.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-is-element: 3.0.0 + + hast-util-format@1.1.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-minify-whitespace: 1.0.1 + hast-util-phrasing: 3.0.1 + hast-util-whitespace: 3.0.0 + html-whitespace-sensitive-tag-names: 3.0.1 + unist-util-visit-parents: 6.0.1 + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.2.1 + vfile: 6.0.3 + vfile-message: 4.0.2 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.0.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-has-property@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-body-ok-link@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-minify-whitespace@1.0.1: + dependencies: + '@types/hast': 3.0.4 + 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 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-phrasing@3.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-has-property: 3.0.0 + hast-util-is-body-ok-link: 3.0.1 + hast-util-is-element: 3.0.0 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + parse5: 7.2.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-select@6.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + bcp-47-match: 2.0.3 + comma-separated-tokens: 2.0.3 + css-selector-parser: 3.1.1 + devlop: 1.1.0 + direction: 2.0.1 + hast-util-has-property: 3.0.0 + hast-util-to-string: 3.0.1 + hast-util-whitespace: 3.0.0 + nth-check: 2.1.1 + property-information: 7.0.0 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.7 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.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.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.0.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.16 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 7.0.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.7 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.0.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.16 + unist-util-position: 5.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.0: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.0.0 + space-separated-tokens: 2.0.2 + + html-escaper@3.0.3: {} + + html-void-elements@3.0.0: {} + + html-whitespace-sensitive-tag-names@3.0.1: {} + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 + + http-cache-semantics@4.1.1: {} + + i18next@23.16.8: + dependencies: + '@babel/runtime': 7.27.0 + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-meta-resolve@4.1.0: {} + + ini@4.1.1: {} + + inline-style-parser@0.2.4: {} + + iron-webcrypto@1.2.1: {} + + is-absolute-url@4.0.1: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arrayish@0.3.2: {} + + is-decimal@2.0.1: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-number@7.0.0: {} + + is-plain-obj@4.1.0: {} + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + iso-datestring-validator@2.2.2: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@1.0.0: {} + + jsonc-parser@2.3.1: {} + + jsonc-parser@3.3.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@3.0.3: {} + + kleur@4.1.5: {} + + klona@2.0.6: {} + + linkedom@0.14.26: + dependencies: + css-select: 5.1.0 + cssom: 0.5.0 + html-escaper: 3.0.3 + htmlparser2: 8.0.2 + uhyphen: 0.2.0 + + lite-youtube-embed@0.3.3: {} + + lodash@4.17.21: {} + + longest-streak@3.1.0: {} + + lru-cache@10.4.3: {} + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 + source-map-js: 1.2.1 + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + mdast-util-definitions@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + unist-util-visit: 5.0.0 + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.1.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.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.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.0 + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.1.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.7 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.7 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.2 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.7 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.7 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.7 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.2 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.0 + decode-named-character-reference: 1.1.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + multiformats@9.9.0: {} + + nanoid@3.3.11: {} + + neotraverse@0.6.18: {} + + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + + node-fetch-native@1.6.6: {} + + node-mock-http@1.0.0: {} + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + ofetch@1.4.1: + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.6 + ufo: 1.5.4 + + oniguruma-parser@0.5.4: {} + + oniguruma-to-es@2.3.0: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 5.1.1 + regex-recursion: 5.1.1 + + oniguruma-to-es@4.1.0: + dependencies: + emoji-regex-xs: 1.0.0 + oniguruma-parser: 0.5.4 + regex: 6.0.1 + regex-recursion: 6.0.2 + + p-limit@6.2.0: + dependencies: + yocto-queue: 1.2.1 + + p-queue@8.1.0: + dependencies: + eventemitter3: 5.0.1 + p-timeout: 6.1.4 + + p-timeout@6.1.4: {} + + package-manager-detector@1.1.0: {} + + pagefind@1.3.0: + optionalDependencies: + '@pagefind/darwin-arm64': 1.3.0 + '@pagefind/darwin-x64': 1.3.0 + '@pagefind/linux-arm64': 1.3.0 + '@pagefind/linux-x64': 1.3.0 + '@pagefind/windows-x64': 1.3.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parent-module@2.0.0: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.1.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-latin@7.0.0: + dependencies: + '@types/nlcst': 2.0.3 + '@types/unist': 3.0.3 + nlcst-to-string: 4.0.0 + unist-util-modify-children: 4.0.0 + unist-util-visit-children: 3.0.0 + vfile: 6.0.3 + + parse5@7.2.1: + dependencies: + entities: 4.5.0 + + path-browserify@1.0.1: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + playwright-core@1.51.1: {} + + playwright-ctrf-json-reporter@0.0.19: {} + + playwright@1.51.1: + dependencies: + playwright-core: 1.51.1 + optionalDependencies: + fsevents: 2.3.2 + + postcss-nested@6.2.0(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@2.8.7: + optional: true + + prismjs@1.30.0: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + property-information@6.5.0: {} + + property-information@7.0.0: {} + + queue-microtask@1.2.3: {} + + radix3@1.1.2: {} + + readdirp@4.1.2: {} + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.7 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.0(acorn@8.14.1): + dependencies: + acorn-jsx: 5.3.2(acorn@8.14.1) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - acorn + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.7 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.7 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + regenerator-runtime@0.14.1: {} + + regex-recursion@5.1.1: + dependencies: + regex: 5.1.1 + regex-utilities: 2.3.0 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@5.1.1: + dependencies: + regex-utilities: 2.3.0 + + regex@6.0.1: + dependencies: + regex-utilities: 2.3.0 + + rehype-expressive-code@0.40.2: + dependencies: + expressive-code: 0.40.2 + + rehype-external-links@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@ungap/structured-clone': 1.3.0 + hast-util-is-element: 3.0.0 + is-absolute-url: 4.0.1 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.0.0 + + rehype-format@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-format: 1.1.0 + + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.7 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + rehype-stringify@10.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + unified: 11.0.5 + + rehype@13.0.2: + dependencies: + '@types/hast': 3.0.4 + rehype-parse: 9.0.1 + rehype-stringify: 10.0.1 + unified: 11.0.5 + + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.0: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 + + remark-smartypants@3.0.2: + dependencies: + retext: 9.0.0 + retext-smartypants: 6.2.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + repeat-string@1.6.1: {} + + request-light@0.5.8: {} + + request-light@0.7.0: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + retext-latin@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + parse-latin: 7.0.0 + unified: 11.0.5 + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.0.0 + + retext-stringify@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unified: 11.0.5 + + retext@9.0.0: + dependencies: + '@types/nlcst': 2.0.3 + retext-latin: 4.0.0 + retext-stringify: 4.0.0 + unified: 11.0.5 + + reusify@1.1.0: {} + + rollup@4.37.0: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.37.0 + '@rollup/rollup-android-arm64': 4.37.0 + '@rollup/rollup-darwin-arm64': 4.37.0 + '@rollup/rollup-darwin-x64': 4.37.0 + '@rollup/rollup-freebsd-arm64': 4.37.0 + '@rollup/rollup-freebsd-x64': 4.37.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.37.0 + '@rollup/rollup-linux-arm-musleabihf': 4.37.0 + '@rollup/rollup-linux-arm64-gnu': 4.37.0 + '@rollup/rollup-linux-arm64-musl': 4.37.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.37.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.37.0 + '@rollup/rollup-linux-riscv64-gnu': 4.37.0 + '@rollup/rollup-linux-riscv64-musl': 4.37.0 + '@rollup/rollup-linux-s390x-gnu': 4.37.0 + '@rollup/rollup-linux-x64-gnu': 4.37.0 + '@rollup/rollup-linux-x64-musl': 4.37.0 + '@rollup/rollup-win32-arm64-msvc': 4.37.0 + '@rollup/rollup-win32-ia32-msvc': 4.37.0 + '@rollup/rollup-win32-x64-msvc': 4.37.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sax@1.4.1: {} + + semver@7.7.1: {} + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + + shiki@1.29.2: + dependencies: + '@shikijs/core': 1.29.2 + '@shikijs/engine-javascript': 1.29.2 + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/langs': 1.29.2 + '@shikijs/themes': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + shiki@3.2.1: + dependencies: + '@shikijs/core': 3.2.1 + '@shikijs/engine-javascript': 3.2.1 + '@shikijs/engine-oniguruma': 3.2.1 + '@shikijs/langs': 3.2.1 + '@shikijs/themes': 3.2.1 + '@shikijs/types': 3.2.1 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + sisteransi@1.0.5: {} + + sitemap@8.0.0: + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.4.1 + + smol-toml@1.3.1: {} + + source-map-js@1.2.1: {} + + source-map@0.7.4: {} + + space-separated-tokens@2.0.2: {} + + starlight-links-validator@0.14.3(@astrojs/starlight@0.32.4(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0))): + dependencies: + '@astrojs/starlight': 0.32.4(astro@5.5.5(@types/node@20.16.10)(rollup@4.37.0)(typescript@5.8.2)(yaml@2.7.0)) + '@types/picomatch': 3.0.2 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-has-property: 3.0.0 + is-absolute-url: 4.0.1 + kleur: 4.1.5 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-to-string: 4.0.0 + picomatch: 4.0.2 + unist-util-visit: 5.0.0 + transitivePeerDependencies: + - supports-color + + stream-replace-string@2.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.4.0 + get-east-asian-width: 1.3.0 + strip-ansi: 7.1.0 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + style-to-js@1.1.16: + dependencies: + style-to-object: 1.0.8 + + style-to-object@1.0.8: + dependencies: + inline-style-parser: 0.2.4 + + tinyexec@0.3.2: {} + + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + + tlds@1.256.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-pattern@5.6.2: {} + + tsconfck@3.1.5(typescript@5.8.2): + optionalDependencies: + typescript: 5.8.2 + + tslib@2.8.1: + optional: true + + type-fest@4.38.0: {} + + typesafe-path@0.2.2: {} + + typescript-auto-import-cache@0.3.5: + dependencies: + semver: 7.7.1 + + typescript@5.8.2: {} + + ufo@1.5.4: {} + + uhyphen@0.2.0: {} + + uint8arrays@3.0.0: + dependencies: + multiformats: 9.9.0 + + ultrahtml@1.5.3: {} + + uncrypto@0.1.3: {} + + undici-types@5.26.5: {} + + undici-types@6.19.8: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-modify-children@4.0.0: + dependencies: + '@types/unist': 3.0.3 + array-iterate: 2.0.1 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.0.0 + + unist-util-select@4.0.3: + dependencies: + '@types/unist': 2.0.11 + css-selector-parser: 1.4.1 + nth-check: 2.1.1 + zwitch: 2.0.4 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-children@3.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + unstorage@1.15.0: + dependencies: + anymatch: 3.1.3 + chokidar: 4.0.3 + destr: 2.0.3 + h3: 1.15.1 + lru-cache: 10.4.3 + node-fetch-native: 1.6.6 + ofetch: 1.4.1 + ufo: 1.5.4 + + util-deprecate@1.0.2: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.2 + + vite@6.2.3(@types/node@20.16.10)(yaml@2.7.0): + dependencies: + esbuild: 0.25.1 + postcss: 8.5.3 + rollup: 4.37.0 + optionalDependencies: + '@types/node': 20.16.10 + fsevents: 2.3.3 + yaml: 2.7.0 + + vitefu@1.0.6(vite@6.2.3(@types/node@20.16.10)(yaml@2.7.0)): + optionalDependencies: + vite: 6.2.3(@types/node@20.16.10)(yaml@2.7.0) + + volar-service-css@0.0.62(@volar/language-service@2.4.12): + dependencies: + vscode-css-languageservice: 6.3.3 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + optionalDependencies: + '@volar/language-service': 2.4.12 + + volar-service-emmet@0.0.62(@volar/language-service@2.4.12): + dependencies: + '@emmetio/css-parser': 0.4.0 + '@emmetio/html-matcher': 1.3.0 + '@vscode/emmet-helper': 2.11.0 + vscode-uri: 3.1.0 + optionalDependencies: + '@volar/language-service': 2.4.12 + + volar-service-html@0.0.62(@volar/language-service@2.4.12): + dependencies: + vscode-html-languageservice: 5.3.3 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + optionalDependencies: + '@volar/language-service': 2.4.12 + + volar-service-prettier@0.0.62(@volar/language-service@2.4.12): + dependencies: + vscode-uri: 3.1.0 + optionalDependencies: + '@volar/language-service': 2.4.12 + + volar-service-typescript-twoslash-queries@0.0.62(@volar/language-service@2.4.12): + dependencies: + vscode-uri: 3.1.0 + optionalDependencies: + '@volar/language-service': 2.4.12 + + volar-service-typescript@0.0.62(@volar/language-service@2.4.12): + dependencies: + path-browserify: 1.0.1 + semver: 7.7.1 + typescript-auto-import-cache: 0.3.5 + vscode-languageserver-textdocument: 1.0.12 + vscode-nls: 5.2.0 + vscode-uri: 3.1.0 + optionalDependencies: + '@volar/language-service': 2.4.12 + + volar-service-yaml@0.0.62(@volar/language-service@2.4.12): + dependencies: + vscode-uri: 3.1.0 + yaml-language-server: 1.15.0 + optionalDependencies: + '@volar/language-service': 2.4.12 + + vscode-css-languageservice@6.3.3: + dependencies: + '@vscode/l10n': 0.0.18 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-uri: 3.1.0 + + vscode-html-languageservice@5.3.3: + dependencies: + '@vscode/l10n': 0.0.18 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-uri: 3.1.0 + + vscode-json-languageservice@4.1.8: + dependencies: + jsonc-parser: 3.3.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-nls: 5.2.0 + vscode-uri: 3.1.0 + + vscode-jsonrpc@6.0.0: {} + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.16.0: + dependencies: + vscode-jsonrpc: 6.0.0 + vscode-languageserver-types: 3.16.0 + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.16.0: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@7.0.0: + dependencies: + vscode-languageserver-protocol: 3.16.0 + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-nls@5.2.0: {} + + vscode-uri@3.1.0: {} + + web-namespaces@2.0.1: {} + + which-pm-runs@1.1.0: {} + + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + + xdg-basedir@5.1.0: {} + + xxhash-wasm@1.1.0: {} + + y18n@5.0.8: {} + + yaml-language-server@1.15.0: + dependencies: + ajv: 8.17.1 + lodash: 4.17.21 + request-light: 0.5.8 + vscode-json-languageservice: 4.1.8 + vscode-languageserver: 7.0.0 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-nls: 5.2.0 + vscode-uri: 3.1.0 + yaml: 2.2.2 + optionalDependencies: + prettier: 2.8.7 + + yaml@2.2.2: {} + + yaml@2.7.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@1.2.1: {} + + yocto-spinner@0.2.1: + dependencies: + yoctocolors: 2.1.1 + + yoctocolors@2.1.1: {} + + zod-to-json-schema@3.24.5(zod@3.24.2): + dependencies: + zod: 3.24.2 + + zod-to-ts@1.2.0(typescript@5.8.2)(zod@3.24.2): + dependencies: + typescript: 5.8.2 + zod: 3.24.2 + + zod@3.24.2: {} + + zwitch@2.0.4: {} diff --git a/component-sets/material/docs/public/favicon.svg b/component-sets/material/docs/public/favicon.svg new file mode 100644 index 000000000..513b7344c --- /dev/null +++ b/component-sets/material/docs/public/favicon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/component-sets/material/docs/src/assets/slint-logo-simple-dark.webp b/component-sets/material/docs/src/assets/slint-logo-simple-dark.webp new file mode 100644 index 000000000..93d9c0c1c Binary files /dev/null and b/component-sets/material/docs/src/assets/slint-logo-simple-dark.webp differ diff --git a/component-sets/material/docs/src/assets/slint-logo-simple-light.webp b/component-sets/material/docs/src/assets/slint-logo-simple-light.webp new file mode 100644 index 000000000..6edd00a50 Binary files /dev/null and b/component-sets/material/docs/src/assets/slint-logo-simple-light.webp differ diff --git a/component-sets/material/docs/src/assets/slint-logo-small-dark.svg b/component-sets/material/docs/src/assets/slint-logo-small-dark.svg new file mode 100644 index 000000000..14e79ec81 --- /dev/null +++ b/component-sets/material/docs/src/assets/slint-logo-small-dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/component-sets/material/docs/src/assets/slint-logo-small-light.svg b/component-sets/material/docs/src/assets/slint-logo-small-light.svg new file mode 100644 index 000000000..dcb1b5adc --- /dev/null +++ b/component-sets/material/docs/src/assets/slint-logo-small-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/component-sets/material/docs/src/assets/slint-logo-square-dark.webp b/component-sets/material/docs/src/assets/slint-logo-square-dark.webp new file mode 100644 index 000000000..cb94c6c4c Binary files /dev/null and b/component-sets/material/docs/src/assets/slint-logo-square-dark.webp differ diff --git a/component-sets/material/docs/src/assets/slint-logo-square-light.webp b/component-sets/material/docs/src/assets/slint-logo-square-light.webp new file mode 100644 index 000000000..868237dc2 Binary files /dev/null and b/component-sets/material/docs/src/assets/slint-logo-square-light.webp differ diff --git a/component-sets/material/docs/src/components/Banner.astro b/component-sets/material/docs/src/components/Banner.astro new file mode 100644 index 000000000..828457923 --- /dev/null +++ b/component-sets/material/docs/src/components/Banner.astro @@ -0,0 +1,10 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import Default from "@astrojs/starlight/components/Banner.astro"; + +import VersionBanner from "./VersionBanner.astro"; +--- + + + diff --git a/component-sets/material/docs/src/components/CodeSnippetMD.astro b/component-sets/material/docs/src/components/CodeSnippetMD.astro new file mode 100644 index 000000000..8b1ce4916 --- /dev/null +++ b/component-sets/material/docs/src/components/CodeSnippetMD.astro @@ -0,0 +1,38 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import "@astrojs/starlight/style/markdown.css"; +import type { ImageMetadata } from "astro"; +import { Image } from "astro:assets"; + +interface Props { + imagePath: string; + imageAlt: string; + imageWidth: number; + imageHeight: number; + needsBackground?: boolean; + skip?: boolean; + scale?: number; +} +const { imagePath, imageAlt, skip, needsBackground } = Astro.props as Props; +const images = import.meta.glob<{ default: ImageMetadata }>( + "/src/assets/generated/*.{jpeg,jpg,png,gif}", +); +if (!images[imagePath]) { + throw new Error( + `"${imagePath}" does not exist in glob: "src/assets/generated/*.{jpeg,jpg,png,gif}"`, + ); +} +const imageSrc = images[imagePath](); +const imageCSS = `image-block ${needsBackground ? "screenshot-container" : ""}`; +--- + +{!skip &&
+
+ +
+
+ {imageAlt} +
+
} + diff --git a/component-sets/material/docs/src/components/Footer.astro b/component-sets/material/docs/src/components/Footer.astro new file mode 100644 index 000000000..6ba6d3fbe --- /dev/null +++ b/component-sets/material/docs/src/components/Footer.astro @@ -0,0 +1,24 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import Default from "@astrojs/starlight/components/Footer.astro"; +const year = new Date().getFullYear(); +--- + + + +
+ +

© {year} SixtyFPS GmbH

+ + diff --git a/component-sets/material/docs/src/components/FourCardGrid.astro b/component-sets/material/docs/src/components/FourCardGrid.astro new file mode 100644 index 000000000..b2b311cbc --- /dev/null +++ b/component-sets/material/docs/src/components/FourCardGrid.astro @@ -0,0 +1,38 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +interface Props { + stagger?: boolean; +} + +const { stagger = false } = Astro.props; +--- + +
+ + diff --git a/component-sets/material/docs/src/components/Header.astro b/component-sets/material/docs/src/components/Header.astro new file mode 100644 index 000000000..b4889c9bf --- /dev/null +++ b/component-sets/material/docs/src/components/Header.astro @@ -0,0 +1,86 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import LanguageSelect from "@astrojs/starlight/components/LanguageSelect.astro"; +import Search from "@astrojs/starlight/components/Search.astro"; +import SiteTitle from "@astrojs/starlight/components/SiteTitle.astro"; +import SocialIcons from "@astrojs/starlight/components/SocialIcons.astro"; +import ThemeSelect from "./ThemeSelect.astro"; +import VersionSelector from "./VersionSelector.astro"; +--- + +
+
+ +
+
+ +
+
+ + + + +
+
+ + diff --git a/component-sets/material/docs/src/components/IconLinkCard.astro b/component-sets/material/docs/src/components/IconLinkCard.astro new file mode 100644 index 000000000..2d2b1290a --- /dev/null +++ b/component-sets/material/docs/src/components/IconLinkCard.astro @@ -0,0 +1,89 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +// biome-ignore lint/style/useImportType: +import { Icon } from "@astrojs/starlight/components"; +import type { HTMLAttributes } from "astro/types"; + +interface Props extends Omit, "title"> { + icon?: keyof typeof Icon; + title: string; +} + +const { icon, title, ...attributes } = Astro.props as Props; +--- + + + + diff --git a/component-sets/material/docs/src/components/LangRefLink.astro b/component-sets/material/docs/src/components/LangRefLink.astro new file mode 100644 index 000000000..213afade8 --- /dev/null +++ b/component-sets/material/docs/src/components/LangRefLink.astro @@ -0,0 +1,41 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { + CPP_BASE_URL, + RUST_SLINT_CRATE_URL, + RUST_SLINT_INTERPRETER_CRATE_URL, + RUST_SLINT_BUILD_CRATE_URL, + NODEJS_BASE_URL, + PYTHON_BASE_URL, +} from "../utils/site-config.ts"; + +const BASE_URL_MAP = { + cpp: `${CPP_BASE_URL}`, + "rust-slint": `${RUST_SLINT_CRATE_URL}`, + "rust-slint-build": `${RUST_SLINT_BUILD_CRATE_URL}`, + "rust-slint-interpreter": `${RUST_SLINT_INTERPRETER_CRATE_URL}`, + nodejs: `${NODEJS_BASE_URL}`, + python: `${PYTHON_BASE_URL}`, +} as const; + +type LangID = keyof typeof BASE_URL_MAP; + +interface Props { + lang: LangID; + title: string; + relpath: string; +} + +const props = Astro.props; +if (!Object.keys(BASE_URL_MAP).includes(props.lang)) { + throw new Error(`Invalid language ID: ${props.lang}`); +} + +const { lang, relpath } = props; +const link = `${BASE_URL_MAP[lang]}${relpath}`; +--- + + + diff --git a/component-sets/material/docs/src/components/Link.astro b/component-sets/material/docs/src/components/Link.astro new file mode 100644 index 000000000..54167a75a --- /dev/null +++ b/component-sets/material/docs/src/components/Link.astro @@ -0,0 +1,29 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { linkMap } from "../utils/utils"; + +type LinkType = keyof typeof linkMap; + +interface Props { + label?: string; + type: LinkType; +} + +const { label, type } = Astro.props as Props; +const displayLabel = label || type; + +if (!(type in linkMap)) { + throw new Error( + `Invalid link type: ${type}. Maybe you forgot to add it to the linkMap?`, + ); +} + +// The base is set in astro.config.mjs +const base = import.meta.env.BASE_URL; +const fullHref = `${base}${linkMap[type].href}`; +--- + +{displayLabel} + diff --git a/component-sets/material/docs/src/components/ReleaseLink.astro b/component-sets/material/docs/src/components/ReleaseLink.astro new file mode 100644 index 000000000..aa4624899 --- /dev/null +++ b/component-sets/material/docs/src/components/ReleaseLink.astro @@ -0,0 +1,27 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { SLINT_DOWNLOAD_VERSION } from "../utils/site-config.ts"; + +const LINK_MAP = { + "slint-cpp-template-stm32h735g-dk.zip": `https://github.com/slint-ui/slint/releases/download/${SLINT_DOWNLOAD_VERSION}/slint-cpp-template-stm32h735g-dk.zip`, + "slint-cpp-template-stm32h747i-disco.zip": `https://github.com/slint-ui/slint/releases/download/${SLINT_DOWNLOAD_VERSION}/slint-cpp-template-stm32h747i-disco.zip`, +} as const; + +type LinkID = keyof typeof LINK_MAP; + +interface Props { + id: LinkID; +} + +const props = Astro.props; +if (!Object.keys(LINK_MAP).includes(props.id)) { + throw new Error(`Invalid link ID: ${props.id}`); +} + +const { id } = props; +const link = LINK_MAP[id]; +--- + +{id} \ No newline at end of file diff --git a/component-sets/material/docs/src/components/SlintProperty.astro b/component-sets/material/docs/src/components/SlintProperty.astro new file mode 100644 index 000000000..528a8aed4 --- /dev/null +++ b/component-sets/material/docs/src/components/SlintProperty.astro @@ -0,0 +1,87 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import "@astrojs/starlight/style/markdown.css"; +import { + type KnownType, + type PropertyVisibility, + getEnumContent, + getStructContent, + getTypeInfo, +} from "../utils/utils.ts"; + +import Type from "./Type.astro"; + +interface Props { + propName: string; + typeName: KnownType; + defaultValue?: string; + enumName?: string; + structName?: string; + propertyVisibility?: PropertyVisibility; +} +const { + propName, + typeName, + defaultValue, + enumName, + structName, + propertyVisibility, +} = Astro.props as Props; + +if (propName === "") { + console.error("No propName!!"); +} + +let fullTypeName = typeName; + +if (typeName === "enum") { + if (enumName === undefined || enumName === "") { + console.error("enum type without an enumName:", propName); + } else { + fullTypeName = typeName.toString() + " " + enumName!.toString(); + } +} else if (typeName === "struct") { + if (structName === undefined || structName === "") { + console.error("struct type without a structName:", propName); + } else { + fullTypeName = typeName.toString() + " " + structName!.toString(); + } +} else { + if (enumName && enumName !== "") { + console.error("Non-enum type with an enumName set:", propName); + } +} + +const typeInfo = getTypeInfo(typeName); +if (typeInfo.href !== "") { + const base = import.meta.env.BASE_URL; + typeInfo.href = `${base}${typeInfo.href}`; +} +const enumContent = await getEnumContent(enumName); +const structContent = await getStructContent(structName); + +const defaultValue_ = defaultValue ? defaultValue : typeInfo.defaultValue; + +if (!defaultValue_) { + console.error("No defaultValue for:", propName); +} +--- + + +
+

+ {typeInfo.href === "" ? ( + + ) : ( + + + + )} + {propertyVisibility && {`(${propertyVisibility})`}} + default: {defaultValue_}
+ {enumName && } + {structContent && } +

+ +
diff --git a/component-sets/material/docs/src/components/ThemeSelect.astro b/component-sets/material/docs/src/components/ThemeSelect.astro new file mode 100644 index 000000000..f939a31e9 --- /dev/null +++ b/component-sets/material/docs/src/components/ThemeSelect.astro @@ -0,0 +1,37 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import { Icon } from "@astrojs/starlight/components"; +--- + + + + + + + \ No newline at end of file diff --git a/component-sets/material/docs/src/components/ThreeCardGrid.astro b/component-sets/material/docs/src/components/ThreeCardGrid.astro new file mode 100644 index 000000000..928c08605 --- /dev/null +++ b/component-sets/material/docs/src/components/ThreeCardGrid.astro @@ -0,0 +1,37 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +interface Props { + stagger?: boolean; +} + +const { stagger = false } = Astro.props; +--- + +
+ + diff --git a/component-sets/material/docs/src/components/Type.astro b/component-sets/material/docs/src/components/Type.astro new file mode 100644 index 000000000..887961fd9 --- /dev/null +++ b/component-sets/material/docs/src/components/Type.astro @@ -0,0 +1,28 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import { z } from "astro:schema"; +import { Badge } from "@astrojs/starlight/components"; + +type Props = z.infer; + +const props = z + .object({ + text: z.string(), + }) + .strict(); + +const { text } = props.parse(Astro.props); +--- + + diff --git a/component-sets/material/docs/src/components/VersionBanner.astro b/component-sets/material/docs/src/components/VersionBanner.astro new file mode 100644 index 000000000..cae343632 --- /dev/null +++ b/component-sets/material/docs/src/components/VersionBanner.astro @@ -0,0 +1,79 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +--- + + + diff --git a/component-sets/material/docs/src/components/VersionSelector.astro b/component-sets/material/docs/src/components/VersionSelector.astro new file mode 100644 index 000000000..136e58cb5 --- /dev/null +++ b/component-sets/material/docs/src/components/VersionSelector.astro @@ -0,0 +1,142 @@ +--- +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import { Icon } from "@astrojs/starlight/components"; +--- + + +
+ + + +
+ + diff --git a/component-sets/material/docs/src/components/editor/codemirror.js b/component-sets/material/docs/src/components/editor/codemirror.js new file mode 100644 index 000000000..c7fbfcfa7 --- /dev/null +++ b/component-sets/material/docs/src/components/editor/codemirror.js @@ -0,0 +1,312 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { EditorState } from "@codemirror/state"; +import { highlightSelectionMatches } from "@codemirror/search"; +import { + indentWithTab, + history, + defaultKeymap, + historyKeymap, +} from "@codemirror/commands"; +import { + foldGutter, + indentOnInput, + indentUnit, + bracketMatching, + foldKeymap, + syntaxHighlighting, + defaultHighlightStyle, +} from "@codemirror/language"; +import { + closeBrackets, + autocompletion, + closeBracketsKeymap, + completionKeymap, +} from "@codemirror/autocomplete"; +import { + lineNumbers, + highlightActiveLineGutter, + highlightSpecialChars, + drawSelection, + rectangularSelection, + crosshairCursor, + highlightActiveLine, + keymap, + EditorView, + showPanel, +} from "@codemirror/view"; + +// Theme +import { dracula } from "@uiw/codemirror-theme-dracula"; + +// Language +import { javascript } from "@codemirror/lang-javascript"; +import { python } from "@codemirror/lang-python"; +import { rust } from "@codemirror/lang-rust"; +import { cpp } from "@codemirror/lang-cpp"; +import { languageNameFacet } from "./language-facets"; + +const editor_url = "https://snapshots.slint.dev/master/editor/"; +const wasm_url = + "https://snapshots.slint.dev/master/wasm-interpreter/slint_wasm_interpreter.js"; +let slint_wasm_module = null; +// keep them alive +var all_instances = new Array(); + +// Function to create the Copy button and add it to the panel +function createCopyButton(view) { + const button = document.createElement("button"); + button.innerHTML = ` + Copy + + + +`; + button.style.marginRight = "10px"; + + button.onclick = () => { + const content = view.state.doc.toString(); + navigator.clipboard.writeText(content).then( + () => { + alert("Content copied to clipboard!"); + }, + (err) => { + console.error("Could not copy text: ", err); + }, + ); + }; + + return button; +} + +// Function to create the Run/Preview button and add it to the panel +function createRunButton(view) { + const button = document.createElement("button"); + button.innerHTML = ` + Open in SlintPad + + +`; + + button.onclick = () => { + const content = view.state.doc.toString(); + window.open( + `${editor_url}?snippet=${encodeURIComponent(content)}`, + "_blank", + ); + }; + + return button; +} + +// Define the status panel with copy and run buttons +function statusPanel(view) { + const dom = document.createElement("div"); + dom.className = "cm-status-panel"; + + // Add the buttons to the panel + const copyButton = createCopyButton(view); + dom.appendChild(copyButton); + + const language = view.state.facet(languageNameFacet); + if (language === "slint") { + const runButton = createRunButton(view); + dom.appendChild(runButton); + } + + return { + dom, + update(_update) { + // You can update the panel content based on editor state changes if needed + }, + }; +} + +// Debounce function to limit how often updates are made +function debounce(func, wait) { + let timeout; + return (...args) => { + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(this, args), wait); + }; +} + +async function updateWasmPreview(previewContainer, content) { + const { component, error_string } = + await slint_wasm_module.compile_from_string(content, ""); + var error_div = previewContainer.parentNode.querySelector(".error-status"); + if (error_string !== "") { + var text = document.createTextNode(error_string); + var p = document.createElement("pre"); + p.appendChild(text); + error_div.innerHTML = + "
" +
+            p.innerHTML +
+            "
"; + } else { + error_div.innerHTML = ""; + } + if (component !== undefined) { + const canvas_id = previewContainer.getAttribute("data-canvas-id"); + const instance = await component.create(canvas_id); + await instance.show(); + all_instances.push(instance); + } +} + +// Wrap updateWasmPreview in a debounce function (500ms delay) +const debouncedUpdateWasmPreview = debounce(updateWasmPreview, 500); + +async function initializePreviewContainers(previewContainer, _content) { + const canvas_id = "canvas_" + Math.random().toString(36).substring(2, 9); + const canvas = document.createElement("canvas"); + canvas.id = canvas_id; + previewContainer.appendChild(canvas); + previewContainer.setAttribute("data-canvas-id", `${canvas_id}`); + const error_div = document.createElement("div"); + error_div.classList.add("error-status"); + previewContainer.parentNode.appendChild(error_div); +} + +async function loadSlintWasmInterpreter(_editor) { + try { + if (slint_wasm_module) { + return; + } + + // Dynamically import the Slint WASM module + slint_wasm_module = await import(wasm_url); + await slint_wasm_module.default(); // Wait for WASM to initialize + + try { + slint_wasm_module.run_event_loop(); // Run the event loop, which will trigger an exception + } catch (e) { + // Swallow the expected JavaScript exception that breaks out of Rust's event loop + } + + return; + } catch (error) { + console.error( + "Error during Slint WASM interpreter initialization:", + error, + ); + throw error; // Re-throw error to handle it in the calling context + } +} + +// Initialize CodeMirror based on the language passed as a data attribute +window.initCodeMirror = (editorDiv, language, content) => { + // const editorDiv_id = editorDiv.getAttribute("id"); + + const extensions = [ + lineNumbers(), + highlightActiveLineGutter(), + highlightSpecialChars(), + history(), + foldGutter(), + drawSelection(), + indentUnit.of(" "), + EditorState.allowMultipleSelections.of(true), + indentOnInput(), + bracketMatching(), + closeBrackets(), + autocompletion(), + rectangularSelection(), + crosshairCursor(), + highlightActiveLine(), + highlightSelectionMatches(), + keymap.of([ + indentWithTab, + ...closeBracketsKeymap, + ...defaultKeymap, + ...historyKeymap, + ...foldKeymap, + ...completionKeymap, + ]), + syntaxHighlighting(defaultHighlightStyle, { fallback: true }), + languageNameFacet.of(language), + dracula, + showPanel.of(statusPanel), + ]; + + // Get the appropriate language extension + let isReadOnly = true; + let previewContainer; + + switch (language.toLowerCase()) { + case "javascript": + extensions.push(javascript()); + break; + case "python": + extensions.push(python()); + break; + case "cpp": + extensions.push(cpp()); + break; + case "rust": + extensions.push(rust()); + break; + case "slint": + isReadOnly = false; + extensions.push(javascript()); + if ( + editorDiv.getAttribute("data-readonly") === "true" || + editorDiv.getAttribute("data-ignore") === "true" + ) { + break; + } + previewContainer = document.createElement("div"); + previewContainer.classList.add("preview-container"); + editorDiv.classList.add("show-preview"); + extensions.push( + EditorView.updateListener.of(async (editor) => { + if (editor.docChanged) { + const newContent = editor.state.doc.toString(); + debouncedUpdateWasmPreview( + previewContainer, + newContent, + ); + } + }), + ); + break; + default: + } + + extensions.push(EditorView.editable.of(!isReadOnly)); + + const editor = new EditorView({ + state: EditorState.create({ + doc: content, + extensions: extensions, + }), + parent: editorDiv, + }); + + if (previewContainer) { + editorDiv.append(previewContainer); + loadSlintWasmInterpreter(editor) + .then(async () => { + initializePreviewContainers(previewContainer, content); + updateWasmPreview(previewContainer, content); + }) + .catch((error) => { + console.error("Error loading Slint WASM interpreter:", error); + }); + } +}; + +document.addEventListener("DOMContentLoaded", async () => { + // Find all the divs that need a CodeMirror editor + document + .querySelectorAll(".codemirror-editor") + .forEach((editorDiv) => { + const editorContent = editorDiv.querySelector( + ".codemirror-content", + ); + const language = editorDiv.getAttribute("data-lang"); + const content = editorContent.textContent.trim(); + window.initCodeMirror(editorDiv, language, content); + }); +}); diff --git a/component-sets/material/docs/src/components/editor/language-facets.js b/component-sets/material/docs/src/components/editor/language-facets.js new file mode 100644 index 000000000..89f4b28e7 --- /dev/null +++ b/component-sets/material/docs/src/components/editor/language-facets.js @@ -0,0 +1,11 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Facet } from "@codemirror/state"; + +// Define a custom facet to hold the language name +export const languageNameFacet = Facet.define({ + combine(languages) { + return languages.length ? languages[0] : null; // Combine to get the first language if set + }, +}); diff --git a/component-sets/material/docs/src/components/editor/package.json b/component-sets/material/docs/src/components/editor/package.json new file mode 100644 index 000000000..720259bd5 --- /dev/null +++ b/component-sets/material/docs/src/components/editor/package.json @@ -0,0 +1,29 @@ +{ + "name": "slint-docs", + "version": "1.11.0", + "type": "module", + "scripts": { + "build": "rollup -c", + "format": "biome format", + "format:fix": "biome format --write", + "lint": "biome lint", + "lint:fix": "biome lint --fix" + }, + "devDependencies": { + "rollup": "^3.5.1", + "@rollup/plugin-node-resolve": "^15.0.1" + }, + "dependencies": { + "@codemirror/commands": "^6.1.2", + "@codemirror/lang-javascript": "^6.1.1", + "@codemirror/lang-rust": "^6.0.0", + "@codemirror/lang-cpp": "^6.0.0", + "@codemirror/lang-python": "^6.1.0", + "@codemirror/search": "^6.2.3", + "@codemirror/theme-one-dark": "^6.1.0", + "@codemirror/view": "^6.6.0", + "minify": "^9.1.0", + "@uiw/codemirror-theme-dracula": "^4.23.5", + "@babel/runtime": "^7.25.7" + } +} diff --git a/component-sets/material/docs/src/components/editor/rollup.config.js b/component-sets/material/docs/src/components/editor/rollup.config.js new file mode 100644 index 000000000..e4697c8af --- /dev/null +++ b/component-sets/material/docs/src/components/editor/rollup.config.js @@ -0,0 +1,19 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import resolve from "@rollup/plugin-node-resolve"; + +export default { + input: "codemirror.js", // Adjust to your entry file + output: { + file: "../../target/slintdocs/_static/cm6.bundle.js", + format: "iife", // Use IIFE format for browser compatibility + name: "cm6", // Name for the global variable + }, + plugins: [ + resolve(), // Helps Rollup find external modules + ], + external: [ + "https://snapshots.slint.dev/master/wasm-interpreter/slint_wasm_interpreter.js", // Mark as external + ], +}; diff --git a/component-sets/material/docs/src/content.config.ts b/component-sets/material/docs/src/content.config.ts new file mode 100644 index 000000000..f078c0722 --- /dev/null +++ b/component-sets/material/docs/src/content.config.ts @@ -0,0 +1,9 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import { defineCollection } from "astro:content"; +import { docsLoader } from "@astrojs/starlight/loaders"; +import { docsSchema } from "@astrojs/starlight/schema"; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/component-sets/material/docs/src/content/docs/basic-widgets/button.mdx b/component-sets/material/docs/src/content/docs/basic-widgets/button.mdx new file mode 100644 index 000000000..6ba122735 --- /dev/null +++ b/component-sets/material/docs/src/content/docs/basic-widgets/button.mdx @@ -0,0 +1,106 @@ +--- + +title: Button +description: Button api. +--- +import SlintProperty from '/src/components/SlintProperty.astro'; +import Link from '/src/components/Link.astro'; + +```slint playground +import { Button, VerticalBox } from "std-widgets.slint"; +export component Example inherits Window { + width: 200px; + height: 100px; + VerticalBox { + label := Text { + text: "Button not clicked"; + } + Button { + text: "Click Me"; + clicked => { + label.text = " Button clicked"; + } + } + } +} +``` + +A simple button. Common types of buttons can also be created with . + + + + +## Properties + +### checkable + +Shows whether the button can be checked or not. This enables the `checked` property to possibly become true. + +```slint "checkable: true;" +Button { + text: "Checkable Button"; + checkable: true; +} +``` + + +### checked + +Shows whether the button is checked or not. Needs `checkable` to be true to work. + + +### enabled + +Defaults to true. When false, the button cannot be pressed. + + +### has-focus + +Set to true when the button has keyboard focus + + +### icon + +The image to show in the button. Note that not all styles support drawing icons. + + +### pressed + +Set to true when the button is pressed. + + +### text + +The text written in the button. + +```slint 'text: "Button with text";' +Button { + text: "Button with text"; +} +``` + + +### primary + +If set to true the button is displayed with the primary accent color. + + +### colorize-icon + +If set to true, the icon will be colorized to the same color as the Button's text color. + + +## Callbacks + +### clicked() + +Invoked when clicked: A finger or the left mouse button is pressed, then released on this element. + +```slint {3-5} +Button { + text: "Click me"; + clicked() => { + debug("Button clicked"); + } +} +``` diff --git a/component-sets/material/docs/src/content/docs/basic-widgets/checkbox.mdx b/component-sets/material/docs/src/content/docs/basic-widgets/checkbox.mdx new file mode 100644 index 000000000..42f84b5ce --- /dev/null +++ b/component-sets/material/docs/src/content/docs/basic-widgets/checkbox.mdx @@ -0,0 +1,74 @@ +--- + +title: CheckBox +description: CheckBox api. +--- + +import CodeSnippetMD from '/src/components/CodeSnippetMD.astro'; +import SlintProperty from '/src/components/SlintProperty.astro'; + +{/* +```slint +import { CheckBox } from "std-widgets.slint"; +export component Example inherits Window { + width: 200px; + height: 25px; + background: transparent; + CheckBox { + x: 5px; + width: parent.width; + height: parent.height; + text: "Hello World"; + } +} +``` + */} + +Use a `CheckBox` to let the user select or deselect values, for example in a list with multiple options. Consider using a `Switch` element instead if the action resembles more something that's turned on or off. + +## Properties + +### checked + +Whether the checkbox is checked or not. +```slint "checked: true;" +CheckBox { + text: self.checked ? "Checked" : "Not checked"; + checked: true; +} +``` + + +### enabled + +Defaults to true. When false, the checkbox can't be pressed. + + +### has-focus + +Set to true when the checkbox has keyboard focus. + + +### text + +The text written next to the checkbox. +```slint 'text: "CheckBox with text";' +CheckBox { + text: "CheckBox with text"; +} +``` + + +## Callbacks + +### toggled() +The checkbox value changed + +```slint {3-5} +CheckBox { + text: "CheckBox"; + toggled() => { + debug("CheckBox checked: ", self.checked); + } +} +``` diff --git a/component-sets/material/docs/src/content/docs/index.mdx b/component-sets/material/docs/src/content/docs/index.mdx new file mode 100644 index 000000000..ef88b868d --- /dev/null +++ b/component-sets/material/docs/src/content/docs/index.mdx @@ -0,0 +1,119 @@ +--- + +title: Overview +description: Widgets Overview. +--- + +import CodeSnippetMD from '/src/components/CodeSnippetMD.astro'; +import SlintProperty from '/src/components/SlintProperty.astro'; +import Link from '/src/components/Link.astro'; + +```slint playground +import { Palette, HorizontalBox } from "std-widgets.slint"; + +export component MyCustomWidget { + in property text <=> label.text; + + Rectangle { + background: Palette.control-background; + + HorizontalBox { + label := Text { + color: Palette.control-foreground; + } + } + } +} +``` + + +Slint provides a series of built-in widgets that can be imported from `"std-widgets.slint"`. + +The widget appearance depends on the selected style. +See for details how to select the style. If no style is selected, `native` is the default. If `native` isn't available, `fluent` is the default. + + +All widgets support all . + +## Palette Properties + +Use `Palette` to create custom widgets that match the colors of +the selected style e.g. fluent, cupertino, material, or qt. + +### background + +Defines the default background brush. Use this if none of the more specialized background brushes apply. + + +### foreground + +Defines the foreground brush that is used for content that is displayed on `background` brush. + + +### alternate-background + +Defines an alternate background brush that is used for example for text input controls or panels like a side bar. + + +### alternate-foreground + +Defines the foreground brush that is used for content that is displayed on `alternate-background` brush. + + +### control-background + +Defines the default background brush for controls, such as push buttons, combo boxes, etc. + + +### control-foreground + +Defines the foreground brush that is used for content that is displayed on `control-background` brush. + + +### accent-background + +Defines the background brush for highlighted controls such as primary buttons. + + +### accent-foreground + +Defines the foreground brush that is used for content that is displayed on `accent-background` brush. + + +### selection-background + +Defines the background brush that is used to highlight a selection such as a text selection. + + +### selection-foreground + +Defines the foreground brush that is used for content that is displayed on `selection-background` brush. + + +### border + +Defines the brush that is used for borders such as separators and widget borders. + + +### color-scheme + +Read this property to determine the color scheme used by the palette. +Set this property to force a dark or light color scheme. All styles +except for the Qt style support setting a dark or light color scheme. + + + +## StyleMetrics Properties + +Use `StyleMetrics` to create custom widgets that match the layout settings of +the selected style e.g. fluent, cupertino, material, or qt. + +### layout-spacing + +Defines the default layout spacing. This spacing is also used by `VerticalBox`, `HorizontalBox` and `GridBox`. + + +### layout-padding + +Defines the default layout padding. This padding is also used by `VerticalBox`, `HorizontalBox` and `GridBox`. + diff --git a/component-sets/material/docs/src/content/docs/style.mdx b/component-sets/material/docs/src/content/docs/style.mdx new file mode 100644 index 000000000..33893d444 --- /dev/null +++ b/component-sets/material/docs/src/content/docs/style.mdx @@ -0,0 +1,89 @@ +--- + +// cSpell: ignore DSLINT +title: Widget Styles +description: std-widgets Style. +--- + + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + +You can modify the look of these widgets by choosing a style. + +The styles available include: + +| Style Name | Light Variant | Dark Variant | Description | +|------------|--------------|--------------|------------| +| `fluent` | `fluent-light`| `fluent-dark`| These variants belong to the **Fluent** style, which is based on the [Fluent Design System](https://fluent2.microsoft.design/). | +| `material` | `material-light`| `material-dark`| These variants are part of the **Material** style, which follows the [Material Design](https://m3.material.io). | +| `cupertino`| `cupertino-light`| `cupertino-dark`| The **Cupertino** variants emulate the style used by macOS. | +| `cosmic`| `cosmic-light`| `cosmic-dark`| The **Cosmic** variants emulate the style used by [Cosmic Desktop](https://github.com/pop-os/cosmic). | +| `qt` | | | The **Qt** style uses [Qt](https://en.wikipedia.org/wiki/Qt_(software)) to render widgets. This style requires Qt to be installed on your system. | +| `native` | | | This is an alias to one of the other styles depending on the platform. It is `cupertino` on macOS, `fluent` on Windows, `material` on Android, `qt` on linux if Qt is available, or `fluent` otherwise. | + + +By default, the styles automatically adapt to the system's dark or light color setting. Select a `-light` or `-dark` variant to override the system setting and always show either dark or light colors. + +The widget style is determined at your project's compile time. The method to select a style depends on how you use Slint. + +If no style is selected, `native` is the default. + + + + +You can select the style before starting your compilation by setting the `SLINT_STYLE` environment variable to the name of your chosen style. + +When using the `slint_build` API, call the [`slint_build::compile_with_config()`](https://docs.rs/slint-build/newest/slint_build/fn.compile_with_config.html) function. + +When using the `slint_interpreter` API, call the [`slint_interpreter::ComponentCompiler::set_style()`](https://docs.rs/slint-interpreter/newest/slint_interpreter/struct.ComponentCompiler.html#method.set_style) function. + + + +Define a `SLINT_STYLE` CMake cache variable to contain the style name as a string. This can be done, for instance, on the command line: + +```sh +cmake -DSLINT_STYLE="material" /path/to/source +``` + + + +You can select the style by setting the `style` property in [`LoadFileOptions`](slint-node:interfaces/LoadFileOptions) passed to [`loadFile`](slint-node:functions/loadFile): + +```js +import * as slint from "slint-ui"; +let ui = slint.loadFile("main.slint", { style: "fluent" }); +let main = new ui.Main(); +main.greeting = "Hello friends"; +``` + + + + +## Previewing Designs With `slint-viewer` + +Select the style either by setting the `SLINT_STYLE` environment variable, or by passing the style name with the `--style` argument: + +slint-viewer --style material /path/to/design.slint + +## Previewing Designs With The Slint Visual Studio Code Extension + +To select the style, first open the Visual Studio Code settings editor: + + + +File > Preferences > Settings + + +Code > Preferences > Settings + + +File > Preferences > Settings + + + +Then enter the style name in Extensions > Slint > Preview:Style + +## Previewing Designs With The Generic LSP Process + +Choose the style by setting the `SLINT_STYLE` environment variable before launching the process. +Alternatively, if your IDE integration allows for command line parameters, you can specify the style using `--style`. diff --git a/component-sets/material/docs/src/misc/Slint-tmLanguage.json b/component-sets/material/docs/src/misc/Slint-tmLanguage.json new file mode 100644 index 000000000..81bd88710 --- /dev/null +++ b/component-sets/material/docs/src/misc/Slint-tmLanguage.json @@ -0,0 +1,251 @@ +{ + "name": "slint", + "scopeName": "source.slint", + "patterns": [ + { + "include": "#document" + } + ], + "repository": { + "document": { + "patterns": [ + { + "include": "#general" + }, + { + "match": "(?", + "captures": { + "1": { + "name": "entity.name.function" + } + } + }, + { + "match": "(?)", + "beginCaptures": { + "1": { + "name": "keyword.other" + } + }, + "patterns": [ + { + "match": "<([a-zA-Z_][a-zA-Z0-9_-]*)>", + "captures": { + "1": { + "name": "entity.name.type" + } + } + }, + { + "match": "[a-zA-Z_][a-zA-Z0-9_-]*", + "name": "variable.parameter" + }, + { + "match": "\\b(<=>|:)\\b", + "name": "keyword.operator" + } + ] + } + ] + }, + "block-comments": { + "patterns": [ + { + "name": "comment.block", + "begin": "/\\*", + "end": "\\*/", + "comment": "Block comment.", + "patterns": [ + { + "include": "#block-comments" + } + ] + } + ] + } + } +} diff --git a/component-sets/material/docs/src/styles/custom.css b/component-sets/material/docs/src/styles/custom.css new file mode 100644 index 000000000..38a53339c --- /dev/null +++ b/component-sets/material/docs/src/styles/custom.css @@ -0,0 +1,132 @@ +.code-image-container { + display: flex; + flex-direction: row; + width: 100%; + align-items: center; +} + +.code-block { + width: 80%; + /* Reduced from 300px to accommodate the gap */ + overflow-x: auto; +} + +.image-block { + width: 20%; + margin-top: 0 !important; + margin-left: 20px; + border-radius: 10px; +} + +.image-block img { + width: auto; + height: auto; + border-radius: 3px; +} + +.no-underline { + text-decoration: none; +} + +.default-value code { + margin-left: -0.3rem; +} + +.default-value { + margin-left: 0.1rem; + font-size: 0.8em; +} + +.plain-code { + background: none !important; +} + +.sl-markdown-content table td:first-child { + min-width: 100px !important; + /* Tweak the table so the first column is wider */ +} + +/* Dark mode colors. */ +:root { + --sl-hue-blue: 222; + --sl-text-h3: var(--sl-text-2xl); + --sl-text-h4: 1.2rem; + --sl-content-width: 50rem; + --sl-color-bg: #1b1b1f; + --sl-color-gray-6: #161618; + --sl-color-hairline: #212329; + --sl-color-hairline-shade: var(--sl-color-hairline); + --badge-border-color: --sl-color-hairline; + --slint-code-background: #151517; + + .screenshot-container { + background-color: #cdcdcd; + } + + --sl-color-accent-low: hsl(228, 70%, 30%); + --sl-color-accent: hsl(228, 100%, 70%); + --sl-color-accent-high: hsl(228, 90%, 85%); +} + +/* Light mode colors. */ +:root[data-theme="light"] { + --sl-text-h3: var(--sl-text-2xl); + --sl-content-width: 50rem; + --sl-color-bg: #ffffff; + --badge-border-color: lightgrey; + --sl-color-hairline: #edeef3; + --slint-code-background: #f6f6f7; + + .screenshot-container { + background-color: whitesmoke; + } + + --sl-color-accent-high: hsl(222, 80%, 35%); + --sl-color-accent: hsl(222, 89%, 55%); + --sl-color-accent-low: hsl(222, 89%, 85%); + .site-title { + color: #000; + } +} + +.hero { + display: flex; + gap: 1.5rem; + flex-direction: column-reverse; + padding-block: initial; +} + +.hero .copy { + align-items: center; +} + +.site-title { + font-size: 1.3rem; + color: #fff; + margin-top: -4px; +} + +span { + display: inline-block; + margin-top: 2px; +} + +.version-banner { + background-color: var(--sl-color-orange-low); + box-shadow: var(--sl-shadow-sm); + color: var(--sl-color-orange-high); + line-height: var(--sl-line-height-headings); + padding: var(--sl-nav-pad-y) var(--sl-nav-pad-x); + text-align: center; + text-wrap: balance; +} + +.version-banner a { + color: var(--sl-color-orange-high); +} + +.sl-markdown-content { + .slint-property { + margin-top: 0.1rem; + } +} diff --git a/component-sets/material/docs/src/styles/theme.css b/component-sets/material/docs/src/styles/theme.css new file mode 100644 index 000000000..6c09eb0b8 --- /dev/null +++ b/component-sets/material/docs/src/styles/theme.css @@ -0,0 +1,34 @@ +theme-switcher { + align-items: center; +} +.theme-selector-light, +.theme-selector-dark { + user-select: none; + z-index: 999999; + position: relative; + cursor: pointer; +} +.theme-selector-light:hover, +.theme-selector-dark:hover { + color: var(--sl-color-accent-high); +} +:root { + .theme-selector-light { + display: none; + } + .theme-selector-dark { + display: inline-block; + } +} +:root[data-theme="light"] { + .theme-selector-light { + display: inline-block; + } + .theme-selector-dark { + display: none; + } + .theme-selector-light:hover, + .theme-selector-dark:hover { + color: var(--sl-color-accent); + } +} diff --git a/component-sets/material/docs/src/utils/link-data.json b/component-sets/material/docs/src/utils/link-data.json new file mode 100644 index 000000000..a7ba4621a --- /dev/null +++ b/component-sets/material/docs/src/utils/link-data.json @@ -0,0 +1,200 @@ +{ + "AnimationRef": { + "href": "reference/primitive-types/#animation" + }, + "AnimationTick": { + "href": "reference/global-functions/builtinfunctions/#animation-tick---duration" + }, + "angle": { + "href": "reference/primitive-types/#angle" + }, + "bool": { + "href": "reference/primitive-types/#bool" + }, + "brush": { + "href": "reference/primitive-types/#brush" + }, + "BorderRadiusRectangle": { + "href": "reference/elements/rectangle/#border-radius-properties" + }, + "cache-rendering-hint": { + "href": "reference/common/#cache-rendering-hint" + }, + "ColorsRef": { + "href": "reference/colors-and-brushes/" + }, + "color": { + "href": "reference/primitive-types/#color" + }, + "ComponentLibraries": { + "href": "guide/language/coding/file/#component-libraries" + }, + "CommonProperties": { + "href": "reference/common/" + }, + "duration": { + "href": "reference/primitive-types/#duration" + }, + "DebugFn": { + "href": "reference/global-functions/builtinfunctions/#debug" + }, + "easing": { + "href": "reference/primitive-types/#easing" + }, + "EnumType": { + "href": "reference/global-structs-enums/" + }, + "Expressions": { + "href": "guide/language/coding/expressions-and-statements/" + }, + "float": { + "href": "reference/primitive-types/#float" + }, + "FocusHandling": { + "href": "guide/development/focus/" + }, + "FontHandling": { + "href": "guide/development/fonts/" + }, + "GridLayout": { + "href": "reference/layouts/gridlayout/" + }, + "Globals": { + "href": "reference/global-structs-enums/" + }, + "HorizontalBox": { + "href": "reference/std-widgets/layouts/horizontalbox/" + }, + "HorizontalLayout": { + "href": "reference/layouts/horizontallayout/" + }, + "Image": { + "href": "reference/elements/image/" + }, + "ImageType": { + "href": "reference/primitive-types/#image" + }, + "int": { + "href": "reference/primitive-types/#int" + }, + "KeyEvent": { + "href": "reference/keyboard-input/overview/" + }, + "length": { + "href": "reference/primitive-types/#length" + }, + "ListView": { + "href": "reference/std-widgets/views/listview/" + }, + "LineEdit": { + "href": "reference/std-widgets/views/lineedit/" + }, + "LinuxkmsBackend": { + "href": "guide/backends-and-renderers/backend_linuxkms/" + }, + "MenuBar": { + "href": "reference/window/menubar/" + }, + "Menu": { + "href": "reference/window/contextmenuarea/#menu" + }, + "Modules": { + "href": "guide/language/coding/file/#modules" + }, + "Models": { + "href": "guide/language/coding/repetition-and-data-models/#models" + }, + "NumericTypes": { + "href": "reference/primitive-types/#numeric-types" + }, + "Path": { + "href": "reference/elements/path/" + }, + "percent": { + "href": "reference/primitive-types/#percent" + }, + "physicalLength": { + "href": "reference/primitive-types/#physical-length" + }, + "PopupWindow": { + "href": "reference/window/popupwindow/" + }, + "ProgressIndicator": { + "href": "reference/std-widgets/basic-widgets/progressindicator/" + }, + "Purity": { + "href": "guide/language/concepts/reactivity/" + }, + "Rectangle": { + "href": "reference/elements/rectangle/" + }, + "relativeFontSize": { + "href": "reference/primitive-types/#relative-font-size" + }, + "slintFile": { + "href": "guide/language/coding/file/" + }, + "ScrollView": { + "href": "reference/std-widgets/views/scrollview/" + }, + "StandardButton": { + "href": "reference/std-widgets/basic-widgets/standardbutton/" + }, + "StringType": { + "href": "reference/primitive-types/#string" + }, + "StructType": { + "href": "reference/global-structs-enums/" + }, + "StyleWidgets": { + "href": "reference/std-widgets/style/" + }, + "Text": { + "href": "reference/elements/text/" + }, + "TextEdit": { + "href": "reference/std-widgets/views/textedit/" + }, + "TextInput": { + "href": "reference/keyboard-input/textinput/" + }, + "Timer": { + "href": "reference/timer/" + }, + "Types": { + "href": "reference/primitive-types/" + }, + "VerticalBox": { + "href": "reference/std-widgets/layouts/verticalbox/" + }, + "VerticalLayout": { + "href": "reference/layouts/verticallayout/" + }, + "QtBackend": { + "href": "guide/backends-and-renderers/backend_qt/" + }, + "Window": { + "href": "reference/window/window/" + }, + "WinitBackend": { + "href": "guide/backends-and-renderers/backend_winit/" + }, + "translations": { + "href": "guide/development/translations/" + }, + "backends_and_renderers": { + "href": "guide/backends-and-renderers/backends_and_renderers/" + }, + "globals": { + "href": "guide/language/coding/globals/" + }, + "quickstart": { + "href": "tutorial/quickstart/" + }, + "modules": { + "href": "guide/language/coding/file/#modules" + }, + "index": { + "href": "" + } +} diff --git a/component-sets/material/docs/src/utils/site-config.ts b/component-sets/material/docs/src/utils/site-config.ts new file mode 100644 index 000000000..841888a25 --- /dev/null +++ b/component-sets/material/docs/src/utils/site-config.ts @@ -0,0 +1,13 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export const BASE_URL = "https://localhost"; +export const BASE_PATH = "/docs/"; +export const SLINT_DOWNLOAD_VERSION = "nightly"; +export const CPP_BASE_URL = `${BASE_URL}${BASE_PATH}../cpp/`; +export const RUST_BASE_URL = `${BASE_URL}${BASE_PATH}../rust/`; +export const RUST_SLINT_CRATE_URL = `${RUST_BASE_URL}slint/`; +export const RUST_SLINT_INTERPRETER_CRATE_URL = `${RUST_BASE_URL}slint_interpreter/`; +export const RUST_SLINT_BUILD_CRATE_URL = `${RUST_BASE_URL}slint_build/`; +export const NODEJS_BASE_URL = `${BASE_URL}${BASE_PATH}../node/`; +export const PYTHON_BASE_URL = `${BASE_URL}${BASE_PATH}../python/`; diff --git a/component-sets/material/docs/src/utils/utils.ts b/component-sets/material/docs/src/utils/utils.ts new file mode 100644 index 000000000..daa4efea8 --- /dev/null +++ b/component-sets/material/docs/src/utils/utils.ts @@ -0,0 +1,210 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export async function getEnumContent(enumName: string | undefined) { + if (enumName) { + try { + const module = await import( + `../content/collections/enums/${enumName}.md` + ); + return module.compiledContent(); + } catch (error) { + console.error(`Failed to load enum file for ${enumName}:`, error); + return ""; + } + } + return ""; +} + +export async function getStructContent( + structName: string | undefined, +): Promise { + if (structName === undefined) { + return ""; + } + const baseStruct = structName.replace(/[\[\]]/g, ""); + + if (baseStruct === "Time" || baseStruct === "Date") { + try { + const module = await import( + `../content/collections/std-widgets/${baseStruct}.md` + ); + return module.compiledContent(); + } catch (error) { + console.error(`Failed to load enum file for ${baseStruct}:`, error); + return ""; + } + } + + if (baseStruct) { + try { + const module = await import( + `../content/collections/structs/${baseStruct}.md` + ); + return module.compiledContent(); + } catch (error) { + console.error( + `Failed to load struct file for ${baseStruct}:`, + error, + ); + return ""; + } + } + return ""; +} + +export type KnownType = + | "angle" + | "bool" + | "brush" + | "color" + | "duration" + | "easing" + | "enum" + | "float" + | "image" + | "int" + | "length" + | "percent" + | "physical-length" + | "Point" + | "relative-font-size" + | "string" + | "struct"; + +export type PropertyVisibility = "private" | "in" | "out" | "in-out"; + +export interface TypeInfo { + href: string; + defaultValue: string; +} + +export function getTypeInfo(typeName: KnownType): TypeInfo { + const baseType = typeName.replace(/[\[\]]/g, "") as KnownType; + switch (baseType) { + case "angle": + return { + href: linkMap.angle.href, + defaultValue: "0deg", + }; + case "bool": + return { + href: linkMap.bool.href, + defaultValue: "false", + }; + case "brush": + return { + href: linkMap.brush.href, + defaultValue: "a transparent brush", + }; + case "color": + return { + href: linkMap.color.href, + defaultValue: "a transparent color", + }; + case "duration": + return { + href: linkMap.duration.href, + defaultValue: "0ms", + }; + case "easing": + return { + href: linkMap.easing.href, + defaultValue: "linear", + }; + case "enum": + return { + href: "", // No need to link here! + defaultValue: "the first enum value", + }; + case "float": + return { + href: linkMap.float.href, + defaultValue: "0.0", + }; + case "image": + return { + href: linkMap.ImageType.href, + defaultValue: "the empty image", + }; + case "int": + return { + href: linkMap.int.href, + defaultValue: "0", + }; + case "length": + return { + href: linkMap.length.href, + defaultValue: "0px", + }; + case "percent": + return { + href: linkMap.percent.href, + defaultValue: "0%", + }; + case "physical-length": + return { + href: linkMap.physicalLength.href, + defaultValue: "0phx", + }; + case "Point": + return { + href: linkMap.StructType.href, + defaultValue: "(0px, 0px)", + }; + case "relative-font-size": + return { + href: linkMap.relativeFontSize.href, + defaultValue: "0rem", + }; + case "string": + return { + href: linkMap.StringType.href, + defaultValue: '""', + }; + case "struct": + return { + href: linkMap.StructType.href, + defaultValue: "a struct with all default values", + }; + default: { + console.error("Unknown type: ", typeName); + return { + href: "", + defaultValue: "", + }; + } + } +} + +export function extractLines( + fileContent: string, + start: number, + end: number, +): string { + return fileContent + .split("\n") + .slice(start - 1, end) + .join("\n"); +} + +export function removeLeadingSpaces(input: string, spaces = 4): string { + const lines = input.split("\n"); + const modifiedLines = lines.map((line) => { + const leadingSpaces = line.match(/^ */)?.[0].length ?? 0; + if (leadingSpaces >= spaces) { + return line.slice(spaces); + } + return line; + }); + return modifiedLines.join("\n"); +} + +type LinkMapType = { + [K: string]: { + href: string; + }; +}; + +import linkMapData from "./link-data.json" assert { type: "json" }; +export const linkMap: Readonly = linkMapData; diff --git a/component-sets/material/docs/tests/smoke-test.spec.ts b/component-sets/material/docs/tests/smoke-test.spec.ts new file mode 100644 index 000000000..ec173ad85 --- /dev/null +++ b/component-sets/material/docs/tests/smoke-test.spec.ts @@ -0,0 +1,18 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT +import { test, expect } from "@playwright/test"; + +test("smoke test", async ({ page }) => { + await page.goto(""); + await expect(page.locator('[id="_top"]')).toContainText("Welcome to Slint"); + await page + .getByLabel("Main") + .getByRole("link", { name: "Reference" }) + .click(); + await page.getByText("Visual Elements").click(); + await page.getByRole("link", { name: "Image" }).click(); + await page.getByRole("link", { name: "colorize" }).click(); + await expect(page.locator("#colorize")).toContainText("colorize"); + await page.getByRole("link", { name: "brush", exact: true }).click(); + await expect(page.locator("#brush")).toContainText("brush"); +}); diff --git a/component-sets/material/docs/tsconfig.json b/component-sets/material/docs/tsconfig.json new file mode 100644 index 000000000..db77b46ce --- /dev/null +++ b/component-sets/material/docs/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "astro/tsconfigs/strict", + "exclude": ["dist", "test-results", "playwright-report"] +} diff --git a/component-sets/material/examples/gallery/Cargo.toml b/component-sets/material/examples/gallery/Cargo.toml new file mode 100644 index 000000000..9a56bc723 --- /dev/null +++ b/component-sets/material/examples/gallery/Cargo.toml @@ -0,0 +1,36 @@ +# Copyright Β© SixtyFPS GmbH +# SPDX-License-Identifier: MIT + +[package] +name = "material-gallery" +version = "1.11.0" +authors = ["Slint Developers "] +edition = "2021" +publish = false +license = "MIT" + +[lib] +crate-type = ["lib", "cdylib"] +path = "src/lib.rs" +name = "gallery_lib" + +[[bin]] +path = "src/main.rs" +name = "gallery" + +[dependencies] +slint = { path = "../../../../api/rs/slint", features = ["backend-android-activity-06"] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen = { version = "0.2" } +console_error_panic_hook = "0.1.5" + +[build-dependencies] +slint-build = { path = "../../../../api/rs/build" } + +[package.metadata.android] +package = "com.slint.material" +apk_name = "gallery" + +[package.metadata.android.application] +label = "Slint Material" diff --git a/component-sets/material/examples/gallery/build.rs b/component-sets/material/examples/gallery/build.rs new file mode 100644 index 000000000..ec3df79ca --- /dev/null +++ b/component-sets/material/examples/gallery/build.rs @@ -0,0 +1,6 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +fn main() { + slint_build::compile("ui/main.slint").expect("Slint build failed"); +} diff --git a/component-sets/material/examples/gallery/index.html b/component-sets/material/examples/gallery/index.html new file mode 100644 index 000000000..14c95293f --- /dev/null +++ b/component-sets/material/examples/gallery/index.html @@ -0,0 +1,54 @@ + + + + + + + + + + musi lili confetti (Web Assembly version) + + + + +
+
Loading...
+
+
+ +
+ + + + diff --git a/component-sets/material/examples/gallery/src/lib.rs b/component-sets/material/examples/gallery/src/lib.rs new file mode 100644 index 000000000..16d7cce5c --- /dev/null +++ b/component-sets/material/examples/gallery/src/lib.rs @@ -0,0 +1,25 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +slint::include_modules!(); + +fn ui() -> MainWindow { + MainWindow::new().unwrap() +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))] +pub fn main() { + let ui = ui(); + ui.run().unwrap(); +} + +#[cfg(target_os = "android")] +#[no_mangle] +fn android_main(android_app: slint::android::AndroidApp) { + slint::android::init(android_app).unwrap(); + let ui = ui(); + ui.run().unwrap(); +} diff --git a/component-sets/material/examples/gallery/src/main.rs b/component-sets/material/examples/gallery/src/main.rs new file mode 100644 index 000000000..654ad2352 --- /dev/null +++ b/component-sets/material/examples/gallery/src/main.rs @@ -0,0 +1,9 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +// In order to be compatible with both desktop, wasm, and android, the example is both a binary and a library. +// Just forward to the library in main + +fn main() { + gallery_lib::main(); +} diff --git a/component-sets/material/examples/gallery/ui/components/component_card.slint b/component-sets/material/examples/gallery/ui/components/component_card.slint new file mode 100644 index 000000000..93370e17a --- /dev/null +++ b/component-sets/material/examples/gallery/ui/components/component_card.slint @@ -0,0 +1,42 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { + MaterialText, + OutlinedCard, + Typography, + MaterialStyleMetrics +} from "../../../../material.slint"; + +export component ComponentCard { + in property title; + + HorizontalLayout { + alignment: center; + + VerticalLayout { + spacing: 4px; + alignment: start; + + MaterialText { + horizontal_alignment: center; + text: root.title; + style: Typography.title_medium; + } + + OutlinedCard { + width: 360px; + + VerticalLayout { + padding_left: 2px; + padding_right: self.padding_left; + padding_top: MaterialStyleMetrics.padding_8; + padding_bottom: self.padding_top; + spacing: MaterialStyleMetrics.spacing_8; + + @children + } + } + } + } +} diff --git a/component-sets/material/examples/gallery/ui/components/group.slint b/component-sets/material/examples/gallery/ui/components/group.slint new file mode 100644 index 000000000..136b0102e --- /dev/null +++ b/component-sets/material/examples/gallery/ui/components/group.slint @@ -0,0 +1,31 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { + MaterialText, + MaterialPalette, + Typography +} from "../../../../material.slint"; + +export component Group { + in property title; + + Rectangle { + border_radius: 12px; + background: MaterialPalette.surface_bright; + + VerticalLayout { + alignment: start; + padding: 8px; + spacing: 16px; + + MaterialText { + horizontal_alignment: center; + text: root.title; + style: Typography.headline_small; + } + + @children + } + } +} diff --git a/component-sets/material/examples/gallery/ui/components/text_icon_button.slint b/component-sets/material/examples/gallery/ui/components/text_icon_button.slint new file mode 100644 index 000000000..615d1bb22 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/components/text_icon_button.slint @@ -0,0 +1,24 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { + IconButton, + MaterialText +} from "../../../../material.slint"; + +export component TextIconButton { + in property icon <=> button.icon; + in property text <=> label.text; + + VerticalLayout { + HorizontalLayout { + alignment: center; + + button := IconButton {} + } + + label := MaterialText { + horizontal_alignment: center; + } + } +} diff --git a/component-sets/material/examples/gallery/ui/icons.slint b/component-sets/material/examples/gallery/ui/icons.slint new file mode 100644 index 000000000..97ff039f7 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons.slint @@ -0,0 +1,68 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export global FilledIcons { + out property account_box: @image-url("./icons/filled/account_box.svg"); + out property calendar_month: @image-url("./icons/filled/calendar_month.svg"); + out property delete: @image-url("./icons/filled/delete.svg"); + out property favorite: @image-url("./icons/filled/favorite.svg"); + out property inbox: @image-url("./icons/filled/inbox.svg"); + out property music_note: @image-url("./icons/filled/music_note.svg"); + out property play_arrow: @image-url("./icons/filled/play_arrow.svg"); + out property today: @image-url("./icons/filled/today.svg"); + out property add: @image-url("./icons/filled/add.svg"); + out property chat_bubble: @image-url("./icons/filled/chat_bubble.svg"); + out property edit: @image-url("./icons/filled/edit.svg"); + out property group: @image-url("./icons/filled/group.svg"); + out property mail: @image-url("./icons/filled/mail.svg"); + out property outbox: @image-url("./icons/filled/outbox.svg"); + out property search: @image-url("./icons/filled/search.svg"); + out property video_chat: @image-url("./icons/filled/video_call.svg"); + out property bookmark: @image-url("./icons/filled/bookmark.svg"); + out property check: @image-url("./icons/filled/check.svg"); + out property explore: @image-url("./icons/filled/explore.svg"); + out property image: @image-url("./icons/filled/image.svg"); + out property more_vert: @image-url("./icons/filled/more_vert.svg"); + out property pets: @image-url("./icons/filled/pets.svg"); + out property settings: @image-url("./icons/filled/settings.svg"); + out property view_week: @image-url("./icons/filled/view_week.svg"); + out property light_mode: @image-url("./icons/filled/light_mode.svg"); + out property dark_mode: @image-url("./icons/filled/dark_mode.svg"); + out property dashboard: @image-url("./icons/filled/dashboard.svg"); + out property pause: @image-url("./icons/filled/pause.svg"); + out property archive: @image-url("./icons/filled/archive.svg"); + out property share: @image-url("./icons/filled/share.svg"); +} + +export global OutlinedIcons { + out property account_box: @image-url("./icons/outlined/account_box.svg"); + out property calendar_month: @image-url("./icons/outlined/calendar_month.svg"); + out property delete: @image-url("./icons/outlined/delete.svg"); + out property favorite: @image-url("./icons/outlined/favorite.svg"); + out property inbox: @image-url("./icons/outlined/inbox.svg"); + out property music_note: @image-url("./icons/outlined/music_note.svg"); + out property play_arrow: @image-url("./icons/outlined/play_arrow.svg"); + out property today: @image-url("./icons/outlined/today.svg"); + out property add: @image-url("./icons/outlined/add.svg"); + out property chat_bubble: @image-url("./icons/outlined/chat_bubble.svg"); + out property edit: @image-url("./icons/outlined/edit.svg"); + out property group: @image-url("./icons/outlined/group.svg"); + out property mail: @image-url("./icons/outlined/mail.svg"); + out property outbox: @image-url("./icons/outlined/outbox.svg"); + out property search: @image-url("./icons/outlined/search.svg"); + out property video_chat: @image-url("./icons/outlined/video_chat.svg"); + out property bookmark: @image-url("./icons/outlined/bookmark.svg"); + out property check: @image-url("./icons/outlined/check.svg"); + out property explore: @image-url("./icons/outlined/explore.svg"); + out property image: @image-url("./icons/outlined/image.svg"); + out property more_vert: @image-url("./icons/outlined/more_vert.svg"); + out property pets: @image-url("./icons/outlined/pets.svg"); + out property settings: @image-url("./icons/outlined/settings.svg"); + out property view_week: @image-url("./icons/outlined/view_week.svg"); + out property light_mode: @image-url("./icons/outlined/light_mode.svg"); + out property dark_mode: @image-url("./icons/outlined/dark_mode.svg"); + out property dashboard: @image-url("./icons/outlined/dashboard.svg"); + out property pause: @image-url("./icons/outlined/pause.svg"); + out property archive: @image-url("./icons/outlined/archive.svg"); + out property share: @image-url("./icons/outlined/share.svg"); + } diff --git a/component-sets/material/examples/gallery/ui/icons/filled/account_box.svg b/component-sets/material/examples/gallery/ui/icons/filled/account_box.svg new file mode 100644 index 000000000..e74d64cd1 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/account_box.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/add.svg b/component-sets/material/examples/gallery/ui/icons/filled/add.svg new file mode 100644 index 000000000..58f73e962 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/archive.svg b/component-sets/material/examples/gallery/ui/icons/filled/archive.svg new file mode 100644 index 000000000..024f790be --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/bookmark.svg b/component-sets/material/examples/gallery/ui/icons/filled/bookmark.svg new file mode 100644 index 000000000..1d507a690 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/bookmark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/calendar_month.svg b/component-sets/material/examples/gallery/ui/icons/filled/calendar_month.svg new file mode 100644 index 000000000..e8fa87b06 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/calendar_month.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/chat_bubble.svg b/component-sets/material/examples/gallery/ui/icons/filled/chat_bubble.svg new file mode 100644 index 000000000..d447be375 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/chat_bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/check.svg b/component-sets/material/examples/gallery/ui/icons/filled/check.svg new file mode 100644 index 000000000..8676ca39a --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/dark_mode.svg b/component-sets/material/examples/gallery/ui/icons/filled/dark_mode.svg new file mode 100644 index 000000000..3d141c401 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/dark_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/dashboard.svg b/component-sets/material/examples/gallery/ui/icons/filled/dashboard.svg new file mode 100644 index 000000000..16822956d --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/dashboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/delete.svg b/component-sets/material/examples/gallery/ui/icons/filled/delete.svg new file mode 100644 index 000000000..0969a4dc2 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/edit.svg b/component-sets/material/examples/gallery/ui/icons/filled/edit.svg new file mode 100644 index 000000000..a2841f941 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/explore.svg b/component-sets/material/examples/gallery/ui/icons/filled/explore.svg new file mode 100644 index 000000000..424334311 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/explore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/favorite.svg b/component-sets/material/examples/gallery/ui/icons/filled/favorite.svg new file mode 100644 index 000000000..80f9a0561 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/favorite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/group.svg b/component-sets/material/examples/gallery/ui/icons/filled/group.svg new file mode 100644 index 000000000..bd9a1335d --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/image.svg b/component-sets/material/examples/gallery/ui/icons/filled/image.svg new file mode 100644 index 000000000..6ccc16add --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/inbox.svg b/component-sets/material/examples/gallery/ui/icons/filled/inbox.svg new file mode 100644 index 000000000..92dbdab63 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/inbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/light_mode.svg b/component-sets/material/examples/gallery/ui/icons/filled/light_mode.svg new file mode 100644 index 000000000..4a29693f3 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/light_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/mail.svg b/component-sets/material/examples/gallery/ui/icons/filled/mail.svg new file mode 100644 index 000000000..876dbcd13 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/mail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/more_vert.svg b/component-sets/material/examples/gallery/ui/icons/filled/more_vert.svg new file mode 100644 index 000000000..f2427f84c --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/more_vert.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/music_note.svg b/component-sets/material/examples/gallery/ui/icons/filled/music_note.svg new file mode 100644 index 000000000..cdc42fcea --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/music_note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/outbox.svg b/component-sets/material/examples/gallery/ui/icons/filled/outbox.svg new file mode 100644 index 000000000..351e92dd3 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/outbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/pause.svg b/component-sets/material/examples/gallery/ui/icons/filled/pause.svg new file mode 100644 index 000000000..c20e1563a --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/pets.svg b/component-sets/material/examples/gallery/ui/icons/filled/pets.svg new file mode 100644 index 000000000..e4d7d48f5 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/pets.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/play_arrow.svg b/component-sets/material/examples/gallery/ui/icons/filled/play_arrow.svg new file mode 100644 index 000000000..c5e1a4c46 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/play_arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/search.svg b/component-sets/material/examples/gallery/ui/icons/filled/search.svg new file mode 100644 index 000000000..cd9fd53c4 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/settings.svg b/component-sets/material/examples/gallery/ui/icons/filled/settings.svg new file mode 100644 index 000000000..f255a5805 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/share.svg b/component-sets/material/examples/gallery/ui/icons/filled/share.svg new file mode 100644 index 000000000..ed3e530b2 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/share.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/today.svg b/component-sets/material/examples/gallery/ui/icons/filled/today.svg new file mode 100644 index 000000000..43abd72af --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/today.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/video_call.svg b/component-sets/material/examples/gallery/ui/icons/filled/video_call.svg new file mode 100644 index 000000000..e1a21e15d --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/video_call.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/filled/view_week.svg b/component-sets/material/examples/gallery/ui/icons/filled/view_week.svg new file mode 100644 index 000000000..d26bb066d --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/filled/view_week.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/account_box.svg b/component-sets/material/examples/gallery/ui/icons/outlined/account_box.svg new file mode 100644 index 000000000..387571187 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/account_box.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/add.svg b/component-sets/material/examples/gallery/ui/icons/outlined/add.svg new file mode 100644 index 000000000..58f73e962 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/archive.svg b/component-sets/material/examples/gallery/ui/icons/outlined/archive.svg new file mode 100644 index 000000000..731821612 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/bookmark.svg b/component-sets/material/examples/gallery/ui/icons/outlined/bookmark.svg new file mode 100644 index 000000000..812bffedb --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/bookmark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/calendar_month.svg b/component-sets/material/examples/gallery/ui/icons/outlined/calendar_month.svg new file mode 100644 index 000000000..c35f75e50 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/calendar_month.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/chat_bubble.svg b/component-sets/material/examples/gallery/ui/icons/outlined/chat_bubble.svg new file mode 100644 index 000000000..d447be375 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/chat_bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/check.svg b/component-sets/material/examples/gallery/ui/icons/outlined/check.svg new file mode 100644 index 000000000..5e3f01e78 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/dark_mode.svg b/component-sets/material/examples/gallery/ui/icons/outlined/dark_mode.svg new file mode 100644 index 000000000..c38c55e05 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/dark_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/dashboard.svg b/component-sets/material/examples/gallery/ui/icons/outlined/dashboard.svg new file mode 100644 index 000000000..01ef59273 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/dashboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/delete.svg b/component-sets/material/examples/gallery/ui/icons/outlined/delete.svg new file mode 100644 index 000000000..14508a229 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/edit.svg b/component-sets/material/examples/gallery/ui/icons/outlined/edit.svg new file mode 100644 index 000000000..01f34c79e --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/explore.svg b/component-sets/material/examples/gallery/ui/icons/outlined/explore.svg new file mode 100644 index 000000000..b62e5edac --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/explore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/favorite.svg b/component-sets/material/examples/gallery/ui/icons/outlined/favorite.svg new file mode 100644 index 000000000..80f9a0561 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/favorite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/group.svg b/component-sets/material/examples/gallery/ui/icons/outlined/group.svg new file mode 100644 index 000000000..7fa6132dd --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/image.svg b/component-sets/material/examples/gallery/ui/icons/outlined/image.svg new file mode 100644 index 000000000..5400d3808 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/inbox.svg b/component-sets/material/examples/gallery/ui/icons/outlined/inbox.svg new file mode 100644 index 000000000..fc55d23ba --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/inbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/light_mode.svg b/component-sets/material/examples/gallery/ui/icons/outlined/light_mode.svg new file mode 100644 index 000000000..d66b3ab50 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/light_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/mail.svg b/component-sets/material/examples/gallery/ui/icons/outlined/mail.svg new file mode 100644 index 000000000..f3809a55c --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/mail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/more_vert.svg b/component-sets/material/examples/gallery/ui/icons/outlined/more_vert.svg new file mode 100644 index 000000000..f2427f84c --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/more_vert.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/music_note.svg b/component-sets/material/examples/gallery/ui/icons/outlined/music_note.svg new file mode 100644 index 000000000..e7be7bff6 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/music_note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/outbox.svg b/component-sets/material/examples/gallery/ui/icons/outlined/outbox.svg new file mode 100644 index 000000000..ae8bda3e3 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/outbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/pause.svg b/component-sets/material/examples/gallery/ui/icons/outlined/pause.svg new file mode 100644 index 000000000..c20e1563a --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/pets.svg b/component-sets/material/examples/gallery/ui/icons/outlined/pets.svg new file mode 100644 index 000000000..e4d7d48f5 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/pets.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/play_arrow.svg b/component-sets/material/examples/gallery/ui/icons/outlined/play_arrow.svg new file mode 100644 index 000000000..842d32f31 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/play_arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/search.svg b/component-sets/material/examples/gallery/ui/icons/outlined/search.svg new file mode 100644 index 000000000..cd9fd53c4 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/settings.svg b/component-sets/material/examples/gallery/ui/icons/outlined/settings.svg new file mode 100644 index 000000000..b36758caf --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/share.svg b/component-sets/material/examples/gallery/ui/icons/outlined/share.svg new file mode 100644 index 000000000..b3295dbaa --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/share.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/today.svg b/component-sets/material/examples/gallery/ui/icons/outlined/today.svg new file mode 100644 index 000000000..b3faffc64 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/today.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/video_chat.svg b/component-sets/material/examples/gallery/ui/icons/outlined/video_chat.svg new file mode 100644 index 000000000..798cd1ea3 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/video_chat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/icons/outlined/view_week.svg b/component-sets/material/examples/gallery/ui/icons/outlined/view_week.svg new file mode 100644 index 000000000..e7a9e7dc1 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/icons/outlined/view_week.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/examples/gallery/ui/main.slint b/component-sets/material/examples/gallery/ui/main.slint new file mode 100644 index 000000000..34df731b5 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/main.slint @@ -0,0 +1,23 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialWindow } from "../../../material.slint"; +import { MainView } from "./views/main_view.slint"; +import { MainWindowAdapter } from "./main_window_adapter.slint"; + +export component MainWindow inherits MaterialWindow { + background: MainWindowAdapter.background; + + MainView { + width: 100%; + height: 100%; + } + + changed width => { + MainWindowAdapter.width = root.width; + } + + changed height => { + MainWindowAdapter.height = root.height; + } +} diff --git a/component-sets/material/examples/gallery/ui/main_window_adapter.slint b/component-sets/material/examples/gallery/ui/main_window_adapter.slint new file mode 100644 index 000000000..8d9d7fa8d --- /dev/null +++ b/component-sets/material/examples/gallery/ui/main_window_adapter.slint @@ -0,0 +1,12 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../../../material.slint"; + +export global MainWindowAdapter { + in property width; + in property height; + in property surface_background; + out property break_layout: root.width < 852px; + out property background: root.surface_background ? MaterialPalette.surface_container : MaterialPalette.background; +} diff --git a/component-sets/material/examples/gallery/ui/views/actions_view.slint b/component-sets/material/examples/gallery/ui/views/actions_view.slint new file mode 100644 index 000000000..33a745982 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/views/actions_view.slint @@ -0,0 +1,605 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { + ElevatedCard, + FilledCard, + OutlinedCard, + MaterialText, + MaterialPalette, + Typography, + ElevatedButton, + FilledButton, + TonalButton, + OutlineButton, + TextButton, + FloatingActionButton, + FABStyle, + IconButton, + Vertical, + Horizontal, + Grid, + FilledIconButton, + TonalIconButton, + OutlineIconButton, + SegmentedButton, + ScrollView, + NavigationBar, + CircularProgressIndicator, + LinearProgressIndicator, + SnackBar, + ModalBottomSheet, + MaterialText, + MaterialStyleMetrics, + HorizontalDivider, + Dialog, + FullscreenDialog +} from "../../../../material.slint"; + +import { Group } from "../components/group.slint"; +import { ComponentCard } from "../components/component_card.slint"; +import { TextIconButton } from "../components/text_icon_button.slint"; +import { MainWindowAdapter } from "../main_window_adapter.slint"; +import { FilledIcons, OutlinedIcons } from "../icons.slint"; + +export component ActionsView { + layout := VerticalLayout { + alignment: start; + spacing: MaterialStyleMetrics.spacing_8; + horizontal-stretch: 1; + + Group { + title: "Actions"; + + ComponentCard { + title: "Common buttons"; + + HorizontalLayout { + alignment: center; + + Grid { + spacing-horizontal: MaterialStyleMetrics.spacing_4; + + ElevatedButton { + text: "Elevated"; + row: 0; + col: 0; + } + + ElevatedButton { + icon: FilledIcons.add; + text: "Icon"; + row: 0; + col: 1; + } + + ElevatedButton { + text: "Elevated"; + enabled: false; + row: 0; + col: 2; + } + + FilledButton { + text: "Filled"; + row: 1; + col: 0; + } + + FilledButton { + icon: FilledIcons.add; + text: "Icon"; + row: 1; + col: 1; + } + + FilledButton { + text: "Filled"; + enabled: false; + row: 1; + col: 2; + } + + TonalButton { + text: "Filled tonal"; + row: 2; + col: 0; + } + + TonalButton { + icon: FilledIcons.add; + text: "Icon"; + row: 2; + col: 1; + } + + TonalButton { + text: "Filled tonal"; + enabled: false; + row: 2; + col: 2; + } + + OutlineButton { + text: "Outlined"; + row: 3; + col: 0; + } + + OutlineButton { + icon: FilledIcons.add; + text: "Icon"; + row: 3; + col: 1; + } + + OutlineButton { + text: "Outlined"; + enabled: false; + row: 3; + col: 2; + } + + TextButton { + text: "Text"; + row: 4; + col: 0; + } + + TextButton { + icon: FilledIcons.add; + text: "Icon"; + row: 4; + col: 1; + } + + TextButton { + text: "Text"; + enabled: false; + row: 4; + col: 2; + } + } + } + } + + + ComponentCard { + title: "Floating Action Buttons"; + + Horizontal { + alignment: center; + + VerticalLayout { + alignment: center; + + FloatingActionButton { + icon: FilledIcons.add; + tooltip: "Small"; + } + } + + VerticalLayout { + alignment: center; + + FloatingActionButton { + icon: FilledIcons.add; + style: FABStyle.standard; + text: "Create"; + tooltip: "Extended"; + } + } + + VerticalLayout { + alignment: center; + + FloatingActionButton { + icon: FilledIcons.add; + style: FABStyle.standard; + tooltip: "Standard"; + } + } + + VerticalLayout { + alignment: center; + + FloatingActionButton { + icon: FilledIcons.add; + style: FABStyle.large; + tooltip: "Large"; + } + } + } + } + + ComponentCard { + title: "Icon buttons"; + + Vertical { + HorizontalLayout { + alignment: center; + spacing: MaterialStyleMetrics.spacing_8; + + default_ib := IconButton { + checkable: true; + icon: OutlinedIcons.settings; + icon_checked: FilledIcons.settings; + } + + filled_ib := FilledIconButton { + icon: OutlinedIcons.settings; + checkable: true; + icon_checked: FilledIcons.settings; + } + + tonal_ib := TonalIconButton { + checkable: true; + icon: OutlinedIcons.settings; + icon_checked: FilledIcons.settings; + } + + outline_ib := OutlineIconButton { + checkable: true; + icon: OutlinedIcons.settings; + icon_checked: FilledIcons.settings; + } + } + + HorizontalLayout { + alignment: center; + spacing: MaterialStyleMetrics.spacing_8; + + IconButton { + icon: OutlinedIcons.settings; + icon_checked: FilledIcons.settings; + checked: default_ib.checked; + enabled: false; + } + + + FilledIconButton { + icon: OutlinedIcons.settings; + icon_checked: FilledIcons.settings; + checked: filled_ib.checked; + enabled: false; + } + + TonalIconButton { + icon: OutlinedIcons.settings; + icon_checked: FilledIcons.settings; + checked: tonal_ib.checked; + enabled: false; + } + + OutlineIconButton { + icon: OutlinedIcons.settings; + icon_checked: FilledIcons.settings; + checked: outline_ib.checked; + enabled: false; + } + } + } + } + + ComponentCard { + title: "Segmented buttons"; + + Vertical { + HorizontalLayout { + alignment: center; + + SegmentedButton { + model: [ + { icon: OutlinedIcons.today, text: "Day" }, + { icon: OutlinedIcons.view_week, text: "Week" }, + { icon: OutlinedIcons.calendar_month, text: "Month" }, + ]; + } + } + + HorizontalLayout { + alignment: center; + + SegmentedButton { + current_item: 4; + + model: [ + { text: "XS" }, + { text: "S" }, + { text: "M" }, + { text: "L" }, + { text: "XL" }, + ]; + } + } + } + } + } + + Group { + title: "Communication"; + + ComponentCard { + title: "Badges"; + + NavigationBar { + items: [ + { + icon: OutlinedIcons.mail, + icon_selected: FilledIcons.mail, + text: "Mail", + badge: "999+" + }, + { + icon: OutlinedIcons.chat_bubble, + icon_selected: FilledIcons.chat_bubble, + text: "Chat", + badge: "10" + }, + { + icon: OutlinedIcons.group, + icon_selected: FilledIcons.group, + text: "Rooms", + empty_badge: true + }, + { + icon: OutlinedIcons.video_chat, + icon_selected: FilledIcons.video_chat, + text: "Meet", + badge: "3" + }, + ]; + } + } + + ComponentCard { + title: "Progress indicators"; + + Horizontal { + IconButton { + icon: pi.indeterminate ? FilledIcons.pause : + FilledIcons.play_arrow; + + clicked => { + pi.indeterminate = !pi.indeterminate; + } + } + + VerticalLayout { + alignment: center; + + pi := CircularProgressIndicator { + value: 0.5; + } + } + + VerticalLayout { + alignment: center; + + LinearProgressIndicator { + indeterminate: pi.indeterminate; + value: 0.5; + } + } + } + } + + ComponentCard { + title: "Snackbar"; + + Horizontal { + alignment: center; + + TextButton { + text: "Show snackbar"; + + clicked => { + snackbar.show(); + } + } + } + } + + ComponentCard { + title: "Containment"; + + Horizontal { + alignment: center; + + TextButton { + text: "Show modal bottom sheet"; + + clicked => { + modal_bottom_sheet.show(); + } + } + } + } + + ComponentCard { + title: "Cards"; + + Horizontal { + alignment: center; + + ElevatedCard { + width: 92px; + height: self.width; + + Vertical { + alignment: space_between; + + HorizontalLayout { + alignment: end; + + IconButton { + icon: OutlinedIcons.more_vert; + } + } + + MaterialText { + text: "Elevated"; + } + } + } + + FilledCard { + width: 92px; + height: self.width; + + Vertical { + alignment: space_between; + + HorizontalLayout { + alignment: end; + + IconButton { + icon: OutlinedIcons.more_vert; + } + } + + MaterialText { + text: "Filled"; + } + } + } + + OutlinedCard { + width: 92px; + height: self.width; + + Vertical { + alignment: space_between; + + HorizontalLayout { + alignment: end; + + IconButton { + icon: OutlinedIcons.more_vert; + } + } + + MaterialText { + text: "Outlined"; + } + } + } + } + } + + ComponentCard { + title: "Dialogs"; + + Horizontal { + alignment: center; + + TextButton { + text: "Show dialog"; + + clicked => { + dialog.show(); + } + } + + TextButton { + text: "Show full-screen dialog"; + + clicked => { + fullscreen_dialog.show(); + } + } + } + } + + ComponentCard { + title: "Dividers"; + + Horizontal { + HorizontalDivider {} + } + } + } + } + + + // popups + + modal_bottom_sheet := ModalBottomSheet { + x: -root.absolute_position.x; + y: -root.absolute_position.y; + width: MainWindowAdapter.width; + height: MainWindowAdapter.height; + + TextIconButton { + icon: OutlinedIcons.share; + text: "Share"; + } + + TextIconButton { + icon: OutlinedIcons.add; + text: "Add to"; + } + + TextIconButton { + icon: OutlinedIcons.delete; + text: "Trash"; + } + + TextIconButton { + icon: OutlinedIcons.archive; + text: "Archive"; + } + + TextIconButton { + icon: OutlinedIcons.settings; + text: "Settings"; + } + } + + snackbar := SnackBar { + x: -root.absolute_position.x; + y: -root.absolute_position.y; + width: MainWindowAdapter.width; + height: MainWindowAdapter.height; + text: "This is a snackbar"; + action_text: "Close"; + } + + dialog := Dialog { + x: -root.absolute_position.x; + y: -root.absolute_position.y; + width: MainWindowAdapter.width; + height: MainWindowAdapter.height; + title: "What is a dialog?"; + default_action_text: "Okay"; + actions: ["Dismiss"]; + + MaterialText { + text: "A dialog is a type of modal window that appears in front of app content to provide critical information, or prompt for a descion to be made."; + wrap: word_wrap; + } + + action(index) => { + dialog.close(); + } + + default_action => { + dialog.close(); + } + } + + fullscreen_dialog := FullscreenDialog { + x: -root.absolute_position.x; + y: -root.absolute_position.y; + width: MainWindowAdapter.width; + height: MainWindowAdapter.height; + title: "Full-screen dialog"; + actions: ["Close"]; + + Rectangle {} + + action => { + fullscreen_dialog.close(); + } + } +} diff --git a/component-sets/material/examples/gallery/ui/views/components_view.slint b/component-sets/material/examples/gallery/ui/views/components_view.slint new file mode 100644 index 000000000..3e8271163 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/views/components_view.slint @@ -0,0 +1,84 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MainWindowAdapter } from "../main_window_adapter.slint"; +import { + ElevatedCard, + FilledCard, + OutlinedCard, + MaterialText, + MaterialPalette, + Typography, + ElevatedButton, + FilledButton, + TonalButton, + OutlineButton, + TextButton, + FloatingActionButton, + FABStyle, + IconButton, + Vertical, + Horizontal, + Grid, + FilledIconButton, + TonalIconButton, + OutlineIconButton, + SegmentedButton, + ScrollView, + NavigationBar, + CircularProgressIndicator, + LinearProgressIndicator, + SnackBar, + ModalBottomSheet, + MaterialText, + MaterialStyleMetrics, + HorizontalDivider, + Dialog, + FullscreenDialog +} from "../../../../material.slint"; + +import { ActionsView } from "./actions_view.slint"; +import { NavigationView } from "./navigation_view.slint"; +import { MainWindowAdapter } from "../main_window_adapter.slint"; + +export component ComponentsView { + if !MainWindowAdapter.break_layout : HorizontalLayout { + ScrollView { + viewport_height: action_view.height; + + action_view := ActionsView { + width: 100%; + } + + changed viewport_y => { + MainWindowAdapter.surface_background = self.viewport_y != 0; + } + } + + ScrollView { + viewport_height: navigation_view.height; + + navigation_view := NavigationView { + width: 100%; + } + + changed viewport_y => { + MainWindowAdapter.surface_background = self.viewport_y != 0; + } + } + } + + if MainWindowAdapter.break_layout : ScrollView { + VerticalLayout { + alignment: start; + spacing: MaterialStyleMetrics.spacing_8; + + ActionsView {} + NavigationView {} + } + + changed viewport_y => { + MainWindowAdapter.surface_background = self.viewport_y != 0; + } + } +} diff --git a/component-sets/material/examples/gallery/ui/views/main_view.slint b/component-sets/material/examples/gallery/ui/views/main_view.slint new file mode 100644 index 000000000..77e3260c5 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/views/main_view.slint @@ -0,0 +1,81 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { ComponentsView } from "components_view.slint"; +import { Palette } from "std-widgets.slint"; +import { MaterialText, Typography, IconButton, MaterialPalette, Animations, NavigationRail, NavigationItem, NavigationBar } from "../../../../material.slint"; +import { MainWindowAdapter } from "../main_window_adapter.slint"; +import { FilledIcons, OutlinedIcons } from "../icons.slint"; + +export enum Views { + components +} + +export component MainView { + property current_view: Views.components; + property <[NavigationItem]> navigation_items: [ + { + text: "Components", + icon: OutlinedIcons.dashboard, + icon_selected: FilledIcons.dashboard + } + ]; + + VerticalLayout { + HorizontalLayout { + height: 64px; + padding_left: 16px; + padding_right: 16px; + spacing: 8px; + + MaterialText { + vertical-alignment: center; + text: "Material 3"; + style: Typography.title_large; + } + + Rectangle {} + + IconButton { + checked: Palette.color_scheme == ColorScheme.light; + checkable: true; + icon: OutlinedIcons.light_mode; + icon_checked: OutlinedIcons.dark_mode; + + changed checked => { + if !self.checked { + Palette.color_scheme = ColorScheme.dark; + return; + } + + Palette.color_scheme = ColorScheme.light; + } + } + } + + Rectangle { + background: MaterialPalette.background; + + if !MainWindowAdapter.break_layout : HorizontalLayout { + NavigationRail { + items: root.navigation_items; + } + + + if root.current_view == Views.components : ComponentsView { + horizontal_stretch: 1; + } + } + + if MainWindowAdapter.break_layout : VerticalLayout { + if root.current_view == Views.components : ComponentsView { + horizontal_stretch: 1; + } + + NavigationBar { + items: root.navigation_items; + } + } + } + } +} diff --git a/component-sets/material/examples/gallery/ui/views/navigation_view.slint b/component-sets/material/examples/gallery/ui/views/navigation_view.slint new file mode 100644 index 000000000..9ad326679 --- /dev/null +++ b/component-sets/material/examples/gallery/ui/views/navigation_view.slint @@ -0,0 +1,288 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { + MaterialStyleMetrics, + NavigationBar, + BottomAppBar, + NavigationDrawer, + TextButton, + ModalNavigationDrawer, + NavigationRail, + Horizontal, + NavigationItem, + TabBar, + SecondaryTabBar, + SearchBar, + MaterialText, + Vertical +} from "../../../../material.slint"; + +import { Group } from "../components/group.slint"; +import { ComponentCard } from "../components/component_card.slint"; +import { MainWindowAdapter } from "../main_window_adapter.slint"; +import { MainWindowAdapter } from "../main_window_adapter.slint"; +import { FilledIcons, OutlinedIcons } from "../icons.slint"; + +export component NavigationView { + layout := VerticalLayout { + alignment: start; + spacing: MaterialStyleMetrics.spacing_8; + horizontal-stretch: 1; + + Group { + title: "Navigation"; + + ComponentCard { + title: "Bottom app bar"; + + BottomAppBar { + icon_buttons: [ + { + icon: OutlinedIcons.more_vert, + enabled: true, + + }, + { + icon: OutlinedIcons.search, + enabled: true, + tooltip: "Search" + }, + { + icon: OutlinedIcons.favorite, + enabled: true, + tooltip: "Favorit" + }, + ]; + fab_icon: OutlinedIcons.add; + } + } + + ComponentCard { + title: "Navigation bar"; + + NavigationBar { + items: [ + { + icon: OutlinedIcons.explore, + icon_selected: FilledIcons.explore, + text: "Explore", + }, + { + icon: OutlinedIcons.pets, + icon_selected: FilledIcons.pets, + text: "Pets", + }, + { + icon: OutlinedIcons.account_box, + icon_selected: FilledIcons.account_box, + text: "Account", + }, + ]; + } + } + + ComponentCard { + title: "Navigation drawer"; + + VerticalLayout { + NavigationDrawer { + groups: [ + { + title: "Mail", + items: [ + { + icon: OutlinedIcons.inbox, + icon_selected: FilledIcons.inbox, + text: "Inbox", + }, + { + icon: OutlinedIcons.outbox, + icon_selected: FilledIcons.outbox, + text: "Outbox", + }, + { + icon: OutlinedIcons.favorite, + icon_selected: FilledIcons.favorite, + text: "Favorites", + }, + { + icon: OutlinedIcons.delete, + icon_selected: FilledIcons.delete, + text: "Trash", + } + ] + }, + { + title: "Labels", + items: [ + { + icon: OutlinedIcons.bookmark, + icon_selected: FilledIcons.bookmark, + text: "Family", + }, + { + icon: OutlinedIcons.bookmark, + icon_selected: FilledIcons.bookmark, + text: "School", + }, + { + icon: OutlinedIcons.bookmark, + icon_selected: FilledIcons.bookmark, + text: "Work", + }, + ] + } + ]; + } + + HorizontalLayout { + alignment: center; + + TextButton { + text: "Show modal navigation drawer"; + + clicked => { + modal_navigation_drawer.show(); + } + } + } + } + } + + ComponentCard { + title: "Navigation rail"; + + Horizontal { + alignment: center; + + NavigationRail { + height: 500px; + fab_icon: FilledIcons.edit; + alignment: center; + + items: [ + { + icon: OutlinedIcons.inbox, + icon_selected: FilledIcons.inbox, + text: "Inbox", + }, + { + icon: OutlinedIcons.outbox, + icon_selected: FilledIcons.outbox, + text: "Outbox", + }, + { + icon: OutlinedIcons.favorite, + icon_selected: FilledIcons.favorite, + text: "Favorites", + }, + { + icon: OutlinedIcons.delete, + icon_selected: FilledIcons.delete, + text: "Trash", + } + ]; + } + } + } + + ComponentCard { + title: "Tabs"; + + Horizontal { + TabBar { + items: [ + { + text: "Video", + icon: OutlinedIcons.video_chat, + }, + { + text: "Photos", + icon: OutlinedIcons.image, + }, + { + text: "Audio", + icon: OutlinedIcons.music_note, + }, + ]; + } + } + } + + ComponentCard { + title: "Search"; + + Vertical { + spacing: MaterialStyleMetrics.spacing_16; + alignment: start; + + SearchBar { + leading_icon: OutlinedIcons.search; + placeholder: "Search color"; + } + + MaterialText { + text: "Select a color"; + horizontal_alignment: center; + } + } + } + } + } + + modal_navigation_drawer := ModalNavigationDrawer { + x: -root.absolute_position.x; + y: -root.absolute_position.y; + width: MainWindowAdapter.width; + height: MainWindowAdapter.height; + position_right: true; + groups: [ + { + title: "Mail", + items: [ + { + icon: OutlinedIcons.inbox, + icon_selected: FilledIcons.inbox, + text: "Inbox", + }, + { + icon: OutlinedIcons.outbox, + icon_selected: FilledIcons.outbox, + text: "Outbox", + }, + { + icon: OutlinedIcons.favorite, + icon_selected: FilledIcons.favorite, + text: "Favorites", + }, + { + icon: OutlinedIcons.delete, + icon_selected: FilledIcons.delete, + text: "Trash", + } + ] + }, + { + title: "Labels", + items: [ + { + icon: OutlinedIcons.bookmark, + icon_selected: FilledIcons.bookmark, + text: "Family", + }, + { + icon: OutlinedIcons.bookmark, + icon_selected: FilledIcons.bookmark, + text: "School", + }, + { + icon: OutlinedIcons.bookmark, + icon_selected: FilledIcons.bookmark, + text: "Work", + }, + ] + } + ]; + } +} diff --git a/component-sets/material/material.slint b/component-sets/material/material.slint new file mode 100644 index 000000000..917bdbf27 --- /dev/null +++ b/component-sets/material/material.slint @@ -0,0 +1,53 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +// components +export { Badge } from "./ui/components/badge.slint"; +export { BottomAppBar } from "./ui/components/bottom_app_bar.slint"; +export { Dialog, FullscreenDialog } from "./ui/components/dialog.slint"; +export { Drawer, ModalDrawer } from "./ui/components/drawer.slint"; +export { VerticalDivider, HorizontalDivider } from "./ui/components/divider.slint"; +export { ModalBottomSheet } from "./ui/components/bottom_sheet.slint"; +export { ElevatedCard, FilledCard, OutlinedCard } from "./ui/components/card.slint"; +export { ElevatedButton } from "./ui/components/elevated_button.slint"; +export { Elevation } from "./ui/components/elevation.slint"; +export { ExtendedTouchArea } from "./ui/components/extended_touch_area.slint"; +export { FilledButton } from "./ui/components/filled_button.slint"; +export { FilledIconButton } from "./ui/components/filled_icon_button.slint"; +export { FloatingActionButton, FABStyle } from "./ui/components/floating_action_button.slint"; +export { Grid } from "./ui/components/grid.slint"; +export { Horizontal } from "./ui/components/horizontal.slint"; +export { Icon } from "./ui/components/icon.slint"; +export { IconButton } from "./ui/components/icon_button.slint"; +export { OutlineButton } from "./ui/components/outline_button.slint"; +export { OutlineIconButton } from "./ui/components/outline_icon_button.slint"; +export { ListItemTemplate } from "./ui/components/list.slint"; +export { ListView } from "./ui/components/list_view.slint"; +export { MaterialText } from "./ui/components/material_text.slint"; +export { MaterialWindow } from "./ui/components/material_window.slint"; +export { NavigationBar } from "./ui/components/navigation_bar.slint"; +export { NavigationDrawer, ModalNavigationDrawer } from "./ui/components/navigation_drawer.slint"; +export { NavigationRail } from "./ui/components/navigation_rail.slint"; +export { CircularProgressIndicator, LinearProgressIndicator } from "./ui/components/progress_indicator.slint"; +export { SearchBar } from "./ui/components/search_bar.slint"; +export { ScrollView } from "./ui/components/scroll_view.slint"; +export { SnackBar } from "./ui/components/snack_bar.slint"; +export { StateLayerArea, StateLayer, Ripple } from "./ui/components/state_layer.slint"; +export { SegmentedButton } from "./ui/components/segmented_button.slint"; +export { TabBar, SecondaryTabBar } from "./ui/components/tab_bar.slint"; +export { TextButton } from "./ui/components/text_button.slint"; +export { TonalButton } from "./ui/components/tonal_button.slint"; +export { TonalIconButton } from "./ui/components/tonal_icon_button.slint"; +export { ToolTip } from "./ui/components/tooltip.slint"; +export { Vertical } from "./ui/components/vertical.slint"; + +// items +export { ListItem } from "./ui/items/list_item.slint"; +export { NavigationItem, NavigationGroup } from "./ui/items/navigation_item.slint"; + +// styles +export { Animations } from "./ui/styling/animations.slint"; +export { MaterialScheme, MaterialTheme } from "./ui/styling/material_theme.slint"; +export { MaterialStyleMetrics } from "./ui/styling/material_style_metrics.slint"; +export { MaterialPalette } from "./ui/styling/material_palette.slint"; +export { Typography } from "./ui/styling/typography.slint"; diff --git a/component-sets/material/src/lib.rs b/component-sets/material/src/lib.rs new file mode 100644 index 000000000..ae8bc15f2 --- /dev/null +++ b/component-sets/material/src/lib.rs @@ -0,0 +1,30 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +use std::env; +use std::path::PathBuf; + +use std::collections::HashMap; + +/// Provides the `material` library paths used by slint-build to make them accessible through `@slint/material.slint` in Slint. +/// +/// ```ignore +/// fn main() { +/// slint_build::compile_with_config( +/// "ui/main.slint", +/// slint_build::CompilerConfiguration::new().with_library_paths(slint_material::import_path()), +/// ) +/// .unwrap(); +/// } +/// ``` +/// +/// Import `slint-material` library in `ui/main.slint` +/// +/// ```slint +/// import { FilledButton } from "@slint/material.slint"; +/// ```` +pub fn import_path() -> HashMap { + let mut import_paths = HashMap::new(); + import_paths.insert("slint".to_string(), PathBuf::from(env!("CARGO_MANIFEST_DIR"))); + import_path +} diff --git a/component-sets/material/ui/components/badge.slint b/component-sets/material/ui/components/badge.slint new file mode 100644 index 000000000..28355c786 --- /dev/null +++ b/component-sets/material/ui/components/badge.slint @@ -0,0 +1,36 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialText } from "material_text.slint"; + +export component Badge { + in property text; + + width: max(MaterialStyleMetrics.size_16, label.width + 2 * MaterialStyleMetrics.padding_4); + height: max(MaterialStyleMetrics.size_16, label.height); + + background_layer := Rectangle { + width: parent.width; + height: parent.height; + border_radius: self.height / 2; + background: MaterialPalette.error; + } + + label := MaterialText { + text: root.text; + color: MaterialPalette.on_error; + vertical_alignment: center; + horizontal_alignment: center; + style: Typography.label_small; + } + + states [ + small when root.text == "" : { + background_layer.width: MaterialStyleMetrics.size_6; + background_layer.height: MaterialStyleMetrics.size_6; + } + ] +} diff --git a/component-sets/material/ui/components/base_button.slint b/component-sets/material/ui/components/base_button.slint new file mode 100644 index 000000000..af10fbfe2 --- /dev/null +++ b/component-sets/material/ui/components/base_button.slint @@ -0,0 +1,52 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { StateLayerArea } from "./state_layer.slint"; +import { MaterialText } from "./material_text.slint"; +import { Icon } from "./icon.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component BaseButton inherits StateLayerArea { + in property icon; + in property text; + in property horizontal_padding: MaterialStyleMetrics.padding_24; + in property vertical_padding: MaterialStyleMetrics.padding_10; + in property spacing; + in property min_layout_width: MaterialStyleMetrics.size_40; + in property min_layout_height: MaterialStyleMetrics.size_40; + in property icon_size: MaterialStyleMetrics.icon_size_40; + + min_width: max(root.min_layout_width, layout.min_width); + min_height: max(root.min_layout_height, layout.min_height); + tooltip_offset: root.height / 2 + root.icon_size / 2 + MaterialStyleMetrics.padding_14; + + layout := HorizontalLayout { + padding_left: root.horizontal_padding; + padding_right: root.horizontal_padding; + padding_top: root.vertical_padding; + padding_bottom: root.vertical_padding; + spacing: root.spacing; + alignment: center; + + if root.icon.width > 0 && root.icon.height > 0 : VerticalLayout { + alignment: center; + + Icon { + source: root.icon; + colorize: root.color; + opacity: root.enabled ? 100% : 38%; + width: root.icon_size; + } + } + + if root.text != "" : MaterialText { + text: root.text; + style: Typography.label_large; + color: root.color; + opacity: root.enabled ? 100% : 38%; + overflow: clip; + vertical_alignment: center; + } + } +} diff --git a/component-sets/material/ui/components/base_navigation.slint b/component-sets/material/ui/components/base_navigation.slint new file mode 100644 index 000000000..0ed144cf4 --- /dev/null +++ b/component-sets/material/ui/components/base_navigation.slint @@ -0,0 +1,45 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { NavigationItem } from "../items/navigation_item.slint"; + +export component BaseNavigationItemTemplate { + in property icon; + in property icon_selected; + in property text; + in property index; + in property selected; + in property empty_badge; + in property badge; + + callback clicked; + + accessible-role: tab; + accessible-label: root.text; + accessible-item-index: root.index; + accessible-item-selectable: true; + accessible-item-selected: root.selected; + accessible-action-default => { self.clicked(); } + + @children +} + +export component BaseNavigation { + in property <[NavigationItem]> items; + in_out property current_item; + + accessible-role: tab-list; + // accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item; + // accessible-label: root.title; + accessible-item-count: root.items.length; + + @children + + protected function select(index: int) { + if index < 0 || index >= root.items.length { + return; + } + + root.current_item = index; + } +} diff --git a/component-sets/material/ui/components/bottom_app_bar.slint b/component-sets/material/ui/components/bottom_app_bar.slint new file mode 100644 index 000000000..daea6acb6 --- /dev/null +++ b/component-sets/material/ui/components/bottom_app_bar.slint @@ -0,0 +1,64 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { IconButton } from "./icon_button.slint"; +import { FloatingActionButton, FABStyle } from "./floating_action_button.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export struct IconButtonItem { + icon: image, + tooltip: string, + enabled: bool +} + +export component BottomAppBar { + in property <[IconButtonItem]> icon_buttons; + in property fab_icon; + + callback fab_clicked(); + callback icon_button_clicked(index: int); + + min_height: max(MaterialStyleMetrics.size_80, layout.min_height); + + Rectangle { + background: MaterialPalette.surface_container; + + layout := HorizontalLayout { + padding_left: MaterialStyleMetrics.padding_4; + padding_right: MaterialStyleMetrics.padding_16; + + VerticalLayout { + alignment: center; + + HorizontalLayout { + for button[index] in root.icon_buttons : IconButton { + icon: button.icon; + enabled: button.enabled; + tooltip: button.tooltip; + + clicked => { + root.icon_button_clicked(index); + } + } + } + } + + // spacer + Rectangle {} + + if root.fab_icon.width > 0 && root.fab_icon.height > 0 : VerticalLayout { + alignment: center; + + FloatingActionButton { + icon: root.fab_icon; + style: FABStyle.standard; + + clicked => { + root.fab_clicked(); + } + } + } + } + } +} diff --git a/component-sets/material/ui/components/bottom_sheet.slint b/component-sets/material/ui/components/bottom_sheet.slint new file mode 100644 index 000000000..a33f43467 --- /dev/null +++ b/component-sets/material/ui/components/bottom_sheet.slint @@ -0,0 +1,125 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { Horizontal } from "./horizontal.slint"; +import { Animations } from "../styling/animations.slint"; +import { Modal } from "./modal.slint"; + +component BottomSheet { + callback drag_moved(offset_y: length); + callback pressed(); + callback released(); + + elevation := Elevation { + width: 100%; + height: 100%; + level: 3; + border_radius: MaterialStyleMetrics.border_radius_16; + } + + TouchArea { + Rectangle { + background: MaterialPalette.surface_container_low; + border_top_left_radius: MaterialStyleMetrics.border_radius_16; + border_top_right_radius: self.border_top_left_radius; + + VerticalLayout { + alignment: start; + + drag_handle := TouchArea { + height: MaterialStyleMetrics.size_36; + + Rectangle { + width: MaterialStyleMetrics.size_32; + height: MaterialStyleMetrics.size_4; + background: MaterialPalette.outline; + border_radius: self.height / 2; + } + + moved => { + root.drag_moved(self.pressed_y - self.mouse_y); + } + + changed pressed => { + if self.pressed { + root.pressed(); + return; + } + + root.released(); + } + } + + Horizontal { + @children + } + } + } + } +} + +export component ModalBottomSheet inherits PopupWindow { + close_policy: no_auto_close; + + property drag_margin: MaterialStyleMetrics.padding_56; + + modal := Modal { + width: 100%; + height: 100%; + + sheet := BottomSheet { + property y_duration: Animations.standard_accelerate_duration; + property y_drag_start; + property height_drag_start; + + x: (parent.width - self.width) / 2; + y: parent.height; + width: min(MaterialStyleMetrics.size_640, parent.width - 2 * MaterialStyleMetrics.padding_56); + + @children + + drag_moved(offset_y) => { + self.y_duration = 0; + self.y = max(self.y - offset_y, self.y_drag_start); + self.height += offset_y; + } + + pressed => { + self.y_drag_start = self.y; + self.height_drag_start = self.height; + } + + released => { + if self.y >= root.height - root.drag_margin { + root.close(); + return; + } + + self.y_duration = Animations.standard_accelerate_duration; + self.height = self.height_drag_start; + self.y = self.y_drag_start; + } + + animate y, height { + duration: self.y_duration; + easing: Animations.standard_easing; + } + } + + clicked => { + root.close(); + } + } + + Timer { + interval: 50ms; + + triggered => { + sheet.y = modal.height - sheet.height; + self.running = false; + } + } +} diff --git a/component-sets/material/ui/components/card.slint b/component-sets/material/ui/components/card.slint new file mode 100644 index 000000000..6afebef45 --- /dev/null +++ b/component-sets/material/ui/components/card.slint @@ -0,0 +1,112 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { Elevation } from "./elevation.slint"; +import { StateLayerArea } from "./state_layer.slint"; + +component BaseCard { + in property clickable; + in property has_elevation; + in property background; + in property border_color; + in property border_width; + + callback clicked(); + + forward_focus: state_layer; + + if root.has_elevation : Elevation { + width: 100%; + height: 100%; + border_radius: background_layer.border_radius; + level: 1; + } + + background_layer := Rectangle { + background: root.background; + border_radius: MaterialStyleMetrics.border_radius_12; + border_width: root.border_width; + border_color: root.border_color; + } + + state_layer := StateLayerArea { + width: 100%; + height: 100%; + border_radius: background_layer.border_radius; + visible: root.clickable; + enabled: root.visible; + + clicked => { + root.clicked(); + } + } + + Rectangle { + clip: true; + border_radius: MaterialStyleMetrics.border_radius_12; + + @children + } +} + +export component ElevatedCard { + in property clickable <=> base.clickable; + + callback clicked <=> base.clicked; + + forward_focus: base; + accessible-role: button; + accessible-enabled: root.clickable; + accessible-action-default => { base.clicked(); } + + base := BaseCard { + width: 100%; + height: 100%; + has_elevation: true; + background: MaterialPalette.surface; + + @children + } +} + +export component FilledCard { + in property clickable <=> base.clickable; + + callback clicked <=> base.clicked; + + forward_focus: base; + accessible-role: button; + accessible-enabled: root.clickable; + accessible-action-default => { base.clicked(); } + + base := BaseCard { + width: 100%; + height: 100%; + background: MaterialPalette.surface_container_highest; + + @children + } +} + +export component OutlinedCard { + in property clickable <=> base.clickable; + + callback clicked <=> base.clicked; + + forward_focus: base; + accessible-role: button; + accessible-enabled: root.clickable; + accessible-action-default => { base.clicked(); } + + base := BaseCard { + width: 100%; + height: 100%; + background: MaterialPalette.surface_container_low; + border_width: 1px; + border_color: MaterialPalette.outline; + + @children + } +} diff --git a/component-sets/material/ui/components/dialog.slint b/component-sets/material/ui/components/dialog.slint new file mode 100644 index 000000000..6b26bf23a --- /dev/null +++ b/component-sets/material/ui/components/dialog.slint @@ -0,0 +1,204 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { Typography } from "../styling/typography.slint"; +import { TextButton } from "./text_button.slint"; +import { FilledButton } from "./filled_button.slint"; +import { MaterialText } from "./material_text.slint"; +import { Animations } from "../styling/animations.slint"; +import { Modal } from "./modal.slint"; +import { Icon } from "./icon.slint"; +import { IconButton } from "./icon_button.slint"; +import { Icons } from "../icons/icons.slint"; + +export component FullscreenDialog inherits PopupWindow { + in property title; + in property <[string]> actions; + + callback action(index: int); + + close_policy: no_auto_close; + forward_focus: focus_scope; + + focus_scope := FocusScope { + x: 0; + width: 0; + + key_pressed(event) => { + if event.text == Key.Escape { + root.close(); + return accept; + } + + reject + } + } + + background_layer := Rectangle { + width: 100%; + height: 100%; + opacity: 0; + background: MaterialPalette.surface; + + VerticalLayout { + spacing: MaterialStyleMetrics.spacing_16; + + HorizontalLayout { + padding: MaterialStyleMetrics.padding_24; + spacing: MaterialStyleMetrics.spacing_16; + vertical_stretch: 0; + + IconButton { + icon: Icons.close; + + clicked => { + root.close(); + } + } + + MaterialText { + text: root.title; + style: Typography.headline_small; + color: MaterialPalette.on_surface; + vertical_alignment: center; + } + + for action[index] in root.actions : TextButton { + text: action; + + clicked => { + root.action(index); + } + } + } + + @children + + } + } + + Timer { + interval: 50ms; + + triggered => { + background_layer.opacity = 1; + self.running = false; + } + } +} + +export component Dialog inherits PopupWindow { + in property title; + in property icon; + in property default_action_text; + in property <[string]> actions; + + property has_icon: root.icon.width > 0 && root.icon.height > 0; + + callback default_action(); + callback action(index: int); + + close_policy: no_auto_close; + forward_focus: focus_scope; + + focus_scope := FocusScope { + x: 0; + width: 0; + + key_pressed(event) => { + if event.text == Key.Return && root.default_action_text != "" { + root.default_action(); + return accept; + } + + if event.text == Key.Escape { + root.close(); + return accept; + } + + reject + } + } + + modal := Modal { + width: 100%; + height: 100%; + + VerticalLayout { + alignment: center; + + HorizontalLayout { + alignment: center; + padding: MaterialStyleMetrics.padding_56; + + background_layer := Rectangle { + opacity: 0; + border_radius: MaterialStyleMetrics.border_radius_28; + background: MaterialPalette.surface_container_high; + + TouchArea { + VerticalLayout { + padding: MaterialStyleMetrics.padding_24; + spacing: MaterialStyleMetrics.spacing_16; + + if root.has_icon : Icon { + x: (parent.width - self.width) / 2; + colorize: MaterialPalette.on_surface; + source: root.icon; + } + + if root.title != "" : MaterialText { + horizontal_alignment: root.has_icon ? center : left; + text: root.title; + style: Typography.headline_small; + color: MaterialPalette.on_surface; + } + + @children + + HorizontalLayout { + alignment: end; + spacing: MaterialStyleMetrics.spacing_8; + + for action[index] in root.actions : TextButton { + text: action; + + clicked => { + root.action(index); + } + } + + if root.default_action_text != "" : FilledButton { + text: root.default_action_text; + + clicked => { + root.default_action(); + } + } + } + } + } + + animate opacity { duration: Animations.opacity_duration; easing: Animations.opacity_easing; } + } + } + } + + + clicked => { + root.close(); + } + } + + + Timer { + interval: 50ms; + + triggered => { + background_layer.opacity = 1; + self.running = false; + } + } +} diff --git a/component-sets/material/ui/components/divider.slint b/component-sets/material/ui/components/divider.slint new file mode 100644 index 000000000..c7b949851 --- /dev/null +++ b/component-sets/material/ui/components/divider.slint @@ -0,0 +1,28 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; + +component BaseDivider { + Rectangle { + background: MaterialPalette.outline_variant; + } +} + +export component VerticalDivider { + width: 1px; + + BaseDivider { + width: 100%; + height: 100%; + } +} + +export component HorizontalDivider { + height: 1px; + + BaseDivider { + width: 100%; + height: 100%; + } +} diff --git a/component-sets/material/ui/components/drawer.slint b/component-sets/material/ui/components/drawer.slint new file mode 100644 index 000000000..a1e8417ef --- /dev/null +++ b/component-sets/material/ui/components/drawer.slint @@ -0,0 +1,89 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialText } from "./material_text.slint"; +import { Animations } from "../styling/animations.slint"; +import { Modal } from "./modal.slint"; + +export component DrawerHeader { + in property title; + + min_height: max(MaterialStyleMetrics.size_56, title_label.min_width); + + title_label := MaterialText { + x: MaterialStyleMetrics.padding_16; + width: root.width - MaterialStyleMetrics.padding_16; + text: root.title; + color: MaterialPalette.on_surface_variant; + vertical_alignment: center; + style: Typography.title_small; + } +} + +export component Drawer { + in property title; + + min_width: max(MaterialStyleMetrics.size_360, layout.min_width); + + TouchArea { + + Rectangle { + background: MaterialPalette.surface_container_low; + border_radius: MaterialStyleMetrics.border_radius_16; + + layout := VerticalLayout { + alignment: start; + padding: MaterialStyleMetrics.padding_12; + + if root.title != "" : DrawerHeader { + width: 100%; + title: root.title; + } + + @children + } + } + } +} + +export component ModalDrawer inherits PopupWindow { + in property position_right; + in property title; + + close_policy: no_auto_close; + + modal := Modal { + width: 100%; + height: 100%; + + drawer := Drawer { + x: root.position_right ? parent.width : -self.width; + y: 0; + height: 100%; + title: root.title; + + @children + + animate x { + duration: Animations.standard_accelerate_duration; + easing: Animations.standard_easing; + } + } + + clicked => { + root.close(); + } + } + + Timer { + interval: 50ms; + + triggered => { + drawer.x = root.position_right ? root.width - drawer.width : 0; + self.running = false; + } + } +} diff --git a/component-sets/material/ui/components/elevated_button.slint b/component-sets/material/ui/components/elevated_button.slint new file mode 100644 index 000000000..7e38d0565 --- /dev/null +++ b/component-sets/material/ui/components/elevated_button.slint @@ -0,0 +1,45 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component ElevatedButton { + in property icon <=> base.icon; + in property text <=> base.text; + in property tooltip <=> base.tooltip; + in property enabled <=> base.enabled; + + callback clicked <=> base.clicked; + + accessible-role: button; + accessible-enabled: root.enabled; + accessible-label: root.text == "" ? root.tooltip : root.text; + accessible-action-default => { base.clicked(); } + + elevation := Elevation { + border_radius: root.height / 2; + background: MaterialPalette.surface_container_low; + level: 1; + width: 100%; + height: 100%; + } + + base := BaseButton { + border_radius: elevation.border_radius; + color: MaterialPalette.primary; + } + + states [ + disabled when !root.enabled : { + elevation.background: transparent; + elevation.level: 0; + base.color: MaterialPalette.on_surface; + } + hover when base.has_hover && !base.pressed && !base.enter_pressed : { + elevation.level: 3; + } + ] +} diff --git a/component-sets/material/ui/components/elevation.slint b/component-sets/material/ui/components/elevation.slint new file mode 100644 index 000000000..7d33ddf2a --- /dev/null +++ b/component-sets/material/ui/components/elevation.slint @@ -0,0 +1,108 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Palette, Switch } from "std-widgets.slint"; +import { MaterialWindow } from "material_window.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component Elevation { + in property background; + in property border_radius; + in property level; + + property dark: Palette.color_scheme == ColorScheme.dark; + + outer_shadow := Rectangle { + border_radius: root.border_radius; + + inner_shadow := Rectangle { + border_radius: root.border_radius; + background: root.background; + + @children + } + } + + states [ + level_1_light when root.level == 1 && !root.dark: { + outer_shadow.drop_shadow_offset_y: 1px; + outer_shadow.drop_shadow_blur: 2px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_30; + inner_shadow.drop_shadow_offset_y: 1px; + inner_shadow.drop_shadow_blur: 2px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_15; + } + level_2_light when root.level == 2 && !root.dark: { + outer_shadow.drop_shadow_offset_y: 1px; + outer_shadow.drop_shadow_blur: 2px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_30; + inner_shadow.drop_shadow_offset_y: 2px; + inner_shadow.drop_shadow_blur: 6px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_15; + } + level_3_light when root.level == 3 && !root.dark: { + outer_shadow.drop_shadow_offset_y: 4px; + outer_shadow.drop_shadow_blur: 8px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_15; + inner_shadow.drop_shadow_offset_y: 1px; + inner_shadow.drop_shadow_blur: 3px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_30; + } + level_4_light when root.level == 4 && !root.dark: { + outer_shadow.drop_shadow_offset_y: 6px; + outer_shadow.drop_shadow_blur: 10px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_15; + inner_shadow.drop_shadow_offset_y: 2px; + inner_shadow.drop_shadow_blur: 3px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_30; + } + level_5_light when root.level == 5 && !root.dark: { + outer_shadow.drop_shadow_offset_y: 8px; + outer_shadow.drop_shadow_blur: 12px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_15; + inner_shadow.drop_shadow_offset_y: 4px; + inner_shadow.drop_shadow_blur: 4px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_30; + } + level_1_dark when root.level == 1 && root.dark: { + outer_shadow.drop_shadow_offset_y: 1px; + outer_shadow.drop_shadow_blur: 3px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_15; + inner_shadow.drop_shadow_offset_y: 1px; + inner_shadow.drop_shadow_blur: 2px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_30; + } + level_2_dark when root.level == 2 && root.dark: { + outer_shadow.drop_shadow_offset_y: 2px; + outer_shadow.drop_shadow_blur: 6px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_15; + inner_shadow.drop_shadow_offset_y: 1px; + inner_shadow.drop_shadow_blur: 2px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_30; + } + level_3_dark when root.level == 3 && root.dark: { + outer_shadow.drop_shadow_offset_y: 4px; + outer_shadow.drop_shadow_blur: 8px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_15; + inner_shadow.drop_shadow_offset_y: 1px; + inner_shadow.drop_shadow_blur: 3px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_30; + } + level_4_dark when root.level == 4 && root.dark: { + outer_shadow.drop_shadow_offset_y: 6px; + outer_shadow.drop_shadow_blur: 10px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_15; + inner_shadow.drop_shadow_offset_y: 2px; + inner_shadow.drop_shadow_blur: 3px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_30; + } + level_5_dark when root.level == 5 && root.dark: { + outer_shadow.drop_shadow_offset_y: 8px; + outer_shadow.drop_shadow_blur: 12px; + outer_shadow.drop_shadow_color: MaterialPalette.shadow_15; + inner_shadow.drop_shadow_offset_y: 4px; + inner_shadow.drop_shadow_blur: 4px; + inner_shadow.drop_shadow_color: MaterialPalette.shadow_30; + } + ] +} diff --git a/component-sets/material/ui/components/extended_touch_area.slint b/component-sets/material/ui/components/extended_touch_area.slint new file mode 100644 index 000000000..e61897055 --- /dev/null +++ b/component-sets/material/ui/components/extended_touch_area.slint @@ -0,0 +1,57 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Animations } from "../styling/animations.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { ToolTip } from "tooltip.slint"; + +export component ExtendedTouchArea inherits TouchArea { + in property tooltip; + in property tooltip_offset; + out property has_focus <=> focus_scope.has_focus; + out property enter_pressed; + + callback key_pressed(KeyEvent) -> EventResult; + + forward-focus: focus-scope; + + focus_scope := FocusScope { + x: 0; + width: 0px; + enabled: root.enabled; + + key_pressed(event) => { + if !root.enabled { + return reject; + } + + if (event.text == " " || event.text == "\n") && !root.enter_pressed { + root.enter_pressed = true; + root.clicked(); + return accept; + } + + root.key_pressed(event) + } + + key_released(event) => { + if !root.enabled { + return reject; + } + + if (event.text == " " || event.text == "\n") && root.enter_pressed { + root.enter_pressed = false; + return accept; + } + + reject + } + } + + @children + + if root.tooltip != "" && root.has-hover && !root.pressed : ToolTip { + y: root.tooltip_offset; + text: root.tooltip; + } +} diff --git a/component-sets/material/ui/components/filled_button.slint b/component-sets/material/ui/components/filled_button.slint new file mode 100644 index 000000000..7363771c1 --- /dev/null +++ b/component-sets/material/ui/components/filled_button.slint @@ -0,0 +1,43 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component FilledButton { + in property icon <=> base.icon; + in property text <=> base.text; + in property tooltip <=> base.tooltip; + in property enabled <=> base.enabled; + + callback clicked <=> base.clicked; + + accessible-role: button; + accessible-enabled: root.enabled; + accessible-label: root.text == "" ? root.tooltip : root.text; + accessible-action-default => { base.clicked(); } + + elevation := Elevation { + border_radius: root.height / 2; + background: MaterialPalette.primary; + width: 100%; + height: 100%; + } + + base := BaseButton { + border_radius: elevation.border_radius; + color: MaterialPalette.on_primary; + } + + states [ + disabled when !root.enabled : { + elevation.background: transparent; + base.color: MaterialPalette.on_surface; + } + hover when base.has_hover && !base.pressed && !base.enter_pressed : { + elevation.level: 1; + } + ] +} diff --git a/component-sets/material/ui/components/filled_icon_button.slint b/component-sets/material/ui/components/filled_icon_button.slint new file mode 100644 index 000000000..0785bfab1 --- /dev/null +++ b/component-sets/material/ui/components/filled_icon_button.slint @@ -0,0 +1,64 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component FilledIconButton { + in property icon; + in property icon_checked: root.icon; + in property checkable; + in_out property checked; + in property tooltip <=> base.tooltip; + in property enabled <=> base.enabled; + + callback clicked(); + + accessible-role: button; + accessible-enabled: true; + accessible-label: root.tooltip; + accessible-checkable: root.checkable; + accessible-checked: root.checked; + accessible-action-default => { base.clicked(); } + + background_layer := Rectangle { + width: 100%; + height: 100%; + border_radius: base.border_radius; + background: root.checkable ? MaterialPalette.surface_container_highest : MaterialPalette.primary; + visible: root.enabled; + } + + base := BaseButton { + icon: root.checked ? root.icon_checked : root.icon; + border_radius: self.height / 2; + color: !root.enabled ? MaterialPalette.on_surface_variant : root.checkable ? MaterialPalette.primary : MaterialPalette.on_primary; + horizontal_padding: 0; + vertical_padding: 0; + width: self.height; + icon_size: MaterialStyleMetrics.icon_size_56; + + clicked => { + root.toggle(); + root.clicked(); + } + } + + function toggle() { + if !root.checkable { + return; + } + + root.checked = !root.checked; + } + + states [ + checked when root.enabled && root.checked : { + base.color: MaterialPalette.on_primary; + background_layer.background: MaterialPalette.primary; + } + ] +} diff --git a/component-sets/material/ui/components/floating_action_button.slint b/component-sets/material/ui/components/floating_action_button.slint new file mode 100644 index 000000000..c6eb3f15b --- /dev/null +++ b/component-sets/material/ui/components/floating_action_button.slint @@ -0,0 +1,55 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export enum FABStyle { + small, + standard, + large +} + +export component FloatingActionButton { + in property icon <=> base.icon; + in property text <=> base.text; + in property tooltip <=> base.tooltip; + in property style; + + callback clicked <=> base.clicked; + + accessible-role: button; + accessible-enabled: true; + accessible-label: root.text == "" ? root.tooltip : root.text; + accessible-action-default => { base.clicked(); } + + elevation := Elevation { + border_radius: root.style == FABStyle.small ? MaterialStyleMetrics.border_radius_12 : + root.style == FABStyle.standard ? MaterialStyleMetrics.border_radius_16 : MaterialStyleMetrics.border_radius_28; + background: MaterialPalette.primary; + level: 3; + width: 100%; + height: 100%; + } + + base := BaseButton { + border_radius: elevation.border_radius; + color: MaterialPalette.on_primary; + vertical_padding: root.style == FABStyle.small ? MaterialStyleMetrics.padding_10 : + root.style == FABStyle.standard ? MaterialStyleMetrics.padding_14 : MaterialStyleMetrics.padding_30; + horizontal_padding: self.vertical_padding; + min_layout_width: self.min_layout_height; + min_layout_height: root.style == FABStyle.small ? MaterialStyleMetrics.size_40 : + root.style == FABStyle.standard ? MaterialStyleMetrics.size_56 : MaterialStyleMetrics.size_90; + icon_size: root.style != FABStyle.large ? MaterialStyleMetrics.icon_size_40 : MaterialStyleMetrics.icon_size_90; + } + + states [ + hover when base.has_hover : { + elevation.level: 4; + } + ] +} diff --git a/component-sets/material/ui/components/grid.slint b/component-sets/material/ui/components/grid.slint new file mode 100644 index 000000000..9c82f5680 --- /dev/null +++ b/component-sets/material/ui/components/grid.slint @@ -0,0 +1,10 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component Grid inherits GridLayout { + padding: MaterialStyleMetrics.padding_8; + spacing_vertical: MaterialStyleMetrics.spacing_8; + spacing_horizontal: MaterialStyleMetrics.spacing_8; +} diff --git a/component-sets/material/ui/components/horizontal.slint b/component-sets/material/ui/components/horizontal.slint new file mode 100644 index 000000000..bddf80157 --- /dev/null +++ b/component-sets/material/ui/components/horizontal.slint @@ -0,0 +1,9 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component Horizontal inherits HorizontalLayout { + padding: MaterialStyleMetrics.padding_8; + spacing: MaterialStyleMetrics.spacing_8; +} diff --git a/component-sets/material/ui/components/icon.slint b/component-sets/material/ui/components/icon.slint new file mode 100644 index 000000000..064495685 --- /dev/null +++ b/component-sets/material/ui/components/icon.slint @@ -0,0 +1,11 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component Icon inherits Image { + width: MaterialStyleMetrics.icon_size_40; + height: self.width; + colorize: MaterialPalette.on_background; +} diff --git a/component-sets/material/ui/components/icon_button.slint b/component-sets/material/ui/components/icon_button.slint new file mode 100644 index 000000000..44690073d --- /dev/null +++ b/component-sets/material/ui/components/icon_button.slint @@ -0,0 +1,57 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component IconButton { + in property icon; + in property icon_checked: root.icon; + in property checkable; + in_out property checked; + in property tooltip <=> base.tooltip; + in property enabled <=> base.enabled; + in property inverse; + + callback clicked(); + + accessible-role: button; + accessible-enabled: true; + accessible-label: root.tooltip; + accessible-checkable: root.checkable; + accessible-checked: root.checked; + accessible-action-default => { base.clicked(); } + + base := BaseButton { + icon: root.checked ? root.icon_checked : root.icon; + border_radius: self.height / 2; + color: root.inverse ? MaterialPalette.inverse_on_surface : MaterialPalette.on_surface_variant; + horizontal_padding: 0; + vertical_padding: 0; + width: self.height; + display_background: false; + icon_size: MaterialStyleMetrics.icon_size_56; + + clicked => { + root.toggle(); + root.clicked(); + } + } + + function toggle() { + if !root.checkable { + return; + } + + root.checked = !root.checked; + } + + states [ + checked when root.enabled && root.checked : { + base.color: MaterialPalette.primary; + } + ] +} diff --git a/component-sets/material/ui/components/list.slint b/component-sets/material/ui/components/list.slint new file mode 100644 index 000000000..d6e32d5fc --- /dev/null +++ b/component-sets/material/ui/components/list.slint @@ -0,0 +1,35 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component Avatar { + in property image; + in property background: MaterialPalette.primary; + + min_width: MaterialStyleMetrics.size_32; + height: self.width; + + Rectangle { + width: 100%; + height: 100%; + border_radius: self.width / 2; + background: root.background; + clip: true; + + Image { + width: 100%; + source: root.image; + } + } +} + +export component ListItemTemplate { + in property text; + in property supporting_text; + in property avatar; + in property avatar_background; + in property avatar_colorize; +} + diff --git a/component-sets/material/ui/components/list_view.slint b/component-sets/material/ui/components/list_view.slint new file mode 100644 index 000000000..aeb847f7c --- /dev/null +++ b/component-sets/material/ui/components/list_view.slint @@ -0,0 +1,8 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { ScrollView } from "./scroll_view.slint"; + +export component ListView inherits ScrollView { + +} diff --git a/component-sets/material/ui/components/material_text.slint b/component-sets/material/ui/components/material_text.slint new file mode 100644 index 000000000..e74032176 --- /dev/null +++ b/component-sets/material/ui/components/material_text.slint @@ -0,0 +1,14 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Typography, TextStyle } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component MaterialText inherits Text { + in property style: Typography.body_medium; + + font_size: root.style.font_size; + font_weight: root.style.font_weight; + color: MaterialPalette.on_background; + overflow: elide; +} diff --git a/component-sets/material/ui/components/material_window.slint b/component-sets/material/ui/components/material_window.slint new file mode 100644 index 000000000..d73cf9952 --- /dev/null +++ b/component-sets/material/ui/components/material_window.slint @@ -0,0 +1,8 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component MaterialWindow inherits Window { + background: MaterialPalette.background; +} diff --git a/component-sets/material/ui/components/modal.slint b/component-sets/material/ui/components/modal.slint new file mode 100644 index 000000000..d716eea2a --- /dev/null +++ b/component-sets/material/ui/components/modal.slint @@ -0,0 +1,28 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; +import { Animations } from "../styling/animations.slint"; + +export component Modal { + callback clicked <=> touch_area.clicked; + + background_layer := Rectangle { + clip: true; + + touch_area := TouchArea { + @children + } + + animate background { duration: Animations.opacity_duration; easing: Animations.opacity_easing; } + } + + Timer { + interval: 50ms; + + triggered => { + background_layer.background = MaterialPalette.background_modal; + self.running = false; + } + } +} diff --git a/component-sets/material/ui/components/navigation_bar.slint b/component-sets/material/ui/components/navigation_bar.slint new file mode 100644 index 000000000..a2339ef2d --- /dev/null +++ b/component-sets/material/ui/components/navigation_bar.slint @@ -0,0 +1,150 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Badge } from "./badge.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { MaterialText } from "./material_text.slint"; +import { Typography } from "../styling/typography.slint"; +import { ExtendedTouchArea } from "./extended_touch_area.slint"; +import { StateLayer, Ripple } from "./state_layer.slint"; +import { Icon } from "./icon.slint"; +import { NavigationItem } from "../items/navigation_item.slint"; +import { BaseNavigationItemTemplate, BaseNavigation } from "./base_navigation.slint"; + +export component NavigationItemTemplate inherits BaseNavigationItemTemplate { + property has_icon: root.icon.width > 0 && root.icon.height > 0; + property has_icon_selected: root.icon_selected.width > 0 || root.icon_selected.height > 0; + property color: MaterialPalette.on_surface; + + padding_top: MaterialStyleMetrics.padding_12; + padding_bottom: MaterialStyleMetrics.padding_16; + + Rectangle { + width: 100%; + height: 100%; + } + + touch_area := ExtendedTouchArea { + HorizontalLayout { + alignment: center; + + VerticalLayout { + alignment: start; + spacing: MaterialStyleMetrics.spacing_4; + padding_top: root.padding_top; + padding_bottom: root.padding_bottom; + + HorizontalLayout { + alignment: center; + + background_layer := Rectangle { + min_width: state_layout.min_width; + min_height: max(MaterialStyleMetrics.size_32, state_layout.min_height); + border_radius: self.height / 2; + + state_layer := StateLayer { + background: root.color; + border_radius: parent.border_radius; + enabled: true; + has_focus: touch_area.has_focus; + has_hover: touch_area.has_hover; + pressed: touch_area.pressed || touch_area.enter_pressed; + width: 100%; + height: 100%; + + if touch_area.pressed && !root.selected : Ripple { + width: root.width; + height: root.height; + pressed_x: touch_area.pressed_x; + pressed_y: touch_area.pressed_y; + color: root.color; + } + + state_layout := HorizontalLayout { + padding_left: MaterialStyleMetrics.padding_20; + padding_right: self.padding_left; + alignment: center; + + VerticalLayout { + alignment: center; + + if !root.has_icon && !root.has_icon_selected : Rectangle { + width: 12px; + height: self.width; + border_radius: self.width / 2; + background: root.color; + } + + if root.has_icon || root.has_icon_selected : Icon { + source: root.icon; + colorize: root.color; + + states [ + selected when root.selected && root.has_icon_selected : { + source: root.icon_selected; + } + ] + } + } + } + } + + if root.empty_badge || root.badge != "" : Badge { + x: parent.width / 2; + y: 0; + text: root.badge; + } + } + } + + label := MaterialText { + text: root.text; + style: Typography.label_medium; + color: root.color; + horizontal_alignment: center; + } + } + } + + clicked => { + root.clicked(); + } + } + + states [ + selected when root.selected : { + background_layer.background: MaterialPalette.secondary_container; + state_layer.background: transparent; + label.style: Typography.label_medium_prominent; + } + ] +} + +export component NavigationBar inherits BaseNavigation { + min_height: max(MaterialStyleMetrics.size_80, layout.min_height); + + Rectangle { + background: MaterialPalette.surface_container; + + layout := HorizontalLayout { + padding_left: MaterialStyleMetrics.padding_8; + padding_right: self.padding_left; + spacing: MaterialStyleMetrics.spacing_8; + + for item[index] in root.items : NavigationItemTemplate { + icon: item.icon; + icon_selected: item.icon_selected; + text: item.text; + index: index; + selected: index == root.current_item; + empty_badge: item.empty_badge; + badge: item.badge; + + clicked => { + root.select(index); + } + } + } + } +} diff --git a/component-sets/material/ui/components/navigation_drawer.slint b/component-sets/material/ui/components/navigation_drawer.slint new file mode 100644 index 000000000..71e006e17 --- /dev/null +++ b/component-sets/material/ui/components/navigation_drawer.slint @@ -0,0 +1,191 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Drawer, ModalDrawer, DrawerHeader } from "./drawer.slint"; +import { NavigationItem, NavigationGroup } from "../items/navigation_item.slint"; +import { HorizontalDivider } from "./divider.slint"; +import { StateLayerArea } from "./state_layer.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { Icon } from "./icon.slint"; +import { MaterialText } from "./material_text.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { Animations } from "../styling/animations.slint"; +import { BaseNavigationItemTemplate } from "./base_navigation.slint"; + +component NavigationItemTempalte inherits BaseNavigationItemTemplate { + property has_icon: root.icon.width > 0 && root.icon.height > 0; + property has_icon_selected: root.icon_selected.width > 0 || root.icon_selected.height > 0; + property color: MaterialPalette.on_surface_variant; + + min_height: max(MaterialStyleMetrics.size_56, layout.min_height); + + background_layer := Rectangle { + border_radius: self.height / 2; + + state_layer := StateLayerArea { + border_radius: parent.border_radius; + color: root.selected ? transparent : root.color; + + layout := HorizontalLayout { + padding_left: MaterialStyleMetrics.padding_16; + padding_right: MaterialStyleMetrics.padding_24; + padding_top: MaterialStyleMetrics.padding_16; + padding_bottom: self.padding_top; + spacing: MaterialStyleMetrics.spacing_12; + + VerticalLayout { + alignment: center; + + if !root.has_icon && !root.has_icon_selected : Rectangle { + width: MaterialStyleMetrics.icon_size_40; + height: self.width; + + Rectangle { + width: 12px; + height: self.width; + border_radius: self.width / 2; + background: root.color; + } + } + + if root.has_icon || root.has_icon_selected : Icon { + source: root.icon; + colorize: root.color; + + states [ + selected when root.selected && root.has_icon_selected : { + source: root.icon_selected; + } + ] + } + } + + MaterialText { + horizontal_stretch: 1; + text: root.text; + style: Typography.label_large; + color: root.color; + vertical_alignment: center; + } + + if root.badge != "" : MaterialText { + text: root.badge; + style: Typography.label_large; + color: root.color; + vertical_alignment: center; + } + } + + clicked => { + root.clicked(); + } + } + + animate background { duration: Animations.opacity_duration; easing: Animations.opacity_easing; } + } + + states [ + selected when root.selected : { + background_layer.background: MaterialPalette.secondary_container; + root.color: MaterialPalette.on_secondary_container; + } + ] + + animate color { duration: Animations.opacity_duration; easing: Animations.opacity_easing; } +} + +component NavigationGroupTemplate { + in property title; + in property <[NavigationItem]> items; + in property current_item: -1; + in property has_divider; + + callback select(index: int); + + VerticalLayout { + alignment: start; + + if root.title != 0 : DrawerHeader { + title: root.title; + } + + for item[index] in root.items : NavigationItemTempalte { + icon: item.icon; + icon_selected: item.icon_selected; + text: item.text; + badge: item.badge; + selected: index == root.current_item; + index: index; + + clicked => { + root.select(index); + } + } + + if root.has_divider : HorizontalDivider {} + } +} + +export component NavigationDrawer inherits Drawer { + in property <[NavigationGroup]> groups; + in_out property current_group; + in_out property current_item; + + accessible-role: tab-list; + // accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item; + // accessible-label: root.title; + accessible-item-count: root.groups.length; + + for group[group_index] in root.groups : NavigationGroupTemplate { + title: group.title; + items: group.items; + current_item: group_index == root.current_group ? root.current_item : -1; + has_divider: root.groups.length > 1 && group_index < root.groups.length - 1; + + select(index) => { + root.select(group_index, index); + } + } + + function select(group_index: int, item_index: int) { + if group_index < 0 || group_index >= root.groups.length || item_index < 0 || item_index >= root.groups[group_index].items.length { + return; + } + + root.current_group = group_index; + root.current_item = item_index; + } +} + +export component ModalNavigationDrawer inherits ModalDrawer { + in property <[NavigationGroup]> groups; + in_out property current_group; + in_out property current_item; + + accessible-role: tab-list; + // accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item; + // accessible-label: root.title; + accessible-item-count: root.groups.length; + + for group[group_index] in root.groups : NavigationGroupTemplate { + title: group.title; + items: group.items; + current_item: group_index == root.current_group ? root.current_item : -1; + has_divider: root.groups.length > 1 && group_index < root.groups.length - 1; + + select(index) => { + root.select(group_index, index); + } + } + + function select(group_index: int, item_index: int) { + if group_index < 0 || group_index >= root.groups.length || item_index < 0 || item_index >= root.groups[group_index].items.length { + return; + } + + root.current_group = group_index; + root.current_item = item_index; + root.close(); + } +} diff --git a/component-sets/material/ui/components/navigation_rail.slint b/component-sets/material/ui/components/navigation_rail.slint new file mode 100644 index 000000000..8097bccf6 --- /dev/null +++ b/component-sets/material/ui/components/navigation_rail.slint @@ -0,0 +1,84 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { NavigationItem } from "../items/navigation_item.slint"; +import { FloatingActionButton, FABStyle } from "./floating_action_button.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { IconButton } from "icon_button.slint"; +import { Icons } from "../icons/icons.slint"; +import { NavigationItemTemplate } from "navigation_bar.slint"; +import { BaseNavigation } from "./base_navigation.slint"; + +export component NavigationRail inherits BaseNavigation { + in property has_menu; + in property fab_icon; + in property alignment; + + callback menu_clicked(); + callback fab_clicked(); + + min_width: max(MaterialStyleMetrics.size_80, layout.min_width); + + Rectangle { + background: MaterialPalette.surface; + + layout := VerticalLayout { + padding_top: MaterialStyleMetrics.padding_44; + padding_bottom: MaterialStyleMetrics.padding_56; + spacing: MaterialStyleMetrics.spacing_4; + + if root.has_menu : IconButton { + icon: Icons.menu; + + clicked => { + root.menu_clicked(); + } + } + + + if root.fab_icon.width > 0 && root.fab_icon.height > 0 : HorizontalLayout { + alignment: center; + + FloatingActionButton { + icon: root.fab_icon; + style: FABStyle.standard; + + clicked => { + root.fab_clicked(); + } + } + } + + // helper to place fab at the top if no items are present + if root.items.length == 0 : Rectangle { + horizontal_stretch: 1; + } + + HorizontalLayout { + vertical_stretch: 1; + alignment: center; + + VerticalLayout { + alignment: root.alignment; + + for item[index] in root.items : NavigationItemTemplate { + icon: item.icon; + icon_selected: item.icon_selected; + text: item.text; + index: index; + selected: index == root.current_item; + empty_badge: item.empty_badge; + badge: item.badge; + padding_top: 0; + padding_bottom: MaterialStyleMetrics.padding_4; + + clicked => { + root.select(index); + } + } + } + } + } + } +} diff --git a/component-sets/material/ui/components/outline_button.slint b/component-sets/material/ui/components/outline_button.slint new file mode 100644 index 000000000..28c65d533 --- /dev/null +++ b/component-sets/material/ui/components/outline_button.slint @@ -0,0 +1,42 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component OutlineButton { + in property icon <=> base.icon; + in property text <=> base.text; + in property enabled <=> base.enabled; + in property tooltip <=> base.tooltip; + + callback clicked <=> base.clicked; + + accessible-role: button; + accessible-enabled: root.enabled; + accessible-label: root.text == "" ? root.tooltip : root.text; + accessible-action-default => { base.clicked(); } + + base := BaseButton { + border_radius: border.border_radius; + color: MaterialPalette.primary; + } + + border := Rectangle { + border_radius: root.height / 2; + border_width: 1px; + border_color: MaterialPalette.outline; + width: 100%; + height: 100%; + } + + states [ + disabled when !root.enabled : { + base.color: MaterialPalette.on_surface; + base.transparent_background: true; + border.border_color: MaterialPalette.on_surface; + border.opacity: MaterialPalette.state_layer_opacity_hover; + } + ] +} diff --git a/component-sets/material/ui/components/outline_icon_button.slint b/component-sets/material/ui/components/outline_icon_button.slint new file mode 100644 index 000000000..1b183f1f0 --- /dev/null +++ b/component-sets/material/ui/components/outline_icon_button.slint @@ -0,0 +1,78 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component OutlineIconButton { + in property icon; + in property icon_checked: root.icon; + in property checkable; + in_out property checked; + in property tooltip <=> base.tooltip; + in property enabled <=> base.enabled; + + callback clicked(); + + accessible-role: button; + accessible-enabled: true; + accessible-label: root.tooltip; + accessible-checkable: root.checkable; + accessible-checked: root.checked; + accessible-action-default => { base.clicked(); } + + background_layer := Rectangle { + width: 100%; + height: 100%; + border_radius: base.border_radius; + border_width: 1px; + border_color: MaterialPalette.outline; + } + + base := BaseButton { + icon: root.checked ? root.icon_checked : root.icon; + border_radius: self.height / 2; + color: !root.enabled ? MaterialPalette.on_surface_variant : MaterialPalette.on_surface_variant; + horizontal_padding: 0; + vertical_padding: 0; + width: self.height; + icon_size: MaterialStyleMetrics.icon_size_56; + display_background: false; + + clicked => { + root.toggle(); + root.clicked(); + } + } + + function toggle() { + if !root.checkable { + return; + } + + root.checked = !root.checked; + } + + states [ + disabled when !root.enabled : { + base.color: MaterialPalette.on_surface; + base.transparent_background: true; + background_layer.border_color: root.checked ? transparent : MaterialPalette.on_surface; + background_layer.background: root.checked ? MaterialPalette.on_surface : transparent; + background_layer.opacity: MaterialPalette.state_layer_opacity_hover; + } + checked when root.enabled && root.checked : { + base.color: MaterialPalette.inverse_on_surface; + background_layer.background: MaterialPalette.inverse_surface; + background_layer.border_width: 0; + } + checked_disabled when root.enabled && root.checked : { + base.color: MaterialPalette.inverse_on_surface; + background_layer.background: MaterialPalette.inverse_on_surface; + background_layer.border_width: 0; + } + ] +} diff --git a/component-sets/material/ui/components/progress_indicator.slint b/component-sets/material/ui/components/progress_indicator.slint new file mode 100644 index 000000000..e2bfe636e --- /dev/null +++ b/component-sets/material/ui/components/progress_indicator.slint @@ -0,0 +1,107 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component LinearProgressIndicator { + in property value; + in property indeterminate; + + height: MaterialStyleMetrics.size_4; + + Rectangle { + width: 100%; + height: 100%; + clip: true; + background: MaterialPalette.primary_container; + border_radius: MaterialStyleMetrics.border_radius_2; + + track := Rectangle { + x: 0; + y: 0; + width: parent.width * root.value; + height: 100%; + border_radius: parent.border_radius; + background: MaterialPalette.primary; + } + } +} + +export component CircularProgressIndicator { + in property value; + in property indeterminate; + + property bar_height: MaterialStyleMetrics.size_4; + + width: self.height; + min_height: MaterialStyleMetrics.size_40; + + background_layer := Rectangle { + width: root.width; + height: root.height; + border_width: root.bar_height; + border_color: root.value == 1 ? MaterialPalette.primary : MaterialPalette.primary_container; + border_radius: max(self.width, self.height) / 2; + } + + track := Path { + property radius: min(self.viewbox_width, self.viewbox_height) / 2; + property start_x: self.viewbox_width / 2; + property start_y: self.viewbox_height / 2; + property inner_radius: self.radius - (root.bar_height * (self.viewbox_height / self.height)); + property start: !root.indeterminate ? 0 : 1 * mod(animation-tick(), 1.5s) / 1.5s; + property progress: !root.indeterminate ? root.value : 0.5; + + x: background_layer.x; + y: background_layer.y; + viewbox_width: 100; + viewbox_height: 100; + width: background_layer.width; + height: background_layer.height; + fill: MaterialPalette.primary; + visible: self.progress > 0 && self.progress < 1; + + MoveTo { + x: !root.indeterminate ? track.start_x : track.start_x - track.radius * sin(-track.start * 360deg); + y: !root.indeterminate ? 0 : track.start_y - track.radius * cos(-track.start * 360deg); + } + + ArcTo { + radius_x: 1; + radius_y: 1; + x: !root.indeterminate ? track.start_x : track.start_x - track.inner-radius * sin(-track.start * 360deg); + y: !root.indeterminate ? root.bar_height * (track.viewbox_height / track.height) : track.start_y - track.inner_radius * cos(-track.start * 360deg); + } + + ArcTo { + radius_x: track.inner_radius; + radius_y: track.inner_radius; + x: start_x - track.inner_radius * sin(-(track.start + track.progress) * 360deg); + y: start_y - track.inner_radius * cos(-(track.start + track.progress) * 360deg); + sweep: track.progress > 0; + large-arc: track.progress > 0.5; + } + + ArcTo { + radius_x: 1; + radius_y: 1; + x: start_x - radius * sin(-(track.start + track.progress) * 360deg); + y: start_y - radius * cos(-(track.start + track.progress) * 360deg); + } + + ArcTo { + radius_x: radius; + radius_y: radius; + x: start_x - radius * sin(-track.start * 360deg); + y: start_y - radius * cos(-track.start * 360deg); + sweep: track.progress < 0; + large-arc: track.progress > 0.5; + } + + LineTo { + x: start_x - radius * sin(-track.start * 360deg); + y: start_y - radius * cos(-track.start * 360deg); + } + } +} diff --git a/component-sets/material/ui/components/scroll_view.slint b/component-sets/material/ui/components/scroll_view.slint new file mode 100644 index 000000000..f14193e9b --- /dev/null +++ b/component-sets/material/ui/components/scroll_view.slint @@ -0,0 +1,166 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component ScrollBar { + in property enabled; + out property has_hover: touch_area.has_hover; + in_out property horizontal; + in_out property maximum; + in_out property page_size; + in_out property value; + in property policy: ScrollBarPolicy.as_needed; + + property track_size: root.horizontal ? root.width - 2 * root.offset : root.height - 2 * offset; + property step_size: 10px; + property offset: 2px; + property state_opacity: 40%; + + visible: (self.policy == ScrollBarPolicy.always_on) || (self.policy == ScrollBarPolicy.as_needed && self.maximum > 0); + + Rectangle { + clip: true; + + thumb := Rectangle { + width: !root.horizontal ? parent.width : root.maximum <= 0phx ? 0phx : max(min(32px, root.width), root.track-size * root.page-size / (root.maximum + root.page-size)); + height: root.horizontal ? parent.height : root.maximum <= 0phx ? 0phx : max(min(32px, root.height), root.track-size * (root.page-size / (root.maximum + root.page-size))); + x: !root.horizontal ? (parent.width - self.width) / 2 : root.offset + (root.track-size - thumb.width) * (-root.value / root.maximum); + y: root.horizontal ? (parent.height - self.height) / 2 : root.offset + (root.track-size - thumb.height) * (-root.value / root.maximum); + border-radius: (root.horizontal ? self.height : self.width) / 2; + background: MaterialPalette.on_background; + opacity: hide_timer.running || touch_area.has_hover || touch_area.pressed ? root.state_opacity : 0; + + animate opacity { duration: 150ms; } + } + } + + touch_area := TouchArea { + property pressed_value; + + width: parent.width; + height: parent.height; + + pointer-event(event) => { + if (event.button == PointerEventButton.left && event.kind == PointerEventKind.down) { + self.pressed-value = -root.value; + } + } + + moved => { + if (self.enabled && self.pressed) { + root.value = -max(0px, min(root.maximum, self.pressed-value + ( + root.horizontal ? (touch-area.mouse-x - touch-area.pressed-x) * (root.maximum / (root.track-size - thumb.width)) + : (touch-area.mouse-y - touch-area.pressed-y) * (root.maximum / (root.track-size - thumb.height)) + ))); + } + } + + scroll-event(event) => { + if (root.horizontal && event.delta-x != 0) { + root.value = max(-root.maximum, min(0px, root.value + event.delta-x)); + return accept; + } else if (!root.horizontal && event.delta-y != 0) { + root.value = max(-root.maximum, min(0px, root.value + event.delta-y)); + return accept; + } + + reject + } + + changed has_hover => { + if !self.has_hover && !hide_timer.running { + hide_timer.running = true; + } + } + + changed pressed => { + if self.pressed && hide_timer.running { + hide_timer.running = false; + } + } + } + + changed value => { + if !self.has_hover && !hide_timer.running { + hide_timer.running = true; + } + } + + hide_timer := Timer { + interval: 1.5s; + running: false; + + triggered => { + self.running = false; + } + } + + states [ + pressed when touch_area.pressed : { + root.state_opacity: 80%; + } + hover when root.has_hover : { + root.state_opacity: 70%; + } + ] +} + +export component ScrollView { + in property enabled: true; + out property visible_width <=> flickable.width; + out property visible_height <=> flickable.height; + in_out property viewport_width <=> flickable.viewport_width; + in_out property viewport_height <=> flickable.viewport_height; + in_out property viewport_x <=> flickable.viewport_x; + in_out property viewport_y <=> flickable.viewport_y; + in property vertical_scrollbar_policy <=> vertical_bar.policy; + in property horizontal_scrollbar_policy <=> horizontal_bar.policy; + // FIXME: remove. This property is currently set by the ListView and is used by the native style to draw the scrollbar differently when it has focus + in_out property has_focus; + + callback scrolled <=> flickable.flicked; + + property scroll_bar_size: 8px; + property scroll_bar_padding: 1px; + + min_height: 50px; + min_width: 50px; + horizontal_stretch: 1; + vertical_stretch: 1; + preferred_height: 100%; + preferred_width: 100%; + + flickable := Flickable { + x: 0; + y: 0; + viewport_y <=> vertical_bar.value; + viewport_x <=> horizontal_bar.value; + width: root.width - root.scroll_bar_size - 2 * root.scroll_bar_padding; + height: root.height - root.scroll_bar_size; + + @children + } + + vertical_bar := ScrollBar { + enabled: root.enabled; + x: flickable.width + root.scroll_bar_padding; + y: 0; + width: root.scroll_bar_size; + height: horizontal_bar.visible ? parent.height - horizontal_bar.height : parent.height; + horizontal: false; + maximum: flickable.viewport_height - flickable.height; + page-size: flickable.height; + } + + horizontal-bar := ScrollBar { + enabled: root.enabled; + width: vertical_bar.visible ? parent.width - vertical_bar.width : parent.width; + height: root.scroll_bar_size; + x: 0; + y: flickable.height + root.scroll_bar_padding; + horizontal: true; + maximum: flickable.viewport_width - flickable.width; + page_size: flickable.width; + } +} diff --git a/component-sets/material/ui/components/search_bar.slint b/component-sets/material/ui/components/search_bar.slint new file mode 100644 index 000000000..953514e58 --- /dev/null +++ b/component-sets/material/ui/components/search_bar.slint @@ -0,0 +1,216 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { ListItem } from "../items/list_item.slint"; +import { Avatar, ListItemTemplate } from "./list.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { Typography } from "../styling/typography.slint"; +import { StateLayerArea } from "./state_layer.slint"; +import { MaterialText } from "./material_text.slint"; +import { Icon } from "./icon.slint"; +import { IconButton } from "./icon_button.slint"; +import { Icons } from "../icons/icons.slint"; + +component SearchIcon { + in property icon; + in property color; + + VerticalLayout { + alignment: center; + padding_left: MaterialStyleMetrics.padding_8; + padding_right: self.padding_left; + + Icon { + source: root.icon; + colorize: root.color; + } + } +} + +component SearchTextInput { + in_out property text <=> text_input.text; + in property placeholder; + property computed_x; + + callback accepted(text: string); + callback edited(text: string); + callback key_pressed(event: KeyEvent) -> EventResult; + callback key_released(event: KeyEvent) -> EventResult; + + horizontal_stretch: 1; + + Rectangle { + clip: true; + + text_input := TextInput { + x: min(0px, max(parent.width - self.width - self.text_cursor_width, root.computed_x)); + width: max(parent.width - self.text-cursor-width, self.preferred-width); + height: 100%; + font_size: Typography.body_large.font_size; + font_weight: Typography.body_large.font_weight; + vertical_alignment: center; + single_line: true; + color: MaterialPalette.on_surface; + selection_background_color: MaterialPalette.secondary_container; + selection_foreground_color: self.color; + // Disable TextInput's built-in accessibility support as the component takes care of that. + accessible-role: none; + + cursor-position-changed(cursor_position) => { + if cursor-position.x + root.computed_x < 0 { + root.computed_x = - cursor-position.x; + } else if cursor-position.x + root.computed_x > parent.width - self.text-cursor-width { + root.computed_x = parent.width - cursor_position.x - self.text-cursor-width; + } + } + + accepted => { + root.accepted(self.text); + } + + edited => { + root.edited(self.text); + } + + key_pressed(event) => { + root.key_pressed(event) + } + + key_released(event) => { + root.key_released(event) + } + } + + if root.text == "" && root.placeholder != "" : MaterialText { + width: 100%; + height: 100%; + text: root.placeholder; + color: MaterialPalette.on_surface_variant; + vertical_alignment: center; + style: Typography.body_large; + } + } +} + +export component SearchBar { + in property leading_icon: Icons.menu; + in property trailing_icon; + in property avatar; + in property avatar_background: #00000000; + in property placeholder; + in_out property text <=> input.text; + in_out property current_item; + in property <[ListItem]> items; + + callback accepted(text: string); + callback edited(text: string); + callback key_pressed(event: KeyEvent) -> EventResult; + callback key_released(event: KeyEvent) -> EventResult; + + property color: MaterialPalette.on_surface_variant; + + min_height: max(MaterialStyleMetrics.size_56, layout.min_height); + + Rectangle { + background: MaterialPalette.surface_container_high; + border_radius: MaterialStyleMetrics.border_radius_28; + + StateLayerArea { + border_radius: parent.border_radius; + color: root.color; + + layout := HorizontalLayout { + padding: MaterialStyleMetrics.padding_4; + spacing: MaterialStyleMetrics.spacing_4; + + SearchIcon { + icon: root.leading_icon; + color: root.color; + } + + input := SearchTextInput { + placeholder: root.placeholder; + + accepted => { + root.accepted(self.text); + } + + edited => { + if self.text != "" { + popup.show(); + } + root.edited(self.text); + } + + key_pressed(event) => { + root.key_pressed(event) + } + + key_released(event) => { + root.key_released(event) + } + } + + SearchIcon { + icon: root.trailing_icon; + color: root.color; + } + + if (root.avatar.width > 0 && root.avatar.height > 0) || root.avatar_background != #00000000 : VerticalLayout { + alignment: center; + + Avatar { + image: root.avatar; + background: root.avatar_background; + } + } + } + } + } + + popup := PopupWindow { + x: 0; + y: 0; + width: root.width; + height: root.height; + close_policy: close_on_click_outside; + + Rectangle { + width: root.width; + height: root.height; + background: MaterialPalette.surface_container_high; + border_radius: MaterialStyleMetrics.border_radius_28; + + HorizontalLayout { + padding: MaterialStyleMetrics.padding_4; + spacing: MaterialStyleMetrics.spacing_4; + + IconButton {} + + SearchTextInput { + placeholder: root.placeholder; + text: root.text; + + accepted => { + root.accepted(self.text); + } + + edited => { + root.edited(self.text); + } + + key_pressed(event) => { + root.key_pressed(event) + } + + key_released(event) => { + root.key_released(event) + } + } + + IconButton {} + } + } + } +} diff --git a/component-sets/material/ui/components/segmented_button.slint b/component-sets/material/ui/components/segmented_button.slint new file mode 100644 index 000000000..bd663574b --- /dev/null +++ b/component-sets/material/ui/components/segmented_button.slint @@ -0,0 +1,96 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { BaseButton } from "base_button.slint"; +import { Icons } from "../icons/icons.slint"; + +export struct SegmentedItem { + icon: image, + text: string +} + +component SegmentedItemTemplate { + in property icon; + in property text; + in property index; + in property selected; + in property last; + + callback clicked <=> base.clicked; + + accessible-role: list-item; + accessible-label: root.text; + accessible-item-selectable: true; + accessible-item-selected: root.selected; + accessible-item-index: root.index; + + if root.selected : Rectangle { + background: MaterialPalette.secondary_container; + } + + base := BaseButton { + min_layout_width: 0; + min_layout_height: 0; + color: MaterialPalette.on_surface; + vertical_padding: MaterialStyleMetrics.padding_10; + horizontal_padding: MaterialStyleMetrics.padding_24; + spacing: MaterialStyleMetrics.spacing_8; + icon: root.icon; + text: root.text; + } + + if !root.last : Rectangle { + x: parent.width - self.width; + width: 1px; + height: 100%; + background: MaterialPalette.outline; + } + + states [ + selected when root.selected : { + base.icon: Icons.check; + } + ] +} + +export component SegmentedButton { + in property <[SegmentedItem]> model; + in_out property current_item; + + min_width: max(2 * MaterialStyleMetrics.size_40, layout.min_width); + min_height: max(MaterialStyleMetrics.size_40, layout.min_height); + + accessible-role: list; + accessible-item-count: root.model.length; + + Rectangle { + clip: true; + border_width: 1px; + border_radius: self.height / 2; + border_color: MaterialPalette.outline; + + layout := HorizontalLayout { + for item[index] in root.model : SegmentedItemTemplate { + icon: item.icon; + text: item.text; + index: index; + last: index == root.model.length - 1; + selected: index == root.current_item; + + clicked => { + root.select(index); + } + } + } + } + + function select(index: int) { + if index < 0 || index >= root.model.length { + return; + } + + root.current_item = index; + } +} diff --git a/component-sets/material/ui/components/snack_bar.slint b/component-sets/material/ui/components/snack_bar.slint new file mode 100644 index 000000000..ac0ab6c7e --- /dev/null +++ b/component-sets/material/ui/components/snack_bar.slint @@ -0,0 +1,88 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { Typography } from "../styling/typography.slint"; +import { Elevation } from "elevation.slint"; +import { MaterialText } from "./material_text.slint"; +import { TextButton } from "./text_button.slint"; +import { IconButton } from "./icon_button.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { Icons } from "../icons/icons.slint"; +import { Animations } from "../styling/animations.slint"; + +export component SnackBar inherits PopupWindow { + in property text; + in property action_text; + in property has_close_button; + + close_policy: no_auto_close; + + callback action(); + + snack_bar := Elevation { + x: (parent.width - self.width) / 2; + y: parent.height - self.height; + width: MaterialStyleMetrics.size_344; + level: 3; + + background_layer := Rectangle { + background: MaterialPalette.inverse_surface; + border_radius: MaterialStyleMetrics.border_radius_4; + + HorizontalLayout { + padding_left: MaterialStyleMetrics.padding_16; + padding_right: self.padding_left; + padding_top: MaterialStyleMetrics.padding_10; + padding_bottom: self.padding_top; + spacing: MaterialStyleMetrics.spacing_4; + + MaterialText { + text: root.text; + vertical_alignment: center; + horizontal_alignment: left; + wrap: word_wrap; + style: Typography.body_medium; + color: MaterialPalette.inverse_on_surface; + } + + if root.action_text != "" : TextButton { + text: root.action_text; + inverse: true; + + clicked => { + root.raise_action(); + } + } + + if root.has_close_button : IconButton { + icon: Icons.close; + inverse: true; + + clicked => { + root.close(); + } + } + } + } + + animate y, height { + duration: Animations.standard_accelerate_duration; + easing: Animations.standard_easing; + } + } + + Timer { + interval: 50ms; + + triggered => { + snack_bar.y = root.height - snack_bar.height - MaterialStyleMetrics.padding_30; + self.running = false; + } + } + + function raise_action() { + root.action(); + root.close(); + } +} diff --git a/component-sets/material/ui/components/state_layer.slint b/component-sets/material/ui/components/state_layer.slint new file mode 100644 index 000000000..a8fc2c864 --- /dev/null +++ b/component-sets/material/ui/components/state_layer.slint @@ -0,0 +1,161 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Animations } from "../styling/animations.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { ToolTip } from "tooltip.slint"; + +export component Ripple { + in property border_radius; + in property pressed_x; + in property pressed_y; + in property color; + + Rectangle { + width: 100%; + height: 100%; + border_radius: root.border_radius; + clip: true; + + ripple := Rectangle { + x: root.pressed_x - self.width / 2; + y: root.pressed_y - self.height / 2; + height: self.width; + border_radius: self.width / 2; + opacity: MaterialPalette.state_layer_opacity_press; + background: root.color; + + init => { + self.width = root.width * 2 * 1.4142; + } + + animate width { duration: Animations.ripple_duration; easing: Animations.ripple_easing; } + } + } +} + +export component StateLayer { + in property background; + in property border_radius; + in property display_background: true; + in property enabled; + in property pressed; + in property has_focus; + in property has_hover; + + property state_layer_opacity; + + Rectangle { + width: 100%; + height: 100%; + opacity: root.state_layer_opacity; + background: root.background; + border_radius: root.border_radius; + } + + Rectangle { + width: 100%; + height: 100%; + clip: true; + border_radius: root.border_radius; + + @children + } + + states [ + disabled when !root.enabled && root.display_background : { + root.state_layer_opacity: MaterialPalette.state_layer_opacity_focus; + } + focus when root.enabled && root.has_focus : { + root.state_layer_opacity: MaterialPalette.state_layer_opacity_focus; + } + pressed when root.enabled && root.pressed : { + root.state_layer_opacity: MaterialPalette.state_layer_opacity_press; + } + hover when root.enabled && root.has_hover : { + root.state_layer_opacity: MaterialPalette.state_layer_opacity_hover; + } + ] + + animate state_layer_opacity { duration: Animations.opacity_duration; easing: Animations.opacity_easing; } +} + +export component StateLayerArea inherits TouchArea { + in property color; + in property border_radius; + in property transparent_background; + in property tooltip; + in property tooltip_offset; + in property display_background: true; + out property has_focus <=> focus_scope.has_focus; + out property enter_pressed; + + property popup_open; + property has_h: root.mouse-x > 0 && root.mouse-x < root.width && root.mouse-y > 0 && root.mouse-y < root.height; + + callback key_pressed(KeyEvent) -> EventResult; + + forward-focus: focus-scope; + + focus_scope := FocusScope { + x: 0; + width: 0px; + enabled: root.enabled; + + key_pressed(event) => { + if !root.enabled { + return reject; + } + + if (event.text == " " || event.text == "\n") && !root.enter_pressed { + root.enter_pressed = true; + root.clicked(); + return accept; + } + + root.key_pressed(event) + } + + key_released(event) => { + if !root.enabled { + return reject; + } + + if (event.text == " " || event.text == "\n") && root.enter_pressed { + root.enter_pressed = false; + return accept; + } + + reject + } + } + + if !root.enabled || (root.enabled && (root.has_focus || root.pressed || root.enter_pressed || root.has_hover)) : StateLayer { + width: 100%; + height: 100%; + background: root.transparent_background ? transparent : root.color; + border_radius: root.border_radius; + enabled: root.enabled; + pressed: root.pressed || root.enter_pressed; + has_focus: root.has_focus; + has_hover: root.has_hover; + display_background: root.display_background; + } + + // ripple + if root.enabled && (root.pressed || root.enter_pressed) : Ripple { + pressed_x: root.pressed_x; + pressed_y: root.pressed_y; + width: 100%; + height: 100%; + border_radius: root.border_radius; + color: root.color; + } + + @children + + if root.tooltip != "" && root.has-hover && !root.pressed : ToolTip { + y: root.tooltip_offset; + text: root.tooltip; + } +} diff --git a/component-sets/material/ui/components/tab_bar.slint b/component-sets/material/ui/components/tab_bar.slint new file mode 100644 index 000000000..1ada35d5d --- /dev/null +++ b/component-sets/material/ui/components/tab_bar.slint @@ -0,0 +1,205 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; +import { NavigationItem } from "../items/navigation_item.slint"; +import { BaseNavigationItemTemplate, BaseNavigation } from "./base_navigation.slint"; +import { StateLayerArea } from "./state_layer.slint"; +import { MaterialText } from "./material_text.slint"; +import { Typography } from "../styling/typography.slint"; +import { Animations } from "../styling/animations.slint"; +import { Icon } from "./icon.slint"; + +component TabItemTemplate inherits BaseNavigationItemTemplate { + out property label_width: label.width; + + property has_icon_selected: root.icon_selected.width > 0 || root.icon_selected.height > 0; + + StateLayerArea { + color: MaterialPalette.primary; + + VerticalLayout { + padding_top: MaterialStyleMetrics.padding_10; + padding_bottom: MaterialStyleMetrics.padding_8; + spacing: MaterialStyleMetrics.spacing_2; + + if root.icon.width > 0 && root.icon.height > 0 : HorizontalLayout { + alignment: center; + + Icon { + source: root.icon; + colorize: label.color; + + states [ + selected when root.selected && root.has_icon_selected : { + source: root.icon_selected; + } + ] + } + } + + HorizontalLayout { + alignment: center; + + label := MaterialText { + text: root.text; + style: Typography.title_small; + color: MaterialPalette.on_surface_variant; + } + } + } + + clicked => { + root.clicked(); + } + } + + states [ + selected when root.selected : { + label.color: MaterialPalette.primary; + } + ] +} + +component SecondaryTabItemTemplate inherits BaseNavigationItemTemplate { + property has_icon_selected: root.icon_selected.width > 0 || root.icon_selected.height > 0; + + StateLayerArea { + color: label.color; + + HorizontalLayout { + alignment: center; + spacing: MaterialStyleMetrics.spacing_8; + + if root.icon.width > 0 && root.icon.height > 0 : VerticalLayout { + alignment: center; + + Icon { + source: root.icon; + colorize: label.color; + + states [ + selected when root.selected && root.has_icon_selected : { + source: root.icon_selected; + } + ] + } + } + + + label := MaterialText { + text: root.text; + style: Typography.title_small; + color: MaterialPalette.on_surface_variant; + vertical_alignment: center; + } + } + + clicked => { + root.clicked(); + } + } + + states [ + selected when root.selected : { + label.color: MaterialPalette.on_surface; + } + ] +} + +export component TabBar inherits BaseNavigation { + property indicator_width; + property item_width: root.width / root.items.length; + property current_x: root.item_width * self.current_item; + + min_height: max(MaterialStyleMetrics.size_49, layout.min_height); + + Rectangle { + background: MaterialPalette.surface; + + layout := HorizontalLayout { + for item[index] in root.items : TabItemTemplate { + icon: item.icon; + icon_selected: item.icon_selected; + text: item.text; + index: index; + selected: index == root.current_item; + empty_badge: item.empty_badge; + badge: item.badge; + + clicked => { + root.select(index); + root.set_indicator_width(index, self.label_width); + } + + init => { + root.set_indicator_width(index, self.label_width); + } + } + } + + indicator := Rectangle { + x: root.current_x + (root.item_width - self.width) / 2; + y: parent.height - self.height; + width: root.indicator_width; + height: MaterialStyleMetrics.size_3; + border_top_left_radius: self.height / 2; + border_top_right_radius: self.border_top_left_radius; + background: MaterialPalette.primary; + + animate x, width { + duration: Animations.standard_accelerate_duration; + easing: Animations.standard_easing; + } + } + } + + function set_indicator_width(index: int, width: length) { + if index != root.current_item { + return; + } + + root.indicator_width = width; + } +} + +export component SecondaryTabBar inherits BaseNavigation { + property item_width: root.width / root.items.length; + property current_x: root.item_width * self.current_item; + + min_height: max(MaterialStyleMetrics.size_49, layout.min_height); + + Rectangle { + background: MaterialPalette.surface; + + layout := HorizontalLayout { + for item[index] in root.items : SecondaryTabItemTemplate { + icon: item.icon; + icon_selected: item.icon_selected; + text: item.text; + index: index; + selected: index == root.current_item; + empty_badge: item.empty_badge; + badge: item.badge; + + clicked => { + root.select(index); + } + } + } + + indicator := Rectangle { + x: root.current_x; + y: parent.height - self.height; + width: root.item_width; + height: MaterialStyleMetrics.size_2; + background: MaterialPalette.primary; + + animate x { + duration: Animations.standard_accelerate_duration; + easing: Animations.standard_easing; + } + } + } +} diff --git a/component-sets/material/ui/components/text_button.slint b/component-sets/material/ui/components/text_button.slint new file mode 100644 index 000000000..65cd0873c --- /dev/null +++ b/component-sets/material/ui/components/text_button.slint @@ -0,0 +1,33 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component TextButton { + in property icon <=> base.icon; + in property text <=> base.text; + in property enabled <=> base.enabled; + in property tooltip <=> base.tooltip; + in property inverse; + + callback clicked <=> base.clicked; + + accessible-role: button; + accessible-enabled: root.enabled; + accessible-label: root.text == "" ? root.tooltip : root.text; + accessible-action-default => { base.clicked(); } + + base := BaseButton { + border_radius: root.height / 2; + color: root.inverse ? MaterialPalette.inverse_primary : MaterialPalette.primary; + } + + states [ + disabled when !root.enabled : { + base.color: MaterialPalette.on_surface; + base.transparent_background: true; + } + ] +} diff --git a/component-sets/material/ui/components/tonal_button.slint b/component-sets/material/ui/components/tonal_button.slint new file mode 100644 index 000000000..125c5307e --- /dev/null +++ b/component-sets/material/ui/components/tonal_button.slint @@ -0,0 +1,44 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; + +export component TonalButton { + in property icon <=> base.icon; + in property text <=> base.text; + in property enabled <=> base.enabled; + in property tooltip <=> base.tooltip; + + callback clicked <=> base.clicked; + + accessible-role: button; + accessible-enabled: root.enabled; + accessible-label: root.text == "" ? root.tooltip : root.text; + accessible-action-default => { base.clicked(); } + + elevation := Elevation { + border_radius: root.height / 2; + background: MaterialPalette.secondary_container; + width: 100%; + height: 100%; + } + + base := BaseButton { + border_radius: elevation.border_radius; + color: MaterialPalette.on_secondary_container; + } + + states [ + disabled when !root.enabled : { + elevation.background: transparent; + elevation.level: 0; + base.color: MaterialPalette.on_surface; + } + hover when base.has_hover && !base.pressed && !base.enter_pressed : { + elevation.level: 2; + } + ] +} diff --git a/component-sets/material/ui/components/tonal_icon_button.slint b/component-sets/material/ui/components/tonal_icon_button.slint new file mode 100644 index 000000000..571dd9a7e --- /dev/null +++ b/component-sets/material/ui/components/tonal_icon_button.slint @@ -0,0 +1,63 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Elevation } from "./elevation.slint"; +import { BaseButton } from "./base_button.slint"; +import { Typography } from "../styling/typography.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component TonalIconButton { + in property icon; + in property icon_checked: root.icon; + in property checkable; + in_out property checked; + in property tooltip <=> base.tooltip; + in property enabled <=> base.enabled; + + callback clicked(); + + accessible-role: button; + accessible-enabled: true; + accessible-label: root.tooltip; + accessible-checkable: root.checkable; + accessible-checked: root.checked; + accessible-action-default => { base.clicked(); } + + background_layer := Rectangle { + width: 100%; + height: 100%; + border_radius: base.border_radius; + background: root.checkable ? MaterialPalette.surface_container_highest : MaterialPalette.secondary_container; + visible: root.enabled; + } + + base := BaseButton { + icon: root.checked ? root.icon_checked : root.icon; + border_radius: self.height / 2; + color: !root.enabled ? MaterialPalette.on_surface_variant : MaterialPalette.on_secondary_container; + horizontal_padding: 0; + vertical_padding: 0; + width: self.height; + icon_size: MaterialStyleMetrics.icon_size_56; + + clicked => { + root.toggle(); + root.clicked(); + } + } + + function toggle() { + if !root.checkable { + return; + } + + root.checked = !root.checked; + } + + states [ + checked when root.enabled && root.checked : { + background_layer.background: MaterialPalette.secondary_container; + } + ] +} diff --git a/component-sets/material/ui/components/tooltip.slint b/component-sets/material/ui/components/tooltip.slint new file mode 100644 index 000000000..3dd13c778 --- /dev/null +++ b/component-sets/material/ui/components/tooltip.slint @@ -0,0 +1,33 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialText } from "./material_text.slint"; +import { MaterialPalette } from "../styling/material_palette.slint"; +import { Typography } from "../styling/typography.slint"; + +export component ToolTip { + in property text; + + z: 10000; + + background_layer := Rectangle { + border_radius: 4px; + background: MaterialPalette.inverse_surface; + + layout := HorizontalLayout { + max_width: 200px; + padding_top: 4px; + padding_bottom: 4px; + padding_left: 8px; + padding_right: 8px; + + MaterialText { + text: root.text; + vertical_alignment: center; + color: MaterialPalette.inverse_on_surface; + style: Typography.body_small; + wrap: word-wrap; + } + } + } +} diff --git a/component-sets/material/ui/components/vertical.slint b/component-sets/material/ui/components/vertical.slint new file mode 100644 index 000000000..3665d26e8 --- /dev/null +++ b/component-sets/material/ui/components/vertical.slint @@ -0,0 +1,9 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; + +export component Vertical inherits VerticalLayout { + padding: MaterialStyleMetrics.padding_8; + spacing: MaterialStyleMetrics.spacing_8; +} diff --git a/component-sets/material/ui/icons/check.svg b/component-sets/material/ui/icons/check.svg new file mode 100644 index 000000000..e692194ba --- /dev/null +++ b/component-sets/material/ui/icons/check.svg @@ -0,0 +1 @@ + diff --git a/component-sets/material/ui/icons/close.svg b/component-sets/material/ui/icons/close.svg new file mode 100644 index 000000000..373c01abf --- /dev/null +++ b/component-sets/material/ui/icons/close.svg @@ -0,0 +1 @@ + diff --git a/component-sets/material/ui/icons/icons.slint b/component-sets/material/ui/icons/icons.slint new file mode 100644 index 000000000..cdcc2fe87 --- /dev/null +++ b/component-sets/material/ui/icons/icons.slint @@ -0,0 +1,8 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export global Icons { + out property check: @image-url("check.svg"); + out property close: @image-url("close.svg"); + out property menu: @image-url("menu.svg"); +} diff --git a/component-sets/material/ui/icons/menu.svg b/component-sets/material/ui/icons/menu.svg new file mode 100644 index 000000000..ae7c36cbf --- /dev/null +++ b/component-sets/material/ui/icons/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/component-sets/material/ui/index.slint b/component-sets/material/ui/index.slint new file mode 100644 index 000000000..47f3344a4 --- /dev/null +++ b/component-sets/material/ui/index.slint @@ -0,0 +1,53 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +// components +export { Badge } from "./components/badge.slint"; +export { BottomAppBar } from "./components/bottom_app_bar.slint"; +export { Dialog, FullscreenDialog } from "./components/dialog.slint"; +export { Drawer, ModalDrawer } from "./components/drawer.slint"; +export { VerticalDivider, HorizontalDivider } from "./components/divider.slint"; +export { ModalBottomSheet } from "./components/bottom_sheet.slint"; +export { ElevatedCard, FilledCard, OutlinedCard } from "./components/card.slint"; +export { ElevatedButton } from "./components/elevated_button.slint"; +export { Elevation } from "./components/elevation.slint"; +export { ExtendedTouchArea } from "./components/extended_touch_area.slint"; +export { FilledButton } from "./components/filled_button.slint"; +export { FilledIconButton } from "./components/filled_icon_button.slint"; +export { FloatingActionButton, FABStyle } from "./components/floating_action_button.slint"; +export { Grid } from "./components/grid.slint"; +export { Horizontal } from "./components/horizontal.slint"; +export { Icon } from "./components/icon.slint"; +export { IconButton } from "./components/icon_button.slint"; +export { OutlineButton } from "./components/outline_button.slint"; +export { OutlineIconButton } from "./components/outline_icon_button.slint"; +export { ListItemTemplate } from "./components/list.slint"; +export { ListView } from "./components/list_view.slint"; +export { MaterialText } from "./components/material_text.slint"; +export { MaterialWindow } from "./components/material_window.slint"; +export { NavigationBar } from "./components/navigation_bar.slint"; +export { NavigationDrawer, ModalNavigationDrawer } from "./components/navigation_drawer.slint"; +export { NavigationRail } from "./components/navigation_rail.slint"; +export { CircularProgressIndicator, LinearProgressIndicator } from "./components/progress_indicator.slint"; +export { SearchBar } from "./components/search_bar.slint"; +export { ScrollView } from "./components/scroll_view.slint"; +export { SnackBar } from "./components/snack_bar.slint"; +export { StateLayerArea, StateLayer, Ripple } from "./components/state_layer.slint"; +export { SegmentedButton } from "./components/segmented_button.slint"; +export { TabBar, SecondaryTabBar } from "./components/tab_bar.slint"; +export { TextButton } from "./components/text_button.slint"; +export { TonalButton } from "./components/tonal_button.slint"; +export { TonalIconButton } from "./components/tonal_icon_button.slint"; +export { ToolTip } from "./components/tooltip.slint"; +export { Vertical } from "./components/vertical.slint"; + +// items +export { ListItem } from "./items/list_item.slint"; +export { NavigationItem, NavigationGroup } from "./items/navigation_item.slint"; + +// styles +export { Animations } from "./styles/animations.slint"; +export { MaterialScheme, MaterialTheme } from "./styles/material_theme.slint"; +export { MaterialStyleMetrics } from "./styles/material_style_metrics.slint"; +export { MaterialPalette } from "./styles/material_palette.slint"; +export { Typography } from "./styles/typography.slint"; diff --git a/component-sets/material/ui/items/list_item.slint b/component-sets/material/ui/items/list_item.slint new file mode 100644 index 000000000..87d32e22a --- /dev/null +++ b/component-sets/material/ui/items/list_item.slint @@ -0,0 +1,10 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export struct ListItem { + text: string, + supporting_text: string, + avatar: image, + avatar_background: color, + avatar_colorize: color +} diff --git a/component-sets/material/ui/items/navigation_item.slint b/component-sets/material/ui/items/navigation_item.slint new file mode 100644 index 000000000..3758ec377 --- /dev/null +++ b/component-sets/material/ui/items/navigation_item.slint @@ -0,0 +1,15 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export struct NavigationItem { + icon: image, + icon_selected: image, + text: string, + empty_badge: bool, + badge: string +} + +export struct NavigationGroup { + title: string, + items: [NavigationItem] +} diff --git a/component-sets/material/ui/styling/animations.slint b/component-sets/material/ui/styling/animations.slint new file mode 100644 index 000000000..565d4330a --- /dev/null +++ b/component-sets/material/ui/styling/animations.slint @@ -0,0 +1,16 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export global Animations { + out property emphasized_easing: cubic-bezier(0.05, 0.7, 0.1, 1.0); + out property emphasized_duration: 500ms; + out property emphasized_decelerate_duration: 400ms; + out property emphasized_accelerate_duration: 200ms; + out property standard_easing: cubic-bezier(0, 0, 0, 1); + out property standard_decelerate_duration: 250ms; + out property standard_accelerate_duration: 200ms; + out property ripple_easing: ease_out; + out property ripple_duration: 2s; + out property opacity_easing: ease; + out property opacity_duration: 250ms; +} diff --git a/component-sets/material/ui/styling/material_palette.slint b/component-sets/material/ui/styling/material_palette.slint new file mode 100644 index 000000000..0b364d89d --- /dev/null +++ b/component-sets/material/ui/styling/material_palette.slint @@ -0,0 +1,171 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +import { Palette } from "std-widgets.slint"; +import { MaterialTheme, MaterialScheme } from "material_theme.slint"; + +export global MaterialPalette { + out property primary: root.scheme.primary; + out property surface_tint: root.scheme.surface_tint; + out property on_primary: root.scheme.on_primary; + out property primary_container: root.scheme.primary_container; + out property on_primary_container: root.scheme.on_primary_container; + out property secondary: root.scheme.secondary; + out property on_secondary: root.scheme.on_secondary; + out property secondary_container: root.scheme.secondary_container; + out property on_secondary_container: root.scheme.on_secondary_container; + out property tertiary: root.scheme.tertiary; + out property on_tertiary: root.scheme.on_tertiary; + out property tertiary_container: root.scheme.tertiary_container; + out property on_tertiary_container: root.scheme.on_tertiary_container; + out property error: root.scheme.error; + out property on_error: root.scheme.on_error; + out property error_container: root.scheme.error_container; + out property on_error_container: root.scheme.on_error_container; + out property background: root.scheme.background; + out property on_background: root.scheme.on_background; + out property surface: root.scheme.surface; + out property on_surface: root.scheme.on_surface; + out property surface_variant: root.scheme.surface_variant; + out property on_surface_variant: root.scheme.on_surface_variant; + out property outline: root.scheme.outline; + out property outline_variant: root.scheme.outline_variant; + out property shadow: root.scheme.shadow; + out property scrim: root.scheme.scrim; + out property inverse_surface: root.scheme.inverse_surface; + out property inverse_on_surface: root.scheme.inverse_on_surface; + out property inverse_primary: root.scheme.inverse_primary; + out property primary_fixed: root.scheme.primary_fixed; + out property on_primary_fixed: root.scheme.on_primary_fixed; + out property primary_fixed_dim: root.scheme.primary_fixed_dim; + out property on_primary_fixed_variant: root.scheme.on_primary_fixed_variant; + out property secondary_fixed: root.scheme.secondary_fixed; + out property on_secondary_fixed: root.scheme.on_secondary_fixed; + out property secondary_fixed_dim: root.scheme.secondary_fixed_dim; + out property on_secondary_fixed_variant: root.scheme.on_secondary_fixed_variant; + out property tertiary_fixed: root.scheme.tertiary_fixed; + out property on_tertiary_fixed: root.scheme.on_tertiary_fixed; + out property tertiary_fixed_dim: root.scheme.tertiary_fixed_dim; + out property on_tertiary_fixed_variant: root.scheme.on_tertiary_fixed_variant; + out property surface_dim: root.scheme.surface_dim; + out property surface_bright: root.scheme.surface_bright; + out property surface_container_lowest: root.scheme.surface_container_lowest; + out property surface_container_low: root.scheme.surface_container_low; + out property surface_container: root.scheme.surface_container; + out property surface_container_high: root.scheme.surface_container_high; + out property surface_container_highest: root.scheme.surface_container_highest; + out property shadow_15: #000000.with_alpha(15%); + out property shadow_30: #000000.with_alpha(30%); + out property state_layer_opacity_hover: 8%; + out property state_layer_opacity_focus: 10%; + out property state_layer_opacity_press: 10%; + out property state_layer_opacity_drag: 16%; + out property background_modal: #000000.with_alpha(50%); + + in property theme: { + light: { + primary: rgb(68, 94, 145), + surface-tint: rgb(68, 94, 145), + on-primary: rgb(255, 255, 255), + primary-container: rgb(216, 226, 255), + on-primary-container: rgb(0, 26, 66), + secondary: rgb(87, 94, 113), + on-secondary: rgb(255, 255, 255), + secondary-container: rgb(219, 226, 249), + on-secondary-container: rgb(20, 27, 44), + tertiary: rgb(113, 85, 115), + on-tertiary: rgb(255, 255, 255), + tertiary-container: rgb(252, 215, 251), + on-tertiary-container: rgb(41, 19, 45), + error: rgb(186, 26, 26), + on-error: rgb(255, 255, 255), + error-container: rgb(255, 218, 214), + on-error-container: rgb(65, 0, 2), + background: rgb(249, 249, 255), + on-background: rgb(26, 27, 32), + surface: rgb(249, 249, 255), + on-surface: rgb(26, 27, 32), + surface-variant: rgb(225, 226, 236), + on-surface-variant: rgb(68, 71, 79), + outline: rgb(117, 119, 127), + outline-variant: rgb(196, 198, 208), + shadow: rgb(0, 0, 0), + scrim: rgb(0, 0, 0), + inverse-surface: rgb(47, 48, 54), + inverse-on-surface: rgb(240, 240, 247), + inverse-primary: rgb(173, 198, 255), + primary-fixed: rgb(216, 226, 255), + on-primary-fixed: rgb(0, 26, 66), + primary-fixed-dim: rgb(173, 198, 255), + on-primary-fixed-variant: rgb(43, 70, 120), + secondary-fixed: rgb(219, 226, 249), + on-secondary-fixed: rgb(20, 27, 44), + secondary-fixed-dim: rgb(191, 198, 220), + on-secondary-fixed-variant: rgb(63, 71, 89), + tertiary-fixed: rgb(252, 215, 251), + on-tertiary-fixed: rgb(41, 19, 45), + tertiary-fixed-dim: rgb(222, 188, 223), + on-tertiary-fixed-variant: rgb(88, 62, 91), + surface-dim: rgb(217, 217, 224), + surface-bright: rgb(249, 249, 255), + surface-container-lowest: rgb(255, 255, 255), + surface-container-low: rgb(243, 243, 250), + surface-container: rgb(238, 237, 244), + surface-container-high: rgb(232, 231, 239), + surface-container-highest: rgb(226, 226, 233), + }, + dark: { + primary: rgb(173, 198, 255), + surface_tint: rgb(173, 198, 255), + on_primary: rgb(17, 47, 96), + primary_container: rgb(43, 70, 120), + on_primary_container: rgb(216, 226, 255), + secondary: rgb(191, 198, 220), + on_secondary: rgb(41, 48, 65), + secondary_container: rgb(63, 71, 89), + on_secondary_container: rgb(219, 226, 249), + tertiary: rgb(222, 188, 223), + on_tertiary: rgb(64, 40, 67), + tertiary_container: rgb(88, 62, 91), + on_tertiary_container: rgb(252, 215, 251), + error: rgb(255, 180, 171), + on_error: rgb(105, 0, 5), + error_container: rgb(147, 0, 10), + on_error_container: rgb(255, 218, 214), + background: rgb(17, 19, 24), + on_background: rgb(226, 226, 233), + surface: rgb(17, 19, 24), + on_surface: rgb(226, 226, 233), + surface_variant: rgb(68, 71, 79), + on_surface_variant: rgb(196, 198, 208), + outline: rgb(142, 144, 153), + outline_variant: rgb(68, 71, 79), + shadow: rgb(0, 0, 0), + scrim: rgb(0, 0, 0), + inverse_surface: rgb(226, 226, 233), + inverse_on_surface: rgb(47, 48, 54), + inverse_primary: rgb(68, 94, 145), + primary_fixed: rgb(216, 226, 255), + on_primary_fixed: rgb(0, 26, 66), + primary_fixed_dim: rgb(173, 198, 255), + on_primary_fixed_variant: rgb(43, 70, 120), + secondary_fixed: rgb(219, 226, 249), + on_secondary_fixed: rgb(20, 27, 44), + secondary_fixed_dim: rgb(191, 198, 220), + on_secondary_fixed_variant: rgb(63, 71, 89), + tertiary_fixed: rgb(252, 215, 251), + on_tertiary_fixed: rgb(41, 19, 45), + tertiary_fixed_dim: rgb(222, 188, 223), + on_tertiary_fixed_variant: rgb(88, 62, 91), + surface_dim: rgb(17, 19, 24), + surface_bright: rgb(55, 57, 62), + surface_container_lowest: rgb(12, 14, 19), + surface_container_low: rgb(26, 27, 32), + surface_container: rgb(30, 31, 37), + surface_container_high: rgb(40, 42, 47), + surface_container_highest: rgb(51, 53, 58), + }, + }; + + property scheme: Palette.color_scheme == ColorScheme.dark ? root.theme.dark : root.theme.light; +} diff --git a/component-sets/material/ui/styling/material_style_metrics.slint b/component-sets/material/ui/styling/material_style_metrics.slint new file mode 100644 index 000000000..ac700295a --- /dev/null +++ b/component-sets/material/ui/styling/material_style_metrics.slint @@ -0,0 +1,54 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export global MaterialStyleMetrics { + // sizes + out property size_2: 2px; + out property size_3: 3px; + out property size_4: 4px; + out property size_6: 6px; + out property size_16: 16px; + out property size_30: 30px; + out property size_32: 32px; + out property size_36: 36px; + out property size_40: 40px; + out property size_49: 49px; + out property size_56: 56px; + out property size_80: 80px; + out property size_90: 96px; + out property size_344: 344px; + out property size_360: 360px; + out property size_640: 640px; + + // icon + out property icon_size_40: 18px; + out property icon_size_56: 24px; + out property icon_size_90: 27px; + + // padding + out property padding_4: 4px; + out property padding_10: 10px; + out property padding_12: 12px; + out property padding_8: 8px; + out property padding_14: 14px; + out property padding_16: 16px; + out property padding_20: 20px; + out property padding_24: 24px; + out property padding_30: 30px; + out property padding_44: 44px; + out property padding_56: 56px; + + // spacing + out property spacing_2: 2px; + out property spacing_4: 4px; + out property spacing_8: 8px; + out property spacing_12: 12px; + out property spacing_16: 16px; + + // border_radius + out property border_radius_2: 2px; + out property border_radius_4: 4px; + out property border_radius_12: 12px; + out property border_radius_16: 16px; + out property border_radius_28: 28px; +} diff --git a/component-sets/material/ui/styling/material_theme.slint b/component-sets/material/ui/styling/material_theme.slint new file mode 100644 index 000000000..62a392dad --- /dev/null +++ b/component-sets/material/ui/styling/material_theme.slint @@ -0,0 +1,59 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export struct MaterialScheme { + primary: color, + surface_tint: color, + on_primary: color, + primary_container: color, + on_primary_container: color, + secondary: color, + on_secondary: color, + secondary_container: color, + on_secondary_container: color, + tertiary: color, + on_tertiary: color, + tertiary_container: color, + on_tertiary_container: color, + error: color, + on_error: color, + error_container: color, + on_error_container: color, + background: color, + on_background: color, + surface: color, + on_surface: color, + surface_variant: color, + on_surface_variant: color, + outline: color, + outline_variant: color, + shadow: color, + scrim: color, + inverse_surface: color, + inverse_on_surface: color, + inverse_primary: color, + primary_fixed: color, + on_primary_fixed: color, + primary_fixed_dim: color, + on_primary_fixed_variant: color, + secondary_fixed: color, + on_secondary_fixed: color, + secondary_fixed_dim: color, + on_secondary_fixed_variant: color, + tertiary_fixed: color, + on_tertiary_fixed: color, + tertiary_fixed_dim: color, + on_tertiary_fixed_variant: color, + surface_dim: color, + surface_bright: color, + surface_container_lowest: color, + surface_container_low: color, + surface_container: color, + surface_container_high: color, + surface_container_highest: color, +} + +export struct MaterialTheme { + light: MaterialScheme, + dark: MaterialScheme +} diff --git a/component-sets/material/ui/styling/typography.slint b/component-sets/material/ui/styling/typography.slint new file mode 100644 index 000000000..c9d6dd38c --- /dev/null +++ b/component-sets/material/ui/styling/typography.slint @@ -0,0 +1,93 @@ +// Copyright Β© SixtyFPS GmbH +// SPDX-License-Identifier: MIT + +export struct TextStyle { + font_size: length, + font_weight: int +} + +export global Typography { + out property regular: 300; + out property medium: 600; + out property semibold: 900; + + out property display_large: { + font_size: 57px, + font_weight: root.regular + }; + + out property display_medium: { + font_size: 45px, + font_weight: root.regular + }; + + out property display_small: { + font_size: 36px, + font_weight: root.regular + }; + + out property headline_large: { + font_size: 32px, + font_weight: root.regular + }; + + out property headline_medium: { + font_size: 28px, + font_weight: root.regular + }; + + out property headline_small: { + font_size: 24px, + font_weight: root.regular + }; + + out property title_large: { + font_size: 22px, + font_weight: root.regular + }; + + out property title_medium: { + font_size: 16px, + font_weight: root.medium + }; + + out property title_small: { + font_size: 14px, + font_weight: root.medium + }; + + out property label_large: { + font_size: 14px, + font_weight: root.medium + }; + + out property label_medium: { + font_size: 12px, + font_weight: root.medium + }; + + out property label_medium_prominent: { + font_size: 12px, + font_weight: root.semibold + }; + + out property label_small: { + font_size: 11px, + font_weight: root.medium + }; + + out property body_large: { + font_size: 16px, + font_weight: root.regular + }; + + out property body_medium: { + font_size: 14px, + font_weight: root.regular + }; + + out property body_small: { + font_size: 12px, + font_weight: root.regular + }; +}