From 9667dc615ab6e194879f5f3190fcfe9f177fcbab Mon Sep 17 00:00:00 2001 From: digua Date: Wed, 26 Nov 2025 23:24:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E8=A7=A3=E6=9E=90=E5=92=8C=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .npmrc | 2 + electron/main/database/index.ts | 634 ++++++++ electron/main/index.ts | 16 +- electron/main/ipcMain.ts | 247 ++- electron/main/parser/index.ts | 73 + electron/main/parser/qqJsonParser.ts | 207 +++ electron/main/parser/qqTxtParser.ts | 208 +++ electron/main/parser/types.ts | 44 + electron/preload/index.d.ts | 44 +- electron/preload/index.ts | 143 +- package.json | 13 +- pnpm-lock.yaml | 1393 ++++++++++------- src/App.vue | 12 + src/components.d.ts | 18 +- src/components/ImportProgressModal.vue | 101 ++ src/components/Sidebar.vue | 150 +- src/components/WelcomeGuide.vue | 126 +- src/components/analysis/AnalysisDashboard.vue | 270 ++++ src/components/analysis/MembersTab.vue | 68 + src/components/analysis/OverviewTab.vue | 221 +++ src/components/analysis/TimelineTab.vue | 183 +++ src/components/charts/BarChart.vue | 117 ++ src/components/charts/DoughnutChart.vue | 82 + src/components/charts/HorizontalBarChart.vue | 105 ++ src/components/charts/LineChart.vue | 114 ++ src/components/charts/MemberRankList.vue | 106 ++ src/components/charts/ProgressBar.vue | 29 + src/components/charts/README.md | 327 ++++ src/components/charts/index.ts | 14 + src/pages/index.vue | 32 +- src/stores/chat.ts | 155 +- src/types/chat.ts | 168 ++ src/types/index.ts | 5 + 34 files changed, 4714 insertions(+), 714 deletions(-) create mode 100644 electron/main/database/index.ts create mode 100644 electron/main/parser/index.ts create mode 100644 electron/main/parser/qqJsonParser.ts create mode 100644 electron/main/parser/qqTxtParser.ts create mode 100644 electron/main/parser/types.ts create mode 100644 src/components/ImportProgressModal.vue create mode 100644 src/components/analysis/AnalysisDashboard.vue create mode 100644 src/components/analysis/MembersTab.vue create mode 100644 src/components/analysis/OverviewTab.vue create mode 100644 src/components/analysis/TimelineTab.vue create mode 100644 src/components/charts/BarChart.vue create mode 100644 src/components/charts/DoughnutChart.vue create mode 100644 src/components/charts/HorizontalBarChart.vue create mode 100644 src/components/charts/LineChart.vue create mode 100644 src/components/charts/MemberRankList.vue create mode 100644 src/components/charts/ProgressBar.vue create mode 100644 src/components/charts/README.md create mode 100644 src/components/charts/index.ts create mode 100644 src/types/chat.ts create mode 100644 src/types/index.ts diff --git a/.gitignore b/.gitignore index 222eec5..471fdad 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ npm-debug.log* yarn-debug.log* yarn-error.log* *.log +error-log-*.txt # Editor !.vscode/settings.json diff --git a/.npmrc b/.npmrc index 3be0371..15e7bf1 100644 --- a/.npmrc +++ b/.npmrc @@ -37,3 +37,5 @@ utp-native-binary-host-mirror=https://npmmirror.com/mirrors/utp-native/v{version zmq-prebuilt-binary-host-mirror=https://npmmirror.com/mirrors/zmq-prebuilt/v{version} phantomjs_cdnurl=https://npmmirror.com/mirrors/phantomjs/ shamefully-hoist=true +# 允许 better-sqlite3 构建脚本 +better-sqlite3_binary_host_mirror=https://npmmirror.com/mirrors/better-sqlite3 diff --git a/electron/main/database/index.ts b/electron/main/database/index.ts new file mode 100644 index 0000000..c305256 --- /dev/null +++ b/electron/main/database/index.ts @@ -0,0 +1,634 @@ +/** + * 数据库服务模块 + * 管理 SQLite 数据库的创建、查询和分析 + */ + +import Database from 'better-sqlite3' +import { app } from 'electron' +import * as fs from 'fs' +import * as path from 'path' +import type { + DbMeta, + ParseResult, + AnalysisSession, + MemberActivity, + HourlyActivity, + DailyActivity, + MessageType, +} from '../../../src/types/chat' + +// 数据库存储目录 +let DB_DIR: string | null = null + +/** + * 获取数据库目录(懒加载) + */ +function getDbDir(): string { + if (DB_DIR) return DB_DIR + + try { + // 使用 Documents 目录,避免开发环境下 userData 被重置的问题,也方便用户管理数据 + const docPath = app.getPath('documents') + console.log('[Database] app.getPath("documents"):', docPath) + DB_DIR = path.join(docPath, 'ChatLens', 'databases') + } catch (error) { + console.error('[Database] Error getting userData path:', error) + DB_DIR = path.join(process.cwd(), 'databases') + console.log('[Database] Using fallback DB_DIR:', DB_DIR) + } + + return DB_DIR +} + +/** + * 确保数据库目录存在 + */ +function ensureDbDir(): void { + const dir = getDbDir() + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }) + } +} + +/** + * 生成唯一的会话ID + */ +function generateSessionId(): string { + const timestamp = Date.now() + const random = Math.random().toString(36).substring(2, 8) + return `chat_${timestamp}_${random}` +} + +/** + * 获取数据库文件路径 + */ +function getDbPath(sessionId: string): string { + return path.join(getDbDir(), `${sessionId}.db`) +} + +/** + * 创建新数据库并初始化表结构 + */ +function createDatabase(sessionId: string): Database.Database { + ensureDbDir() + const dbPath = getDbPath(sessionId) + const db = new Database(dbPath) + + // 启用 WAL 模式提升性能 + db.pragma('journal_mode = WAL') + + // 创建表结构 + db.exec(` + -- 元信息表(单行) + CREATE TABLE IF NOT EXISTS meta ( + name TEXT NOT NULL, + platform TEXT NOT NULL, + type TEXT NOT NULL, + imported_at INTEGER NOT NULL + ); + + -- 成员表 + CREATE TABLE IF NOT EXISTS member ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + platform_id TEXT NOT NULL UNIQUE, + name TEXT NOT NULL + ); + + -- 消息表 + CREATE TABLE IF NOT EXISTS message ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + sender_id INTEGER NOT NULL, + ts INTEGER NOT NULL, + type INTEGER NOT NULL, + content TEXT, + FOREIGN KEY(sender_id) REFERENCES member(id) + ); + + -- 索引 + CREATE INDEX IF NOT EXISTS idx_message_ts ON message(ts); + CREATE INDEX IF NOT EXISTS idx_message_sender ON message(sender_id); + `) + + return db +} + +/** + * 打开已存在的数据库 + */ +function openDatabase(sessionId: string): Database.Database | null { + const dbPath = getDbPath(sessionId) + if (!fs.existsSync(dbPath)) { + return null + } + const db = new Database(dbPath, { readonly: true }) + db.pragma('journal_mode = WAL') + return db +} + +/** + * 导入解析后的数据到数据库 + */ +export function importData(parseResult: ParseResult): string { + console.log('[Database] importData called') + const sessionId = generateSessionId() + console.log('[Database] Generated sessionId:', sessionId) + + const dbPath = getDbPath(sessionId) + console.log('[Database] Creating database at:', dbPath) + + const db = createDatabase(sessionId) + console.log('[Database] Database created successfully') + + try { + // 使用事务提升性能 + const importTransaction = db.transaction(() => { + // 插入元信息 + const insertMeta = db.prepare(` + INSERT INTO meta (name, platform, type, imported_at) + VALUES (?, ?, ?, ?) + `) + insertMeta.run( + parseResult.meta.name, + parseResult.meta.platform, + parseResult.meta.type, + Math.floor(Date.now() / 1000) + ) + + // 插入成员并建立 platformId -> id 映射 + const insertMember = db.prepare(` + INSERT OR IGNORE INTO member (platform_id, name) VALUES (?, ?) + `) + const updateMemberName = db.prepare(` + UPDATE member SET name = ? WHERE platform_id = ? + `) + const getMemberId = db.prepare(` + SELECT id FROM member WHERE platform_id = ? + `) + + const memberIdMap = new Map() + + for (const member of parseResult.members) { + insertMember.run(member.platformId, member.name) + // 更新为最新昵称 + updateMemberName.run(member.name, member.platformId) + const row = getMemberId.get(member.platformId) as { id: number } + memberIdMap.set(member.platformId, row.id) + } + + // 批量插入消息 + const insertMessage = db.prepare(` + INSERT INTO message (sender_id, ts, type, content) VALUES (?, ?, ?, ?) + `) + + for (const msg of parseResult.messages) { + const senderId = memberIdMap.get(msg.senderPlatformId) + if (senderId !== undefined) { + insertMessage.run(senderId, msg.timestamp, msg.type, msg.content) + } + } + }) + + console.log('[Database] Executing transaction...') + importTransaction() + console.log('[Database] Transaction completed') + + // 验证文件是否存在 + const dbPath = getDbPath(sessionId) + const fileExists = fs.existsSync(dbPath) + console.log('[Database] File exists after transaction:', fileExists, dbPath) + + return sessionId + } catch (error) { + console.error('[Database] Error in importData:', error) + throw error + } finally { + console.log('[Database] Closing database...') + db.close() + console.log('[Database] Database closed') + + // 再次验证文件 + const dbPath = getDbPath(sessionId) + const fileExists = fs.existsSync(dbPath) + console.log('[Database] File exists after close:', fileExists) + } +} + +/** + * 获取所有分析会话列表 + */ +export function getAllSessions(): AnalysisSession[] { + ensureDbDir() + const sessions: AnalysisSession[] = [] + + const dbDir = getDbDir() + console.log('[Database] getAllSessions: DB_DIR =', dbDir) + console.log('[Database] getAllSessions: DB_DIR exists =', fs.existsSync(dbDir)) + + // 列出目录内容 + const allFiles = fs.readdirSync(dbDir) + console.log('[Database] getAllSessions: all files in dir:', allFiles) + + const files = allFiles.filter((f) => f.endsWith('.db')) + console.log('[Database] getAllSessions: filtered .db files:', files) + + for (const file of files) { + const sessionId = file.replace('.db', '') + const dbPath = getDbPath(sessionId) + console.log('[Database] Opening database:', dbPath) + + try { + // 不使用 readonly 模式,以便能正确读取 WAL 日志 + const db = new Database(dbPath) + db.pragma('journal_mode = WAL') + + // 获取元信息 + const meta = db.prepare('SELECT * FROM meta LIMIT 1').get() as DbMeta | undefined + console.log('[Database] Meta:', meta) + + if (meta) { + // 获取消息数和成员数(排除系统消息) + const messageCount = ( + db + .prepare( + `SELECT COUNT(*) as count + FROM message msg + JOIN member m ON msg.sender_id = m.id + WHERE m.name != '系统消息'` + ) + .get() as { count: number } + ).count + const memberCount = ( + db + .prepare( + `SELECT COUNT(*) as count + FROM member + WHERE name != '系统消息'` + ) + .get() as { count: number } + ).count + console.log('[Database] Counts:', { messageCount, memberCount }) + + sessions.push({ + id: sessionId, + name: meta.name, + platform: meta.platform as AnalysisSession['platform'], + type: meta.type as AnalysisSession['type'], + importedAt: meta.imported_at, + messageCount, + memberCount, + dbPath, + }) + } + + db.close() + } catch (error) { + // 跳过无法读取的数据库文件 + console.error(`[Database] Failed to read database ${file}:`, error) + } + } + + console.log('[Database] getAllSessions: returning', sessions.length, 'sessions') + // 按导入时间倒序排列 + return sessions.sort((a, b) => b.importedAt - a.importedAt) +} + +/** + * 获取单个会话信息 + */ +export function getSession(sessionId: string): AnalysisSession | null { + const db = openDatabase(sessionId) + if (!db) return null + + try { + const meta = db.prepare('SELECT * FROM meta LIMIT 1').get() as DbMeta | undefined + if (!meta) return null + + // 排除系统消息的消息数 + const messageCount = ( + db + .prepare( + `SELECT COUNT(*) as count + FROM message msg + JOIN member m ON msg.sender_id = m.id + WHERE m.name != '系统消息'` + ) + .get() as { count: number } + ).count + + // 排除系统消息的成员数 + const memberCount = ( + db + .prepare( + `SELECT COUNT(*) as count + FROM member + WHERE name != '系统消息'` + ) + .get() as { count: number } + ).count + + return { + id: sessionId, + name: meta.name, + platform: meta.platform as AnalysisSession['platform'], + type: meta.type as AnalysisSession['type'], + importedAt: meta.imported_at, + messageCount, + memberCount, + dbPath: getDbPath(sessionId), + } + } finally { + db.close() + } +} + +/** + * 删除会话 + */ +export function deleteSession(sessionId: string): boolean { + const dbPath = getDbPath(sessionId) + const walPath = dbPath + '-wal' + const shmPath = dbPath + '-shm' + + try { + if (fs.existsSync(dbPath)) fs.unlinkSync(dbPath) + if (fs.existsSync(walPath)) fs.unlinkSync(walPath) + if (fs.existsSync(shmPath)) fs.unlinkSync(shmPath) + return true + } catch { + return false + } +} + +// ==================== 分析查询 ==================== + +/** + * 时间过滤参数 + */ +export interface TimeFilter { + startTs?: number // 开始时间戳(秒) + endTs?: number // 结束时间戳(秒) +} + +/** + * 构建时间过滤 WHERE 子句 + */ +function buildTimeFilter(filter?: TimeFilter): { clause: string; params: number[] } { + const conditions: string[] = [] + const params: number[] = [] + + if (filter?.startTs !== undefined) { + conditions.push('ts >= ?') + params.push(filter.startTs) + } + if (filter?.endTs !== undefined) { + conditions.push('ts <= ?') + params.push(filter.endTs) + } + + return { + clause: conditions.length > 0 ? ` WHERE ${conditions.join(' AND ')}` : '', + params, + } +} + +/** + * 构建排除系统消息的过滤条件 + * @param existingClause 已有的 WHERE 子句(如时间过滤) + */ +function buildSystemMessageFilter(existingClause: string): string { + const systemFilter = "m.name != '系统消息'" + + if (existingClause.includes('WHERE')) { + return existingClause + ' AND ' + systemFilter + } else { + return ' WHERE ' + systemFilter + } +} + +/** + * 获取可用的年份列表 + */ +export function getAvailableYears(sessionId: string): number[] { + const db = openDatabase(sessionId) + if (!db) return [] + + try { + const rows = db + .prepare( + ` + SELECT DISTINCT CAST(strftime('%Y', ts, 'unixepoch', 'localtime') AS INTEGER) as year + FROM message + ORDER BY year + ` + ) + .all() as Array<{ year: number }> + + return rows.map((r) => r.year) + } finally { + db.close() + } +} + +/** + * 获取成员活跃度排行 + */ +export function getMemberActivity(sessionId: string, filter?: TimeFilter): MemberActivity[] { + const db = openDatabase(sessionId) + if (!db) return [] + + try { + const { clause, params } = buildTimeFilter(filter) + + // 构建消息过滤条件(排除系统消息 + 时间过滤) + const msgFilterBase = clause ? clause.replace('WHERE', 'AND') : '' + const msgFilterWithSystem = msgFilterBase + " AND m.name != '系统消息'" + + // 计算总消息数(排除系统消息) + const totalClauseWithSystem = buildSystemMessageFilter(clause) + const totalMessages = ( + db + .prepare( + `SELECT COUNT(*) as count + FROM message msg + JOIN member m ON msg.sender_id = m.id + ${totalClauseWithSystem}` + ) + .get(...params) as { count: number } + ).count + + const rows = db + .prepare( + ` + SELECT + m.id as memberId, + m.platform_id as platformId, + m.name, + COUNT(msg.id) as messageCount + FROM member m + LEFT JOIN message msg ON m.id = msg.sender_id ${msgFilterWithSystem} + WHERE m.name != '系统消息' + GROUP BY m.id + HAVING messageCount > 0 + ORDER BY messageCount DESC + ` + ) + .all(...params) as Array<{ + memberId: number + platformId: string + name: string + messageCount: number + }> + + return rows.map((row) => ({ + memberId: row.memberId, + platformId: row.platformId, + name: row.name, + messageCount: row.messageCount, + percentage: totalMessages > 0 ? Math.round((row.messageCount / totalMessages) * 10000) / 100 : 0, + })) + } finally { + db.close() + } +} + +/** + * 获取每小时活跃度分布 + */ +export function getHourlyActivity(sessionId: string, filter?: TimeFilter): HourlyActivity[] { + const db = openDatabase(sessionId) + if (!db) return [] + + try { + const { clause, params } = buildTimeFilter(filter) + const clauseWithSystem = buildSystemMessageFilter(clause) + + const rows = db + .prepare( + ` + SELECT + CAST(strftime('%H', msg.ts, 'unixepoch', 'localtime') AS INTEGER) as hour, + COUNT(*) as messageCount + FROM message msg + JOIN member m ON msg.sender_id = m.id + ${clauseWithSystem} + GROUP BY hour + ORDER BY hour + ` + ) + .all(...params) as Array<{ hour: number; messageCount: number }> + + // 补齐所有24小时 + const result: HourlyActivity[] = [] + for (let h = 0; h < 24; h++) { + const found = rows.find((r) => r.hour === h) + result.push({ + hour: h, + messageCount: found ? found.messageCount : 0, + }) + } + + return result + } finally { + db.close() + } +} + +/** + * 获取每日活跃度趋势 + */ +export function getDailyActivity(sessionId: string, filter?: TimeFilter): DailyActivity[] { + const db = openDatabase(sessionId) + if (!db) return [] + + try { + const { clause, params } = buildTimeFilter(filter) + const clauseWithSystem = buildSystemMessageFilter(clause) + + const rows = db + .prepare( + ` + SELECT + strftime('%Y-%m-%d', msg.ts, 'unixepoch', 'localtime') as date, + COUNT(*) as messageCount + FROM message msg + JOIN member m ON msg.sender_id = m.id + ${clauseWithSystem} + GROUP BY date + ORDER BY date + ` + ) + .all(...params) as Array<{ date: string; messageCount: number }> + + return rows + } finally { + db.close() + } +} + +/** + * 获取消息类型分布 + */ +export function getMessageTypeDistribution( + sessionId: string, + filter?: TimeFilter +): Array<{ type: MessageType; count: number }> { + const db = openDatabase(sessionId) + if (!db) return [] + + try { + const { clause, params } = buildTimeFilter(filter) + const clauseWithSystem = buildSystemMessageFilter(clause) + + const rows = db + .prepare( + ` + SELECT msg.type, COUNT(*) as count + FROM message msg + JOIN member m ON msg.sender_id = m.id + ${clauseWithSystem} + GROUP BY msg.type + ORDER BY count DESC + ` + ) + .all(...params) as Array<{ type: number; count: number }> + + return rows.map((r) => ({ + type: r.type as MessageType, + count: r.count, + })) + } finally { + db.close() + } +} + +/** + * 获取时间范围 + */ +export function getTimeRange(sessionId: string): { start: number; end: number } | null { + const db = openDatabase(sessionId) + if (!db) return null + + try { + const row = db + .prepare( + ` + SELECT MIN(ts) as start, MAX(ts) as end FROM message + ` + ) + .get() as { start: number | null; end: number | null } + + if (row.start === null || row.end === null) return null + + return { start: row.start, end: row.end } + } finally { + db.close() + } +} + +/** + * 获取数据库存储目录 + */ +export function getDbDirectory(): string { + ensureDbDir() + return getDbDir() +} diff --git a/electron/main/index.ts b/electron/main/index.ts index 6e170d2..ac15021 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -63,7 +63,6 @@ class MainProcess { minHeight: 720, show: false, autoHideMenuBar: true, - titleBarStyle: 'hidden', webPreferences: { preload: join(__dirname, '../preload/index.js'), sandbox: false, @@ -98,15 +97,24 @@ class MainProcess { // 主应用程序事件 mainAppEvents() { app.whenReady().then(async () => { + console.log('[Main] App is ready') // 设置Windows应用程序用户模型id if (process.platform === 'win32') app.setAppUserModelId(app.getName()) // 创建主窗口 - this.createWindow() + console.log('[Main] Creating window...') + await this.createWindow() + console.log('[Main] Window created') + // 检查更新逻辑 checkUpdate(this.mainWindow) + // 引入主进程ipcMain - mainIpcMain(this.mainWindow) + if (this.mainWindow) { + console.log('[Main] Registering IPC handlers...') + mainIpcMain(this.mainWindow) + console.log('[Main] IPC handlers registered') + } // 开发环境下 F12 打开控制台 app.on('browser-window-created', (_, window) => { @@ -130,7 +138,7 @@ class MainProcess { if (d.reason == 'crashed') { w.reload() } - fs.appendFile(`./error-log-${+new Date()}.txt`, `${new Date()}渲染进程被杀死${d.reason}\n`) + // fs.appendFile(`./error-log-${+new Date()}.txt`, `${new Date()}渲染进程被杀死${d.reason}\n`) }) // 自定义协议 diff --git a/electron/main/ipcMain.ts b/electron/main/ipcMain.ts index f2ef5c4..410c6f2 100644 --- a/electron/main/ipcMain.ts +++ b/electron/main/ipcMain.ts @@ -1,8 +1,15 @@ -import { ipcMain, app, dialog, clipboard, shell } from 'electron' +import { ipcMain, app, dialog, clipboard, shell, BrowserWindow } from 'electron' import { autoUpdater } from 'electron-updater' import * as fs from 'fs/promises' -const mainIpcMain = (win) => { +// 导入数据库和解析器模块 +import * as database from './database' +import * as parser from './parser' + +console.log('[IpcMain] Database and Parser modules imported') + +const mainIpcMain = (win: BrowserWindow) => { + console.log('[IpcMain] Registering IPC handlers...') // ==================== 窗口操作 ==================== ipcMain.on('window-min', (ev) => { ev.preventDefault() @@ -105,6 +112,242 @@ const mainIpcMain = (win) => { return false } }) + + // ==================== 聊天记录导入与分析 ==================== + + /** + * 选择聊天记录文件 + */ + ipcMain.handle('chat:selectFile', async () => { + try { + const { canceled, filePaths } = await dialog.showOpenDialog({ + title: '选择聊天记录文件', + defaultPath: app.getPath('documents'), + properties: ['openFile'], + filters: [ + { name: '聊天记录', extensions: ['json', 'txt'] }, + { name: '所有文件', extensions: ['*'] }, + ], + buttonLabel: '导入', + }) + + if (canceled || filePaths.length === 0) { + return null + } + + const filePath = filePaths[0] + console.log('[IpcMain] File selected:', filePath) + + // 检测文件格式 + const format = parser.detectFormat(filePath) + console.log('[IpcMain] Detected format:', format) + if (!format) { + return { error: '无法识别的文件格式' } + } + + return { filePath, format } + } catch (error) { + console.error('[IpcMain] Error selecting file:', error) + return { error: String(error) } + } + }) + + /** + * 导入聊天记录 + */ + ipcMain.handle('chat:import', async (_, filePath: string) => { + console.log('[IpcMain] chat:import called with:', filePath) + + try { + // 发送进度:开始解析 + win.webContents.send('chat:importProgress', { + stage: 'parsing', + progress: 10, + message: '正在解析文件...', + }) + + console.log('[IpcMain] Parsing file...') + // 解析文件 + const parseResult = parser.parseFile(filePath) + console.log('[IpcMain] Parse result:', { + memberCount: parseResult.members.length, + messageCount: parseResult.messages.length, + }) + + // 发送进度:开始保存 + win.webContents.send('chat:importProgress', { + stage: 'saving', + progress: 50, + message: `正在保存 ${parseResult.messages.length} 条消息...`, + }) + + console.log('[IpcMain] Importing to database...') + // 导入到数据库 + const sessionId = database.importData(parseResult) + console.log('[IpcMain] Import successful, sessionId:', sessionId) + + // 发送进度:完成 + win.webContents.send('chat:importProgress', { + stage: 'done', + progress: 100, + message: '导入完成', + }) + + return { success: true, sessionId } + } catch (error) { + console.error('[IpcMain] Import failed:', error) + + win.webContents.send('chat:importProgress', { + stage: 'error', + progress: 0, + message: String(error), + }) + + return { success: false, error: String(error) } + } + }) + + /** + * 获取所有分析会话列表 + */ + ipcMain.handle('chat:getSessions', async () => { + console.log('[IpcMain] chat:getSessions called') + try { + const sessions = database.getAllSessions() + console.log('[IpcMain] Found sessions:', sessions.length) + return sessions + } catch (error) { + console.error('[IpcMain] Error getting sessions:', error) + return [] + } + }) + + /** + * 获取单个会话信息 + */ + ipcMain.handle('chat:getSession', async (_, sessionId: string) => { + try { + return database.getSession(sessionId) + } catch (error) { + console.error('获取会话信息失败:', error) + return null + } + }) + + /** + * 删除会话 + */ + ipcMain.handle('chat:deleteSession', async (_, sessionId: string) => { + try { + return database.deleteSession(sessionId) + } catch (error) { + console.error('删除会话失败:', error) + return false + } + }) + + /** + * 获取可用年份列表 + */ + ipcMain.handle('chat:getAvailableYears', async (_, sessionId: string) => { + try { + return database.getAvailableYears(sessionId) + } catch (error) { + console.error('获取可用年份失败:', error) + return [] + } + }) + + /** + * 获取成员活跃度排行 + */ + ipcMain.handle( + 'chat:getMemberActivity', + async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => { + try { + return database.getMemberActivity(sessionId, filter) + } catch (error) { + console.error('获取成员活跃度失败:', error) + return [] + } + } + ) + + /** + * 获取每小时活跃度分布 + */ + ipcMain.handle( + 'chat:getHourlyActivity', + async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => { + try { + return database.getHourlyActivity(sessionId, filter) + } catch (error) { + console.error('获取小时活跃度失败:', error) + return [] + } + } + ) + + /** + * 获取每日活跃度趋势 + */ + ipcMain.handle( + 'chat:getDailyActivity', + async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => { + try { + return database.getDailyActivity(sessionId, filter) + } catch (error) { + console.error('获取日活跃度失败:', error) + return [] + } + } + ) + + /** + * 获取消息类型分布 + */ + ipcMain.handle( + 'chat:getMessageTypeDistribution', + async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => { + try { + return database.getMessageTypeDistribution(sessionId, filter) + } catch (error) { + console.error('获取消息类型分布失败:', error) + return [] + } + } + ) + + /** + * 获取时间范围 + */ + ipcMain.handle('chat:getTimeRange', async (_, sessionId: string) => { + try { + return database.getTimeRange(sessionId) + } catch (error) { + console.error('获取时间范围失败:', error) + return null + } + }) + + /** + * 获取数据库存储目录 + */ + ipcMain.handle('chat:getDbDirectory', async () => { + try { + return database.getDbDirectory() + } catch (error) { + console.error('获取数据库目录失败:', error) + return null + } + }) + + /** + * 获取支持的格式列表 + */ + ipcMain.handle('chat:getSupportedFormats', async () => { + return parser.getSupportedFormats() + }) } export default mainIpcMain diff --git a/electron/main/parser/index.ts b/electron/main/parser/index.ts new file mode 100644 index 0000000..2afa229 --- /dev/null +++ b/electron/main/parser/index.ts @@ -0,0 +1,73 @@ +/** + * Parser 模块入口 + * 自动检测文件格式并使用对应的解析器 + */ + +import * as fs from 'fs' +import type { ChatParser } from './types' +import { qqJsonParser } from './qqJsonParser' +import { qqTxtParser } from './qqTxtParser' +import type { ParseResult } from '../../../src/types/chat' + +// 注册所有解析器(按优先级排序) +const parsers: ChatParser[] = [ + qqJsonParser, // JSON 格式优先 + qqTxtParser // TXT 格式兜底 +] + +/** + * 自动检测文件格式并解析 + * @param filePath 文件路径 + * @returns 解析结果 + */ +export function parseFile(filePath: string): ParseResult { + // 读取文件内容 + const content = fs.readFileSync(filePath, 'utf-8') + const filename = filePath.split(/[/\\]/).pop() || '' + + // 尝试每个解析器 + for (const parser of parsers) { + if (parser.detect(content, filename)) { + console.log(`使用解析器: ${parser.name}`) + return parser.parse(content, filename) + } + } + + throw new Error(`无法识别文件格式: ${filename}`) +} + +/** + * 检测文件格式 + * @param filePath 文件路径 + * @returns 解析器名称,如果无法识别则返回 null + */ +export function detectFormat(filePath: string): string | null { + try { + const content = fs.readFileSync(filePath, 'utf-8') + const filename = filePath.split(/[/\\]/).pop() || '' + + for (const parser of parsers) { + if (parser.detect(content, filename)) { + return parser.name + } + } + } catch { + // 文件读取失败 + } + + return null +} + +/** + * 获取支持的格式列表 + */ +export function getSupportedFormats(): Array<{ name: string; platform: string }> { + return parsers.map((p) => ({ + name: p.name, + platform: p.platform + })) +} + +// 导出类型 +export type { ChatParser, ParseError } from './types' + diff --git a/electron/main/parser/qqJsonParser.ts b/electron/main/parser/qqJsonParser.ts new file mode 100644 index 0000000..cd289a1 --- /dev/null +++ b/electron/main/parser/qqJsonParser.ts @@ -0,0 +1,207 @@ +/** + * QQ Chat Exporter V4 JSON 格式解析器 + * 支持 https://github.com/shuakami/qq-chat-exporter 导出的 JSON 格式 + */ + +import type { ChatParser, ParseError } from './types' +import { + ChatPlatform, + ChatType, + MessageType, + type ParseResult, + type ParsedMember, + type ParsedMessage +} from '../../../src/types/chat' + +/** + * QQ JSON 导出格式的消息结构 + */ +interface QQJsonMessage { + id: string + seq?: string + timestamp: number + time?: string + sender: { + uid?: string + uin: string + name: string + } + type: string + content: { + text: string + html?: string + elements?: Array<{ + type: string + data: Record + }> + resources?: Array<{ + type: string + filename?: string + size?: number + url?: string + }> + } + recalled?: boolean + system?: boolean +} + +/** + * QQ JSON 导出格式的根结构 + */ +interface QQJsonExport { + metadata?: { + name?: string + version?: string + } + chatInfo: { + name: string + type: 'private' | 'group' + } + statistics?: { + totalMessages?: number + senders?: Array<{ + uid?: string + name: string + messageCount: number + }> + } + messages: QQJsonMessage[] +} + +/** + * 将 QQ 消息类型转换为统一类型 + */ +function convertMessageType(qqType: string, content: QQJsonMessage['content']): MessageType { + // 检查是否有资源(图片等) + if (content.resources && content.resources.length > 0) { + const resourceType = content.resources[0].type + switch (resourceType) { + case 'image': + return MessageType.IMAGE + case 'video': + return MessageType.VIDEO + case 'voice': + case 'audio': + return MessageType.VOICE + case 'file': + return MessageType.FILE + } + } + + // 检查 elements 中是否有特殊类型 + if (content.elements) { + for (const elem of content.elements) { + if (elem.type === 'market_face' || elem.type === 'face') { + return MessageType.EMOJI + } + } + } + + // 根据 QQ 原始类型判断 + switch (qqType) { + case 'type_1': + return MessageType.TEXT + case 'type_17': // 表情包 + return MessageType.EMOJI + case 'type_3': // 图片 + return MessageType.IMAGE + case 'type_7': // 语音 + return MessageType.VOICE + default: + return MessageType.TEXT + } +} + +/** + * QQ JSON 格式解析器 + */ +export const qqJsonParser: ChatParser = { + name: 'QQ Chat Exporter JSON', + platform: 'qq', + + detect(content: string, filename: string): boolean { + // 检查文件扩展名 + if (!filename.toLowerCase().endsWith('.json')) { + return false + } + + try { + const data = JSON.parse(content) + // 检查是否有 QQ Chat Exporter 的特征 + return ( + data.chatInfo && + typeof data.chatInfo.name === 'string' && + Array.isArray(data.messages) && + (data.metadata?.name?.includes('QQChatExporter') || + // 兼容没有 metadata 的情况,检查消息结构 + (data.messages.length > 0 && data.messages[0].sender?.uin !== undefined)) + ) + } catch { + return false + } + }, + + parse(content: string, _filename: string): ParseResult { + let data: QQJsonExport + try { + data = JSON.parse(content) + } catch (e) { + throw new Error(`JSON 解析失败: ${e}`) as ParseError + } + + if (!data.chatInfo || !Array.isArray(data.messages)) { + throw new Error('无效的 QQ JSON 格式:缺少 chatInfo 或 messages') as ParseError + } + + // 解析元信息 + const meta = { + name: data.chatInfo.name, + platform: ChatPlatform.QQ, + type: data.chatInfo.type === 'group' ? ChatType.GROUP : ChatType.PRIVATE + } + + // 收集成员信息(使用 Map 去重,保留最新昵称) + const memberMap = new Map() + + // 解析消息 + const messages: ParsedMessage[] = [] + + for (const msg of data.messages) { + const platformId = msg.sender.uin + + // 更新成员信息(保留最新昵称) + memberMap.set(platformId, { + platformId, + name: msg.sender.name || platformId + }) + + // 转换时间戳(QQ 导出是毫秒,需要转为秒) + const timestamp = Math.floor(msg.timestamp / 1000) + + // 确定消息类型 + const type = msg.system ? MessageType.SYSTEM : convertMessageType(msg.type, msg.content) + + // 提取文本内容 + let textContent = msg.content.text || '' + + // 如果是撤回的消息,添加标记 + if (msg.recalled) { + textContent = '[已撤回] ' + textContent + } + + messages.push({ + senderPlatformId: platformId, + timestamp, + type, + content: textContent || null + }) + } + + return { + meta, + members: Array.from(memberMap.values()), + messages + } + } +} + diff --git a/electron/main/parser/qqTxtParser.ts b/electron/main/parser/qqTxtParser.ts new file mode 100644 index 0000000..a84682a --- /dev/null +++ b/electron/main/parser/qqTxtParser.ts @@ -0,0 +1,208 @@ +/** + * QQ 原生导出 TXT 格式解析器 + * 支持 QQ 客户端导出的文本格式聊天记录 + */ + +import type { ChatParser } from './types' +import { + ChatPlatform, + ChatType, + MessageType, + type ParseResult, + type ParsedMember, + type ParsedMessage +} from '../../../src/types/chat' + +/** + * 消息行正则表达式 + * 格式: 2017-02-25 10:40:20 昵称(QQ号) + * 或: 2017-02-25 10:40:20 (QQ号) + * 或: 2017-02-25 10:40:20 【管理员】昵称(QQ号) + * 或: 2017-02-25 10:40:20 昵称<邮箱> + */ +const MESSAGE_HEADER_REGEX = + /^(\d{4}-\d{2}-\d{2}\s+\d{1,2}:\d{2}:\d{2})\s+(?:【[^】]+】)?(.+?)(?:\((\d+)\)|<([^>]+)>)\s*$/ + +/** + * 群名提取正则 + * 格式: 消息对象:群名 + */ +const GROUP_NAME_REGEX = /^消息对象[::](.+)$/ + +/** + * 检测消息类型 + */ +function detectMessageType(content: string): MessageType { + const trimmed = content.trim() + + // 图片 + if (trimmed === '[图片]' || trimmed.startsWith('[图片]')) { + return MessageType.IMAGE + } + + // 表情 + if (/^\[.+\]$/.test(trimmed) || /^\[\[.+\]\]$/.test(trimmed)) { + return MessageType.EMOJI + } + + // 语音 + if (trimmed === '[语音]' || trimmed.startsWith('[语音]')) { + return MessageType.VOICE + } + + // 视频 + if (trimmed === '[视频]' || trimmed.startsWith('[视频]')) { + return MessageType.VIDEO + } + + // 文件 + if (trimmed === '[文件]' || trimmed.startsWith('[文件]')) { + return MessageType.FILE + } + + // 系统消息 + if ( + trimmed.includes('加入了群聊') || + trimmed.includes('退出了群聊') || + trimmed.includes('撤回了一条消息') || + trimmed.includes('被管理员') || + trimmed.includes('成为管理员') + ) { + return MessageType.SYSTEM + } + + return MessageType.TEXT +} + +/** + * 解析日期时间字符串为时间戳(秒) + */ +function parseDateTime(dateTimeStr: string): number { + // 格式: 2017-02-25 10:40:20 + const [datePart, timePart] = dateTimeStr.split(/\s+/) + const [year, month, day] = datePart.split('-').map(Number) + const [hour, minute, second] = timePart.split(':').map(Number) + + const date = new Date(year, month - 1, day, hour, minute, second) + return Math.floor(date.getTime() / 1000) +} + +/** + * QQ TXT 格式解析器 + */ +export const qqTxtParser: ChatParser = { + name: 'QQ Native TXT Export', + platform: 'qq', + + detect(content: string, filename: string): boolean { + // 检查文件扩展名 + if (!filename.toLowerCase().endsWith('.txt')) { + return false + } + + // 检查文件头特征 + const lines = content.split('\n').slice(0, 20) + const hasHeader = lines.some( + (line) => + line.includes('消息记录') || + line.includes('消息分组') || + line.includes('消息对象') || + line.includes('================================================================') + ) + + // 检查是否有符合格式的消息行 + const hasMessagePattern = lines.some((line) => MESSAGE_HEADER_REGEX.test(line.trim())) + + return hasHeader || hasMessagePattern + }, + + parse(content: string, _filename: string): ParseResult { + const lines = content.split('\n') + + // 提取群名 + let groupName = '未知对话' + for (const line of lines.slice(0, 20)) { + const match = line.trim().match(GROUP_NAME_REGEX) + if (match) { + groupName = match[1].trim() + break + } + } + + // 收集成员信息 + const memberMap = new Map() + + // 解析消息 + const messages: ParsedMessage[] = [] + + let currentSender: { platformId: string; name: string } | null = null + let currentTimestamp: number = 0 + let currentContent: string[] = [] + + // 处理当前累积的消息 + const flushMessage = (): void => { + if (currentSender && currentContent.length > 0) { + const content = currentContent.join('\n').trim() + if (content) { + messages.push({ + senderPlatformId: currentSender.platformId, + timestamp: currentTimestamp, + type: detectMessageType(content), + content + }) + } + } + currentContent = [] + } + + for (const line of lines) { + const trimmedLine = line.trim() + + // 跳过空行和分隔线 + if (!trimmedLine || trimmedLine.startsWith('===') || trimmedLine.startsWith('消息')) { + continue + } + + // 尝试匹配消息头 + const headerMatch = trimmedLine.match(MESSAGE_HEADER_REGEX) + + if (headerMatch) { + // 先保存之前的消息 + flushMessage() + + const dateTimeStr = headerMatch[1] + const nameOrEmpty = headerMatch[2].trim() + const qqNumber = headerMatch[3] || headerMatch[4] // QQ号或邮箱 + + // 处理只有QQ号没有昵称的情况 + const name = nameOrEmpty || qqNumber + + // 更新成员信息(保留最新昵称) + memberMap.set(qqNumber, { + platformId: qqNumber, + name + }) + + currentSender = { platformId: qqNumber, name } + currentTimestamp = parseDateTime(dateTimeStr) + } else { + // 这是消息内容行 + currentContent.push(trimmedLine) + } + } + + // 处理最后一条消息 + flushMessage() + + return { + meta: { + name: groupName, + platform: ChatPlatform.QQ, + type: ChatType.GROUP // TXT 导出通常是群聊 + }, + members: Array.from(memberMap.values()), + messages + } + } +} + diff --git a/electron/main/parser/types.ts b/electron/main/parser/types.ts new file mode 100644 index 0000000..b691f3d --- /dev/null +++ b/electron/main/parser/types.ts @@ -0,0 +1,44 @@ +/** + * Parser 接口定义 + */ + +import type { ParseResult } from '../../../src/types/chat' + +/** + * 聊天记录解析器接口 + */ +export interface ChatParser { + /** 解析器名称 */ + name: string + + /** 支持的平台 */ + platform: string + + /** + * 检测文件内容是否匹配该解析器 + * @param content 文件内容 + * @param filename 文件名 + */ + detect(content: string, filename: string): boolean + + /** + * 解析文件内容 + * @param content 文件内容 + * @param filename 文件名 + */ + parse(content: string, filename: string): ParseResult +} + +/** + * 解析错误 + */ +export class ParseError extends Error { + constructor( + message: string, + public readonly parserName: string + ) { + super(message) + this.name = 'ParseError' + } +} + diff --git a/electron/preload/index.d.ts b/electron/preload/index.d.ts index a153669..4149bcf 100644 --- a/electron/preload/index.d.ts +++ b/electron/preload/index.d.ts @@ -1,8 +1,50 @@ import { ElectronAPI } from '@electron-toolkit/preload' +import type { + AnalysisSession, + MemberActivity, + HourlyActivity, + DailyActivity, + MessageType, + ImportProgress +} from '../../src/types/chat' + +interface TimeFilter { + startTs?: number + endTs?: number +} + +interface ChatApi { + selectFile: () => Promise<{ filePath?: string; format?: string; error?: string } | null> + import: (filePath: string) => Promise<{ success: boolean; sessionId?: string; error?: string }> + getSessions: () => Promise + getSession: (sessionId: string) => Promise + deleteSession: (sessionId: string) => Promise + getAvailableYears: (sessionId: string) => Promise + getMemberActivity: (sessionId: string, filter?: TimeFilter) => Promise + getHourlyActivity: (sessionId: string, filter?: TimeFilter) => Promise + getDailyActivity: (sessionId: string, filter?: TimeFilter) => Promise + getMessageTypeDistribution: ( + sessionId: string, + filter?: TimeFilter + ) => Promise> + getTimeRange: (sessionId: string) => Promise<{ start: number; end: number } | null> + getDbDirectory: () => Promise + getSupportedFormats: () => Promise> + onImportProgress: (callback: (progress: ImportProgress) => void) => () => void +} + +interface Api { + send: (channel: string, data?: unknown) => void + receive: (channel: string, func: (...args: unknown[]) => void) => void + removeListener: (channel: string, func: (...args: unknown[]) => void) => void +} declare global { interface Window { electron: ElectronAPI - api: unknown + api: Api + chatApi: ChatApi } } + +export { ChatApi, Api } diff --git a/electron/preload/index.ts b/electron/preload/index.ts index 949f77c..4b2f8a6 100644 --- a/electron/preload/index.ts +++ b/electron/preload/index.ts @@ -1,28 +1,158 @@ import { contextBridge, ipcRenderer } from 'electron' import { electronAPI } from '@electron-toolkit/preload' +import type { + AnalysisSession, + MemberActivity, + HourlyActivity, + DailyActivity, + MessageType, + ImportProgress +} from '../../src/types/chat' // Custom APIs for renderer const api = { - send: (channel, data) => { + send: (channel: string, data?: unknown) => { // whitelist channels const validChannels = [ 'show-message', 'check-update', 'get-gpu-acceleration', 'set-gpu-acceleration', - 'save-gpu-acceleration', + 'save-gpu-acceleration' ] if (validChannels.includes(channel)) { ipcRenderer.send(channel, data) } }, - receive: (channel, func) => { - const validChannels = ['show-message'] + receive: (channel: string, func: (...args: unknown[]) => void) => { + const validChannels = ['show-message', 'chat:importProgress'] if (validChannels.includes(channel)) { // Deliberately strip event as it includes `sender` - ipcRenderer.on(channel, (event, ...args) => func(...args)) + ipcRenderer.on(channel, (_event, ...args) => func(...args)) } }, + removeListener: (channel: string, func: (...args: unknown[]) => void) => { + ipcRenderer.removeListener(channel, func) + } +} + +// Chat Analysis API +const chatApi = { + /** + * 选择聊天记录文件 + */ + selectFile: (): Promise<{ filePath?: string; format?: string; error?: string } | null> => { + return ipcRenderer.invoke('chat:selectFile') + }, + + /** + * 导入聊天记录 + */ + import: (filePath: string): Promise<{ success: boolean; sessionId?: string; error?: string }> => { + return ipcRenderer.invoke('chat:import', filePath) + }, + + /** + * 获取所有分析会话列表 + */ + getSessions: (): Promise => { + return ipcRenderer.invoke('chat:getSessions') + }, + + /** + * 获取单个会话信息 + */ + getSession: (sessionId: string): Promise => { + return ipcRenderer.invoke('chat:getSession', sessionId) + }, + + /** + * 删除会话 + */ + deleteSession: (sessionId: string): Promise => { + return ipcRenderer.invoke('chat:deleteSession', sessionId) + }, + + /** + * 获取可用年份列表 + */ + getAvailableYears: (sessionId: string): Promise => { + return ipcRenderer.invoke('chat:getAvailableYears', sessionId) + }, + + /** + * 获取成员活跃度排行 + */ + getMemberActivity: ( + sessionId: string, + filter?: { startTs?: number; endTs?: number } + ): Promise => { + return ipcRenderer.invoke('chat:getMemberActivity', sessionId, filter) + }, + + /** + * 获取每小时活跃度分布 + */ + getHourlyActivity: ( + sessionId: string, + filter?: { startTs?: number; endTs?: number } + ): Promise => { + return ipcRenderer.invoke('chat:getHourlyActivity', sessionId, filter) + }, + + /** + * 获取每日活跃度趋势 + */ + getDailyActivity: ( + sessionId: string, + filter?: { startTs?: number; endTs?: number } + ): Promise => { + return ipcRenderer.invoke('chat:getDailyActivity', sessionId, filter) + }, + + /** + * 获取消息类型分布 + */ + getMessageTypeDistribution: ( + sessionId: string, + filter?: { startTs?: number; endTs?: number } + ): Promise> => { + return ipcRenderer.invoke('chat:getMessageTypeDistribution', sessionId, filter) + }, + + /** + * 获取时间范围 + */ + getTimeRange: (sessionId: string): Promise<{ start: number; end: number } | null> => { + return ipcRenderer.invoke('chat:getTimeRange', sessionId) + }, + + /** + * 获取数据库存储目录 + */ + getDbDirectory: (): Promise => { + return ipcRenderer.invoke('chat:getDbDirectory') + }, + + /** + * 获取支持的格式列表 + */ + getSupportedFormats: (): Promise> => { + return ipcRenderer.invoke('chat:getSupportedFormats') + }, + + /** + * 监听导入进度 + */ + onImportProgress: (callback: (progress: ImportProgress) => void) => { + const handler = (_event: Electron.IpcRendererEvent, progress: ImportProgress) => { + callback(progress) + } + ipcRenderer.on('chat:importProgress', handler) + return () => { + ipcRenderer.removeListener('chat:importProgress', handler) + } + } } // Use `contextBridge` APIs to expose Electron APIs to @@ -32,6 +162,7 @@ if (process.contextIsolated) { try { contextBridge.exposeInMainWorld('electron', electronAPI) contextBridge.exposeInMainWorld('api', api) + contextBridge.exposeInMainWorld('chatApi', chatApi) } catch (error) { console.error(error) } @@ -40,4 +171,6 @@ if (process.contextIsolated) { window.electron = electronAPI // @ts-ignore (define in dts) window.api = api + // @ts-ignore (define in dts) + window.chatApi = chatApi } diff --git a/package.json b/package.json index 7975852..b3e4a53 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,11 @@ "description": "获取你的聊天记录年度分析报告", "author": "", "main": "./out/main/index.js", + "pnpm": { + "onlyBuiltDependencies": [ + "better-sqlite3" + ] + }, "scripts": { "dev": "electron-vite dev", "preview": "electron-vite preview", @@ -13,7 +18,8 @@ "build:mac": "electron-vite build && electron-builder --mac", "build:win": "electron-vite build && electron-builder --win", "build:linux": "electron-vite build && electron-builder --linux", - "build:all": "electron-vite build && electron-builder --mac --win --linux" + "build:all": "electron-vite build && electron-builder --mac --win --linux", + "postinstall": "electron-rebuild" }, "dependencies": { "@electron-toolkit/preload": "^3.0.1", @@ -21,19 +27,24 @@ "@nuxt/ui": "^4.2.1", "@vueuse/core": "^13.9.0", "axios": "^1.13.2", + "better-sqlite3": "^12.4.6", + "chart.js": "^4.5.1", "dayjs": "^1.11.19", "electron-updater": "^6.6.2", "mitt": "^3.0.1", "pinia": "^3.0.4", "vue": "^3.5.25", + "vue-chartjs": "^5.3.3", "vue-router": "^4.6.3" }, "devDependencies": { "@electron-toolkit/eslint-config": "^1.0.2", "@electron-toolkit/eslint-config-ts": "^2.0.0", "@electron-toolkit/tsconfig": "^1.0.1", + "@electron/rebuild": "^4.0.1", "@rushstack/eslint-patch": "^1.15.0", "@tailwindcss/vite": "^4.0.0", + "@types/better-sqlite3": "^7.6.13", "@vitejs/plugin-vue": "^5.2.3", "@vue/eslint-config-prettier": "^10.2.0", "cross-env": "^7.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f55f76f..6b44d73 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,13 +16,19 @@ importers: version: 4.0.0(electron@35.7.5) '@nuxt/ui': specifier: ^4.2.1 - version: 4.2.1(@babel/parser@7.28.5)(axios@1.13.2)(embla-carousel@8.6.0)(typescript@5.9.2)(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.2)))(vue@3.5.25(typescript@5.9.2)) + version: 4.2.1(@babel/parser@7.28.5)(axios@1.13.2)(embla-carousel@8.6.0)(typescript@5.9.3)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) '@vueuse/core': specifier: ^13.9.0 - version: 13.9.0(vue@3.5.25(typescript@5.9.2)) + version: 13.9.0(vue@3.5.25(typescript@5.9.3)) axios: specifier: ^1.13.2 version: 1.13.2 + better-sqlite3: + specifier: ^12.4.6 + version: 12.4.6 + chart.js: + specifier: ^4.5.1 + version: 4.5.1 dayjs: specifier: ^1.11.19 version: 1.11.19 @@ -34,32 +40,41 @@ importers: version: 3.0.1 pinia: specifier: ^3.0.4 - version: 3.0.4(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2)) + version: 3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) vue: specifier: ^3.5.25 - version: 3.5.25(typescript@5.9.2) + version: 3.5.25(typescript@5.9.3) + vue-chartjs: + specifier: ^5.3.3 + version: 5.3.3(chart.js@4.5.1)(vue@3.5.25(typescript@5.9.3)) vue-router: specifier: ^4.6.3 - version: 4.6.3(vue@3.5.25(typescript@5.9.2)) + version: 4.6.3(vue@3.5.25(typescript@5.9.3)) devDependencies: '@electron-toolkit/eslint-config': specifier: ^1.0.2 version: 1.0.2(eslint@9.39.1(jiti@2.6.1)) '@electron-toolkit/eslint-config-ts': specifier: ^2.0.0 - version: 2.0.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) + version: 2.0.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) '@electron-toolkit/tsconfig': specifier: ^1.0.1 - version: 1.0.1(@types/node@24.3.0) + version: 1.0.1(@types/node@24.10.1) + '@electron/rebuild': + specifier: ^4.0.1 + version: 4.0.1 '@rushstack/eslint-patch': specifier: ^1.15.0 version: 1.15.0 '@tailwindcss/vite': specifier: ^4.0.0 - version: 4.1.17(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)) + version: 4.1.17(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) + '@types/better-sqlite3': + specifier: ^7.6.13 + version: 7.6.13 '@vitejs/plugin-vue': specifier: ^5.2.3 - version: 5.2.4(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))(vue@3.5.25(typescript@5.9.2)) + version: 5.2.4(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.9.3)) '@vue/eslint-config-prettier': specifier: ^10.2.0 version: 10.2.0(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) @@ -74,7 +89,7 @@ importers: version: 26.0.12(electron-builder-squirrel-windows@26.0.12) electron-vite: specifier: ^3.0.0 - version: 3.1.0(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)) + version: 3.1.0(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) eslint: specifier: ^9.39.1 version: 9.39.1(jiti@2.6.1) @@ -83,7 +98,7 @@ importers: version: 9.33.0(eslint@9.39.1(jiti@2.6.1)) pinia-plugin-persistedstate: specifier: ^4.7.1 - version: 4.7.1(@nuxt/kit@4.2.1)(pinia@3.0.4(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2))) + version: 4.7.1(@nuxt/kit@4.2.1)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))) prettier: specifier: ^3.5.3 version: 3.6.2 @@ -92,7 +107,7 @@ importers: version: 4.1.17 vite: specifier: ^6.3.5 - version: 6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2) + version: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) packages: @@ -103,10 +118,6 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} @@ -117,16 +128,16 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.0': - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.3': - resolution: {integrity: sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==} + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.3': - resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.27.2': @@ -155,10 +166,6 @@ packages: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} @@ -167,15 +174,10 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.3': - resolution: {integrity: sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==} + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.28.5': resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} engines: {node: '>=6.0.0'} @@ -191,12 +193,8 @@ packages: resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.3': - resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} engines: {node: '>=6.9.0'} '@babel/types@7.28.5': @@ -278,6 +276,11 @@ packages: engines: {node: '>=12.13.0'} hasBin: true + '@electron/rebuild@4.0.1': + resolution: {integrity: sha512-iMGXb6Ib7H/Q3v+BKZJoETgF9g6KMNZVbsO4b7Dmpgb5qTFqyFTzqW9F3TOSHdybv2vKYKzSS9OiZL+dcJb+1Q==} + engines: {node: '>=22.12.0'} + hasBin: true + '@electron/universal@2.0.1': resolution: {integrity: sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==} engines: {node: '>=16.4'} @@ -443,20 +446,14 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@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/config-array@0.21.1': @@ -550,6 +547,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -563,8 +564,11 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@kurkle/color@0.3.4': + resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} '@malept/cross-spawn-promise@2.0.0': resolution: {integrity: sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==} @@ -586,10 +590,18 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@npmcli/agent@3.0.0': + resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==} + engines: {node: ^18.17.0 || >=20.5.0} + '@npmcli/fs@2.1.2': resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + '@npmcli/fs@4.0.0': + resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==} + engines: {node: ^18.17.0 || >=20.5.0} + '@npmcli/move-file@2.0.1': resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -657,94 +669,6 @@ packages: '@nuxtjs/color-mode@3.5.2': resolution: {integrity: sha512-cC6RfgZh3guHBMLLjrBB2Uti5eUoGM9KyauOaYS9ETmxNWBMTvpgjvSiSJp1OFljIXPIqVTJ3xtJpSNZiO3ZaA==} - '@parcel/watcher-android-arm64@2.5.1': - resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [android] - - '@parcel/watcher-darwin-arm64@2.5.1': - resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [darwin] - - '@parcel/watcher-darwin-x64@2.5.1': - resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [darwin] - - '@parcel/watcher-freebsd-x64@2.5.1': - resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [freebsd] - - '@parcel/watcher-linux-arm-glibc@2.5.1': - resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@parcel/watcher-linux-arm-musl@2.5.1': - resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - libc: [musl] - - '@parcel/watcher-linux-arm64-glibc@2.5.1': - resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@parcel/watcher-linux-arm64-musl@2.5.1': - resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@parcel/watcher-linux-x64-glibc@2.5.1': - resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@parcel/watcher-linux-x64-musl@2.5.1': - resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@parcel/watcher-win32-arm64@2.5.1': - resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [win32] - - '@parcel/watcher-win32-ia32@2.5.1': - resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} - engines: {node: '>= 10.0.0'} - cpu: [ia32] - os: [win32] - - '@parcel/watcher-win32-x64@2.5.1': - resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [win32] - - '@parcel/watcher@2.5.1': - resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} - engines: {node: '>= 10.0.0'} - '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1013,6 +937,9 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} + '@types/better-sqlite3@7.6.13': + resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} + '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} @@ -1040,8 +967,8 @@ packages: '@types/node@22.19.1': resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==} - '@types/node@24.3.0': - resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} + '@types/node@24.10.1': + resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} '@types/plist@3.0.5': resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} @@ -1258,6 +1185,10 @@ packages: abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1296,16 +1227,16 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.0: - resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} anymatch@3.1.3: @@ -1364,6 +1295,17 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.31: + resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==} + hasBin: true + + better-sqlite3@12.4.6: + resolution: {integrity: sha512-gaYt9yqTbQ1iOxLpJA8FPR5PiaHP+jlg8I5EX0Rs2KFwNzhBsF40KzMZS5FwelY7RG0wzaucWdqSAJM3uNCPCg==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + birpc@2.8.0: resolution: {integrity: sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==} @@ -1390,8 +1332,8 @@ packages: brotli@1.3.3: resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} - browserslist@4.25.4: - resolution: {integrity: sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==} + browserslist@4.28.0: + resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1427,6 +1369,10 @@ packages: resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + cacache@19.0.1: + resolution: {integrity: sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==} + engines: {node: ^18.17.0 || >=20.5.0} + cacheable-lookup@5.0.4: resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} engines: {node: '>=10.6.0'} @@ -1443,21 +1389,32 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001739: - resolution: {integrity: sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==} + caniuse-lite@1.0.30001757: + resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chart.js@4.5.1: + resolution: {integrity: sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==} + engines: {pnpm: '>=8'} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + chromium-pickle-js@0.2.0: resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} @@ -1581,21 +1538,12 @@ packages: engines: {node: '>=4'} hasBin: true - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} dayjs@1.11.19: resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1609,6 +1557,10 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1637,13 +1589,8 @@ packages: destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - detect-libc@1.0.3: - resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} - engines: {node: '>=0.10'} - hasBin: true - - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} detect-node@2.1.0: @@ -1703,8 +1650,8 @@ packages: electron-publish@26.0.11: resolution: {integrity: sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==} - electron-to-chromium@1.5.211: - resolution: {integrity: sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==} + electron-to-chromium@1.5.260: + resolution: {integrity: sha512-ov8rBoOBhVawpzdre+Cmz4FB+y66Eqrk6Gwqd8NGxuhv99GQ8XqMAr351KEkOt7gukXWDg6gJWEMKgL2RLMPtA==} electron-updater@6.6.2: resolution: {integrity: sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==} @@ -1925,8 +1872,12 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - exponential-backoff@3.1.2: - resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} @@ -1975,6 +1926,9 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -2022,8 +1976,8 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} framer-motion@12.23.12: @@ -2040,12 +1994,15 @@ packages: react-dom: optional: true + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.1: - resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} + fs-extra@11.3.2: + resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -2064,6 +2021,10 @@ packages: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2107,6 +2068,9 @@ packages: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2115,8 +2079,8 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true glob@7.2.3: @@ -2248,9 +2212,6 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - immutable@5.1.3: - resolution: {integrity: sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==} - import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -2273,8 +2234,11 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ip-address@10.0.1: - resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} engines: {node: '>= 12'} iron-webcrypto@1.2.1: @@ -2323,13 +2287,17 @@ packages: resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} engines: {node: '>= 8.0.0'} - isbinaryfile@5.0.6: - resolution: {integrity: sha512-I+NmIfBHUl+r2wcDd6JwE9yWje/PIVY/R5/CmV8dXLZd5K+L9X2klAOwfAHNnondLXkbHyTAleQAWonpTJBTtw==} + isbinaryfile@5.0.7: + resolution: {integrity: sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==} engines: {node: '>= 18.0.0'} isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -2348,8 +2316,8 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true jsesc@3.1.0: @@ -2520,9 +2488,6 @@ packages: magic-regexp@0.10.0: resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==} - magic-string@0.30.18: - resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} - magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -2530,6 +2495,10 @@ packages: resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + make-fetch-happen@14.0.3: + resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==} + engines: {node: ^18.17.0 || >=20.5.0} + matcher@3.0.0: resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} engines: {node: '>=10'} @@ -2581,8 +2550,8 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - minimatch@10.0.3: - resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} engines: {node: 20 || >=22} minimatch@3.1.2: @@ -2603,10 +2572,18 @@ packages: resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} engines: {node: '>= 8'} + minipass-collect@2.0.1: + resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} + engines: {node: '>=16 || 14 >=14.17'} + minipass-fetch@2.1.2: resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + minipass-fetch@4.0.1: + resolution: {integrity: sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==} + engines: {node: ^18.17.0 || >=20.5.0} + minipass-flush@1.0.5: resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} engines: {node: '>= 8'} @@ -2635,9 +2612,16 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -2674,6 +2658,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -2681,33 +2668,48 @@ packages: resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} engines: {node: '>= 0.6'} - node-abi@3.75.0: - resolution: {integrity: sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + node-abi@3.85.0: + resolution: {integrity: sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==} engines: {node: '>=10'} + node-abi@4.24.0: + resolution: {integrity: sha512-u2EC1CeNe25uVtX3EZbdQ275c74zdZmmpzrHEQh2aIYqoVjlglfUpOX9YY85x1nlBydEKDVaSmMNhR7N82Qj8A==} + engines: {node: '>=22.12.0'} + node-addon-api@1.7.2: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} - node-addon-api@7.1.1: - resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - node-api-version@0.2.1: resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-gyp@11.5.0: + resolution: {integrity: sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + node-mock-http@1.0.3: resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} hasBin: true + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -2773,11 +2775,15 @@ packages: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@1.3.0: - resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} + package-manager-detector@1.5.0: + resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==} pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} @@ -2886,6 +2892,11 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + hasBin: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2903,6 +2914,10 @@ packages: resolution: {integrity: sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + proc-log@5.0.0: + resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} + engines: {node: ^18.17.0 || >=20.5.0} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -2945,6 +2960,10 @@ packages: rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + read-binary-file-arch@1.0.6: resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} hasBin: true @@ -3033,13 +3052,8 @@ packages: sanitize-filename@1.6.3: resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} - sass@1.94.2: - resolution: {integrity: sha512-N+7WK20/wOr7CzA2snJcUSSNTCzeCGUTFY3OgeQP3mZ1aj9NMQ0mSTXwlrnd89j33zzQJGqIN52GIOmYrfq46A==} - engines: {node: '>=14.0.0'} - hasBin: true - - sax@1.4.1: - resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + sax@1.4.3: + resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} @@ -3055,11 +3069,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} @@ -3084,6 +3093,12 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} @@ -3108,6 +3123,10 @@ packages: resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} engines: {node: '>= 10'} + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + socks@2.8.7: resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} @@ -3130,6 +3149,10 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + ssri@12.0.0: + resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} + engines: {node: ^18.17.0 || >=20.5.0} + ssri@9.0.1: resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -3156,14 +3179,18 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -3207,10 +3234,21 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} + tar@7.5.2: + resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} + engines: {node: '>=18'} + temp-file@3.4.0: resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} @@ -3227,8 +3265,9 @@ packages: tiny-typed-emitter@2.1.0: resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} - tinyexec@1.0.1: - resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} @@ -3261,6 +3300,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -3276,8 +3318,8 @@ packages: type-level-regexp@0.1.17: resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true @@ -3293,8 +3335,8 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.10.0: - resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} unhead@2.0.19: resolution: {integrity: sha512-gEEjkV11Aj+rBnY6wnRfsFtF2RxKOLaPN4i+Gx3UhBxnszvV6ApSNZbGk7WKyy/lErQ6ekPN63qdFL7sa1leow==} @@ -3316,10 +3358,18 @@ packages: resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + unique-filename@4.0.0: + resolution: {integrity: sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==} + engines: {node: ^18.17.0 || >=20.5.0} + unique-slug@3.0.0: resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + unique-slug@5.0.0: + resolution: {integrity: sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==} + engines: {node: ^18.17.0 || >=20.5.0} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -3427,8 +3477,8 @@ packages: resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} hasBin: true - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -3492,6 +3542,12 @@ packages: yaml: optional: true + vue-chartjs@5.3.3: + resolution: {integrity: sha512-jqxtL8KZ6YJ5NTv6XzrzLS7osyegOi28UGNZW0h9OkDL7Sh1396ht4Dorh04aKrl2LiSalQ84WtqiG0RIJb0tA==} + peerDependencies: + chart.js: ^4.1.1 + vue: ^3.0.0-0 || ^2.7.0 + vue-component-type-helpers@3.1.5: resolution: {integrity: sha512-7V3yJuNWW7/1jxCcI1CswnpDsvs02Qcx/N43LkV+ZqhLj2PKj50slUflHAroNkN4UWiYfzMUUUXiNuv9khmSpQ==} @@ -3540,6 +3596,11 @@ packages: engines: {node: '>= 8'} hasBin: true + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -3573,6 +3634,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -3594,59 +3659,54 @@ snapshots: '@alloc/quick-lru@5.2.0': {} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - '@antfu/install-pkg@1.1.0': dependencies: - package-manager-detector: 1.3.0 - tinyexec: 1.0.1 + package-manager-detector: 1.5.0 + tinyexec: 1.0.2 '@antfu/utils@9.3.0': {} '@babel/code-frame@7.27.1': dependencies: - '@babel/helper-validator-identifier': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.0': {} + '@babel/compat-data@7.28.5': {} - '@babel/core@7.28.3': + '@babel/core@7.28.5': dependencies: - '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 + '@babel/generator': 7.28.5 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) - '@babel/helpers': 7.28.3 - '@babel/parser': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.28.3': + '@babel/generator@7.28.5': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.28.0 + '@babel/compat-data': 7.28.5 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.4 + browserslist: 4.28.0 lru-cache: 5.1.1 semver: 6.3.1 @@ -3654,17 +3714,17 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.3)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.5 '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 transitivePeerDependencies: - supports-color @@ -3672,53 +3732,42 @@ snapshots: '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.28.3': + '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - - '@babel/parser@7.28.3': - dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.5 '@babel/parser@7.28.5': dependencies: '@babel/types': 7.28.5 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 - '@babel/traverse@7.28.3': + '@babel/traverse@7.28.5': dependencies: '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 + '@babel/generator': 7.28.5 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.5 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 + '@babel/types': 7.28.5 + debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/types@7.28.5': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -3733,13 +3782,13 @@ snapshots: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) - '@electron-toolkit/eslint-config-ts@2.0.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2)': + '@electron-toolkit/eslint-config-ts@2.0.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) - '@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.1(jiti@2.6.1) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3751,9 +3800,9 @@ snapshots: dependencies: electron: 35.7.5 - '@electron-toolkit/tsconfig@1.0.1(@types/node@24.3.0)': + '@electron-toolkit/tsconfig@1.0.1(@types/node@24.10.1)': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.10.1 '@electron-toolkit/utils@4.0.0(electron@35.7.5)': dependencies: @@ -3779,7 +3828,7 @@ snapshots: '@electron/get@2.0.3': dependencies: - debug: 4.4.1 + debug: 4.4.3 env-paths: 2.2.1 fs-extra: 8.1.0 got: 11.8.6 @@ -3794,7 +3843,7 @@ snapshots: '@electron/node-gyp@https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2': dependencies: env-paths: 2.2.1 - exponential-backoff: 3.1.2 + exponential-backoff: 3.1.3 glob: 8.1.0 graceful-fs: 4.2.11 make-fetch-happen: 10.2.1 @@ -3809,7 +3858,7 @@ snapshots: '@electron/notarize@2.5.0': dependencies: - debug: 4.4.1 + debug: 4.4.3 fs-extra: 9.1.0 promise-retry: 2.0.1 transitivePeerDependencies: @@ -3818,7 +3867,7 @@ snapshots: '@electron/osx-sign@1.3.1': dependencies: compare-version: 0.1.2 - debug: 4.4.1 + debug: 4.4.3 fs-extra: 10.1.0 isbinaryfile: 4.0.10 minimist: 1.2.8 @@ -3831,11 +3880,11 @@ snapshots: '@electron/node-gyp': https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2 '@malept/cross-spawn-promise': 2.0.0 chalk: 4.1.2 - debug: 4.4.1 - detect-libc: 2.0.4 + debug: 4.4.3 + detect-libc: 2.1.2 fs-extra: 10.1.0 got: 11.8.6 - node-abi: 3.75.0 + node-abi: 3.85.0 node-api-version: 0.2.1 ora: 5.4.1 read-binary-file-arch: 1.0.6 @@ -3846,13 +3895,32 @@ snapshots: - bluebird - supports-color + '@electron/rebuild@4.0.1': + dependencies: + '@malept/cross-spawn-promise': 2.0.0 + chalk: 4.1.2 + debug: 4.4.3 + detect-libc: 2.1.2 + got: 11.8.6 + graceful-fs: 4.2.11 + node-abi: 4.24.0 + node-api-version: 0.2.1 + node-gyp: 11.5.0 + ora: 5.4.1 + read-binary-file-arch: 1.0.6 + semver: 7.7.3 + tar: 6.2.1 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + '@electron/universal@2.0.1': dependencies: '@electron/asar': 3.2.18 '@malept/cross-spawn-promise': 2.0.0 - debug: 4.4.1 + debug: 4.4.3 dir-compare: 4.2.0 - fs-extra: 11.3.1 + fs-extra: 11.3.2 minimatch: 9.0.5 plist: 3.1.0 transitivePeerDependencies: @@ -3862,7 +3930,7 @@ snapshots: dependencies: cross-dirname: 0.1.0 debug: 4.4.3 - fs-extra: 11.3.1 + fs-extra: 11.3.2 minimist: 1.2.8 postject: 1.0.0-alpha.6 transitivePeerDependencies: @@ -3947,17 +4015,12 @@ snapshots: '@esbuild/win32-x64@0.25.12': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.39.1(jiti@2.6.1))': - dependencies: - eslint: 9.39.1(jiti@2.6.1) - eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1(jiti@2.6.1))': dependencies: eslint: 9.39.1(jiti@2.6.1) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} '@eslint/config-array@0.21.1': dependencies: @@ -3983,7 +4046,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -4009,11 +4072,11 @@ snapshots: '@floating-ui/utils@0.2.10': {} - '@floating-ui/vue@1.1.9(vue@3.5.25(typescript@5.9.2))': + '@floating-ui/vue@1.1.9(vue@3.5.25(typescript@5.9.3))': dependencies: '@floating-ui/dom': 1.7.4 '@floating-ui/utils': 0.2.10 - vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.2)) + vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.3)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -4050,10 +4113,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@iconify/vue@5.0.0(vue@3.5.25(typescript@5.9.2))': + '@iconify/vue@5.0.0(vue@3.5.25(typescript@5.9.3))': dependencies: '@iconify/types': 2.0.0 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) '@internationalized/date@3.10.0': dependencies: @@ -4073,37 +4136,43 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': dependencies: '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.30': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@kurkle/color@0.3.4': {} + '@malept/cross-spawn-promise@2.0.0': dependencies: cross-spawn: 7.0.6 '@malept/flatpak-bundler@0.4.0': dependencies: - debug: 4.4.1 + debug: 4.4.3 fs-extra: 9.1.0 lodash: 4.17.21 tmp-promise: 3.0.3 @@ -4122,42 +4191,56 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@npmcli/agent@3.0.0': + dependencies: + agent-base: 7.1.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 10.4.3 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + '@npmcli/fs@2.1.2': dependencies: '@gar/promisify': 1.1.3 semver: 7.7.3 + '@npmcli/fs@4.0.0': + dependencies: + semver: 7.7.3 + '@npmcli/move-file@2.0.1': dependencies: mkdirp: 1.0.4 rimraf: 3.0.2 - '@nuxt/devtools-kit@2.7.0(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))': + '@nuxt/devtools-kit@2.7.0(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@nuxt/kit': 3.20.1 execa: 8.0.1 - vite: 6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2) + vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - magicast - '@nuxt/devtools-kit@3.1.1(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))': + '@nuxt/devtools-kit@3.1.1(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@nuxt/kit': 4.2.1 execa: 8.0.1 - vite: 6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2) + vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - magicast - '@nuxt/fonts@0.12.1(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))': + '@nuxt/fonts@0.12.1(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: - '@nuxt/devtools-kit': 3.1.1(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)) + '@nuxt/devtools-kit': 3.1.1(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) '@nuxt/kit': 4.2.1 consola: 3.4.2 css-tree: 3.1.0 defu: 6.1.4 esbuild: 0.25.12 fontaine: 0.7.0 - fontless: 0.1.0(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)) + fontless: 0.1.0(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) h3: 1.15.4 jiti: 2.6.1 magic-regexp: 0.10.0 @@ -4194,13 +4277,13 @@ snapshots: - uploadthing - vite - '@nuxt/icon@2.1.0(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))(vue@3.5.25(typescript@5.9.2))': + '@nuxt/icon@2.1.0(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.9.3))': dependencies: '@iconify/collections': 1.0.621 '@iconify/types': 2.0.0 '@iconify/utils': 3.0.2 - '@iconify/vue': 5.0.0(vue@3.5.25(typescript@5.9.2)) - '@nuxt/devtools-kit': 2.7.0(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)) + '@iconify/vue': 5.0.0(vue@3.5.25(typescript@5.9.3)) + '@nuxt/devtools-kit': 2.7.0(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) '@nuxt/kit': 4.2.1 consola: 3.4.2 local-pkg: 1.1.2 @@ -4275,24 +4358,24 @@ snapshots: pkg-types: 2.3.0 std-env: 3.10.0 - '@nuxt/ui@4.2.1(@babel/parser@7.28.5)(axios@1.13.2)(embla-carousel@8.6.0)(typescript@5.9.2)(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.2)))(vue@3.5.25(typescript@5.9.2))': + '@nuxt/ui@4.2.1(@babel/parser@7.28.5)(axios@1.13.2)(embla-carousel@8.6.0)(typescript@5.9.3)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))': dependencies: - '@iconify/vue': 5.0.0(vue@3.5.25(typescript@5.9.2)) + '@iconify/vue': 5.0.0(vue@3.5.25(typescript@5.9.3)) '@internationalized/date': 3.10.0 '@internationalized/number': 3.6.5 - '@nuxt/fonts': 0.12.1(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)) - '@nuxt/icon': 2.1.0(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))(vue@3.5.25(typescript@5.9.2)) + '@nuxt/fonts': 0.12.1(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) + '@nuxt/icon': 2.1.0(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.9.3)) '@nuxt/kit': 4.2.1 '@nuxt/schema': 4.2.1 '@nuxtjs/color-mode': 3.5.2 '@standard-schema/spec': 1.0.0 '@tailwindcss/postcss': 4.1.17 - '@tailwindcss/vite': 4.1.17(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)) - '@tanstack/vue-table': 8.21.3(vue@3.5.25(typescript@5.9.2)) - '@tanstack/vue-virtual': 3.13.12(vue@3.5.25(typescript@5.9.2)) - '@unhead/vue': 2.0.19(vue@3.5.25(typescript@5.9.2)) - '@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.2)) - '@vueuse/integrations': 13.9.0(axios@1.13.2)(fuse.js@7.1.0)(vue@3.5.25(typescript@5.9.2)) + '@tailwindcss/vite': 4.1.17(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) + '@tanstack/vue-table': 8.21.3(vue@3.5.25(typescript@5.9.3)) + '@tanstack/vue-virtual': 3.13.12(vue@3.5.25(typescript@5.9.3)) + '@unhead/vue': 2.0.19(vue@3.5.25(typescript@5.9.3)) + '@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.3)) + '@vueuse/integrations': 13.9.0(axios@1.13.2)(fuse.js@7.1.0)(vue@3.5.25(typescript@5.9.3)) colortranslator: 5.0.0 consola: 3.4.2 defu: 6.1.4 @@ -4301,30 +4384,30 @@ snapshots: embla-carousel-autoplay: 8.6.0(embla-carousel@8.6.0) embla-carousel-class-names: 8.6.0(embla-carousel@8.6.0) embla-carousel-fade: 8.6.0(embla-carousel@8.6.0) - embla-carousel-vue: 8.6.0(vue@3.5.25(typescript@5.9.2)) + embla-carousel-vue: 8.6.0(vue@3.5.25(typescript@5.9.3)) embla-carousel-wheel-gestures: 8.1.0(embla-carousel@8.6.0) fuse.js: 7.1.0 hookable: 5.5.3 knitwork: 1.3.0 magic-string: 0.30.21 mlly: 1.8.0 - motion-v: 1.7.4(@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.2)))(vue@3.5.25(typescript@5.9.2)) + motion-v: 1.7.4(@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) ohash: 2.0.11 pathe: 2.0.3 - reka-ui: 2.6.0(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2)) + reka-ui: 2.6.0(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) scule: 1.3.0 tailwind-merge: 3.4.0 tailwind-variants: 3.2.2(tailwind-merge@3.4.0)(tailwindcss@4.1.17) tailwindcss: 4.1.17 tinyglobby: 0.2.15 - typescript: 5.9.2 + typescript: 5.9.3 unplugin: 2.3.11 - unplugin-auto-import: 20.2.0(@nuxt/kit@4.2.1)(@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.2))) - unplugin-vue-components: 30.0.0(@babel/parser@7.28.5)(@nuxt/kit@4.2.1)(vue@3.5.25(typescript@5.9.2)) - vaul-vue: 0.4.1(reka-ui@2.6.0(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2)))(vue@3.5.25(typescript@5.9.2)) + unplugin-auto-import: 20.2.0(@nuxt/kit@4.2.1)(@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.3))) + unplugin-vue-components: 30.0.0(@babel/parser@7.28.5)(@nuxt/kit@4.2.1)(vue@3.5.25(typescript@5.9.3)) + vaul-vue: 0.4.1(reka-ui@2.6.0(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) vue-component-type-helpers: 3.1.5 optionalDependencies: - vue-router: 4.6.3(vue@3.5.25(typescript@5.9.2)) + vue-router: 4.6.3(vue@3.5.25(typescript@5.9.3)) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -4375,67 +4458,6 @@ snapshots: transitivePeerDependencies: - magicast - '@parcel/watcher-android-arm64@2.5.1': - optional: true - - '@parcel/watcher-darwin-arm64@2.5.1': - optional: true - - '@parcel/watcher-darwin-x64@2.5.1': - optional: true - - '@parcel/watcher-freebsd-x64@2.5.1': - optional: true - - '@parcel/watcher-linux-arm-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-arm-musl@2.5.1': - optional: true - - '@parcel/watcher-linux-arm64-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-arm64-musl@2.5.1': - optional: true - - '@parcel/watcher-linux-x64-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-x64-musl@2.5.1': - optional: true - - '@parcel/watcher-win32-arm64@2.5.1': - optional: true - - '@parcel/watcher-win32-ia32@2.5.1': - optional: true - - '@parcel/watcher-win32-x64@2.5.1': - optional: true - - '@parcel/watcher@2.5.1': - dependencies: - detect-libc: 1.0.3 - is-glob: 4.0.3 - micromatch: 4.0.8 - node-addon-api: 7.1.1 - optionalDependencies: - '@parcel/watcher-android-arm64': 2.5.1 - '@parcel/watcher-darwin-arm64': 2.5.1 - '@parcel/watcher-darwin-x64': 2.5.1 - '@parcel/watcher-freebsd-x64': 2.5.1 - '@parcel/watcher-linux-arm-glibc': 2.5.1 - '@parcel/watcher-linux-arm-musl': 2.5.1 - '@parcel/watcher-linux-arm64-glibc': 2.5.1 - '@parcel/watcher-linux-arm64-musl': 2.5.1 - '@parcel/watcher-linux-x64-glibc': 2.5.1 - '@parcel/watcher-linux-x64-musl': 2.5.1 - '@parcel/watcher-win32-arm64': 2.5.1 - '@parcel/watcher-win32-ia32': 2.5.1 - '@parcel/watcher-win32-x64': 2.5.1 - optional: true - '@pkgjs/parseargs@0.11.0': optional: true @@ -4592,34 +4614,38 @@ snapshots: postcss: 8.5.6 tailwindcss: 4.1.17 - '@tailwindcss/vite@4.1.17(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))': + '@tailwindcss/vite@4.1.17(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@tailwindcss/node': 4.1.17 '@tailwindcss/oxide': 4.1.17 tailwindcss: 4.1.17 - vite: 6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2) + vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) '@tanstack/table-core@8.21.3': {} '@tanstack/virtual-core@3.13.12': {} - '@tanstack/vue-table@8.21.3(vue@3.5.25(typescript@5.9.2))': + '@tanstack/vue-table@8.21.3(vue@3.5.25(typescript@5.9.3))': dependencies: '@tanstack/table-core': 8.21.3 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) - '@tanstack/vue-virtual@3.13.12(vue@3.5.25(typescript@5.9.2))': + '@tanstack/vue-virtual@3.13.12(vue@3.5.25(typescript@5.9.3))': dependencies: '@tanstack/virtual-core': 3.13.12 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) '@tootallnate/once@2.0.0': {} + '@types/better-sqlite3@7.6.13': + dependencies: + '@types/node': 24.10.1 + '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 24.3.0 + '@types/node': 24.10.1 '@types/responselike': 1.0.3 '@types/debug@4.1.12': @@ -4630,7 +4656,7 @@ snapshots: '@types/fs-extra@9.0.13': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.10.1 '@types/http-cache-semantics@4.0.4': {} @@ -4638,7 +4664,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.10.1 '@types/ms@2.1.0': {} @@ -4646,19 +4672,19 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.3.0': + '@types/node@24.10.1': dependencies: - undici-types: 7.10.0 + undici-types: 7.16.0 '@types/plist@3.0.5': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.10.1 xmlbuilder: 15.1.1 optional: true '@types/responselike@1.0.3': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.10.1 '@types/verror@1.10.11': optional: true @@ -4669,37 +4695,37 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 24.3.0 + '@types/node': 22.19.1 optional: true - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) - '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/type-utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 7.18.0 eslint: 9.39.1(jiti@2.6.1) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.4.3(typescript@5.9.2) + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.1 + debug: 4.4.3 eslint: 9.39.1(jiti@2.6.1) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -4708,41 +4734,41 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/type-utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/type-utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.2) - '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) - debug: 4.4.1 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3 eslint: 9.39.1(jiti@2.6.1) - ts-api-utils: 1.4.3(typescript@5.9.2) + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.1 + debug: 4.4.3 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 1.4.3(typescript@5.9.2) + semver: 7.7.3 + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.39.1(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) eslint: 9.39.1(jiti@2.6.1) transitivePeerDependencies: - supports-color @@ -4753,16 +4779,16 @@ snapshots: '@typescript-eslint/types': 7.18.0 eslint-visitor-keys: 3.4.3 - '@unhead/vue@2.0.19(vue@3.5.25(typescript@5.9.2))': + '@unhead/vue@2.0.19(vue@3.5.25(typescript@5.9.3))': dependencies: hookable: 5.5.3 unhead: 2.0.19 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) - '@vitejs/plugin-vue@5.2.4(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2))(vue@3.5.25(typescript@5.9.2))': + '@vitejs/plugin-vue@5.2.4(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.9.3))': dependencies: - vite: 6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2) - vue: 3.5.25(typescript@5.9.2) + vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) + vue: 3.5.25(typescript@5.9.3) '@vue/compiler-core@3.5.25': dependencies: @@ -4837,47 +4863,47 @@ snapshots: '@vue/reactivity': 3.5.25 '@vue/runtime-core': 3.5.25 '@vue/shared': 3.5.25 - csstype: 3.1.3 + csstype: 3.2.3 - '@vue/server-renderer@3.5.25(vue@3.5.25(typescript@5.9.2))': + '@vue/server-renderer@3.5.25(vue@3.5.25(typescript@5.9.3))': dependencies: '@vue/compiler-ssr': 3.5.25 '@vue/shared': 3.5.25 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) '@vue/shared@3.5.25': {} - '@vueuse/core@10.11.1(vue@3.5.25(typescript@5.9.2))': + '@vueuse/core@10.11.1(vue@3.5.25(typescript@5.9.3))': dependencies: '@types/web-bluetooth': 0.0.20 '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.5.25(typescript@5.9.2)) - vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.2)) + '@vueuse/shared': 10.11.1(vue@3.5.25(typescript@5.9.3)) + vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.3)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/core@12.8.2(typescript@5.9.2)': + '@vueuse/core@12.8.2(typescript@5.9.3)': dependencies: '@types/web-bluetooth': 0.0.21 '@vueuse/metadata': 12.8.2 - '@vueuse/shared': 12.8.2(typescript@5.9.2) - vue: 3.5.25(typescript@5.9.2) + '@vueuse/shared': 12.8.2(typescript@5.9.3) + vue: 3.5.25(typescript@5.9.3) transitivePeerDependencies: - typescript - '@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.2))': + '@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.3))': dependencies: '@types/web-bluetooth': 0.0.21 '@vueuse/metadata': 13.9.0 - '@vueuse/shared': 13.9.0(vue@3.5.25(typescript@5.9.2)) - vue: 3.5.25(typescript@5.9.2) + '@vueuse/shared': 13.9.0(vue@3.5.25(typescript@5.9.3)) + vue: 3.5.25(typescript@5.9.3) - '@vueuse/integrations@13.9.0(axios@1.13.2)(fuse.js@7.1.0)(vue@3.5.25(typescript@5.9.2))': + '@vueuse/integrations@13.9.0(axios@1.13.2)(fuse.js@7.1.0)(vue@3.5.25(typescript@5.9.3))': dependencies: - '@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.2)) - '@vueuse/shared': 13.9.0(vue@3.5.25(typescript@5.9.2)) - vue: 3.5.25(typescript@5.9.2) + '@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.3)) + '@vueuse/shared': 13.9.0(vue@3.5.25(typescript@5.9.3)) + vue: 3.5.25(typescript@5.9.3) optionalDependencies: axios: 1.13.2 fuse.js: 7.1.0 @@ -4888,27 +4914,29 @@ snapshots: '@vueuse/metadata@13.9.0': {} - '@vueuse/shared@10.11.1(vue@3.5.25(typescript@5.9.2))': + '@vueuse/shared@10.11.1(vue@3.5.25(typescript@5.9.3))': dependencies: - vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.2)) + vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.3)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/shared@12.8.2(typescript@5.9.2)': + '@vueuse/shared@12.8.2(typescript@5.9.3)': dependencies: - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) transitivePeerDependencies: - typescript - '@vueuse/shared@13.9.0(vue@3.5.25(typescript@5.9.2))': + '@vueuse/shared@13.9.0(vue@3.5.25(typescript@5.9.3))': dependencies: - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) '@xmldom/xmldom@0.8.11': {} abbrev@1.1.1: {} + abbrev@3.0.1: {} + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -4945,13 +4973,13 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.0: {} + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} anymatch@3.1.3: dependencies: @@ -4976,7 +5004,7 @@ snapshots: builder-util-runtime: 9.3.1 chromium-pickle-js: 0.2.0 config-file-ts: 0.2.8-rc1 - debug: 4.4.1 + debug: 4.4.3 dmg-builder: 26.0.12(electron-builder-squirrel-windows@26.0.12) dotenv: 16.6.1 dotenv-expand: 11.0.7 @@ -4986,14 +5014,14 @@ snapshots: fs-extra: 10.1.0 hosted-git-info: 4.1.0 is-ci: 3.0.1 - isbinaryfile: 5.0.6 - js-yaml: 4.1.0 + isbinaryfile: 5.0.7 + js-yaml: 4.1.1 json5: 2.2.3 lazy-val: 1.0.5 - minimatch: 10.0.3 + minimatch: 10.1.1 plist: 3.1.0 resedit: 1.7.2 - semver: 7.7.2 + semver: 7.7.3 tar: 6.2.1 temp-file: 3.4.0 tiny-async-pool: 1.3.0 @@ -5026,7 +5054,7 @@ snapshots: axios@1.13.2: dependencies: follow-redirects: 1.15.11 - form-data: 4.0.4 + form-data: 4.0.5 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -5035,6 +5063,17 @@ snapshots: base64-js@1.5.1: {} + baseline-browser-mapping@2.8.31: {} + + better-sqlite3@12.4.6: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.3 + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + birpc@2.8.0: {} bl@4.1.0: @@ -5065,12 +5104,13 @@ snapshots: dependencies: base64-js: 1.5.1 - browserslist@4.25.4: + browserslist@4.28.0: dependencies: - caniuse-lite: 1.0.30001739 - electron-to-chromium: 1.5.211 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.4) + baseline-browser-mapping: 2.8.31 + caniuse-lite: 1.0.30001757 + electron-to-chromium: 1.5.260 + node-releases: 2.0.27 + update-browserslist-db: 1.1.4(browserslist@4.28.0) buffer-crc32@0.2.13: {} @@ -5083,8 +5123,8 @@ snapshots: builder-util-runtime@9.3.1: dependencies: - debug: 4.4.1 - sax: 1.4.1 + debug: 4.4.3 + sax: 1.4.3 transitivePeerDependencies: - supports-color @@ -5096,12 +5136,12 @@ snapshots: builder-util-runtime: 9.3.1 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 fs-extra: 10.1.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-ci: 3.0.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 sanitize-filename: 1.6.3 source-map-support: 0.5.21 stat-mode: 1.0.0 @@ -5150,6 +5190,21 @@ snapshots: transitivePeerDependencies: - bluebird + cacache@19.0.1: + dependencies: + '@npmcli/fs': 4.0.0 + fs-minipass: 3.0.3 + glob: 10.5.0 + lru-cache: 10.4.3 + minipass: 7.1.2 + minipass-collect: 2.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 7.0.4 + ssri: 12.0.0 + tar: 7.5.2 + unique-filename: 4.0.0 + cacheable-lookup@5.0.4: {} cacheable-request@7.0.4: @@ -5169,19 +5224,27 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001739: {} + caniuse-lite@1.0.30001757: {} chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + chart.js@4.5.1: + dependencies: + '@kurkle/color': 0.3.4 + chokidar@4.0.3: dependencies: readdirp: 4.1.2 + chownr@1.1.4: {} + chownr@2.0.0: {} + chownr@3.0.0: {} + chromium-pickle-js@0.2.0: {} ci-info@3.9.0: {} @@ -5245,8 +5308,8 @@ snapshots: config-file-ts@0.2.8-rc1: dependencies: - glob: 10.4.5 - typescript: 5.9.2 + glob: 10.5.0 + typescript: 5.9.3 consola@3.4.2: {} @@ -5290,14 +5353,10 @@ snapshots: cssesc@3.0.0: {} - csstype@3.1.3: {} + csstype@3.2.3: {} dayjs@1.11.19: {} - debug@4.4.1: - dependencies: - ms: 2.1.3 - debug@4.4.3: dependencies: ms: 2.1.3 @@ -5306,6 +5365,8 @@ snapshots: dependencies: mimic-response: 3.1.0 + deep-extend@0.6.0: {} + deep-is@0.1.4: {} defaults@1.0.4: @@ -5334,10 +5395,7 @@ snapshots: destr@2.0.5: {} - detect-libc@1.0.3: - optional: true - - detect-libc@2.0.4: {} + detect-libc@2.1.2: {} detect-node@2.1.0: optional: true @@ -5360,7 +5418,7 @@ snapshots: builder-util-runtime: 9.3.1 fs-extra: 10.1.0 iconv-lite: 0.6.3 - js-yaml: 4.1.0 + js-yaml: 4.1.1 optionalDependencies: dmg-license: 1.0.11 transitivePeerDependencies: @@ -5433,37 +5491,37 @@ snapshots: builder-util: 26.0.11 builder-util-runtime: 9.3.1 chalk: 4.1.2 - form-data: 4.0.4 + form-data: 4.0.5 fs-extra: 10.1.0 lazy-val: 1.0.5 mime: 2.6.0 transitivePeerDependencies: - supports-color - electron-to-chromium@1.5.211: {} + electron-to-chromium@1.5.260: {} electron-updater@6.6.2: dependencies: builder-util-runtime: 9.3.1 fs-extra: 10.1.0 - js-yaml: 4.1.0 + js-yaml: 4.1.1 lazy-val: 1.0.5 lodash.escaperegexp: 4.1.2 lodash.isequal: 4.5.0 - semver: 7.7.2 + semver: 7.7.3 tiny-typed-emitter: 2.1.0 transitivePeerDependencies: - supports-color - electron-vite@3.1.0(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)): + electron-vite@3.1.0(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)): dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.5 + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5) cac: 6.7.14 esbuild: 0.25.12 - magic-string: 0.30.18 + magic-string: 0.30.21 picocolors: 1.1.1 - vite: 6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2) + vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - supports-color @@ -5511,11 +5569,11 @@ snapshots: dependencies: embla-carousel: 8.6.0 - embla-carousel-vue@8.6.0(vue@3.5.25(typescript@5.9.2)): + embla-carousel-vue@8.6.0(vue@3.5.25(typescript@5.9.3)): dependencies: embla-carousel: 8.6.0 embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) embla-carousel-wheel-gestures@8.1.0(embla-carousel@8.6.0): dependencies: @@ -5618,13 +5676,13 @@ snapshots: eslint-plugin-vue@9.33.0(eslint@9.39.1(jiti@2.6.1)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.39.1(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) eslint: 9.39.1(jiti@2.6.1) globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 - semver: 7.7.2 + semver: 7.7.3 vue-eslint-parser: 9.4.3(eslint@9.39.1(jiti@2.6.1)) xml-name-validator: 4.0.0 transitivePeerDependencies: @@ -5647,7 +5705,7 @@ snapshots: eslint@9.39.1(jiti@2.6.1): dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) - '@eslint-community/regexpp': 4.12.1 + '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.1 '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 @@ -5727,13 +5785,15 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - exponential-backoff@3.1.2: {} + expand-template@2.0.3: {} + + exponential-backoff@3.1.3: {} exsolve@1.0.8: {} extract-zip@2.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.3 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -5776,6 +5836,8 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-uri-to-path@1.0.0: {} + filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -5820,7 +5882,7 @@ snapshots: unicode-properties: 1.4.1 unicode-trie: 2.0.0 - fontless@0.1.0(vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2)): + fontless@0.1.0(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)): dependencies: consola: 3.4.2 css-tree: 3.1.0 @@ -5836,7 +5898,7 @@ snapshots: unifont: 0.6.0 unstorage: 1.17.3 optionalDependencies: - vite: 6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2) + vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -5863,7 +5925,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data@4.0.4: + form-data@4.0.5: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -5877,13 +5939,15 @@ snapshots: motion-utils: 12.23.6 tslib: 2.8.1 + fs-constants@1.0.0: {} + fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.0 universalify: 2.0.1 - fs-extra@11.3.1: + fs-extra@11.3.2: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.0 @@ -5912,6 +5976,10 @@ snapshots: dependencies: minipass: 3.3.6 + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -5958,6 +6026,8 @@ snapshots: nypm: 0.6.2 pathe: 2.0.3 + github-from-package@0.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -5966,7 +6036,7 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.4.5: + glob@10.5.0: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 @@ -5998,7 +6068,7 @@ snapshots: es6-error: 4.1.1 matcher: 3.0.0 roarr: 2.15.4 - semver: 7.7.2 + semver: 7.7.3 serialize-error: 7.0.1 optional: true @@ -6095,7 +6165,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -6114,7 +6184,7 @@ snapshots: https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -6140,9 +6210,6 @@ snapshots: ignore@7.0.5: {} - immutable@5.1.3: - optional: true - import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -6161,7 +6228,9 @@ snapshots: inherits@2.0.4: {} - ip-address@10.0.1: {} + ini@1.3.8: {} + + ip-address@10.1.0: {} iron-webcrypto@1.2.1: {} @@ -6191,10 +6260,12 @@ snapshots: isbinaryfile@4.0.10: {} - isbinaryfile@5.0.6: {} + isbinaryfile@5.0.7: {} isexe@2.0.0: {} + isexe@3.1.1: {} + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -6213,7 +6284,7 @@ snapshots: js-tokens@9.0.1: {} - js-yaml@4.1.0: + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -6292,7 +6363,7 @@ snapshots: lightningcss@1.30.2: dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.2 optionalDependencies: lightningcss-android-arm64: 1.30.2 lightningcss-darwin-arm64: 1.30.2 @@ -6353,10 +6424,6 @@ snapshots: ufo: 1.6.1 unplugin: 2.3.11 - magic-string@0.30.18: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -6383,6 +6450,22 @@ snapshots: - bluebird - supports-color + make-fetch-happen@14.0.3: + dependencies: + '@npmcli/agent': 3.0.0 + cacache: 19.0.1 + http-cache-semantics: 4.2.0 + minipass: 7.1.2 + minipass-fetch: 4.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 1.0.0 + proc-log: 5.0.0 + promise-retry: 2.0.1 + ssri: 12.0.0 + transitivePeerDependencies: + - supports-color + matcher@3.0.0: dependencies: escape-string-regexp: 4.0.0 @@ -6417,7 +6500,7 @@ snapshots: mimic-response@3.1.0: {} - minimatch@10.0.3: + minimatch@10.1.1: dependencies: '@isaacs/brace-expansion': 5.0.0 @@ -6439,6 +6522,10 @@ snapshots: dependencies: minipass: 3.3.6 + minipass-collect@2.0.1: + dependencies: + minipass: 7.1.2 + minipass-fetch@2.1.2: dependencies: minipass: 3.3.6 @@ -6447,6 +6534,14 @@ snapshots: optionalDependencies: encoding: 0.1.13 + minipass-fetch@4.0.1: + dependencies: + minipass: 7.1.2 + minipass-sized: 1.0.3 + minizlib: 3.1.0 + optionalDependencies: + encoding: 0.1.13 + minipass-flush@1.0.5: dependencies: minipass: 3.3.6 @@ -6472,8 +6567,14 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + minizlib@3.1.0: + dependencies: + minipass: 7.1.2 + mitt@3.0.1: {} + mkdirp-classic@0.5.3: {} + mkdirp@0.5.6: dependencies: minimist: 1.2.8 @@ -6493,13 +6594,13 @@ snapshots: motion-utils@12.23.6: {} - motion-v@1.7.4(@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.2)))(vue@3.5.25(typescript@5.9.2)): + motion-v@1.7.4(@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)): dependencies: - '@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.2)) + '@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.3)) framer-motion: 12.23.12 hey-listen: 1.0.8 motion-dom: 12.23.12 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) transitivePeerDependencies: - '@emotion/is-prop-valid' - react @@ -6511,34 +6612,58 @@ snapshots: nanoid@3.3.11: {} + napi-build-utils@2.0.0: {} + natural-compare@1.4.0: {} negotiator@0.6.4: {} - node-abi@3.75.0: + negotiator@1.0.0: {} + + node-abi@3.85.0: + dependencies: + semver: 7.7.3 + + node-abi@4.24.0: dependencies: semver: 7.7.3 node-addon-api@1.7.2: optional: true - node-addon-api@7.1.1: - optional: true - node-api-version@0.2.1: dependencies: semver: 7.7.3 node-fetch-native@1.6.7: {} + node-gyp@11.5.0: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + graceful-fs: 4.2.11 + make-fetch-happen: 14.0.3 + nopt: 8.1.0 + proc-log: 5.0.0 + semver: 7.7.3 + tar: 7.5.2 + tinyglobby: 0.2.15 + which: 5.0.0 + transitivePeerDependencies: + - supports-color + node-mock-http@1.0.3: {} - node-releases@2.0.19: {} + node-releases@2.0.27: {} nopt@6.0.0: dependencies: abbrev: 1.1.1 + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + normalize-path@3.0.0: {} normalize-url@6.1.0: {} @@ -6557,7 +6682,7 @@ snapshots: consola: 3.4.2 pathe: 2.0.3 pkg-types: 2.3.0 - tinyexec: 1.0.1 + tinyexec: 1.0.2 object-keys@1.1.1: optional: true @@ -6617,9 +6742,11 @@ snapshots: dependencies: aggregate-error: 3.1.0 + p-map@7.0.4: {} + package-json-from-dist@1.0.1: {} - package-manager-detector@1.3.0: {} + package-manager-detector@1.5.0: {} pako@0.2.9: {} @@ -6660,19 +6787,19 @@ snapshots: picomatch@4.0.3: {} - pinia-plugin-persistedstate@4.7.1(@nuxt/kit@4.2.1)(pinia@3.0.4(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2))): + pinia-plugin-persistedstate@4.7.1(@nuxt/kit@4.2.1)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))): dependencies: defu: 6.1.4 optionalDependencies: '@nuxt/kit': 4.2.1 - pinia: 3.0.4(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2)) + pinia: 3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) - pinia@3.0.4(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2)): + pinia@3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)): dependencies: '@vue/devtools-api': 7.7.9 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 pkg-types@1.3.1: dependencies: @@ -6708,6 +6835,21 @@ snapshots: commander: 9.5.0 optional: true + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.85.0 + pump: 3.0.3 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.0: @@ -6718,6 +6860,8 @@ snapshots: proc-log@2.0.1: {} + proc-log@5.0.0: {} + progress@2.0.3: {} promise-inflight@1.0.1: {} @@ -6749,6 +6893,13 @@ snapshots: defu: 6.1.4 destr: 2.0.5 + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + read-binary-file-arch@1.0.6: dependencies: debug: 4.4.3 @@ -6765,19 +6916,19 @@ snapshots: regexp-tree@0.1.27: {} - reka-ui@2.6.0(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2)): + reka-ui@2.6.0(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)): dependencies: '@floating-ui/dom': 1.7.4 - '@floating-ui/vue': 1.1.9(vue@3.5.25(typescript@5.9.2)) + '@floating-ui/vue': 1.1.9(vue@3.5.25(typescript@5.9.3)) '@internationalized/date': 3.10.0 '@internationalized/number': 3.6.5 - '@tanstack/vue-virtual': 3.13.12(vue@3.5.25(typescript@5.9.2)) - '@vueuse/core': 12.8.2(typescript@5.9.2) - '@vueuse/shared': 12.8.2(typescript@5.9.2) + '@tanstack/vue-virtual': 3.13.12(vue@3.5.25(typescript@5.9.3)) + '@vueuse/core': 12.8.2(typescript@5.9.3) + '@vueuse/shared': 12.8.2(typescript@5.9.3) aria-hidden: 1.2.6 defu: 6.1.4 ohash: 2.0.11 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) transitivePeerDependencies: - '@vue/composition-api' - typescript @@ -6867,16 +7018,7 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sass@1.94.2: - dependencies: - chokidar: 4.0.3 - immutable: 5.1.3 - source-map-js: 1.2.1 - optionalDependencies: - '@parcel/watcher': 2.5.1 - optional: true - - sax@1.4.1: {} + sax@1.4.3: {} scule@1.3.0: {} @@ -6887,8 +7029,6 @@ snapshots: semver@6.3.1: {} - semver@7.7.2: {} - semver@7.7.3: {} serialize-error@7.0.1: @@ -6906,9 +7046,17 @@ snapshots: signal-exit@4.1.0: {} + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + simple-update-notifier@2.0.0: dependencies: - semver: 7.7.2 + semver: 7.7.3 sirv@3.0.2: dependencies: @@ -6935,9 +7083,17 @@ snapshots: transitivePeerDependencies: - supports-color + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + socks@2.8.7: dependencies: - ip-address: 10.0.1 + ip-address: 10.1.0 smart-buffer: 4.2.0 source-map-js@1.2.1: {} @@ -6954,6 +7110,10 @@ snapshots: sprintf-js@1.1.3: optional: true + ssri@12.0.0: + dependencies: + minipass: 7.1.2 + ssri@9.0.1: dependencies: minipass: 3.3.6 @@ -6972,7 +7132,7 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 string_decoder@1.3.0: dependencies: @@ -6982,12 +7142,14 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.1.2: dependencies: - ansi-regex: 6.2.0 + ansi-regex: 6.2.2 strip-final-newline@3.0.0: {} + strip-json-comments@2.0.1: {} + strip-json-comments@3.1.1: {} strip-literal@3.1.0: @@ -6996,7 +7158,7 @@ snapshots: sumchecker@3.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -7024,6 +7186,21 @@ snapshots: tapable@2.3.0: {} + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.3 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + tar@6.2.1: dependencies: chownr: 2.0.0 @@ -7033,6 +7210,14 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + tar@7.5.2: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 + temp-file@3.4.0: dependencies: async-exit-hook: 2.0.1 @@ -7051,7 +7236,7 @@ snapshots: tiny-typed-emitter@2.1.0: {} - tinyexec@1.0.1: {} + tinyexec@1.0.2: {} tinyglobby@0.2.15: dependencies: @@ -7074,12 +7259,16 @@ snapshots: dependencies: utf8-byte-length: 1.0.5 - ts-api-utils@1.4.3(typescript@5.9.2): + ts-api-utils@1.4.3(typescript@5.9.3): dependencies: - typescript: 5.9.2 + typescript: 5.9.3 tslib@2.8.1: {} + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -7091,7 +7280,7 @@ snapshots: type-level-regexp@0.1.17: {} - typescript@5.9.2: {} + typescript@5.9.3: {} ufo@1.6.1: {} @@ -7106,7 +7295,7 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.10.0: {} + undici-types@7.16.0: {} unhead@2.0.19: dependencies: @@ -7149,15 +7338,23 @@ snapshots: dependencies: unique-slug: 3.0.0 + unique-filename@4.0.0: + dependencies: + unique-slug: 5.0.0 + unique-slug@3.0.0: dependencies: imurmurhash: 0.1.4 + unique-slug@5.0.0: + dependencies: + imurmurhash: 0.1.4 + universalify@0.1.2: {} universalify@2.0.1: {} - unplugin-auto-import@20.2.0(@nuxt/kit@4.2.1)(@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.2))): + unplugin-auto-import@20.2.0(@nuxt/kit@4.2.1)(@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.3))): dependencies: local-pkg: 1.1.2 magic-string: 0.30.21 @@ -7167,14 +7364,14 @@ snapshots: unplugin-utils: 0.3.1 optionalDependencies: '@nuxt/kit': 4.2.1 - '@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.2)) + '@vueuse/core': 13.9.0(vue@3.5.25(typescript@5.9.3)) unplugin-utils@0.3.1: dependencies: pathe: 2.0.3 picomatch: 4.0.3 - unplugin-vue-components@30.0.0(@babel/parser@7.28.5)(@nuxt/kit@4.2.1)(vue@3.5.25(typescript@5.9.2)): + unplugin-vue-components@30.0.0(@babel/parser@7.28.5)(@nuxt/kit@4.2.1)(vue@3.5.25(typescript@5.9.3)): dependencies: chokidar: 4.0.3 debug: 4.4.3 @@ -7184,7 +7381,7 @@ snapshots: tinyglobby: 0.2.15 unplugin: 2.3.11 unplugin-utils: 0.3.1 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) optionalDependencies: '@babel/parser': 7.28.5 '@nuxt/kit': 4.2.1 @@ -7217,9 +7414,9 @@ snapshots: knitwork: 1.3.0 scule: 1.3.0 - update-browserslist-db@1.1.3(browserslist@4.25.4): + update-browserslist-db@1.1.4(browserslist@4.28.0): dependencies: - browserslist: 4.25.4 + browserslist: 4.28.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -7231,11 +7428,11 @@ snapshots: util-deprecate@1.0.2: {} - vaul-vue@0.4.1(reka-ui@2.6.0(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2)))(vue@3.5.25(typescript@5.9.2)): + vaul-vue@0.4.1(reka-ui@2.6.0(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)): dependencies: - '@vueuse/core': 10.11.1(vue@3.5.25(typescript@5.9.2)) - reka-ui: 2.6.0(typescript@5.9.2)(vue@3.5.25(typescript@5.9.2)) - vue: 3.5.25(typescript@5.9.2) + '@vueuse/core': 10.11.1(vue@3.5.25(typescript@5.9.3)) + reka-ui: 2.6.0(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) + vue: 3.5.25(typescript@5.9.3) transitivePeerDependencies: - '@vue/composition-api' @@ -7246,7 +7443,7 @@ snapshots: extsprintf: 1.4.1 optional: true - vite@6.4.1(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.2): + vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -7255,45 +7452,49 @@ snapshots: rollup: 4.53.3 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.3.0 + '@types/node': 24.10.1 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 - sass: 1.94.2 + + vue-chartjs@5.3.3(chart.js@4.5.1)(vue@3.5.25(typescript@5.9.3)): + dependencies: + chart.js: 4.5.1 + vue: 3.5.25(typescript@5.9.3) vue-component-type-helpers@3.1.5: {} - vue-demi@0.14.10(vue@3.5.25(typescript@5.9.2)): + vue-demi@0.14.10(vue@3.5.25(typescript@5.9.3)): dependencies: - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) vue-eslint-parser@9.4.3(eslint@9.39.1(jiti@2.6.1)): dependencies: - debug: 4.4.1 + debug: 4.4.3 eslint: 9.39.1(jiti@2.6.1) eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 esquery: 1.6.0 lodash: 4.17.21 - semver: 7.7.2 + semver: 7.7.3 transitivePeerDependencies: - supports-color - vue-router@4.6.3(vue@3.5.25(typescript@5.9.2)): + vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.25(typescript@5.9.2) + vue: 3.5.25(typescript@5.9.3) - vue@3.5.25(typescript@5.9.2): + vue@3.5.25(typescript@5.9.3): dependencies: '@vue/compiler-dom': 3.5.25 '@vue/compiler-sfc': 3.5.25 '@vue/runtime-dom': 3.5.25 - '@vue/server-renderer': 3.5.25(vue@3.5.25(typescript@5.9.2)) + '@vue/server-renderer': 3.5.25(vue@3.5.25(typescript@5.9.3)) '@vue/shared': 3.5.25 optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 wcwidth@1.0.1: dependencies: @@ -7307,6 +7508,10 @@ snapshots: dependencies: isexe: 2.0.0 + which@5.0.0: + dependencies: + isexe: 3.1.1 + word-wrap@1.2.5: {} wrap-ansi@7.0.0: @@ -7317,9 +7522,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 wrappy@1.0.2: {} @@ -7333,6 +7538,8 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yargs-parser@21.1.1: {} yargs@17.7.2: diff --git a/src/App.vue b/src/App.vue index 3948ea0..2d92a21 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,8 +1,20 @@ diff --git a/src/components.d.ts b/src/components.d.ts index 4d1701b..03f3ed3 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -13,23 +13,25 @@ declare module 'vue' { export interface GlobalComponents { RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] - UApp: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/App.vue')['default'] - UAvatar: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Avatar.vue')['default'] + UApp: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/App.vue')['default'] + UAvatar: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/Avatar.vue')['default'] UBadge: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Badge.vue')['default'] - UButton: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Button.vue')['default'] - UCard: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Card.vue')['default'] + UButton: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/Button.vue')['default'] + UCard: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/Card.vue')['default'] UCheckbox: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Checkbox.vue')['default'] UFormField: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/FormField.vue')['default'] - UIcon: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/vue/components/Icon.vue')['default'] + UIcon: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/vue/components/Icon.vue')['default'] UInput: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Input.vue')['default'] - UModal: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Modal.vue')['default'] - UProgress: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Progress.vue')['default'] + UModal: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/Modal.vue')['default'] + UPopover: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/Popover.vue')['default'] + UProgress: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/Progress.vue')['default'] USelect: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Select.vue')['default'] + USelectMenu: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/SelectMenu.vue')['default'] USkeleton: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Skeleton.vue')['default'] USwitch: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Switch.vue')['default'] UTabs: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Tabs.vue')['default'] UTextarea: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Textarea.vue')['default'] UToaster: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Toaster.vue')['default'] - UTooltip: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Tooltip.vue')['default'] + UTooltip: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.3__1572391ae10a8169a5c9784ec5cec455/node_modules/@nuxt/ui/dist/runtime/components/Tooltip.vue')['default'] } } diff --git a/src/components/ImportProgressModal.vue b/src/components/ImportProgressModal.vue new file mode 100644 index 0000000..58fa379 --- /dev/null +++ b/src/components/ImportProgressModal.vue @@ -0,0 +1,101 @@ + + + + diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index 6da642d..c975bf2 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -1,20 +1,66 @@ @@ -27,28 +73,22 @@ function handleImport() {
-
- ChatLens -
- +
ChatLens
+
- + @@ -56,44 +96,84 @@ function handleImport() {
-
- 暂无记录 -
+
暂无记录
- 最近 + 分析记录
- + + +
+ + + + + +
+
- +
- + - +
diff --git a/src/components/WelcomeGuide.vue b/src/components/WelcomeGuide.vue index 05cab9b..19472fe 100644 --- a/src/components/WelcomeGuide.vue +++ b/src/components/WelcomeGuide.vue @@ -1,4 +1,13 @@