From 8f5fa15d3a994f2e564807d66eff6f2574f9face Mon Sep 17 00:00:00 2001 From: skytek_xinliang Date: Thu, 13 Aug 2026 15:41:12 +0800 Subject: [PATCH] chore: OXC Formatter --- .gitignore | 1 - AGENTS.md | 8 +- app/citizen-frontend/.oxfmtrc.json | 5 + app/citizen-frontend/.vscode/extensions.json | 5 +- app/citizen-frontend/.vscode/settings.json | 5 + app/citizen-frontend/AGENTS.md | 5 +- app/citizen-frontend/env.d.ts | 6 +- app/citizen-frontend/eslint.config.js | 13 - app/citizen-frontend/package.json | 9 +- app/citizen-frontend/src/api/auth.ts | 10 +- app/citizen-frontend/src/api/client.ts | 6 +- app/citizen-frontend/src/api/course.ts | 58 +- app/citizen-frontend/src/api/types.ts | 34 +- .../src/components/BrandAvatar.vue | 17 +- .../src/components/HealthRadarChart.vue | 56 +- .../src/components/ModuleRouterCard.vue | 22 +- .../src/components/QRCode.vue | 31 +- .../src/components/layout/DefaultLayout.vue | 95 +- .../src/data/course-detail.json | 14 +- app/citizen-frontend/src/data/courseDetail.ts | 24 +- app/citizen-frontend/src/main.ts | 14 +- .../src/pages/appointment.vue | 127 +- app/citizen-frontend/src/pages/checkin.vue | 248 ++- .../src/pages/checkinDetail.vue | 495 +++-- app/citizen-frontend/src/pages/course.vue | 263 ++- app/citizen-frontend/src/pages/index.vue | 95 +- .../src/pages/introduction.vue | 28 +- app/citizen-frontend/src/pages/login.vue | 96 +- .../src/pages/self-assessment.vue | 280 ++- app/citizen-frontend/src/plugins/i18n.ts | 14 +- app/citizen-frontend/src/plugins/index.ts | 20 +- app/citizen-frontend/src/plugins/vuetify.ts | 42 +- app/citizen-frontend/src/router/index.ts | 79 +- app/citizen-frontend/src/stores/app.ts | 410 ++-- app/citizen-frontend/src/stores/course.ts | 344 ++-- app/citizen-frontend/src/styles/settings.scss | 12 +- app/citizen-frontend/src/utils/qrcode.ts | 623 +++--- app/citizen-frontend/tsconfig.app.json | 14 +- app/citizen-frontend/vite.config.mts | 28 +- pnpm-lock.yaml | 1745 +++-------------- 40 files changed, 2392 insertions(+), 3009 deletions(-) create mode 100644 app/citizen-frontend/.oxfmtrc.json create mode 100644 app/citizen-frontend/.vscode/settings.json delete mode 100644 app/citizen-frontend/eslint.config.js diff --git a/.gitignore b/.gitignore index bd31cd7..95a68bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .cachebro -.eslintcache node_modules dist diff --git a/AGENTS.md b/AGENTS.md index 614bd66..0b0c27a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,13 +26,13 @@ Run commands from `app/citizen-frontend` unless noted otherwise. - `pnpm build`: run type-checking and production build. - `pnpm build-only`: build the Vite app without type-checking. - `pnpm type-check`: run `vue-tsc`. -- `pnpm lint`: run ESLint. -- `pnpm lint:fix`: apply ESLint auto-fixes. +- `pnpm format`: format source files with OXC Formatter. +- `pnpm format:check`: check source formatting with OXC Formatter. - `pnpm preview`: preview the production build locally. ## Coding Style & Naming Conventions -Use TypeScript, Vue 3 Composition API, and ` diff --git a/app/citizen-frontend/src/pages/self-assessment.vue b/app/citizen-frontend/src/pages/self-assessment.vue index ca634b2..26cd457 100644 --- a/app/citizen-frontend/src/pages/self-assessment.vue +++ b/app/citizen-frontend/src/pages/self-assessment.vue @@ -11,11 +11,20 @@ - + @@ -43,8 +52,14 @@
-

- +

+ 基本資料確認

@@ -140,19 +155,31 @@
-

+

活動習慣與想要改善的能力

-

+

1. 最近 7 天,您每週進行大運動幾次?

- + @@ -161,7 +188,11 @@ @@ -170,7 +201,11 @@ @@ -178,7 +213,9 @@ -

+

2. 您目前最想改善的身體功能? (可複選)

@@ -186,16 +223,25 @@ @@ -207,21 +253,36 @@
-

- +

+ 身體限制與慢性病史

-

+

1. 過去一年是否有過跌倒史?

- + -

+

2. 目前身體關節疼痛狀況?

@@ -234,7 +295,9 @@ variant="outlined" /> -

+

3. 您有哪些慢性疾病? (可複選)

@@ -254,8 +317,16 @@
- - + +

-

您的健康自評報告已產生

+

+ 您的健康自評報告已產生 +

- -
+ +
系統評估建議:
-

+

您的身體功能與日常活動習慣良好。建議您每週繼續保持 3 次以上的運動,並可以預約普測活動以獲得精準的五維健康指標與運動處方。

@@ -289,7 +371,9 @@ 檢測到您有多項慢性病或中重度疼痛,運動時請特別留意。建議您先向您的家庭醫師或社區據點諮詢,並在運動普測現場合對您的健康狀態,以確保運動安全。

