From e4627caa4c8498899785ba52fef8413b4cf97431 Mon Sep 17 00:00:00 2001 From: Hyoseong Jo Date: Sat, 10 Jan 2026 14:40:01 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8C=80=EC=8B=9C=EB=B3=B4=EB=93=9C=EC=99=80?= =?UTF-8?q?=20=EC=A3=BC=EA=B0=84=EB=B3=B4=EA=B3=A0=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/vcs.xml | 1 - README.md | 26 +- backend/api/ai/parse-my-report-image.post.ts | 133 ++ backend/api/ai/parse-my-report.post.ts | 152 ++ backend/api/auth/current-user.get.ts | 32 +- backend/api/auth/login-history.get.ts | 63 +- backend/api/auth/login.post.ts | 25 +- backend/api/auth/logout.post.ts | 31 +- backend/api/auth/me.get.ts | 19 +- backend/api/auth/select-user.post.ts | 29 +- backend/api/dashboard/stats.get.ts | 7 +- backend/api/report/review.post.ts | 161 +- backend/api/report/weekly/list.get.ts | 29 +- backend/sql/create_session_table.sql | 18 + backend/utils/session.ts | 198 ++ .../migrate-completed.mjs | 0 frontend/admin/bulk-import.vue | 117 +- frontend/composables/useWeekCalc.ts | 188 +- frontend/index.vue | 137 +- frontend/mypage/index.vue | 3 +- frontend/report/summary/index.vue | 17 +- frontend/report/weekly/[id].vue | 735 ++++++- frontend/report/weekly/aggregate.vue | 64 +- frontend/report/weekly/index.vue | 212 +- frontend/report/weekly/write.vue | 842 +++++++- package-lock.json | 1810 ++++++----------- 26 files changed, 3329 insertions(+), 1720 deletions(-) create mode 100644 backend/api/ai/parse-my-report-image.post.ts create mode 100644 backend/api/ai/parse-my-report.post.ts create mode 100644 backend/sql/create_session_table.sql create mode 100644 backend/utils/session.ts rename migrate-completed.mjs => claude_temp/migrate-completed.mjs (100%) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 8306744..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,5 @@ - \ No newline at end of file diff --git a/README.md b/README.md index a846327..aae8ed4 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,11 @@ weeklyreport/ │ ├── composables/ # Vue Composables │ ├── report/ # 주간보고 관련 │ │ ├── weekly/ # 개인 주간보고 +│ │ │ └── bulk-import.vue # AI 일괄 등록 │ │ └── summary/ # 취합 보고서 │ ├── employee/ # 직원 관리 │ ├── project/ # 프로젝트 관리 -│ └── admin/ # 관리자 기능 +│ └── mypage/ # 마이페이지 ├── backend/ │ ├── api/ # API 엔드포인트 │ │ ├── auth/ # 인증 @@ -61,6 +62,29 @@ weeklyreport/ └── package.json ``` +## 🔗 메뉴 구조 + +| 메뉴 | 경로 | 설명 | 권한 | +|------|------|------|------| +| 로그인 | `/login` | 로그인 페이지 | 전체 | +| 홈 | `/` | 대시보드 | 로그인 | +| **주간보고** | | | | +| ├ 목록 | `/report/weekly` | 주간보고 목록 | 로그인 | +| ├ 작성 | `/report/weekly/write` | 주간보고 작성 | 로그인 | +| ├ 일괄작성 | `/report/weekly/bulk-import` | AI 기반 일괄 등록 | 로그인 | +| ├ 상세 | `/report/weekly/[id]` | 주간보고 상세보기 | 로그인 | +| └ 취합현황 | `/report/weekly/aggregate` | 주차별 취합 현황 | 로그인 | +| **취합보고서** | | | | +| ├ 목록 | `/report/summary` | 취합 보고서 목록 | 관리자 | +| └ 상세 | `/report/summary/[id]` | 취합 보고서 상세 | 관리자 | +| **관리** | | | | +| ├ 직원 목록 | `/employee` | 직원 관리 | 관리자 | +| ├ 직원 상세 | `/employee/[id]` | 직원 정보 상세 | 관리자 | +| ├ 프로젝트 목록 | `/project` | 프로젝트 관리 | 관리자 | +| └ 프로젝트 상세 | `/project/[id]` | 프로젝트 정보 상세 | 관리자 | +| **마이페이지** | `/mypage` | 내 정보 | 로그인 | +| **피드백** | `/feedback` | 피드백 | 로그인 | + ## 🗄 데이터베이스 스키마 ### 주요 테이블 diff --git a/backend/api/ai/parse-my-report-image.post.ts b/backend/api/ai/parse-my-report-image.post.ts new file mode 100644 index 0000000..3c93e02 --- /dev/null +++ b/backend/api/ai/parse-my-report-image.post.ts @@ -0,0 +1,133 @@ +import { query } from '../../utils/db' +import { callOpenAIVision } from '../../utils/openai' + +/** + * 개인 주간보고 이미지 분석 (OpenAI Vision) + * POST /api/ai/parse-my-report-image + */ +export default defineEventHandler(async (event) => { + const userId = getCookie(event, 'user_id') + if (!userId) { + throw createError({ statusCode: 401, message: '로그인이 필요합니다.' }) + } + + const body = await readBody<{ images: string[] }>(event) + + if (!body.images || body.images.length === 0) { + throw createError({ statusCode: 400, message: '분석할 이미지를 업로드해주세요.' }) + } + + // 기존 프로젝트 목록 조회 + const projects = await query(` + SELECT project_id, project_code, project_name + FROM wr_project_info + WHERE project_status = 'IN_PROGRESS' + `) + + // 프로젝트 목록을 ID 포함해서 전달 + const projectList = projects.map(p => `[ID:${p.project_id}] ${p.project_code}: ${p.project_name}`).join('\n') + + // OpenAI Vision 분석 + const prompt = buildImagePrompt(projectList) + console.log('=== AI 이미지 분석 시작 ===') + console.log('이미지 개수:', body.images.length) + console.log('프로젝트 목록:', projectList) + + const aiResponse = await callOpenAIVision(prompt, body.images) + console.log('=== AI 응답 (raw) ===') + console.log(aiResponse) + + let parsed: any + try { + parsed = JSON.parse(aiResponse) + console.log('=== AI 응답 (parsed) ===') + console.log(JSON.stringify(parsed, null, 2)) + } catch (e) { + console.error('=== JSON 파싱 실패 ===') + console.error(e) + throw createError({ statusCode: 500, message: 'AI 응답 파싱 실패' }) + } + + // 프로젝트 매칭 + if (parsed.projects) { + for (const proj of parsed.projects) { + if (!proj.matchedProjectId && proj.projectName) { + const matched = projects.find((p: any) => + p.project_name.toLowerCase().includes(proj.projectName.toLowerCase()) || + proj.projectName.toLowerCase().includes(p.project_name.toLowerCase()) || + p.project_code.toLowerCase() === proj.projectName.toLowerCase() + ) + if (matched) { + proj.matchedProjectId = matched.project_id + proj.projectName = matched.project_name + } + } + + proj.workTasks = (proj.workTasks || []).map((t: any) => ({ + description: t.description || '', + hours: t.hours || 0, + isCompleted: t.isCompleted !== false + })) + + proj.planTasks = (proj.planTasks || []).map((t: any) => ({ + description: t.description || '', + hours: t.hours || 0 + })) + } + + // 내용 없는 프로젝트 제외 (workTasks, planTasks 모두 비어있으면 제외) + parsed.projects = parsed.projects.filter((proj: any) => + (proj.workTasks && proj.workTasks.length > 0) || + (proj.planTasks && proj.planTasks.length > 0) + ) + } + + return { + success: true, + parsed, + projects + } +}) + +function buildImagePrompt(projectList: string): string { + return `당신은 주간보고 내용을 분석하는 AI입니다. +이미지에서 주간보고 내용을 추출하여 JSON으로 반환해주세요. +이미지에 여러 사람의 내용이 있어도 모두 추출하여 하나의 보고서로 통합해주세요. + +현재 등록된 프로젝트 목록 (형식: [ID:숫자] 코드: 이름): +${projectList} + +⚠️ 중요: 이미지에서 추출한 프로젝트명과 위 목록을 비교하여 가장 유사한 프로젝트의 ID를 matchedProjectId에 반환하세요. +- 유사도 판단: 키워드 일치, 약어, 부분 문자열 등 고려 +- 예: "한우 유전체" → "보은 한우 온라인 유전체 분석" 매칭 가능 +- 예: "HEIS" → "보건환경연구원 HEIS" 매칭 가능 +- 매칭되는 프로젝트가 없으면 matchedProjectId는 null + +응답은 반드시 아래 JSON 형식으로만 출력하세요: +{ + "projects": [ + { + "projectName": "이미지에서 추출한 원본 프로젝트명", + "matchedProjectId": 5, + "workTasks": [ + {"description": "작업내용", "hours": 8, "isCompleted": true} + ], + "planTasks": [ + {"description": "계획내용", "hours": 8} + ] + } + ], + "issueDescription": "이슈/리스크 내용 또는 null", + "vacationDescription": "휴가일정 내용 또는 null", + "remarkDescription": "기타사항 내용 또는 null" +} + +규칙: +1. 이미지에서 모든 주간보고 내용을 추출 +2. projectName은 이미지에서 추출한 원본 텍스트 그대로 +3. matchedProjectId는 위 프로젝트 목록에서 가장 유사한 프로젝트의 ID (숫자) +4. "금주 실적", "이번주", "완료" 등은 workTasks로 분류 +5. "차주 계획", "다음주", "예정" 등은 planTasks로 분류 +6. 시간이 명시되지 않은 경우 hours는 0으로 +7. JSON 외의 텍스트는 절대 출력하지 마세요` +} diff --git a/backend/api/ai/parse-my-report.post.ts b/backend/api/ai/parse-my-report.post.ts new file mode 100644 index 0000000..c975246 --- /dev/null +++ b/backend/api/ai/parse-my-report.post.ts @@ -0,0 +1,152 @@ +import { query } from '../../utils/db' +import { callOpenAI } from '../../utils/openai' + +interface ParsedTask { + description: string + hours: number + isCompleted?: boolean +} + +interface ParsedProject { + projectName: string + matchedProjectId: number | null + workTasks: ParsedTask[] + planTasks: ParsedTask[] +} + +interface ParsedResult { + projects: ParsedProject[] + issueDescription: string | null + vacationDescription: string | null + remarkDescription: string | null +} + +/** + * 개인 주간보고 텍스트 분석 (OpenAI) + * POST /api/ai/parse-my-report + */ +export default defineEventHandler(async (event) => { + const userId = getCookie(event, 'user_id') + if (!userId) { + throw createError({ statusCode: 401, message: '로그인이 필요합니다.' }) + } + + const body = await readBody<{ rawText: string }>(event) + + if (!body.rawText || body.rawText.trim().length < 5) { + throw createError({ statusCode: 400, message: '분석할 텍스트를 입력해주세요.' }) + } + + // 기존 프로젝트 목록 조회 + const projects = await query(` + SELECT project_id, project_code, project_name + FROM wr_project_info + WHERE project_status = 'IN_PROGRESS' + `) + + // 프로젝트 목록을 ID 포함해서 전달 + const projectList = projects.map(p => `[ID:${p.project_id}] ${p.project_code}: ${p.project_name}`).join('\n') + + // OpenAI 분석 + const prompt = buildMyReportPrompt(body.rawText, projectList) + const aiResponse = await callOpenAI(prompt, true) + + let parsed: ParsedResult + try { + parsed = JSON.parse(aiResponse) + } catch (e) { + throw createError({ statusCode: 500, message: 'AI 응답 파싱 실패' }) + } + + // 프로젝트 매칭 + if (parsed.projects) { + for (const proj of parsed.projects) { + if (!proj.matchedProjectId && proj.projectName) { + const matched = projects.find((p: any) => + p.project_name.toLowerCase().includes(proj.projectName.toLowerCase()) || + proj.projectName.toLowerCase().includes(p.project_name.toLowerCase()) || + p.project_code.toLowerCase() === proj.projectName.toLowerCase() + ) + if (matched) { + proj.matchedProjectId = matched.project_id + proj.projectName = matched.project_name + } + } + + // workTasks 기본값 + proj.workTasks = (proj.workTasks || []).map((t: any) => ({ + description: t.description || '', + hours: t.hours || 0, + isCompleted: t.isCompleted !== false + })) + + // planTasks 기본값 + proj.planTasks = (proj.planTasks || []).map((t: any) => ({ + description: t.description || '', + hours: t.hours || 0 + })) + } + + // 내용 없는 프로젝트 제외 (workTasks, planTasks 모두 비어있으면 제외) + parsed.projects = parsed.projects.filter((proj: any) => + (proj.workTasks && proj.workTasks.length > 0) || + (proj.planTasks && proj.planTasks.length > 0) + ) + } + + return { + success: true, + parsed, + projects + } +}) + +function buildMyReportPrompt(rawText: string, projectList: string): any[] { + return [ + { + role: 'system', + content: `당신은 주간보고 내용을 분석하는 AI입니다. +사용자가 입력한 텍스트를 분석하여 프로젝트별 업무 내용을 추출해주세요. + +현재 등록된 프로젝트 목록 (형식: [ID:숫자] 코드: 이름): +${projectList} + +⚠️ 중요: 입력 텍스트에서 추출한 프로젝트명과 위 목록을 비교하여 가장 유사한 프로젝트의 ID를 matchedProjectId에 반환하세요. +- 유사도 판단: 키워드 일치, 약어, 부분 문자열 등 고려 +- 예: "한우 유전체" → "보은 한우 온라인 유전체 분석" 매칭 가능 +- 예: "HEIS" → "보건환경연구원 HEIS" 매칭 가능 +- 매칭되는 프로젝트가 없으면 matchedProjectId는 null + +응답은 반드시 아래 JSON 형식으로만 출력하세요: +{ + "projects": [ + { + "projectName": "입력에서 추출한 원본 프로젝트명", + "matchedProjectId": 5, + "workTasks": [ + {"description": "작업내용", "hours": 8, "isCompleted": true} + ], + "planTasks": [ + {"description": "계획내용", "hours": 8} + ] + } + ], + "issueDescription": "이슈/리스크 내용 또는 null", + "vacationDescription": "휴가일정 내용 또는 null", + "remarkDescription": "기타사항 내용 또는 null" +} + +규칙: +1. projectName은 입력 텍스트에서 추출한 원본 그대로 +2. matchedProjectId는 위 프로젝트 목록에서 가장 유사한 프로젝트의 ID (숫자) +3. "금주 실적", "이번주", "완료" 등은 workTasks로 분류 +4. "차주 계획", "다음주", "예정" 등은 planTasks로 분류 +5. 시간이 명시되지 않은 경우 hours는 0으로 +6. JSON 외의 텍스트는 절대 출력하지 마세요` + }, + { + role: 'user', + content: rawText + } + ] +} diff --git a/backend/api/auth/current-user.get.ts b/backend/api/auth/current-user.get.ts index 6433372..e983713 100644 --- a/backend/api/auth/current-user.get.ts +++ b/backend/api/auth/current-user.get.ts @@ -1,26 +1,48 @@ -import { queryOne } from '../../utils/db' +import { getSession, refreshSession, getSessionIdFromCookie, deleteSessionCookie } from '../../utils/session' /** * 현재 로그인 사용자 정보 * GET /api/auth/current-user */ export default defineEventHandler(async (event) => { - const userId = getCookie(event, 'user_id') + const sessionId = getSessionIdFromCookie(event) - if (!userId) { + if (!sessionId) { return { user: null } } + // DB에서 세션 조회 + const session = await getSession(sessionId) + + if (!session) { + // 세션이 만료되었거나 없음 → 쿠키 삭제 + deleteSessionCookie(event) + return { user: null } + } + + // 사용자 정보 조회 const employee = await queryOne(` SELECT * FROM wr_employee_info WHERE employee_id = $1 AND is_active = true - `, [parseInt(userId)]) + `, [session.employeeId]) if (!employee) { - deleteCookie(event, 'user_id') + deleteSessionCookie(event) return { user: null } } + // 세션 갱신 (Sliding Expiration - 10분 연장) + await refreshSession(sessionId) + + // 로그인 이력의 last_active_at도 업데이트 + if (session.loginHistoryId) { + await execute(` + UPDATE wr_login_history + SET last_active_at = NOW() + WHERE history_id = $1 + `, [session.loginHistoryId]) + } + return { user: { employeeId: employee.employee_id, diff --git a/backend/api/auth/login-history.get.ts b/backend/api/auth/login-history.get.ts index a126228..8bea7c4 100644 --- a/backend/api/auth/login-history.get.ts +++ b/backend/api/auth/login-history.get.ts @@ -1,17 +1,32 @@ -import { query } from '../../utils/db' +import { getSession, getSessionIdFromCookie, deleteSessionCookie, SESSION_TIMEOUT_MINUTES } from '../../utils/session' /** * 본인 로그인 이력 조회 * GET /api/auth/login-history */ export default defineEventHandler(async (event) => { - const userId = getCookie(event, 'user_id') - const currentHistoryId = getCookie(event, 'login_history_id') + const sessionId = getSessionIdFromCookie(event) - if (!userId) { + if (!sessionId) { throw createError({ statusCode: 401, message: '로그인이 필요합니다.' }) } + const session = await getSession(sessionId) + + if (!session) { + deleteSessionCookie(event) + throw createError({ statusCode: 401, message: '세션이 만료되었습니다.' }) + } + + // 현재 활성 세션 ID 목록 조회 + const activeSessions = await query(` + SELECT login_history_id FROM wr_session + WHERE employee_id = $1 AND expires_at > NOW() + `, [session.employeeId]) + + const activeHistoryIds = new Set(activeSessions.map(s => s.login_history_id)) + + // 로그인 이력 조회 const history = await query(` SELECT history_id, @@ -24,17 +39,37 @@ export default defineEventHandler(async (event) => { WHERE employee_id = $1 ORDER BY login_at DESC LIMIT 50 - `, [userId]) + `, [session.employeeId]) + + const SESSION_TIMEOUT_MS = SESSION_TIMEOUT_MINUTES * 60 * 1000 + const now = Date.now() return { - history: history.map(h => ({ - historyId: h.history_id, - loginAt: h.login_at, - loginIp: h.login_ip, - logoutAt: h.logout_at, - logoutIp: h.logout_ip, - lastActiveAt: h.last_active_at, - isCurrentSession: currentHistoryId && h.history_id === parseInt(currentHistoryId) - })) + history: history.map(h => { + const isCurrentSession = h.history_id === session.loginHistoryId + const isActiveSession = activeHistoryIds.has(h.history_id) + + // 세션 상태 판단 + let sessionStatus: 'active' | 'logout' | 'expired' + if (h.logout_at) { + sessionStatus = 'logout' + } else if (isActiveSession) { + sessionStatus = 'active' + } else { + // 활성 세션에 없으면 만료 + sessionStatus = 'expired' + } + + return { + historyId: h.history_id, + loginAt: h.login_at, + loginIp: h.login_ip, + logoutAt: h.logout_at, + logoutIp: h.logout_ip, + lastActiveAt: h.last_active_at, + isCurrentSession, + sessionStatus + } + }) } }) diff --git a/backend/api/auth/login.post.ts b/backend/api/auth/login.post.ts index a0823f0..60f8e0d 100644 --- a/backend/api/auth/login.post.ts +++ b/backend/api/auth/login.post.ts @@ -1,5 +1,5 @@ -import { query, insertReturning, execute } from '../../utils/db' import { getClientIp } from '../../utils/ip' +import { createSession, setSessionCookie } from '../../utils/session' interface LoginBody { email: string @@ -7,12 +7,13 @@ interface LoginBody { } /** - * 이메일+이름 로그인 (임시) + * 이메일+이름 로그인 * POST /api/auth/login */ export default defineEventHandler(async (event) => { const body = await readBody(event) const clientIp = getClientIp(event) + const userAgent = getHeader(event, 'user-agent') || null if (!body.email || !body.name) { throw createError({ statusCode: 400, message: '이메일과 이름을 입력해주세요.' }) @@ -60,18 +61,16 @@ export default defineEventHandler(async (event) => { RETURNING history_id `, [employeeData.employee_id, clientIp, emailLower]) - // 쿠키에 사용자 정보 저장 - setCookie(event, 'user_id', String(employeeData.employee_id), { - httpOnly: true, - maxAge: 60 * 60 * 24 * 7, - path: '/' - }) + // DB 기반 세션 생성 + const sessionId = await createSession( + employeeData.employee_id, + loginHistory.history_id, + clientIp, + userAgent + ) - setCookie(event, 'login_history_id', String(loginHistory.history_id), { - httpOnly: true, - maxAge: 60 * 60 * 24 * 7, - path: '/' - }) + // 세션 쿠키 설정 + setSessionCookie(event, sessionId) return { success: true, diff --git a/backend/api/auth/logout.post.ts b/backend/api/auth/logout.post.ts index 6540238..24b7997 100644 --- a/backend/api/auth/logout.post.ts +++ b/backend/api/auth/logout.post.ts @@ -1,26 +1,33 @@ -import { execute } from '../../utils/db' import { getClientIp } from '../../utils/ip' +import { getSession, deleteSession, getSessionIdFromCookie, deleteSessionCookie } from '../../utils/session' /** * 로그아웃 * POST /api/auth/logout */ export default defineEventHandler(async (event) => { - const historyId = getCookie(event, 'login_history_id') + const sessionId = getSessionIdFromCookie(event) const clientIp = getClientIp(event) - // 로그아웃 이력 기록 - if (historyId) { - await execute(` - UPDATE wr_login_history - SET logout_at = NOW(), logout_ip = $1 - WHERE history_id = $2 - `, [clientIp, historyId]) + if (sessionId) { + // 세션 정보 조회 + const session = await getSession(sessionId) + + // 로그아웃 이력 기록 + if (session?.loginHistoryId) { + await execute(` + UPDATE wr_login_history + SET logout_at = NOW(), logout_ip = $1 + WHERE history_id = $2 + `, [clientIp, session.loginHistoryId]) + } + + // DB에서 세션 삭제 + await deleteSession(sessionId) } - // 쿠키 삭제 - deleteCookie(event, 'user_id') - deleteCookie(event, 'login_history_id') + // 세션 쿠키 삭제 + deleteSessionCookie(event) return { success: true } }) diff --git a/backend/api/auth/me.get.ts b/backend/api/auth/me.get.ts index f4180f3..852bbf9 100644 --- a/backend/api/auth/me.get.ts +++ b/backend/api/auth/me.get.ts @@ -1,15 +1,24 @@ -import { queryOne } from '../../utils/db' +import { getSession, getSessionIdFromCookie, deleteSessionCookie } from '../../utils/session' /** - * 로그인된 사용자 정보 조회 + * 로그인된 사용자 상세 정보 조회 * GET /api/auth/me */ export default defineEventHandler(async (event) => { - const userId = getCookie(event, 'user_id') - if (!userId) { + const sessionId = getSessionIdFromCookie(event) + + if (!sessionId) { throw createError({ statusCode: 401, message: '로그인이 필요합니다.' }) } + // DB에서 세션 조회 + const session = await getSession(sessionId) + + if (!session) { + deleteSessionCookie(event) + throw createError({ statusCode: 401, message: '세션이 만료되었습니다. 다시 로그인해주세요.' }) + } + const employee = await queryOne(` SELECT employee_id, @@ -22,7 +31,7 @@ export default defineEventHandler(async (event) => { is_active FROM wr_employee_info WHERE employee_id = $1 - `, [userId]) + `, [session.employeeId]) if (!employee) { throw createError({ statusCode: 404, message: '사용자를 찾을 수 없습니다.' }) diff --git a/backend/api/auth/select-user.post.ts b/backend/api/auth/select-user.post.ts index aea8130..d564073 100644 --- a/backend/api/auth/select-user.post.ts +++ b/backend/api/auth/select-user.post.ts @@ -1,4 +1,5 @@ -import { queryOne, execute } from '../../utils/db' +import { getClientIp } from '../../utils/ip' +import { createSession, setSessionCookie } from '../../utils/session' interface SelectUserBody { employeeId: number @@ -10,6 +11,8 @@ interface SelectUserBody { */ export default defineEventHandler(async (event) => { const body = await readBody(event) + const clientIp = getClientIp(event) + const userAgent = getHeader(event, 'user-agent') || null if (!body.employeeId) { throw createError({ statusCode: 400, message: '사용자를 선택해주세요.' }) @@ -26,16 +29,22 @@ export default defineEventHandler(async (event) => { } // 로그인 이력 추가 - await execute(` - INSERT INTO wr_login_history (employee_id) VALUES ($1) - `, [employee.employee_id]) + const loginHistory = await insertReturning(` + INSERT INTO wr_login_history (employee_id, login_ip, login_email) + VALUES ($1, $2, $3) + RETURNING history_id + `, [employee.employee_id, clientIp, employee.employee_email]) - // 쿠키 설정 - setCookie(event, 'user_id', String(employee.employee_id), { - httpOnly: true, - maxAge: 60 * 60 * 24 * 7, - path: '/' - }) + // DB 기반 세션 생성 + const sessionId = await createSession( + employee.employee_id, + loginHistory.history_id, + clientIp, + userAgent + ) + + // 세션 쿠키 설정 + setSessionCookie(event, sessionId) return { success: true, diff --git a/backend/api/dashboard/stats.get.ts b/backend/api/dashboard/stats.get.ts index 063caf8..ff6d669 100644 --- a/backend/api/dashboard/stats.get.ts +++ b/backend/api/dashboard/stats.get.ts @@ -54,14 +54,15 @@ export default defineEventHandler(async (event) => { JOIN wr_weekly_report r ON t.report_id = r.report_id AND r.report_year = $1 AND r.report_week = $2 JOIN wr_employee_info e ON r.author_id = e.employee_id - WHERE p.project_status = 'IN_PROGRESS' GROUP BY p.project_id, p.project_code, p.project_name ORDER BY work_hours DESC `, [year, week]) // 3. 전체 요약 const activeEmployees = employeeStats.length - const submittedCount = employeeStats.filter((e: any) => e.report_id).length + const submittedCount = employeeStats.filter((e: any) => + e.report_status === 'SUBMITTED' || e.report_status === 'AGGREGATED' + ).length const totalWorkHours = employeeStats.reduce((sum: number, e: any) => sum + parseFloat(e.work_hours || 0), 0) const totalPlanHours = employeeStats.reduce((sum: number, e: any) => sum + parseFloat(e.plan_hours || 0), 0) @@ -86,7 +87,7 @@ export default defineEventHandler(async (event) => { planHours: parseFloat(e.plan_hours) || 0, workProjectCount: parseInt(e.work_project_count) || 0, planProjectCount: parseInt(e.plan_project_count) || 0, - isSubmitted: !!e.report_id + isSubmitted: e.report_status === 'SUBMITTED' || e.report_status === 'AGGREGATED' })), projects: projectStats.map((p: any) => ({ projectId: p.project_id, diff --git a/backend/api/report/review.post.ts b/backend/api/report/review.post.ts index 7816e60..aed3822 100644 --- a/backend/api/report/review.post.ts +++ b/backend/api/report/review.post.ts @@ -6,8 +6,32 @@ const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }) +// 문자열 해시 함수 (seed용) +function hashCode(str: string): number { + let hash = 0 + for (let i = 0; i < str.length; i++) { + const char = str.charCodeAt(i) + hash = ((hash << 5) - hash) + char + hash = hash & hash // 32bit 정수로 변환 + } + return Math.abs(hash) +} + +interface QualityScore { + summary: string // 총평 (맨 위) + specificity: { score: number; improvement: string } // 구체성 + completeness: { score: number; improvement: string } // 완결성 + timeEstimation: { score: number; improvement: string } // 시간산정 + planning: { score: number; improvement: string } // 계획성 + overall: number // 종합점수 + bestPractice: { // 모범 답안 + workTasks: string[] // 금주 실적 모범 답안 + planTasks: string[] // 차주 계획 모범 답안 + } +} + /** - * 주간보고 PMO AI 리뷰 + * 주간보고 PMO AI 리뷰 - 작성 품질 점수 + 모범 답안 * POST /api/report/review */ export default defineEventHandler(async (event) => { @@ -77,61 +101,75 @@ export default defineEventHandler(async (event) => { }) } - // OpenAI PMO 리뷰 요청 - const systemPrompt = `당신은 SI 프로젝트의 PMO(Project Management Officer)이자 주간보고 작성 코치입니다. -개발자들이 더 나은 주간보고를 작성할 수 있도록 구체적인 피드백과 가이드를 제공해주세요. + // OpenAI 품질 점수 + 모범 답안 요청 + const systemPrompt = `당신은 SI 프로젝트의 PMO(Project Management Officer)입니다. +주간보고의 작성 품질을 평가하고, 모범 답안을 제시해주세요. -[주간보고 작성의 목적] -- 프로젝트 진행 현황을 명확히 파악 -- 일정 지연이나 리스크를 사전에 감지 -- 팀원 간 업무 공유 및 협업 촉진 +[평가 항목] (각 1~10점) +1. 구체성 (specificity): 작업 내용이 어떤 기능/모듈인지 구체적으로 작성되었는지 +2. 완결성 (completeness): 필수 정보 포함 여부 +3. 시간산정 (timeEstimation): 작업 시간이 내용 대비 적절하게 배분되었는지 +4. 계획성 (planning): 차주 계획이 실현 가능하고 명확한 목표가 있는지 -[검토 기준 - 엄격하게 적용] +[완결성 상세 기준] - 엄격하게 적용 +- 진행중 작업에 진척률(%)이 없으면 -2점 +- 진행중 작업에 완료 예정일이 없으면 -2점 +- 완료 작업인데 산출물/결과 언급이 없으면 -1점 +- 상태(완료/진행중)가 명확하지 않으면 -1점 -1. **실적의 구체성** (가장 중요!) - - "DB 작업", "화면 개발", "API 개발" 같은 모호한 표현 지양 - - 좋은 예시: "사용자 관리 테이블 3개(user, role, permission) 설계 및 생성" - - 좋은 예시: "로그인 API 개발 - JWT 토큰 발급, 리프레시 토큰 구현" - - 좋은 예시: "검색 화면 UI 구현 - 필터 조건 5개, 페이징, 엑셀 다운로드" - - 어떤 기능/모듈/화면인지, 무엇을 구체적으로 했는지 명시되어야 함 +[계획성 상세 기준] - 엄격하게 적용 +- 차주 계획에 예상 소요시간 근거가 없으면 -1점 +- 차주 계획에 목표 완료일/산출물이 없으면 -2점 +- 단순 "~할 예정", "~진행" 만 있고 구체적 목표가 없으면 -2점 +- 실현 가능성이 낮은 과도한 계획이면 -1점 -2. **일정의 명확성** - - "진행중"만 있고 완료 예정일이 없으면 부족 - - 언제 완료될 예정인지, 진척률은 얼마인지 표기 권장 - - 좋은 예시: "사용자 관리 화면 개발 (70% 완료, 1/10 완료 예정)" +[점수 기준] +- 1~3점: 매우 부족 (내용이 거의 없거나 한 단어 수준) +- 4~5점: 부족 (진척률/예정일 누락, 모호한 표현) +- 6~7점: 보통 (기본 내용은 있으나 구체성 부족) +- 8~9점: 양호 (진척률, 예정일, 산출물 모두 명시) +- 10점: 우수 (완벽한 모범 사례) -3. **시간 산정의 적절성** - - 8시간(1일) 이상 작업은 세부 내역이 필요 - - 16시간(2일) 이상인데 내용이 한 줄이면 분리 필요 - - "회의", "검토" 등은 별도 기재 권장 +※ 진행중 작업에 진척률/예정일이 없으면 완결성은 6점 이하로 평가하세요. +※ 차주 계획에 구체적 목표가 없으면 계획성은 6점 이하로 평가하세요. -4. **차주 계획의 실현 가능성** - - 계획이 너무 추상적이면 실행하기 어려움 - - 구체적인 목표와 예상 산출물 명시 필요 - - 좋은 예시: "결제 모듈 연동 - PG사 API 연동, 결제 테스트 완료 목표" +[모범 답안 작성 규칙] +- 사용자가 작성한 내용을 기반으로 더 구체적으로 보완 +- 같은 프로젝트명, 비슷한 작업 내용을 유지하되 구체성 추가 +- 진행중인 작업은 반드시 진척률(%)과 완료 예정일 추가 +- 시간이 긴 작업은 세부 내역 포함 +- 차주 계획은 목표 산출물과 예상 완료일 명시 +- 형식: "프로젝트명 / 작업내용 (세부사항, 진척률, 예정일) / 시간h / 상태" -[피드백 작성 규칙] -- 각 Task별로 구체적인 개선 제안 제시 -- 잘 작성된 부분은 "✅" 로 인정 -- 보완이 필요한 부분은 "📝" 로 개선 방향 제시 -- 일정 관련 질문은 "📅" 로 표시 -- 리스크/우려사항은 "⚠️" 로 경고 -- **반드시 어떻게 수정하면 좋을지 예시를 들어 설명** -- 친절하지만 명확하게, 구체적인 작성 예시를 포함 -- 마지막에 전체적인 작성 팁 1-2개 추가 +[응답 규칙] +- 반드시 아래 JSON 형식으로만 응답 +- summary: 전체적인 총평 (30~60자, 격려 포함) +- improvement: 각 항목별 개선 포인트 (15~30자, 구체적으로) +- bestPractice: 모범 답안 (workTasks, planTasks 배열) +- JSON 외의 텍스트는 절대 포함하지 마세요` -[피드백 톤] -- 비난하지 않고 코칭하는 느낌으로 -- "~하면 더 좋겠습니다", "~로 수정해보시면 어떨까요?" 형태로 -- 개선점뿐 아니라 잘한 점도 언급` + const userPrompt = `다음 주간보고의 작성 품질을 평가하고, 모범 답안을 만들어주세요. - const userPrompt = `다음 주간보고를 PMO 관점에서 상세히 리뷰해주세요. -특히 실적과 계획이 구체적으로 작성되었는지, 일정이 명확한지 중점적으로 검토해주세요. -모호한 표현이 있다면 어떻게 수정하면 좋을지 예시와 함께 피드백해주세요. +${taskText} -${taskText}` +아래 JSON 형식으로만 응답하세요: +{ + "summary": "총평 (격려 포함)", + "specificity": { "score": 숫자, "improvement": "개선포인트" }, + "completeness": { "score": 숫자, "improvement": "개선포인트" }, + "timeEstimation": { "score": 숫자, "improvement": "개선포인트" }, + "planning": { "score": 숫자, "improvement": "개선포인트" }, + "overall": 종합점수(소수점1자리), + "bestPractice": { + "workTasks": ["모범답안1", "모범답안2", ...], + "planTasks": ["모범답안1", "모범답안2", ...] + } +}` try { + // Task 내용 기반 seed 생성 (같은 내용 = 같은 점수) + const seed = hashCode(taskText) + const response = await openai.chat.completions.create({ model: 'gpt-4o-mini', messages: [ @@ -139,29 +177,52 @@ ${taskText}` { role: 'user', content: userPrompt } ], max_tokens: 1500, - temperature: 0.7 + temperature: 0.2, // 낮춰서 일관성 강화 + seed: seed // 같은 내용 = 같은 seed = 같은 결과 }) - const review = response.choices[0]?.message?.content || '리뷰를 생성할 수 없습니다.' + const content = response.choices[0]?.message?.content || '' + + // JSON 파싱 + let qualityScore: QualityScore + try { + // JSON 블록 추출 (```json ... ``` 형태 처리) + let jsonStr = content + const jsonMatch = content.match(/```json\s*([\s\S]*?)\s*```/) + if (jsonMatch) { + jsonStr = jsonMatch[1] + } else { + // { } 사이 추출 + const braceMatch = content.match(/\{[\s\S]*\}/) + if (braceMatch) { + jsonStr = braceMatch[0] + } + } + qualityScore = JSON.parse(jsonStr) + } catch (parseError) { + console.error('JSON 파싱 실패:', content) + throw new Error('AI 응답을 파싱할 수 없습니다.') + } + const reviewedAt = new Date().toISOString() - // DB에 저장 + // DB에 저장 (ai_review에 JSON 문자열로 저장) await query(` UPDATE wr_weekly_report SET ai_review = $1, ai_review_at = $2 WHERE report_id = $3 - `, [review, reviewedAt, reportId]) + `, [JSON.stringify(qualityScore), reviewedAt, reportId]) return { success: true, - review, + qualityScore, reviewedAt } } catch (error: any) { console.error('OpenAI API error:', error) throw createError({ statusCode: 500, - message: 'AI 리뷰 생성 중 오류가 발생했습니다: ' + error.message + message: 'AI 품질 평가 중 오류가 발생했습니다: ' + error.message }) } }) diff --git a/backend/api/report/weekly/list.get.ts b/backend/api/report/weekly/list.get.ts index 190cfa5..66e1443 100644 --- a/backend/api/report/weekly/list.get.ts +++ b/backend/api/report/weekly/list.get.ts @@ -32,26 +32,14 @@ export default defineEventHandler(async (event) => { const q = getQuery(event) const limit = parseInt(q.limit as string) || 100 - const viewAll = q.viewAll === 'true' // 필터 조건 구성 const conditions: string[] = [] const params: any[] = [] let paramIndex = 1 - // 관리자가 viewAll이면 전체 조회, 아니면 본인 것만 - if (!isAdmin || !viewAll) { - // 작성자 필터 (본인 또는 지정된 작성자) - if (q.authorId) { - conditions.push(`r.author_id = $${paramIndex++}`) - params.push(q.authorId) - } else if (!isAdmin) { - // 관리자가 아니면 본인 것만 - conditions.push(`r.author_id = $${paramIndex++}`) - params.push(userId) - } - } else if (q.authorId) { - // 관리자가 viewAll이어도 작성자 필터가 있으면 적용 + // 작성자 필터 (선택된 경우에만 적용) + if (q.authorId) { conditions.push(`r.author_id = $${paramIndex++}`) params.push(q.authorId) } @@ -77,6 +65,15 @@ export default defineEventHandler(async (event) => { params.push(q.week) } + // 특정 주차 이전 필터 (beforeYear, beforeWeek) + if (q.beforeYear && q.beforeWeek) { + conditions.push(`(r.report_year < $${paramIndex} OR (r.report_year = $${paramIndex} AND r.report_week < $${paramIndex + 1}))`) + params.push(q.beforeYear) + paramIndex++ + params.push(q.beforeWeek) + paramIndex++ + } + // 주차 범위 필터 if (q.weekFrom) { conditions.push(`r.report_week >= $${paramIndex++}`) @@ -122,6 +119,8 @@ export default defineEventHandler(async (event) => { r.report_status, r.submitted_at, r.created_at, + r.updated_at, + r.ai_review, (SELECT COUNT(DISTINCT project_id) FROM wr_weekly_report_task WHERE report_id = r.report_id) as project_count, (SELECT string_agg(DISTINCT p.project_name, ', ') FROM wr_weekly_report_task t @@ -152,6 +151,8 @@ export default defineEventHandler(async (event) => { reportStatus: r.report_status, submittedAt: r.submitted_at, createdAt: r.created_at, + updatedAt: r.updated_at, + aiReview: r.ai_review, projectCount: parseInt(r.project_count), projectNames: r.project_names, totalWorkHours: parseFloat(r.total_work_hours) || 0, diff --git a/backend/sql/create_session_table.sql b/backend/sql/create_session_table.sql new file mode 100644 index 0000000..c50646a --- /dev/null +++ b/backend/sql/create_session_table.sql @@ -0,0 +1,18 @@ +-- 세션 테이블 (Spring Session JDBC와 유사한 구조) +CREATE TABLE IF NOT EXISTS wr_session ( + session_id VARCHAR(64) PRIMARY KEY, -- 세션 토큰 (랜덤 생성) + employee_id INTEGER NOT NULL REFERENCES wr_employee_info(employee_id), + login_history_id INTEGER REFERENCES wr_login_history(history_id), + created_at TIMESTAMP DEFAULT NOW(), -- 세션 생성 시간 + last_access_at TIMESTAMP DEFAULT NOW(), -- 마지막 접근 시간 + expires_at TIMESTAMP NOT NULL, -- 만료 시간 + login_ip VARCHAR(45), -- 로그인 IP + user_agent TEXT -- 브라우저 정보 +); + +-- 인덱스 +CREATE INDEX IF NOT EXISTS idx_wr_session_employee_id ON wr_session(employee_id); +CREATE INDEX IF NOT EXISTS idx_wr_session_expires_at ON wr_session(expires_at); + +-- 만료된 세션 자동 정리 (선택사항 - 배치로 실행) +-- DELETE FROM wr_session WHERE expires_at < NOW(); diff --git a/backend/utils/session.ts b/backend/utils/session.ts new file mode 100644 index 0000000..a526d69 --- /dev/null +++ b/backend/utils/session.ts @@ -0,0 +1,198 @@ +import crypto from 'crypto' +import { query, queryOne, execute, insertReturning } from './db' + +// 세션 설정 +const SESSION_TIMEOUT_MINUTES = 10 // 10분 타임아웃 +const SESSION_COOKIE_NAME = 'session_token' +const SESSION_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 // 쿠키는 7일 (세션 만료와 별개) + +interface Session { + sessionId: string + employeeId: number + loginHistoryId: number | null + createdAt: Date + lastAccessAt: Date + expiresAt: Date + loginIp: string | null + userAgent: string | null +} + +/** + * 랜덤 세션 토큰 생성 (Spring Session과 유사) + */ +function generateSessionToken(): string { + return crypto.randomBytes(32).toString('hex') // 64자 hex 문자열 +} + +/** + * 세션 생성 + */ +export async function createSession( + employeeId: number, + loginHistoryId: number, + loginIp: string | null, + userAgent: string | null +): Promise { + const sessionId = generateSessionToken() + const expiresAt = new Date(Date.now() + SESSION_TIMEOUT_MINUTES * 60 * 1000) + + await execute(` + INSERT INTO wr_session (session_id, employee_id, login_history_id, expires_at, login_ip, user_agent) + VALUES ($1, $2, $3, $4, $5, $6) + `, [sessionId, employeeId, loginHistoryId, expiresAt, loginIp, userAgent]) + + return sessionId +} + +/** + * 세션 조회 (유효한 세션만) + */ +export async function getSession(sessionId: string): Promise { + if (!sessionId) return null + + const row = await queryOne(` + SELECT + session_id, + employee_id, + login_history_id, + created_at, + last_access_at, + expires_at, + login_ip, + user_agent + FROM wr_session + WHERE session_id = $1 AND expires_at > NOW() + `, [sessionId]) + + if (!row) return null + + return { + sessionId: row.session_id, + employeeId: row.employee_id, + loginHistoryId: row.login_history_id, + createdAt: row.created_at, + lastAccessAt: row.last_access_at, + expiresAt: row.expires_at, + loginIp: row.login_ip, + userAgent: row.user_agent + } +} + +/** + * 세션 갱신 (Sliding Expiration) + * - 마지막 접근 시간 업데이트 + * - 만료 시간 연장 + */ +export async function refreshSession(sessionId: string): Promise { + const newExpiresAt = new Date(Date.now() + SESSION_TIMEOUT_MINUTES * 60 * 1000) + + const result = await execute(` + UPDATE wr_session + SET last_access_at = NOW(), expires_at = $1 + WHERE session_id = $2 AND expires_at > NOW() + `, [newExpiresAt, sessionId]) + + return result.rowCount > 0 +} + +/** + * 세션 삭제 (로그아웃) + */ +export async function deleteSession(sessionId: string): Promise { + const result = await execute(` + DELETE FROM wr_session WHERE session_id = $1 + `, [sessionId]) + + return result.rowCount > 0 +} + +/** + * 사용자의 모든 세션 삭제 (모든 기기에서 로그아웃) + */ +export async function deleteAllUserSessions(employeeId: number): Promise { + const result = await execute(` + DELETE FROM wr_session WHERE employee_id = $1 + `, [employeeId]) + + return result.rowCount +} + +/** + * 만료된 세션 정리 (배치용) + */ +export async function cleanupExpiredSessions(): Promise { + const result = await execute(` + DELETE FROM wr_session WHERE expires_at < NOW() + `) + + return result.rowCount +} + +/** + * 세션 쿠키 설정 + */ +export function setSessionCookie(event: any, sessionId: string) { + setCookie(event, SESSION_COOKIE_NAME, sessionId, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax', + maxAge: SESSION_COOKIE_MAX_AGE, + path: '/' + }) +} + +/** + * 세션 쿠키 삭제 + */ +export function deleteSessionCookie(event: any) { + deleteCookie(event, SESSION_COOKIE_NAME) +} + +/** + * 세션 쿠키에서 세션 ID 가져오기 + */ +export function getSessionIdFromCookie(event: any): string | null { + return getCookie(event, SESSION_COOKIE_NAME) || null +} + +// 설정값 export +export { SESSION_TIMEOUT_MINUTES, SESSION_COOKIE_NAME } + +/** + * 인증된 사용자 ID 가져오기 (다른 API에서 사용) + * - 세션이 없거나 만료되면 null 반환 + * - 세션이 유효하면 자동 갱신 + * - [호환성] 기존 user_id 쿠키도 지원 (마이그레이션 기간) + */ +export async function getAuthenticatedUserId(event: any): Promise { + // 1. 새로운 세션 토큰 확인 + const sessionId = getSessionIdFromCookie(event) + if (sessionId) { + const session = await getSession(sessionId) + if (session) { + await refreshSession(sessionId) + return session.employeeId + } + // 세션 만료 → 쿠키 삭제 + deleteSessionCookie(event) + } + + // 2. [호환성] 기존 user_id 쿠키 확인 (마이그레이션 기간) + const legacyUserId = getCookie(event, 'user_id') + if (legacyUserId) { + return parseInt(legacyUserId) + } + + return null +} + +/** + * 인증 필수 API용 - 미인증시 에러 throw + */ +export async function requireAuth(event: any): Promise { + const userId = await getAuthenticatedUserId(event) + if (!userId) { + throw createError({ statusCode: 401, message: '로그인이 필요합니다.' }) + } + return userId +} diff --git a/migrate-completed.mjs b/claude_temp/migrate-completed.mjs similarity index 100% rename from migrate-completed.mjs rename to claude_temp/migrate-completed.mjs diff --git a/frontend/admin/bulk-import.vue b/frontend/admin/bulk-import.vue index 50cf64d..5b4c9ec 100644 --- a/frontend/admin/bulk-import.vue +++ b/frontend/admin/bulk-import.vue @@ -64,9 +64,11 @@

