diff --git a/.vscode/settings.json b/.vscode/settings.json index e58cc1b..9acc450 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,14 +3,14 @@ "source.fixAll.eslint": "explicit" }, "eslint.validate": [ - "typescript", - "typescriptreact", + "css", + "html", "javascript", "json", "jsonc", + "typescript", + "typescriptreact", "yaml" ], - "files.associations": { - "*.css": "tailwindcss" - } + "css.customData": ["./.vscode/tailwind.json"] } diff --git a/.vscode/tailwind.json b/.vscode/tailwind.json new file mode 100644 index 0000000..3dcd253 --- /dev/null +++ b/.vscode/tailwind.json @@ -0,0 +1,14 @@ +{ + "atDirectives": [ + { + "name": "@theme", + "description": "Use the @theme directive to define your project's custom design tokens, like fonts, colors, and breakpoints.", + "references": [ + { + "name": "Tailwind's “Functions & Directives” documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#theme-directive" + } + ] + } + ] +} diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..0d16d8a --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,26 @@ +{ + "disable_ai": true, + "code_actions_on_format": { + "source.fixAll.eslint": true + }, + "languages": { + "CSS": { + "language_servers": ["eslint", "tailwindcss-language-server"] + }, + "HTML": { + "formatter": [{ "code_action": "source.fixAll.eslint" }], + "language_servers": ["eslint", "vscode-html-language-server"] + }, + "JSONC": { + "formatter": [{ "code_action": "source.fixAll.eslint" }], + "language_servers": ["eslint", "json-language-server"] + }, + "JSON": { + "formatter": [{ "code_action": "source.fixAll.eslint" }], + "language_servers": ["eslint", "json-language-server"] + }, + "YAML": { + "language_servers": ["eslint", "yaml-language-server"] + } + } +} diff --git a/env.d.ts b/env.d.ts index eea1472..c85e5b1 100644 --- a/env.d.ts +++ b/env.d.ts @@ -2,10 +2,10 @@ /// /// -interface ImportMetaEnv { - readonly BASE?: string; -} - interface ImportMeta { readonly env: ImportMetaEnv; } + +interface ImportMetaEnv { + readonly BASE?: string; +} diff --git a/eslint.config.ts b/eslint.config.ts index d898c4d..a8eae15 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -1,30 +1,21 @@ -import eslint from '@eslint/js'; +/* eslint-disable import-x/no-named-as-default-member */ import { includeIgnoreFile } from '@eslint/compat'; -import { defineConfig, globalIgnores } from 'eslint/config'; -import { configs as tseslintConfigs } from 'typescript-eslint'; +import css from '@eslint/css'; +import eslint from '@eslint/js'; +import html from '@html-eslint/eslint-plugin'; +import stylistic from '@stylistic/eslint-plugin'; +import { importX } from 'eslint-plugin-import-x'; +import jsonc from 'eslint-plugin-jsonc'; import jsxA11y from 'eslint-plugin-jsx-a11y'; -import solidTsConfig from 'eslint-plugin-solid/configs/typescript'; +import perfectionist from 'eslint-plugin-perfectionist'; import prettierRecommended from 'eslint-plugin-prettier/recommended'; -import jsonc from 'eslint-plugin-jsonc'; +import solidTsConfig from 'eslint-plugin-solid/configs/typescript'; import yml from 'eslint-plugin-yml'; -import { importX } from 'eslint-plugin-import-x'; -import stylistic from '@stylistic/eslint-plugin'; +import { defineConfig, globalIgnores } from 'eslint/config'; import { fileURLToPath } from 'node:url'; -import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript'; +import tseslint from 'typescript-eslint'; export default defineConfig( - eslint.configs.recommended, - tseslintConfigs.strictTypeChecked, - tseslintConfigs.stylisticTypeChecked, - jsxA11y.flatConfigs.strict, - // @ts-expect-error Argument of type is not assignable to parameter of type 'InfiniteArray'ts(2345) - solidTsConfig, - importX.flatConfigs.recommended, - importX.flatConfigs.typescript, - stylistic.configs.customize({ - semi: true, - }), - prettierRecommended, includeIgnoreFile(fileURLToPath(new URL('.gitignore', import.meta.url))), globalIgnores(['pnpm-lock.yaml']), { @@ -34,26 +25,76 @@ export default defineConfig( ecmaFeatures: { jsx: true, }, + extraFileExtensions: ['.css'], projectService: true, tsconfigRootDir: import.meta.dirname, }, }, + }, + { + extends: [ + eslint.configs.recommended, + tseslint.configs.strictTypeChecked, + tseslint.configs.stylisticTypeChecked, + jsxA11y.flatConfigs.strict, + // @ts-expect-error Types of property create are incompatible. (ts 2322) + solidTsConfig, + // @ts-expect-error Types of property languageOptions are incompatible. (ts 2322) + importX.flatConfigs.recommended, + // @ts-expect-error Types of property languageOptions are incompatible. (ts 2322) + importX.flatConfigs.typescript, + stylistic.configs.customize({ + jsx: false, + semi: true, + }), + perfectionist.configs['recommended-natural'], + prettierRecommended, + ], + files: ['**/*.{ts,tsx}'], rules: { '@typescript-eslint/restrict-template-expressions': [ 'error', { allowNumber: true }, ], }, - settings: { - 'import-x/resolver-next': [createTypeScriptImportResolver()], + }, + { + extends: [ + jsonc.configs['flat/recommended-with-jsonc'], + jsonc.configs['flat/prettier'], + prettierRecommended, + ], + files: ['**/*.json'], + }, + { + extends: [ + yml.configs['flat/recommended'], + yml.configs['flat/prettier'], + prettierRecommended, + ], + files: ['**/*.{yml,yaml}'], + }, + { + extends: ['css/recommended', prettierRecommended], + files: ['**/*.css'], + language: 'css/css', + plugins: { css }, + rules: { + 'css/no-invalid-at-rules': 'off', }, }, - jsonc.configs['flat/recommended-with-jsonc'], - jsonc.configs['flat/prettier'], - yml.configs['flat/recommended'], - yml.configs['flat/prettier'], { - files: ['**/*.{json,yml,yaml}'], - ...tseslintConfigs.disableTypeChecked, + extends: ['html/recommended'], + files: ['**/*.html'], + language: 'html/html', + plugins: { html }, + rules: { + 'html/attrs-newline': [ + 'error', + { closeStyle: 'newline', ifAttrsMoreThan: 3 }, + ], + 'html/indent': ['error', 2], + 'html/no-trailing-spaces': 'error', + }, }, ); diff --git a/index.html b/index.html index 5f26164..69cce57 100644 --- a/index.html +++ b/index.html @@ -1,10 +1,10 @@ - - + + Solid Clock - + diff --git a/package.json b/package.json index 006ebfc..fccab8e 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ }, "devDependencies": { "@eslint/compat": "2.0.0", + "@eslint/css": "0.14.1", "@eslint/js": "9.39.2", + "@html-eslint/eslint-plugin": "0.52.1", "@solidjs/testing-library": "0.8.10", "@stylistic/eslint-plugin": "5.7.0", "@tailwindcss/vite": "4.1.18", @@ -28,6 +30,7 @@ "eslint-plugin-import-x": "4.16.1", "eslint-plugin-jsonc": "2.21.0", "eslint-plugin-jsx-a11y": "6.10.2", + "eslint-plugin-perfectionist": "5.3.1", "eslint-plugin-prettier": "5.5.4", "eslint-plugin-solid": "0.14.5", "eslint-plugin-yml": "1.19.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c75651..e573b39 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,9 +15,15 @@ importers: '@eslint/compat': specifier: 2.0.0 version: 2.0.0(eslint@9.39.2(jiti@2.6.1)) + '@eslint/css': + specifier: 0.14.1 + version: 0.14.1 '@eslint/js': specifier: 9.39.2 version: 9.39.2 + '@html-eslint/eslint-plugin': + specifier: 0.52.1 + version: 0.52.1(eslint@9.39.2(jiti@2.6.1))(jiti@2.6.1) '@solidjs/testing-library': specifier: 0.8.10 version: 0.8.10(solid-js@1.9.10) @@ -57,6 +63,9 @@ importers: eslint-plugin-jsx-a11y: specifier: 6.10.2 version: 6.10.2(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-perfectionist: + specifier: 5.3.1 + version: 5.3.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-prettier: specifier: 5.5.4 version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.7.4) @@ -223,312 +232,156 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.2': - resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/android-arm64@0.25.9': resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.2': - resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm@0.25.9': resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.2': - resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-x64@0.25.9': resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.2': - resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/darwin-arm64@0.25.9': resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.2': - resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-x64@0.25.9': resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.2': - resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/freebsd-arm64@0.25.9': resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.2': - resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-x64@0.25.9': resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.2': - resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/linux-arm64@0.25.9': resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.2': - resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm@0.25.9': resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.2': - resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-ia32@0.25.9': resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.2': - resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-loong64@0.25.9': resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.2': - resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-mips64el@0.25.9': resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.2': - resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-ppc64@0.25.9': resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.2': - resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-riscv64@0.25.9': resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.2': - resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-s390x@0.25.9': resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.2': - resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-x64@0.25.9': resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.2': - resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/netbsd-arm64@0.25.9': resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.27.2': - resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-x64@0.25.9': resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.2': - resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/openbsd-arm64@0.25.9': resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.27.2': - resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-x64@0.25.9': resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.2': - resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openharmony-arm64@0.25.9': resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.27.2': - resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/sunos-x64@0.25.9': resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.2': - resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/win32-arm64@0.25.9': resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.2': - resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-ia32@0.25.9': resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.2': - resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-x64@0.25.9': resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.2': - resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -574,6 +427,14 @@ packages: resolution: {integrity: sha512-PRfWP+8FOldvbApr6xL7mNCw4cJcSTq4GA7tYbgq15mRb0kWKO/wEB2jr+uwjFH3sZvEZneZyCUGTxsv4Sahyw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@eslint/css-tree@3.6.8': + resolution: {integrity: sha512-s0f40zY7dlMp8i0Jf0u6l/aSswS0WRAgkhgETgiCJRcxIWb4S/Sp9uScKHWbkM3BnoFLbJbmOYk5AZUDFVxaLA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + '@eslint/css@0.14.1': + resolution: {integrity: sha512-NXiteSacmpaXqgyIW3+GcNzexXyfC0kd+gig6WTjD4A74kBGJeNx1tV0Hxa0v7x0+mnIyKfGPhGNs1uhRFdh+w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -590,6 +451,24 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@html-eslint/eslint-plugin@0.52.1': + resolution: {integrity: sha512-RaaSpP0hE/rYbssZZdlJjf0+CIVyWx9z/xj4KF5zHLvCeTYwJHAFb9x1/RvFRiMnWaME6ygtwMFYdHauahfvbA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.0.0 || ^9.0.0 + + '@html-eslint/parser@0.52.0': + resolution: {integrity: sha512-2r2NEPOK/Il8bVhAtc/Za0cxB8/CFaw6yZMpCk4yPJ8hHj/2lka14zBbBHDJAAVqmv+fiW9FrgcXKPmJY7CgAQ==} + + '@html-eslint/template-parser@0.52.0': + resolution: {integrity: sha512-0hw1Lh53MJbo+ePj9K8hShDHssi61UDb7s89tcZy9vZDIGUKfyUZxgax7/IkeBW/e9LAB/j/Pw+0Qkk34oKm2g==} + + '@html-eslint/template-syntax-parser@0.52.0': + resolution: {integrity: sha512-LADV0HWQVNaWck438WyE1C+WTLP80he69lSjudJY7Zir9YgL39gHzAFwbfyCFWbJfD2GjSbbGX88s1EgTZQRyQ==} + + '@html-eslint/types@0.52.0': + resolution: {integrity: sha512-g1qwSpUX5Xp5aw8a6U8fCnjEmiUuFfpHq6FKwyG0XRDMabBcc0LgbC4MArmHJVob77I6+kjM7LhTKqZhVslM/g==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1001,8 +880,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@20.19.27': - resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} + '@types/node@20.19.11': + resolution: {integrity: sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==} '@types/node@25.0.3': resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} @@ -1054,8 +933,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/tsconfig-utils@8.51.0': - resolution: {integrity: sha512-Qi5bSy/vuHeWyir2C8u/uqGMIlIDu8fuiYWv48ZGlZ/k+PRPHtaAu7erpc7p5bzw2WNNSniuxoMSO4Ar6V9OXw==} + '@typescript-eslint/tsconfig-utils@8.50.0': + resolution: {integrity: sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' @@ -1077,8 +956,8 @@ packages: resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.51.0': - resolution: {integrity: sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag==} + '@typescript-eslint/types@8.50.0': + resolution: {integrity: sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/types@8.52.0': @@ -1511,6 +1390,9 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-html-parser@0.3.1: + resolution: {integrity: sha512-YTEasG4xt7FEN4b6qJIPbFo/fzQ5kjRMEQ33QMqSXTvfXqAbC2rHxo32x2/1Rhq7Mlu6wI3MIpM5Kf2VHPXrUQ==} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} @@ -1535,11 +1417,6 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.27.2: - resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} - engines: {node: '>=18'} - hasBin: true - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1618,6 +1495,12 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + eslint-plugin-perfectionist@5.3.1: + resolution: {integrity: sha512-v8kAP8TarQYqDC4kxr343ZNi++/oOlBnmWovsUZpbJ7A/pq1VHGlgsf/fDh4CdEvEstzkrc8NLvoVKtfpsC4oA==} + engines: {node: ^20.0.0 || >=22.0.0} + peerDependencies: + eslint: '>=8.45.0' + eslint-plugin-prettier@5.5.4: resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -2176,6 +2059,9 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdn-data@2.23.0: + resolution: {integrity: sha512-786vq1+4079JSeu2XdcDjrhi/Ry7BWtjDl9WtGPWLiIHb2T66GvIVflZTBoSNZ5JqTtJGYEVMuFA/lbQlMOyDQ==} + merge-anything@5.1.7: resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} engines: {node: '>=12.13'} @@ -2219,6 +2105,10 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + natural-orderby@5.0.0: + resolution: {integrity: sha512-kKHJhxwpR/Okycz4HhQKKlhWe4ASEfPgkSWNmKFHd7+ezuQlxkA5cM3+XkBPvm1gmHen3w53qsYAv+8GwRrBlg==} + engines: {node: '>=18'} + node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -2738,8 +2628,8 @@ packages: vite: optional: true - vite@7.3.0: - resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==} + vite@7.1.4: + resolution: {integrity: sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3081,159 +2971,81 @@ snapshots: '@esbuild/aix-ppc64@0.25.9': optional: true - '@esbuild/aix-ppc64@0.27.2': - optional: true - '@esbuild/android-arm64@0.25.9': optional: true - '@esbuild/android-arm64@0.27.2': - optional: true - '@esbuild/android-arm@0.25.9': optional: true - '@esbuild/android-arm@0.27.2': - optional: true - '@esbuild/android-x64@0.25.9': optional: true - '@esbuild/android-x64@0.27.2': - optional: true - '@esbuild/darwin-arm64@0.25.9': optional: true - '@esbuild/darwin-arm64@0.27.2': - optional: true - '@esbuild/darwin-x64@0.25.9': optional: true - '@esbuild/darwin-x64@0.27.2': - optional: true - '@esbuild/freebsd-arm64@0.25.9': optional: true - '@esbuild/freebsd-arm64@0.27.2': - optional: true - '@esbuild/freebsd-x64@0.25.9': optional: true - '@esbuild/freebsd-x64@0.27.2': - optional: true - '@esbuild/linux-arm64@0.25.9': optional: true - '@esbuild/linux-arm64@0.27.2': - optional: true - '@esbuild/linux-arm@0.25.9': optional: true - '@esbuild/linux-arm@0.27.2': - optional: true - '@esbuild/linux-ia32@0.25.9': optional: true - '@esbuild/linux-ia32@0.27.2': - optional: true - '@esbuild/linux-loong64@0.25.9': optional: true - '@esbuild/linux-loong64@0.27.2': - optional: true - '@esbuild/linux-mips64el@0.25.9': optional: true - '@esbuild/linux-mips64el@0.27.2': - optional: true - '@esbuild/linux-ppc64@0.25.9': optional: true - '@esbuild/linux-ppc64@0.27.2': - optional: true - '@esbuild/linux-riscv64@0.25.9': optional: true - '@esbuild/linux-riscv64@0.27.2': - optional: true - '@esbuild/linux-s390x@0.25.9': optional: true - '@esbuild/linux-s390x@0.27.2': - optional: true - '@esbuild/linux-x64@0.25.9': optional: true - '@esbuild/linux-x64@0.27.2': - optional: true - '@esbuild/netbsd-arm64@0.25.9': optional: true - '@esbuild/netbsd-arm64@0.27.2': - optional: true - '@esbuild/netbsd-x64@0.25.9': optional: true - '@esbuild/netbsd-x64@0.27.2': - optional: true - '@esbuild/openbsd-arm64@0.25.9': optional: true - '@esbuild/openbsd-arm64@0.27.2': - optional: true - '@esbuild/openbsd-x64@0.25.9': optional: true - '@esbuild/openbsd-x64@0.27.2': - optional: true - '@esbuild/openharmony-arm64@0.25.9': optional: true - '@esbuild/openharmony-arm64@0.27.2': - optional: true - '@esbuild/sunos-x64@0.25.9': optional: true - '@esbuild/sunos-x64@0.27.2': - optional: true - '@esbuild/win32-arm64@0.25.9': optional: true - '@esbuild/win32-arm64@0.27.2': - optional: true - '@esbuild/win32-ia32@0.25.9': optional: true - '@esbuild/win32-ia32@0.27.2': - optional: true - '@esbuild/win32-x64@0.25.9': optional: true - '@esbuild/win32-x64@0.27.2': - optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2(jiti@2.6.1))': dependencies: eslint: 9.39.2(jiti@2.6.1) @@ -3274,6 +3086,17 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@eslint/css-tree@3.6.8': + dependencies: + mdn-data: 2.23.0 + source-map-js: 1.2.1 + + '@eslint/css@0.14.1': + dependencies: + '@eslint/core': 0.17.0 + '@eslint/css-tree': 3.6.8 + '@eslint/plugin-kit': 0.4.1 + '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 @@ -3297,6 +3120,51 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@html-eslint/eslint-plugin@0.52.1(eslint@9.39.2(jiti@2.6.1))(jiti@2.6.1)': + dependencies: + '@eslint/plugin-kit': 0.4.1 + '@html-eslint/parser': 0.52.0(jiti@2.6.1) + '@html-eslint/template-parser': 0.52.0(jiti@2.6.1) + '@html-eslint/template-syntax-parser': 0.52.0(jiti@2.6.1) + '@html-eslint/types': 0.52.0(jiti@2.6.1) + eslint: 9.39.2(jiti@2.6.1) + transitivePeerDependencies: + - jiti + - supports-color + + '@html-eslint/parser@0.52.0(jiti@2.6.1)': + dependencies: + '@html-eslint/template-syntax-parser': 0.52.0(jiti@2.6.1) + '@html-eslint/types': 0.52.0(jiti@2.6.1) + es-html-parser: 0.3.1 + transitivePeerDependencies: + - jiti + - supports-color + + '@html-eslint/template-parser@0.52.0(jiti@2.6.1)': + dependencies: + '@html-eslint/types': 0.52.0(jiti@2.6.1) + es-html-parser: 0.3.1 + transitivePeerDependencies: + - jiti + - supports-color + + '@html-eslint/template-syntax-parser@0.52.0(jiti@2.6.1)': + dependencies: + '@html-eslint/types': 0.52.0(jiti@2.6.1) + transitivePeerDependencies: + - jiti + - supports-color + + '@html-eslint/types@0.52.0(jiti@2.6.1)': + dependencies: + '@types/estree': 1.0.8 + es-html-parser: 0.3.1 + eslint: 9.39.2(jiti@2.6.1) + transitivePeerDependencies: + - jiti + - supports-color + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -3629,7 +3497,7 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@20.19.27': + '@types/node@20.19.11': dependencies: undici-types: 6.21.0 @@ -3673,8 +3541,8 @@ snapshots: '@typescript-eslint/project-service@8.42.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.51.0(typescript@5.9.3) - '@typescript-eslint/types': 8.51.0 + '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) + '@typescript-eslint/types': 8.50.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -3703,7 +3571,7 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.51.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.50.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -3725,7 +3593,7 @@ snapshots: '@typescript-eslint/types@8.42.0': {} - '@typescript-eslint/types@8.51.0': {} + '@typescript-eslint/types@8.50.0': {} '@typescript-eslint/types@8.52.0': {} @@ -3877,13 +3745,13 @@ snapshots: chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1))': + '@vitest/mocker@4.0.16(vite@7.1.4(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1))': dependencies: '@vitest/spy': 4.0.16 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1) + vite: 7.1.4(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1) '@vitest/pretty-format@4.0.16': dependencies: @@ -4217,6 +4085,8 @@ snapshots: es-errors@1.3.0: {} + es-html-parser@0.3.1: {} + es-module-lexer@1.7.0: {} es-object-atoms@1.1.1: @@ -4268,36 +4138,6 @@ snapshots: '@esbuild/win32-arm64': 0.25.9 '@esbuild/win32-ia32': 0.25.9 '@esbuild/win32-x64': 0.25.9 - optional: true - - esbuild@0.27.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.2 - '@esbuild/android-arm': 0.27.2 - '@esbuild/android-arm64': 0.27.2 - '@esbuild/android-x64': 0.27.2 - '@esbuild/darwin-arm64': 0.27.2 - '@esbuild/darwin-x64': 0.27.2 - '@esbuild/freebsd-arm64': 0.27.2 - '@esbuild/freebsd-x64': 0.27.2 - '@esbuild/linux-arm': 0.27.2 - '@esbuild/linux-arm64': 0.27.2 - '@esbuild/linux-ia32': 0.27.2 - '@esbuild/linux-loong64': 0.27.2 - '@esbuild/linux-mips64el': 0.27.2 - '@esbuild/linux-ppc64': 0.27.2 - '@esbuild/linux-riscv64': 0.27.2 - '@esbuild/linux-s390x': 0.27.2 - '@esbuild/linux-x64': 0.27.2 - '@esbuild/netbsd-arm64': 0.27.2 - '@esbuild/netbsd-x64': 0.27.2 - '@esbuild/openbsd-arm64': 0.27.2 - '@esbuild/openbsd-x64': 0.27.2 - '@esbuild/openharmony-arm64': 0.27.2 - '@esbuild/sunos-x64': 0.27.2 - '@esbuild/win32-arm64': 0.27.2 - '@esbuild/win32-ia32': 0.27.2 - '@esbuild/win32-x64': 0.27.2 escalade@3.2.0: {} @@ -4391,6 +4231,15 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 + eslint-plugin-perfectionist@5.3.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) + natural-orderby: 5.0.0 + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.7.4): dependencies: eslint: 9.39.2(jiti@2.6.1) @@ -4633,7 +4482,7 @@ snapshots: happy-dom@20.1.0: dependencies: - '@types/node': 20.19.27 + '@types/node': 20.19.11 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 whatwg-mimetype: 3.0.0 @@ -4959,6 +4808,8 @@ snapshots: math-intrinsics@1.1.0: {} + mdn-data@2.23.0: {} + merge-anything@5.1.7: dependencies: is-what: 4.1.16 @@ -4992,6 +4843,8 @@ snapshots: natural-compare@1.4.0: {} + natural-orderby@5.0.0: {} + node-releases@2.0.19: {} npm-run-path@6.0.0: @@ -5534,9 +5387,9 @@ snapshots: - supports-color - typescript - vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1): + vite@7.1.4(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1): dependencies: - esbuild: 0.27.2 + esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -5572,7 +5425,7 @@ snapshots: vitest@4.0.16(@types/node@25.0.3)(happy-dom@20.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1): dependencies: '@vitest/expect': 4.0.16 - '@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1)) + '@vitest/mocker': 4.0.16(vite@7.1.4(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1)) '@vitest/pretty-format': 4.0.16 '@vitest/runner': 4.0.16 '@vitest/snapshot': 4.0.16 @@ -5589,7 +5442,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1) + vite: 7.1.4(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.0.3 diff --git a/src/ClockFace.tsx b/src/ClockFace.tsx index 270143c..eda23b5 100644 --- a/src/ClockFace.tsx +++ b/src/ClockFace.tsx @@ -1,13 +1,13 @@ import { ClockHands } from '@/ClockHands'; -import { getTestId } from '@/utilities'; import { Graduations } from '@/Graduations'; +import { getTestId } from '@/utilities'; export const ClockFace = () => (
- + diff --git a/src/ClockHands.tsx b/src/ClockHands.tsx index fafa18b..e6ede84 100644 --- a/src/ClockHands.tsx +++ b/src/ClockHands.tsx @@ -1,4 +1,5 @@ import { createSignal, onCleanup } from 'solid-js'; + import { ClockLine as ClockHand } from '@/ClockLine'; import { hours, rotate, seconds } from '@/common'; import { getTestId } from '@/utilities'; @@ -26,25 +27,25 @@ export const ClockHands = () => { return ( <> ); diff --git a/src/ClockLine.tsx b/src/ClockLine.tsx index ff53101..26db97e 100644 --- a/src/ClockLine.tsx +++ b/src/ClockLine.tsx @@ -1,9 +1,9 @@ -import { mergeProps, splitProps, type JSX } from 'solid-js'; +import { type JSX, mergeProps, splitProps } from 'solid-js'; interface ClockLineProps extends JSX.LineSVGAttributes { + graduation?: true; length: number; limit?: number; - graduation?: boolean; } export const ClockLine = (props: ClockLineProps) => { @@ -12,9 +12,9 @@ export const ClockLine = (props: ClockLineProps) => { return ( ); diff --git a/src/Graduations.tsx b/src/Graduations.tsx index 501dae0..c735dc0 100644 --- a/src/Graduations.tsx +++ b/src/Graduations.tsx @@ -1,22 +1,19 @@ -import { For } from 'solid-js'; import { ClockLine as Graduation } from '@/ClockLine'; import { rotate, seconds } from '@/common'; -export const Graduations = () => ( - <> - index % 5 === 0)}> - {(isHour, index) => ( - - )} - - -); +// For not used because Graduations are static - minor optimization +export const Graduations = () => + [...Array(seconds).keys()] + .map<[boolean, number]>((index) => [index % 5 === 0, index]) + .map(([isHour, index]) => ( + + )); diff --git a/src/index.css b/src/index.css index abf9c92..2a75ac8 100644 --- a/src/index.css +++ b/src/index.css @@ -1,4 +1,4 @@ -@import "tailwindcss"; +@import 'tailwindcss'; @theme { --color-solid: #2c4f7c; diff --git a/src/index.tsx b/src/index.tsx index 4e891ed..067678c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,6 @@ import '@/index.css'; import { render } from 'solid-js/web'; + import { ClockFace } from '@/ClockFace'; render(() => , document.body); diff --git a/test/ClockFace.test.tsx b/test/ClockFace.test.tsx index 70f211d..7027ec2 100644 --- a/test/ClockFace.test.tsx +++ b/test/ClockFace.test.tsx @@ -1,5 +1,6 @@ -import { describe, expect, test } from 'vitest'; import { render, screen } from '@solidjs/testing-library'; +import { describe, expect, test } from 'vitest'; + import { ClockFace } from '@/ClockFace'; describe('', () => { diff --git a/test/index.test.ts b/test/index.test.ts index d6d6e6b..96fa01b 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,5 +1,5 @@ -import { describe, expect, test, vi } from 'vitest'; import { render } from 'solid-js/web'; +import { describe, expect, test, vi } from 'vitest'; describe('index', () => { test('renders without crashing', async () => { diff --git a/test/utilitiest.test.ts b/test/utilitiest.test.ts index db26435..94ea3bc 100644 --- a/test/utilitiest.test.ts +++ b/test/utilitiest.test.ts @@ -1,4 +1,5 @@ -import { afterAll, beforeAll, describe, expect, vi, test } from 'vitest'; +import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest'; + import { getTestId } from '@/utilities'; beforeAll(() => void vi.stubEnv('MODE', 'development')); diff --git a/vite.config.ts b/vite.config.ts index be49ec2..80861a5 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,10 +1,10 @@ /// +import tailwindcss from '@tailwindcss/vite'; import { defineConfig, loadEnv } from 'vite'; +import { checker } from 'vite-plugin-checker'; import solid from 'vite-plugin-solid'; -import tailwindcss from '@tailwindcss/vite'; import tsconfigPaths from 'vite-tsconfig-paths'; -import { checker } from 'vite-plugin-checker'; export default defineConfig(({ mode }) => ({ base: loadEnv(mode, process.cwd(), '')['BASE'] ?? '', @@ -13,18 +13,18 @@ export default defineConfig(({ mode }) => ({ tailwindcss(), solid(), checker({ - typescript: true, eslint: { lintCommand: 'eslint . --max-warnings 0', useFlatConfig: true, }, + typescript: true, }), ], - test: { - environment: 'happy-dom', - }, resolve: { conditions: ['development', 'browser'], tsconfigPaths: true, }, + test: { + environment: 'happy-dom', + }, }));