-
+
* 禁忌提醒:若收縮壓 > 160mmHg、有關節強烈疼痛或暈眩時,請立即暫停所有體能檢測與訓練!
@@ -364,13 +448,13 @@ diff --git a/app/citizen-frontend/src/plugins/i18n.ts b/app/citizen-frontend/src/plugins/i18n.ts index 73640f9..8ac3e3e 100644 --- a/app/citizen-frontend/src/plugins/i18n.ts +++ b/app/citizen-frontend/src/plugins/i18n.ts @@ -1,21 +1,21 @@ -import { createI18n } from 'vue-i18n' +import { createI18n } from "vue-i18n"; const messages = { en: { message: { - hello: 'hello world', + hello: "hello world", }, }, ja: { message: { - hello: 'こんにちは、世界', + hello: "こんにちは、世界", }, }, -} +}; export default createI18n({ legacy: false, - locale: 'en', - fallbackLocale: 'en', + locale: "en", + fallbackLocale: "en", messages, -}) +}); diff --git a/app/citizen-frontend/src/plugins/index.ts b/app/citizen-frontend/src/plugins/index.ts index 4132982..3501c66 100644 --- a/app/citizen-frontend/src/plugins/index.ts +++ b/app/citizen-frontend/src/plugins/index.ts @@ -5,18 +5,18 @@ */ // Types -import type { App } from 'vue' +import type { App } from "vue"; -import { createPinia } from 'pinia' +import { createPinia } from "pinia"; // Plugins -import router from '../router' -import i18n from './i18n' -import vuetify from './vuetify' +import router from "../router"; +import i18n from "./i18n"; +import vuetify from "./vuetify"; -export function registerPlugins (app: App) { - app.use(vuetify) - app.use(createPinia()) - app.use(i18n) - app.use(router) +export function registerPlugins(app: App) { + app.use(vuetify); + app.use(createPinia()); + app.use(i18n); + app.use(router); } diff --git a/app/citizen-frontend/src/plugins/vuetify.ts b/app/citizen-frontend/src/plugins/vuetify.ts index 047fbea..199b59c 100644 --- a/app/citizen-frontend/src/plugins/vuetify.ts +++ b/app/citizen-frontend/src/plugins/vuetify.ts @@ -5,43 +5,43 @@ */ // Composables -import { createVuetify, type ThemeDefinition } from 'vuetify' -import { zhHant } from 'vuetify/locale' +import { createVuetify, type ThemeDefinition } from "vuetify"; +import { zhHant } from "vuetify/locale"; // Styles -import '@mdi/font/css/materialdesignicons.css' -import 'vuetify/styles' +import "@mdi/font/css/materialdesignicons.css"; +import "vuetify/styles"; const HPTheme: ThemeDefinition = { dark: false, colors: { - 'background': '#F0F9F6', // 頁面背景 - 'surface': '#FFFFFF', // 卡片與白底區塊 - 'primary': '#1D7063', // 主要品牌色 - 'primary-darken-1': '#145248', - 'secondary': '#dc5349', // CTA 按鈕 - 'secondary-darken-1': '#ab4c3d', - 'accent': '#47C2A6', // 標籤與強調 - 'error': '#B00020', - 'info': '#2196F3', - 'success': '#4CAF50', - 'warning': '#FB8C00', + background: "#F0F9F6", // 頁面背景 + surface: "#FFFFFF", // 卡片與白底區塊 + primary: "#1D7063", // 主要品牌色 + "primary-darken-1": "#145248", + secondary: "#dc5349", // CTA 按鈕 + "secondary-darken-1": "#ab4c3d", + accent: "#47C2A6", // 標籤與強調 + error: "#B00020", + info: "#2196F3", + success: "#4CAF50", + warning: "#FB8C00", }, -} +}; // https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides export default createVuetify({ locale: { - locale: 'zhHant', - fallback: 'zhHant', + locale: "zhHant", + fallback: "zhHant", messages: { zhHant }, }, date: { locale: { - zhHant: 'zh-TW', + zhHant: "zh-TW", }, }, theme: { - defaultTheme: 'HPTheme', + defaultTheme: "HPTheme", themes: { HPTheme }, }, -}) +}); diff --git a/app/citizen-frontend/src/router/index.ts b/app/citizen-frontend/src/router/index.ts index bf1e60e..670c450 100644 --- a/app/citizen-frontend/src/router/index.ts +++ b/app/citizen-frontend/src/router/index.ts @@ -1,79 +1,80 @@ -import { createRouter, createWebHistory } from 'vue-router' -import Appointment from '@/pages/appointment.vue' -import Checkin from '@/pages/checkin.vue' -import CheckinDetail from '@/pages/checkinDetail.vue' -import Course from '@/pages/course.vue' -import Index from '@/pages/index.vue' -import Introduction from '@/pages/introduction.vue' -import Login from '@/pages/login.vue' -import SelfAssessment from '@/pages/self-assessment.vue' -import { useAppStore } from '@/stores/app' +import { createRouter, createWebHistory } from "vue-router"; +import Appointment from "@/pages/appointment.vue"; +import Checkin from "@/pages/checkin.vue"; +import CheckinDetail from "@/pages/checkinDetail.vue"; +import Course from "@/pages/course.vue"; +import Index from "@/pages/index.vue"; +import Introduction from "@/pages/introduction.vue"; +import Login from "@/pages/login.vue"; +import SelfAssessment from "@/pages/self-assessment.vue"; +import { useAppStore } from "@/stores/app"; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), - scrollBehavior () { - return { left: 0, top: 0 } + scrollBehavior() { + return { left: 0, top: 0 }; }, routes: [ { - path: '/', - name: 'home', + path: "/", + name: "home", component: Index, }, { - path: '/introduction', - name: 'introduction', + path: "/introduction", + name: "introduction", component: Introduction, - meta: { title: '計畫簡介|運動玩轉健康力' }, + meta: { title: "計畫簡介|運動玩轉健康力" }, }, { - path: '/login', - name: 'login', + path: "/login", + name: "login", component: Login, }, { - path: '/self-assessment', - name: 'self-assessment', + path: "/self-assessment", + name: "self-assessment", component: SelfAssessment, }, { - path: '/appointment', - name: 'appointment', + path: "/appointment", + name: "appointment", component: Appointment, meta: { requiresAuth: true }, }, { - path: '/course', - name: 'course', + path: "/course", + name: "course", component: Course, - meta: { requiresAuth: true, title: '課程建議|運動玩轉健康力' }, + meta: { requiresAuth: true, title: "課程建議|運動玩轉健康力" }, }, { - path: '/checkin', - name: 'checkin', + path: "/checkin", + name: "checkin", component: Checkin, meta: { requiresAuth: true }, }, { - path: '/checkin/:code', - name: 'checkin-detail', + path: "/checkin/:code", + name: "checkin-detail", component: CheckinDetail, meta: { requiresAuth: true }, }, ], -}) +}); // 簡單的導航守衛:只有標記需要登入的頁面會導向登入頁 -router.beforeEach(to => { - const store = useAppStore() +router.beforeEach((to) => { + const store = useAppStore(); if (to.meta.requiresAuth && !store.isLoggedIn) { - return { name: 'login' } + return { name: "login" }; } -}) +}); -router.afterEach(to => { - document.title = typeof to.meta.title === 'string' ? to.meta.title : '運動玩轉健康力' -}) +router.afterEach((to) => { + document.title = + typeof to.meta.title === "string" ? to.meta.title : "運動玩轉健康力"; +}); -export default router +export default router; diff --git a/app/citizen-frontend/src/stores/app.ts b/app/citizen-frontend/src/stores/app.ts index 2ffddd5..5fd6d3c 100644 --- a/app/citizen-frontend/src/stores/app.ts +++ b/app/citizen-frontend/src/stores/app.ts @@ -1,365 +1,377 @@ -import { defineStore } from 'pinia' -import { computed, ref } from 'vue' -import { login as apiLogin } from '@/api/auth' +import { defineStore } from "pinia"; +import { computed, ref } from "vue"; +import { login as apiLogin } from "@/api/auth"; /** 後端尚未完成前保持 true,改為 false 才會實際呼叫登入 API */ -const USE_MOCK = import.meta.env.VITE_USE_MOCK !== 'false' +const USE_MOCK = import.meta.env.VITE_USE_MOCK !== "false"; export interface UserProfile { - name: string - birthday: string - gender: string - height: number - weight: number - phone: string - email: string - emergencyContact: string - emergencyPhone: string - consent: boolean + name: string; + birthday: string; + gender: string; + height: number; + weight: number; + phone: string; + email: string; + emergencyContact: string; + emergencyPhone: string; + consent: boolean; } export interface SelfAssessment { - exerciseFrequency: string - painLevel: string - hasFalls: boolean - chronicDiseases: string[] - wantedImprovements: string[] - scoreLevel: string - completed: boolean + exerciseFrequency: string; + painLevel: string; + hasFalls: boolean; + chronicDiseases: string[]; + wantedImprovements: string[]; + scoreLevel: string; + completed: boolean; } export interface Appointment { - id: string - title: string - date: string - time: string - location: string - status: '未報名' | '已報名' | '已報到' - slots: number - organizer: string - items: string[] + id: string; + title: string; + date: string; + time: string; + location: string; + status: "未報名" | "已報名" | "已報到"; + slots: number; + organizer: string; + items: string[]; } export interface MeasurementStation { - name: string - completed: boolean - time?: string - values: Record + name: string; + completed: boolean; + time?: string; + values: Record; } -function createDefaultUserProfile (): UserProfile { +function createDefaultUserProfile(): UserProfile { return { - name: '林大明', - birthday: '1961-08-15', - gender: '男', + name: "林大明", + birthday: "1961-08-15", + gender: "男", height: 168, weight: 65, - phone: '0912-345-678', - email: 'jianguo.lin@email.com', - emergencyContact: '林小明 (長子)', - emergencyPhone: '0987-654-321', + phone: "0912-345-678", + email: "jianguo.lin@email.com", + emergencyContact: "林小明 (長子)", + emergencyPhone: "0987-654-321", consent: true, - } + }; } -function createDefaultSelfAssessment (): SelfAssessment { +function createDefaultSelfAssessment(): SelfAssessment { return { - exerciseFrequency: '1-2', - painLevel: '輕微', + exerciseFrequency: "1-2", + painLevel: "輕微", hasFalls: false, - chronicDiseases: ['高血壓'], - wantedImprovements: ['肌力', '平衡'], - scoreLevel: '需追蹤', + chronicDiseases: ["高血壓"], + wantedImprovements: ["肌力", "平衡"], + scoreLevel: "需追蹤", completed: true, - } + }; } -function createDefaultAppointments (): Appointment[] { +function createDefaultAppointments(): Appointment[] { const measurementItems = [ - '血壓', - '體脂', - '握力', - '5次坐站', - '30秒椅子坐立', - '原地抬膝踏步', - '手臂屈舉', - '抓背測驗', - '坐姿體前彎', - '2.44米繞物', - '開眼單足立', - ] - const location = '信義區運動中心 3 樓多功能教室' - const organizer = '臺北市政府體育局' + "血壓", + "體脂", + "握力", + "5次坐站", + "30秒椅子坐立", + "原地抬膝踏步", + "手臂屈舉", + "抓背測驗", + "坐姿體前彎", + "2.44米繞物", + "開眼單足立", + ]; + const location = "信義區運動中心 3 樓多功能教室"; + const organizer = "臺北市政府體育局"; return [ { - id: 'apt-01', - title: '銀髮活力公益普測 A 時段', - date: '2026-07-04', - time: '09:00 - 10:00', + id: "apt-01", + title: "銀髮活力公益普測 A 時段", + date: "2026-07-04", + time: "09:00 - 10:00", location, - status: '已報名', + status: "已報名", slots: 12, organizer, items: measurementItems, }, { - id: 'apt-02', - title: '銀髮活力公益普測 B 時段', - date: '2026-07-04', - time: '10:30 - 11:30', + id: "apt-02", + title: "銀髮活力公益普測 B 時段", + date: "2026-07-04", + time: "10:30 - 11:30", location, - status: '已報到', + status: "已報到", slots: 5, organizer, items: measurementItems, }, { - id: 'apt-03', - title: '銀髮活力公益普測 C 時段', - date: '2026-07-04', - time: '13:30 - 14:30', + id: "apt-03", + title: "銀髮活力公益普測 C 時段", + date: "2026-07-04", + time: "13:30 - 14:30", location, - status: '未報名', + status: "未報名", slots: 45, organizer, items: measurementItems, }, - ] + ]; } -function createDefaultMeasurements (): Record { +function createDefaultMeasurements(): Record { return { BloodPressure: { - name: '血壓量測', + name: "血壓量測", completed: true, - time: '2026-06-18 15:00', + time: "2026-06-18 15:00", values: { systolic: 132, diastolic: 84, heartRate: 72 }, }, BodyFat: { - name: '體組成分析', + name: "體組成分析", completed: true, - time: '2026-06-18 15:05', + time: "2026-06-18 15:05", values: { bmi: 23, bodyFatPct: 24.5 }, }, GripStrength: { - name: '左右握力', + name: "左右握力", completed: false, values: { leftHand: 0, rightHand: 0 }, }, Sit5x: { - name: '5次坐站測試', + name: "5次坐站測試", completed: false, values: { durationSeconds: 0 }, }, Sit30s: { - name: '30秒椅子坐立', + name: "30秒椅子坐立", completed: false, values: { count: 0 }, }, StepTest: { - name: '2分鐘原地抬膝踏步', + name: "2分鐘原地抬膝踏步", completed: false, values: { count: 0 }, }, ArmTest: { - name: '30秒肱二頭肌手臂屈舉', + name: "30秒肱二頭肌手臂屈舉", completed: false, values: { count: 0 }, }, BackTest: { - name: '抓背測驗(柔軟度)', + name: "抓背測驗(柔軟度)", completed: false, values: { leftDistanceCm: 0, rightDistanceCm: 0 }, }, SitReachTest: { - name: '坐姿體前彎(柔軟度)', + name: "坐姿體前彎(柔軟度)", completed: false, values: { distanceCm: 0 }, }, UpGo8ft: { - name: '2.44公尺起立繞物(敏捷)', + name: "2.44公尺起立繞物(敏捷)", completed: false, values: { durationSeconds: 0 }, }, OneLegTest: { - name: '開眼單足立(平衡)', + name: "開眼單足立(平衡)", completed: false, values: { leftSeconds: 0, rightSeconds: 0 }, }, - } + }; } -function createDefaultRadarData () { +function createDefaultRadarData() { return { strength: 65, balance: 60, flexibility: 55, agility: 70, cardio: 62, - } + }; } -export const useAppStore = defineStore('app', () => { - const isLoggedIn = ref(false) +export const useAppStore = defineStore("app", () => { + const isLoggedIn = ref(false); /** 登入取得的使用者識別碼,課程建議等 API 需要此值查詢 */ - const userID = ref('') - const userProfile = ref(createDefaultUserProfile()) - const selfAssessment = ref(createDefaultSelfAssessment()) - const appointments = ref(createDefaultAppointments()) - const measurements = ref>(createDefaultMeasurements()) - const healthScore = ref(72) - const radarData = ref(createDefaultRadarData()) - const isReportGenerated = ref(false) + const userID = ref(""); + const userProfile = ref(createDefaultUserProfile()); + const selfAssessment = ref(createDefaultSelfAssessment()); + const appointments = ref(createDefaultAppointments()); + const measurements = ref>( + createDefaultMeasurements(), + ); + const healthScore = ref(72); + const radarData = ref(createDefaultRadarData()); + const isReportGenerated = ref(false); const completedStationsCount = computed(() => { - return Object.values(measurements.value).filter(station => station.completed).length - }) + return Object.values(measurements.value).filter( + (station) => station.completed, + ).length; + }); const totalStationsCount = computed(() => { - return Object.keys(measurements.value).length - }) + return Object.keys(measurements.value).length; + }); const progressPercent = computed((): number => { - const keys = Object.keys(measurements.value) + const keys = Object.keys(measurements.value); if (keys.length === 0) { - return 0 + return 0; } - const done = Object.values(measurements.value).filter(station => station.completed).length - return Math.round((done / keys.length) * 100) - }) + const done = Object.values(measurements.value).filter( + (station) => station.completed, + ).length; + return Math.round((done / keys.length) * 100); + }); /** 手機門號登入;後端未完成時走模擬資料,完成後設 VITE_USE_MOCK=false 改打真實 API */ - async function login (phone: string) { + async function login(phone: string) { if (USE_MOCK) { - isLoggedIn.value = true - userID.value = 'MOCK-USER' - userProfile.value.phone = phone - return + isLoggedIn.value = true; + userID.value = "MOCK-USER"; + userProfile.value.phone = phone; + return; } - const response = await apiLogin(phone) + const response = await apiLogin(phone); - isLoggedIn.value = true - userID.value = response.userID - userProfile.value.phone = response.phone - userProfile.value.name = response.userName + isLoggedIn.value = true; + userID.value = response.userID; + userProfile.value.phone = response.phone; + userProfile.value.name = response.userName; } - function logout () { - isLoggedIn.value = false - userID.value = '' + function logout() { + isLoggedIn.value = false; + userID.value = ""; } - function updateProfile (profile: Partial) { - userProfile.value = { ...userProfile.value, ...profile } + function updateProfile(profile: Partial) { + userProfile.value = { ...userProfile.value, ...profile }; } - function submitSelfAssessment (answers: Partial) { + function submitSelfAssessment(answers: Partial) { selfAssessment.value = { ...selfAssessment.value, ...answers, completed: true, - } + }; - let level = '低風險' - if (answers.exerciseFrequency === '0' || answers.hasFalls === true) { - level = '需追蹤' + let level = "低風險"; + if (answers.exerciseFrequency === "0" || answers.hasFalls === true) { + level = "需追蹤"; } if ( - answers.painLevel === '中度' - || answers.painLevel === '重度' - || (answers.chronicDiseases && answers.chronicDiseases.length >= 2) + answers.painLevel === "中度" || + answers.painLevel === "重度" || + (answers.chronicDiseases && answers.chronicDiseases.length >= 2) ) { - level = '建議諮詢' + level = "建議諮詢"; } - selfAssessment.value.scoreLevel = level + selfAssessment.value.scoreLevel = level; } - function registerAppointment (appointmentId: string) { - const appointment = appointments.value.find(item => item.id === appointmentId) + function registerAppointment(appointmentId: string) { + const appointment = appointments.value.find( + (item) => item.id === appointmentId, + ); if (!appointment) { - return + return; } - appointment.status = '已報名' - appointment.slots -= 1 + appointment.status = "已報名"; + appointment.slots -= 1; } - function cancelAppointment (appointmentId: string) { - const appointment = appointments.value.find(item => item.id === appointmentId) + function cancelAppointment(appointmentId: string) { + const appointment = appointments.value.find( + (item) => item.id === appointmentId, + ); if (!appointment) { - return + return; } - appointment.status = '未報名' - appointment.slots += 1 + appointment.status = "未報名"; + appointment.slots += 1; } - function checkinAppointment (appointmentId: string) { - const appointment = appointments.value.find(item => item.id === appointmentId) + function checkinAppointment(appointmentId: string) { + const appointment = appointments.value.find( + (item) => item.id === appointmentId, + ); if (!appointment) { - return + return; } - appointment.status = '已報到' + appointment.status = "已報到"; } - function saveMeasurement (code: string, values: Record) { - const measurement = measurements.value[code] + function saveMeasurement(code: string, values: Record) { + const measurement = measurements.value[code]; if (!measurement) { - return + return; } - const now = new Date() - const timeStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}` + const now = new Date(); + const timeStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")} ${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`; - measurement.values = { ...values } - measurement.completed = true - measurement.time = timeStr + measurement.values = { ...values }; + measurement.completed = true; + measurement.time = timeStr; } - function generateFinalReport () { - const currentMeasurements = measurements.value + function generateFinalReport() { + const currentMeasurements = measurements.value; - let strScore = 65 + let strScore = 65; if (currentMeasurements.GripStrength.completed) { - const avgGrip - = ((currentMeasurements.GripStrength.values.leftHand || 0) - + (currentMeasurements.GripStrength.values.rightHand || 0)) - / 2 - const limit = userProfile.value.gender === '男' ? 30 : 20 - strScore = Math.min(95, Math.max(50, Math.round((avgGrip / limit) * 75))) + const avgGrip = + ((currentMeasurements.GripStrength.values.leftHand || 0) + + (currentMeasurements.GripStrength.values.rightHand || 0)) / + 2; + const limit = userProfile.value.gender === "男" ? 30 : 20; + strScore = Math.min(95, Math.max(50, Math.round((avgGrip / limit) * 75))); } - let balScore = 60 + let balScore = 60; if (currentMeasurements.OneLegTest.completed) { const maxSec = Math.max( currentMeasurements.OneLegTest.values.leftSeconds || 0, currentMeasurements.OneLegTest.values.rightSeconds || 0, - ) - balScore = Math.min(98, Math.max(40, Math.round((maxSec / 30) * 90))) + ); + balScore = Math.min(98, Math.max(40, Math.round((maxSec / 30) * 90))); } - let flexScore = 55 + let flexScore = 55; if (currentMeasurements.SitReachTest.completed) { - const dist = currentMeasurements.SitReachTest.values.distanceCm || 0 - flexScore = Math.min(95, Math.max(45, 60 + dist * 1.5)) + const dist = currentMeasurements.SitReachTest.values.distanceCm || 0; + flexScore = Math.min(95, Math.max(45, 60 + dist * 1.5)); } - let agiScore = 70 + let agiScore = 70; if (currentMeasurements.UpGo8ft.completed) { - const sec = currentMeasurements.UpGo8ft.values.durationSeconds || 10 - agiScore = Math.min(95, Math.max(40, Math.round(100 - sec * 5))) + const sec = currentMeasurements.UpGo8ft.values.durationSeconds || 10; + agiScore = Math.min(95, Math.max(40, Math.round(100 - sec * 5))); } - let cardScore = 62 + let cardScore = 62; if (currentMeasurements.StepTest.completed) { - const count = currentMeasurements.StepTest.values.count || 60 - cardScore = Math.min(95, Math.max(45, Math.round((count / 80) * 80))) + const count = currentMeasurements.StepTest.values.count || 60; + cardScore = Math.min(95, Math.max(45, Math.round((count / 80) * 80))); } radarData.value = { @@ -368,27 +380,29 @@ export const useAppStore = defineStore('app', () => { flexibility: flexScore, agility: agiScore, cardio: cardScore, - } + }; - const avg = Math.round((strScore + balScore + flexScore + agiScore + cardScore) / 5) - healthScore.value = Math.min(100, avg + 5) - isReportGenerated.value = true + const avg = Math.round( + (strScore + balScore + flexScore + agiScore + cardScore) / 5, + ); + healthScore.value = Math.min(100, avg + 5); + isReportGenerated.value = true; } - function resetMeasurements () { + function resetMeasurements() { for (const [key, measurement] of Object.entries(measurements.value)) { - if (key !== 'BloodPressure' && key !== 'BodyFat') { - measurement.completed = false + if (key !== "BloodPressure" && key !== "BodyFat") { + measurement.completed = false; for (const valueKey of Object.keys(measurement.values)) { - measurement.values[valueKey] = 0 + measurement.values[valueKey] = 0; } } } - isReportGenerated.value = false - healthScore.value = 72 - radarData.value = createDefaultRadarData() + isReportGenerated.value = false; + healthScore.value = 72; + radarData.value = createDefaultRadarData(); } return { @@ -414,5 +428,5 @@ export const useAppStore = defineStore('app', () => { saveMeasurement, generateFinalReport, resetMeasurements, - } -}) + }; +}); diff --git a/app/citizen-frontend/src/stores/course.ts b/app/citizen-frontend/src/stores/course.ts index 8e16a34..168ed56 100644 --- a/app/citizen-frontend/src/stores/course.ts +++ b/app/citizen-frontend/src/stores/course.ts @@ -5,225 +5,331 @@ import type { FitnessGroup, TimeSlot, YesNo, -} from '@/api/types' -import { defineStore } from 'pinia' -import { computed, ref } from 'vue' +} from "@/api/types"; +import { defineStore } from "pinia"; +import { computed, ref } from "vue"; import { fetchCourseList, fetchGroup, fetchMorning, fetchNight, fetchNoon, -} from '@/api/course' -import { useAppStore } from '@/stores/app' +} from "@/api/course"; +import { useAppStore } from "@/stores/app"; /** 後端尚未完成,預設走前端模擬資料;設定 VITE_USE_MOCK=false 即改打真實 API */ -const USE_MOCK = import.meta.env.VITE_USE_MOCK !== 'false' +const USE_MOCK = import.meta.env.VITE_USE_MOCK !== "false"; /** 模擬網路延遲,讓載入狀態在開發時可被觀察到 */ -const MOCK_DELAY = 300 +const MOCK_DELAY = 300; export interface GroupMeta { - label: string - color: string + label: string; + color: string; /** 以活動強度遞增的圖示表達組別高低,讓組別不只靠顏色辨識 */ - icon: string - description: string + icon: string; + description: string; } /** 組別的顯示資訊,文案取自 doc/課程說明.md */ export const GROUP_META: Record = { low: { - label: '低體適能', - color: 'warning', - icon: 'mdi-walk', - description: '肌力、平衡與心肺功能較弱,以降低跌倒風險、重建日常生活功能為優先。', + label: "低體適能", + color: "warning", + icon: "mdi-walk", + description: + "肌力、平衡與心肺功能較弱,以降低跌倒風險、重建日常生活功能為優先。", }, medium: { - label: '中體適能', - color: 'info', - icon: 'mdi-run', - description: '尚未失能但已出現部分衰退,重點在累積功能儲備、增加肌肉量與心肺能力。', + label: "中體適能", + color: "info", + icon: "mdi-run", + description: + "尚未失能但已出現部分衰退,重點在累積功能儲備、增加肌肉量與心肺能力。", }, high: { - label: '高體適能', - color: 'success', - icon: 'mdi-run-fast', - description: '功能儲備高、跌倒風險低,目標是延緩衰退速度並長期維持既有功能。', + label: "高體適能", + color: "success", + icon: "mdi-run-fast", + description: + "功能儲備高、跌倒風險低,目標是延緩衰退速度並長期維持既有功能。", }, -} +}; /** * 三組一週課表,內容逐格轉錄自 doc/課程表.png。 * 後端完成後這份資料會由第 5 支 API 提供。 */ -function createCourseTable (): Record { +function createCourseTable(): Record { return { low: [ - { day: 1, morning: '慢走 15 分鐘', noon: '正常飲食,多吃蔬菜與蛋白質', night: '坐站訓練 10 次 ×2 組+伸展 10 分鐘' }, - { day: 2, morning: '公園散步 20 分鐘', noon: '1 顆蛋+豆漿', night: '單腳站立和平衡訓練 15 分鐘' }, - { day: 3, morning: '慢走 15 分鐘', noon: '魚肉與青菜', night: '扶牆踮腳 15 次 ×2 組' }, - { day: 4, morning: '休閒散步 20 分鐘', noon: '補充水果', night: '伸展運動 10 分鐘' }, - { day: 5, morning: '慢走 20 分鐘', noon: '雞肉與蔬菜', night: '坐站訓練+平衡訓練' }, - { day: 6, morning: '腳踏車或散步 30 分鐘', noon: '均衡飲食', night: '全身伸展' }, - { day: 7, morning: '輕鬆散步', noon: '與家人共餐', night: '早睡休息' }, + { + day: 1, + morning: "慢走 15 分鐘", + noon: "正常飲食,多吃蔬菜與蛋白質", + night: "坐站訓練 10 次 ×2 組+伸展 10 分鐘", + }, + { + day: 2, + morning: "公園散步 20 分鐘", + noon: "1 顆蛋+豆漿", + night: "單腳站立和平衡訓練 15 分鐘", + }, + { + day: 3, + morning: "慢走 15 分鐘", + noon: "魚肉與青菜", + night: "扶牆踮腳 15 次 ×2 組", + }, + { + day: 4, + morning: "休閒散步 20 分鐘", + noon: "補充水果", + night: "伸展運動 10 分鐘", + }, + { + day: 5, + morning: "慢走 20 分鐘", + noon: "雞肉與蔬菜", + night: "坐站訓練+平衡訓練", + }, + { + day: 6, + morning: "腳踏車或散步 30 分鐘", + noon: "均衡飲食", + night: "全身伸展", + }, + { day: 7, morning: "輕鬆散步", noon: "與家人共餐", night: "早睡休息" }, ], medium: [ - { day: 1, morning: '快走 30 分鐘', noon: '高蛋白午餐', night: '深蹲 15 次 ×3 組' }, - { day: 2, morning: '騎腳踏車 40 分鐘', noon: '水果與豆類', night: '伸展 15 分鐘' }, - { day: 3, morning: '快走 30 分鐘', noon: '魚肉與蔬菜', night: '彈力帶訓練' }, - { day: 4, morning: '游泳或太極 40 分鐘', noon: '均衡飲食', night: '核心訓練 15 分鐘' }, - { day: 5, morning: '快走 30 分鐘', noon: '高蛋白午餐', night: '深蹲+彈力帶' }, - { day: 6, morning: '郊山健行 60 分鐘', noon: '補充水分', night: '輕鬆散步' }, - { day: 7, morning: '休息', noon: '家人聚餐', night: '伸展 10 分鐘' }, + { + day: 1, + morning: "快走 30 分鐘", + noon: "高蛋白午餐", + night: "深蹲 15 次 ×3 組", + }, + { + day: 2, + morning: "騎腳踏車 40 分鐘", + noon: "水果與豆類", + night: "伸展 15 分鐘", + }, + { + day: 3, + morning: "快走 30 分鐘", + noon: "魚肉與蔬菜", + night: "彈力帶訓練", + }, + { + day: 4, + morning: "游泳或太極 40 分鐘", + noon: "均衡飲食", + night: "核心訓練 15 分鐘", + }, + { + day: 5, + morning: "快走 30 分鐘", + noon: "高蛋白午餐", + night: "深蹲+彈力帶", + }, + { + day: 6, + morning: "郊山健行 60 分鐘", + noon: "補充水分", + night: "輕鬆散步", + }, + { day: 7, morning: "休息", noon: "家人聚餐", night: "伸展 10 分鐘" }, ], high: [ - { day: 1, morning: '重量訓練 60 分鐘', noon: '蛋白質與蔬菜', night: '散步 20 分鐘' }, - { day: 2, morning: '快走或慢跑 45 分鐘', noon: '水果與堅果', night: '核心訓練 20 分鐘' }, - { day: 3, morning: '平衡與敏捷訓練 40 分鐘', noon: '均衡飲食', night: '伸展 15 分鐘' }, - { day: 4, morning: '重量訓練 60 分鐘', noon: '高蛋白午餐', night: '散步 20 分鐘' }, - { day: 5, morning: '間歇跑 30 分鐘', noon: '補充水分', night: '輕量伸展' }, - { day: 6, morning: '登山、羽球或游泳 90 分鐘', noon: '魚類與蔬菜', night: '放鬆休息' }, - { day: 7, morning: '輕鬆散步 30 分鐘', noon: '家人聚餐', night: '早睡恢復' }, + { + day: 1, + morning: "重量訓練 60 分鐘", + noon: "蛋白質與蔬菜", + night: "散步 20 分鐘", + }, + { + day: 2, + morning: "快走或慢跑 45 分鐘", + noon: "水果與堅果", + night: "核心訓練 20 分鐘", + }, + { + day: 3, + morning: "平衡與敏捷訓練 40 分鐘", + noon: "均衡飲食", + night: "伸展 15 分鐘", + }, + { + day: 4, + morning: "重量訓練 60 分鐘", + noon: "高蛋白午餐", + night: "散步 20 分鐘", + }, + { + day: 5, + morning: "間歇跑 30 分鐘", + noon: "補充水分", + night: "輕量伸展", + }, + { + day: 6, + morning: "登山、羽球或游泳 90 分鐘", + noon: "魚類與蔬菜", + night: "放鬆休息", + }, + { + day: 7, + morning: "輕鬆散步 30 分鐘", + noon: "家人聚餐", + night: "早睡恢復", + }, ], - } + }; } -function delay (ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)) +function delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); } /** 模擬後端依 Y/N 篩選時段欄位的行為 */ -function mockCourseList (params: CourseListParams): CourseList { - return createCourseTable()[params.group].map(row => { - const filtered: CourseRow = { day: row.day } +function mockCourseList(params: CourseListParams): CourseList { + return createCourseTable()[params.group].map((row) => { + const filtered: CourseRow = { day: row.day }; - if (params.morning === 'Y') { - filtered.morning = row.morning + if (params.morning === "Y") { + filtered.morning = row.morning; } - if (params.noon === 'Y') { - filtered.noon = row.noon + if (params.noon === "Y") { + filtered.noon = row.noon; } - if (params.night === 'Y') { - filtered.night = row.night + if (params.night === "Y") { + filtered.night = row.night; } - return filtered - }) + return filtered; + }); } -export const useCourseStore = defineStore('course', () => { - const group = ref('medium') - const morning = ref('Y') - const noon = ref('Y') - const night = ref('Y') - const courseList = ref([]) - const loading = ref(false) - const error = ref('') +export const useCourseStore = defineStore("course", () => { + const group = ref("medium"); + const morning = ref("Y"); + const noon = ref("Y"); + const night = ref("Y"); + const courseList = ref([]); + const loading = ref(false); + const error = ref(""); - const groupMeta = computed(() => GROUP_META[group.value]) + const groupMeta = computed(() => GROUP_META[group.value]); /** 目前被選取的時段,供畫面判斷要顯示哪些欄位 */ const selectedSlots = computed(() => { - const slots: TimeSlot[] = [] + const slots: TimeSlot[] = []; - if (morning.value === 'Y') { - slots.push('morning') + if (morning.value === "Y") { + slots.push("morning"); } - if (noon.value === 'Y') { - slots.push('noon') + if (noon.value === "Y") { + slots.push("noon"); } - if (night.value === 'Y') { - slots.push('night') + if (night.value === "Y") { + slots.push("night"); } - return slots - }) + return slots; + }); - const hasCourse = computed(() => selectedSlots.value.length > 0 && courseList.value.length > 0) + const hasCourse = computed( + () => selectedSlots.value.length > 0 && courseList.value.length > 0, + ); /** 前 4 支 API:平行取得組別與三個時段設定 */ - async function loadPreferences () { + async function loadPreferences() { if (USE_MOCK) { - await delay(MOCK_DELAY) - group.value = 'medium' - morning.value = 'Y' - noon.value = 'Y' - night.value = 'Y' - return + await delay(MOCK_DELAY); + group.value = "medium"; + morning.value = "Y"; + noon.value = "Y"; + night.value = "Y"; + return; } // 真實後端:course/group 需要 userID,course/morning、noon、night 需要 group, // 兩者有相依順序,因此無法四支平行呼叫(與 doc/課程建議API規格.md 的示意圖不同, // 以 doc/課程建議_API_前端使用說明_20260806.md 的建議測試流程為準) - const { userID } = useAppStore() - const groupValue = await fetchGroup(userID) + const { userID } = useAppStore(); + const groupValue = await fetchGroup(userID); const [morningValue, noonValue, nightValue] = await Promise.all([ fetchMorning(groupValue), fetchNoon(groupValue), fetchNight(groupValue), - ]) + ]); - group.value = groupValue - morning.value = morningValue - noon.value = noonValue - night.value = nightValue + group.value = groupValue; + morning.value = morningValue; + noon.value = noonValue; + night.value = nightValue; } /** 第 5 支 API:以前 4 個值為參數取得課表 */ - async function loadCourseList () { + async function loadCourseList() { const params: CourseListParams = { group: group.value, morning: morning.value, noon: noon.value, night: night.value, - } + }; if (USE_MOCK) { - await delay(MOCK_DELAY) - courseList.value = mockCourseList(params) - return + await delay(MOCK_DELAY); + courseList.value = mockCourseList(params); + return; } - courseList.value = await fetchCourseList(params) + courseList.value = await fetchCourseList(params); } /** 頁面進入時呼叫:先取設定再取課表 */ - async function loadAll () { - loading.value = true - error.value = '' + async function loadAll() { + loading.value = true; + error.value = ""; try { - await loadPreferences() - await loadCourseList() + await loadPreferences(); + await loadCourseList(); } catch (error_) { - error.value = error_ instanceof Error ? error_.message : '課程資料載入失敗,請稍後再試。' - courseList.value = [] + error.value = + error_ instanceof Error + ? error_.message + : "課程資料載入失敗,請稍後再試。"; + courseList.value = []; } finally { - loading.value = false + loading.value = false; } } /** 使用者切換時段後重新取課表 */ - async function setSlot (slot: TimeSlot, value: YesNo) { - const target = { morning, noon, night }[slot] + async function setSlot(slot: TimeSlot, value: YesNo) { + const target = { morning, noon, night }[slot]; if (target.value === value) { - return + return; } - target.value = value - loading.value = true - error.value = '' + target.value = value; + loading.value = true; + error.value = ""; try { - await loadCourseList() + await loadCourseList(); } catch (error_) { - error.value = error_ instanceof Error ? error_.message : '課程資料載入失敗,請稍後再試。' - courseList.value = [] + error.value = + error_ instanceof Error + ? error_.message + : "課程資料載入失敗,請稍後再試。"; + courseList.value = []; } finally { - loading.value = false + loading.value = false; } } @@ -242,5 +348,5 @@ export const useCourseStore = defineStore('course', () => { loadCourseList, loadPreferences, setSlot, - } -}) + }; +}); diff --git a/app/citizen-frontend/src/styles/settings.scss b/app/citizen-frontend/src/styles/settings.scss index 65cb84e..7daa354 100644 --- a/app/citizen-frontend/src/styles/settings.scss +++ b/app/citizen-frontend/src/styles/settings.scss @@ -5,7 +5,13 @@ */ // https://vuetifyjs.com/features/sass-variables/ -@use 'vuetify/settings' with ( - $body-font-family: ('line-seed', sans-serif), - $heading-font-family: ('line-seed', sans-serif) +@use "vuetify/settings" with ( + $body-font-family: ( + "line-seed", + sans-serif, + ), + $heading-font-family: ( + "line-seed", + sans-serif, + ) ); diff --git a/app/citizen-frontend/src/utils/qrcode.ts b/app/citizen-frontend/src/utils/qrcode.ts index d9c511d..32a3dc1 100644 --- a/app/citizen-frontend/src/utils/qrcode.ts +++ b/app/citizen-frontend/src/utils/qrcode.ts @@ -1,105 +1,199 @@ -type Cell = boolean | null +type Cell = boolean | null; interface BlockGroup { - count: number - dataCodewords: number + count: number; + dataCodewords: number; } interface VersionSpec { - version: number - size: number - dataCodewords: number - eccCodewords: number - blockGroups: BlockGroup[] - capacity: number - alignment: number[] + version: number; + size: number; + dataCodewords: number; + eccCodewords: number; + blockGroups: BlockGroup[]; + capacity: number; + alignment: number[]; } export interface QrCodeMatrix { - size: number - modules: boolean[][] + size: number; + modules: boolean[][]; } const VERSION_SPECS: VersionSpec[] = [ - { version: 1, size: 21, dataCodewords: 16, eccCodewords: 10, blockGroups: [{ count: 1, dataCodewords: 16 }], capacity: 14, alignment: [] }, - { version: 2, size: 25, dataCodewords: 28, eccCodewords: 16, blockGroups: [{ count: 1, dataCodewords: 28 }], capacity: 26, alignment: [6, 18] }, - { version: 3, size: 29, dataCodewords: 44, eccCodewords: 26, blockGroups: [{ count: 1, dataCodewords: 44 }], capacity: 42, alignment: [6, 22] }, - { version: 4, size: 33, dataCodewords: 64, eccCodewords: 18, blockGroups: [{ count: 2, dataCodewords: 32 }], capacity: 62, alignment: [6, 26] }, - { version: 5, size: 37, dataCodewords: 86, eccCodewords: 24, blockGroups: [{ count: 2, dataCodewords: 43 }], capacity: 84, alignment: [6, 30] }, - { version: 6, size: 41, dataCodewords: 108, eccCodewords: 16, blockGroups: [{ count: 4, dataCodewords: 27 }], capacity: 106, alignment: [6, 34] }, - { version: 7, size: 45, dataCodewords: 124, eccCodewords: 18, blockGroups: [{ count: 4, dataCodewords: 31 }], capacity: 122, alignment: [6, 22, 38] }, - { version: 8, size: 49, dataCodewords: 154, eccCodewords: 22, blockGroups: [{ count: 2, dataCodewords: 38 }, { count: 2, dataCodewords: 39 }], capacity: 152, alignment: [6, 24, 42] }, - { version: 9, size: 53, dataCodewords: 182, eccCodewords: 22, blockGroups: [{ count: 3, dataCodewords: 36 }, { count: 2, dataCodewords: 37 }], capacity: 180, alignment: [6, 26, 46] }, - { version: 10, size: 57, dataCodewords: 216, eccCodewords: 26, blockGroups: [{ count: 4, dataCodewords: 43 }, { count: 1, dataCodewords: 44 }], capacity: 213, alignment: [6, 28, 50] }, -] + { + version: 1, + size: 21, + dataCodewords: 16, + eccCodewords: 10, + blockGroups: [{ count: 1, dataCodewords: 16 }], + capacity: 14, + alignment: [], + }, + { + version: 2, + size: 25, + dataCodewords: 28, + eccCodewords: 16, + blockGroups: [{ count: 1, dataCodewords: 28 }], + capacity: 26, + alignment: [6, 18], + }, + { + version: 3, + size: 29, + dataCodewords: 44, + eccCodewords: 26, + blockGroups: [{ count: 1, dataCodewords: 44 }], + capacity: 42, + alignment: [6, 22], + }, + { + version: 4, + size: 33, + dataCodewords: 64, + eccCodewords: 18, + blockGroups: [{ count: 2, dataCodewords: 32 }], + capacity: 62, + alignment: [6, 26], + }, + { + version: 5, + size: 37, + dataCodewords: 86, + eccCodewords: 24, + blockGroups: [{ count: 2, dataCodewords: 43 }], + capacity: 84, + alignment: [6, 30], + }, + { + version: 6, + size: 41, + dataCodewords: 108, + eccCodewords: 16, + blockGroups: [{ count: 4, dataCodewords: 27 }], + capacity: 106, + alignment: [6, 34], + }, + { + version: 7, + size: 45, + dataCodewords: 124, + eccCodewords: 18, + blockGroups: [{ count: 4, dataCodewords: 31 }], + capacity: 122, + alignment: [6, 22, 38], + }, + { + version: 8, + size: 49, + dataCodewords: 154, + eccCodewords: 22, + blockGroups: [ + { count: 2, dataCodewords: 38 }, + { count: 2, dataCodewords: 39 }, + ], + capacity: 152, + alignment: [6, 24, 42], + }, + { + version: 9, + size: 53, + dataCodewords: 182, + eccCodewords: 22, + blockGroups: [ + { count: 3, dataCodewords: 36 }, + { count: 2, dataCodewords: 37 }, + ], + capacity: 180, + alignment: [6, 26, 46], + }, + { + version: 10, + size: 57, + dataCodewords: 216, + eccCodewords: 26, + blockGroups: [ + { count: 4, dataCodewords: 43 }, + { count: 1, dataCodewords: 44 }, + ], + capacity: 213, + alignment: [6, 28, 50], + }, +]; -const FORMAT_XOR = 0x54_12 -const FORMAT_POLY = 0x5_37 -const VERSION_POLY = 0x1f_25 +const FORMAT_XOR = 0x54_12; +const FORMAT_POLY = 0x5_37; +const VERSION_POLY = 0x1f_25; -const gfExp = Array.from({ length: 512 }, () => 0) -const gfLog = Array.from({ length: 256 }, () => 0) -let x = 1 +const gfExp = Array.from({ length: 512 }, () => 0); +const gfLog = Array.from({ length: 256 }, () => 0); +let x = 1; for (let i = 0; i < 255; i += 1) { - gfExp[i] = x - gfLog[x] = i - x <<= 1 + gfExp[i] = x; + gfLog[x] = i; + x <<= 1; if (x & 0x1_00) { - x ^= 0x1_1d + x ^= 0x1_1d; } } for (let i = 255; i < 512; i += 1) { - gfExp[i] = gfExp[i - 255] + gfExp[i] = gfExp[i - 255]; } -export function createQrCodeMatrix (value: string): QrCodeMatrix { - const data = [...new TextEncoder().encode(value)] - const spec = VERSION_SPECS.find(item => data.length <= item.capacity) +export function createQrCodeMatrix(value: string): QrCodeMatrix { + const data = [...new TextEncoder().encode(value)]; + const spec = VERSION_SPECS.find((item) => data.length <= item.capacity); if (!spec) { - throw new Error('QR Code 內容過長,請將 payload 控制在 213 bytes 以內') + throw new Error("QR Code 內容過長,請將 payload 控制在 213 bytes 以內"); } - const dataCodewords = createDataCodewords(data, spec) - const codewords = createFinalCodewords(dataCodewords, spec) - const dataBits = codewords.flatMap(codeword => byteToBits(codeword)) - const base = createBaseMatrix(spec) + const dataCodewords = createDataCodewords(data, spec); + const codewords = createFinalCodewords(dataCodewords, spec); + const dataBits = codewords.flatMap((codeword) => byteToBits(codeword)); + const base = createBaseMatrix(spec); - let bestModules = base.modules - let bestScore = Number.POSITIVE_INFINITY + let bestModules = base.modules; + let bestScore = Number.POSITIVE_INFINITY; for (let mask = 0; mask < 8; mask += 1) { - const modules = cloneMatrix(base.modules) - placeDataBits(modules, base.reserved, dataBits, mask) - drawFormatBits(modules, spec.size, mask) + const modules = cloneMatrix(base.modules); + placeDataBits(modules, base.reserved, dataBits, mask); + drawFormatBits(modules, spec.size, mask); if (spec.version >= 7) { - drawVersionBits(modules, spec) + drawVersionBits(modules, spec); } - const score = getPenaltyScore(modules) + const score = getPenaltyScore(modules); if (score < bestScore) { - bestScore = score - bestModules = modules + bestScore = score; + bestModules = modules; } } return { size: spec.size, - modules: bestModules.map(row => row.map(Boolean)), - } + modules: bestModules.map((row) => row.map(Boolean)), + }; } -export function createQrCodeSvg (value: string, options: { scale?: number, quietZone?: number } = {}) { - const { size, modules } = createQrCodeMatrix(value) - const quietZone = options.quietZone ?? 4 - const scale = options.scale ?? 6 - const viewSize = size + quietZone * 2 - const rects: string[] = [] +export function createQrCodeSvg( + value: string, + options: { scale?: number; quietZone?: number } = {}, +) { + const { size, modules } = createQrCodeMatrix(value); + const quietZone = options.quietZone ?? 4; + const scale = options.scale ?? 6; + const viewSize = size + quietZone * 2; + const rects: string[] = []; for (const [y, row] of modules.entries()) { for (const [x, dark] of row.entries()) { if (dark) { - rects.push(``) + rects.push( + ``, + ); } } } @@ -109,433 +203,462 @@ export function createQrCodeSvg (value: string, options: { scale?: number, quiet '', '', ...rects, - '', - '', - ].join('') + "", + "", + ].join(""); } -function createDataCodewords (data: number[], spec: VersionSpec) { - const bits: number[] = [] - appendBits(bits, 0b0100, 4) - appendBits(bits, data.length, spec.version < 10 ? 8 : 16) +function createDataCodewords(data: number[], spec: VersionSpec) { + const bits: number[] = []; + appendBits(bits, 0b0100, 4); + appendBits(bits, data.length, spec.version < 10 ? 8 : 16); for (const byte of data) { - appendBits(bits, byte, 8) + appendBits(bits, byte, 8); } - const capacityBits = spec.dataCodewords * 8 - appendBits(bits, 0, Math.min(4, capacityBits - bits.length)) + const capacityBits = spec.dataCodewords * 8; + appendBits(bits, 0, Math.min(4, capacityBits - bits.length)); while (bits.length % 8 !== 0) { - bits.push(0) + bits.push(0); } - const codewords: number[] = [] + const codewords: number[] = []; for (let i = 0; i < bits.length; i += 8) { - codewords.push(bitsToByte(bits.slice(i, i + 8))) + codewords.push(bitsToByte(bits.slice(i, i + 8))); } - for (let pad = 0xec; codewords.length < spec.dataCodewords; pad ^= 0xec ^ 0x11) { - codewords.push(pad) + for ( + let pad = 0xec; + codewords.length < spec.dataCodewords; + pad ^= 0xec ^ 0x11 + ) { + codewords.push(pad); } - return codewords + return codewords; } -function createFinalCodewords (dataCodewords: number[], spec: VersionSpec) { - const blocks: { data: number[], ecc: number[] }[] = [] - let offset = 0 +function createFinalCodewords(dataCodewords: number[], spec: VersionSpec) { + const blocks: { data: number[]; ecc: number[] }[] = []; + let offset = 0; for (const group of spec.blockGroups) { for (let i = 0; i < group.count; i += 1) { - const data = dataCodewords.slice(offset, offset + group.dataCodewords) - offset += group.dataCodewords - blocks.push({ data, ecc: createErrorCorrectionCodewords(data, spec.eccCodewords) }) + const data = dataCodewords.slice(offset, offset + group.dataCodewords); + offset += group.dataCodewords; + blocks.push({ + data, + ecc: createErrorCorrectionCodewords(data, spec.eccCodewords), + }); } } - const result: number[] = [] - const maxDataLength = Math.max(...blocks.map(block => block.data.length)) + const result: number[] = []; + const maxDataLength = Math.max(...blocks.map((block) => block.data.length)); for (let i = 0; i < maxDataLength; i += 1) { for (const block of blocks) { if (i < block.data.length) { - result.push(block.data[i]) + result.push(block.data[i]); } } } for (let i = 0; i < spec.eccCodewords; i += 1) { for (const block of blocks) { - result.push(block.ecc[i]) + result.push(block.ecc[i]); } } - return result + return result; } -function createErrorCorrectionCodewords (data: number[], degree: number) { - const generator = createGeneratorPolynomial(degree) - const result = Array.from({ length: degree }, () => 0) +function createErrorCorrectionCodewords(data: number[], degree: number) { + const generator = createGeneratorPolynomial(degree); + const result = Array.from({ length: degree }, () => 0); for (const byte of data) { - const factor = byte ^ result.shift()! - result.push(0) + const factor = byte ^ result.shift()!; + result.push(0); for (const [index, coefficient] of generator.entries()) { - result[index] ^= gfMultiply(coefficient, factor) + result[index] ^= gfMultiply(coefficient, factor); } } - return result + return result; } -function createGeneratorPolynomial (degree: number) { - let result = [1] +function createGeneratorPolynomial(degree: number) { + let result = [1]; for (let i = 0; i < degree; i += 1) { - const next = Array.from({ length: result.length + 1 }, () => 0) + const next = Array.from({ length: result.length + 1 }, () => 0); for (const [index, coefficient] of result.entries()) { - next[index] ^= gfMultiply(coefficient, 1) - next[index + 1] ^= gfMultiply(coefficient, gfExp[i]) + next[index] ^= gfMultiply(coefficient, 1); + next[index + 1] ^= gfMultiply(coefficient, gfExp[i]); } - result = next + result = next; } - return result.slice(1) + return result.slice(1); } -function createBaseMatrix (spec: VersionSpec) { +function createBaseMatrix(spec: VersionSpec) { const modules = Array.from({ length: spec.size }, (): Cell[] => { - return Array.from({ length: spec.size }, (): Cell => null) - }) + return Array.from({ length: spec.size }, (): Cell => null); + }); const reserved = Array.from({ length: spec.size }, (): boolean[] => { - return Array.from({ length: spec.size }, () => false) - }) + return Array.from({ length: spec.size }, () => false); + }); - drawFinderPattern(modules, reserved, 3, 3) - drawFinderPattern(modules, reserved, spec.size - 4, 3) - drawFinderPattern(modules, reserved, 3, spec.size - 4) - drawTimingPatterns(modules, reserved) - drawAlignmentPatterns(modules, reserved, spec.alignment) - drawDarkModule(modules, reserved, spec.size) - reserveFormatAreas(reserved, spec.size) + drawFinderPattern(modules, reserved, 3, 3); + drawFinderPattern(modules, reserved, spec.size - 4, 3); + drawFinderPattern(modules, reserved, 3, spec.size - 4); + drawTimingPatterns(modules, reserved); + drawAlignmentPatterns(modules, reserved, spec.alignment); + drawDarkModule(modules, reserved, spec.size); + reserveFormatAreas(reserved, spec.size); if (spec.version >= 7) { - reserveVersionAreas(reserved, spec.size) + reserveVersionAreas(reserved, spec.size); } - return { modules, reserved } + return { modules, reserved }; } -function drawFinderPattern (modules: Cell[][], reserved: boolean[][], centerX: number, centerY: number) { +function drawFinderPattern( + modules: Cell[][], + reserved: boolean[][], + centerX: number, + centerY: number, +) { for (let y = -4; y <= 4; y += 1) { for (let x = -4; x <= 4; x += 1) { - const xx = centerX + x - const yy = centerY + y + const xx = centerX + x; + const yy = centerY + y; if (!isInBounds(modules.length, xx, yy)) { - continue + continue; } - const distance = Math.max(Math.abs(x), Math.abs(y)) - modules[yy][xx] = distance !== 2 && distance !== 4 - reserved[yy][xx] = true + const distance = Math.max(Math.abs(x), Math.abs(y)); + modules[yy][xx] = distance !== 2 && distance !== 4; + reserved[yy][xx] = true; } } } -function drawTimingPatterns (modules: Cell[][], reserved: boolean[][]) { +function drawTimingPatterns(modules: Cell[][], reserved: boolean[][]) { for (let i = 8; i < modules.length - 8; i += 1) { - const dark = i % 2 === 0 - modules[6][i] = dark - modules[i][6] = dark - reserved[6][i] = true - reserved[i][6] = true + const dark = i % 2 === 0; + modules[6][i] = dark; + modules[i][6] = dark; + reserved[6][i] = true; + reserved[i][6] = true; } } -function drawAlignmentPatterns (modules: Cell[][], reserved: boolean[][], positions: number[]) { +function drawAlignmentPatterns( + modules: Cell[][], + reserved: boolean[][], + positions: number[], +) { for (const y of positions) { for (const x of positions) { if (reserved[y][x]) { - continue + continue; } for (let dy = -2; dy <= 2; dy += 1) { for (let dx = -2; dx <= 2; dx += 1) { - const distance = Math.max(Math.abs(dx), Math.abs(dy)) - modules[y + dy][x + dx] = distance !== 1 - reserved[y + dy][x + dx] = true + const distance = Math.max(Math.abs(dx), Math.abs(dy)); + modules[y + dy][x + dx] = distance !== 1; + reserved[y + dy][x + dx] = true; } } } } } -function drawDarkModule (modules: Cell[][], reserved: boolean[][], size: number) { - modules[size - 8][8] = true - reserved[size - 8][8] = true +function drawDarkModule( + modules: Cell[][], + reserved: boolean[][], + size: number, +) { + modules[size - 8][8] = true; + reserved[size - 8][8] = true; } -function reserveFormatAreas (reserved: boolean[][], size: number) { +function reserveFormatAreas(reserved: boolean[][], size: number) { for (let i = 0; i <= 5; i += 1) { - reserved[8][i] = true - reserved[i][8] = true + reserved[8][i] = true; + reserved[i][8] = true; } - reserved[8][7] = true - reserved[8][8] = true - reserved[7][8] = true + reserved[8][7] = true; + reserved[8][8] = true; + reserved[7][8] = true; for (let i = 0; i < 8; i += 1) { - reserved[8][size - 1 - i] = true + reserved[8][size - 1 - i] = true; } for (let i = 8; i < 15; i += 1) { - reserved[size - 15 + i][8] = true + reserved[size - 15 + i][8] = true; } } -function reserveVersionAreas (reserved: boolean[][], size: number) { +function reserveVersionAreas(reserved: boolean[][], size: number) { for (let i = 0; i < 6; i += 1) { for (let j = 0; j < 3; j += 1) { - reserved[size - 11 + j][i] = true - reserved[i][size - 11 + j] = true + reserved[size - 11 + j][i] = true; + reserved[i][size - 11 + j] = true; } } } -function placeDataBits (modules: Cell[][], reserved: boolean[][], bits: number[], mask: number) { - const size = modules.length - let bitIndex = 0 - let direction = -1 - let y = size - 1 +function placeDataBits( + modules: Cell[][], + reserved: boolean[][], + bits: number[], + mask: number, +) { + const size = modules.length; + let bitIndex = 0; + let direction = -1; + let y = size - 1; for (let right = size - 1; right >= 1; right -= 2) { if (right === 6) { - right -= 1 + right -= 1; } while (y >= 0 && y < size) { for (let column = 0; column < 2; column += 1) { - const x = right - column + const x = right - column; if (!reserved[y][x]) { - const bit = bitIndex < bits.length ? bits[bitIndex] === 1 : false - modules[y][x] = bit !== getMaskBit(mask, x, y) - bitIndex += 1 + const bit = bitIndex < bits.length ? bits[bitIndex] === 1 : false; + modules[y][x] = bit !== getMaskBit(mask, x, y); + bitIndex += 1; } } - y += direction + y += direction; } - y -= direction - direction = -direction + y -= direction; + direction = -direction; } } -function drawFormatBits (modules: Cell[][], size: number, mask: number) { - const bits = getFormatBits(mask) +function drawFormatBits(modules: Cell[][], size: number, mask: number) { + const bits = getFormatBits(mask); for (let i = 0; i <= 5; i += 1) { - setModule(modules, 8, i, getBit(bits, i)) + setModule(modules, 8, i, getBit(bits, i)); } - setModule(modules, 8, 7, getBit(bits, 6)) - setModule(modules, 8, 8, getBit(bits, 7)) - setModule(modules, 7, 8, getBit(bits, 8)) + setModule(modules, 8, 7, getBit(bits, 6)); + setModule(modules, 8, 8, getBit(bits, 7)); + setModule(modules, 7, 8, getBit(bits, 8)); for (let i = 9; i < 15; i += 1) { - setModule(modules, 14 - i, 8, getBit(bits, i)) + setModule(modules, 14 - i, 8, getBit(bits, i)); } for (let i = 0; i < 8; i += 1) { - setModule(modules, size - 1 - i, 8, getBit(bits, i)) + setModule(modules, size - 1 - i, 8, getBit(bits, i)); } for (let i = 8; i < 15; i += 1) { - setModule(modules, 8, size - 15 + i, getBit(bits, i)) + setModule(modules, 8, size - 15 + i, getBit(bits, i)); } } -function drawVersionBits (modules: Cell[][], spec: VersionSpec) { - const bits = getVersionBits(spec.version) - const size = spec.size +function drawVersionBits(modules: Cell[][], spec: VersionSpec) { + const bits = getVersionBits(spec.version); + const size = spec.size; for (let i = 0; i < 18; i += 1) { - const bit = getBit(bits, i) - const x = i % 3 - const y = Math.floor(i / 3) - setModule(modules, size - 11 + x, y, bit) - setModule(modules, y, size - 11 + x, bit) + const bit = getBit(bits, i); + const x = i % 3; + const y = Math.floor(i / 3); + setModule(modules, size - 11 + x, y, bit); + setModule(modules, y, size - 11 + x, bit); } } -function getFormatBits (mask: number) { - let data = mask - let bits = data << 10 +function getFormatBits(mask: number) { + let data = mask; + let bits = data << 10; for (let i = 4; i >= 0; i -= 1) { if (((bits >>> (i + 10)) & 1) === 1) { - bits ^= FORMAT_POLY << i + bits ^= FORMAT_POLY << i; } } - data = (data << 10) | (bits & 0x03_ff) - return data ^ FORMAT_XOR + data = (data << 10) | (bits & 0x03_ff); + return data ^ FORMAT_XOR; } -function getVersionBits (version: number) { - let bits = version << 12 +function getVersionBits(version: number) { + let bits = version << 12; for (let i = 5; i >= 0; i -= 1) { if (((bits >>> (i + 12)) & 1) === 1) { - bits ^= VERSION_POLY << i + bits ^= VERSION_POLY << i; } } - return (version << 12) | (bits & 0x0f_ff) + return (version << 12) | (bits & 0x0f_ff); } -function getPenaltyScore (modules: Cell[][]) { - const size = modules.length - let score = 0 +function getPenaltyScore(modules: Cell[][]) { + const size = modules.length; + let score = 0; for (let y = 0; y < size; y += 1) { - score += getRunPenalty(modules[y].map(Boolean)) + score += getRunPenalty(modules[y].map(Boolean)); } for (let x = 0; x < size; x += 1) { - score += getRunPenalty(modules.map(row => Boolean(row[x]))) + score += getRunPenalty(modules.map((row) => Boolean(row[x]))); } for (let y = 0; y < size - 1; y += 1) { for (let x = 0; x < size - 1; x += 1) { - const dark = modules[y][x] - if (modules[y][x + 1] === dark && modules[y + 1][x] === dark && modules[y + 1][x + 1] === dark) { - score += 3 + const dark = modules[y][x]; + if ( + modules[y][x + 1] === dark && + modules[y + 1][x] === dark && + modules[y + 1][x + 1] === dark + ) { + score += 3; } } } - score += getFinderLikePenalty(modules) + score += getFinderLikePenalty(modules); - const darkCount = modules.flat().filter(Boolean).length - const percent = (darkCount * 100) / (size * size) - score += Math.floor(Math.abs(percent - 50) / 5) * 10 + const darkCount = modules.flat().filter(Boolean).length; + const percent = (darkCount * 100) / (size * size); + score += Math.floor(Math.abs(percent - 50) / 5) * 10; - return score + return score; } -function getRunPenalty (line: boolean[]) { - let score = 0 - let runColor = line[0] - let runLength = 1 +function getRunPenalty(line: boolean[]) { + let score = 0; + let runColor = line[0]; + let runLength = 1; for (let i = 1; i < line.length; i += 1) { if (line[i] === runColor) { - runLength += 1 + runLength += 1; } else { if (runLength >= 5) { - score += runLength - 2 + score += runLength - 2; } - runColor = line[i] - runLength = 1 + runColor = line[i]; + runLength = 1; } } - return runLength >= 5 ? score + runLength - 2 : score + return runLength >= 5 ? score + runLength - 2 : score; } -function getFinderLikePenalty (modules: Cell[][]) { - const pattern = '10111010000' - const reversePattern = '00001011101' - const size = modules.length - let score = 0 +function getFinderLikePenalty(modules: Cell[][]) { + const pattern = "10111010000"; + const reversePattern = "00001011101"; + const size = modules.length; + let score = 0; const scan = (line: boolean[]) => { - const text = line.map(bit => (bit ? '1' : '0')).join('') + const text = line.map((bit) => (bit ? "1" : "0")).join(""); for (let i = 0; i <= text.length - pattern.length; i += 1) { - const chunk = text.slice(i, i + pattern.length) + const chunk = text.slice(i, i + pattern.length); if (chunk === pattern || chunk === reversePattern) { - score += 40 + score += 40; } } - } + }; for (const row of modules) { - scan(row.map(Boolean)) + scan(row.map(Boolean)); } for (let x = 0; x < size; x += 1) { - scan(modules.map(row => Boolean(row[x]))) + scan(modules.map((row) => Boolean(row[x]))); } - return score + return score; } -function getMaskBit (mask: number, x: number, y: number) { +function getMaskBit(mask: number, x: number, y: number) { switch (mask) { case 0: { - return (x + y) % 2 === 0 + return (x + y) % 2 === 0; } case 1: { - return y % 2 === 0 + return y % 2 === 0; } case 2: { - return x % 3 === 0 + return x % 3 === 0; } case 3: { - return (x + y) % 3 === 0 + return (x + y) % 3 === 0; } case 4: { - return (Math.floor(y / 2) + Math.floor(x / 3)) % 2 === 0 + return (Math.floor(y / 2) + Math.floor(x / 3)) % 2 === 0; } case 5: { - return ((x * y) % 2) + ((x * y) % 3) === 0 + return ((x * y) % 2) + ((x * y) % 3) === 0; } case 6: { - return (((x * y) % 2) + ((x * y) % 3)) % 2 === 0 + return (((x * y) % 2) + ((x * y) % 3)) % 2 === 0; } case 7: { - return (((x + y) % 2) + ((x * y) % 3)) % 2 === 0 + return (((x + y) % 2) + ((x * y) % 3)) % 2 === 0; } default: { - return false + return false; } } } -function appendBits (target: number[], value: number, length: number) { +function appendBits(target: number[], value: number, length: number) { for (let i = length - 1; i >= 0; i -= 1) { - target.push((value >>> i) & 1) + target.push((value >>> i) & 1); } } -function byteToBits (value: number) { - const bits: number[] = [] - appendBits(bits, value, 8) - return bits +function byteToBits(value: number) { + const bits: number[] = []; + appendBits(bits, value, 8); + return bits; } -function bitsToByte (bits: number[]) { - return bits.reduce((value, bit) => (value << 1) | bit, 0) +function bitsToByte(bits: number[]) { + return bits.reduce((value, bit) => (value << 1) | bit, 0); } -function gfMultiply (a: number, b: number) { +function gfMultiply(a: number, b: number) { if (a === 0 || b === 0) { - return 0 + return 0; } - return gfExp[gfLog[a] + gfLog[b]] + return gfExp[gfLog[a] + gfLog[b]]; } -function getBit (value: number, index: number) { - return ((value >>> index) & 1) === 1 +function getBit(value: number, index: number) { + return ((value >>> index) & 1) === 1; } -function cloneMatrix (modules: Cell[][]) { - return modules.map(row => [...row]) +function cloneMatrix(modules: Cell[][]) { + return modules.map((row) => [...row]); } -function setModule (modules: Cell[][], x: number, y: number, value: boolean) { - modules[y][x] = value +function setModule(modules: Cell[][], x: number, y: number, value: boolean) { + modules[y][x] = value; } -function isInBounds (size: number, x: number, y: number) { - return x >= 0 && y >= 0 && x < size && y < size +function isInBounds(size: number, x: number, y: number) { + return x >= 0 && y >= 0 && x < size && y < size; } diff --git a/app/citizen-frontend/tsconfig.app.json b/app/citizen-frontend/tsconfig.app.json index d346785..707708f 100644 --- a/app/citizen-frontend/tsconfig.app.json +++ b/app/citizen-frontend/tsconfig.app.json @@ -1,22 +1,14 @@ { "extends": "@vue/tsconfig/tsconfig.dom.json", - "include": [ - "env.d.ts", - "src/**/*", - "src/**/*.vue" - ], - "exclude": [ - "src/**/__tests__/*" - ], + "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], + "exclude": ["src/**/__tests__/*"], "compilerOptions": { "composite": true, "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "baseUrl": ".", "rootDir": ".", "paths": { - "@/*": [ - "./src/*" - ] + "@/*": ["./src/*"] } }, "vueCompilerOptions": { diff --git a/app/citizen-frontend/vite.config.mts b/app/citizen-frontend/vite.config.mts index 1d49a0b..aff9a7b 100644 --- a/app/citizen-frontend/vite.config.mts +++ b/app/citizen-frontend/vite.config.mts @@ -1,7 +1,7 @@ -import { fileURLToPath, URL } from 'node:url' -import Vue from '@vitejs/plugin-vue' -import { defineConfig, loadEnv } from 'vite' -import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify' +import { fileURLToPath, URL } from "node:url"; +import Vue from "@vitejs/plugin-vue"; +import { defineConfig, loadEnv } from "vite"; +import Vuetify, { transformAssetUrls } from "vite-plugin-vuetify"; // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { @@ -9,8 +9,8 @@ export default defineConfig(({ mode }) => { // 本機開發改用 dev server 轉發 /api,避開瀏覽器的跨網域限制。 // 在 .env.local 設定 API_PROXY_TARGET(例如內網後端位址)即可啟用; // 未設定時維持原行為(前端走 VITE_USE_MOCK 的模擬資料)。 - const env = loadEnv(mode, process.cwd(), '') - const apiProxyTarget = env.API_PROXY_TARGET + const env = loadEnv(mode, process.cwd(), ""); + const apiProxyTarget = env.API_PROXY_TARGET; return { plugins: [ @@ -21,28 +21,28 @@ export default defineConfig(({ mode }) => { Vuetify({ autoImport: true, styles: { - configFile: 'src/styles/settings.scss', + configFile: "src/styles/settings.scss", }, }), ], - define: { 'process.env': {} }, + define: { "process.env": {} }, resolve: { alias: { - '@': fileURLToPath(new URL('src', import.meta.url)), + "@": fileURLToPath(new URL("src", import.meta.url)), }, - extensions: ['.js', '.json', '.jsx', '.mjs', '.ts', '.tsx', '.vue'], + extensions: [".js", ".json", ".jsx", ".mjs", ".ts", ".tsx", ".vue"], }, server: { port: 3678, proxy: apiProxyTarget ? { - '/api': { + "/api": { target: apiProxyTarget, changeOrigin: true, - rewrite: (path: string) => path.replace(/^\/api/, ''), + rewrite: (path: string) => path.replace(/^\/api/, ""), }, } : undefined, }, - } -}) + }; +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 605b2de..9810b38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,15 +44,12 @@ importers: '@vue/tsconfig': specifier: ^0.9.0 version: 0.9.1(typescript@5.9.3)(vue@3.5.38(typescript@5.9.3)) - eslint: - specifier: ^9.39.4 - version: 9.39.4 - eslint-config-vuetify: - specifier: ^4.3.4 - version: 4.7.1(eslint@9.39.4)(typescript@5.9.3) npm-run-all2: specifier: ^8.0.4 version: 8.0.4 + oxfmt: + specifier: ^0.62.0 + version: 0.62.0 sass-embedded: specifier: ^1.98.0 version: 1.100.0 @@ -71,12 +68,6 @@ importers: packages: - '@apidevtools/json-schema-ref-parser@14.2.1': - resolution: {integrity: sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==} - engines: {node: '>= 20'} - peerDependencies: - '@types/json-schema': ^7.0.15 - '@babel/generator@8.0.0': resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} engines: {node: ^22.18.0 || >=24.11.0} @@ -118,14 +109,6 @@ packages: '@bufbuild/protobuf@2.12.0': resolution: {integrity: sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==} - '@clack/core@1.4.1': - resolution: {integrity: sha512-FILJa1gGKEFTGZAJE9RpVhrjKz3c3h4ar60dSv6cGuDqufQ84YEIS3GAGvZiN+H6yaLbbvTFNejjCC4tXpZEuw==} - engines: {node: '>= 20.12.0'} - - '@clack/prompts@1.5.1': - resolution: {integrity: sha512-zccHj2z2oCCO4yrDiRSlFOxWerGqRiysP7a5jPK6uoI9URKAquwY42Dd/iUP8JWHxEzdRe4TlbvZCo8z1/mhrw==} - engines: {node: '>= 20.12.0'} - '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} @@ -135,94 +118,6 @@ packages: '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/compat@2.1.0': - resolution: {integrity: sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - peerDependencies: - eslint: ^8.40 || 9 || 10 - peerDependenciesMeta: - eslint: - optional: true - - '@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.5': - resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@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.2.1': - resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} - 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@10.0.1': - resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - peerDependencies: - eslint: ^10.0.0 - peerDependenciesMeta: - eslint: - optional: true - - '@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@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.7.2': - resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@humanfs/core@0.19.2': - resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.8': - resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} - engines: {node: '>=18.18.0'} - - '@humanfs/types@0.15.0': - resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - '@intlify/core-base@11.4.5': resolution: {integrity: sha512-lja3F/iKVIvTa48mIwmrIeDcQUFZ0F0drvFvT8AwINOvbwnAzl/S/p8p2DxILZpWEUHRi1qewfWNIkMvhD3kKA==} engines: {node: '>= 22'} @@ -264,13 +159,131 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 - '@ota-meshi/ast-token-store@0.3.0': - resolution: {integrity: sha512-XRO0zi2NIUKq2lUk3T1ecFSld1fMWRKE6naRFGkgkdeosx7IslyUKNv5Dcb5PJTja9tHJoFu0v/7yEpAkrkrTg==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@oxc-project/types@0.133.0': resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + '@oxfmt/binding-android-arm-eabi@0.62.0': + resolution: {integrity: sha512-pdsv0C4gPjJ8H1+sd8u0BDx+yLACTL+rgeMIOL1ln4ihSnhw8CWXtYWgvcSkyTfgGBIzFKab+d8rx9Xl4en/Kw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxfmt/binding-android-arm64@0.62.0': + resolution: {integrity: sha512-WC3YQ7uS/KtDrjmqwBviwFKe9qeoi+eXx8aX1z/ffG23Md75myjrJaQqTuJvdOLPoa4EYTjDWH0dHXfwulCVog==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxfmt/binding-darwin-arm64@0.62.0': + resolution: {integrity: sha512-GM8Yf3LjjaR1I8PD0SfeoIlwhsh9GvSF+cQ8sf624Yxnjsyumn95aFzYfKJVefblfDIiOAnZ7QVm2sa21Er/0Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxfmt/binding-darwin-x64@0.62.0': + resolution: {integrity: sha512-d5THp7F8bCxLqNogEXDORRsQD6dosf3EyFtnXfBer6v+8tGdcWIjoDX9WaXrrF/26zOmL8qHpPTKCEvpBDmZkQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxfmt/binding-freebsd-x64@0.62.0': + resolution: {integrity: sha512-1DnrtXGZooOZ0fHgAXZUaDQzBVh1CM2MNW4oBXyQ2aWKvCHjyljvT9fgBkOM0fEOb96X5eqtcfJ0YUVt9jj66g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxfmt/binding-linux-arm-gnueabihf@0.62.0': + resolution: {integrity: sha512-4pQDHOYRH+Huqe0StIaWyvk2CVl/aTaqSrbZpA3/pLS2xH24ME7lBgYprhQF2fRkHBzhGGGKliwxFsDdHwx59g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm-musleabihf@0.62.0': + resolution: {integrity: sha512-X0jAaZJFMCVKhB6YyWVTQ/wN2DLsBcZKSMqTS76bF6riT+XZdtg2FPEdjDvdVbunO9cG+tWiVaEs4Zs38lxYog==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm64-gnu@0.62.0': + resolution: {integrity: sha512-682Z8T5s8T5ATArYtsejKvbIfd8LEAXyyDkKkoZVq8HND7Vx8TYLlrDjDSeYfodMeVwHOgkj13lJYR8cj6vUSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-arm64-musl@0.62.0': + resolution: {integrity: sha512-lk25fAl7KWaLWVJcW0CHEXB7QlQZtx5eDkjpaGMK0hzXTjUe0Wmlu8IKuFHoviSOcEJedRTs4VE/506VqGxGew==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-ppc64-gnu@0.62.0': + resolution: {integrity: sha512-SFyNqHQLwySceWNLhiSldx7wPXRAzP0L0WcW9GegP3uWrpZGJiZlQO85NbHAFPEfxR9PhZ9qSnZryEh7+v+4Gw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-riscv64-gnu@0.62.0': + resolution: {integrity: sha512-KYj55C1ywJfHo6+aKDuEmUtVEdJALsC5GwayDGsI6FGz2GxFqNr/mA8nxVsNbJzm7sE5MRqTQ9ziImSzhYXysA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-riscv64-musl@0.62.0': + resolution: {integrity: sha512-BhZDNo5GOU5nC378RhD0/XpvaEBHsH3HLgJp8YZX3A0InC7oivzA63HsRmiXFLtLSHAstEVrDf6fbC7Rs8Jh/A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-s390x-gnu@0.62.0': + resolution: {integrity: sha512-UyAFmyHkgSgUJ/wOM4p3U8AC2yAFvRH5PNBs7TnK0fObTT/XSWcdr/lAzPSWaekHaZFaMeFZyk9n93Joq3J93A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-x64-gnu@0.62.0': + resolution: {integrity: sha512-1iYMP0leytWazFubD/WnINJuIrzRPuoL1aWEJdlGezEzDbTxcd29R4r8IUzP2oWeKst5V02uMJgR2NILlPlG6w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-x64-musl@0.62.0': + resolution: {integrity: sha512-4rA/URtJSTVNVAQz6Q8wf7SaRvOXVy+TizriT9hs/Y1XhLR/R+92uWKRQG8yFWRAIEBbFHJ6WevQcl/G9SXEfw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-openharmony-arm64@0.62.0': + resolution: {integrity: sha512-mSZuFHU2ar1KLUjXpI2QBQcJ1VsOB3mOCgQXuXCpKs19dgh4u+OaovNfrWDfiJb+ihJ2+f7YFcaO9bS2dlTCXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxfmt/binding-win32-arm64-msvc@0.62.0': + resolution: {integrity: sha512-OfwuhkcjDlqC4EgDojtiV9mzpLqeB9KqTOWPOjLEYBVdDCVSxqW3qzp/xcIxsbtI0UgGCnKvAqYKyY25kf5JZw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxfmt/binding-win32-ia32-msvc@0.62.0': + resolution: {integrity: sha512-P9uDDNFRzghO3X8QAzhkjKhK7JvtABsVn8UYtFX7uor12IAnwNt8nNIctvfWj1JkQU/kE+fmLRPiw7XlrIHsZw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxfmt/binding-win32-x64-msvc@0.62.0': + resolution: {integrity: sha512-dlI5SY7XYQCiCBafntWagCR6HcAJB/NpsLtdlPx8x08+Osz8Ok1HHz1GZuusegCe/VoJ6pAnF5a4pd5OZAq7qQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@parcel/watcher-android-arm64@2.5.6': resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} engines: {node: '>= 10.0.0'} @@ -359,10 +372,6 @@ packages: resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} engines: {node: '>= 10.0.0'} - '@pkgr/core@0.3.6': - resolution: {integrity: sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==} - engines: {node: ^14.18.0 || >=16.0.0} - '@rolldown/binding-android-arm64@1.0.3': resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -461,92 +470,18 @@ packages: '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@stylistic/eslint-plugin@5.10.0': - resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - '@tsconfig/node22@22.0.5': resolution: {integrity: sha512-hLf2ld+sYN/BtOJjHUWOk568dvjFQkHnLNa6zce25GIH+vxKfvTgm3qpaH6ToF5tu/NN0IH66s+Bb5wElHrLcw==} '@tybys/wasm-util@0.10.2': resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} - '@types/esrecurse@4.3.1': - resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - '@types/jsesc@2.5.1': resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@24.13.2': resolution: {integrity: sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==} - '@typescript-eslint/eslint-plugin@8.61.1': - resolution: {integrity: sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.61.1 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/parser@8.61.1': - resolution: {integrity: sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==} - 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/project-service@8.61.1': - resolution: {integrity: sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/scope-manager@8.61.1': - resolution: {integrity: sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.61.1': - resolution: {integrity: sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/type-utils@8.61.1': - resolution: {integrity: sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==} - 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/types@8.61.1': - resolution: {integrity: sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.61.1': - resolution: {integrity: sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/utils@8.61.1': - resolution: {integrity: sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==} - 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.61.1': - resolution: {integrity: sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitejs/plugin-vue@6.0.7': resolution: {integrity: sha512-km+p+XdSz9Sxm5rqUbqcSfZYaAniKxWBj1KURl+Jr7UaPvvX7BmaWMdP69I5rrFDeQGyxAG7NXdc57vz+snhWg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -642,33 +577,18 @@ packages: vue: ^3.0.0 vuetify: '>=3' - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.17.0: resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} hasBin: true - ajv@6.15.0: - resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} - alien-signals@3.2.1: resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - ansi-styles@6.2.3: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - ast-kit@2.2.0: resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} engines: {node: '>=20.19.0'} @@ -677,82 +597,16 @@ packages: resolution: {integrity: sha512-IJdzo2vLiElBxKzwS36VsCue/62d6IdWjnPB2v3nuPKeWGynp6FF/CYoLa5i/3jXH/z97ZDdsXz6abpgM6w07A==} engines: {node: '>=20.19.0'} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} - - baseline-browser-mapping@2.10.38: - resolution: {integrity: sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==} - engines: {node: '>=6.0.0'} - hasBin: true - birpc@2.9.0: resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - brace-expansion@1.1.15: - resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} - - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} - engines: {node: 18 || 20 || >=22} - - browserslist@4.28.2: - resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - builtin-modules@5.2.0: - resolution: {integrity: sha512-02yxLeyxF4dNl6SlY6/5HfRSrSdZ/sCPoxy2kZNP5dZZX8LSAD9aE2gtJIUgWrsQTiMPl3mxESyrobSwvRGisQ==} - engines: {node: '>=18.20'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - caniuse-lite@1.0.30001799: - resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - change-case@5.4.4: - resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} - chokidar@5.0.0: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} - ci-info@4.4.0: - resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} - engines: {node: '>=8'} - - citty@0.2.2: - resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colorjs.io@0.5.2: resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==} - comment-parser@1.4.7: - resolution: {integrity: sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ==} - engines: {node: '>= 12.0.0'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -763,18 +617,10 @@ packages: resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} engines: {node: '>=18'} - core-js-compat@3.49.0: - resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -787,218 +633,20 @@ packages: supports-color: optional: true - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - detect-indent@7.0.2: - resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} - engines: {node: '>=12.20'} - detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - electron-to-chromium@1.5.375: - resolution: {integrity: sha512-ZWP5eB4BVPW/ZYo9252hQZHZ5XavtsTgpbhcmMmRwymavC5AsLWQWBPaKMeNd2LW0KGby5HPXvj7+sr4ta5j/Q==} - - empathic@2.0.1: - resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} - engines: {node: '>=14'} - entities@7.0.1: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-config-flat-gitignore@2.3.0: - resolution: {integrity: sha512-bg4ZLGgoARg1naWfsINUUb/52Ksw/K22K+T16D38Y8v+/sGwwIYrGvH/JBjOin+RQtxxC9tzNNiy4shnGtGyyQ==} - peerDependencies: - eslint: ^9.5.0 || ^10.0.0 - - eslint-config-vuetify@4.7.1: - resolution: {integrity: sha512-7nVkPe+veKcnEr0I4ZSnwFb+sziuYqk6teAU2OjDBP3FLHYVw5yQ4J4Pdw6CEK1HPToPTseslk/n/Y0cTlRGoA==} - hasBin: true - peerDependencies: - '@vitest/eslint-plugin': ^1.1.42 - eslint: ^9.5.0 || ^10.0.0 - eslint-plugin-import-x: '*' - eslint-plugin-jest: ^29.0.1 - eslint-plugin-no-only-tests: ^3.3.0 - eslint-plugin-vuejs-accessibility: ^2.0.0 - peerDependenciesMeta: - '@vitest/eslint-plugin': - optional: true - eslint-plugin-import-x: - optional: true - eslint-plugin-jest: - optional: true - eslint-plugin-no-only-tests: - optional: true - eslint-plugin-vuejs-accessibility: - optional: true - - eslint-flat-config-utils@3.2.0: - resolution: {integrity: sha512-PHgo1X5uqIorJONLVD9BIaOSdoYFD3z/AeJljdqDPlWVRpeCYkDbK9k0AXoYVqqNJr6FEYIEr5Rm2TSktLQcHw==} - - eslint-json-compat-utils@0.2.3: - resolution: {integrity: sha512-RbBmDFyu7FqnjE8F0ZxPNzx5UaptdeS9Uu50r7A+D7s/+FCX+ybiyViYEgFUaFIFqSWJgZRTpL5d8Kanxxl2lQ==} - engines: {node: '>=12'} - peerDependencies: - '@eslint/json': '*' - eslint: '*' - jsonc-eslint-parser: ^2.4.0 || ^3.0.0 - peerDependenciesMeta: - '@eslint/json': - optional: true - - eslint-plugin-antfu@3.2.3: - resolution: {integrity: sha512-U2fnz/H0gFPxpuC7QpaHa0Jv2AgCZ5hunp36SOP/yWo8yFzgvMh8X4pZ4uN4IKoqtBhk7G3HuVa93Urf51+sZg==} - peerDependencies: - eslint: '*' - - eslint-plugin-import-lite@0.6.0: - resolution: {integrity: sha512-80vevx2A7i3H7n1/6pqDO8cc5wRz6OwLDvIyVl9UflBV1N1f46e9Ihzi65IOLYoSxM6YykK2fTw1xm0Ixx6aTQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - - eslint-plugin-jsonc@3.2.0: - resolution: {integrity: sha512-eQSxJypkpNycQAFE/ph/j+bDD2MiCcojxNb+7nugYzuQZvELYg4YO1Cv1y/8MbjPIEw5u3Lx0VPOTlqJJIhPPw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - peerDependencies: - eslint: '>=9.38.0' - - eslint-plugin-perfectionist@5.9.1: - resolution: {integrity: sha512-30mHLNfEhzwaq5cquyWgnzrNXvT8AzwIwyeH5aj4U5ajhHSF2uiO6i09xpMDLv7koaZVTjLsvYF4m3gK/15tyA==} - engines: {node: ^20.0.0 || >=22.0.0} - peerDependencies: - eslint: ^8.45.0 || ^9.0.0 || ^10.0.0 - - eslint-plugin-pnpm@1.6.1: - resolution: {integrity: sha512-pgcaJclu3YxZ/WMsiKMF58bHQasbGVARSMqCJvFaETYxSc7KcR2H74UVWV6exuGv9nNv9c0KKqn4PVHQlzMSEg==} - peerDependencies: - eslint: ^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-unicorn@65.0.1: - resolution: {integrity: sha512-daCrQrgxOoOz2uMPWB3Y3vvv/5q+ncwICI8IjoebiwtW87CaY4tAN5EEiRXTYVnf7qi1v1BGBdHOSnZLV0rx6A==} - engines: {node: ^20.10.0 || >=21.0.0} - peerDependencies: - eslint: '>=9.38.0' - - eslint-plugin-vue@10.9.2: - resolution: {integrity: sha512-4g7ZP3pYcuqd7Zp0pzUKcos0W+RkjBz4EGdhJ92FcYk6v03Ti/GK5NwjgsjxHK+98eXDbHeK7VtX1az7/8doZA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - vue-eslint-parser: ^10.3.0 - peerDependenciesMeta: - '@stylistic/eslint-plugin': - optional: true - '@typescript-eslint/parser': - optional: true - - 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} - - eslint-typegen@2.3.1: - resolution: {integrity: sha512-zVdh8rThBvv2o5T/K524Fr5iy1Jo0q09rHL7y7FbOhgMB177T2gw+shxfC4ChCEqdq6/y6LJA4j8Fbr/Xls9aw==} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@5.0.1: - resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} - 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: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - espree@11.2.0: - resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fast-string-truncated-width@3.0.3: - resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} - - fast-string-width@3.0.2: - resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - - fast-wrap-ansi@0.2.2: - resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1008,42 +656,11 @@ packages: picomatch: optional: true - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - find-up-simple@1.0.1: - resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} - engines: {node: '>=18'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - globals@17.6.0: - resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==} - engines: {node: '>=18'} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1051,33 +668,9 @@ packages: hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - immutable@5.1.6: resolution: {integrity: sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==} - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - - is-builtin-module@5.0.0: - resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} - engines: {node: '>=18.20'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1097,58 +690,24 @@ packages: resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} engines: {node: '>=18'} - js-yaml@4.2.0: - resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} - hasBin: true - - jsdoc-type-pratt-parser@7.2.0: - resolution: {integrity: sha512-dh140MMgjyg3JhJZY/+iEzW+NO5xR2gpbDFKHqotCmexElVntw7GjWjt511+C/Ef02RU5TKYrJo/Xlzk+OLaTw==} - engines: {node: '>=20.0.0'} - jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} hasBin: true - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-parse-even-better-errors@4.0.0: resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==} engines: {node: ^18.17.0 || >=20.5.0} - json-schema-to-typescript-lite@15.0.0: - resolution: {integrity: sha512-5mMORSQm9oTLyjM4mWnyNBi2T042Fhg1/0gCIB6X8U/LVpM2A+Nmj2yEyArqVouDmFThDxpEXcnTgSrjkGJRFA==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true - jsonc-eslint-parser@3.1.0: - resolution: {integrity: sha512-75EA7EWZExL/j+MDKQrRbdzcRI2HOkRlmUw8fZJc1ioqFEOvBsq7Rt+A6yCxOt9w/TYNpkt52gC6nm/g5tFIng==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - ky@2.0.2: resolution: {integrity: sha512-/GmXpo9F9W+f8n4Ivr2iH+7h7wL7jLbLKWkMlpflcCRb6kGjBfTlASEXaZ9qUgNTn4VgS0P2pwxxzQ4EM6Ulgg==} engines: {node: '>=22'} - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -1227,13 +786,6 @@ packages: resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} engines: {node: '>=14'} - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - magic-string-ast@1.0.3: resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==} engines: {node: '>=20.19.0'} @@ -1245,13 +797,6 @@ packages: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} - - minimatch@3.1.5: - resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -1269,20 +814,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - natural-orderby@5.0.0: - resolution: {integrity: sha512-kKHJhxwpR/Okycz4HhQKKlhWe4ASEfPgkSWNmKFHd7+ezuQlxkA5cM3+XkBPvm1gmHen3w53qsYAv+8GwRrBlg==} - engines: {node: '>=18'} - node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - node-releases@2.0.47: - resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} - engines: {node: '>=18'} - npm-normalize-package-bin@4.0.0: resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} engines: {node: ^18.17.0 || >=20.5.0} @@ -1292,43 +826,22 @@ packages: engines: {node: ^20.5.0 || >=22.0.0, npm: '>= 10'} hasBin: true - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - nypm@0.6.7: - resolution: {integrity: sha512-s3ds97SD5pd1dULE+tHUk1DrV0cSHOnsfpcdGATJ8JpBo21DoKqN9exTH4/2nhPQNOLomBdTFMicN94S4DrZrQ==} - engines: {node: '>=18'} + oxfmt@0.62.0: + resolution: {integrity: sha512-vxgGHTmnDU9j4CX7dDBLzxgmHxfda/yPcgJkGCMUSCwRmz+euo/V08xXLNgXTeqAB9Fhf3Pe2nO1RNKLCVgphQ==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - - ohash@2.0.11: - resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - 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'} + peerDependencies: + svelte: ^5.0.0 + vite-plus: '*' + peerDependenciesMeta: + svelte: + optional: true + vite-plus: + optional: true path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1369,29 +882,10 @@ packages: pkg-types@2.3.1: resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - - pnpm-workspace-yaml@1.6.1: - resolution: {integrity: sha512-yTeZntGWi8m9WNuhoVsP0DpFc4sC1U0+rr/qR6Zi9n2g3sxXY+JfccjXjjruNz96tM8I09yaJUA86doRnNLkbg==} - - postcss-selector-parser@7.1.4: - resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} - engines: {node: '>=4'} - postcss@8.5.15: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -1403,22 +897,6 @@ packages: resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} engines: {node: '>= 20.19.0'} - refa@0.12.1: - resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - regexp-ast-analysis@0.7.1: - resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - regjsparser@0.13.2: - resolution: {integrity: sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==} - hasBin: true - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} @@ -1552,18 +1030,9 @@ packages: engines: {node: '>=20.19.0'} hasBin: true - scslre@0.3.0: - resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} - engines: {node: ^14.0.0 || >=16.0.0} - scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - semver@7.8.4: - resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} - engines: {node: '>=10'} - hasBin: true - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1576,9 +1045,6 @@ packages: resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==} engines: {node: '>= 0.4'} - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -1587,22 +1053,10 @@ packages: resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} engines: {node: '>=0.10.0'} - strip-indent@4.1.1: - resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} - engines: {node: '>=12'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - superjson@2.2.6: resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} engines: {node: '>=16'} - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} @@ -1615,38 +1069,17 @@ packages: resolution: {integrity: sha512-gAQ9qrUN/UCypHtGFbbe7Rc/f9bzO88IwrG8TDo/aMKAApKyD6E3W4Cm0EfhfBb6Z6SKt59tTCTfD+n1xmAvMg==} engines: {node: '>=16.0.0'} - synckit@0.11.13: - resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==} - engines: {node: ^14.18.0 || >=16.0.0} - - tinyexec@1.2.4: - resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} - engines: {node: '>=18'} - tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} - ts-api-utils@2.5.0: - resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' + tinypool@2.1.0: + resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} + engines: {node: ^20.0.0 || >=22.0.0} tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - typescript-eslint@8.61.1: - resolution: {integrity: sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==} - 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@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -1670,18 +1103,6 @@ packages: resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} engines: {node: '>=4'} - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - varint@6.0.0: resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} @@ -1739,12 +1160,6 @@ packages: vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - vue-eslint-parser@10.4.1: - resolution: {integrity: sha512-Gk6gRDj0n/fkRa3C3l0bBheoBckUq/Rs0F/TvMWIS6nzzx67amAViMe9CkNgsP2tXyQONvGiHQESHwFtZ3aYDA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - vue-i18n@11.4.5: resolution: {integrity: sha512-rm8YJ6RpjOrkcgS2GLrZwLvs/VbhxbTSuEspbyXDo233+fPK0OMFNLOj3fdQYVKdOgcpSfLW91JhbqgpkkcBWA==} engines: {node: '>= 22'} @@ -1811,34 +1226,13 @@ packages: engines: {node: ^18.17.0 || >=20.5.0} hasBin: true - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} - - yaml-eslint-parser@2.0.0: - resolution: {integrity: sha512-h0uDm97wvT2bokfwwTmY6kJ1hp6YDFL0nRHwNKz8s/VD1FH/vvZjAKoMUE+un0eaYBSG7/c6h+lJTP+31tjgTw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} hasBin: true - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - snapshots: - '@apidevtools/json-schema-ref-parser@14.2.1(@types/json-schema@7.0.15)': - dependencies: - '@types/json-schema': 7.0.15 - js-yaml: 4.2.0 - '@babel/generator@8.0.0': dependencies: '@babel/parser': 8.0.0 @@ -1876,18 +1270,6 @@ snapshots: '@bufbuild/protobuf@2.12.0': {} - '@clack/core@1.4.1': - dependencies: - fast-wrap-ansi: 0.2.2 - sisteransi: 1.0.5 - - '@clack/prompts@1.5.1': - dependencies: - '@clack/core': 1.4.1 - fast-string-width: 3.0.2 - fast-wrap-ansi: 0.2.2 - sisteransi: 1.0.5 - '@emnapi/core@1.10.0': dependencies: '@emnapi/wasi-threads': 1.2.1 @@ -1904,91 +1286,6 @@ snapshots: tslib: 2.8.1 optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': - dependencies: - eslint: 9.39.4 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/compat@2.1.0(eslint@9.39.4)': - dependencies: - '@eslint/core': 1.2.1 - optionalDependencies: - eslint: 9.39.4 - - '@eslint/config-array@0.21.2': - dependencies: - '@eslint/object-schema': 2.1.7 - debug: 4.4.3 - minimatch: 3.1.5 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.4.2': - dependencies: - '@eslint/core': 0.17.0 - - '@eslint/config-helpers@0.5.5': - dependencies: - '@eslint/core': 1.2.1 - - '@eslint/core@0.17.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/core@1.2.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.5': - dependencies: - ajv: 6.15.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.2.0 - minimatch: 3.1.5 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@10.0.1(eslint@9.39.4)': - optionalDependencies: - eslint: 9.39.4 - - '@eslint/js@9.39.4': {} - - '@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.7.2': - dependencies: - '@eslint/core': 1.2.1 - levn: 0.4.1 - - '@humanfs/core@0.19.2': - dependencies: - '@humanfs/types': 0.15.0 - - '@humanfs/node@0.16.8': - dependencies: - '@humanfs/core': 0.19.2 - '@humanfs/types': 0.15.0 - '@humanwhocodes/retry': 0.4.3 - - '@humanfs/types@0.15.0': {} - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.4.3': {} - '@intlify/core-base@11.4.5': dependencies: '@intlify/devtools-types': 11.4.5 @@ -2035,10 +1332,65 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true - '@ota-meshi/ast-token-store@0.3.0': {} - '@oxc-project/types@0.133.0': {} + '@oxfmt/binding-android-arm-eabi@0.62.0': + optional: true + + '@oxfmt/binding-android-arm64@0.62.0': + optional: true + + '@oxfmt/binding-darwin-arm64@0.62.0': + optional: true + + '@oxfmt/binding-darwin-x64@0.62.0': + optional: true + + '@oxfmt/binding-freebsd-x64@0.62.0': + optional: true + + '@oxfmt/binding-linux-arm-gnueabihf@0.62.0': + optional: true + + '@oxfmt/binding-linux-arm-musleabihf@0.62.0': + optional: true + + '@oxfmt/binding-linux-arm64-gnu@0.62.0': + optional: true + + '@oxfmt/binding-linux-arm64-musl@0.62.0': + optional: true + + '@oxfmt/binding-linux-ppc64-gnu@0.62.0': + optional: true + + '@oxfmt/binding-linux-riscv64-gnu@0.62.0': + optional: true + + '@oxfmt/binding-linux-riscv64-musl@0.62.0': + optional: true + + '@oxfmt/binding-linux-s390x-gnu@0.62.0': + optional: true + + '@oxfmt/binding-linux-x64-gnu@0.62.0': + optional: true + + '@oxfmt/binding-linux-x64-musl@0.62.0': + optional: true + + '@oxfmt/binding-openharmony-arm64@0.62.0': + optional: true + + '@oxfmt/binding-win32-arm64-msvc@0.62.0': + optional: true + + '@oxfmt/binding-win32-ia32-msvc@0.62.0': + optional: true + + '@oxfmt/binding-win32-x64-msvc@0.62.0': + optional: true + '@parcel/watcher-android-arm64@2.5.6': optional: true @@ -2100,8 +1452,6 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.6 optional: true - '@pkgr/core@0.3.6': {} - '@rolldown/binding-android-arm64@1.0.3': optional: true @@ -2153,16 +1503,6 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@stylistic/eslint-plugin@5.10.0(eslint@9.39.4)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - '@typescript-eslint/types': 8.61.1 - eslint: 9.39.4 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - estraverse: 5.3.0 - picomatch: 4.0.4 - '@tsconfig/node22@22.0.5': {} '@tybys/wasm-util@0.10.2': @@ -2170,109 +1510,12 @@ snapshots: tslib: 2.8.1 optional: true - '@types/esrecurse@4.3.1': {} - - '@types/estree@1.0.9': {} - '@types/jsesc@2.5.1': {} - '@types/json-schema@7.0.15': {} - '@types/node@24.13.2': dependencies: undici-types: 7.18.2 - '@typescript-eslint/eslint-plugin@8.61.1(@typescript-eslint/parser@8.61.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/type-utils': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/utils': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.61.1 - eslint: 9.39.4 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.61.1(eslint@9.39.4)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.61.1 - debug: 4.4.3 - eslint: 9.39.4 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.61.1(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@5.9.3) - '@typescript-eslint/types': 8.61.1 - debug: 4.4.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.61.1': - dependencies: - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/visitor-keys': 8.61.1 - - '@typescript-eslint/tsconfig-utils@8.61.1(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - - '@typescript-eslint/type-utils@8.61.1(eslint@9.39.4)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.39.4 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.61.1': {} - - '@typescript-eslint/typescript-estree@8.61.1(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.61.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@5.9.3) - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/visitor-keys': 8.61.1 - debug: 4.4.3 - minimatch: 10.2.5 - semver: 7.8.4 - tinyglobby: 0.2.17 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.61.1(eslint@9.39.4)(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@5.9.3) - eslint: 9.39.4 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.61.1': - dependencies: - '@typescript-eslint/types': 8.61.1 - eslint-visitor-keys: 5.0.1 - '@vitejs/plugin-vue@6.0.7(vite@8.0.16(@types/node@24.13.2)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.38(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.1 @@ -2409,29 +1652,12 @@ snapshots: vue: 3.5.38(typescript@5.9.3) vuetify: 4.1.2(typescript@5.9.3)(vite-plugin-vuetify@2.1.3)(vue@3.5.38(typescript@5.9.3)) - acorn-jsx@5.3.2(acorn@8.17.0): - dependencies: - acorn: 8.17.0 - acorn@8.17.0: {} - ajv@6.15.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - alien-signals@3.2.1: {} - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - ansi-styles@6.2.3: {} - argparse@2.0.1: {} - ast-kit@2.2.0: dependencies: '@babel/parser': 7.29.7 @@ -2443,66 +1669,14 @@ snapshots: '@babel/types': 7.29.7 ast-kit: 2.2.0 - balanced-match@1.0.2: {} - - balanced-match@4.0.4: {} - - baseline-browser-mapping@2.10.38: {} - birpc@2.9.0: {} - boolbase@1.0.0: {} - - brace-expansion@1.1.15: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@5.0.6: - dependencies: - balanced-match: 4.0.4 - - browserslist@4.28.2: - dependencies: - baseline-browser-mapping: 2.10.38 - caniuse-lite: 1.0.30001799 - electron-to-chromium: 1.5.375 - node-releases: 2.0.47 - update-browserslist-db: 1.2.3(browserslist@4.28.2) - - builtin-modules@5.2.0: {} - - callsites@3.1.0: {} - - caniuse-lite@1.0.30001799: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - change-case@5.4.4: {} - chokidar@5.0.0: dependencies: readdirp: 5.0.0 - ci-info@4.4.0: {} - - citty@0.2.2: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - colorjs.io@0.5.2: {} - comment-parser@1.4.7: {} - - concat-map@0.0.1: {} - confbox@0.1.8: {} confbox@0.2.4: {} @@ -2511,348 +1685,46 @@ snapshots: dependencies: is-what: 5.5.0 - core-js-compat@3.49.0: - dependencies: - browserslist: 4.28.2 - cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - cssesc@3.0.0: {} - csstype@3.2.3: {} debug@4.4.3: dependencies: ms: 2.1.3 - deep-is@0.1.4: {} - - detect-indent@7.0.2: {} - detect-libc@2.1.2: {} - diff-sequences@29.6.3: {} - - electron-to-chromium@1.5.375: {} - - empathic@2.0.1: {} - entities@7.0.1: {} - escalade@3.2.0: {} - - escape-string-regexp@4.0.0: {} - - eslint-config-flat-gitignore@2.3.0(eslint@9.39.4): - dependencies: - '@eslint/compat': 2.1.0(eslint@9.39.4) - eslint: 9.39.4 - - eslint-config-vuetify@4.7.1(eslint@9.39.4)(typescript@5.9.3): - dependencies: - '@clack/prompts': 1.5.1 - '@eslint/eslintrc': 3.3.5 - '@eslint/js': 10.0.1(eslint@9.39.4) - '@stylistic/eslint-plugin': 5.10.0(eslint@9.39.4) - '@typescript-eslint/parser': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 - eslint-config-flat-gitignore: 2.3.0(eslint@9.39.4) - eslint-flat-config-utils: 3.2.0 - eslint-plugin-antfu: 3.2.3(eslint@9.39.4) - eslint-plugin-import-lite: 0.6.0(eslint@9.39.4) - eslint-plugin-jsonc: 3.2.0(eslint@9.39.4) - eslint-plugin-perfectionist: 5.9.1(eslint@9.39.4)(typescript@5.9.3) - eslint-plugin-pnpm: 1.6.1(eslint@9.39.4) - eslint-plugin-regexp: 3.1.0(eslint@9.39.4) - eslint-plugin-unicorn: 65.0.1(eslint@9.39.4) - eslint-plugin-vue: 10.9.2(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4))(@typescript-eslint/parser@8.61.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(vue-eslint-parser@10.4.1(eslint@9.39.4)) - eslint-typegen: 2.3.1(eslint@9.39.4) - exsolve: 1.0.8 - globals: 17.6.0 - jsonc-eslint-parser: 3.1.0 - kolorist: 1.8.0 - local-pkg: 1.2.1 - nypm: 0.6.7 - package-manager-detector: 1.6.0 - tinyexec: 1.2.4 - typescript-eslint: 8.61.1(eslint@9.39.4)(typescript@5.9.3) - vue-eslint-parser: 10.4.1(eslint@9.39.4) - yaml-eslint-parser: 2.0.0 - transitivePeerDependencies: - - '@eslint/json' - - supports-color - - typescript - - eslint-flat-config-utils@3.2.0: - dependencies: - '@eslint/config-helpers': 0.5.5 - pathe: 2.0.3 - - eslint-json-compat-utils@0.2.3(eslint@9.39.4)(jsonc-eslint-parser@3.1.0): - dependencies: - eslint: 9.39.4 - esquery: 1.7.0 - jsonc-eslint-parser: 3.1.0 - - eslint-plugin-antfu@3.2.3(eslint@9.39.4): - dependencies: - eslint: 9.39.4 - - eslint-plugin-import-lite@0.6.0(eslint@9.39.4): - dependencies: - eslint: 9.39.4 - - eslint-plugin-jsonc@3.2.0(eslint@9.39.4): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.2 - '@ota-meshi/ast-token-store': 0.3.0 - diff-sequences: 29.6.3 - eslint: 9.39.4 - eslint-json-compat-utils: 0.2.3(eslint@9.39.4)(jsonc-eslint-parser@3.1.0) - jsonc-eslint-parser: 3.1.0 - natural-compare: 1.4.0 - synckit: 0.11.13 - transitivePeerDependencies: - - '@eslint/json' - - eslint-plugin-perfectionist@5.9.1(eslint@9.39.4)(typescript@5.9.3): - dependencies: - '@typescript-eslint/utils': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 - natural-orderby: 5.0.0 - transitivePeerDependencies: - - supports-color - - typescript - - eslint-plugin-pnpm@1.6.1(eslint@9.39.4): - dependencies: - empathic: 2.0.1 - eslint: 9.39.4 - jsonc-eslint-parser: 3.1.0 - pathe: 2.0.3 - pnpm-workspace-yaml: 1.6.1 - tinyglobby: 0.2.17 - yaml: 2.9.0 - yaml-eslint-parser: 2.0.0 - - eslint-plugin-regexp@3.1.0(eslint@9.39.4): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - '@eslint-community/regexpp': 4.12.2 - comment-parser: 1.4.7 - eslint: 9.39.4 - jsdoc-type-pratt-parser: 7.2.0 - refa: 0.12.1 - regexp-ast-analysis: 0.7.1 - scslre: 0.3.0 - - eslint-plugin-unicorn@65.0.1(eslint@9.39.4): - dependencies: - '@babel/helper-validator-identifier': 7.29.7 - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - change-case: 5.4.4 - ci-info: 4.4.0 - core-js-compat: 3.49.0 - detect-indent: 7.0.2 - eslint: 9.39.4 - find-up-simple: 1.0.1 - globals: 17.6.0 - indent-string: 5.0.0 - is-builtin-module: 5.0.0 - jsesc: 3.1.0 - pluralize: 8.0.0 - regjsparser: 0.13.2 - semver: 7.8.4 - strip-indent: 4.1.1 - - eslint-plugin-vue@10.9.2(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4))(@typescript-eslint/parser@8.61.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(vue-eslint-parser@10.4.1(eslint@9.39.4)): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - eslint: 9.39.4 - natural-compare: 1.4.0 - nth-check: 2.1.1 - postcss-selector-parser: 7.1.4 - semver: 7.8.4 - vue-eslint-parser: 10.4.1(eslint@9.39.4) - xml-name-validator: 4.0.0 - optionalDependencies: - '@stylistic/eslint-plugin': 5.10.0(eslint@9.39.4) - '@typescript-eslint/parser': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-scope@9.1.2: - dependencies: - '@types/esrecurse': 4.3.1 - '@types/estree': 1.0.9 - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-typegen@2.3.1(eslint@9.39.4): - dependencies: - eslint: 9.39.4 - json-schema-to-typescript-lite: 15.0.0 - ohash: 2.0.11 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint-visitor-keys@5.0.1: {} - - eslint@9.39.4: - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - '@eslint-community/regexpp': 4.12.2 - '@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.8 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.9 - ajv: 6.15.0 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - escape-string-regexp: 4.0.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 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.5 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.17.0 - acorn-jsx: 5.3.2(acorn@8.17.0) - eslint-visitor-keys: 4.2.1 - - espree@11.2.0: - dependencies: - acorn: 8.17.0 - acorn-jsx: 5.3.2(acorn@8.17.0) - eslint-visitor-keys: 5.0.1 - - esquery@1.7.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - estree-walker@2.0.2: {} - esutils@2.0.3: {} - exsolve@1.0.8: {} - fast-deep-equal@3.1.3: {} - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fast-string-truncated-width@3.0.3: {} - - fast-string-width@3.0.2: - dependencies: - fast-string-truncated-width: 3.0.3 - - fast-wrap-ansi@0.2.2: - dependencies: - fast-string-width: 3.0.2 - fdir@6.5.0(picomatch@4.0.4): optionalDependencies: picomatch: 4.0.4 - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - find-up-simple@1.0.1: {} - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.4.2 - keyv: 4.5.4 - - flatted@3.4.2: {} - fsevents@2.3.3: optional: true - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - globals@14.0.0: {} - - globals@17.6.0: {} - has-flag@4.0.0: {} hookable@5.5.3: {} - ignore@5.3.2: {} - - ignore@7.0.5: {} - immutable@5.1.6: {} - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - indent-string@5.0.0: {} - - is-builtin-module@5.0.0: - dependencies: - builtin-modules: 5.2.0 - - is-extglob@2.1.1: {} + is-extglob@2.1.1: + optional: true is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + optional: true is-what@5.5.0: {} @@ -2860,48 +1732,14 @@ snapshots: isexe@3.1.5: {} - js-yaml@4.2.0: - dependencies: - argparse: 2.0.1 - - jsdoc-type-pratt-parser@7.2.0: {} - jsesc@3.1.0: {} - json-buffer@3.0.1: {} - json-parse-even-better-errors@4.0.0: {} - json-schema-to-typescript-lite@15.0.0: - dependencies: - '@apidevtools/json-schema-ref-parser': 14.2.1(@types/json-schema@7.0.15) - '@types/json-schema': 7.0.15 - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - json5@2.2.3: {} - jsonc-eslint-parser@3.1.0: - dependencies: - acorn: 8.17.0 - eslint-visitor-keys: 5.0.1 - semver: 7.8.4 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kolorist@1.8.0: {} - ky@2.0.2: {} - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - lightningcss-android-arm64@1.32.0: optional: true @@ -2957,12 +1795,6 @@ snapshots: pkg-types: 2.3.1 quansync: 0.2.11 - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - magic-string-ast@1.0.3: dependencies: magic-string: 0.30.21 @@ -2973,14 +1805,6 @@ snapshots: memorystream@0.3.1: {} - minimatch@10.2.5: - dependencies: - brace-expansion: 5.0.6 - - minimatch@3.1.5: - dependencies: - brace-expansion: 1.1.15 - mitt@3.0.1: {} mlly@1.8.2: @@ -2996,15 +1820,9 @@ snapshots: nanoid@3.3.12: {} - natural-compare@1.4.0: {} - - natural-orderby@5.0.0: {} - node-addon-api@7.1.1: optional: true - node-releases@2.0.47: {} - npm-normalize-package-bin@4.0.0: {} npm-run-all2@8.0.4: @@ -3018,45 +1836,32 @@ snapshots: shell-quote: 1.8.4 which: 5.0.0 - nth-check@2.1.1: + oxfmt@0.62.0: dependencies: - boolbase: 1.0.0 - - nypm@0.6.7: - dependencies: - citty: 0.2.2 - pathe: 2.0.3 - tinyexec: 1.2.4 - - ohash@2.0.11: {} - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - package-manager-detector@1.6.0: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 + tinypool: 2.1.0 + optionalDependencies: + '@oxfmt/binding-android-arm-eabi': 0.62.0 + '@oxfmt/binding-android-arm64': 0.62.0 + '@oxfmt/binding-darwin-arm64': 0.62.0 + '@oxfmt/binding-darwin-x64': 0.62.0 + '@oxfmt/binding-freebsd-x64': 0.62.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.62.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.62.0 + '@oxfmt/binding-linux-arm64-gnu': 0.62.0 + '@oxfmt/binding-linux-arm64-musl': 0.62.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.62.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.62.0 + '@oxfmt/binding-linux-riscv64-musl': 0.62.0 + '@oxfmt/binding-linux-s390x-gnu': 0.62.0 + '@oxfmt/binding-linux-x64-gnu': 0.62.0 + '@oxfmt/binding-linux-x64-musl': 0.62.0 + '@oxfmt/binding-openharmony-arm64': 0.62.0 + '@oxfmt/binding-win32-arm64-msvc': 0.62.0 + '@oxfmt/binding-win32-ia32-msvc': 0.62.0 + '@oxfmt/binding-win32-x64-msvc': 0.62.0 path-browserify@1.0.1: {} - path-exists@4.0.0: {} - path-key@3.1.1: {} pathe@2.0.3: {} @@ -3090,27 +1895,12 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 - pluralize@8.0.0: {} - - pnpm-workspace-yaml@1.6.1: - dependencies: - yaml: 2.9.0 - - postcss-selector-parser@7.1.4: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - postcss@8.5.15: dependencies: nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 - prelude-ls@1.2.1: {} - - punycode@2.3.1: {} - quansync@0.2.11: {} read-package-json-fast@4.0.0: @@ -3120,21 +1910,6 @@ snapshots: readdirp@5.0.0: {} - refa@0.12.1: - dependencies: - '@eslint-community/regexpp': 4.12.2 - - regexp-ast-analysis@0.7.1: - dependencies: - '@eslint-community/regexpp': 4.12.2 - refa: 0.12.1 - - regjsparser@0.13.2: - dependencies: - jsesc: 3.1.0 - - resolve-from@4.0.0: {} - rfdc@1.4.1: {} rolldown@1.0.3: @@ -3258,16 +2033,8 @@ snapshots: '@parcel/watcher': 2.5.6 optional: true - scslre@0.3.0: - dependencies: - '@eslint-community/regexpp': 4.12.2 - refa: 0.12.1 - regexp-ast-analysis: 0.7.1 - scule@1.3.0: {} - semver@7.8.4: {} - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -3276,24 +2043,14 @@ snapshots: shell-quote@1.8.4: {} - sisteransi@1.0.5: {} - source-map-js@1.2.1: {} speakingurl@14.0.1: {} - strip-indent@4.1.1: {} - - strip-json-comments@3.1.1: {} - superjson@2.2.6: dependencies: copy-anything: 4.0.5 - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - supports-color@8.1.1: dependencies: has-flag: 4.0.0 @@ -3304,38 +2061,15 @@ snapshots: sync-message-port@1.2.0: {} - synckit@0.11.13: - dependencies: - '@pkgr/core': 0.3.6 - - tinyexec@1.2.4: {} - tinyglobby@0.2.17: dependencies: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - ts-api-utils@2.5.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 + tinypool@2.1.0: {} tslib@2.8.1: {} - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - typescript-eslint@8.61.1(eslint@9.39.4)(typescript@5.9.3): - dependencies: - '@typescript-eslint/eslint-plugin': 8.61.1(@typescript-eslint/parser@8.61.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/parser': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.61.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.61.1(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - typescript@5.9.3: {} ufo@1.6.4: {} @@ -3355,18 +2089,6 @@ snapshots: upath@2.0.1: {} - update-browserslist-db@1.2.3(browserslist@4.28.2): - dependencies: - browserslist: 4.28.2 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - util-deprecate@1.0.2: {} - varint@6.0.0: {} vite-plugin-vuetify@2.1.3(vite@8.0.16(@types/node@24.13.2)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.38(typescript@5.9.3))(vuetify@4.1.2): @@ -3396,18 +2118,6 @@ snapshots: vscode-uri@3.1.0: {} - vue-eslint-parser@10.4.1(eslint@9.39.4): - dependencies: - debug: 4.4.3 - eslint: 9.39.4 - eslint-scope: 9.1.2 - eslint-visitor-keys: 5.0.1 - espree: 11.2.0 - esquery: 1.7.0 - semver: 7.8.4 - transitivePeerDependencies: - - supports-color - vue-i18n@11.4.5(vue@3.5.38(typescript@5.9.3)): dependencies: '@intlify/core-base': 11.4.5 @@ -3474,15 +2184,4 @@ snapshots: dependencies: isexe: 3.1.5 - word-wrap@1.2.5: {} - - xml-name-validator@4.0.0: {} - - yaml-eslint-parser@2.0.0: - dependencies: - eslint-visitor-keys: 5.0.1 - yaml: 2.9.0 - yaml@2.9.0: {} - - yocto-queue@0.1.0: {}