From 5e66eb83d156f5717f4605bb32530f322b2bcbda Mon Sep 17 00:00:00 2001 From: Thorsten Seyschab Date: Sun, 3 May 2026 14:37:35 +0200 Subject: [PATCH 1/9] chore: split eslint config files --- eslint.config.format-css.mjs | 20 +++ eslint.config.format-html.mjs | 20 +++ eslint.config.format-markdown.mjs | 43 +++++++ eslint.config.global-ignores.mjs | 13 ++ eslint.config.jsonc.mjs | 58 +++++++++ eslint.config.max-len-disabled.mjs | 11 ++ eslint.config.mjs | 186 ++++------------------------ eslint.config.nuxt.mjs | 22 ++++ eslint.config.old.mjs | 187 +++++++++++++++++++++++++++++ eslint.config.stylistic.mjs | 46 +++++++ eslint.config.tailwind.mjs | 48 ++++++++ eslint.config.trailing-spaces.mjs | 17 +++ eslint.config.vue.mjs | 34 ++++++ eslint.config.yaml.mjs | 24 ++++ eslint.tailwind-apply-order.mjs | 134 +++++++++++++++++++++ 15 files changed, 701 insertions(+), 162 deletions(-) create mode 100755 eslint.config.format-css.mjs create mode 100755 eslint.config.format-html.mjs create mode 100755 eslint.config.format-markdown.mjs create mode 100755 eslint.config.global-ignores.mjs create mode 100755 eslint.config.jsonc.mjs create mode 100755 eslint.config.max-len-disabled.mjs mode change 100644 => 100755 eslint.config.mjs create mode 100755 eslint.config.nuxt.mjs create mode 100644 eslint.config.old.mjs create mode 100755 eslint.config.stylistic.mjs create mode 100755 eslint.config.tailwind.mjs create mode 100755 eslint.config.trailing-spaces.mjs create mode 100755 eslint.config.vue.mjs create mode 100755 eslint.config.yaml.mjs create mode 100755 eslint.tailwind-apply-order.mjs diff --git a/eslint.config.format-css.mjs b/eslint.config.format-css.mjs new file mode 100755 index 0000000..f1e68fe --- /dev/null +++ b/eslint.config.format-css.mjs @@ -0,0 +1,20 @@ +import pluginFormat from 'eslint-plugin-format' + +/** @type {import('eslint').Linter.FlatConfig} */ +export const formatCssConfig = { // Prettier formatting for CSS + files: [ + '**/*.css', + ], + languageOptions: { + parser: pluginFormat.parserPlain, + }, + plugins: { + format: pluginFormat, + }, + rules: { + 'format/prettier': [ + 'error', + { parser: 'css' }, + ], + }, +} diff --git a/eslint.config.format-html.mjs b/eslint.config.format-html.mjs new file mode 100755 index 0000000..360ff57 --- /dev/null +++ b/eslint.config.format-html.mjs @@ -0,0 +1,20 @@ +import pluginFormat from 'eslint-plugin-format' + +/** @type {import('eslint').Linter.FlatConfig} */ +export const formatHtmlConfig = { // Prettier formatting for HTML + files: [ + '**/*.html', + ], + languageOptions: { + parser: pluginFormat.parserPlain, + }, + plugins: { + format: pluginFormat, + }, + rules: { + 'format/prettier': [ + 'error', + { parser: 'html' }, + ], + }, +} diff --git a/eslint.config.format-markdown.mjs b/eslint.config.format-markdown.mjs new file mode 100755 index 0000000..7ed535b --- /dev/null +++ b/eslint.config.format-markdown.mjs @@ -0,0 +1,43 @@ +import pluginStylistic from '@stylistic/eslint-plugin' +import pluginFormat from 'eslint-plugin-format' + +const markdownPlainProcessor = { + meta: { + name: 'format-markdown/plain-processor', + version: '1.0.0', + }, + preprocess(text) { + return [ + text, + ] + }, + postprocess(messageLists) { + return messageLists[0] ?? [] + }, + supportsAutofix: true, +} + +/** @type {import('eslint').Linter.FlatConfig} */ +export const formatMarkdownConfig = { // Stylistic formatting for Markdown + files: [ + '**/*.md', + ], + processor: markdownPlainProcessor, + languageOptions: { + parser: pluginFormat.parserPlain, + }, + plugins: { + '@stylistic': pluginStylistic, + }, + rules: { + '@stylistic/no-multiple-empty-lines': [ + 'error', + { + max: 1, + maxBOF: 0, + maxEOF: 0, + }, + ], + '@stylistic/no-trailing-spaces': 'error', + }, +} diff --git a/eslint.config.global-ignores.mjs b/eslint.config.global-ignores.mjs new file mode 100755 index 0000000..a3a5eec --- /dev/null +++ b/eslint.config.global-ignores.mjs @@ -0,0 +1,13 @@ +/** @type {import('eslint').Linter.FlatConfig} */ +export const globalIgnoresConfig = { + ignores: [ + '.nuxt/', + '.output/', + 'dist/', + '.data/', + 'server/database/migrations/**', + '.claude/skills/**/.skilld/', + '.claude/skills/skilld-lock.yaml', + 'pnpm-lock.yaml', + ], +} diff --git a/eslint.config.jsonc.mjs b/eslint.config.jsonc.mjs new file mode 100755 index 0000000..6cd4e25 --- /dev/null +++ b/eslint.config.jsonc.mjs @@ -0,0 +1,58 @@ +import * as pluginJsonc from 'eslint-plugin-jsonc' + +/** @type {import('eslint').Linter.FlatConfig[]} */ +export const jsonAndJsoncConfigs = [ + ...pluginJsonc.configs['flat/recommended-with-jsonc'], + { + files: [ + '**/*.json', + '**/*.jsonc', + ], + rules: { + 'jsonc/array-bracket-newline': [ + 'error', + { multiline: true, minItems: 1 }, + ], + 'jsonc/array-element-newline': [ + 'error', + 'always', + ], + 'jsonc/indent': [ + 'error', + 2, + ], + 'jsonc/comma-dangle': [ + 'error', + 'never', + ], + 'jsonc/sort-keys': 'error', + }, + }, + { + // Enforce trailing commas for editor and agent settings files + files: [ + '**/*.jsonc', + '.claude/settings.json', + '.vscode/extensions.json', + '.vscode/settings.json', + 'tsconfig.json', + ], + rules: { + 'jsonc/comma-dangle': [ + 'error', + 'always', + ], + }, + }, + { + // Disable JSONC sort-keys for files where key order is meaningful + files: [ + '.vscode/settings.json', + 'package.json', + 'tsconfig.json', + ], + rules: { + 'jsonc/sort-keys': 'off', + }, + }, +] diff --git a/eslint.config.max-len-disabled.mjs b/eslint.config.max-len-disabled.mjs new file mode 100755 index 0000000..8f23491 --- /dev/null +++ b/eslint.config.max-len-disabled.mjs @@ -0,0 +1,11 @@ +/** @type {import('eslint').Linter.FlatConfig} */ +export const maxLenDisabledConfig = { // Disable max-len in Markdown and YAML + files: [ + '**/*.md', + '**/*.yaml', + '**/*.yml', + ], + rules: { + '@stylistic/max-len': 'off', + }, +} diff --git a/eslint.config.mjs b/eslint.config.mjs old mode 100644 new mode 100755 index 9c5594a..029759b --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,167 +1,29 @@ // @ts-check -import pluginStylistic from '@stylistic/eslint-plugin' -import pluginFormat from 'eslint-plugin-format' -import * as pluginJsonc from 'eslint-plugin-jsonc' -import pluginTailwindCSS from 'eslint-plugin-tailwindcss' -import * as pluginYml from 'eslint-plugin-yml' - import withNuxt from './.nuxt/eslint.config.mjs' +import { formatCssConfig } from './eslint.config.format-css.mjs' +import { formatHtmlConfig } from './eslint.config.format-html.mjs' +import { formatMarkdownConfig } from './eslint.config.format-markdown.mjs' +import { globalIgnoresConfig } from './eslint.config.global-ignores.mjs' +import { jsonAndJsoncConfigs } from './eslint.config.jsonc.mjs' +import { maxLenDisabledConfig } from './eslint.config.max-len-disabled.mjs' +import { nuxtConfigSortingConfig } from './eslint.config.nuxt.mjs' +import { stylisticConfig } from './eslint.config.stylistic.mjs' +import { tailwindConfigs } from './eslint.config.tailwind.mjs' +import { trailingSpacesConfig } from './eslint.config.trailing-spaces.mjs' +import { vueConfig } from './eslint.config.vue.mjs' +import { yamlConfigs } from './eslint.config.yaml.mjs' export default withNuxt( - // ── Global ignores ────────────────────────────────────────────────────────── - { - ignores: [ - '.nuxt/', - '.output/', - 'dist/', - '.data/', - '.claude/skills/**/.skilld/', - 'pnpm-lock.yaml', - 'data/', - ], - }, - - // ── JSON / JSONC support ──────────────────────────────────────────────────── - ...pluginJsonc.configs['flat/recommended-with-jsonc'], - { - files: [ - '**/*.json', - '**/*.jsonc', - ], - rules: { - 'jsonc/sort-keys': 'error', - }, - }, - { - // Disable JSONC sort-keys for files where key order is meaningful - files: [ - '.vscode/settings.json', - 'package.json', - 'tsconfig.json', - ], - rules: { - 'jsonc/sort-keys': 'off', - }, - }, - - // ── YAML support ──────────────────────────────────────────────────────────── - ...pluginYml.configs['flat/standard'], - - // ── Prettier formatting for CSS ───────────────────────────────────────────── - { - files: [ - '**/*.css', - ], - languageOptions: { - parser: pluginFormat.parserPlain, - }, - plugins: { - format: pluginFormat, - }, - rules: { - 'format/prettier': ['error', { parser: 'css' }], - }, - }, - - // ── Prettier formatting for HTML ──────────────────────────────────────────── - { - files: [ - '**/*.html', - ], - languageOptions: { - parser: pluginFormat.parserPlain, - }, - plugins: { - format: pluginFormat, - }, - rules: { - 'format/prettier': ['error', { parser: 'html' }], - }, - }, - - // ── Prettier formatting for Markdown ──────────────────────────────────────── - { - files: [ - '**/*.md', - ], - languageOptions: { - parser: pluginFormat.parserPlain, - }, - plugins: { - format: pluginFormat, - }, - rules: { - 'format/prettier': ['error', { parser: 'markdown' }], - }, - }, - - // ── Stylistic overrides ───────────────────────────────────────────────────── - { - files: [ - '**/*.js', - '**/*.mjs', - '**/*.ts', - '**/*.vue', - ], - plugins: { - '@stylistic': pluginStylistic, - }, - rules: { - '@stylistic/max-len': ['error', { - code: 120, - // Ignore SVG path d attributes and inline data-URI background images - ignorePattern: String.raw`^\s*d="|url\(["']data:image`, - }], - }, - }, - - // ── Vue rules ─────────────────────────────────────────────────────────────── - { - files: [ - '**/*.vue', - ], - rules: { - 'vue/attributes-order': ['error', { - alphabetical: true, - }], - 'vue/max-attributes-per-line': ['error', { - multiline: 1, - singleline: 3, - }], - }, - }, - - // ── Tailwind CSS class sorting ────────────────────────────────────────────── - // @ts-expect-error - pluginTailwindCSS types diverge from ESLint flat config Plugin type - { - files: [ - '**/*.{js,mjs,ts,vue}', - ], - plugins: { - tailwindcss: pluginTailwindCSS, - }, - rules: { - 'tailwindcss/classnames-order': 'error', - 'tailwindcss/no-custom-classname': 'off', - }, - settings: { - tailwindcss: { - // TW v3 without a tailwind.config.js - use empty object to suppress resolve warnings - config: {}, - cssFiles: ['app/assets/css/main.css'], - }, - }, - }, - - // ── Disable max-len in Markdown & YAML ────────────────────────────────────── - { - files: [ - '**/*.md', - '**/*.yaml', - '**/*.yml', - ], - rules: { - '@stylistic/max-len': 'off', - }, - }, + globalIgnoresConfig, // Global ignores + ...jsonAndJsoncConfigs, // JSON / JSONC support + trailingSpacesConfig, // Trailing spaces for JSON, JSONC, and YAML + ...yamlConfigs, // YAML support + formatCssConfig, // Prettier formatting for CSS + formatHtmlConfig, // Prettier formatting for HTML + formatMarkdownConfig, // Stylistic formatting for Markdown + stylisticConfig, // Stylistic overrides + ...tailwindConfigs, // Tailwind CSS class sorting + nuxtConfigSortingConfig, // Nuxt config object sorting + vueConfig, // Vue rules + maxLenDisabledConfig, // Disable max-len in Markdown and YAML ) diff --git a/eslint.config.nuxt.mjs b/eslint.config.nuxt.mjs new file mode 100755 index 0000000..0fa9924 --- /dev/null +++ b/eslint.config.nuxt.mjs @@ -0,0 +1,22 @@ +import pluginPerfectionist from 'eslint-plugin-perfectionist' + +/** @type {import('eslint').Linter.FlatConfig} */ +export const nuxtConfigSortingConfig = { + files: [ + 'nuxt.config.ts', + ], + plugins: { + perfectionist: pluginPerfectionist, + }, + rules: { + 'nuxt/nuxt-config-keys-order': 'off', + 'perfectionist/sort-objects': [ + 'error', + { + order: 'asc', + partitionByComment: true, + type: 'alphabetical', + }, + ], + }, +} diff --git a/eslint.config.old.mjs b/eslint.config.old.mjs new file mode 100644 index 0000000..8c804a3 --- /dev/null +++ b/eslint.config.old.mjs @@ -0,0 +1,187 @@ +// @ts-check +import pluginStylistic from '@stylistic/eslint-plugin' +import pluginFormat from 'eslint-plugin-format' +import * as pluginJsonc from 'eslint-plugin-jsonc' +import pluginTailwindCSS from 'eslint-plugin-tailwindcss' +import * as pluginYml from 'eslint-plugin-yml' + +import withNuxt from './.nuxt/eslint.config.mjs' + +export default withNuxt( + // ── Global ignores ────────────────────────────────────────────────────────── + { + ignores: [ + '.nuxt/', + '.output/', + 'dist/', + '.data/', + '.claude/skills/**/.skilld/', + 'pnpm-lock.yaml', + 'data/', + ], + }, + + // ── JSON / JSONC support ──────────────────────────────────────────────────── + ...pluginJsonc.configs['flat/recommended-with-jsonc'], + { + files: [ + '**/*.json', + '**/*.jsonc', + ], + rules: { + 'jsonc/sort-keys': 'error', + }, + }, + { + // Disable JSONC sort-keys for files where key order is meaningful + files: [ + '.vscode/settings.json', + 'package.json', + 'tsconfig.json', + ], + rules: { + 'jsonc/sort-keys': 'off', + }, + }, + + // ── YAML support ──────────────────────────────────────────────────────────── + ...pluginYml.configs['flat/standard'], + + // ── Prettier formatting for CSS ───────────────────────────────────────────── + { + files: [ + '**/*.css', + ], + languageOptions: { + parser: pluginFormat.parserPlain, + }, + plugins: { + format: pluginFormat, + }, + rules: { + 'format/prettier': [ + 'error', + { parser: 'css' }, + ], + }, + }, + + // ── Prettier formatting for HTML ──────────────────────────────────────────── + { + files: [ + '**/*.html', + ], + languageOptions: { + parser: pluginFormat.parserPlain, + }, + plugins: { + format: pluginFormat, + }, + rules: { + 'format/prettier': [ + 'error', + { parser: 'html' }, + ], + }, + }, + + // ── Prettier formatting for Markdown ──────────────────────────────────────── + { + files: [ + '**/*.md', + ], + languageOptions: { + parser: pluginFormat.parserPlain, + }, + plugins: { + format: pluginFormat, + }, + rules: { + 'format/prettier': [ + 'error', + { parser: 'markdown' }, + ], + }, + }, + + // ── Stylistic overrides ───────────────────────────────────────────────────── + { + files: [ + '**/*.js', + '**/*.mjs', + '**/*.ts', + '**/*.vue', + ], + plugins: { + '@stylistic': pluginStylistic, + }, + rules: { + '@stylistic/max-len': [ + 'error', + { + code: 120, + // Ignore SVG path d attributes and inline data-URI background images + ignorePattern: String.raw`^\s*d="|url\(["']data:image`, + }, + ], + }, + }, + + // ── Vue rules ─────────────────────────────────────────────────────────────── + { + files: [ + '**/*.vue', + ], + rules: { + 'vue/attributes-order': [ + 'error', + { + alphabetical: true, + }, + ], + 'vue/max-attributes-per-line': [ + 'error', + { + multiline: 1, + singleline: 3, + }, + ], + }, + }, + + // ── Tailwind CSS class sorting ────────────────────────────────────────────── + // @ts-expect-error - pluginTailwindCSS types diverge from ESLint flat config Plugin type + { + files: [ + '**/*.{js,mjs,ts,vue}', + ], + plugins: { + tailwindcss: pluginTailwindCSS, + }, + rules: { + 'tailwindcss/classnames-order': 'error', + 'tailwindcss/no-custom-classname': 'off', + }, + settings: { + tailwindcss: { + // TW v3 without a tailwind.config.js - use empty object to suppress resolve warnings + config: {}, + cssFiles: [ + 'app/assets/css/main.css', + ], + }, + }, + }, + + // ── Disable max-len in Markdown & YAML ────────────────────────────────────── + { + files: [ + '**/*.md', + '**/*.yaml', + '**/*.yml', + ], + rules: { + '@stylistic/max-len': 'off', + }, + }, +) diff --git a/eslint.config.stylistic.mjs b/eslint.config.stylistic.mjs new file mode 100755 index 0000000..77d5734 --- /dev/null +++ b/eslint.config.stylistic.mjs @@ -0,0 +1,46 @@ +import pluginStylistic from '@stylistic/eslint-plugin' + +/** @type {import('eslint').Linter.FlatConfig} */ +export const stylisticConfig = { // Stylistic overrides + files: [ + '**/*.js', + '**/*.mjs', + '**/*.ts', + '**/*.vue', + ], + plugins: { + '@stylistic': pluginStylistic, + }, + rules: { + '@stylistic/array-bracket-newline': [ + 'error', + { multiline: true, minItems: 1 }, + ], + '@stylistic/array-element-newline': [ + 'error', + 'always', + ], + '@stylistic/comma-dangle': [ + 'error', + 'always-multiline', + ], + '@stylistic/indent': [ + 'error', + 2, + ], + '@stylistic/no-trailing-spaces': 'error', + '@stylistic/quotes': [ + 'error', + 'single', + { avoidEscape: true }, + ], + '@stylistic/max-len': [ + 'error', + { + code: 120, + // Ignore SVG path d attributes and inline data-URI background images + ignorePattern: String.raw`^\s*d="|url\(["']data:image`, + }, + ], + }, +} diff --git a/eslint.config.tailwind.mjs b/eslint.config.tailwind.mjs new file mode 100755 index 0000000..5a763e2 --- /dev/null +++ b/eslint.config.tailwind.mjs @@ -0,0 +1,48 @@ +import { dirname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import pluginTailwindCSS from 'eslint-plugin-tailwindcss' +import tailwindApplyOrderPlugin from './eslint.tailwind-apply-order.mjs' + +const __dirname = dirname(fileURLToPath(import.meta.url)) +const tailwindCssEntryPath = resolve(__dirname, 'app/assets/css/main.css') +const tailwindConfig = {} + +/** @type {import('eslint').Linter.FlatConfig[]} */ +export const tailwindConfigs = [ + ...pluginTailwindCSS.configs['flat/recommended'], + { + settings: { + tailwindcss: { + config: tailwindConfig, + cssFiles: [ + tailwindCssEntryPath, + ], + }, + }, + }, + { + files: [ + '**/*.{js,mjs,ts,vue}', + ], + rules: { + 'tailwindcss/classnames-order': 'error', + 'tailwindcss/no-custom-classname': 'off', + }, + }, + { + files: [ + '**/*.css', + ], + plugins: { + 'tailwindcss-local': tailwindApplyOrderPlugin, + }, + rules: { + 'tailwindcss-local/apply-classnames-order': [ + 'error', + { + config: tailwindConfig, + }, + ], + }, + }, +] diff --git a/eslint.config.trailing-spaces.mjs b/eslint.config.trailing-spaces.mjs new file mode 100755 index 0000000..4aa8f0c --- /dev/null +++ b/eslint.config.trailing-spaces.mjs @@ -0,0 +1,17 @@ +import pluginStylistic from '@stylistic/eslint-plugin' + +/** @type {import('eslint').Linter.FlatConfig} */ +export const trailingSpacesConfig = { // Trailing spaces for JSON/JSONC/YAML + files: [ + '**/*.json', + '**/*.jsonc', + '**/*.yaml', + '**/*.yml', + ], + plugins: { + '@stylistic': pluginStylistic, + }, + rules: { + '@stylistic/no-trailing-spaces': 'error', + }, +} diff --git a/eslint.config.vue.mjs b/eslint.config.vue.mjs new file mode 100755 index 0000000..47a29be --- /dev/null +++ b/eslint.config.vue.mjs @@ -0,0 +1,34 @@ +/** @type {import('eslint').Linter.FlatConfig} */ +export const vueConfig = { + files: [ + '**/*.vue', + ], + rules: { + 'vue/html-indent': [ + 'error', + 2, + ], + 'vue/script-indent': [ + 'error', + 2, + { baseIndent: 0 }, + ], + 'vue/html-quotes': [ + 'error', + 'double', + ], + 'vue/attributes-order': [ + 'error', + { + alphabetical: true, + }, + ], + 'vue/max-attributes-per-line': [ + 'error', + { + multiline: 1, + singleline: 3, + }, + ], + }, +} diff --git a/eslint.config.yaml.mjs b/eslint.config.yaml.mjs new file mode 100755 index 0000000..b990493 --- /dev/null +++ b/eslint.config.yaml.mjs @@ -0,0 +1,24 @@ +import * as pluginYml from 'eslint-plugin-yml' + +/** @type {import('eslint').Linter.FlatConfig[]} */ +export const yamlConfigs = [ + ...pluginYml.configs['flat/standard'], + { + files: [ + '**/*.yaml', + '**/*.yml', + ], + rules: { + 'yml/sort-keys': 'error', + }, + }, + { + files: [ + '.coderabbit.yml', + '.github/workflows/*.yml', + ], + rules: { + 'yml/sort-keys': 'off', + }, + }, +] diff --git a/eslint.tailwind-apply-order.mjs b/eslint.tailwind-apply-order.mjs new file mode 100755 index 0000000..2433530 --- /dev/null +++ b/eslint.tailwind-apply-order.mjs @@ -0,0 +1,134 @@ +import { createRequire } from 'node:module' + +const require = createRequire(import.meta.url) +const { getSortedClassNames } = require('eslint-plugin-tailwindcss/lib/util/tailwindAPI') + +/** + * Custom local ESLint plugin for this repository. + * + * Why this exists: + * - `eslint-plugin-tailwindcss` sorts class names in JS/TSX/Vue class attributes. + * - It does not validate `@apply` token order inside plain CSS declarations. + * + * What it does: + * - Finds `@apply ...;` directives in CSS files. + * - Sorts tokens with the same Tailwind ordering utility used by + * `eslint-plugin-tailwindcss` (`getSortedClassNames`). + * - Reports invalid order and provides an autofix. + */ +const ruleName = 'apply-classnames-order' + +/** @type {import('eslint').Rule.RuleModule} */ +const applyClassnamesOrderRule = { + meta: { + type: 'layout', + docs: { + description: 'Enforce Tailwind class order in CSS @apply directives', + }, + fixable: 'code', + schema: [ + { + type: 'object', + properties: { + config: { + type: [ + 'string', + 'object', + ], + }, + }, + additionalProperties: false, + }, + ], + messages: { + invalidOrder: 'Invalid Tailwind @apply class order', + }, + }, + create(context) { + const sourceCode = context.sourceCode ?? context.getSourceCode() + const options = context.options[0] ?? {} + const twConfig = options.config + + return { + Program(node) { + const text = sourceCode.getText() + const applyRegex = /@apply(\s+)([^;]+);/g + const blockCommentRegex = /\/\*[\s\S]*?\*\//g + const blockCommentRanges = [] + + for ( + let commentMatch = blockCommentRegex.exec(text); + commentMatch !== null; + commentMatch = blockCommentRegex.exec(text) + ) { + blockCommentRanges.push([ + commentMatch.index, + commentMatch.index + commentMatch[0].length, + ]) + } + + const isInsideBlockComment = index => + blockCommentRanges.some(([ + start, + end, + ]) => index >= start && index < end) + + for (let match = applyRegex.exec(text); match !== null; match = applyRegex.exec(text)) { + if (isInsideBlockComment(match.index)) { + continue + } + + const rawClasses = match[2] + const trimmedClasses = rawClasses.trim() + + if (!trimmedClasses) { + continue + } + + const classNames = trimmedClasses.split(/\s+/) + + if (classNames.length <= 1) { + continue + } + + const orderedClassNames = getSortedClassNames(twConfig, classNames) + const hasSameOrder + = orderedClassNames.length === classNames.length + && orderedClassNames.every((className, index) => className === classNames[index]) + + if (hasSameOrder) { + continue + } + + const expectedClassNames = orderedClassNames.join(' ') + const classValueStart = match.index + match[0].indexOf(rawClasses) + const classValueEnd = classValueStart + rawClasses.length + const leadingWhitespace = rawClasses.match(/^\s*/)?.[0] ?? '' + const trailingWhitespace = rawClasses.match(/\s*$/)?.[0] ?? '' + + context.report({ + node, + messageId: 'invalidOrder', + loc: { + start: sourceCode.getLocFromIndex(classValueStart), + end: sourceCode.getLocFromIndex(classValueEnd), + }, + fix: fixer => fixer.replaceTextRange( + [ + classValueStart, + classValueEnd, + ], + `${leadingWhitespace}${expectedClassNames}${trailingWhitespace}`, + ), + }) + } + }, + } + }, +} + +export default { + rules: { + [ruleName]: applyClassnamesOrderRule, + }, +} From 1062eabc080fac616d85777d573e19550117a106 Mon Sep 17 00:00:00 2001 From: Thorsten Seyschab Date: Sun, 3 May 2026 14:37:35 +0200 Subject: [PATCH 2/9] chore: add eslint workflow dependencies --- package.json | 84 +++--- pnpm-lock.yaml | 704 ++++++++++++++++++++++++++++++++++---------- pnpm-workspace.yaml | 3 + 3 files changed, 602 insertions(+), 189 deletions(-) diff --git a/package.json b/package.json index 26f3cd0..83e589e 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,12 @@ { "name": "@todde.tv/stage-flow-tools", - "type": "module", "version": "1.0.0-rc.0", - "packageManager": "pnpm@10.33.0", "description": "Real-time quiz and interaction tool for live presentations. Features include admin-controlled quiz flow, live results, and instant audience participation. Boost engagement on stage - at conferences, sessions, and workshops.", + "license": "SEE LICENSE IN LICENSE.md", "author": "Thorsten Seyschab (https://todde.tv/)", "contributors": [ - { - "name": "Thorsten Seyschab", - "email": "hello@todde.tv", - "url": "https://todde.tv/" - } + "Thorsten Seyschab (https://todde.tv/)" ], - "license": "SEE LICENSE IN LICENSE.md", "homepage": "https://todde.tv/", "repository": { "type": "git", @@ -21,43 +15,27 @@ "bugs": { "url": "https://github.com/toddeTV/stage-flow-tools/issues" }, - "keywords": [ - "quiz", - "live-interaction", - "audience-participation", - "presentation-tool", - "conference-tool", - "workshop", - "web-app", - "voting", - "results-display", - "engagement", - "educational", - "stage-flow", - "presenter", - "interactive" - ], - "engines": { - "node": "24.x", - "pnpm": "10.x" - }, + "type": "module", "scripts": { "build:ssg": "cross-env NODE_OPTIONS=--max-old-space-size=8192 nuxt generate", "build:ssr": "cross-env NODE_OPTIONS=--max-old-space-size=8192 nuxt build", "dev": "nuxt dev", "dev:preset": "nuxt dev --port 3000 --public", - "fix:lint": "run-s \"test:lint-format --fix\"", + "fix": "vp run fix:lint-format && vp run fix:package-json", + "fix:lint-format": "vp exec eslint . --fix", + "fix:package-json": "vp exec prettier-package-json --write package.json", + "postinstall": "nuxt prepare", + "install:clean": "vp install --frozen-lockfile --prefer-offline", "nuxi": "nuxi", "nuxt": "nuxt", + "prepare": "vp config --hooks-only", "preview": "nuxt preview", "preview:ssg": "vp dlx serve .output/public", "preview:ssr": "nuxt preview", - "postinstall": "nuxt prepare", - "install:clean": "vp install --frozen-lockfile --prefer-offline", - "test": "run-s test:*", - "test:lint-format": "eslint .", - "test:type": "nuxt typecheck", - "prepare": "vp config --hooks-only" + "test": "concurrently --names \"test:lint-format,test:package-json,test:type\" \"vp exec eslint .\" \"vp exec prettier-package-json --list-different package.json\" \"nuxt typecheck\"", + "test:lint-format": "vp exec eslint .", + "test:package-json": "vp exec prettier-package-json --list-different package.json", + "test:type": "nuxt typecheck" }, "dependencies": { "nuxt": "~4.1.2" @@ -69,21 +47,45 @@ "@paralleldrive/cuid2": "~2.2.2", "@vueuse/core": "~13.9.0", "@vueuse/nuxt": "~13.9.0", + "concurrently": "~9.2.1", "cross-env": "~10.1.0", "crossws": "~0.4.1", - "eslint": "~10.0.3", + "eslint": "catalog:", "eslint-plugin-format": "~2.0.1", - "eslint-plugin-jsonc": "~3.1.1", - "eslint-plugin-tailwindcss": "~3.18.2", + "eslint-plugin-jsonc": "~3.1.2", + "eslint-plugin-perfectionist": "~5.9.0", + "eslint-plugin-tailwindcss": "~4.0.0-alpha.2", "eslint-plugin-yml": "~3.3.1", "jose": "~6.2.1", "npm-run-all2": "~8.0.4", "nuxi": "~3.28.0", "prettier": "~3.8.1", + "prettier-package-json": "~2.8.0", "typescript": "~5.9.3", + "vite-plus": "catalog:", "vue": "~3.5.22", "vue-router": "~4.5.1", - "vue-tsc": "~3.1.0", - "vite-plus": "catalog:" - } + "vue-tsc": "~3.1.0" + }, + "keywords": [ + "audience-participation", + "conference-tool", + "educational", + "engagement", + "interactive", + "live-interaction", + "presentation-tool", + "presenter", + "quiz", + "results-display", + "stage-flow", + "voting", + "web-app", + "workshop" + ], + "engines": { + "node": "24.x", + "pnpm": "10.x" + }, + "packageManager": "pnpm@10.33.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf05fc1..e5ed00e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,9 @@ settings: catalogs: default: + eslint: + specifier: ~9.39.4 + version: 9.39.4 vite-plus: specifier: ~0.1.19 version: 0.1.20 @@ -21,14 +24,14 @@ importers: dependencies: nuxt: specifier: ~4.1.2 - version: 4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@10.0.3(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2) + version: 4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.4(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2) devDependencies: '@nuxt/eslint': specifier: ~1.15.2 - version: 1.15.2(@typescript-eslint/utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(magicast@0.5.2)(srvx@0.11.9)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2)) + version: 1.15.2(@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-format@2.0.1(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1))(magicast@0.5.2)(srvx@0.11.9)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2)) '@nuxtjs/i18n': specifier: ^10.1.1 - version: 10.2.3(@vue/compiler-dom@3.5.30)(db0@0.3.4)(eslint@10.0.3(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(rollup@4.59.0)(srvx@0.11.9)(vue@3.5.30(typescript@5.9.3)) + version: 10.2.3(@vue/compiler-dom@3.5.30)(db0@0.3.4)(eslint@9.39.4(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(rollup@4.59.0)(srvx@0.11.9)(vue@3.5.30(typescript@5.9.3)) '@nuxtjs/tailwindcss': specifier: ~6.14.0 version: 6.14.0(magicast@0.5.2)(srvx@0.11.9)(yaml@2.8.2) @@ -40,7 +43,10 @@ importers: version: 13.9.0(vue@3.5.30(typescript@5.9.3)) '@vueuse/nuxt': specifier: ~13.9.0 - version: 13.9.0(magicast@0.5.2)(nuxt@4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@10.0.3(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2))(vue@3.5.30(typescript@5.9.3)) + version: 13.9.0(magicast@0.5.2)(nuxt@4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.4(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2))(vue@3.5.30(typescript@5.9.3)) + concurrently: + specifier: ~9.2.1 + version: 9.2.1 cross-env: specifier: ~10.1.0 version: 10.1.0 @@ -48,20 +54,23 @@ importers: specifier: 0.4.1 version: 0.4.1(srvx@0.11.9) eslint: - specifier: ~10.0.3 - version: 10.0.3(jiti@2.6.1) + specifier: 'catalog:' + version: 9.39.4(jiti@2.6.1) eslint-plugin-format: specifier: ~2.0.1 - version: 2.0.1(eslint@10.0.3(jiti@2.6.1)) + version: 2.0.1(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-jsonc: - specifier: ~3.1.1 - version: 3.1.1(eslint@10.0.3(jiti@2.6.1)) + specifier: ~3.1.2 + version: 3.1.2(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-perfectionist: + specifier: ~5.9.0 + version: 5.9.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-tailwindcss: - specifier: ~3.18.2 - version: 3.18.2(tailwindcss@3.4.19(yaml@2.8.2)) + specifier: ~4.0.0-alpha.2 + version: 4.0.0-beta.0(tailwindcss@3.4.19(yaml@2.8.2)) eslint-plugin-yml: specifier: ~3.3.1 - version: 3.3.1(eslint@10.0.3(jiti@2.6.1)) + version: 3.3.1(eslint@9.39.4(jiti@2.6.1)) jose: specifier: ~6.2.1 version: 6.2.1 @@ -74,6 +83,9 @@ importers: prettier: specifier: ~3.8.1 version: 3.8.1 + prettier-package-json: + specifier: ~2.8.0 + version: 2.8.0 typescript: specifier: ~5.9.3 version: 5.9.3 @@ -619,9 +631,13 @@ packages: eslint: optional: true - '@eslint/config-array@0.23.3': - resolution: {integrity: sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/config-helpers@0.5.3': resolution: {integrity: sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==} @@ -633,17 +649,29 @@ packages: peerDependencies: eslint: ^8.50.0 || ^9.0.0 || ^10.0.0 + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@1.1.1': resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@9.39.4': resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@3.0.3': - resolution: {integrity: sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/plugin-kit@0.6.1': resolution: {integrity: sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==} @@ -2183,6 +2211,12 @@ packages: '@types/node@25.4.0': resolution: {integrity: sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==} + '@types/parse-author@2.0.3': + resolution: {integrity: sha512-pgRW2K/GVQoogylrGJXDl7PBLW9A6T4OOc9Hy9MLT5f7vgufK2GQ8FcfAbjFHR5HjcN9ByzuCczAORk49REqoA==} + + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -2210,16 +2244,32 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/project-service@8.59.1': + resolution: {integrity: sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/scope-manager@8.57.0': resolution: {integrity: sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.59.1': + resolution: {integrity: sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.57.0': resolution: {integrity: sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/tsconfig-utils@8.59.1': + resolution: {integrity: sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/type-utils@8.57.0': resolution: {integrity: sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2231,12 +2281,22 @@ packages: resolution: {integrity: sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.59.1': + resolution: {integrity: sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.57.0': resolution: {integrity: sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/typescript-estree@8.59.1': + resolution: {integrity: sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.57.0': resolution: {integrity: sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2244,10 +2304,21 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/utils@8.59.1': + resolution: {integrity: sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/visitor-keys@8.57.0': resolution: {integrity: sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.59.1': + resolution: {integrity: sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@unhead/vue@2.1.12': resolution: {integrity: sha512-zEWqg0nZM8acpuTZE40wkeUl8AhIe0tU0OkilVi1D4fmVjACrwoh5HP6aNqJ8kUnKsoy6D+R3Vi/O+fmdNGO7g==} peerDependencies: @@ -2744,6 +2815,10 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} + author-regex@1.0.0: + resolution: {integrity: sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==} + engines: {node: '>=0.8'} + autoprefixer@10.4.27: resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} engines: {node: ^10 || ^12 || >=14} @@ -2896,6 +2971,10 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -3001,6 +3080,11 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + concurrently@9.2.1: + resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} + engines: {node: '>=18'} + hasBin: true + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -3042,6 +3126,10 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} @@ -3286,6 +3374,10 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + enhanced-resolve@5.21.0: + resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} + engines: {node: '>=10.13.0'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -3294,6 +3386,9 @@ packages: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} @@ -3374,8 +3469,8 @@ packages: unrs-resolver: optional: true - eslint-json-compat-utils@0.2.2: - resolution: {integrity: sha512-KcTUifi8VSSHkrOY0FzB7smuTZRU9T2nCrcCy6k2b+Q77+uylBQVIxN4baVCIWvWJEpud+IsrYgco4JJ6io05g==} + eslint-json-compat-utils@0.2.3: + resolution: {integrity: sha512-RbBmDFyu7FqnjE8F0ZxPNzx5UaptdeS9Uu50r7A+D7s/+FCX+ybiyViYEgFUaFIFqSWJgZRTpL5d8Kanxxl2lQ==} engines: {node: '>=12'} peerDependencies: '@eslint/json': '*' @@ -3423,23 +3518,29 @@ packages: peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 - eslint-plugin-jsonc@3.1.1: - resolution: {integrity: sha512-7TSQO8ZyvOuXWb0sYke3KUSh0DJA4/QviKfuzD3/Cy3XDjtrIrTWQbjb7j/Yy2l/DgwuM+lCS2c/jqJifv5jhg==} + eslint-plugin-jsonc@3.1.2: + resolution: {integrity: sha512-dopTxdB22iuOkgKyJCupEC5IYBItUT4J/teq1H5ddUObcaYhOURxtJElZczdcYnnKCghNU/vccuyPkliy2Wxsg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: '>=9.38.0' + eslint-plugin-perfectionist@5.9.0: + resolution: {integrity: sha512-8TWzg02zmnBdZwCkWLi8jhzqXI+fE7Z/RwV8SL6xD45tJ8Bp3wGuYL2XtQgfe/Wd0eBqOUX+s6ey73IyszvKTA==} + engines: {node: ^20.0.0 || >=22.0.0} + peerDependencies: + eslint: ^8.45.0 || ^9.0.0 || ^10.0.0 + eslint-plugin-regexp@3.1.0: resolution: {integrity: sha512-qGXIC3DIKZHcK1H9A9+Byz9gmndY6TTSRkSMTZpNXdyCw2ObSehRgccJv35n9AdUakEjQp5VFNLas6BMXizCZg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: '>=9.38.0' - eslint-plugin-tailwindcss@3.18.2: - resolution: {integrity: sha512-QbkMLDC/OkkjFQ1iz/5jkMdHfiMu/uwujUHLAJK5iwNHD8RTxVTlsUezE0toTZ6VhybNBsk+gYGPDq2agfeRNA==} + eslint-plugin-tailwindcss@4.0.0-beta.0: + resolution: {integrity: sha512-WWCajZgQu38Sd67ZCl2W6i3MRzqB0d+H8s4qV9iB6lBJbsDOIpIlj6R1Fj2FXkoWErbo05pZnZYbCGIU9o/DsA==} engines: {node: '>=18.12.0'} peerDependencies: - tailwindcss: ^3.4.0 + tailwindcss: ^3.4.0 || ^4.0.0 eslint-plugin-unicorn@63.0.0: resolution: {integrity: sha512-Iqecl9118uQEXYh7adylgEmGfkn5es3/mlQTLLkd4pXkIk9CTGrAbeUux+YljSa2ohXCBmQQ0+Ej1kZaFgcfkA==} @@ -3473,6 +3574,10 @@ packages: '@vue/compiler-sfc': ^3.3.0 eslint: '>=9.0.0' + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@9.1.2: resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -3494,9 +3599,9 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.0.3: - resolution: {integrity: sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: jiti: '*' @@ -3644,6 +3749,10 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -3729,6 +3838,10 @@ packages: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} engines: {node: '>=18'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + globals@16.5.0: resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} @@ -3825,6 +3938,10 @@ packages: image-meta@0.2.2: resolution: {integrity: sha512-3MOLanc3sb3LNGWQl1RlQlNWURE5g32aUphrDyFeCsxBTk08iE3VNe4CwsUZ0Qs1X+EfX0+r29Sxdpza4B+yRA==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + impound@1.1.5: resolution: {integrity: sha512-5AUn+QE0UofqNHu5f2Skf6Svukdg4ehOIq8O0EtqIx4jta0CDZYBPqpIHt0zrlUTiFVYlLpeH39DoikXBjPKpA==} @@ -3857,6 +3974,9 @@ packages: iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -3992,6 +4112,9 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-parse-even-better-errors@4.0.0: resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -4183,6 +4306,9 @@ packages: lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} @@ -4339,6 +4465,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'} + negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -4565,9 +4695,21 @@ packages: package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-author@2.0.0: + resolution: {integrity: sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==} + engines: {node: '>=0.10.0'} + parse-imports-exports@0.2.4: resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + parse-statements@1.0.11: resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} @@ -4608,6 +4750,10 @@ packages: path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -4893,6 +5039,10 @@ packages: resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} engines: {node: '>=6.0.0'} + prettier-package-json@2.8.0: + resolution: {integrity: sha512-WxtodH/wWavfw3MR7yK/GrS4pASEQ+iSTkdtSxPJWvqzG55ir5nvbLt9rw5AOiEcqqPCRM92WCtR1rk3TG3JSQ==} + hasBin: true + prettier@3.8.1: resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} @@ -5005,6 +5155,10 @@ packages: resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==} engines: {node: '>=18'} + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} @@ -5053,6 +5207,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -5137,6 +5294,12 @@ packages: resolution: {integrity: sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==} engines: {node: '>=20.0.0'} + sort-object-keys@1.1.3: + resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} + + sort-order@1.1.2: + resolution: {integrity: sha512-Q8tOrwB1TSv9fNUXym9st3TZJODtmcOIi2JWCkVNQPrRg17KPwlpwweTEb7pMwUIFMTAgx2/JsQQXEPFzYQj3A==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -5224,6 +5387,10 @@ packages: resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} engines: {node: '>=12'} + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} @@ -5253,6 +5420,10 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -5274,6 +5445,11 @@ packages: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} + tailwind-api-utils@1.0.3: + resolution: {integrity: sha512-KpzUHkH1ug1sq4394SLJX38ZtpeTiqQ1RVyFTTSY2XuHsNSTWUkRo108KmyyrMWdDbQrLYkSHaNKj/a3bmA4sQ==} + peerDependencies: + tailwindcss: ^3.3.0 || ^4.0.0 || ^4.0.0-beta + tailwind-config-viewer@2.0.4: resolution: {integrity: sha512-icvcmdMmt9dphvas8wL40qttrHwAnW3QEN4ExJ2zICjwRsPj7gowd1cOceaWG3IfTuM/cTNGQcx+bsjMtmV+cw==} engines: {node: '>=13'} @@ -5286,6 +5462,10 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + tar-stream@3.1.8: resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} @@ -5356,12 +5536,22 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + ts-api-utils@2.4.0: resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -5794,6 +5984,10 @@ packages: resolution: {integrity: sha512-h0uDm97wvT2bokfwwTmY6kJ1hp6YDFL0nRHwNKz8s/VD1FH/vvZjAKoMUE+un0eaYBSG7/c6h+lJTP+31tjgTw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} + engines: {node: '>= 6'} + yaml@2.8.2: resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} @@ -6224,39 +6418,43 @@ snapshots: '@esbuild/win32-x64@0.27.3': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.0.3(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.0.3(eslint@10.0.3(jiti@2.6.1))': + '@eslint/compat@2.0.3(eslint@9.39.4(jiti@2.6.1))': dependencies: '@eslint/core': 1.1.1 optionalDependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) - '@eslint/config-array@0.23.3': + '@eslint/config-array@0.21.2': dependencies: - '@eslint/object-schema': 3.0.3 + '@eslint/object-schema': 2.1.7 debug: 4.4.3 - minimatch: 10.2.4 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + '@eslint/config-helpers@0.5.3': dependencies: '@eslint/core': 1.1.1 - '@eslint/config-inspector@1.5.0(eslint@10.0.3(jiti@2.6.1))(srvx@0.11.9)': + '@eslint/config-inspector@1.5.0(eslint@9.39.4(jiti@2.6.1))(srvx@0.11.9)': dependencies: ansis: 4.2.0 bundle-require: 5.1.0(esbuild@0.27.3) cac: 7.0.0 chokidar: 5.0.0 esbuild: 0.27.3 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) h3: 1.15.6(srvx@0.11.9) tinyglobby: 0.2.15 ws: 8.19.0 @@ -6265,13 +6463,36 @@ snapshots: - srvx - utf-8-validate + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/core@1.1.1': dependencies: '@types/json-schema': 7.0.15 + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + '@eslint/js@9.39.4': {} - '@eslint/object-schema@3.0.3': {} + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 '@eslint/plugin-kit@0.6.1': dependencies: @@ -6331,9 +6552,9 @@ snapshots: '@intlify/shared@11.3.0': {} - '@intlify/unplugin-vue-i18n@11.0.7(@vue/compiler-dom@3.5.30)(eslint@10.0.3(jiti@2.6.1))(rollup@4.59.0)(typescript@5.9.3)(vue-i18n@11.3.0(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3))': + '@intlify/unplugin-vue-i18n@11.0.7(@vue/compiler-dom@3.5.30)(eslint@9.39.4(jiti@2.6.1))(rollup@4.59.0)(typescript@5.9.3)(vue-i18n@11.3.0(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@intlify/bundle-utils': 11.0.7(vue-i18n@11.3.0(vue@3.5.30(typescript@5.9.3))) '@intlify/shared': 11.3.0 '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.3.0)(@vue/compiler-dom@3.5.30)(vue-i18n@11.3.0(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)) @@ -6578,32 +6799,32 @@ snapshots: - utf-8-validate - vue - '@nuxt/eslint-config@1.15.2(@typescript-eslint/utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@nuxt/eslint-config@1.15.2(@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-format@2.0.1(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 1.1.0 '@eslint/js': 9.39.4 - '@nuxt/eslint-plugin': 1.15.2(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@stylistic/eslint-plugin': 5.10.0(eslint@10.0.3(jiti@2.6.1)) - '@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - eslint: 10.0.3(jiti@2.6.1) - eslint-config-flat-gitignore: 2.2.1(eslint@10.0.3(jiti@2.6.1)) + '@nuxt/eslint-plugin': 1.15.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@stylistic/eslint-plugin': 5.10.0(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + eslint-config-flat-gitignore: 2.2.1(eslint@9.39.4(jiti@2.6.1)) eslint-flat-config-utils: 3.0.2 - eslint-merge-processors: 2.0.0(eslint@10.0.3(jiti@2.6.1)) - eslint-plugin-import-lite: 0.5.2(eslint@10.0.3(jiti@2.6.1)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1)) - eslint-plugin-jsdoc: 62.7.1(eslint@10.0.3(jiti@2.6.1)) - eslint-plugin-regexp: 3.1.0(eslint@10.0.3(jiti@2.6.1)) - eslint-plugin-unicorn: 63.0.0(eslint@10.0.3(jiti@2.6.1)) - eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1))) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.30)(eslint@10.0.3(jiti@2.6.1)) + eslint-merge-processors: 2.0.0(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import-lite: 0.5.2(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-jsdoc: 62.7.1(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-regexp: 3.1.0(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-unicorn: 63.0.0(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4(jiti@2.6.1)))(@typescript-eslint/parser@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.30)(eslint@9.39.4(jiti@2.6.1)) globals: 17.4.0 local-pkg: 1.1.2 pathe: 2.0.3 - vue-eslint-parser: 10.4.0(eslint@10.0.3(jiti@2.6.1)) + vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) optionalDependencies: - eslint-plugin-format: 2.0.1(eslint@10.0.3(jiti@2.6.1)) + eslint-plugin-format: 2.0.1(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - '@typescript-eslint/utils' - '@vue/compiler-sfc' @@ -6611,26 +6832,26 @@ snapshots: - supports-color - typescript - '@nuxt/eslint-plugin@1.15.2(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@nuxt/eslint-plugin@1.15.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - eslint: 10.0.3(jiti@2.6.1) + '@typescript-eslint/utils': 8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) transitivePeerDependencies: - supports-color - typescript - '@nuxt/eslint@1.15.2(@typescript-eslint/utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(magicast@0.5.2)(srvx@0.11.9)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))': + '@nuxt/eslint@1.15.2(@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-format@2.0.1(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1))(magicast@0.5.2)(srvx@0.11.9)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))': dependencies: - '@eslint/config-inspector': 1.5.0(eslint@10.0.3(jiti@2.6.1))(srvx@0.11.9) + '@eslint/config-inspector': 1.5.0(eslint@9.39.4(jiti@2.6.1))(srvx@0.11.9) '@nuxt/devtools-kit': 3.2.3(magicast@0.5.2)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2)) - '@nuxt/eslint-config': 1.15.2(@typescript-eslint/utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@nuxt/eslint-plugin': 1.15.2(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@nuxt/eslint-config': 1.15.2(@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-format@2.0.1(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@nuxt/eslint-plugin': 1.15.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@nuxt/kit': 4.3.1(magicast@0.5.2) chokidar: 5.0.0 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-flat-config-utils: 3.0.2 - eslint-typegen: 2.3.1(eslint@10.0.3(jiti@2.6.1)) + eslint-typegen: 2.3.1(eslint@9.39.4(jiti@2.6.1)) find-up: 8.0.0 get-port-please: 3.2.0 mlly: 1.8.1 @@ -6772,7 +6993,7 @@ snapshots: rc9: 3.0.0 std-env: 3.10.0 - '@nuxt/vite-builder@4.1.3(@types/node@25.4.0)(eslint@10.0.3(jiti@2.6.1))(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vue-tsc@3.1.8(typescript@5.9.3))(vue@3.5.30(typescript@5.9.3))(yaml@2.8.2)': + '@nuxt/vite-builder@4.1.3(@types/node@25.4.0)(eslint@9.39.4(jiti@2.6.1))(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vue-tsc@3.1.8(typescript@5.9.3))(vue@3.5.30(typescript@5.9.3))(yaml@2.8.2)': dependencies: '@nuxt/kit': 4.1.3(magicast@0.5.2) '@rollup/plugin-replace': 6.0.3(rollup@4.59.0) @@ -6801,7 +7022,7 @@ snapshots: unenv: 2.0.0-rc.24 vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.4.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)' vite-node: 3.2.4(@types/node@25.4.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) - vite-plugin-checker: 0.11.0(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.4.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))(eslint@10.0.3(jiti@2.6.1))(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(typescript@5.9.3)(vue-tsc@3.1.8(typescript@5.9.3)) + vite-plugin-checker: 0.11.0(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.4.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))(eslint@9.39.4(jiti@2.6.1))(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(typescript@5.9.3)(vue-tsc@3.1.8(typescript@5.9.3)) vue: 3.5.30(typescript@5.9.3) vue-bundle-renderer: 2.2.0 transitivePeerDependencies: @@ -6835,12 +7056,12 @@ snapshots: - vue-tsc - yaml - '@nuxtjs/i18n@10.2.3(@vue/compiler-dom@3.5.30)(db0@0.3.4)(eslint@10.0.3(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(rollup@4.59.0)(srvx@0.11.9)(vue@3.5.30(typescript@5.9.3))': + '@nuxtjs/i18n@10.2.3(@vue/compiler-dom@3.5.30)(db0@0.3.4)(eslint@9.39.4(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(rollup@4.59.0)(srvx@0.11.9)(vue@3.5.30(typescript@5.9.3))': dependencies: '@intlify/core': 11.3.0 '@intlify/h3': 0.7.4 '@intlify/shared': 11.3.0 - '@intlify/unplugin-vue-i18n': 11.0.7(@vue/compiler-dom@3.5.30)(eslint@10.0.3(jiti@2.6.1))(rollup@4.59.0)(typescript@5.9.3)(vue-i18n@11.3.0(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)) + '@intlify/unplugin-vue-i18n': 11.0.7(@vue/compiler-dom@3.5.30)(eslint@9.39.4(jiti@2.6.1))(rollup@4.59.0)(typescript@5.9.3)(vue-i18n@11.3.0(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)) '@intlify/utils': 0.13.0 '@miyaneee/rollup-plugin-json5': 1.2.0(rollup@4.59.0) '@nuxt/kit': 4.3.1(magicast@0.5.2) @@ -7601,11 +7822,11 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1))': + '@stylistic/eslint-plugin@5.10.0(eslint@9.39.4(jiti@2.6.1))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/types': 8.57.0 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -7634,19 +7855,23 @@ snapshots: undici-types: 7.18.2 optional: true + '@types/parse-author@2.0.3': {} + + '@types/parse-json@4.0.2': {} + '@types/resolve@1.20.2': {} '@types/web-bluetooth@0.0.21': {} - '@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/type-utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.57.0 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.4.0(typescript@5.9.3) @@ -7654,14 +7879,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.57.0 '@typescript-eslint/types': 8.57.0 '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.57.0 debug: 4.4.3 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -7675,22 +7900,40 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/project-service@8.59.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@8.57.0': dependencies: '@typescript-eslint/types': 8.57.0 '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/scope-manager@8.59.1': + dependencies: + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 + '@typescript-eslint/tsconfig-utils@8.57.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.1(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.57.0 '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -7698,6 +7941,8 @@ snapshots: '@typescript-eslint/types@8.57.0': {} + '@typescript-eslint/types@8.59.1': {} + '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.57.0(typescript@5.9.3) @@ -7713,13 +7958,39 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.59.1(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@typescript-eslint/project-service': 8.59.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 + debug: 4.4.3 + minimatch: 10.2.4 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.57.0 '@typescript-eslint/types': 8.57.0 '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -7729,6 +8000,11 @@ snapshots: '@typescript-eslint/types': 8.57.0 eslint-visitor-keys: 5.0.1 + '@typescript-eslint/visitor-keys@8.59.1': + dependencies: + '@typescript-eslint/types': 8.59.1 + eslint-visitor-keys: 5.0.1 + '@unhead/vue@2.1.12(vue@3.5.30(typescript@5.9.3))': dependencies: hookable: 6.0.1 @@ -8089,13 +8365,13 @@ snapshots: '@vueuse/metadata@13.9.0': {} - '@vueuse/nuxt@13.9.0(magicast@0.5.2)(nuxt@4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@10.0.3(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2))(vue@3.5.30(typescript@5.9.3))': + '@vueuse/nuxt@13.9.0(magicast@0.5.2)(nuxt@4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.4(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2))(vue@3.5.30(typescript@5.9.3))': dependencies: '@nuxt/kit': 3.21.1(magicast@0.5.2) '@vueuse/core': 13.9.0(vue@3.5.30(typescript@5.9.3)) '@vueuse/metadata': 13.9.0 local-pkg: 1.1.2 - nuxt: 4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@10.0.3(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2) + nuxt: 4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.4(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2) vue: 3.5.30(typescript@5.9.3) transitivePeerDependencies: - magicast @@ -8203,6 +8479,8 @@ snapshots: at-least-node@1.0.0: {} + author-regex@1.0.0: {} + autoprefixer@10.4.27(postcss@8.5.8): dependencies: browserslist: 4.28.1 @@ -8363,6 +8641,8 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + callsites@3.1.0: {} + camelcase-css@2.0.1: {} caniuse-api@3.0.0: @@ -8463,6 +8743,15 @@ snapshots: concat-map@0.0.1: {} + concurrently@9.2.1: + dependencies: + chalk: 4.1.2 + rxjs: 7.8.2 + shell-quote: 1.8.3 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + confbox@0.1.8: {} confbox@0.2.4: {} @@ -8496,6 +8785,14 @@ snapshots: core-util-is@1.0.3: {} + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.3 + crc-32@1.2.2: {} crc32-stream@6.0.0: @@ -8695,10 +8992,19 @@ snapshots: encodeurl@2.0.0: {} + enhanced-resolve@5.21.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + entities@4.5.0: {} entities@7.0.1: {} + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + error-stack-parser-es@1.0.5: {} errx@0.1.0: {} @@ -8791,19 +9097,19 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-flat-gitignore@2.2.1(eslint@10.0.3(jiti@2.6.1)): + eslint-config-flat-gitignore@2.2.1(eslint@9.39.4(jiti@2.6.1)): dependencies: - '@eslint/compat': 2.0.3(eslint@10.0.3(jiti@2.6.1)) - eslint: 10.0.3(jiti@2.6.1) + '@eslint/compat': 2.0.3(eslint@9.39.4(jiti@2.6.1)) + eslint: 9.39.4(jiti@2.6.1) eslint-flat-config-utils@3.0.2: dependencies: '@eslint/config-helpers': 0.5.3 pathe: 2.0.3 - eslint-formatting-reporter@0.0.0(eslint@10.0.3(jiti@2.6.1)): + eslint-formatting-reporter@0.0.0(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) prettier-linter-helpers: 1.0.1 eslint-import-context@0.1.9(unrs-resolver@1.11.1): @@ -8813,41 +9119,41 @@ snapshots: optionalDependencies: unrs-resolver: 1.11.1 - eslint-json-compat-utils@0.2.2(eslint@10.0.3(jiti@2.6.1))(jsonc-eslint-parser@3.1.0): + eslint-json-compat-utils@0.2.3(eslint@9.39.4(jiti@2.6.1))(jsonc-eslint-parser@3.1.0): dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) esquery: 1.7.0 jsonc-eslint-parser: 3.1.0 - eslint-merge-processors@2.0.0(eslint@10.0.3(jiti@2.6.1)): + eslint-merge-processors@2.0.0(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-parser-plain@0.1.1: {} - eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-format@2.0.1(eslint@9.39.4(jiti@2.6.1)): dependencies: '@dprint/formatter': 0.5.1 '@dprint/markdown': 0.21.1 '@dprint/toml': 0.7.0 - eslint: 10.0.3(jiti@2.6.1) - eslint-formatting-reporter: 0.0.0(eslint@10.0.3(jiti@2.6.1)) + eslint: 9.39.4(jiti@2.6.1) + eslint-formatting-reporter: 0.0.0(eslint@9.39.4(jiti@2.6.1)) eslint-parser-plain: 0.1.1 ohash: 2.0.11 oxfmt: 0.35.0 prettier: 3.8.1 synckit: 0.11.12 - eslint-plugin-import-lite@0.5.2(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-import-lite@0.5.2(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)): dependencies: '@typescript-eslint/types': 8.57.0 comment-parser: 1.4.5 debug: 4.4.3 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-import-context: 0.1.9(unrs-resolver@1.11.1) is-glob: 4.0.3 minimatch: 10.2.4 @@ -8855,11 +9161,11 @@ snapshots: stable-hash-x: 0.2.0 unrs-resolver: 1.11.1 optionalDependencies: - '@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - supports-color - eslint-plugin-jsdoc@62.7.1(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-jsdoc@62.7.1(eslint@9.39.4(jiti@2.6.1)): dependencies: '@es-joy/jsdoccomment': 0.84.0 '@es-joy/resolve.exports': 1.2.0 @@ -8867,7 +9173,7 @@ snapshots: comment-parser: 1.4.5 debug: 4.4.3 escape-string-regexp: 4.0.0 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) espree: 11.2.0 esquery: 1.7.0 html-entities: 2.6.0 @@ -8879,47 +9185,58 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-jsonc@3.1.1(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-jsonc@3.1.2(eslint@9.39.4(jiti@2.6.1)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint/core': 1.1.1 '@eslint/plugin-kit': 0.6.1 '@ota-meshi/ast-token-store': 0.3.0 diff-sequences: 29.6.3 - eslint: 10.0.3(jiti@2.6.1) - eslint-json-compat-utils: 0.2.2(eslint@10.0.3(jiti@2.6.1))(jsonc-eslint-parser@3.1.0) + eslint: 9.39.4(jiti@2.6.1) + eslint-json-compat-utils: 0.2.3(eslint@9.39.4(jiti@2.6.1))(jsonc-eslint-parser@3.1.0) jsonc-eslint-parser: 3.1.0 natural-compare: 1.4.0 synckit: 0.11.12 transitivePeerDependencies: - '@eslint/json' - eslint-plugin-regexp@3.1.0(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-perfectionist@5.9.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@typescript-eslint/utils': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + natural-orderby: 5.0.0 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-regexp@3.1.0(eslint@9.39.4(jiti@2.6.1)): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 comment-parser: 1.4.5 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) jsdoc-type-pratt-parser: 7.1.1 refa: 0.12.1 regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-tailwindcss@3.18.2(tailwindcss@3.4.19(yaml@2.8.2)): + eslint-plugin-tailwindcss@4.0.0-beta.0(tailwindcss@3.4.19(yaml@2.8.2)): dependencies: fast-glob: 3.3.3 postcss: 8.5.8 + synckit: 0.11.12 + tailwind-api-utils: 1.0.3(tailwindcss@3.4.19(yaml@2.8.2)) tailwindcss: 3.4.19(yaml@2.8.2) - eslint-plugin-unicorn@63.0.0(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-unicorn@63.0.0(eslint@9.39.4(jiti@2.6.1)): dependencies: '@babel/helper-validator-identifier': 7.28.5 - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) change-case: 5.4.4 ci-info: 4.4.0 clean-regexp: 1.0.0 core-js-compat: 3.48.0 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) find-up-simple: 1.0.1 globals: 16.5.0 indent-string: 5.0.0 @@ -8931,21 +9248,21 @@ snapshots: semver: 7.7.4 strip-indent: 4.1.1 - eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1))): + eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4(jiti@2.6.1)))(@typescript-eslint/parser@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) - eslint: 10.0.3(jiti@2.6.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + eslint: 9.39.4(jiti@2.6.1) natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 7.1.1 semver: 7.7.4 - vue-eslint-parser: 10.4.0(eslint@10.0.3(jiti@2.6.1)) + vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) xml-name-validator: 4.0.0 optionalDependencies: - '@stylistic/eslint-plugin': 5.10.0(eslint@10.0.3(jiti@2.6.1)) - '@typescript-eslint/parser': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@stylistic/eslint-plugin': 5.10.0(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/parser': 8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-yml@3.3.1(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-yml@3.3.1(eslint@9.39.4(jiti@2.6.1)): dependencies: '@eslint/core': 1.1.1 '@eslint/plugin-kit': 0.6.1 @@ -8953,16 +9270,21 @@ snapshots: debug: 4.4.3 diff-sequences: 29.6.3 escape-string-regexp: 5.0.0 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) natural-compare: 1.4.0 yaml-eslint-parser: 2.0.0 transitivePeerDependencies: - supports-color - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.30)(eslint@10.0.3(jiti@2.6.1)): + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.30)(eslint@9.39.4(jiti@2.6.1)): dependencies: '@vue/compiler-sfc': 3.5.30 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 eslint-scope@9.1.2: dependencies: @@ -8971,9 +9293,9 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-typegen@2.3.1(eslint@10.0.3(jiti@2.6.1)): + eslint-typegen@2.3.1(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) json-schema-to-typescript-lite: 15.0.0 ohash: 2.0.11 @@ -8983,25 +9305,28 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.0.3(jiti@2.6.1): + eslint@9.39.4(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.3 - '@eslint/config-helpers': 0.5.3 - '@eslint/core': 1.1.1 - '@eslint/plugin-kit': 0.6.1 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 ajv: 6.14.0 + chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.3 escape-string-regexp: 4.0.0 - eslint-scope: 9.1.2 - eslint-visitor-keys: 5.0.1 - espree: 11.2.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -9012,7 +9337,8 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 - minimatch: 10.2.4 + lodash.merge: 4.6.2 + minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -9152,6 +9478,12 @@ snapshots: fresh@2.0.0: {} + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 @@ -9249,6 +9581,8 @@ snapshots: dependencies: ini: 4.1.1 + globals@14.0.0: {} + globals@16.5.0: {} globals@17.4.0: {} @@ -9351,6 +9685,11 @@ snapshots: image-meta@0.2.2: {} + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + impound@1.1.5: dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -9390,6 +9729,8 @@ snapshots: iron-webcrypto@1.2.1: {} + is-arrayish@0.2.1: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -9498,6 +9839,8 @@ snapshots: json-buffer@3.0.1: {} + json-parse-even-better-errors@2.3.1: {} + json-parse-even-better-errors@4.0.0: {} json-schema-to-typescript-lite@15.0.0: @@ -9708,6 +10051,8 @@ snapshots: lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} + lodash.uniq@4.5.0: {} lodash@4.17.23: {} @@ -9842,6 +10187,8 @@ snapshots: natural-compare@1.4.0: {} + natural-orderby@5.0.0: {} + negotiator@0.6.3: {} nitropack@2.13.1(srvx@0.11.9): @@ -10000,7 +10347,7 @@ snapshots: nuxt-define@1.0.0: {} - nuxt@4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@10.0.3(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2): + nuxt@4.1.3(@parcel/watcher@2.5.6)(@types/node@25.4.0)(@vue/compiler-sfc@3.5.30)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.4(jiti@2.6.1))(ioredis@5.10.0)(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.2(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@3.1.8(typescript@5.9.3))(yaml@2.8.2): dependencies: '@nuxt/cli': 3.34.0(@nuxt/schema@4.1.3)(cac@6.7.14)(magicast@0.5.2) '@nuxt/devalue': 2.0.2 @@ -10008,7 +10355,7 @@ snapshots: '@nuxt/kit': 4.1.3(magicast@0.5.2) '@nuxt/schema': 4.1.3 '@nuxt/telemetry': 2.7.0(@nuxt/kit@4.1.3(magicast@0.5.2)) - '@nuxt/vite-builder': 4.1.3(@types/node@25.4.0)(eslint@10.0.3(jiti@2.6.1))(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vue-tsc@3.1.8(typescript@5.9.3))(vue@3.5.30(typescript@5.9.3))(yaml@2.8.2) + '@nuxt/vite-builder': 4.1.3(@types/node@25.4.0)(eslint@9.39.4(jiti@2.6.1))(magicast@0.5.2)(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(rollup@4.59.0)(srvx@0.11.9)(terser@5.46.0)(typescript@5.9.3)(vue-tsc@3.1.8(typescript@5.9.3))(vue@3.5.30(typescript@5.9.3))(yaml@2.8.2) '@unhead/vue': 2.1.12(vue@3.5.30(typescript@5.9.3)) '@vue/shared': 3.5.30 c12: 3.3.3(magicast@0.5.2) @@ -10406,10 +10753,25 @@ snapshots: package-manager-detector@1.6.0: {} + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-author@2.0.0: + dependencies: + author-regex: 1.0.0 + parse-imports-exports@0.2.4: dependencies: parse-statements: 1.0.11 + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + parse-statements@1.0.11: {} parseurl@1.3.3: {} @@ -10438,6 +10800,8 @@ snapshots: path-to-regexp@6.3.0: {} + path-type@4.0.0: {} + pathe@1.1.2: {} pathe@2.0.3: {} @@ -10690,6 +11054,18 @@ snapshots: dependencies: fast-diff: 1.3.0 + prettier-package-json@2.8.0: + dependencies: + '@types/parse-author': 2.0.3 + commander: 4.1.1 + cosmiconfig: 7.1.0 + fs-extra: 10.1.0 + glob: 7.2.3 + minimatch: 3.1.5 + parse-author: 2.0.0 + sort-object-keys: 1.1.3 + sort-order: 1.1.2 + prettier@3.8.1: {} pretty-bytes@7.1.0: {} @@ -10797,6 +11173,8 @@ snapshots: reserved-identifiers@1.2.0: {} + resolve-from@4.0.0: {} + resolve-from@5.0.0: {} resolve-path@1.4.0: @@ -10862,6 +11240,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -10953,6 +11335,10 @@ snapshots: smob@1.6.1: {} + sort-object-keys@1.1.3: {} + + sort-order@1.1.2: {} + source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -11030,6 +11416,8 @@ snapshots: strip-indent@4.1.1: {} + strip-json-comments@3.1.1: {} + strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 @@ -11062,6 +11450,10 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} svgo@4.0.1: @@ -11082,6 +11474,13 @@ snapshots: tagged-tag@1.0.0: {} + tailwind-api-utils@1.0.3(tailwindcss@3.4.19(yaml@2.8.2)): + dependencies: + enhanced-resolve: 5.21.0 + jiti: 2.6.1 + local-pkg: 1.1.2 + tailwindcss: 3.4.19(yaml@2.8.2) + tailwind-config-viewer@2.0.4(tailwindcss@3.4.19(yaml@2.8.2)): dependencies: '@koa/router': 12.0.2 @@ -11124,6 +11523,8 @@ snapshots: - tsx - yaml + tapable@2.3.3: {} + tar-stream@3.1.8: dependencies: b4a: 1.8.0 @@ -11203,14 +11604,19 @@ snapshots: tr46@0.0.3: {} + tree-kill@1.2.2: {} + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + ts-interface-checker@0.1.13: {} - tslib@2.8.1: - optional: true + tslib@2.8.1: {} tsscmp@1.0.6: {} @@ -11469,7 +11875,7 @@ snapshots: - unplugin-unused - yaml - vite-plugin-checker@0.11.0(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.4.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))(eslint@10.0.3(jiti@2.6.1))(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(typescript@5.9.3)(vue-tsc@3.1.8(typescript@5.9.3)): + vite-plugin-checker@0.11.0(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.4.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))(eslint@9.39.4(jiti@2.6.1))(optionator@0.9.4)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(typescript@5.9.3)(vue-tsc@3.1.8(typescript@5.9.3)): dependencies: '@babel/code-frame': 7.29.0 chokidar: 4.0.3 @@ -11481,7 +11887,7 @@ snapshots: vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.4.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)' vscode-uri: 3.1.0 optionalDependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) optionator: 0.9.4 oxlint: 1.61.0(oxlint-tsgolint@0.22.0) typescript: 5.9.3 @@ -11585,10 +11991,10 @@ snapshots: vue-devtools-stub@0.1.0: {} - vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1)): + vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 4.4.3 - eslint: 10.0.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-scope: 9.1.2 eslint-visitor-keys: 5.0.1 espree: 11.2.0 @@ -11688,6 +12094,8 @@ snapshots: eslint-visitor-keys: 5.0.1 yaml: 2.8.2 + yaml@1.10.3: {} + yaml@2.8.2: {} yargs-parser@21.1.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4cc22d0..b13a23b 100755 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,9 @@ allowBuilds: esbuild: false catalog: + # pin ESLint to v9, as `"eslint-plugin-tailwindcss": "~4.0.0-alpha.2",` has problems with eslint v10 + eslint: ~9.39.4 + # vite-plus ecosystem, all same version to avoid mismatches vite: npm:@voidzero-dev/vite-plus-core@~0.1.19 vite-plus: ~0.1.19 From 2450ce99c98ae29c57eef43d3f049c2b423cdb19 Mon Sep 17 00:00:00 2001 From: Thorsten Seyschab Date: Sun, 3 May 2026 14:37:35 +0200 Subject: [PATCH 3/9] chore: wire staged eslint checks --- vite.config.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 9340795..0fece33 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,7 +5,16 @@ export default defineConfig({ '*': [ 'vp run test:lint-format', ], + 'package.json': [ + 'vp run test:package-json', + ], + '*.{ts,vue}': [ + // Wrapped in `sh -c` so Vite+ staged doesn't append file paths; + // `nuxt typecheck` is project-wide and fails when given individual files. + 'sh -c "vp run test:type"', + ], + }, + run: { + cache: true, }, - fmt: {}, - lint: { options: { typeAware: true, typeCheck: true } }, }) From 6753f8dd60dfbebf038aee89c03c61ca8cc76067 Mon Sep 17 00:00:00 2001 From: Thorsten Seyschab Date: Sun, 3 May 2026 15:33:43 +0200 Subject: [PATCH 4/9] chore: document tailwind eslint internal import --- eslint.tailwind-apply-order.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/eslint.tailwind-apply-order.mjs b/eslint.tailwind-apply-order.mjs index 2433530..d15d0ce 100755 --- a/eslint.tailwind-apply-order.mjs +++ b/eslint.tailwind-apply-order.mjs @@ -1,6 +1,12 @@ import { createRequire } from 'node:module' const require = createRequire(import.meta.url) + +// Uses `eslint-plugin-tailwindcss` internals on purpose, since there is no +// public utility for sorting `@apply` tokens in plain CSS. This path may break +// on plugin upgrades. TODO: re-check and update this import when bumping +// `eslint-plugin-tailwindcss`, and add coverage that fails if the util path or +// sorting behavior changes. const { getSortedClassNames } = require('eslint-plugin-tailwindcss/lib/util/tailwindAPI') /** From d37d5bfb64992d97763de807526fd8851c5beb7c Mon Sep 17 00:00:00 2001 From: Thorsten Seyschab Date: Sun, 3 May 2026 15:34:38 +0200 Subject: [PATCH 5/9] chore: remove old eslint configuration --- eslint.config.old.mjs | 187 ------------------------------------------ 1 file changed, 187 deletions(-) delete mode 100644 eslint.config.old.mjs diff --git a/eslint.config.old.mjs b/eslint.config.old.mjs deleted file mode 100644 index 8c804a3..0000000 --- a/eslint.config.old.mjs +++ /dev/null @@ -1,187 +0,0 @@ -// @ts-check -import pluginStylistic from '@stylistic/eslint-plugin' -import pluginFormat from 'eslint-plugin-format' -import * as pluginJsonc from 'eslint-plugin-jsonc' -import pluginTailwindCSS from 'eslint-plugin-tailwindcss' -import * as pluginYml from 'eslint-plugin-yml' - -import withNuxt from './.nuxt/eslint.config.mjs' - -export default withNuxt( - // ── Global ignores ────────────────────────────────────────────────────────── - { - ignores: [ - '.nuxt/', - '.output/', - 'dist/', - '.data/', - '.claude/skills/**/.skilld/', - 'pnpm-lock.yaml', - 'data/', - ], - }, - - // ── JSON / JSONC support ──────────────────────────────────────────────────── - ...pluginJsonc.configs['flat/recommended-with-jsonc'], - { - files: [ - '**/*.json', - '**/*.jsonc', - ], - rules: { - 'jsonc/sort-keys': 'error', - }, - }, - { - // Disable JSONC sort-keys for files where key order is meaningful - files: [ - '.vscode/settings.json', - 'package.json', - 'tsconfig.json', - ], - rules: { - 'jsonc/sort-keys': 'off', - }, - }, - - // ── YAML support ──────────────────────────────────────────────────────────── - ...pluginYml.configs['flat/standard'], - - // ── Prettier formatting for CSS ───────────────────────────────────────────── - { - files: [ - '**/*.css', - ], - languageOptions: { - parser: pluginFormat.parserPlain, - }, - plugins: { - format: pluginFormat, - }, - rules: { - 'format/prettier': [ - 'error', - { parser: 'css' }, - ], - }, - }, - - // ── Prettier formatting for HTML ──────────────────────────────────────────── - { - files: [ - '**/*.html', - ], - languageOptions: { - parser: pluginFormat.parserPlain, - }, - plugins: { - format: pluginFormat, - }, - rules: { - 'format/prettier': [ - 'error', - { parser: 'html' }, - ], - }, - }, - - // ── Prettier formatting for Markdown ──────────────────────────────────────── - { - files: [ - '**/*.md', - ], - languageOptions: { - parser: pluginFormat.parserPlain, - }, - plugins: { - format: pluginFormat, - }, - rules: { - 'format/prettier': [ - 'error', - { parser: 'markdown' }, - ], - }, - }, - - // ── Stylistic overrides ───────────────────────────────────────────────────── - { - files: [ - '**/*.js', - '**/*.mjs', - '**/*.ts', - '**/*.vue', - ], - plugins: { - '@stylistic': pluginStylistic, - }, - rules: { - '@stylistic/max-len': [ - 'error', - { - code: 120, - // Ignore SVG path d attributes and inline data-URI background images - ignorePattern: String.raw`^\s*d="|url\(["']data:image`, - }, - ], - }, - }, - - // ── Vue rules ─────────────────────────────────────────────────────────────── - { - files: [ - '**/*.vue', - ], - rules: { - 'vue/attributes-order': [ - 'error', - { - alphabetical: true, - }, - ], - 'vue/max-attributes-per-line': [ - 'error', - { - multiline: 1, - singleline: 3, - }, - ], - }, - }, - - // ── Tailwind CSS class sorting ────────────────────────────────────────────── - // @ts-expect-error - pluginTailwindCSS types diverge from ESLint flat config Plugin type - { - files: [ - '**/*.{js,mjs,ts,vue}', - ], - plugins: { - tailwindcss: pluginTailwindCSS, - }, - rules: { - 'tailwindcss/classnames-order': 'error', - 'tailwindcss/no-custom-classname': 'off', - }, - settings: { - tailwindcss: { - // TW v3 without a tailwind.config.js - use empty object to suppress resolve warnings - config: {}, - cssFiles: [ - 'app/assets/css/main.css', - ], - }, - }, - }, - - // ── Disable max-len in Markdown & YAML ────────────────────────────────────── - { - files: [ - '**/*.md', - '**/*.yaml', - '**/*.yml', - ], - rules: { - '@stylistic/max-len': 'off', - }, - }, -) From 86f95e5b2edf3e8b8f58e49188caf01bbbbab1d6 Mon Sep 17 00:00:00 2001 From: Thorsten Seyschab Date: Sun, 3 May 2026 15:39:12 +0200 Subject: [PATCH 6/9] chore: lint frontend display components --- app/assets/css/main.css | 6 +++--- app/components/DebugWebsockets.vue | 2 +- app/components/app/AppFooter.vue | 2 +- app/components/ui/UiRadioOption.vue | 2 +- app/pages/index.vue | 27 +++++++++++++++++---------- app/utils/seededShuffle.ts | 4 +++- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/app/assets/css/main.css b/app/assets/css/main.css index 0072150..fd8b04b 100644 --- a/app/assets/css/main.css +++ b/app/assets/css/main.css @@ -4,7 +4,7 @@ @layer base { body { - @apply text-black min-h-screen relative; + @apply relative min-h-screen text-black; } ::selection { @@ -42,11 +42,11 @@ } ::-webkit-scrollbar-track { - @apply bg-gray-100 border border-black; + @apply border border-black bg-gray-100; } ::-webkit-scrollbar-thumb { - @apply bg-black border border-gray-100; + @apply border border-gray-100 bg-black; } ::-webkit-scrollbar-thumb:hover { diff --git a/app/components/DebugWebsockets.vue b/app/components/DebugWebsockets.vue index 0b16278..6803df1 100644 --- a/app/components/DebugWebsockets.vue +++ b/app/components/DebugWebsockets.vue @@ -3,7 +3,7 @@ const { data: connections, refresh: refreshConnections } = useFetch('/api/websoc