diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef724674..ee59f369 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,33 +31,21 @@ jobs: - uses: dtolnay/rust-toolchain@stable - - name: Checkout ps-qa - uses: actions/checkout@v4 - with: - repository: pathscale/ps-qa - # Pin the reviewed sweep schema. The source branch may be deleted - # when its PR merges, but this release gate must remain reproducible. - ref: 08007a073164cf3f54214aee2471f2c6c3f939b1 - path: .qa/ps-qa - - - name: Checkout qa-inspect-host - uses: actions/checkout@v4 - with: - repository: pathscale/qa-inspect-host - # Pin the reviewed native text-input host for the same reason. - ref: b4212ef5cb73e5d2639b9b210672aa96e98cf9a3 - path: .qa/qa-inspect-host - - uses: Swatinem/rust-cache@v2 with: - workspaces: | - .qa/ps-qa - .qa/qa-inspect-host + # A UI assertion failing after native tool installation must not make + # the next corrective run rebuild the observability stack from zero. + cache-on-failure: true - - name: Build native QA tools + # Track the current ps-qa release so UI coverage cannot silently remain + # on an obsolete harness. Do not inherit a tool crate's packaged lockfile. + - name: Install native QA tools + env: + # cargo install otherwise builds in disposable temporary directories, + # which leaves rust-cache nothing useful to restore on the next run. + CARGO_TARGET_DIR: target/qa-tools run: | - cargo build --release --manifest-path .qa/ps-qa/Cargo.toml - cargo build --release --manifest-path .qa/qa-inspect-host/Cargo.toml + cargo install ps-qa qa-inspect-host - name: Install Dependencies run: bun install @@ -73,7 +61,7 @@ jobs: run: bun run check - name: Type Check - run: npx tsc --noEmit + run: bunx tsc --noEmit - name: Build run: bun run build @@ -83,8 +71,6 @@ jobs: # minutes while preserving a clean document between components. - name: Rendered component outcomes env: - QA_PS_QA: ${{ github.workspace }}/.qa/ps-qa/target/release/ps-qa - QA_HOST: ${{ github.workspace }}/.qa/qa-inspect-host/target/release/qa-inspect-host # GitHub's shared macOS runner took 1.6-1.9s for outcomes that pass # locally under 1.25s. This widens scheduling deadlines only; every # declared rendered-state transition is still required. @@ -94,7 +80,7 @@ jobs: bun run qa:entries git diff --exit-code -- tests/ps-qa tests/qa-harness/entries bun run qa:build - bash tests/qa-harness/run-all.sh + zsh tests/qa-harness/run-all.sh # Fails when docs/api-contract.md and the shipped types disagree, in # either direction. Never runs with --write: regenerating the document on diff --git a/bun.lock b/bun.lock deleted file mode 100644 index 606e4bcd..00000000 --- a/bun.lock +++ /dev/null @@ -1,728 +0,0 @@ -{ - "lockfileVersion": 1, - "configVersion": 0, - "workspaces": { - "": { - "name": "@pathscale/ui", - "dependencies": { - "@solidjs/web": "^2.0.0-rc.0", - "clsx": "^2.1.1", - "tailwind-merge": "^3.6.0", - }, - "devDependencies": { - "@babel/core": "^7.29.0", - "@biomejs/biome": "^2.4.16", - "@iconify/json": "^2.2.481", - "@iconify/utils": "^2.3.0", - "@pathscale/rsbuild-plugin-ui-css-purge": "^0.9.11", - "@rsbuild/core": "^2.0.9", - "@rsbuild/plugin-solid": "^1.2.1", - "@rslib/core": "^0.22.0", - "@solidjs/h": "^2.0.0-rc.0", - "@standard-schema/spec": "^1.1.0", - "@tailwindcss/postcss": "^4.3.3", - "@types/bun": "^1.3.14", - "babel-preset-solid": "^2.0.0-rc.0", - "cally": "^0.8.0", - "cssnano": "^7.1.9", - "popmotion": "^11.0.5", - "postcss": "^8.5.15", - "postcss-cli": "^11.0.1", - "postcss-selector-parser": "^7.1.1", - "rsbuild-plugin-solid-layouts": "^0.2.1", - "solid-js": "^2.0.0-rc.0", - "solid-layouts": "^0.2.1", - "solid-layouts-oxc": "^0.2.1", - "svgo": "^3.3.3", - "tailwindcss": "^4.3.3", - "typescript": "^6.0.3", - }, - "peerDependencies": { - "@standard-schema/spec": "^1.0.0", - "popmotion": "^11.0.5", - "solid-js": ">=2.0.0-rc.0", - "solid-layouts": "^0.2.0", - }, - "optionalPeers": [ - "@standard-schema/spec", - "popmotion", - ], - }, - }, - "overrides": { - "babel-preset-solid": "^2.0.0-rc.0", - }, - "packages": { - "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - - "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], - - "@antfu/utils": ["@antfu/utils@8.1.1", "", {}, "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ=="], - - "@ast-grep/napi": ["@ast-grep/napi@0.37.0", "", { "optionalDependencies": { "@ast-grep/napi-darwin-arm64": "0.37.0", "@ast-grep/napi-darwin-x64": "0.37.0", "@ast-grep/napi-linux-arm64-gnu": "0.37.0", "@ast-grep/napi-linux-arm64-musl": "0.37.0", "@ast-grep/napi-linux-x64-gnu": "0.37.0", "@ast-grep/napi-linux-x64-musl": "0.37.0", "@ast-grep/napi-win32-arm64-msvc": "0.37.0", "@ast-grep/napi-win32-ia32-msvc": "0.37.0", "@ast-grep/napi-win32-x64-msvc": "0.37.0" } }, "sha512-Hb4o6h1Pf6yRUAX07DR4JVY7dmQw+RVQMW5/m55GoiAT/VRoKCWBtIUPPOnqDVhbx1Cjfil9b6EDrgJsUAujEQ=="], - - "@ast-grep/napi-darwin-arm64": ["@ast-grep/napi-darwin-arm64@0.37.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QAiIiaAbLvMEg/yBbyKn+p1gX2/FuaC0SMf7D7capm/oG4xGMzdeaQIcSosF4TCxxV+hIH4Bz9e4/u7w6Bnk3Q=="], - - "@ast-grep/napi-darwin-x64": ["@ast-grep/napi-darwin-x64@0.37.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-zvcvdgekd4ySV3zUbUp8HF5nk5zqwiMXTuVzTUdl/w08O7JjM6XPOIVT+d2o/MqwM9rsXdzdergY5oY2RdhSPA=="], - - "@ast-grep/napi-linux-arm64-gnu": ["@ast-grep/napi-linux-arm64-gnu@0.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-L7Sj0lXy8X+BqSMgr1LB8cCoWk0rericdeu+dC8/c8zpsav5Oo2IQKY1PmiZ7H8IHoFBbURLf8iklY9wsD+cyA=="], - - "@ast-grep/napi-linux-arm64-musl": ["@ast-grep/napi-linux-arm64-musl@0.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-LF9sAvYy6es/OdyJDO3RwkX3I82Vkfsng1sqUBcoWC1jVb1wX5YVzHtpQox9JrEhGl+bNp7FYxB4Qba9OdA5GA=="], - - "@ast-grep/napi-linux-x64-gnu": ["@ast-grep/napi-linux-x64-gnu@0.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-TViz5/klqre6aSmJzswEIjApnGjJzstG/SE8VDWsrftMBMYt2PTu3MeluZVwzSqDao8doT/P+6U11dU05UOgxw=="], - - "@ast-grep/napi-linux-x64-musl": ["@ast-grep/napi-linux-x64-musl@0.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-/BcCH33S9E3ovOAEoxYngUNXgb+JLg991sdyiNP2bSoYd30a9RHrG7CYwW6fMgua3ijQ474eV6cq9yZO1bCpXg=="], - - "@ast-grep/napi-win32-arm64-msvc": ["@ast-grep/napi-win32-arm64-msvc@0.37.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-TjQA4cFoIEW2bgjLkaL9yqT4XWuuLa5MCNd0VCDhGRDMNQ9+rhwi9eLOWRaap3xzT7g+nlbcEHL3AkVCD2+b3A=="], - - "@ast-grep/napi-win32-ia32-msvc": ["@ast-grep/napi-win32-ia32-msvc@0.37.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-uNmVka8fJCdYsyOlF9aZqQMLTatEYBynjChVTzUfFMDfmZ0bihs/YTqJVbkSm8TZM7CUX82apvn50z/dX5iWRA=="], - - "@ast-grep/napi-win32-x64-msvc": ["@ast-grep/napi-win32-x64-msvc@0.37.0", "", { "os": "win32", "cpu": "x64" }, "sha512-vCiFOT3hSCQuHHfZ933GAwnPzmL0G04JxQEsBRfqONywyT8bSdDc/ECpAfr3S9VcS4JZ9/F6tkePKW/Om2Dq2g=="], - - "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], - - "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], - - "@babel/core": ["@babel/core@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-module-transforms": "^7.29.7", "@babel/helpers": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA=="], - - "@babel/generator": ["@babel/generator@7.29.7", "", { "dependencies": { "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ=="], - - "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" } }, "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw=="], - - "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.29.7", "", { "dependencies": { "@babel/compat-data": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g=="], - - "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-member-expression-to-functions": "^7.29.7", "@babel/helper-optimise-call-expression": "^7.29.7", "@babel/helper-replace-supers": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/traverse": "^7.29.7", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg=="], - - "@babel/helper-globals": ["@babel/helper-globals@7.29.7", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="], - - "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg=="], - - "@babel/helper-module-imports": ["@babel/helper-module-imports@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="], - - "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg=="], - - "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" } }, "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong=="], - - "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.29.7", "", {}, "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw=="], - - "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.29.7", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.29.7", "@babel/helper-optimise-call-expression": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ=="], - - "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ=="], - - "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], - - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], - - "@babel/helper-validator-option": ["@babel/helper-validator-option@7.29.7", "", {}, "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw=="], - - "@babel/helpers": ["@babel/helpers@7.29.7", "", { "dependencies": { "@babel/template": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg=="], - - "@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="], - - "@babel/plugin-proposal-decorators": ["@babel/plugin-proposal-decorators@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/plugin-syntax-decorators": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg=="], - - "@babel/plugin-syntax-decorators": ["@babel/plugin-syntax-decorators@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg=="], - - "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A=="], - - "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA=="], - - "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA=="], - - "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.29.7", "", { "dependencies": { "@babel/helper-module-transforms": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ=="], - - "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/plugin-syntax-typescript": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw=="], - - "@babel/preset-typescript": ["@babel/preset-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "@babel/plugin-syntax-jsx": "^7.29.7", "@babel/plugin-transform-modules-commonjs": "^7.29.7", "@babel/plugin-transform-typescript": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ=="], - - "@babel/template": ["@babel/template@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg=="], - - "@babel/traverse": ["@babel/traverse@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", "@babel/helper-globals": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", "@babel/types": "^7.29.7", "debug": "^4.3.1" } }, "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw=="], - - "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], - - "@biomejs/biome": ["@biomejs/biome@2.4.16", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.16", "@biomejs/cli-darwin-x64": "2.4.16", "@biomejs/cli-linux-arm64": "2.4.16", "@biomejs/cli-linux-arm64-musl": "2.4.16", "@biomejs/cli-linux-x64": "2.4.16", "@biomejs/cli-linux-x64-musl": "2.4.16", "@biomejs/cli-win32-arm64": "2.4.16", "@biomejs/cli-win32-x64": "2.4.16" }, "bin": { "biome": "bin/biome" } }, "sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA=="], - - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wxPvu4XOA85YJk9ixSWUmq/QBHbid85BISbOAqqBM/5xQpPk9ayjk5375tOlSC0BeCwNSbPFafQBm+vBumXq0A=="], - - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-xFCqGPwYusQJp4N4NJLi1XJiZqjwFdjhT+KqtNy+Ug3qgfczqnTa6MSDvxJF6TkuDLoYJItMapz6tAf7kCekFw=="], - - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-2kFb4//jxfZaP6D+Rj5VkHkxgyD9EoRAVBEQb8PKRv+s4NO2zYNJKXFaJmK1CmhufJOWEfpHKaRbOja7qjmdhQ=="], - - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-oYxnW0ARfJkr72ezzF2OR8N/rtkgLUQeYtF8cFhVswbknHxtTcmzSsanVJP8yQKnGpGpc2ck6c5zLvHahL6Cbg=="], - - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.16", "", { "os": "linux", "cpu": "x64" }, "sha512-NbcBbi/nJqn5baae6wqRXdS7Gadf2uRpehSh6vMSYpG8OhkXl/Xg8aorWrJ+9VWqAT5ml90alLvorkpMW0nBwQ=="], - - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.16", "", { "os": "linux", "cpu": "x64" }, "sha512-iHDS+MCM65DPqWGu+ECC3uoALyj2H7F4nVUPxIPjz/PIl94EUu+EDfGZDzFP+NY1EOPVt9NQvwFqq7HdMmowdg=="], - - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-0rgImMsNb5v/chhkIFe3wu7PEFClS6RBAYUijGL9UsYN3PanSaoK24HSSuSJb1pYbYYVjzAyZTl3gtjJ84BM8A=="], - - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.16", "", { "os": "win32", "cpu": "x64" }, "sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw=="], - - "@colordx/core": ["@colordx/core@5.4.3", "", {}, "sha512-kIxYSfA5T8HXjav55UaaH/o/cKivF6jCCGIb8eqtcsfI46wsvlSiT8jMDyrl779qLec3c2c2oHBZo4oAhvbjrQ=="], - - "@dom-expressions/babel-plugin-jsx": ["@dom-expressions/babel-plugin-jsx@0.50.0-next.42", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2", "validate-html-nesting": "^1.2.1" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-ol24x9RW8loPyOTzC/mQzh/zAsrsPxyTG4WRxxRlwzNK2uBWIBftWN5IwmSV51zDQa7JcT6sE6kkXFCLUvsYIQ=="], - - "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], - - "@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], - - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], - - "@iconify/json": ["@iconify/json@2.2.481", "", { "dependencies": { "@iconify/types": "*", "pathe": "^2.0.3" } }, "sha512-H/bCPJN+JawFnEgSFtBGQMz2nAc3KNsLZ6fKG6KfJX7X9H0blv0Acbt6umCBVRxZ0xBM/9FcUYZst4/Zv6SB/A=="], - - "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], - - "@iconify/utils": ["@iconify/utils@2.3.0", "", { "dependencies": { "@antfu/install-pkg": "^1.0.0", "@antfu/utils": "^8.1.0", "@iconify/types": "^2.0.0", "debug": "^4.4.0", "globals": "^15.14.0", "kolorist": "^1.8.0", "local-pkg": "^1.0.0", "mlly": "^1.7.4" } }, "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA=="], - - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], - - "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], - - "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], - - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - - "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], - - "@module-federation/error-codes": ["@module-federation/error-codes@0.22.0", "", {}, "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug=="], - - "@module-federation/runtime": ["@module-federation/runtime@0.22.0", "", { "dependencies": { "@module-federation/error-codes": "0.22.0", "@module-federation/runtime-core": "0.22.0", "@module-federation/sdk": "0.22.0" } }, "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA=="], - - "@module-federation/runtime-core": ["@module-federation/runtime-core@0.22.0", "", { "dependencies": { "@module-federation/error-codes": "0.22.0", "@module-federation/sdk": "0.22.0" } }, "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA=="], - - "@module-federation/runtime-tools": ["@module-federation/runtime-tools@0.22.0", "", { "dependencies": { "@module-federation/runtime": "0.22.0", "@module-federation/webpack-bundler-runtime": "0.22.0" } }, "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA=="], - - "@module-federation/sdk": ["@module-federation/sdk@0.22.0", "", {}, "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g=="], - - "@module-federation/webpack-bundler-runtime": ["@module-federation/webpack-bundler-runtime@0.22.0", "", { "dependencies": { "@module-federation/runtime": "0.22.0", "@module-federation/sdk": "0.22.0" } }, "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA=="], - - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], - - "@pathscale/rsbuild-plugin-ui-css-purge": ["@pathscale/rsbuild-plugin-ui-css-purge@0.9.11", "", { "dependencies": { "@swc/core": "^1.15.40", "lightningcss": "^1.32.0", "postcss": "^8.5.15" }, "bin": { "rsbuild-plugin-ui-css-purge": "dist/postbuild-purge.js", "generate-manifest": "src/generate-manifest.ts" } }, "sha512-iIyScjlJ1/yfbtD+vPWQP+S5WSQp6tBtppDAMGImBPCxzoSnpQPwhvsyFGpNyVwGUZj/8QxhbpY34ev0FXKpng=="], - - "@rsbuild/core": ["@rsbuild/core@2.0.9", "", { "dependencies": { "@rspack/core": "~2.0.5", "@swc/helpers": "^0.5.23" }, "peerDependencies": { "core-js": ">= 3.0.0" }, "optionalPeers": ["core-js"], "bin": { "rsbuild": "./bin/rsbuild.js" } }, "sha512-lK2bMNuwh3TuLXLskS7nG3fnQk+6eaLeeZiquJWcna4JZx9iaI59JSd+iLcg5TeZLjEVygkwn/HcE+yuYDQRAw=="], - - "@rsbuild/plugin-babel": ["@rsbuild/plugin-babel@1.2.1", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-proposal-decorators": "^7.29.0", "@babel/plugin-transform-class-properties": "^7.29.7", "@babel/preset-typescript": "^7.29.7", "@types/babel__core": "^7.20.5", "reduce-configs": "^1.1.2" }, "peerDependencies": { "@rsbuild/core": "^1.0.0 || ^2.0.0-0" }, "optionalPeers": ["@rsbuild/core"] }, "sha512-6Zad7Ff/RUNc91AtftemJcJ1wcZRGOiwuJy349qlLJl9F++oRYwUhx+MxLSpNnVeIywWx2mKdZZBtD1hLqfj9w=="], - - "@rsbuild/plugin-solid": ["@rsbuild/plugin-solid@1.2.1", "", { "dependencies": { "@rsbuild/plugin-babel": "1.2.1", "babel-preset-solid": "^1.9.12", "solid-refresh": "^0.7.8" }, "peerDependencies": { "@rsbuild/core": "^1.0.0 || ^2.0.0-0" }, "optionalPeers": ["@rsbuild/core"] }, "sha512-jL1EflslIdwt9J0brMxE4TouH+oEdAzCLwxt53+0RzdhDU3uDbdCc2jBu0+4RW57h/ITcumxNEUidBROqzpCMw=="], - - "@rslib/core": ["@rslib/core@0.22.0", "", { "dependencies": { "@rsbuild/core": "~2.0.8", "rsbuild-plugin-dts": "0.22.0" }, "peerDependencies": { "@microsoft/api-extractor": "^7", "typescript": "^5 || ^6" }, "optionalPeers": ["@microsoft/api-extractor", "typescript"], "bin": { "rslib": "./bin/rslib.js" } }, "sha512-DGTMBDTSdILac0SmeBWvdYf/ZDn09vXgbJQ3/N1J7i6vBpFGWCCKjARoz1R5jYqr1Z9tLJ1OfOVZktbNY/XXuA=="], - - "@rspack/binding": ["@rspack/binding@2.0.5", "", { "optionalDependencies": { "@rspack/binding-darwin-arm64": "2.0.5", "@rspack/binding-darwin-x64": "2.0.5", "@rspack/binding-linux-arm64-gnu": "2.0.5", "@rspack/binding-linux-arm64-musl": "2.0.5", "@rspack/binding-linux-x64-gnu": "2.0.5", "@rspack/binding-linux-x64-musl": "2.0.5", "@rspack/binding-wasm32-wasi": "2.0.5", "@rspack/binding-win32-arm64-msvc": "2.0.5", "@rspack/binding-win32-ia32-msvc": "2.0.5", "@rspack/binding-win32-x64-msvc": "2.0.5" } }, "sha512-Ta1y4WXJA87wM1OstqaMddoPsBGv7Cu779bYToKxEAqR/Yy9DxLkp7bdgBaAx2JH++BwVjV+toWts2V9AaiTFQ=="], - - "@rspack/binding-darwin-arm64": ["@rspack/binding-darwin-arm64@2.0.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-++wjLQjQ20GcR0DwbzQmVXg9qy4XCX5NlfSzkzj2icHoDxr3KkrXhyVrQkdWuNG6l/bQrGLPnvLEAqkroC2Y7A=="], - - "@rspack/binding-darwin-x64": ["@rspack/binding-darwin-x64@2.0.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-JBD5mCN3JKjV64Mh9nDYx8lLUrWDfEl5tLBuMkREUnqEKbo+z4nfwotyqHHM8/XgZwL+Gr7ps4GLWuQQrZB8+Q=="], - - "@rspack/binding-linux-arm64-gnu": ["@rspack/binding-linux-arm64-gnu@2.0.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-JI8+//woanJPNsfL7iGjX39zyiWumnrKHznWQM/7lEtE5nPmk+j+X7TYXxczSWC9zfZegiqI74D3L5JPDC84Fw=="], - - "@rspack/binding-linux-arm64-musl": ["@rspack/binding-linux-arm64-musl@2.0.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-5LujilxLtJFRiiPz5i5iWcWJriK9oy4gN7gZtTo8YRB7wwmwA8LMypTjjO0GLbkPS4/KeCfY4fDfTC29KmK+tA=="], - - "@rspack/binding-linux-x64-gnu": ["@rspack/binding-linux-x64-gnu@2.0.5", "", { "os": "linux", "cpu": "x64" }, "sha512-241wqE132jh+/U/pn97qUPV4KpIy4bSrTH0tqfzQCocgw+8hrUj02GqNG+3MXVC3qtwaQeJFYgEBy3TqFKsrIQ=="], - - "@rspack/binding-linux-x64-musl": ["@rspack/binding-linux-x64-musl@2.0.5", "", { "os": "linux", "cpu": "x64" }, "sha512-BhaXZD064Lci3Kia0kLDAb4TyxO2C+0UidMlj44e8+ctasxIfFZgnrhCJrhTFHAtOiAwqhU3FHun2UuxPqX0Eg=="], - - "@rspack/binding-wasm32-wasi": ["@rspack/binding-wasm32-wasi@2.0.5", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "1.1.4" }, "cpu": "none" }, "sha512-duEkRoXrl9SW8uGHv7JURJ5lgKu87qFDQ4Exy6UQPvsUJVXhtRXTfvMHCb/CejVJuW2Bw2D632/axZq3qRSuBQ=="], - - "@rspack/binding-win32-arm64-msvc": ["@rspack/binding-win32-arm64-msvc@2.0.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-q2WT3HFoWL+2g84l3s2kY7CiE1gEZ1bwB3txx3eZzQQ6YKP7bE82z6sl6S/pTOHGjHdAO4snQXpSaHwUt3LX5g=="], - - "@rspack/binding-win32-ia32-msvc": ["@rspack/binding-win32-ia32-msvc@2.0.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-nMJGIY7kvgbyMolEE7tXDe+Z9jSItDshTIqMQQkkD3WTHdjlBQozHxk4kBtKLsunO+3NkCLe5Oa3hXg1yyStIg=="], - - "@rspack/binding-win32-x64-msvc": ["@rspack/binding-win32-x64-msvc@2.0.5", "", { "os": "win32", "cpu": "x64" }, "sha512-vP0BR6fxdPL9cb02HAuZATg/CjR07aecWel3s1vqRwW1aDffgXh9PVmqEKIHTgyaNsNR55kSKNJsB9AcQ8/QrA=="], - - "@rspack/core": ["@rspack/core@2.0.5", "", { "dependencies": { "@rspack/binding": "2.0.5" }, "peerDependencies": { "@module-federation/runtime-tools": "^0.24.1 || ^2.0.0", "@swc/helpers": "^0.5.23" }, "optionalPeers": ["@module-federation/runtime-tools", "@swc/helpers"] }, "sha512-9tv2HAnSiTote5WPH2tmz1hLZ1zKbzkiZc1eYp7LP/8jcsiJBuf40ihiWidAgbbuYtJo3kWET6q+qOm5UhNiGA=="], - - "@solidjs/h": ["@solidjs/h@2.0.0-rc.0", "", { "peerDependencies": { "@solidjs/web": "^2.0.0-rc.0" } }, "sha512-APPxIiLi7E0JME1RDkwvkwhjgk5PB6wg81aZ8lqGxb+ljqLgTogCK30E9K3BHJTk/qnWGlvOHbVvmgGf3s2fZQ=="], - - "@solidjs/signals": ["@solidjs/signals@2.0.0-rc.0", "", {}, "sha512-oKZSfvsCcKw1uJjOGbUkJ+OqlhXLHtZ+rShSyu9KH0lUH7UUwfMfsKeh81JPiQxDDg4YLhEwI38hg0JkwzTdvA=="], - - "@solidjs/web": ["@solidjs/web@2.0.0-rc.0", "", { "dependencies": { "seroval": "~1.5.4", "seroval-plugins": "~1.5.4" }, "peerDependencies": { "solid-js": "^2.0.0-rc.0" } }, "sha512-pYSaA9+dH8H1h/d/ZF/P2kR6omfzFGNcdzKhWTcg9fJghXhn8+5UrXUr2iYxDdYNOXZzxxFQhYHSJ7P4HKDqgw=="], - - "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@swc/core": ["@swc/core@1.15.40", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.26" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.40", "@swc/core-darwin-x64": "1.15.40", "@swc/core-linux-arm-gnueabihf": "1.15.40", "@swc/core-linux-arm64-gnu": "1.15.40", "@swc/core-linux-arm64-musl": "1.15.40", "@swc/core-linux-ppc64-gnu": "1.15.40", "@swc/core-linux-s390x-gnu": "1.15.40", "@swc/core-linux-x64-gnu": "1.15.40", "@swc/core-linux-x64-musl": "1.15.40", "@swc/core-win32-arm64-msvc": "1.15.40", "@swc/core-win32-ia32-msvc": "1.15.40", "@swc/core-win32-x64-msvc": "1.15.40" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-2kwzJikRvgtNAG7MwVZY2vEzZjTxKIq5jXOihuSV/8U+Hej8Va22t65aKnJZs3P+NwojZvR8Mf8kyM7O+V8sQg=="], - - "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.40", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PaYyclfmQ++77D8ityYvmmVzHv9aG8ROwt2GfG6/ccloy4Hgf80qtOnzb9VYvPsUT7Ty1uhuDRhv3XYpf62qhQ=="], - - "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.40", "", { "os": "darwin", "cpu": "x64" }, "sha512-HbbPzvfLBUXjIB1Ezks+//lNUjmLjfyd63XSwprJgrZaXYdm70kohXPJUWdqKZozolFxbPaO+xtBaiUp6BoueA=="], - - "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.40", "", { "os": "linux", "cpu": "arm" }, "sha512-SlRZsCjOCPR2LvFs0Ri/Xrx/5o5TCt8vl4gW6mX1hEZOG0a625RxzRHpHdAQNGykmAN/7IeaFAJG+QnNmxlHcA=="], - - "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-Q8byxJt2fh8CR3EUX6snBpy47AoBVm+In/+Z3rjDHMjC38ZvR9/gtUUNCT0tfrn4EdVsO8/QPi59nxrxvqxvBQ=="], - - "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-4z0MgHU+7M0pZDqBN1El7mFXDI1SBwinfcUkAyA4v8QrhOIUOZltySt2aStQLZGrdXVXM4Y4ylfiTC04ED+MoQ=="], - - "@swc/core-linux-ppc64-gnu": ["@swc/core-linux-ppc64-gnu@1.15.40", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fLI4iUgeSZu0eRWUXwe6YzPFx9gHbFiPkl8Rp3mJfP8OpNR3nTQCGPvHdDh9xniW7mVvgMY4ni7A4VzqI1KrpA=="], - - "@swc/core-linux-s390x-gnu": ["@swc/core-linux-s390x-gnu@1.15.40", "", { "os": "linux", "cpu": "s390x" }, "sha512-YqeKMAb7d4nQSGMJQ454IlaCENpzcDqhvBE9+CPfdnYpnUXxd+BSrB6Xk0YjW8UyoEhUj4p6quATCxbsp6J3jg=="], - - "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-7HOuS1iGcme/j/TuL1TfmmLGiMQrjv/GmjyZeydl00FKPtpGXEldwqfI56xgd1YzrzoB2svWjxbGGyQ0TEASxg=="], - - "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-h4kZYHc7dpc9P9u4brRJaS8Pl7tPVHAeiLSzw7T5RfIJgAoSdaCMKzI/2Uay9gFhaw8uyCDl0L5q37r0EpAfIA=="], - - "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.40", "", { "os": "win32", "cpu": "arm64" }, "sha512-+mQgKZXSj6mV38Zh05QaxSjUDmGP/R2JWlXZTDLSPkDzHU6p3GxN9eeSf5dfyDVU86946fmCvSzyl/ucImx8+A=="], - - "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.40", "", { "os": "win32", "cpu": "ia32" }, "sha512-yvwdPLGd25mcj/mNatjNQ0lZujtQD6psH3v9PNmMb+fSzjbNG8KIDxjFWrcV+fsFVLOkyOmdJsFmX7NAFjVyPw=="], - - "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.40", "", { "os": "win32", "cpu": "x64" }, "sha512-OXtKsLU1bVtInzzDEAY2sYiF/rl4tvAnLLLpuMp3HzAOQZ5A+i69AKDhA1YLQTaMAqO3vzyYNVAYVRMPtSYD4w=="], - - "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], - - "@swc/helpers": ["@swc/helpers@0.5.23", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw=="], - - "@swc/types": ["@swc/types@0.1.26", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw=="], - - "@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="], - - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.3", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="], - - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.3", "", { "os": "android", "cpu": "arm64" }, "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw=="], - - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw=="], - - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw=="], - - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw=="], - - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ=="], - - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w=="], - - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA=="], - - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w=="], - - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img=="], - - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.3", "", { "dependencies": { "@emnapi/core": "^1.11.1", "@emnapi/runtime": "^1.11.1", "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ=="], - - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ=="], - - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw=="], - - "@tailwindcss/postcss": ["@tailwindcss/postcss@4.3.3", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "postcss": "^8.5.16", "tailwindcss": "4.3.3" } }, "sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg=="], - - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], - - "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], - - "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], - - "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], - - "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], - - "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], - - "@types/node": ["@types/node@25.9.1", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg=="], - - "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], - - "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - - "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], - - "atomico": ["atomico@1.79.2", "", {}, "sha512-mshhLRMeIltNYbnQnqgnrvJ/uDa8XDfTQcjw3ymOygQqwHIQ4Sp0LcNYMCbACkV3DtV+eDXb9szwU4qMUuGwYQ=="], - - "babel-preset-solid": ["babel-preset-solid@2.0.0-rc.0", "", { "dependencies": { "@dom-expressions/babel-plugin-jsx": "0.50.0-next.42" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^2.0.0-rc.0" }, "optionalPeers": ["solid-js"] }, "sha512-Ap2/QQY3pICj+Q0VM/RnIOpZo7e6icZnUA0oBJuhqzoCrljqMNo3eFb2OeEa4pUQeFREJOlex4Bt1ggwrcgC8w=="], - - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.33", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw=="], - - "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], - - "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], - - "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - - "browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="], - - "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], - - "cally": ["cally@0.8.0", "", { "dependencies": { "atomico": "^1.76.1" } }, "sha512-jvQ2QMrsZM/ZPG/LWTkJEUPrp/ew1uS2KjKA/E6ru7mVvTMY2JgSagci9IghLmuamFh1pDajrxXAX4Qgo4FHbw=="], - - "caniuse-api": ["caniuse-api@3.0.0", "", { "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="], - - "caniuse-lite": ["caniuse-lite@1.0.30001793", "", {}, "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA=="], - - "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], - - "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], - - "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], - - "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], - - "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], - - "commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], - - "confbox": ["confbox@0.2.4", "", {}, "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ=="], - - "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - - "css-declaration-sorter": ["css-declaration-sorter@7.4.0", "", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw=="], - - "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], - - "css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="], - - "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], - - "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], - - "cssnano": ["cssnano@7.1.9", "", { "dependencies": { "cssnano-preset-default": "^7.0.17", "lilconfig": "^3.1.3" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-uPR75+5Dk/WJ/YSPR1/YDHdwMM9c5FsaARljfKWgeCKLKOtJ0we21xy/RcCjn53fZnD/f6yYEIZ8pu18+GnbNQ=="], - - "cssnano-preset-default": ["cssnano-preset-default@7.0.17", "", { "dependencies": { "browserslist": "^4.28.2", "css-declaration-sorter": "^7.2.0", "cssnano-utils": "^5.0.3", "postcss-calc": "^10.1.1", "postcss-colormin": "^7.0.10", "postcss-convert-values": "^7.0.12", "postcss-discard-comments": "^7.0.8", "postcss-discard-duplicates": "^7.0.4", "postcss-discard-empty": "^7.0.3", "postcss-discard-overridden": "^7.0.3", "postcss-merge-longhand": "^7.0.7", "postcss-merge-rules": "^7.0.11", "postcss-minify-font-values": "^7.0.3", "postcss-minify-gradients": "^7.0.5", "postcss-minify-params": "^7.0.9", "postcss-minify-selectors": "^7.1.2", "postcss-normalize-charset": "^7.0.3", "postcss-normalize-display-values": "^7.0.3", "postcss-normalize-positions": "^7.0.4", "postcss-normalize-repeat-style": "^7.0.4", "postcss-normalize-string": "^7.0.3", "postcss-normalize-timing-functions": "^7.0.3", "postcss-normalize-unicode": "^7.0.9", "postcss-normalize-url": "^7.0.3", "postcss-normalize-whitespace": "^7.0.3", "postcss-ordered-values": "^7.0.4", "postcss-reduce-initial": "^7.0.9", "postcss-reduce-transforms": "^7.0.3", "postcss-svgo": "^7.1.3", "postcss-unique-selectors": "^7.0.7" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-11qO63A+czwguQFJCaTdICvbaxn0pJzz/XghLlv+OT7WyToDxAMR0Xb3/26/l0y0hQJywwNbj/SLSQlGBHE1OA=="], - - "cssnano-utils": ["cssnano-utils@5.0.3", "", { "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-ynIREMICLxkxm7e9bCR9sh75s4Q5drICi0ua1yxo5jH2XPBqSKkl4dOh4EbFqtUmnTMhRffHgYL0EKKkMjtJTg=="], - - "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], - - "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - - "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - - "dependency-graph": ["dependency-graph@1.0.0", "", {}, "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg=="], - - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - - "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], - - "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], - - "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], - - "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], - - "electron-to-chromium": ["electron-to-chromium@1.5.364", "", {}, "sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw=="], - - "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "enhanced-resolve": ["enhanced-resolve@5.24.5", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A=="], - - "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - - "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], - - "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], - - "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], - - "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - - "framesync": ["framesync@6.1.2", "", { "dependencies": { "tslib": "2.4.0" } }, "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g=="], - - "fs-extra": ["fs-extra@11.3.5", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg=="], - - "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], - - "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], - - "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], - - "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - - "globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="], - - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - - "hey-listen": ["hey-listen@1.0.8", "", {}, "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="], - - "html-entities": ["html-entities@2.3.3", "", {}, "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA=="], - - "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], - - "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], - - "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], - - "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], - - "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], - - "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], - - "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - - "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], - - "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], - - "jsonfile": ["jsonfile@6.2.1", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q=="], - - "kolorist": ["kolorist@1.8.0", "", {}, "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ=="], - - "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], - - "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], - - "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], - - "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], - - "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], - - "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], - - "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], - - "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], - - "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], - - "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], - - "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], - - "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], - - "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], - - "local-pkg": ["local-pkg@1.2.1", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.3.0", "quansync": "^0.2.11" } }, "sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q=="], - - "lodash.memoize": ["lodash.memoize@4.1.2", "", {}, "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="], - - "lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="], - - "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], - - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - - "mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="], - - "mlly": ["mlly@1.8.2", "", { "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.3" } }, "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA=="], - - "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - - "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], - - "node-releases": ["node-releases@2.0.46", "", {}, "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ=="], - - "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - - "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], - - "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], - - "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], - - "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - - "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], - - "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], - - "pkg-types": ["pkg-types@2.3.1", "", { "dependencies": { "confbox": "^0.2.4", "exsolve": "^1.0.8", "pathe": "^2.0.3" } }, "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg=="], - - "popmotion": ["popmotion@11.0.5", "", { "dependencies": { "framesync": "6.1.2", "hey-listen": "^1.0.8", "style-value-types": "5.1.2", "tslib": "2.4.0" } }, "sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA=="], - - "postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="], - - "postcss-calc": ["postcss-calc@10.1.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.38" } }, "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw=="], - - "postcss-cli": ["postcss-cli@11.0.1", "", { "dependencies": { "chokidar": "^3.3.0", "dependency-graph": "^1.0.0", "fs-extra": "^11.0.0", "picocolors": "^1.0.0", "postcss-load-config": "^5.0.0", "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", "slash": "^5.0.0", "tinyglobby": "^0.2.12", "yargs": "^17.0.0" }, "peerDependencies": { "postcss": "^8.0.0" }, "bin": { "postcss": "index.js" } }, "sha512-0UnkNPSayHKRe/tc2YGW6XnSqqOA9eqpiRMgRlV1S6HdGi16vwJBx7lviARzbV1HpQHqLLRH3o8vTcB0cLc+5g=="], - - "postcss-colormin": ["postcss-colormin@7.0.10", "", { "dependencies": { "@colordx/core": "^5.4.3", "browserslist": "^4.28.2", "caniuse-api": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-yFr6JezOolHLta/buLE71VKPh2mXursp4saVe98/ol8ZnEWhL+racShqPKlvd/DKWLre/39B6HhcMXf7RZ3hxg=="], - - "postcss-convert-values": ["postcss-convert-values@7.0.12", "", { "dependencies": { "browserslist": "^4.28.2", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-xurKu5qqk4viR3Cp3p4xBR4KfnZm4w4ys6+UBwBmeuBSNkH7+DtLnYOYnOffgtE4yx8sH9S1VZ6RAAvROXzP2Q=="], - - "postcss-discard-comments": ["postcss-discard-comments@7.0.8", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-CvvS5S9WrXblFXCEJ9nVo+4z+eA7zSC7Z88V1HEJuwlQhlFnYTIjg1xJY+BCUiG2bvICap2tXii4mP22BD108Q=="], - - "postcss-discard-duplicates": ["postcss-discard-duplicates@7.0.4", "", { "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-VBNn1+EuMZkeGVVtz0gRfbNGtx9IFgAsAV+E2pHtXPrp4qfGBkhTIiAuE/wrb+Y6Pakg9NewAlfTpYIFAWODtw=="], - - "postcss-discard-empty": ["postcss-discard-empty@7.0.3", "", { "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-M2pyjQCU+/7cMHVtL6bKTHjv0lZnPLMpicgr67Dlth7AbuV9gjVTtUqaRwn6Pp6BwSDspUzhz8SaUrRykJU5Dw=="], - - "postcss-discard-overridden": ["postcss-discard-overridden@7.0.3", "", { "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-aNovXo9UsZuRNLzHJtp13lHIvinDPfiXBPePpXkSjCbgp++iU2FqE+YxvjIsg6EdyPZsASFbfu+JcBFVsErXIQ=="], - - "postcss-load-config": ["postcss-load-config@5.1.0", "", { "dependencies": { "lilconfig": "^3.1.1", "yaml": "^2.4.2" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1" }, "optionalPeers": ["jiti", "postcss", "tsx"] }, "sha512-G5AJ+IX0aD0dygOE0yFZQ/huFFMSNneyfp0e3/bT05a8OfPC5FUoZRPfGijUdGOJNMewJiwzcHJXFafFzeKFVA=="], - - "postcss-merge-longhand": ["postcss-merge-longhand@7.0.7", "", { "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^7.0.11" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-b3mfYUxR388u5Pt0HPcVIUtUDn/k15UfTY9M+ORW+meCR6JLNxoZffiYvXyOYQoRYQNZyX/UFkMCM/mNHxe1qA=="], - - "postcss-merge-rules": ["postcss-merge-rules@7.0.11", "", { "dependencies": { "browserslist": "^4.28.2", "caniuse-api": "^3.0.0", "cssnano-utils": "^5.0.3", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-SJUPM18g2BmPhf8BVlbwqWz4aK3pLu6u6xjfwEzra7xL6IBR10sUaiB++EzqcVfadPHrKBSMlNdP+XieykhI+Q=="], - - "postcss-minify-font-values": ["postcss-minify-font-values@7.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-yilG/VOaNI74IylQvAQQxm3/wZVBkXyYUqNUAdxqwtbWUXPsbK1q8Ms0mL83v+f8YicgcyfYCRZtWACUdYajpA=="], - - "postcss-minify-gradients": ["postcss-minify-gradients@7.0.5", "", { "dependencies": { "@colordx/core": "^5.4.3", "cssnano-utils": "^5.0.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-YraROyQRg3BI1+Hg8E05B/JPdnTm8EDSVu4P2BxdM+CRiOyfmou809+chGIqo6fQqwjPGQ947nbGncSjmTU1WQ=="], - - "postcss-minify-params": ["postcss-minify-params@7.0.9", "", { "dependencies": { "browserslist": "^4.28.2", "cssnano-utils": "^5.0.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-R8itbB8BhlpoYyBm1ou0dD+vJnQ3F6adQipR4UnkCHUwlo+S9WXJaDRg1RHjC8YVAtIdrQzSWvJl40HnGDTKjA=="], - - "postcss-minify-selectors": ["postcss-minify-selectors@7.1.2", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-api": "^3.0.0", "cssesc": "^3.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-aQtrEWKwqafNlExcKHQvPGsXR2+vlUqqJtf5XsCQcgsSb5PL4wlujWBYDJuWsP4UnQX1YHDHU8qRlD+1PzTQ+Q=="], - - "postcss-normalize-charset": ["postcss-normalize-charset@7.0.3", "", { "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-NoBfZu8PR4c2NlmjvrqQTzCzLY79hwcSRgNQ3ZiNK0ABzf9kYKloE/jNj+/8GQY1wsm8pRRgANk6ydLH8cwo0Q=="], - - "postcss-normalize-display-values": ["postcss-normalize-display-values@7.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-ldsCX0QIt05pKIOobZtVQ48wXJecr+czw4+e1/YjVhLMqslShgpVxgPtI2CefURR8oyVoYaU/l829MMwExDMLw=="], - - "postcss-normalize-positions": ["postcss-normalize-positions@7.0.4", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-VEvlpeGd3Ju1Hqa/oN4jaP3+ms4laYwkEL9N9u+B6k54PZjXbW1n6wI+aVprf1BQXlCYpS5+1pl/7/vHiKgARg=="], - - "postcss-normalize-repeat-style": ["postcss-normalize-repeat-style@7.0.4", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-6mPKlY/8cSaDHxX502wERADarJsccwlky6yIrOapHH2ZgfoKAV94SbiTKfKEs4EEpdazuc3J72WsqeYk7hp9+Q=="], - - "postcss-normalize-string": ["postcss-normalize-string@7.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-HnEQPUchi1eznmDKEYrKUTqrprEq97SrpUYClgUkv7V2zRODD9DFoUsYU+m9ZOetmD5ku7fEMZB/lwy8IT6xVQ=="], - - "postcss-normalize-timing-functions": ["postcss-normalize-timing-functions@7.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-zmEzHdvpZBZu0OKlbJSfgASQvaayyAoVuWtvyr34IJ/LyS+DaOKvvR3EvFJ9RWWtNIx+CMvO125OVophaxNYew=="], - - "postcss-normalize-unicode": ["postcss-normalize-unicode@7.0.9", "", { "dependencies": { "browserslist": "^4.28.2", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-DRAdWfeh/TjmhLJsw91vdiWCnUod9iwvM7xyS02/nF/sLsCR3A8l3pztrSUrWG8DSBqfX7yEk9FM0USaVJ2mSg=="], - - "postcss-normalize-url": ["postcss-normalize-url@7.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-CL93wmloq5qsffmFv+bw24MIRbmhHrp53qoh1LDAb/5TtjWEXI/np4xcP/Gw9oWCb2XyWnqHYLDUwiKRoJBA1Q=="], - - "postcss-normalize-whitespace": ["postcss-normalize-whitespace@7.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-FdHjjn+Ht5Z2ZRjNOmeCbNq6lq09sUYKpmlF/Aq0XjVNSLTL6fmHlA/3swN2wP2caY9GV/tjSDcIIyS7aN7W0A=="], - - "postcss-ordered-values": ["postcss-ordered-values@7.0.4", "", { "dependencies": { "cssnano-utils": "^5.0.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-nubSi49hDHQk4E8KIj+IbLY8Bg+8OcSUEhgyolgM+atnOvXjV7EjaR6bac4YGZoFyPa9mWoAF3EaYbWdFkKqVg=="], - - "postcss-reduce-initial": ["postcss-reduce-initial@7.0.9", "", { "dependencies": { "browserslist": "^4.28.2", "caniuse-api": "^3.0.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-ztTNPdIxXTxtBcG03E9u8v44M4ElXbMIRT7pf2onlquGula0Y83nKKxqM22FA/hMgkfCjN7ohevkVlaNwI8iOQ=="], - - "postcss-reduce-transforms": ["postcss-reduce-transforms@7.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-FXsnN9ZwcZTT8Yf8cAHA8qIGUXcX6WfLd9JoYhrdDfmvsVhhfqkkv7m4AC3rwFOfz+GzkUa87OCKF9dUcicd+g=="], - - "postcss-reporter": ["postcss-reporter@7.1.0", "", { "dependencies": { "picocolors": "^1.0.0", "thenby": "^1.3.4" }, "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-/eoEylGWyy6/DOiMP5lmFRdmDKThqgn7D6hP2dXKJI/0rJSO1ADFNngZfDzxL0YAxFvws+Rtpuji1YIHj4mySA=="], - - "postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], - - "postcss-svgo": ["postcss-svgo@7.1.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^4.0.1" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-2QfoFOYMcj8lwcVEf9WeTlkVIAm7u2QvOEhMzkQU3KUhhGX/l8hVV9EtjMv4iq3E9iI3OeeMN0YoMLbGusuigw=="], - - "postcss-unique-selectors": ["postcss-unique-selectors@7.0.7", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-d+sCkaRnSefghOUdH8CMJZV9yUQhj2ojpe8Nw/lA+LV1UOfeleGkLTl6XdCFFSai9UJ+DJPb69FFuqthXYsY8w=="], - - "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], - - "pretty-hrtime": ["pretty-hrtime@1.0.3", "", {}, "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A=="], - - "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], - - "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], - - "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - - "reduce-configs": ["reduce-configs@1.1.2", "", {}, "sha512-AgBP55V8FC7NaqoOP2RCbTpu6LE+YuX3LUZkNAoitcfyS3/PIC8Obg/TJrBzTkJ+lDvZv0TTAeDpLkzjTtYlbw=="], - - "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], - - "rsbuild-plugin-dts": ["rsbuild-plugin-dts@0.22.0", "", { "dependencies": { "@ast-grep/napi": "0.37.0" }, "peerDependencies": { "@microsoft/api-extractor": "^7", "@rsbuild/core": "^1.0.0 || ^2.0.0-0", "@typescript/native-preview": "7.x", "typescript": "^5 || ^6" }, "optionalPeers": ["@microsoft/api-extractor", "@typescript/native-preview", "typescript"] }, "sha512-Oyiu5oJDHWOnBv7yRr8eAGfoEddwxfPqUbAX6HvcJxrnR/h6Zd0VgTBWVTgqALYhLcL2ZdyZ2vwnqfhan4krwA=="], - - "rsbuild-plugin-solid-layouts": ["rsbuild-plugin-solid-layouts@0.2.1", "", { "dependencies": { "solid-layouts-oxc": "^0.2.1" }, "peerDependencies": { "@rsbuild/core": ">=1.3.0" } }, "sha512-BUUC6P3wvLPowWCkRZj/82PXaHMLxLNg7FgQFWiR6AU0VrH9MFGKT8f83GCNdwBUHYjymZ1EX31SxZQ3KDu5NA=="], - - "sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], - - "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - - "seroval": ["seroval@1.5.4", "", {}, "sha512-46uFvgrXTVxZcUorgSSRZ4y+ieqLLQRMlG4bnCZKW3qI6BZm7Rg4ntMW4p1mILEEBZWrFlcpp0AyIIlM6jD9iw=="], - - "seroval-plugins": ["seroval-plugins@1.5.4", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-S0xQPhUTefAhNvNWFg0c1J8qJArHt5KdtJ/cFAofo06KD1MVSeFWyl4iiu+ApDIuw0WhjpOfCdgConOfAnLgkw=="], - - "slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="], - - "solid-js": ["solid-js@2.0.0-rc.0", "", { "dependencies": { "@solidjs/signals": "^2.0.0-rc.0", "csstype": "^3.1.0", "seroval": "~1.5.4", "seroval-plugins": "~1.5.4" } }, "sha512-3enTJ71VL69nM5p/it2InVBDBt316Cqfij+F0S7VuHZLITc8YV7Rvavjoy52nAKKxYWXM+BcXh2K7KcLTf1zdQ=="], - - "solid-layouts": ["solid-layouts@0.2.1", "", { "peerDependencies": { "@solidjs/web": "^2.0.0-rc.0", "solid-js": "^1.9.14 || ^2.0.0-rc.0" }, "optionalPeers": ["@solidjs/web"] }, "sha512-afgDiwRhBNimxCrEUfh2+6rO18ti6X1gFz5peZ4BPycDYGyeBrxLDy97C4BmmmwgqPkLZrIbbQEUJ4i32W9TPA=="], - - "solid-layouts-oxc": ["solid-layouts-oxc@0.2.1", "", { "bin": { "solid-layouts-library": "bin/solid-layouts-library.js", "solid-layouts-application": "bin/solid-layouts-application.js", "solid-layouts-lint": "bin/solid-layouts-lint.js" } }, "sha512-u245kTqsNzYOEwpKxaTQOIubOgkXBQDuwP7xKzQ8MNFMHsNP6FrgtTA0tEf5UcUcE+WEyjl17VRRKnmUChat2w=="], - - "solid-refresh": ["solid-refresh@0.7.8", "", { "dependencies": { "@babel/generator": "^7.29.1", "@babel/types": "^7.29.0" }, "peerDependencies": { "solid-js": "^1.3" } }, "sha512-iG442T3HXJp5jEebCy8okETrWnmX7CnxNOKrJQVeufh6WXSn+xtLXaptUXXMHTWcRqTJOJwQ8UwzxrRtVFSIzA=="], - - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - - "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "style-value-types": ["style-value-types@5.1.2", "", { "dependencies": { "hey-listen": "^1.0.8", "tslib": "2.4.0" } }, "sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q=="], - - "stylehacks": ["stylehacks@7.0.11", "", { "dependencies": { "browserslist": "^4.28.2", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.5.13" } }, "sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg=="], - - "svgo": ["svgo@3.3.3", "", { "dependencies": { "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0", "sax": "^1.5.0" }, "bin": "./bin/svgo" }, "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng=="], - - "tailwind-merge": ["tailwind-merge@3.6.0", "", {}, "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w=="], - - "tailwindcss": ["tailwindcss@4.3.3", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="], - - "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], - - "thenby": ["thenby@1.4.1", "", {}, "sha512-D5a/bO0KdalOE3q8MlrRmSxjbKZHT3MQmXkJP+r97Vw8MMwOZKOwUSEyTtK7eSMj2y0kyAjpYMRMZmmLw1FtNQ=="], - - "tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], - - "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], - - "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], - - "tslib": ["tslib@2.4.0", "", {}, "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="], - - "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], - - "ufo": ["ufo@1.6.4", "", {}, "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA=="], - - "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], - - "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], - - "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], - - "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - - "validate-html-nesting": ["validate-html-nesting@1.2.4", "", {}, "sha512-doQi7e8EJ2OWneSG1aZpJluS6A49aZM0+EICXWKm1i6WvqTLmq0tpUcImc4KTWG50mORO0C4YDBtOCSYvElftw=="], - - "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - - "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], - - "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - - "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], - - "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], - - "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - - "@dom-expressions/babel-plugin-jsx/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="], - - "@emnapi/core/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@emnapi/runtime/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@emnapi/wasi-threads/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g=="], - - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], - - "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], - - "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@tailwindcss/postcss/postcss": ["postcss@8.5.26", "", { "dependencies": { "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ=="], - - "@tybys/wasm-util/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - - "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], - - "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - - "mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], - - "postcss-svgo/svgo": ["svgo@4.0.1", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.5.0" }, "bin": "./bin/svgo.js" }, "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w=="], - - "readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - - "@tailwindcss/postcss/postcss/nanoid": ["nanoid@3.3.18", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w=="], - - "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], - - "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], - - "postcss-svgo/svgo/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], - - "postcss-svgo/svgo/css-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="], - - "postcss-svgo/svgo/css-tree/mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], - } -} diff --git a/docs/api-contract.md b/docs/api-contract.md index f3458777..085e0b37 100644 --- a/docs/api-contract.md +++ b/docs/api-contract.md @@ -11,7 +11,7 @@ invisible for a day behind a doc that looked correct the whole time. When an API change is intentional, run `bun run check:api -- --write`, read the diff, and commit it. The diff is the review. -184 components. An empty list means the component adds nothing beyond +185 components. An empty list means the component adds nothing beyond HTML attributes and `UIBaseProps`; that is an assertion, not a gap. --- @@ -182,7 +182,7 @@ HTML attributes and `UIBaseProps`; that is an assertion, not a gap. ### ColorWheelFlower -`class mode palette` +`class id mode palette` ### ComboBox @@ -474,7 +474,7 @@ HTML attributes and `UIBaseProps`; that is an assertion, not a gap. ### LanguageSwitcher -`align aria-label currentLanguageLabel i18n loadingLabel onLanguageChange optionsLabel` +`align aria-label currentLanguageLabel i18n id loadingLabel onLanguageChange optionsLabel` ### Link @@ -560,6 +560,10 @@ HTML attributes and `UIBaseProps`; that is an assertion, not a gap. `onChange page state total` +### PanelToggle + +`aria-controls aria-label expanded id side` + ### PasswordField `aria-describedby autocomplete autofocus class disabled hiddenIcon hideLabel id inputClass inputRef invalid label name onBlur onInput onVisibilityChange placeholder required showLabel startIcon value visibleIcon` diff --git a/layouts.library.json b/layouts.library.json index ef458e94..7cd8d9db 100644 --- a/layouts.library.json +++ b/layouts.library.json @@ -144,6 +144,7 @@ "NoiseBackground", "PWAInstallPrompt", "Pagination", + "PanelToggle", "PasswordField", "PasswordRequirements", "Popover", diff --git a/package.json b/package.json index e0872a8a..8c8612e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pathscale/ui", - "version": "2.11.8", + "version": "2.11.9", "author": "pathscale", "repository": { "type": "git", @@ -75,6 +75,7 @@ "@rsbuild/plugin-solid": "^1.2.1", "@rslib/core": "^0.22.0", "@solidjs/h": "^2.0.0-rc.0", + "@solidjs/web": "next", "@standard-schema/spec": "^1.1.0", "@tailwindcss/postcss": "^4.3.3", "@types/bun": "^1.3.14", @@ -86,7 +87,7 @@ "postcss-cli": "^11.0.1", "postcss-selector-parser": "^7.1.1", "rsbuild-plugin-solid-layouts": "^0.2.1", - "solid-js": "^2.0.0-rc.0", + "solid-js": "next", "solid-layouts": "^0.2.1", "solid-layouts-oxc": "^0.2.1", "svgo": "^3.3.3", @@ -97,12 +98,12 @@ "babel-preset-solid": "^2.0.0-rc.0" }, "dependencies": { - "@solidjs/web": "^2.0.0-rc.0", "clsx": "^2.1.1", "tailwind-merge": "^3.6.0" }, "peerDependencies": { "@standard-schema/spec": "^1.0.0", + "@solidjs/web": ">=2.0.0-rc.0", "popmotion": "^11.0.5", "solid-js": ">=2.0.0-rc.0", "solid-layouts": "^0.2.0" @@ -134,7 +135,7 @@ "qa:checks": "bun run tests/qa-harness/generate-checks.ts", "qa:entries": "bun run tests/qa-harness/generate-entries.ts", "qa:dev": "rsbuild dev --config tests/qa-harness/rsbuild.config.ts", - "qa:build": "bun run qa:entries && rsbuild build --config tests/qa-harness/rsbuild.config.ts", + "qa:build": "bun run build && bun run qa:checks && bun run qa:entries && rsbuild build --config tests/qa-harness/rsbuild.config.ts", "test": "bun test --conditions=browser", "check:api": "bun run scripts/check-api-contract.ts", "qa:lint": "bun biome lint tests/qa-harness" diff --git a/rslib.config.ts b/rslib.config.ts index 66b3d6d5..a96c3f95 100644 --- a/rslib.config.ts +++ b/rslib.config.ts @@ -2,6 +2,20 @@ import { pluginBabel } from "@rsbuild/plugin-babel"; import { pluginSolid } from "@rsbuild/plugin-solid"; import { pluginSolidLayoutsLibrary } from "rsbuild-plugin-solid-layouts"; import { defineConfig } from "@rslib/core"; +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; + +const packageVersion = (name: string) => + JSON.parse(readFileSync(resolve(__dirname, "node_modules", name, "package.json"), "utf8")) + .version as string; +const solidVersion = packageVersion("solid-js"); +const solidWebVersion = packageVersion("@solidjs/web"); + +if (solidVersion !== solidWebVersion || !solidVersion.startsWith("2.")) { + throw new Error( + `UI requires one matching Solid 2 runtime; resolved solid-js=${solidVersion}, @solidjs/web=${solidWebVersion}`, + ); +} export default defineConfig({ source: { diff --git a/src/components/color-wheel-flower/ColorWheelFlower.css b/src/components/color-wheel-flower/ColorWheelFlower.css index d8d73d23..6af81e34 100644 --- a/src/components/color-wheel-flower/ColorWheelFlower.css +++ b/src/components/color-wheel-flower/ColorWheelFlower.css @@ -49,20 +49,55 @@ .color-wheel-flower__dot { position: absolute; - transform: translate(-50%, -50%); + z-index: 1; + } + + .color-wheel-flower__dot--pulsing { + z-index: 20; + } + + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:hover, + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:focus-within { + z-index: 30; } .color-wheel-flower__dot-frame { position: relative; width: 32px; height: 32px; + margin-top: -16px; + margin-left: -16px; } .color-wheel-flower__dot-motion { position: relative; width: 100%; height: 100%; - will-change: transform, opacity; + opacity: 1; + transform: translate(0, 0) scale(1); + transform-origin: center; + transition: transform 100ms ease-out; + } + + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:hover + .color-wheel-flower__dot-motion, + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:focus-within + .color-wheel-flower__dot-motion { + transform: translate(0, 0) scale(1.1); + } + + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:active + .color-wheel-flower__dot-motion { + transform: translate(0, 0) scale(1.04); + } + + .color-wheel-flower__dot--pulsing .color-wheel-flower__dot-motion { + animation: color-wheel-flower-pulse 220ms ease-out; } .color-wheel-flower__halo { @@ -73,11 +108,26 @@ bottom: -5px; border-radius: var(--radius-pill, 9999px); pointer-events: none; + opacity: 0; background: radial-gradient( circle, rgb(255 255 255 / 25%) 0%, rgb(255 255 255 / 0%) 70% ); + transition: opacity 100ms ease-out; + } + + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:hover + .color-wheel-flower__halo, + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:focus-within + .color-wheel-flower__halo { + opacity: 0.6; + } + + .color-wheel-flower__dot--pulsing .color-wheel-flower__halo { + opacity: 0.35; } .color-wheel-flower__swatch { @@ -85,6 +135,8 @@ z-index: 10; width: 100% !important; height: 100% !important; + border: 1px solid + color-mix(in srgb, var(--color-base-content) 72%, transparent) !important; border-radius: var(--radius-pill, 9999px) !important; background: var(--color-swatch-current) !important; transform: none !important; @@ -120,6 +172,7 @@ .color-wheel-flower__highlight { position: absolute; + z-index: 11; inset: 0; border-radius: var(--radius-pill, 9999px); border: 2px solid rgb(255 255 255 / 100%); @@ -131,13 +184,41 @@ box-shadow 300ms ease-out; } - .color-wheel-flower__highlight--hovered { + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:hover + .color-wheel-flower__highlight, + .color-wheel-flower:not(.color-wheel-flower--disabled) + .color-wheel-flower__dot:focus-within + .color-wheel-flower__highlight { opacity: 0.75; box-shadow: 0 0 6px rgb(255 255 255 / 45%); + transition: none; } .color-wheel-flower__highlight--pulsing { opacity: 0.45; box-shadow: 0 0 4px rgb(255 255 255 / 35%); } + + @keyframes color-wheel-flower-pulse { + 0%, + 100% { + transform: translate(0, 0) scale(1); + } + 55% { + transform: translate(0, 0) scale(1.12); + } + } + + @media (prefers-reduced-motion: reduce) { + .color-wheel-flower__dot-motion, + .color-wheel-flower__halo, + .color-wheel-flower__highlight { + transition: none; + } + + .color-wheel-flower__dot--pulsing .color-wheel-flower__dot-motion { + animation: none; + } + } } diff --git a/src/components/color-wheel-flower/ColorWheelFlower.layout.tsx b/src/components/color-wheel-flower/ColorWheelFlower.layout.tsx index 8dc689c1..9d0d8ca7 100644 --- a/src/components/color-wheel-flower/ColorWheelFlower.layout.tsx +++ b/src/components/color-wheel-flower/ColorWheelFlower.layout.tsx @@ -17,21 +17,15 @@ import { type ColorWheelFlowerMode, resolveColorWheelFlowerPalette, } from "./ColorWheelFlower.palette"; -import { - motionDistances, - motionDurations, - motionEasings, - prefersReducedMotion, - runMotion, - type MotionState, - type MotionTransition, -} from "../../motion"; +import { prefersReducedMotion } from "../../motion"; import { CLASSES } from "./ColorWheelFlower.recipe"; import type { Layout } from "../../lib/layouts"; import { componentRecipe } from "./ColorWheelFlower.recipe"; import { flowerPetalPosition } from "./ColorWheelFlower.geometry"; export interface ColorWheelFlowerProps { + /** Stable base for the flower and each interactive petal. */ + id?: string; class?: string; /** Explicit mode. Omit to follow the root `data-theme` attribute. */ mode?: ColorWheelFlowerMode; @@ -100,66 +94,6 @@ const createColorItem = ( }; }; -const readMotionState = (el: HTMLElement): MotionState => { - if (typeof getComputedStyle === "undefined") { - return { opacity: 1, x: 0, y: 0, scale: 1 }; - } - const styles = getComputedStyle(el); - const opacityValue = Number.parseFloat(styles.opacity); - const opacity = Number.isFinite(opacityValue) ? opacityValue : 1; - const transform = styles.transform; - - if (!transform || transform === "none") { - return { opacity, x: 0, y: 0, scale: 1 }; - } - - if (typeof DOMMatrixReadOnly !== "undefined") { - const matrix = new DOMMatrixReadOnly(transform); - return { opacity, x: matrix.m41, y: matrix.m42, scale: matrix.a }; - } - - const matrixMatch = transform.match(/matrix\(([^)]+)\)/); - if (!matrixMatch) { - return { opacity, x: 0, y: 0, scale: 1 }; - } - - const values = matrixMatch[1] - .split(",") - .map((value) => Number.parseFloat(value.trim())); - - return { - opacity, - scale: Number.isFinite(values[0]) ? values[0] : 1, - x: Number.isFinite(values[4]) ? values[4] : 0, - y: Number.isFinite(values[5]) ? values[5] : 0, - }; -}; - -const applyMotionState = (el: HTMLElement, state: MotionState) => { - el.style.opacity = String(state.opacity ?? 1); - el.style.transform = `translate3d(${state.x ?? 0}px, ${state.y ?? 0}px, 0) scale(${state.scale ?? 1})`; -}; - -const getLiftOffset = (item: ColorItem, distance: number) => { - const radius = Math.sqrt(item.offsetX ** 2 + item.offsetY ** 2); - if (!Number.isFinite(radius) || radius === 0) { - return { x: 0, y: 0 }; - } - - return { - x: (item.offsetX / radius) * distance, - y: (item.offsetY / radius) * distance, - }; -}; - -const easeOutBack = - (overshoot = 1.4) => - (t: number) => { - const c1 = overshoot; - const c3 = c1 + 1; - return 1 + c3 * (t - 1) ** 3 + c1 * (t - 1) ** 2; - }; - const toRgba = (rgb: string, alpha: number) => { const match = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); if (!match) return rgb; @@ -237,20 +171,11 @@ function buildColors(palette: readonly string[]): ColorItem[] { } const CENTER_INDEX = LAYOUT.findIndex((l) => l.isCenter); -const MAX_RADIUS = Math.max( - ...LAYOUT.map((l) => Math.sqrt(l.offsetX ** 2 + l.offsetY ** 2)), -); -const MAX_WAVE_DISTANCE = MAX_RADIUS * 2; -const MAX_WAVE_DELAY = 0.12; - const ColorWheelFlower: Layout = () => { const context = useColorPickerContext(); const [selectedIndex, setSelectedIndex] = createSignal(null); - const [hoveredIndex, setHoveredIndex] = createSignal(null); - const [pressedIndex, setPressedIndex] = createSignal(null); - const [pointer, setPointer] = createSignal({ x: 0, y: 0, active: false }); const [pulseState, setPulseState] = createSignal<{ index: number; key: number; @@ -286,26 +211,7 @@ const ColorWheelFlower: Layout = buildColors(resolveColorWheelFlowerPalette(mode(), props.palette)), ); - const rainbowGradient = () => { - const outer = colors().slice(0, 12); - const stops = outer.map( - (item, index) => `${item.rgb} ${(index / outer.length) * 360}deg`, - ); - stops.push(`${outer[0].rgb} 360deg`); - return `conic-gradient(from 0deg, ${stops.join(", ")})`; - }; - const reduceMotion = prefersReducedMotion(); - const ringTransition: MotionTransition = reduceMotion - ? { duration: 0 } - : { duration: motionDurations.slow, easing: motionEasings.inOut }; - - const hoverLift = reduceMotion ? 0 : motionDistances.sm; - const pressScale = 0.96; - const pulseScale = 1.12; - - let containerRef: HTMLDivElement | undefined; - let pointerTimeout: number | undefined; let pulseTimeout: number | undefined; const closestIndex = createMemo(() => { @@ -417,54 +323,17 @@ const ColorWheelFlower: Layout = } }); - const handlePointerMove = (event: MouseEvent) => { - // Bound to a const so the guard narrows across the closure boundary. - const node = containerRef; - if (!node) return; - - const rect = node.getBoundingClientRect(); - const x = event.clientX - rect.left - rect.width / 2; - const y = event.clientY - rect.top - rect.height / 2; - - setPointer({ x, y, active: true }); - - if (pointerTimeout !== undefined) { - clearTimeout(pointerTimeout); - } - - pointerTimeout = window.setTimeout(() => { - setPointer((prev) => ({ ...prev, active: false })); - }, 120); - }; - - const handlePointerLeave = () => { - setPointer((prev) => ({ ...prev, active: false })); - setHoveredIndex(null); - - if (pointerTimeout !== undefined) { - clearTimeout(pointerTimeout); - } - }; - - - - onCleanup(() => { - if (pulseTimeout !== undefined) { clearTimeout(pulseTimeout); } - - if (pointerTimeout !== undefined) { - clearTimeout(pointerTimeout); - } }); const pickerValue = () => colors()[visualSelectedIndex()]?.hex; return (
= props.class, ), }} - onMouseMove={handlePointerMove} - onMouseLeave={handlePointerLeave} data-slot="color-wheel-flower" data-color-mode={mode()} data-disabled={context.disabled() ? "true" : "false"} @@ -489,6 +356,7 @@ const ColorWheelFlower: Layout =
= > {(item, index) => { - let motionRef: HTMLDivElement | undefined; - let dotControl: { stop: () => void } | null = null; - let hasPaintedFinalState = false; - - const isHovered = () => hoveredIndex() === index(); - const isPressed = () => pressedIndex() === index(); const isPulsing = () => pulseState()?.index === index(); - const dotBaseTarget = createMemo(() => { - if (context.disabled()) { - return { opacity: 0.5, scale: 1, x: 0, y: 0 }; - } - - const pointerState = pointer(); - const anchorIdx = hoveredIndex(); - - let scale = 1; - let offsetX = 0; - let offsetY = 0; - - if (anchorIdx !== null && pointerState.active) { - const anchor = colors()[anchorIdx]; - const distance = Math.sqrt( - (item.offsetX - anchor.offsetX) ** 2 + - (item.offsetY - anchor.offsetY) ** 2, - ); - - const waveRadius = MAX_RADIUS * 0.9; - const influence = Math.max(0, 1 - distance / waveRadius); - - if (influence > 0) { - const maxDelta = 16; - const deltaX = Math.max( - -maxDelta, - Math.min(maxDelta, pointerState.x - anchor.offsetX), - ); - const deltaY = Math.max( - -maxDelta, - Math.min(maxDelta, pointerState.y - anchor.offsetY), - ); - - const waveStrength = isHovered() ? 0.25 : 0.18; - offsetX += deltaX * influence * waveStrength; - offsetY += deltaY * influence * waveStrength; - - const liftStrength = isHovered() ? 0.8 : 0.35; - const lift = getLiftOffset(item, hoverLift * liftStrength); - offsetX += lift.x * influence; - offsetY += lift.y * influence; - - const scaleBoost = isHovered() ? 0.06 : 0.03; - scale += influence * scaleBoost; - } - } - - return { opacity: 1, scale, x: offsetX, y: offsetY }; - }); - - const dotTarget = createMemo(() => { - const base = dotBaseTarget(); - let scale = base.scale ?? 1; - - if (isPulsing()) { - scale *= pulseScale; - } - if (isPressed()) { - scale *= pressScale; - } - - return { - ...base, - scale, - }; - }); - - const glowOpacity = createMemo(() => { - if (context.disabled()) return 0; - if (isHovered()) return 0.6; - if (isPulsing()) return 0.35; - return 0; - }); - - const dotTransition = (): MotionTransition => { - if (reduceMotion) return { duration: 0 }; - - const anchorIdx = hoveredIndex(); - const pointerState = pointer(); - let delay = 0; - - if (anchorIdx !== null && pointerState.active) { - const anchor = colors()[anchorIdx]; - const distance = Math.sqrt( - (item.offsetX - anchor.offsetX) ** 2 + - (item.offsetY - anchor.offsetY) ** 2, - ); - - delay = Math.min( - MAX_WAVE_DELAY, - (distance / MAX_WAVE_DISTANCE) * MAX_WAVE_DELAY, - ); - } - - if (isPulsing()) { - return { - duration: motionDurations.fast, - easing: easeOutBack(1.25), - }; - } - - if (isHovered()) { - return { - duration: motionDurations.fast, - easing: motionEasings.out, - delay, - }; - } - - return { - duration: motionDurations.base, - easing: motionEasings.out, - delay, - }; - }; - - createTrackedEffect(() => { - if (!motionRef) return; - - const target = dotTarget(); - if (!hasPaintedFinalState) { - applyMotionState(motionRef, target); - hasPaintedFinalState = true; - return; - } - - const transition = dotTransition(); - dotControl?.stop(); - dotControl = runMotion( - motionRef, - readMotionState(motionRef), - target, - transition, - ); - }); - - onCleanup(() => { - dotControl?.stop(); - }); - return (
-
{ - motionRef = el; - }} - {...{ class: CLASSES.dot.motion }} - > +
= : `Theme color ${item.hex}` } state={context.disabled() ? "disabled" : undefined} - onMouseEnter={() => { - if (!context.disabled()) { - setHoveredIndex(index()); - } - }} - onMouseLeave={() => { - if (!context.disabled()) { - setHoveredIndex(null); - } - }} - onFocus={() => { - if (!context.disabled()) { - setHoveredIndex(index()); - } - }} - onBlur={() => { - if (!context.disabled()) { - setHoveredIndex(null); - } - }} - onPointerDown={() => { - if (!context.disabled()) { - setPressedIndex(index()); - } - }} - onPointerUp={() => { - if (!context.disabled()) { - setPressedIndex(null); - } - }} - onPointerLeave={() => { - if (!context.disabled()) { - setPressedIndex(null); - } - }} - onPointerCancel={() => { - if (!context.disabled()) { - setPressedIndex(null); - } - }} /> = () => ( - +
+ -
- -
{local.action}
-
+
+ +
{local.action}
+
- - {(adjustment) => ( -
-
- {adjustment().label} - - {adjustment().formatValue?.(adjustment().value) ?? adjustment().value} - -
-
- - -
- - {adjustment().hint} - -
- )} -
+ )} + +
); diff --git a/src/components/dropdown/Dropdown.layout.tsx b/src/components/dropdown/Dropdown.layout.tsx index 98d8b736..cd6369a4 100644 --- a/src/components/dropdown/Dropdown.layout.tsx +++ b/src/components/dropdown/Dropdown.layout.tsx @@ -91,9 +91,14 @@ const DropdownRoot: Layout = () => { "ref", ); - const baseId = createUniqueId(); - const triggerId = `${baseId}-trigger`; - const menuId = `${baseId}-menu`; + // The authored root id is the component's stable identity. `createUniqueId` + // is only an ARIA fallback for callers that have not adopted that contract; + // it must never overwrite a supplied id with creation-order state. + const generatedBaseId = createUniqueId(); + const authoredBaseId = typeof props.id === "string" ? props.id.trim() : ""; + const baseId = authoredBaseId || generatedBaseId; + const triggerId = `${baseId}--trigger`; + const menuId = `${baseId}--menu`; const [internalOpen, setInternalOpen] = createSignal(Boolean(props.defaultOpen)); const [items, setItems] = createSignal([]); diff --git a/src/components/inline-edit/InlineEdit.layout.tsx b/src/components/inline-edit/InlineEdit.layout.tsx index f06a7ec5..f522b2ae 100644 --- a/src/components/inline-edit/InlineEdit.layout.tsx +++ b/src/components/inline-edit/InlineEdit.layout.tsx @@ -103,6 +103,7 @@ const InlineEdit: Layout = () => { {props.children ?? props.value} + ); +}; diff --git a/src/components/panel-toggle/PanelToggle.recipe.ts b/src/components/panel-toggle/PanelToggle.recipe.ts new file mode 100644 index 00000000..564e1518 --- /dev/null +++ b/src/components/panel-toggle/PanelToggle.recipe.ts @@ -0,0 +1,19 @@ +import { recipe } from "../../lib/layouts"; + +export const panelToggle = recipe({ + component: "panel-toggle", + element: "button", + slots: { + root: { base: "panel-toggle" }, + indicator: { base: "panel-toggle__indicator" }, + }, + props: { + side: { + left: "panel-toggle--left", + right: "panel-toggle--right", + }, + }, + defaults: { + side: "right", + }, +}); diff --git a/src/components/panel-toggle/index.ts b/src/components/panel-toggle/index.ts new file mode 100644 index 00000000..ef00157d --- /dev/null +++ b/src/components/panel-toggle/index.ts @@ -0,0 +1,7 @@ +export { + PanelToggleLayout as default, + PanelToggleLayout as PanelToggle, + type PanelToggleProps, + type PanelToggleSide, +} from "./PanelToggle.generated"; +export { panelToggle } from "./PanelToggle.recipe"; diff --git a/src/components/select/Select.layout.tsx b/src/components/select/Select.layout.tsx index b42a2c2f..6766488f 100644 --- a/src/components/select/Select.layout.tsx +++ b/src/components/select/Select.layout.tsx @@ -1,5 +1,5 @@ import "./Select.css"; -import {createContext, createMemo, createSignal, createTrackedEffect, createUniqueId, onCleanup, onSettled, omit, useContext, type Accessor, type Component} from "solid-js"; +import {createContext, createMemo, createSignal, createTrackedEffect, createUniqueId, onCleanup, onSettled, omit, Show, untrack, useContext, type Accessor, type Component} from "solid-js"; import type { JSX} from "@solidjs/web"; import { twMerge } from "../../lib/twMerge"; import { @@ -49,6 +49,8 @@ type SelectContextValue = { focusNext: (direction: 1 | -1) => void; requestFocus: (target: SelectFocusRequest) => void; selectKey: (key: string) => void; + registerOptionText: (key: string, textValue: string) => void; + unregisterOptionText: (key: string) => void; registerOption: (option: SelectOptionRecord) => void; unregisterOption: (key: string) => void; setTriggerRef: (el: HTMLButtonElement) => void; @@ -158,7 +160,8 @@ const SelectRoot: Layout = () => { "ref", ); - const baseId = createUniqueId(); + const generatedId = createUniqueId(); + const baseId = props.id || generatedId; const triggerId = `${baseId}-trigger`; const listboxId = `${baseId}-listbox`; @@ -174,7 +177,8 @@ const SelectRoot: Layout = () => { const [internalSelectedKeys, setInternalSelectedKeys] = createSignal(initialSelected); const [internalOpen, setInternalOpen] = createSignal(Boolean(props.defaultOpen)); const [options, setOptions] = createSignal([]); - const [optionTextByKey, setOptionTextByKey] = createSignal(new Map()); + const optionTextByKey = new Map(); + const [optionTextRevision, setOptionTextRevision] = createSignal(0); const [focusedKey, setFocusedKey] = createSignal(); const [focusRequest, setFocusRequest] = createSignal(null); const [triggerRef, setTriggerRefSignal] = createSignal(); @@ -197,10 +201,11 @@ const SelectRoot: Layout = () => { const selectedSet = createMemo(() => new Set(selectedKeys())); const selectedText = createMemo(() => { + optionTextRevision(); if (!selectedKeys().length) return ""; return selectedKeys() - .map((key) => optionTextByKey().get(key) ?? key) + .map((key) => optionTextByKey.get(key) ?? key) .join(selectionMode() === "multiple" ? ", " : ""); }); @@ -295,13 +300,23 @@ const SelectRoot: Layout = () => { setOpen(false, { focusTrigger: true }); }; + const registerOptionText = (key: string, textValue: string) => { + if (optionTextByKey.get(key) === textValue) return; + optionTextByKey.set(key, textValue); + if (untrack(selectedKeys).includes(key)) { + setOptionTextRevision((revision) => revision + 1); + } + }; + + const unregisterOptionText = (key: string) => { + if (!optionTextByKey.delete(key)) return; + if (untrack(selectedKeys).includes(key)) { + setOptionTextRevision((revision) => revision + 1); + } + }; + const registerOption = (option: SelectOptionRecord) => { - setOptionTextByKey((current) => { - if (current.get(option.key) === option.textValue) return current; - const next = new Map(current); - next.set(option.key, option.textValue); - return next; - }); + registerOptionText(option.key, option.textValue); setOptions((current) => sortOptionsByDomOrder([ ...current.filter((entry) => entry.key !== option.key), @@ -397,6 +412,8 @@ const SelectRoot: Layout = () => { focusNext, requestFocus: setFocusRequest, selectKey, + registerOptionText, + unregisterOptionText, registerOption, unregisterOption, setTriggerRef, @@ -769,6 +786,7 @@ const SelectOption: Layout = () => { } const key = () => String(props.value); + const textValue = () => props.textValue ?? (typeof props.children === "string" ? props.children : key()); const isDisabled = () => Boolean((props.state === "disabled")) || Boolean(props.disabled) || ctx.disabled(); const isSelected = () => ctx.isSelected(key()); const isFocused = () => ctx.focusedKey() === key(); @@ -778,9 +796,7 @@ const SelectOption: Layout = () => { optionRef = el; ctx.registerOption({ key: key(), - textValue: - props.textValue ?? - (typeof props.children === "string" ? props.children : key()), + textValue: textValue(), disabled: isDisabled(), ref: el, }); @@ -789,13 +805,16 @@ const SelectOption: Layout = () => { } }; + onSettled(() => { + ctx.registerOptionText(key(), textValue()); + return () => ctx.unregisterOptionText(key()); + }); + createTrackedEffect(() => { if (!optionRef) return; ctx.registerOption({ key: key(), - textValue: - props.textValue ?? - (typeof props.children === "string" ? props.children : key()), + textValue: textValue(), disabled: isDisabled(), ref: optionRef, }); @@ -865,7 +884,13 @@ const SelectOption: Layout = () => { } }; - return ( + const MountedOption: Component = () => { + onCleanup(() => { + optionRef = undefined; + ctx.unregisterOption(key()); + }); + + return ( - ); + ); + }; + + return ; }; export type SelectProps = SelectRootProps; diff --git a/src/components/slider/Slider.layout.tsx b/src/components/slider/Slider.layout.tsx index 531a1d0b..5584ad1c 100644 --- a/src/components/slider/Slider.layout.tsx +++ b/src/components/slider/Slider.layout.tsx @@ -48,7 +48,8 @@ const Slider: Layout = () => { const size = () => props.size ?? "md"; const isDisabled = () => Boolean(props.disabled); - const labelId = createUniqueId(); + const generatedLabelId = createUniqueId(); + const labelId = () => (props.id ? `${props.id}-label` : generatedLabelId); const [dragging, setDragging] = createSignal(false); const [focusVisible, setFocusVisible] = createSignal(false); @@ -185,7 +186,7 @@ const Slider: Layout = () => { > @@ -217,6 +218,7 @@ const Slider: Layout = () => { {/* biome-ignore lint/a11y/useFocusableInteractive: Solid's JSX DOM typing requires lowercase tabindex, supplied below. */}
= () => { aria-valuenow={props.value} aria-valuetext={formattedValue()} aria-label={props["aria-label"] ?? props.label} - aria-labelledby={props.label ? labelId : undefined} + aria-labelledby={props.label ? labelId() : undefined} aria-disabled={isDisabled() ? "true" : undefined} onKeyDown={interactions.onKeyDown} onKeyUp={interactions.onKeyUp} diff --git a/src/components/tabs/Tabs.css b/src/components/tabs/Tabs.css index bd8f915b..99dc8a60 100644 --- a/src/components/tabs/Tabs.css +++ b/src/components/tabs/Tabs.css @@ -29,12 +29,17 @@ width: 100%; } + .tabs__list[data-orientation="horizontal"] .tabs__tab { + width: auto; + } + .tabs__list[data-orientation="vertical"] { flex-direction: column; gap: 0.25rem; } .tabs__list[data-orientation="vertical"] .tabs__tab { + width: 100%; min-width: 5rem; } diff --git a/src/components/tabs/Tabs.layout.tsx b/src/components/tabs/Tabs.layout.tsx index f4fb5635..e6da4126 100644 --- a/src/components/tabs/Tabs.layout.tsx +++ b/src/components/tabs/Tabs.layout.tsx @@ -67,7 +67,8 @@ const TabsRoot: Layout = () => { "onSelectionChange", ); - const baseId = createUniqueId(); + const generatedId = createUniqueId(); + const baseId = () => props.id || generatedId; const [internalSelectedKey, setInternalSelectedKey] = createSignal( props.defaultSelectedKey, ); @@ -101,8 +102,8 @@ const TabsRoot: Layout = () => { setTabs((prev) => prev.filter((item) => item.key !== key)); }; - const getTabId = (key: TabKey) => `${baseId}-tab-${String(key)}`; - const getPanelId = (key: TabKey) => `${baseId}-panel-${String(key)}`; + const getTabId = (key: TabKey) => `${baseId()}-tab-${String(key)}`; + const getPanelId = (key: TabKey) => `${baseId()}-panel-${String(key)}`; const classes = () => twMerge( diff --git a/src/index.ts b/src/index.ts index 3d2ef956..3f9d66ca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -71,6 +71,11 @@ export { } from "./components/breadcrumb"; export type { ButtonProps } from "./components/button"; export { default as Button } from "./components/button"; +export { + PanelToggle, + type PanelToggleProps, + type PanelToggleSide, +} from "./components/panel-toggle"; export { type CalendarDayHoverHandler, type CalendarDaySelectHandler, diff --git a/src/motion/engine.ts b/src/motion/engine.ts index 80c6ad11..763ffb88 100644 --- a/src/motion/engine.ts +++ b/src/motion/engine.ts @@ -51,7 +51,25 @@ export const runMotion = ( } applyTransform(); - const animationTargets = Object.keys(to) as Array; + const valueFor = (key: keyof MotionState, state: MotionState): number => { + if (key === "opacity") { + return state.opacity ?? readOpacity(el); + } + if (key === "scale") return state.scale ?? 1; + if (key === "x") return state.x ?? 0; + return state.y ?? 0; + }; + + /* + * Do not start a timed animation for a value which is already at its target. + * Apart from wasting a frame callback per channel, a component mounting in + * its final state would keep repainting for the full declared duration. A + * 31-petal colour wheel used to launch 124 such no-op animations on first + * paint, which made its apparently-static initial render fail to settle. + */ + const animationTargets = (Object.keys(to) as Array).filter( + (key) => valueFor(key, from) !== valueFor(key, to), + ); if (animationTargets.length === 0) { onComplete?.(); return { @@ -68,11 +86,10 @@ export const runMotion = ( const start = () => { animationTargets.forEach((key) => { if (key === "opacity") { - const fromValue = - from.opacity ?? (to.opacity !== undefined ? readOpacity(el) : 1); + const fromValue = valueFor(key, from); const control = driver({ from: fromValue, - to: to.opacity ?? fromValue, + to: valueFor(key, to), duration, ease, onUpdate: (latest) => { @@ -84,13 +101,8 @@ export const runMotion = ( return; } - const fromValue = - key === "scale" - ? (from.scale ?? 1) - : key === "x" - ? (from.x ?? 0) - : (from.y ?? 0); - const toValue = to[key] ?? fromValue; + const fromValue = valueFor(key, from); + const toValue = valueFor(key, to); const control = driver({ from: fromValue, diff --git a/tests/color-wheel-flower-first-paint.test.ts b/tests/color-wheel-flower-first-paint.test.ts index 248fafc5..70712596 100644 --- a/tests/color-wheel-flower-first-paint.test.ts +++ b/tests/color-wheel-flower-first-paint.test.ts @@ -3,20 +3,31 @@ import { describe, expect, it } from "bun:test"; const layout = await Bun.file( new URL("../src/components/color-wheel-flower/ColorWheelFlower.layout.tsx", import.meta.url), ).text(); +const css = await Bun.file( + new URL("../src/components/color-wheel-flower/ColorWheelFlower.css", import.meta.url), +).text(); describe("ColorWheelFlower first paint", () => { - it("writes final petal state before enabling interaction motion", () => { - expect(layout).toMatch( - /if \(!hasPaintedFinalState\) \{\s*applyMotionState\(motionRef, target\);\s*hasPaintedFinalState = true;\s*return;\s*\}\s*const transition = dotTransition\(\);/s, - ); + it("authors the neutral petal state before JavaScript runs", () => { + const rule = css.match(/\.color-wheel-flower__dot-motion\s*\{([\s\S]*?)\}/)?.[1] ?? ""; + + expect(rule).toContain("opacity: 1"); + expect(rule).toContain("transform: translate(0, 0) scale(1)"); + }); + + it("does not rely on a ref-timing style write for first paint", () => { + expect(layout).not.toContain("hasPaintedFinalState"); + expect(layout).not.toContain("applyMotionState"); }); - it("does not pay for computed-style reads on initial mount", () => { - const firstPaint = layout.indexOf("if (!hasPaintedFinalState)"); - const animatedRead = layout.indexOf("readMotionState(motionRef)", firstPaint); - const earlyReturn = layout.indexOf("return;", firstPaint); + it("centres the fixed petal frame without a percentage transform", () => { + const dotRule = css.match(/\.color-wheel-flower__dot\s*\{([\s\S]*?)\}/)?.[1] ?? ""; + const frameRule = css.match(/\.color-wheel-flower__dot-frame\s*\{([\s\S]*?)\}/)?.[1] ?? ""; - expect(firstPaint).toBeGreaterThan(-1); - expect(animatedRead).toBeGreaterThan(earlyReturn); + expect(dotRule).not.toContain("transform"); + expect(frameRule).toContain("width: 32px"); + expect(frameRule).toContain("height: 32px"); + expect(frameRule).toContain("margin-top: -16px"); + expect(frameRule).toContain("margin-left: -16px"); }); }); diff --git a/tests/interactive-stable-ids.test.ts b/tests/interactive-stable-ids.test.ts new file mode 100644 index 00000000..7a6ec3ce --- /dev/null +++ b/tests/interactive-stable-ids.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from "bun:test"; + +const slider = await Bun.file( + new URL("../src/components/slider/Slider.layout.tsx", import.meta.url), +).text(); +const wheel = await Bun.file( + new URL("../src/components/color-wheel/ComplexColorWheel.layout.tsx", import.meta.url), +).text(); +const flower = await Bun.file( + new URL("../src/components/color-wheel-flower/ColorWheelFlower.layout.tsx", import.meta.url), +).text(); +const select = await Bun.file( + new URL("../src/components/select/Select.layout.tsx", import.meta.url), +).text(); +const inlineEdit = await Bun.file( + new URL("../src/components/inline-edit/InlineEdit.layout.tsx", import.meta.url), +).text(); + +describe("interactive stable ids", () => { + it("puts a Slider id on the semantic thumb", () => { + expect(slider).toContain("id={props.id}"); + expect(slider).toContain("role=\"slider\""); + expect(slider).toContain("`${props.id}-label`"); + }); + + it("derives every complex wheel control id from its caller-owned base", () => { + expect(wheel).toContain("id={local.id}"); + expect(wheel).toContain("`${local.id}-${adjustment().id}`"); + expect(wheel).toContain("`${local.id}-${adjustment().id}-${stopIndex()}`"); + expect(flower).toContain("`${props.id}-petal-${index()}`"); + }); + + it("uses a caller-owned Select id as the trigger/listbox base", () => { + expect(select).toContain("const baseId = props.id || generatedId"); + expect(select).toContain("`${baseId}-trigger`"); + expect(select).toContain("`${baseId}-listbox`"); + }); + + it("derives both InlineEdit control ids from its caller-owned base", () => { + expect(inlineEdit).toContain("`${props.id}-trigger`"); + expect(inlineEdit).toContain("`${props.id}-field`"); + }); +}); diff --git a/tests/motion/engine.test.ts b/tests/motion/engine.test.ts new file mode 100644 index 00000000..a576e396 --- /dev/null +++ b/tests/motion/engine.test.ts @@ -0,0 +1,32 @@ +import { afterEach, describe, expect, it } from "bun:test"; +import { immediateDriver, setMotionDriver } from "../../src/motion/driver"; +import { runMotion } from "../../src/motion/engine"; + +afterEach(() => setMotionDriver(immediateDriver)); + +describe("runMotion", () => { + it("settles immediately without scheduling channels already at their targets", () => { + let calls = 0; + let completed = 0; + setMotionDriver(() => { + calls += 1; + return { stop: () => {} }; + }); + + const element = { style: {} } as unknown as HTMLElement; + runMotion( + element, + { opacity: 1, x: 0, y: 0, scale: 1 }, + { opacity: 1, x: 0, y: 0, scale: 1 }, + { duration: 0.3 }, + () => { + completed += 1; + }, + ); + + expect(calls).toBe(0); + expect(completed).toBe(1); + expect(element.style.opacity).toBe("1"); + expect(element.style.transform).toBe("translate3d(0px, 0px, 0) scale(1)"); + }); +}); diff --git a/tests/ps-qa/complex-color-wheel.ron b/tests/ps-qa/complex-color-wheel.ron index 00721a7c..8f6b06d3 100644 --- a/tests/ps-qa/complex-color-wheel.ron +++ b/tests/ps-qa/complex-color-wheel.ron @@ -14,6 +14,70 @@ subject: "heading:ComplexColorWheel", expect: PaintsNamed, ), + ( + id: "complex-color-wheel-first-frame-distinct", + group: "complex-color-wheel", + what: "ComplexColorWheel paints its repeated parts at distinct positions before interaction", + open: None, + hover: None, + click: None, + subject: "radio:Theme color ", + expect: DistinctPositions, + ), + ( + id: "complex-color-wheel-first-frame-contained", + group: "complex-color-wheel", + what: "ComplexColorWheel keeps its repeated parts inside their composition before interaction", + open: None, + hover: None, + click: None, + compare: Some("@color-wheel-flower"), + subject: "radio:Theme color ", + expect: ContainedBy, + ), + ( + id: "complex-color-wheel-hover-feedback", + group: "complex-color-wheel", + what: "ComplexColorWheel visibly responds when a rendered part is hovered", + open: None, + hover: None, + after_prepare_hover: Some("radio:Theme color "), + click: None, + subject: "@color-wheel-flower", + expect: PixelsChange, + ), + ( + id: "complex-color-wheel-desktop-parts-sit-beside", + group: "complex-color-wheel", + what: "ComplexColorWheel places its desktop controls to the right of the primary visual", + open: None, + hover: None, + click: None, + compare: Some("@color-wheel-flower"), + subject: "button:Strength 20", + expect: RightOf, + ), + ( + id: "complex-color-wheel-desktop-parts-center-vertically", + group: "complex-color-wheel", + what: "ComplexColorWheel vertically centers its primary visual against the desktop controls", + open: None, + hover: None, + click: None, + compare: Some("@complex-color-wheel-adjustments"), + subject: "@color-wheel-flower", + expect: CenterAlignedY, + ), + ( + id: "complex-color-wheel-contrast", + group: "complex-color-wheel", + what: "ComplexColorWheel keeps its rendered controls distinguishable from their surface", + open: None, + hover: None, + click: None, + subject: "Theme color ", + expect: Contrast, + ), ( id: "complex-color-wheel-renders", group: "complex-color-wheel", diff --git a/tests/ps-qa/panel-toggle.ron b/tests/ps-qa/panel-toggle.ron new file mode 100644 index 00000000..51e49150 --- /dev/null +++ b/tests/ps-qa/panel-toggle.ron @@ -0,0 +1,58 @@ +// Generated from tests/qa-harness/components.ts by tests/qa-harness/generate-checks.ts. Do not edit. +// +// PanelToggle, mounted alone on its own harness page. Outcomes for +// this component share one native host; idempotent preparation keeps each +// outcome reproducible by id against a fresh host as well. +[ + ( + id: "panel-toggle-page-paints", + group: "panel-toggle", + what: "the PanelToggle page builds and paints", + open: None, + hover: None, + click: None, + subject: "heading:PanelToggle", + expect: PaintsNamed, + ), + ( + id: "panel-toggle-measures", + group: "panel-toggle", + what: "PanelToggle keeps its standard control geometry", + open: None, + hover: None, + click: None, + expect_size: Some("8x48"), + subject: "button:Hide details", + expect: Measures, + ), + ( + id: "panel-toggle-renders", + group: "panel-toggle", + what: "PanelToggle renders a node of its own", + open: None, + hover: None, + click: None, + subject: "fixture", + expect: Paints, + ), + ( + id: "panel-toggle-paints", + group: "panel-toggle", + what: "the PanelToggle control is on screen and addressable", + open: None, + hover: None, + click: None, + subject: "button:Hide details", + expect: PaintsNamed, + ), + ( + id: "panel-toggle-acts", + group: "panel-toggle", + what: "activating PanelToggle exposes the callback result", + open: None, + hover: None, + click: Some("button:Hide details"), + subject: "heading:Action result: PanelToggle complete", + expect: PaintsNamed, + ), +] diff --git a/tests/ps-qa/select.ron b/tests/ps-qa/select.ron index d47d9b99..e5e353c4 100644 --- a/tests/ps-qa/select.ron +++ b/tests/ps-qa/select.ron @@ -24,6 +24,16 @@ subject: "fixture", expect: Paints, ), + ( + id: "select-closed-content-is-absent", + group: "select", + what: "the closed Select does not retain its menu content in the renderer", + open: None, + hover: None, + click: None, + subject: "option:first fixture", + expect: Absent, + ), ( id: "select-opens", group: "select", diff --git a/tests/qa-harness/README.md b/tests/qa-harness/README.md index a74436c8..bdbd62a0 100644 --- a/tests/qa-harness/README.md +++ b/tests/qa-harness/README.md @@ -32,11 +32,11 @@ valid way to make an outcome pass. ## Running -```bash +```zsh bun run build bun run qa:checks bun run qa:build -bash tests/qa-harness/run-all.sh +zsh tests/qa-harness/run-all.sh ``` Set `QA_PS_QA` or `QA_HOST` to test local builds of ps-qa or qa-inspect-host. diff --git a/tests/qa-harness/components.ts b/tests/qa-harness/components.ts index 7b6a0f0f..fddf7bac 100644 --- a/tests/qa-harness/components.ts +++ b/tests/qa-harness/components.ts @@ -80,10 +80,27 @@ export type ComponentSpec = { activate?: string; /** Node that proves an overlay/editor opened or a tab panel changed. */ opens?: string; + /** Menu content that must not remain in the renderer while closed. */ + closedContent?: string; /** Mount props. Kept literal so the fixture is readable in one glance. */ props?: Record; /** Option labels, for components that need children. */ options?: { value: string; label: string }[]; + /** First-frame rendered family whose members must be distinct and contained. */ + geometry?: { + family: string; + container: string; + /** Pointer target whose authored hover feedback must change rendered pixels. */ + changesOnHover?: string; + /** Desktop relationship that must not collapse into the narrow stack. */ + rightOf?: { subject: string; compare: string }; + /** Side-by-side regions whose rendered vertical centers must align. */ + centerAlignedY?: { subject: string; compare: string }; + }; + /** Exact authored control geometry, before app zoom or theme scaling. */ + measure?: { subject: string; size: string }; + /** Named painted family that must meet the native contrast floor. */ + contrast?: string; }; export const COMPONENTS: ComponentSpec[] = [ @@ -171,6 +188,20 @@ export const COMPONENTS: ComponentSpec[] = [ kind: "adjustment", subject: "Strength 20", subjectRole: "button", + geometry: { + family: "radio:Theme color ", + container: "@color-wheel-flower", + changesOnHover: "radio:Theme color ", + rightOf: { + subject: "button:Strength 20", + compare: "@color-wheel-flower", + }, + centerAlignedY: { + subject: "@color-wheel-flower", + compare: "@complex-color-wheel-adjustments", + }, + }, + contrast: "Theme color ", }, { id: "composer", @@ -322,6 +353,14 @@ export const COMPONENTS: ComponentSpec[] = [ subject: "Go to next page", subjectRole: "button", }, + { + id: "panel-toggle", + component: "PanelToggle", + kind: "action", + subject: "Hide details", + subjectRole: "button", + measure: { subject: "button:Hide details", size: "8x48" }, + }, { id: "password-field", component: "PasswordField", @@ -356,12 +395,13 @@ export const COMPONENTS: ComponentSpec[] = [ id: "select", component: "Select", kind: "value", - // Measured: the trigger reads "Session: first fixture". The options exist - // in the tree but at 0x0 hidden until it opens. + // The trigger reads "Session: first fixture" before the menu first opens, + // while the option nodes themselves stay out of the renderer until then. subject: "Session:", subjectRole: "button", activate: "option:second fixture", opens: "option:first fixture", + closedContent: "option:first fixture", props: { placeholder: "Session" }, options: [ { value: "first", label: "first fixture" }, diff --git a/tests/qa-harness/generate-checks.ts b/tests/qa-harness/generate-checks.ts index f3ccbd91..3554357e 100644 --- a/tests/qa-harness/generate-checks.ts +++ b/tests/qa-harness/generate-checks.ts @@ -9,13 +9,14 @@ * * Run: bun run qa:checks */ + +import { mkdirSync, readdirSync, unlinkSync, writeFileSync } from "node:fs"; +import { join } from "node:path"; import { COMPONENTS, type ComponentSpec, validateComponentSpecs, } from "./components"; -import { mkdirSync, readdirSync, unlinkSync, writeFileSync } from "node:fs"; -import { join } from "node:path"; /* * `tests/ps-qa/` is where ps-qa looks when nobody passes `--checks`, and it is @@ -77,6 +78,110 @@ function checksFor(spec: ComponentSpec): string { }), ); + if (spec.geometry) { + records.push( + check({ + id: `"${spec.id}-first-frame-distinct"`, + group: `"${spec.id}"`, + what: `"${spec.component} paints its repeated parts at distinct positions before interaction"`, + open: surface, + hover: "None", + click: "None", + subject: `"${spec.geometry.family}"`, + expect: "DistinctPositions", + }), + ); + records.push( + check({ + id: `"${spec.id}-first-frame-contained"`, + group: `"${spec.id}"`, + what: `"${spec.component} keeps its repeated parts inside their composition before interaction"`, + open: surface, + hover: "None", + click: "None", + compare: `Some("${spec.geometry.container}")`, + subject: `"${spec.geometry.family}"`, + expect: "ContainedBy", + }), + ); + if (spec.geometry.changesOnHover) { + records.push( + check({ + id: `"${spec.id}-hover-feedback"`, + group: `"${spec.id}"`, + what: `"${spec.component} visibly responds when a rendered part is hovered"`, + open: surface, + hover: "None", + after_prepare_hover: `Some("${spec.geometry.changesOnHover}")`, + click: "None", + subject: `"${spec.geometry.container}"`, + expect: "PixelsChange", + }), + ); + } + if (spec.geometry.rightOf) { + records.push( + check({ + id: `"${spec.id}-desktop-parts-sit-beside"`, + group: `"${spec.id}"`, + what: `"${spec.component} places its desktop controls to the right of the primary visual"`, + open: surface, + hover: "None", + click: "None", + compare: `Some("${spec.geometry.rightOf.compare}")`, + subject: `"${spec.geometry.rightOf.subject}"`, + expect: "RightOf", + }), + ); + } + if (spec.geometry.centerAlignedY) { + records.push( + check({ + id: `"${spec.id}-desktop-parts-center-vertically"`, + group: `"${spec.id}"`, + what: `"${spec.component} vertically centers its primary visual against the desktop controls"`, + open: surface, + hover: "None", + click: "None", + compare: `Some("${spec.geometry.centerAlignedY.compare}")`, + subject: `"${spec.geometry.centerAlignedY.subject}"`, + expect: "CenterAlignedY", + }), + ); + } + } + + if (spec.measure) { + records.push( + check({ + id: `"${spec.id}-measures"`, + group: `"${spec.id}"`, + what: `"${spec.component} keeps its standard control geometry"`, + open: surface, + hover: "None", + click: "None", + expect_size: `Some("${spec.measure.size}")`, + subject: `"${spec.measure.subject}"`, + expect: "Measures", + }), + ); + } + + if (spec.contrast) { + records.push( + check({ + id: `"${spec.id}-contrast"`, + group: `"${spec.id}"`, + what: `"${spec.component} keeps its rendered controls distinguishable from their surface"`, + open: surface, + hover: "None", + click: "None", + subject: `"${spec.contrast}"`, + expect: "Contrast", + }), + ); + } + /* * The component itself produced something. * @@ -152,6 +257,21 @@ function checksFor(spec: ComponentSpec): string { } if (spec.kind === "value" || spec.kind === "mode") { + if (spec.closedContent) { + records.push( + check({ + id: `"${spec.id}-closed-content-is-absent"`, + group: `"${spec.id}"`, + what: `"the closed ${spec.component} does not retain its menu content in the renderer"`, + open: surface, + hover: "None", + click: "None", + subject: `"${spec.closedContent}"`, + expect: "Absent", + }), + ); + } + // 1. It opens. Addressed by `role:name` on a node that only exists once the // mode is open: a name-only check is satisfied by the trigger, which // paints whether or not anything happened. diff --git a/tests/qa-harness/generate-entries.ts b/tests/qa-harness/generate-entries.ts index 718feede..bf6e360f 100644 --- a/tests/qa-harness/generate-entries.ts +++ b/tests/qa-harness/generate-entries.ts @@ -159,6 +159,7 @@ const IMPORT_FORM: Record = { "MetalBorder": "named", "Navbar": "default", "Pagination": "default", + "PanelToggle": "named", "PasswordField": "named", "PasswordRequirements": "named", "Popover": "default", @@ -286,6 +287,7 @@ const MODULE_PATHS: Record = { "navbar": "components/navbar", "pwa-install-prompt": "components/immersive-landing", "pagination": "components/pagination", + "panel-toggle": "components/panel-toggle", "password-field": "components/password-field", "password-requirements": "components/password-requirements", "popover": "components/popover", diff --git a/tests/qa-harness/mount.tsx b/tests/qa-harness/mount.tsx index 23e21c2f..b1bfa28f 100644 --- a/tests/qa-harness/mount.tsx +++ b/tests/qa-harness/mount.tsx @@ -244,22 +244,30 @@ function TabsFixture() { function ComplexColorWheelFixture() { const [strength, setStrength] = createSignal(10); return ( - {}} - aria-label="Fixture colour" - adjustments={[ - { - id: "strength", - label: "Strength", - get value() { - return strength(); +
{ + queueMicrotask(() => { + document.getElementById("root")?.style.setProperty("zoom", "1.16"); + }); + }} + > + {}} + aria-label="Fixture colour" + adjustments={[ + { + id: "strength", + label: "Strength", + get value() { + return strength(); + }, + stops: [10, 20], + onChange: setStrength, }, - stops: [10, 20], - onChange: setStrength, - }, - ]} - /> + ]} + /> +
); } @@ -353,6 +361,43 @@ function PaginationFixture(props: { spec: ComponentSpec; under?: unknown }) { ); } +function PanelToggleFixture(props: { spec: ComponentSpec; under?: unknown }) { + const [expanded, setExpanded] = createSignal(true); + return ( + ) => JSX.Element) + | undefined + } + fallback={{props.spec.component} is not exported} + > + {(Component) => ( +
+ setExpanded((value) => !value)} + /> + + +
+ )} +
+ ); +} + function FieldFixture(props: { spec: ComponentSpec; under?: unknown }) { const [value, setValue] = createSignal(""); return ( @@ -528,6 +573,7 @@ const FIXTURES: Record< "live-chat-bubble": LiveChatBubbleFixture, "live-chat-panel": LiveChatPanelFixture, pagination: PaginationFixture, + "panel-toggle": PanelToggleFixture, popover: PopoverFixture, radio: ToggleFixture, select: SelectFixture, diff --git a/tests/qa-harness/run-all.sh b/tests/qa-harness/run-all.sh index c778428e..9f708bfc 100755 --- a/tests/qa-harness/run-all.sh +++ b/tests/qa-harness/run-all.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env zsh # # Drive every component and report a verdict per component. # @@ -19,8 +19,8 @@ set -uo pipefail # The harness directory itself, and the repository root above it. The script # reads its own files from HERE and the checks from the repository's # `tests/ps-qa`, so it needs both. -readonly HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -readonly ROOT="$(cd "$HERE/../.." && pwd)" +readonly HERE="${0:A:h}" +readonly ROOT="${HERE:h:h}" # Before either lookup below: `cargo install` puts both binaries here, and a # non-interactive shell does not read the profile that adds it. Resolving the # host first reported a freshly installed one as missing. @@ -47,8 +47,7 @@ ids=() if [[ $# -gt 0 ]]; then ids=("$@") else - # `mapfile` is bash 4; macOS ships 3.2, where it does not exist and the - # script died before running anything. + # Read one id at a time so the array works on the stock macOS shell. while IFS= read -r line; do ids+=("$line") done < <(grep -oE 'id: "[a-z0-9-]+"' "$HERE/components.ts" | sed 's/id: "//;s/"//') diff --git a/tests/tabs-horizontal-layout.test.ts b/tests/tabs-horizontal-layout.test.ts new file mode 100644 index 00000000..06c00496 --- /dev/null +++ b/tests/tabs-horizontal-layout.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from "bun:test"; + +const css = await Bun.file( + new URL("../src/components/tabs/Tabs.css", import.meta.url), +).text(); + +describe("Tabs horizontal layout", () => { + it("sizes horizontal tabs to their content instead of one list width each", () => { + const horizontal = + css.match( + /\.tabs__list\[data-orientation="horizontal"\] \.tabs__tab\s*\{([\s\S]*?)\}/, + )?.[1] ?? ""; + const vertical = + css.match( + /\.tabs__list\[data-orientation="vertical"\] \.tabs__tab\s*\{([\s\S]*?)\}/, + )?.[1] ?? ""; + + expect(horizontal).toContain("width: auto"); + expect(vertical).toContain("width: 100%"); + }); +}); diff --git a/tests/tabs-stable-id.test.ts b/tests/tabs-stable-id.test.ts new file mode 100644 index 00000000..79328916 --- /dev/null +++ b/tests/tabs-stable-id.test.ts @@ -0,0 +1,13 @@ +import { describe, expect, it } from "bun:test"; + +const layout = await Bun.file( + new URL("../src/components/tabs/Tabs.layout.tsx", import.meta.url), +).text(); + +describe("Tabs stable identity", () => { + it("derives tab and panel ids from a caller-supplied root id", () => { + expect(layout).toContain("const baseId = () => props.id || generatedId"); + expect(layout).toContain('`${baseId()}-tab-${String(key)}`'); + expect(layout).toContain('`${baseId()}-panel-${String(key)}`'); + }); +});