이미지를 드래그하거나 클릭해서 업로드
- (최대 10장, PNG/JPG) + 또는 Ctrl+V로 붙여넣기 (최대 10장)

@@ -358,6 +360,7 @@ diff --git a/frontend/report/weekly/aggregate.vue b/frontend/report/weekly/aggregate.vue index ffd1052..d7c277a 100644 --- a/frontend/report/weekly/aggregate.vue +++ b/frontend/report/weekly/aggregate.vue @@ -139,6 +139,7 @@ import { useRouter } from 'vue-router' const router = useRouter() const { fetchCurrentUser, isAdmin } = useAuth() +const { getWeekInfo, getWeekDates, getWeeksInYear, changeWeek: calcChangeWeek } = useWeekCalc() const isLoading = ref(false) const isLoaded = ref(false) @@ -178,72 +179,23 @@ onMounted(async () => { }) function initCurrentWeek() { - const now = new Date() - const jan4 = new Date(now.getFullYear(), 0, 4) - const jan4Day = jan4.getDay() || 7 - const week1Monday = new Date(jan4) - week1Monday.setDate(jan4.getDate() - jan4Day + 1) - - const diff = now.getTime() - week1Monday.getTime() - const weekNum = Math.floor(diff / (7 * 24 * 60 * 60 * 1000)) + 1 - - selectedYear.value = now.getFullYear() - selectedWeek.value = weekNum > 0 ? weekNum : 1 + const weekInfo = getWeekInfo(new Date()) + selectedYear.value = weekInfo.year + selectedWeek.value = weekInfo.week updateWeekDates() } function changeWeek(delta: number) { - let year = selectedYear.value - let week = selectedWeek.value + delta - - if (week < 1) { - year-- - week = getWeeksInYear(year) - } else if (week > getWeeksInYear(year)) { - year++ - week = 1 - } - + const { year, week } = calcChangeWeek(selectedYear.value, selectedWeek.value, delta) selectedYear.value = year selectedWeek.value = week updateWeekDates() } -function getWeeksInYear(year: number): number { - const dec31 = new Date(year, 11, 31) - const dayOfWeek = dec31.getDay() - return dayOfWeek >= 4 || dayOfWeek === 0 ? 53 : 52 -} - function updateWeekDates() { - const { monday, sunday } = getWeekDates(selectedYear.value, selectedWeek.value) - weekStartDate.value = monday - weekEndDate.value = sunday -} - -function getWeekDates(year: number, week: number): { monday: string, sunday: string } { - const jan4 = new Date(year, 0, 4) - const jan4Day = jan4.getDay() || 7 - const week1Monday = new Date(jan4) - week1Monday.setDate(jan4.getDate() - jan4Day + 1) - - const monday = new Date(week1Monday) - monday.setDate(week1Monday.getDate() + (week - 1) * 7) - - const sunday = new Date(monday) - sunday.setDate(monday.getDate() + 6) - - return { - monday: formatDate(monday), - sunday: formatDate(sunday) - } -} - -function formatDate(date: Date): string { - const y = date.getFullYear() - const m = String(date.getMonth() + 1).padStart(2, '0') - const d = String(date.getDate()).padStart(2, '0') - return `${y}-${m}-${d}` + const weekInfo = getWeekDates(selectedYear.value, selectedWeek.value) + weekStartDate.value = weekInfo.startDateStr + weekEndDate.value = weekInfo.endDateStr } async function loadAggregate() { diff --git a/frontend/report/weekly/index.vue b/frontend/report/weekly/index.vue index aafc4c5..255063b 100644 --- a/frontend/report/weekly/index.vue +++ b/frontend/report/weekly/index.vue @@ -8,10 +8,7 @@ 주간보고
- - 취합하기 - - + 작성하기
@@ -21,16 +18,8 @@
- -
-
- - -
-
- -
+
- -
- - -
- - -
- - + +
+
+ + + + +
@@ -76,20 +68,22 @@ 주차 기간 - 작성자 프로젝트 + 작성자 상태 - 제출일 + 작성/수정 + 제출일시 + 품질 - + 로딩 중... - +

조회된 주간보고가 없습니다.

@@ -103,21 +97,33 @@ {{ formatDate(r.weekStartDate) }} ~ {{ formatDate(r.weekEndDate) }} - - {{ r.authorName }} - {{ r.projectNames || '-' }} {{ r.projectCount }}건 + {{ r.authorName }} {{ getStatusText(r.reportStatus) }} - {{ formatDateTime(r.submittedAt || r.createdAt) }} + +
{{ formatShortDateTime(r.createdAt) }}
+
+ {{ formatShortDateTime(r.updatedAt) }} +
+ + + {{ r.submittedAt ? formatShortDateTime(r.submittedAt) : '-' }} + + + + {{ getQualityGrade(r.aiReview) }} + + - + @@ -133,24 +139,74 @@ diff --git a/package-lock.json b/package-lock.json index b023b1c..e3e286f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -421,9 +421,9 @@ } }, "node_modules/@bomb.sh/tab": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/@bomb.sh/tab/-/tab-0.0.10.tgz", - "integrity": "sha512-6ALS2rh/4LKn0Yxwm35V6LcgQuSiECHbqQo7+9g4rkgGyXZ0siOc8K+IuWIq/4u0Zkv2mevP9QSqgKhGIvLJMw==", + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/@bomb.sh/tab/-/tab-0.0.11.tgz", + "integrity": "sha512-RSqyreeicYBALcMaNxIUJTBknftXsyW45VRq5gKDNwKroh0Re5SDoWwXZaphb+OTEzVdpm/BA8Uq6y0P+AtVYw==", "license": "MIT", "bin": { "tab": "dist/bin/cli.js" @@ -456,9 +456,9 @@ } }, "node_modules/@clack/prompts": { - "version": "1.0.0-alpha.8", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.0.0-alpha.8.tgz", - "integrity": "sha512-YZGC4BmTKSF5OturNKEz/y4xNjYGmGk6NI785CQucJ7OEdX0qbMmL/zok+9bL6c7qE3WSYffyK5grh2RnkGNtQ==", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.0.0-alpha.9.tgz", + "integrity": "sha512-sKs0UjiHFWvry4SiRfBi5Qnj0C/6AYx8aKkFPZQSuUZXgAram25ZDmhQmP7vj1aFyLpfHWtLQjWvOvcat0TOLg==", "license": "MIT", "dependencies": { "@clack/core": "1.0.0-alpha.7", @@ -569,9 +569,9 @@ "license": "MIT" }, "node_modules/@emnapi/core": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.0.tgz", - "integrity": "sha512-ryJnSmj4UhrGLZZPJ6PKVb4wNPAIkW6iyLy+0TRwazd3L1u0wzMe8RfqevAh2HbcSkoeLiSYnOVDOys4JSGYyg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", "license": "MIT", "optional": true, "dependencies": { @@ -580,9 +580,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.0.tgz", - "integrity": "sha512-Z82FDl1ByxqPEPrAYYeTQVlx2FSHPe1qwX465c+96IRS3fTdSYRoJcRxg3g2fEG5I69z1dSEWQlNRRr0/677mg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", "license": "MIT", "optional": true, "dependencies": { @@ -999,27 +999,32 @@ "node": ">=18" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", - "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", - "cpu": [ - "x64" - ], + "node_modules/@ioredis/commands": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.0.tgz", + "integrity": "sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==", + "license": "MIT" + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">=18" + "node": "20 || >=22" } }, - "node_modules/@ioredis/commands": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.4.0.tgz", - "integrity": "sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==", - "license": "MIT" + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -1038,6 +1043,85 @@ "node": ">=12" } }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", @@ -1202,14 +1286,14 @@ } }, "node_modules/@nuxt/cli": { - "version": "3.31.3", - "resolved": "https://registry.npmjs.org/@nuxt/cli/-/cli-3.31.3.tgz", - "integrity": "sha512-K0T1ZpBXnlb41NU/RWf1F0U0C14KzlEXCoaSgD2y8BiLoCBWcgQ1UAlRtx4cThqWbJmIxaNZZTDL0NZ9d1U7ag==", + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/@nuxt/cli/-/cli-3.32.0.tgz", + "integrity": "sha512-n2f3SRjPlhthPvo2qWjLRRiTrUtB6WFwg0BGsvtqcqZVeQpNEU371zuKWBaFrWgqDZHV1r/aD9jrVCo+C8Pmrw==", "license": "MIT", "dependencies": { - "@bomb.sh/tab": "^0.0.10", - "@clack/prompts": "1.0.0-alpha.8", - "c12": "^3.3.2", + "@bomb.sh/tab": "^0.0.11", + "@clack/prompts": "1.0.0-alpha.9", + "c12": "^3.3.3", "citty": "^0.1.6", "confbox": "^0.2.2", "consola": "^3.4.2", @@ -1229,7 +1313,7 @@ "pkg-types": "^2.3.0", "scule": "^1.3.0", "semver": "^7.7.3", - "srvx": "^0.9.8", + "srvx": "^0.10.0", "std-env": "^3.10.0", "tinyexec": "^1.0.2", "ufo": "^1.6.1", @@ -1410,6 +1494,132 @@ "nuxt": "^3.20.2" } }, + "node_modules/@nuxt/nitro-server/node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@nuxt/nitro-server/node_modules/nitropack": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/nitropack/-/nitropack-2.13.0.tgz", + "integrity": "sha512-31H9EgJNsJqfa5f6775ksZlKH+Fk8Kv3CV2wF6v9+KY57DexH8+qCLrcOXgM72vKB/j/7dVmOtuiVY8Jy8+8nw==", + "license": "MIT", + "dependencies": { + "@cloudflare/kv-asset-handler": "^0.4.1", + "@rollup/plugin-alias": "^6.0.0", + "@rollup/plugin-commonjs": "^29.0.0", + "@rollup/plugin-inject": "^5.0.5", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-replace": "^6.0.3", + "@rollup/plugin-terser": "^0.4.4", + "@vercel/nft": "^1.2.0", + "archiver": "^7.0.1", + "c12": "^3.3.3", + "chokidar": "^5.0.0", + "citty": "^0.1.6", + "compatx": "^0.2.0", + "confbox": "^0.2.2", + "consola": "^3.4.2", + "cookie-es": "^2.0.0", + "croner": "^9.1.0", + "crossws": "^0.3.5", + "db0": "^0.3.4", + "defu": "^6.1.4", + "destr": "^2.0.5", + "dot-prop": "^10.1.0", + "esbuild": "^0.27.2", + "escape-string-regexp": "^5.0.0", + "etag": "^1.8.1", + "exsolve": "^1.0.8", + "globby": "^16.1.0", + "gzip-size": "^7.0.0", + "h3": "^1.15.4", + "hookable": "^5.5.3", + "httpxy": "^0.1.7", + "ioredis": "^5.9.1", + "jiti": "^2.6.1", + "klona": "^2.0.6", + "knitwork": "^1.3.0", + "listhen": "^1.9.0", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mime": "^4.1.0", + "mlly": "^1.8.0", + "node-fetch-native": "^1.6.7", + "node-mock-http": "^1.0.4", + "ofetch": "^1.5.1", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^2.0.0", + "pkg-types": "^2.3.0", + "pretty-bytes": "^7.1.0", + "radix3": "^1.1.2", + "rollup": "^4.55.1", + "rollup-plugin-visualizer": "^6.0.5", + "scule": "^1.3.0", + "semver": "^7.7.3", + "serve-placeholder": "^2.0.2", + "serve-static": "^2.2.1", + "source-map": "^0.7.6", + "std-env": "^3.10.0", + "ufo": "^1.6.2", + "ultrahtml": "^1.6.0", + "uncrypto": "^0.1.3", + "unctx": "^2.5.0", + "unenv": "^2.0.0-rc.24", + "unimport": "^5.6.0", + "unplugin-utils": "^0.3.1", + "unstorage": "^1.17.3", + "untyped": "^2.0.0", + "unwasm": "^0.5.2", + "youch": "^4.1.0-beta.13", + "youch-core": "^0.3.3" + }, + "bin": { + "nitro": "dist/cli/index.mjs", + "nitropack": "dist/cli/index.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "xml2js": "^0.6.2" + }, + "peerDependenciesMeta": { + "xml2js": { + "optional": true + } + } + }, + "node_modules/@nuxt/nitro-server/node_modules/perfect-debounce": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz", + "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", + "license": "MIT" + }, + "node_modules/@nuxt/nitro-server/node_modules/unplugin-utils": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz", + "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/@nuxt/schema": { "version": "3.20.2", "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-3.20.2.tgz", @@ -1748,22 +1958,6 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-minify/binding-win32-x64-msvc": { - "version": "0.102.0", - "resolved": "https://registry.npmjs.org/@oxc-minify/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.102.0.tgz", - "integrity": "sha512-XdyJZdSMN8rbBXH10CrFuU+Q9jIP2+MnxHmNzjK4+bldbTI1UxqwjUMS9bKVC5VCaIEZhh8IE8x4Vf8gmCgrKQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, "node_modules/@oxc-parser/binding-android-arm64": { "version": "0.102.0", "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.102.0.tgz", @@ -1988,22 +2182,6 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-win32-x64-msvc": { - "version": "0.102.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.102.0.tgz", - "integrity": "sha512-ntMcL35wuLR1A145rLSmm7m7j8JBZGkROoB9Du0KFIFcfi/w1qk75BdCeiTl3HAKrreAnuhW3QOGs6mJhntowA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, "node_modules/@oxc-project/types": { "version": "0.102.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.102.0.tgz", @@ -2237,22 +2415,6 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-transform/binding-win32-x64-msvc": { - "version": "0.102.0", - "resolved": "https://registry.npmjs.org/@oxc-transform/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.102.0.tgz", - "integrity": "sha512-eYOm6mch+1cP9qlNkMdorfBFY8aEOxY/isqrreLmEWqF/hyXA0SbLKDigTbvh3JFKny/gXlHoCKckqfua4cwtg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, "node_modules/@parcel/watcher": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", @@ -2632,15 +2794,15 @@ "license": "MIT" }, "node_modules/@rollup/plugin-alias": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.1.tgz", - "integrity": "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-6.0.0.tgz", + "integrity": "sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==", "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=20.19.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + "rollup": ">=4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -2649,9 +2811,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.9", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.9.tgz", - "integrity": "sha512-PIR4/OHZ79romx0BVVll/PkwWpJ7e5lsqFa3gFfcrFPWwLXLV39JVUzQV9RKjWerE7B845Hqjj9VYlQeieZ2dA==", + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-29.0.0.tgz", + "integrity": "sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ==", "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -2806,9 +2968,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz", - "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", + "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", "cpu": [ "arm" ], @@ -2819,9 +2981,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz", - "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", + "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", "cpu": [ "arm64" ], @@ -2832,9 +2994,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz", - "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", + "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", "cpu": [ "arm64" ], @@ -2845,9 +3007,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz", - "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", + "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", "cpu": [ "x64" ], @@ -2858,9 +3020,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz", - "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", + "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", "cpu": [ "arm64" ], @@ -2871,9 +3033,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz", - "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", + "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", "cpu": [ "x64" ], @@ -2884,9 +3046,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz", - "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", + "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", "cpu": [ "arm" ], @@ -2897,9 +3059,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz", - "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", + "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", "cpu": [ "arm" ], @@ -2910,9 +3072,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz", - "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", + "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", "cpu": [ "arm64" ], @@ -2923,9 +3085,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz", - "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", + "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", "cpu": [ "arm64" ], @@ -2936,9 +3098,22 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz", - "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", + "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", + "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", "cpu": [ "loong64" ], @@ -2949,9 +3124,22 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz", - "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", + "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", + "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", "cpu": [ "ppc64" ], @@ -2962,9 +3150,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz", - "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", + "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", "cpu": [ "riscv64" ], @@ -2975,9 +3163,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz", - "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", + "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", "cpu": [ "riscv64" ], @@ -2988,9 +3176,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz", - "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", + "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", "cpu": [ "s390x" ], @@ -3001,9 +3189,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz", - "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", + "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", "cpu": [ "x64" ], @@ -3014,9 +3202,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz", - "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", + "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", "cpu": [ "x64" ], @@ -3026,10 +3214,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", + "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz", - "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", + "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", "cpu": [ "arm64" ], @@ -3040,9 +3241,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz", - "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", + "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", "cpu": [ "arm64" ], @@ -3053,9 +3254,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz", - "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", + "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", "cpu": [ "ia32" ], @@ -3066,22 +3267,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz", - "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz", - "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", + "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", "cpu": [ "x64" ], @@ -3189,9 +3377,9 @@ } }, "node_modules/@vercel/nft": { - "version": "0.30.4", - "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.30.4.tgz", - "integrity": "sha512-wE6eAGSXScra60N2l6jWvNtVK0m+sh873CpfZW4KI2v8EHuUQp+mSEi4T+IcdPCSEDgCdAS/7bizbhQlkjzrSA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-1.2.0.tgz", + "integrity": "sha512-68326CAWJmd6P1cUgUmufor5d4ocPbpLxiy9TKG6U/a4aWEx9aC+NIzaDI6GmBZVpt3+MkO3OwnQ2YcgJg12Qw==", "license": "MIT", "dependencies": { "@mapbox/node-pre-gyp": "^2.0.0", @@ -3201,7 +3389,7 @@ "async-sema": "^3.1.1", "bindings": "^1.4.0", "estree-walker": "2.0.2", - "glob": "^10.5.0", + "glob": "^13.0.0", "graceful-fs": "^4.2.9", "node-gyp-build": "^4.2.2", "picomatch": "^4.0.2", @@ -3211,7 +3399,7 @@ "nft": "out/cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@vitejs/plugin-vue": { @@ -3251,9 +3439,9 @@ } }, "node_modules/@vitejs/plugin-vue-jsx/node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.58", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.58.tgz", - "integrity": "sha512-qWhDs6yFGR5xDfdrwiSa3CWGIHxD597uGE/A9xGqytBjANvh4rLCTTkq7szhMV4+Ygh+PMS90KVJ8xWG/TkX4w==", + "version": "1.0.0-beta.59", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.59.tgz", + "integrity": "sha512-aoh6LAJRyhtazs98ydgpNOYstxUlsOV1KJXcpf/0c0vFcUA8uyd/hwKRhqE/AAPNqAho9RliGsvitCoOzREoVA==", "license": "MIT" }, "node_modules/@volar/language-core": { @@ -3272,9 +3460,9 @@ "license": "MIT" }, "node_modules/@vue-macros/common": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-3.1.1.tgz", - "integrity": "sha512-afW2DMjgCBVs33mWRlz7YsGHzoEEupnl0DK5ZTKsgziAlLh5syc5m+GM7eqeYrgiQpwMaVxa1fk73caCvPxyAw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-3.1.2.tgz", + "integrity": "sha512-h9t4ArDdniO9ekYHAD95t9AZcAbb19lEGK+26iAjUODOIJKmObDNBSe4+6ELQAA3vtYiFPPBtHh7+cQCKi3Dng==", "license": "MIT", "dependencies": { "@vue/compiler-sfc": "^3.5.22", @@ -3466,9 +3654,9 @@ } }, "node_modules/@vue/language-core": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.2.1.tgz", - "integrity": "sha512-g6oSenpnGMtpxHGAwKuu7HJJkNZpemK/zg3vZzZbJ6cnnXq1ssxuNrXSsAHYM3NvH8p4IkTw+NLmuxyeYz4r8A==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.2.2.tgz", + "integrity": "sha512-5DAuhxsxBN9kbriklh3Q5AMaJhyOCNiQJvCskN9/30XOpdLiqZU9Q+WvjArP17ubdGEyZtBzlIeG5nIjEbNOrQ==", "license": "MIT", "dependencies": { "@volar/language-core": "2.4.27", @@ -3589,24 +3777,24 @@ "license": "MIT" }, "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=12" + "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" @@ -3682,6 +3870,26 @@ "node": ">= 14" } }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/archiver-utils/node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -3694,6 +3902,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/archiver-utils/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/archiver-utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ast-kit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz", @@ -3829,9 +4074,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "version": "2.9.14", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz", + "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -4027,9 +4272,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001762", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", - "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", + "version": "1.0.30001763", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001763.tgz", + "integrity": "sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==", "funding": [ { "type": "opencollective", @@ -4111,79 +4356,6 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/cluster-key-slot": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", @@ -4217,6 +4389,16 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "license": "MIT" }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -4844,9 +5026,9 @@ "license": "ISC" }, "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/encodeurl": { @@ -4945,6 +5127,22 @@ "@esbuild/win32-x64": "0.27.2" } }, + "node_modules/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -5279,20 +5477,17 @@ } }, "node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "license": "ISC", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", + "minimatch": "^10.1.1", "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "path-scurry": "^2.0.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5326,17 +5521,17 @@ } }, "node_modules/globby": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-15.0.0.tgz", - "integrity": "sha512-oB4vkQGqlMl682wL1IlWd02tXCbquGWM4voPEI85QmNKCaw8zGTm1f1rubFgkg3Eli2PtKlFgrnmUqasbQWlkw==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.1.0.tgz", + "integrity": "sha512-+A4Hq7m7Ze592k9gZRy4gJ27DrXRNnC1vPjxTt1qQxEY8RxagBkBxivkCwg7FxSTG0iLLEMaUx13oOr0R2/qcQ==", "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "fast-glob": "^3.3.3", "ignore": "^7.0.5", - "path-type": "^6.0.0", + "is-path-inside": "^4.0.0", "slash": "^5.1.0", - "unicorn-magic": "^0.3.0" + "unicorn-magic": "^0.4.0" }, "engines": { "node": ">=20" @@ -5541,12 +5736,12 @@ } }, "node_modules/ioredis": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.8.2.tgz", - "integrity": "sha512-C6uC+kleiIMmjViJINWk80sOQw5lEzse1ZmvD+S/s8p8CWapftSaC+kocGTx6xrbrJ4WmYQGC08ffHLr6ToR6Q==", + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.9.1.tgz", + "integrity": "sha512-BXNqFQ66oOsR82g9ajFFsR8ZKrjVvYCLyeML9IvSMAsP56XH2VXBdZjmI11p65nXXJxTEt1hie3J2QeFJVgrtQ==", "license": "MIT", "dependencies": { - "@ioredis/commands": "1.4.0", + "@ioredis/commands": "1.5.0", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", @@ -6069,6 +6264,7 @@ "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", @@ -6174,15 +6370,15 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -6295,617 +6491,6 @@ "integrity": "sha512-9ca1h0Xjvo9bEkE4UOxgAzLV0jHKe6LMaxo37ND2DAhhAtd0j8pR1Wxz+/goMrZO8AEZTWCmyaOsFI/W5AdpCQ==", "license": "MIT" }, - "node_modules/nitropack": { - "version": "2.12.9", - "resolved": "https://registry.npmjs.org/nitropack/-/nitropack-2.12.9.tgz", - "integrity": "sha512-t6qqNBn2UDGMWogQuORjbL2UPevB8PvIPsPHmqvWpeGOlPr4P8Oc5oA8t3wFwGmaolM2M/s2SwT23nx9yARmOg==", - "license": "MIT", - "dependencies": { - "@cloudflare/kv-asset-handler": "^0.4.0", - "@rollup/plugin-alias": "^5.1.1", - "@rollup/plugin-commonjs": "^28.0.9", - "@rollup/plugin-inject": "^5.0.5", - "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-node-resolve": "^16.0.3", - "@rollup/plugin-replace": "^6.0.2", - "@rollup/plugin-terser": "^0.4.4", - "@vercel/nft": "^0.30.3", - "archiver": "^7.0.1", - "c12": "^3.3.1", - "chokidar": "^4.0.3", - "citty": "^0.1.6", - "compatx": "^0.2.0", - "confbox": "^0.2.2", - "consola": "^3.4.2", - "cookie-es": "^2.0.0", - "croner": "^9.1.0", - "crossws": "^0.3.5", - "db0": "^0.3.4", - "defu": "^6.1.4", - "destr": "^2.0.5", - "dot-prop": "^10.1.0", - "esbuild": "^0.25.11", - "escape-string-regexp": "^5.0.0", - "etag": "^1.8.1", - "exsolve": "^1.0.7", - "globby": "^15.0.0", - "gzip-size": "^7.0.0", - "h3": "^1.15.4", - "hookable": "^5.5.3", - "httpxy": "^0.1.7", - "ioredis": "^5.8.2", - "jiti": "^2.6.1", - "klona": "^2.0.6", - "knitwork": "^1.2.0", - "listhen": "^1.9.0", - "magic-string": "^0.30.21", - "magicast": "^0.5.0", - "mime": "^4.1.0", - "mlly": "^1.8.0", - "node-fetch-native": "^1.6.7", - "node-mock-http": "^1.0.3", - "ofetch": "^1.5.0", - "ohash": "^2.0.11", - "pathe": "^2.0.3", - "perfect-debounce": "^2.0.0", - "pkg-types": "^2.3.0", - "pretty-bytes": "^7.1.0", - "radix3": "^1.1.2", - "rollup": "^4.52.5", - "rollup-plugin-visualizer": "^6.0.5", - "scule": "^1.3.0", - "semver": "^7.7.3", - "serve-placeholder": "^2.0.2", - "serve-static": "^2.2.0", - "source-map": "^0.7.6", - "std-env": "^3.10.0", - "ufo": "^1.6.1", - "ultrahtml": "^1.6.0", - "uncrypto": "^0.1.3", - "unctx": "^2.4.1", - "unenv": "^2.0.0-rc.23", - "unimport": "^5.5.0", - "unplugin-utils": "^0.3.1", - "unstorage": "^1.17.1", - "untyped": "^2.0.0", - "unwasm": "^0.3.11", - "youch": "^4.1.0-beta.11", - "youch-core": "^0.3.3" - }, - "bin": { - "nitro": "dist/cli/index.mjs", - "nitropack": "dist/cli/index.mjs" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "xml2js": "^0.6.2" - }, - "peerDependenciesMeta": { - "xml2js": { - "optional": true - } - } - }, - "node_modules/nitropack/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/nitropack/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/nitropack/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "node_modules/nitropack/node_modules/magicast": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", - "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "source-map-js": "^1.2.1" - } - }, - "node_modules/nitropack/node_modules/perfect-debounce": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz", - "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", - "license": "MIT" - }, - "node_modules/nitropack/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/nitropack/node_modules/unplugin-utils": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz", - "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", - "license": "MIT", - "dependencies": { - "pathe": "^2.0.3", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=20.19.0" - }, - "funding": { - "url": "https://github.com/sponsors/sxzz" - } - }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -7451,9 +7036,9 @@ } }, "node_modules/openai": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-6.15.0.tgz", - "integrity": "sha512-F1Lvs5BoVvmZtzkUEVyh8mDQPPFolq4F+xdsx/DO8Hee8YF3IGAlZqUIsF+DVGhqf4aU0a3bTghsxB6OIsRy1g==", + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.16.0.tgz", + "integrity": "sha512-fZ1uBqjFUjXzbGc35fFtYKEOxd20kd9fDpFeqWtsOZWiubY8CZ1NAlXHW3iathaFvqmNtCWMIsosCuyeI7Joxg==", "license": "Apache-2.0", "bin": { "openai": "bin/cli" @@ -7500,12 +7085,27 @@ "@oxc-minify/binding-win32-x64-msvc": "0.102.0" } }, + "node_modules/oxc-minify/node_modules/@oxc-minify/binding-win32-x64-msvc": { + "version": "0.102.0", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.102.0.tgz", + "integrity": "sha512-XdyJZdSMN8rbBXH10CrFuU+Q9jIP2+MnxHmNzjK4+bldbTI1UxqwjUMS9bKVC5VCaIEZhh8IE8x4Vf8gmCgrKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/oxc-parser": { "version": "0.102.0", "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.102.0.tgz", "integrity": "sha512-xMiyHgr2FZsphQ12ZCsXRvSYzmKXCm1ejmyG4GDZIiKOmhyt5iKtWq0klOfFsEQ6jcgbwrUdwcCVYzr1F+h5og==", "license": "MIT", - "peer": true, "dependencies": { "@oxc-project/types": "^0.102.0" }, @@ -7533,6 +7133,22 @@ "@oxc-parser/binding-win32-x64-msvc": "0.102.0" } }, + "node_modules/oxc-parser/node_modules/@oxc-parser/binding-win32-x64-msvc": { + "version": "0.102.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.102.0.tgz", + "integrity": "sha512-ntMcL35wuLR1A145rLSmm7m7j8JBZGkROoB9Du0KFIFcfi/w1qk75BdCeiTl3HAKrreAnuhW3QOGs6mJhntowA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/oxc-transform": { "version": "0.102.0", "resolved": "https://registry.npmjs.org/oxc-transform/-/oxc-transform-0.102.0.tgz", @@ -7562,6 +7178,22 @@ "@oxc-transform/binding-win32-x64-msvc": "0.102.0" } }, + "node_modules/oxc-transform/node_modules/@oxc-transform/binding-win32-x64-msvc": { + "version": "0.102.0", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.102.0.tgz", + "integrity": "sha512-eYOm6mch+1cP9qlNkMdorfBFY8aEOxY/isqrreLmEWqF/hyXA0SbLKDigTbvh3JFKny/gXlHoCKckqfua4cwtg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/oxc-walker": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/oxc-walker/-/oxc-walker-0.6.0.tgz", @@ -7639,37 +7271,28 @@ "license": "MIT" }, "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/path-type": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", - "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", - "license": "MIT", + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "20 || >=22" } }, "node_modules/pathe": { @@ -8571,9 +8194,9 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", - "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", + "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", "license": "MIT", "peer": true, "dependencies": { @@ -8587,28 +8210,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.54.0", - "@rollup/rollup-android-arm64": "4.54.0", - "@rollup/rollup-darwin-arm64": "4.54.0", - "@rollup/rollup-darwin-x64": "4.54.0", - "@rollup/rollup-freebsd-arm64": "4.54.0", - "@rollup/rollup-freebsd-x64": "4.54.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", - "@rollup/rollup-linux-arm-musleabihf": "4.54.0", - "@rollup/rollup-linux-arm64-gnu": "4.54.0", - "@rollup/rollup-linux-arm64-musl": "4.54.0", - "@rollup/rollup-linux-loong64-gnu": "4.54.0", - "@rollup/rollup-linux-ppc64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-musl": "4.54.0", - "@rollup/rollup-linux-s390x-gnu": "4.54.0", - "@rollup/rollup-linux-x64-gnu": "4.54.0", - "@rollup/rollup-linux-x64-musl": "4.54.0", - "@rollup/rollup-openharmony-arm64": "4.54.0", - "@rollup/rollup-win32-arm64-msvc": "4.54.0", - "@rollup/rollup-win32-ia32-msvc": "4.54.0", - "@rollup/rollup-win32-x64-gnu": "4.54.0", - "@rollup/rollup-win32-x64-msvc": "4.54.0", + "@rollup/rollup-android-arm-eabi": "4.55.1", + "@rollup/rollup-android-arm64": "4.55.1", + "@rollup/rollup-darwin-arm64": "4.55.1", + "@rollup/rollup-darwin-x64": "4.55.1", + "@rollup/rollup-freebsd-arm64": "4.55.1", + "@rollup/rollup-freebsd-x64": "4.55.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", + "@rollup/rollup-linux-arm-musleabihf": "4.55.1", + "@rollup/rollup-linux-arm64-gnu": "4.55.1", + "@rollup/rollup-linux-arm64-musl": "4.55.1", + "@rollup/rollup-linux-loong64-gnu": "4.55.1", + "@rollup/rollup-linux-loong64-musl": "4.55.1", + "@rollup/rollup-linux-ppc64-gnu": "4.55.1", + "@rollup/rollup-linux-ppc64-musl": "4.55.1", + "@rollup/rollup-linux-riscv64-gnu": "4.55.1", + "@rollup/rollup-linux-riscv64-musl": "4.55.1", + "@rollup/rollup-linux-s390x-gnu": "4.55.1", + "@rollup/rollup-linux-x64-gnu": "4.55.1", + "@rollup/rollup-linux-x64-musl": "4.55.1", + "@rollup/rollup-openbsd-x64": "4.55.1", + "@rollup/rollup-openharmony-arm64": "4.55.1", + "@rollup/rollup-win32-arm64-msvc": "4.55.1", + "@rollup/rollup-win32-ia32-msvc": "4.55.1", + "@rollup/rollup-win32-x64-gnu": "4.55.1", + "@rollup/rollup-win32-x64-msvc": "4.55.1", "fsevents": "~2.3.2" } }, @@ -8642,6 +8268,19 @@ } } }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", + "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/run-applescript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", @@ -8704,10 +8343,13 @@ "license": "MIT" }, "node_modules/sax": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz", - "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==", - "license": "BlueOak-1.0.0" + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } }, "node_modules/scule": { "version": "1.3.0", @@ -8959,9 +8601,9 @@ } }, "node_modules/srvx": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/srvx/-/srvx-0.9.8.tgz", - "integrity": "sha512-RZaxTKJEE/14HYn8COLuUOJAt0U55N9l1Xf6jj+T0GoA01EUH1Xz5JtSUOI+EHn+AEgPCVn7gk6jHJffrr06fQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/srvx/-/srvx-0.10.0.tgz", + "integrity": "sha512-NqIsR+wQCfkvvwczBh8J8uM4wTZx41K2lLSEp/3oMp917ODVVMtW5Me4epCmQ3gH8D+0b+/t4xxkUKutyhimTA==", "license": "MIT", "bin": { "srvx": "bin/srvx.mjs" @@ -9012,20 +8654,17 @@ } }, "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/string-width-cjs": { @@ -9043,22 +8682,7 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -9070,21 +8694,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", @@ -9098,15 +8707,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -9220,15 +8820,6 @@ "url": "https://opencollective.com/svgo" } }, - "node_modules/svgo/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, "node_modules/system-architecture": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/system-architecture/-/system-architecture-0.1.0.tgz", @@ -9446,9 +9037,9 @@ } }, "node_modules/ufo": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", - "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.2.tgz", + "integrity": "sha512-heMioaxBcG9+Znsda5Q8sQbWnLJSl98AFDXTO80wELWEzX3hordXsTdxrIfMQoO9IY1MEnoGoPjpoKpMj+Yx0Q==", "license": "MIT" }, "node_modules/ultrahtml": { @@ -9513,12 +9104,12 @@ } }, "node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9822,17 +9413,17 @@ } }, "node_modules/unwasm": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/unwasm/-/unwasm-0.3.11.tgz", - "integrity": "sha512-Vhp5gb1tusSQw5of/g3Q697srYgMXvwMgXMjcG4ZNga02fDX9coxJ9fAb0Ci38hM2Hv/U1FXRPGgjP2BYqhNoQ==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/unwasm/-/unwasm-0.5.2.tgz", + "integrity": "sha512-uWhB7IXQjMC4530uVAeu0lzvYK6P3qHVnmmdQniBi48YybOLN/DqEzcP9BRGk1YTDG3rRWRD8me55nIYoTHyMg==", "license": "MIT", "dependencies": { - "knitwork": "^1.2.0", - "magic-string": "^0.30.17", - "mlly": "^1.7.4", + "exsolve": "^1.0.8", + "knitwork": "^1.3.0", + "magic-string": "^0.30.21", + "mlly": "^1.8.0", "pathe": "^2.0.3", - "pkg-types": "^2.2.0", - "unplugin": "^2.3.6" + "pkg-types": "^2.3.0" } }, "node_modules/update-browserslist-db": { @@ -9878,9 +9469,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", - "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "license": "MIT", "peer": true, "dependencies": { @@ -10122,6 +9713,18 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/vite-plugin-checker/node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/vite-plugin-inspect": { "version": "11.3.3", "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-11.3.3.tgz", @@ -10331,17 +9934,17 @@ } }, "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -10365,66 +9968,10 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -10523,47 +10070,6 @@ "node": ">=12" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/youch": { "version": "4.1.0-beta.13", "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.13.tgz",