diff --git a/.gitignore b/.gitignore index dc11a8f5..02e8e113 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,9 @@ packages/api-schema/src/apis/ packages/api-schema/.cache/ +# superpowers design docs +docs/superpowers/ + # misc .DS_Store *.pem diff --git a/apps/admin/src/app/home-universities/page.tsx b/apps/admin/src/app/home-universities/page.tsx new file mode 100644 index 00000000..a364cda9 --- /dev/null +++ b/apps/admin/src/app/home-universities/page.tsx @@ -0,0 +1,10 @@ +import { RequireAdminSession } from "@/components/features/auth/RequireAdminSession"; +import { HomeUniversitiesPageContent } from "@/components/features/home-universities/HomeUniversitiesPageContent"; + +export default function HomeUniversitiesPage() { + return ( + + + + ); +} diff --git a/apps/admin/src/app/terms/page.tsx b/apps/admin/src/app/terms/page.tsx new file mode 100644 index 00000000..f44ac9cf --- /dev/null +++ b/apps/admin/src/app/terms/page.tsx @@ -0,0 +1,10 @@ +import { RequireAdminSession } from "@/components/features/auth/RequireAdminSession"; +import { TermsPageContent } from "@/components/features/terms/TermsPageContent"; + +export default function TermsPage() { + return ( + + + + ); +} diff --git a/apps/admin/src/app/univ-apply-infos/page.tsx b/apps/admin/src/app/univ-apply-infos/page.tsx new file mode 100644 index 00000000..1e975026 --- /dev/null +++ b/apps/admin/src/app/univ-apply-infos/page.tsx @@ -0,0 +1,10 @@ +import { RequireAdminSession } from "@/components/features/auth/RequireAdminSession"; +import { UnivApplyInfosPageContent } from "@/components/features/univ-apply-infos/UnivApplyInfosPageContent"; + +export default function UnivApplyInfosPage() { + return ( + + + + ); +} diff --git a/apps/admin/src/components/features/home-universities/HomeUniversitiesPageContent.tsx b/apps/admin/src/components/features/home-universities/HomeUniversitiesPageContent.tsx new file mode 100644 index 00000000..68169d9c --- /dev/null +++ b/apps/admin/src/components/features/home-universities/HomeUniversitiesPageContent.tsx @@ -0,0 +1,224 @@ +"use client"; + +import { keepPreviousData, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { type FormEvent, useState } from "react"; +import { toast } from "sonner"; +import { AdminLayout } from "@/components/layout/AdminLayout"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { adminApi, type HomeUniversityResponse } from "@/lib/api/admin"; + +export function HomeUniversitiesPageContent() { + const queryClient = useQueryClient(); + const [name, setName] = useState(""); + const [maxChoiceCount, setMaxChoiceCount] = useState(""); + const [editingId, setEditingId] = useState(null); + const [editingName, setEditingName] = useState(""); + const [editingMaxChoiceCount, setEditingMaxChoiceCount] = useState(""); + + const query = useQuery({ + queryKey: ["admin", "home-universities"], + queryFn: adminApi.getHomeUniversities, + placeholderData: keepPreviousData, + }); + + const universities = query.data ?? []; + + const invalidate = async () => { + await queryClient.invalidateQueries({ queryKey: ["admin", "home-universities"] }); + }; + + const createMutation = useMutation({ + mutationFn: adminApi.createHomeUniversity, + onSuccess: async () => { + await invalidate(); + setName(""); + setMaxChoiceCount(""); + toast.success("협정 대학을 생성했습니다."); + }, + onError: () => toast.error("협정 대학 생성에 실패했습니다."), + }); + + const updateMutation = useMutation({ + mutationFn: ({ id, ...data }: { id: number; name: string; maxChoiceCount: number }) => + adminApi.updateHomeUniversity(id, data), + onSuccess: async () => { + await invalidate(); + setEditingId(null); + toast.success("협정 대학을 수정했습니다."); + }, + onError: () => toast.error("협정 대학 수정에 실패했습니다."), + }); + + const deleteMutation = useMutation({ + mutationFn: adminApi.deleteHomeUniversity, + onSuccess: async () => { + await invalidate(); + toast.success("협정 대학을 삭제했습니다."); + }, + onError: () => toast.error("협정 대학 삭제에 실패했습니다."), + }); + + const handleCreate = (e: FormEvent) => { + e.preventDefault(); + const trimmedName = name.trim(); + const count = Number(maxChoiceCount); + if (!trimmedName || !Number.isInteger(count) || count < 1) { + toast.error("대학명과 최대 지망 수(1 이상)를 입력해주세요."); + return; + } + createMutation.mutate({ name: trimmedName, maxChoiceCount: count }); + }; + + const handleStartEdit = (univ: HomeUniversityResponse) => { + setEditingId(univ.id); + setEditingName(univ.name); + setEditingMaxChoiceCount(String(univ.maxChoiceCount)); + }; + + const handleUpdate = (id: number) => { + const trimmedName = editingName.trim(); + const count = Number(editingMaxChoiceCount); + if (!trimmedName || !Number.isInteger(count) || count < 1) { + toast.error("대학명과 최대 지망 수(1 이상)를 입력해주세요."); + return; + } + updateMutation.mutate({ id, name: trimmedName, maxChoiceCount: count }); + }; + + const handleDelete = (id: number, univName: string) => { + if (!window.confirm(`협정 대학 "${univName}"을 삭제할까요?`)) return; + deleteMutation.mutate(id); + }; + + const isMutating = createMutation.isPending || updateMutation.isPending || deleteMutation.isPending; + + return ( + + + + + + 협정 대학 + 예: 인하대학교 + + 총 {universities.length.toLocaleString()}건 + + + + setName(e.target.value)} placeholder="대학명" /> + setMaxChoiceCount(e.target.value)} + placeholder="최대 지망 수" + type="number" + min={1} + /> + + 생성 + + + + + + + + ID + 대학명 + 최대 지망 수 + 작업 + + + + {query.isLoading ? ( + + + 불러오는 중... + + + ) : query.isError ? ( + + + 협정 대학을 불러오지 못했습니다. + + + ) : universities.length === 0 ? ( + + + 협정 대학이 없습니다. + + + ) : ( + universities.map((univ) => { + const isEditing = editingId === univ.id; + return ( + + {univ.id} + + {isEditing ? ( + setEditingName(e.target.value)} /> + ) : ( + univ.name + )} + + + {isEditing ? ( + setEditingMaxChoiceCount(e.target.value)} + type="number" + min={1} + className="w-24" + /> + ) : ( + univ.maxChoiceCount + )} + + + {isEditing ? ( + + handleUpdate(univ.id)} disabled={isMutating}> + 저장 + + setEditingId(null)}> + 취소 + + + ) : ( + + handleStartEdit(univ)} + disabled={isMutating} + > + 수정 + + handleDelete(univ.id, univ.name)} + disabled={isMutating} + > + 삭제 + + + )} + + + ); + }) + )} + + + + + + + ); +} diff --git a/apps/admin/src/components/features/terms/TermsPageContent.tsx b/apps/admin/src/components/features/terms/TermsPageContent.tsx new file mode 100644 index 00000000..50ede6ad --- /dev/null +++ b/apps/admin/src/components/features/terms/TermsPageContent.tsx @@ -0,0 +1,157 @@ +"use client"; + +import { keepPreviousData, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { type FormEvent, useState } from "react"; +import { toast } from "sonner"; +import { AdminLayout } from "@/components/layout/AdminLayout"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { adminApi, type TermResponse } from "@/lib/api/admin"; +import { normalizeTermName } from "./termValidation"; + +const TERMS_QUERY_KEY = ["admin", "terms"] as const; + +export function TermsPageContent() { + const queryClient = useQueryClient(); + const [name, setName] = useState(""); + + const termsQuery = useQuery({ + queryKey: TERMS_QUERY_KEY, + queryFn: adminApi.getTerms, + placeholderData: keepPreviousData, + }); + + const invalidateTerms = async () => { + await queryClient.invalidateQueries({ queryKey: TERMS_QUERY_KEY }); + }; + + const createMutation = useMutation({ + mutationFn: adminApi.createTerm, + onSuccess: async () => { + await invalidateTerms(); + setName(""); + toast.success("학기를 생성했습니다."); + }, + onError: () => toast.error("학기 생성에 실패했습니다."), + }); + + const activateMutation = useMutation({ + mutationFn: adminApi.activateTerm, + onSuccess: async () => { + await invalidateTerms(); + toast.success("현재 학기를 변경했습니다."); + }, + onError: () => toast.error("현재 학기 설정에 실패했습니다."), + }); + + const handleCreate = (event: FormEvent) => { + event.preventDefault(); + const normalizedName = normalizeTermName(name); + + if (!normalizedName) { + toast.error("학기 이름은 2026-1 형식으로 입력해주세요."); + return; + } + + createMutation.mutate({ name: normalizedName }); + }; + + const handleActivate = (term: TermResponse) => { + const confirmed = window.confirm(`"${term.label}" 학기를 현재 학기로 설정할까요?`); + if (!confirmed) return; + + activateMutation.mutate(term.id); + }; + + const terms = termsQuery.data ?? []; + const isMutating = createMutation.isPending || activateMutation.isPending; + + return ( + + + + + + 학기 + 예: 2026-1 + + 총 {terms.length.toLocaleString()}건 + + + + setName(event.target.value)} + placeholder="2026-1" + aria-label="학기 이름" + /> + + 생성 + + + + + + + + ID + 학기 + 상태 + 작업 + + + + {termsQuery.isLoading ? ( + + + 불러오는 중... + + + ) : termsQuery.isError ? ( + + + 학기 목록을 불러오지 못했습니다. + + + ) : terms.length === 0 ? ( + + + 등록된 학기가 없습니다. + + + ) : ( + terms.map((term) => ( + + {term.id} + {term.label} + + {term.isCurrent ? ( + + 현재 학기 + + ) : ( + "-" + )} + + + handleActivate(term)} + disabled={term.isCurrent || isMutating} + > + {term.isCurrent ? "현재 학기" : "현재 학기로 설정"} + + + + )) + )} + + + + + + + ); +} diff --git a/apps/admin/src/components/features/terms/termValidation.test.ts b/apps/admin/src/components/features/terms/termValidation.test.ts new file mode 100644 index 00000000..9e91dd80 --- /dev/null +++ b/apps/admin/src/components/features/terms/termValidation.test.ts @@ -0,0 +1,12 @@ +import { describe, expect, it } from "vitest"; +import { normalizeTermName } from "./termValidation"; + +describe("normalizeTermName", () => { + it("trims and accepts YYYY-N term names", () => { + expect(normalizeTermName(" 2026-1 ")).toBe("2026-1"); + }); + + it.each(["", "2026", "26-1", "2026-10"])("rejects %s", (value) => { + expect(normalizeTermName(value)).toBeNull(); + }); +}); diff --git a/apps/admin/src/components/features/terms/termValidation.ts b/apps/admin/src/components/features/terms/termValidation.ts new file mode 100644 index 00000000..d372b2f6 --- /dev/null +++ b/apps/admin/src/components/features/terms/termValidation.ts @@ -0,0 +1,6 @@ +const TERM_NAME_PATTERN = /^\d{4}-\d$/; + +export function normalizeTermName(value: string): string | null { + const normalized = value.trim(); + return TERM_NAME_PATTERN.test(normalized) ? normalized : null; +} diff --git a/apps/admin/src/components/features/univ-apply-infos/UnivApplyInfosPageContent.tsx b/apps/admin/src/components/features/univ-apply-infos/UnivApplyInfosPageContent.tsx new file mode 100644 index 00000000..0bacef31 --- /dev/null +++ b/apps/admin/src/components/features/univ-apply-infos/UnivApplyInfosPageContent.tsx @@ -0,0 +1,441 @@ +"use client"; + +import { useMutation, useQuery } from "@tanstack/react-query"; +import { type FormEvent, useId, useState } from "react"; +import { toast } from "sonner"; +import { AdminLayout } from "@/components/layout/AdminLayout"; +import { Button } from "@/components/ui/button"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { Textarea } from "@/components/ui/textarea"; +import { adminApi, type UnivApplyInfoImportResponse } from "@/lib/api/admin"; +import { preprocessMarkdownCountryCodes } from "./countryCodeAliases"; +import { findFieldByHeader, UNIV_APPLY_INFO_FIELDS } from "./univApplyInfoFields"; +import { canConfirmUnivApplyInfoImport } from "./univApplyInfoImportGuard"; +import { buildPreviewRows, getPreviewCellError, parseMarkdownRow } from "./univApplyInfoPreview"; +import { validatePreviewRows } from "./univApplyInfoValidation"; + +function extractMarkdownHeaders(markdown: string): string[] { + const lines = markdown.trim().split("\n"); + if (lines.length < 2) return []; + const separatorPattern = /^\|[-| :]+\|$/; + if (!separatorPattern.test(lines[1].trim())) return []; + return parseMarkdownRow(lines[0]).filter((h) => h.length > 0); +} + +function buildAutoMappings(headers: string[], languageTestTypes: string[]): Record { + const mappings: Record = {}; + for (const header of headers) { + const field = findFieldByHeader(header); + if (field) { + mappings[header] = field; + continue; + } + if (languageTestTypes.includes(header)) { + mappings[header] = header; + } + } + return mappings; +} + +export function UnivApplyInfosPageContent() { + const homeUniversitySelectId = useId(); + const termSelectId = useId(); + + const [homeUniversityId, setHomeUniversityId] = useState(""); + const [termId, setTermId] = useState(""); + const [markdown, setMarkdown] = useState(""); + const [parsedHeaders, setParsedHeaders] = useState([]); + const [columnMappings, setColumnMappings] = useState>({}); + const [importResult, setImportResult] = useState(null); + const [showPreviewModal, setShowPreviewModal] = useState(false); + + const homeUniversitiesQuery = useQuery({ + queryKey: ["admin", "home-universities"], + queryFn: adminApi.getHomeUniversities, + }); + + const termsQuery = useQuery({ + queryKey: ["admin", "terms"], + queryFn: adminApi.getTerms, + }); + + const fieldsQuery = useQuery({ + queryKey: ["admin", "univ-apply-info-fields"], + queryFn: adminApi.getUnivApplyInfoFields, + staleTime: Number.POSITIVE_INFINITY, + }); + + const importMutation = useMutation({ + mutationFn: adminApi.importUnivApplyInfos, + onSuccess: (data) => { + setShowPreviewModal(false); + setImportResult(data); + toast.success(`${data.successCount}건 모두 추가됐습니다.`); + }, + onError: () => toast.error("지원 대학 추가에 실패했습니다."), + }); + + const handleMarkdownChange = (e: React.ChangeEvent) => { + setMarkdown(e.target.value); + if (parsedHeaders.length > 0) { + setParsedHeaders([]); + setColumnMappings({}); + setImportResult(null); + } + }; + + const handleParse = () => { + const headers = extractMarkdownHeaders(markdown); + if (headers.length === 0) { + toast.error("마크다운 헤더를 파싱할 수 없습니다. 형식을 확인해주세요."); + return; + } + const auto = buildAutoMappings(headers, fieldsQuery.data?.languageTestTypes ?? []); + setParsedHeaders(headers); + setColumnMappings(auto); + setImportResult(null); + }; + + const handleImport = (e: FormEvent) => { + e.preventDefault(); + const univId = Number(homeUniversityId); + const term = Number(termId); + if (!univId || !term) { + toast.error("협정 대학과 학기를 선택해주세요."); + return; + } + if (!markdown.trim()) { + toast.error("마크다운을 입력해주세요."); + return; + } + if (parsedHeaders.length === 0) { + toast.error("먼저 [파싱] 버튼을 눌러 컬럼을 확인해주세요."); + return; + } + setShowPreviewModal(true); + }; + + const handleConfirmImport = () => { + if (!canConfirmImport) { + if (previewRows.length === 0) { + toast.error("추가할 지원 대학이 없습니다."); + } + return; + } + + const processedMarkdown = preprocessMarkdownCountryCodes(markdown.trim(), columnMappings); + importMutation.mutate({ + homeUniversityId: Number(homeUniversityId), + termId: Number(termId), + markdown: processedMarkdown, + columnMappings, + }); + }; + + const universities = homeUniversitiesQuery.data ?? []; + const terms = termsQuery.data ?? []; + const fields = fieldsQuery.data; + + const mappedFieldSet = new Set(Object.values(columnMappings).filter(Boolean)); + const previewColumns: { field: string; label: string; required: boolean; mapped: boolean }[] = [ + // 필수 필드: 매핑 여부와 관계없이 항상 표시 + ...UNIV_APPLY_INFO_FIELDS.filter((f) => f.required).map((f) => ({ + field: f.field, + label: f.label, + required: true, + mapped: mappedFieldSet.has(f.field), + })), + // 비필수 시스템 필드: 매핑된 경우에만 표시 + ...UNIV_APPLY_INFO_FIELDS.filter((f) => !f.required && mappedFieldSet.has(f.field)).map((f) => ({ + field: f.field, + label: f.label, + required: false, + mapped: true, + })), + // 언어 시험 타입 컬럼 + ...[...mappedFieldSet] + .filter((f) => !UNIV_APPLY_INFO_FIELDS.some((sf) => sf.field === f)) + .map((f) => ({ field: f, label: f, required: false, mapped: true })), + ]; + const previewRows = showPreviewModal ? buildPreviewRows(markdown.trim(), columnMappings) : []; + const clientCellErrors = validatePreviewRows(previewRows); + // key format: "rowNumber:field:fieldName" — rowNumber is always the first segment + const clientErrorRowNumbers = new Set([...clientCellErrors.keys()].map((k) => Number(k.split(":")[0]))); + const failedCellMessages = clientCellErrors; + const canConfirmImport = canConfirmUnivApplyInfoImport({ + previewRowCount: previewRows.length, + clientErrorCount: clientCellErrors.size, + isPending: importMutation.isPending, + }); + + return ( + + + {/* ① 기본 정보 */} + + ① 기본 정보 + + + + 협정 대학 + + setHomeUniversityId(e.target.value)} + className="h-9 w-full rounded-md border border-k-200 bg-k-0 px-3 typo-regular-4 text-k-700 outline-none focus-visible:border-primary" + > + 협정 대학 선택 + {universities.map((u) => ( + + {u.name} + + ))} + + {homeUniversitiesQuery.isLoading && 불러오는 중...} + {homeUniversitiesQuery.isError && ( + 협정 대학을 불러오지 못했습니다. + )} + + + + 학기 + + setTermId(e.target.value)} + className="h-9 w-full rounded-md border border-k-200 bg-k-0 px-3 typo-regular-4 text-k-700 outline-none focus-visible:border-primary" + > + 학기 선택 + {terms.map((t) => ( + + {t.label} + + ))} + + {termsQuery.isLoading && 불러오는 중...} + {termsQuery.isError && ( + 학기 목록을 불러오지 못했습니다. + )} + + + + + {/* ② 마크다운 입력 */} + + ② 마크다운 입력 + 파이프(|)로 구분된 마크다운 테이블을 붙여넣으세요. + + + 파싱 + + {fieldsQuery.isError && ( + + 필드 정보를 불러오지 못해 자동 매핑이 비활성화됩니다. + + )} + + + {/* ③ 컬럼 매핑 */} + {parsedHeaders.length > 0 && ( + + ③ 컬럼 매핑 + + + + + 시스템 필드 + 마크다운 컬럼 + + + + {UNIV_APPLY_INFO_FIELDS.map((f) => { + const mappedHeader = Object.entries(columnMappings).find(([, v]) => v === f.field)?.[0] ?? ""; + const nonLangHeaders = parsedHeaders.filter( + (h) => !(fields?.languageTestTypes.includes(h) ?? false), + ); + return ( + + {f.label} + + { + const newHeader = e.target.value; + setColumnMappings((prev) => { + const next = { ...prev }; + const oldHeader = Object.entries(next).find(([, v]) => v === f.field)?.[0]; + if (oldHeader) delete next[oldHeader]; + if (newHeader) next[newHeader] = f.field; + return next; + }); + }} + className="h-9 min-w-[220px] rounded-md border border-k-200 bg-k-0 px-3 typo-regular-4 text-k-700 outline-none focus-visible:border-primary" + > + — 매핑 안 함 — + {nonLangHeaders.map((h) => ( + + {h} + + ))} + + + + ); + })} + {parsedHeaders + .filter((h) => fields?.languageTestTypes.includes(h) ?? false) + .map((header) => ( + + 언어 시험 타입 + + + {header} + + + + ))} + + + + + )} + + {/* ④ 임포트 버튼 */} + {parsedHeaders.length > 0 && ( + + 지원 대학 추가 + + )} + + + {/* ⑤ 결과 */} + {importResult && ( + + 결과 + + 성공 {importResult.successCount}건 + + {importResult.createdUniversities.length > 0 && ( + + 신규 등록된 대학 {importResult.createdUniversities.length}개 + + {importResult.createdUniversities.map((name) => ( + + {name} + + ))} + + + )} + + )} + + {/* 임포트 미리보기 모달 */} + {showPreviewModal && ( + + setShowPreviewModal(false)} + /> + + {/* 모달 헤더 */} + + + 임포트 미리보기 + + 총 {previewRows.length}개 대학 + {clientErrorRowNumbers.size > 0 && ( + 오류 {clientErrorRowNumbers.size}행 + )} + + + setShowPreviewModal(false)} + className="typo-regular-4 text-k-400 hover:text-k-700" + > + ✕ + + + + {/* 모달 테이블 */} + + + + + # + {previewColumns.map((col) => ( + + {col.label} + + ))} + + + + {previewRows.map((row) => ( + + {row.rowNumber} + {previewColumns.map((col) => { + const cell = row.cellsByField[col.field]; + const cellError = getPreviewCellError(failedCellMessages, row, col.field); + return ( + + + {cell?.value ?? "—"} + + {cellError && {cellError}} + + ); + })} + + ))} + + + + + {/* 모달 푸터 */} + + setShowPreviewModal(false)}> + 취소 + + + {importMutation.isPending ? "추가 중..." : "추가"} + + + + + )} + + ); +} diff --git a/apps/admin/src/components/features/univ-apply-infos/countryCodeAliases.ts b/apps/admin/src/components/features/univ-apply-infos/countryCodeAliases.ts new file mode 100644 index 00000000..4633d0df --- /dev/null +++ b/apps/admin/src/components/features/univ-apply-infos/countryCodeAliases.ts @@ -0,0 +1,47 @@ +import { COUNTRY_CODE_BY_NAME } from "./countryCodeConstants"; + +export function resolveCountryCode(value: string): string { + return COUNTRY_CODE_BY_NAME[value.trim()] ?? value; +} + +export function isValidCountryCode(resolvedValue: string): boolean { + return /^[A-Z]{2}$/.test(resolvedValue); +} + +function parseMarkdownRow(line: string): string[] { + let stripped = line.trim(); + if (stripped.startsWith("|")) stripped = stripped.slice(1); + if (stripped.endsWith("|")) stripped = stripped.slice(0, -1); + return stripped.split("|").map((cell) => cell.trim()); +} + +export function preprocessMarkdownCountryCodes(markdown: string, columnMappings: Record): string { + const lines = markdown.trim().split("\n"); + if (lines.length < 3) return markdown; + + const headers = parseMarkdownRow(lines[0]); + + const countryCodeIndices = headers.reduce((acc, header, i) => { + if (columnMappings[header] === "universityCountryCode") acc.push(i); + return acc; + }, []); + + if (countryCodeIndices.length === 0) return markdown; + + const ESCAPED_PIPE = "\x00"; + const processedLines = lines.map((line, lineIndex) => { + if (lineIndex === 0 || lineIndex === 1) return line; + const hasLeadingPipe = line.trim().startsWith("|"); + const cells = line.replace(/\\\|/g, ESCAPED_PIPE).split("|"); + countryCodeIndices.forEach((colIndex) => { + const cellIndex = hasLeadingPipe ? colIndex + 1 : colIndex; + if (cells[cellIndex] !== undefined) { + const cellValue = cells[cellIndex].replaceAll(ESCAPED_PIPE, "|").trim(); + cells[cellIndex] = ` ${resolveCountryCode(cellValue)} `; + } + }); + return cells.map((c) => c.replaceAll(ESCAPED_PIPE, "\\|")).join("|"); + }); + + return processedLines.join("\n"); +} diff --git a/apps/admin/src/components/features/univ-apply-infos/countryCodeConstants.ts b/apps/admin/src/components/features/univ-apply-infos/countryCodeConstants.ts new file mode 100644 index 00000000..1b73fc4a --- /dev/null +++ b/apps/admin/src/components/features/univ-apply-infos/countryCodeConstants.ts @@ -0,0 +1,107 @@ +export const COUNTRY_CODE_BY_NAME: Record = { + // 한국어 + 오스트리아: "AT", + 호주: "AU", + 아제르바이잔: "AZ", + 벨기에: "BE", + 브루나이: "BN", + 브라질: "BR", + 캐나다: "CA", + 콜롬비아: "CO", + 스위스: "CH", + 중국: "CN", + 체코: "CZ", + 에스토니아: "EE", + 독일: "DE", + 덴마크: "DK", + 스페인: "ES", + 핀란드: "FI", + 프랑스: "FR", + 영국: "GB", + 아일랜드: "IE", + 홍콩: "HK", + 헝가리: "HU", + 인도네시아: "ID", + 이스라엘: "IL", + 이탈리아: "IT", + 일본: "JP", + 카자흐스탄: "KZ", + 리투아니아: "LT", + 마카오: "MO", + 모로코: "MA", + 말레이시아: "MY", + 멕시코: "MX", + 네덜란드: "NL", + 뉴질랜드: "NZ", + 노르웨이: "NO", + 폴란드: "PL", + 포르투갈: "PT", + 루마니아: "RO", + 러시아: "RU", + 스웨덴: "SE", + 싱가포르: "SG", + 슬로베니아: "SI", + 태국: "TH", + 튀르키예: "TR", + 대만: "TW", + 우루과이: "UY", + 미국: "US", + 베트남: "VN", + 우즈베키스탄: "UZ", + // 영어 풀 네임 + Austria: "AT", + Australia: "AU", + Azerbaijan: "AZ", + Belgium: "BE", + Brunei: "BN", + Brazil: "BR", + Canada: "CA", + Colombia: "CO", + Switzerland: "CH", + China: "CN", + "Czech Republic": "CZ", + Czechia: "CZ", + Czech: "CZ", + Estonia: "EE", + Germany: "DE", + Denmark: "DK", + Spain: "ES", + Finland: "FI", + France: "FR", + "United Kingdom": "GB", + UK: "GB", + "Hong Kong": "HK", + Hungary: "HU", + Ireland: "IE", + Indonesia: "ID", + Israel: "IL", + Italy: "IT", + Japan: "JP", + Kazakhstan: "KZ", + Lithuania: "LT", + Malaysia: "MY", + Netherlands: "NL", + Norway: "NO", + Portugal: "PT", + Russia: "RU", + Sweden: "SE", + Singapore: "SG", + Thailand: "TH", + Macau: "MO", + Morocco: "MA", + Mexico: "MX", + "New Zealand": "NZ", + Poland: "PL", + Romania: "RO", + Slovenia: "SI", + Turkey: "TR", + Türkiye: "TR", + Turkiye: "TR", + Taiwan: "TW", + Uruguay: "UY", + "United States": "US", + USA: "US", + Vietnam: "VN", + Uzbekistan: "UZ", + "Mainland China": "CN", +}; diff --git a/apps/admin/src/components/features/univ-apply-infos/univApplyInfoFields.test.ts b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoFields.test.ts new file mode 100644 index 00000000..3ba02564 --- /dev/null +++ b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoFields.test.ts @@ -0,0 +1,23 @@ +import { describe, expect, it } from "vitest"; +import { findFieldByHeader, UNIV_APPLY_INFO_FIELDS } from "./univApplyInfoFields"; + +describe("univApplyInfoFields", () => { + it("contains only required system fields", () => { + expect(UNIV_APPLY_INFO_FIELDS.every((field) => field.required)).toBe(true); + }); + + it("matches required field labels and whitespace variants", () => { + expect(findFieldByHeader("국가 코드")).toBe("universityCountryCode"); + expect(findFieldByHeader("국가코드")).toBe("universityCountryCode"); + expect(findFieldByHeader("선발 인원")).toBe("studentCapacity"); + expect(findFieldByHeader("파견 가능 학기")).toBe("semesterAvailableForDispatch"); + }); + + it("does not match optional headers that should be stored in extraInfo", () => { + const extraInfoHeaders = ["등록금유형", "지원사항", "전공사항", "영어강좌", "비고", "표기명"]; + + for (const header of extraInfoHeaders) { + expect(findFieldByHeader(header)).toBeUndefined(); + } + }); +}); diff --git a/apps/admin/src/components/features/univ-apply-infos/univApplyInfoFields.ts b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoFields.ts new file mode 100644 index 00000000..33abffb9 --- /dev/null +++ b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoFields.ts @@ -0,0 +1,43 @@ +export const UNIV_APPLY_INFO_FIELDS = [ + { field: "universityKoreanName", label: "대학명 (국문)", required: true, aliases: ["대학명", "학교명", "대학교명"] }, + { field: "universityEnglishName", label: "대학명 (영문)", required: true, aliases: ["영문명", "영어명"] }, + { field: "universityCountryCode", label: "국가", required: true, aliases: ["국가코드"] }, + { field: "studentCapacity", label: "선발 인원", required: true, aliases: ["인원", "모집인원", "정원", "모집정원"] }, + { + field: "semesterAvailableForDispatch", + label: "파견 가능 학기", + required: true, + aliases: ["파견가능학기", "파견학기"], + }, + { field: "semesterRequirement", label: "최저 이수학기", required: true, aliases: ["학기요건", "재학학기"] }, + { field: "gpaRequirement", label: "최저 성적 요건", required: true, aliases: ["성적요건", "학점요건", "최소학점"] }, + { field: "gpaRequirementCriteria", label: "성적 기준", required: true, aliases: ["학점기준", "성적기준"] }, + { + field: "detailsForLanguage", + label: "어학 세부 요건", + required: true, + aliases: ["어학사항", "어학요건상세", "어학요건"], + }, + { field: "detailsForAccommodation", label: "기숙사", required: true, aliases: ["숙소사항", "기숙사안내"] }, + { + field: "universityHomepageUrl", + label: "관련 홈페이지", + required: false, + aliases: ["홈페이지", "대학홈페이지", "관련홈페이지"], + }, +] as const; + +export type UnivApplyInfoFieldName = (typeof UNIV_APPLY_INFO_FIELDS)[number]["field"]; + +function normalizeHeader(header: string): string { + return header.replace(/\s+/g, "").trim(); +} + +export function findFieldByHeader(header: string): UnivApplyInfoFieldName | undefined { + const normalizedHeader = normalizeHeader(header); + const matched = UNIV_APPLY_INFO_FIELDS.find((f) => { + const candidates = [f.field, f.label, ...f.aliases]; + return candidates.some((candidate) => candidate === header || normalizeHeader(candidate) === normalizedHeader); + }); + return matched?.field; +} diff --git a/apps/admin/src/components/features/univ-apply-infos/univApplyInfoImportGuard.ts b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoImportGuard.ts new file mode 100644 index 00000000..c9233b9f --- /dev/null +++ b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoImportGuard.ts @@ -0,0 +1,13 @@ +interface CanConfirmUnivApplyInfoImportParams { + previewRowCount: number; + clientErrorCount: number; + isPending: boolean; +} + +export function canConfirmUnivApplyInfoImport({ + previewRowCount, + clientErrorCount, + isPending, +}: CanConfirmUnivApplyInfoImportParams): boolean { + return previewRowCount > 0 && clientErrorCount === 0 && !isPending; +} diff --git a/apps/admin/src/components/features/univ-apply-infos/univApplyInfoPreview.ts b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoPreview.ts new file mode 100644 index 00000000..8a9ba011 --- /dev/null +++ b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoPreview.ts @@ -0,0 +1,61 @@ +import { preprocessMarkdownCountryCodes } from "./countryCodeAliases"; + +export interface PreviewCell { + header: string; + field: string; + value: string; +} + +export interface PreviewRow { + rowNumber: number; + cellsByField: Record; +} + +export function parseMarkdownRow(line: string): string[] { + const ESCAPED_PIPE = "\x00"; + let stripped = line.trim().replace(/\\\|/g, ESCAPED_PIPE); + if (stripped.startsWith("|")) stripped = stripped.slice(1); + if (stripped.endsWith("|")) stripped = stripped.slice(0, -1); + return stripped.split("|").map((cell) => cell.trim().replaceAll(ESCAPED_PIPE, "|")); +} + +export function buildPreviewRows(markdown: string, columnMappings: Record): PreviewRow[] { + const processed = preprocessMarkdownCountryCodes(markdown, columnMappings); + const lines = processed.trim().split("\n"); + if (lines.length < 3) return []; + + const rawHeaders = parseMarkdownRow(lines[0]); + + return lines.slice(2).map((line, rowIndex) => { + const cells = parseMarkdownRow(line); + const row: PreviewRow = { + rowNumber: rowIndex + 1, + cellsByField: {}, + }; + + rawHeaders.forEach((header, i) => { + const field = columnMappings[header]; + if (field && cells[i] !== undefined) { + row.cellsByField[field] = { + header, + field, + value: cells[i], + }; + } + }); + + return row; + }); +} + +export function getPreviewCellError( + failedCellMessages: Map, + row: PreviewRow, + field: string, +): string | undefined { + const cell = row.cellsByField[field]; + return ( + failedCellMessages.get(`${row.rowNumber}:field:${field}`) ?? + (cell?.header ? failedCellMessages.get(`${row.rowNumber}:header:${cell.header}`) : undefined) + ); +} diff --git a/apps/admin/src/components/features/univ-apply-infos/univApplyInfoValidation.ts b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoValidation.ts new file mode 100644 index 00000000..a75ee8fa --- /dev/null +++ b/apps/admin/src/components/features/univ-apply-infos/univApplyInfoValidation.ts @@ -0,0 +1,133 @@ +import { isValidCountryCode } from "./countryCodeAliases"; +import { UNIV_APPLY_INFO_FIELDS } from "./univApplyInfoFields"; +import type { PreviewRow } from "./univApplyInfoPreview"; + +const TUITION_FEE_TYPES = ["HOME_UNIVERSITY_PAYMENT", "OVERSEAS_UNIVERSITY_PAYMENT", "MIXED_PAYMENT"] as const; + +const SEMESTER_AVAILABLE_FOR_DISPATCH_VALUES = [ + "ONE_SEMESTER", + "TWO_SEMESTER", + "FOUR_SEMESTER", + "ONE_OR_TWO_SEMESTER", + "ONE_YEAR", + "IRRELEVANT", + "NO_DATA", +] as const; + +type FieldRule = + | { type: "required"; message: string } + | { type: "maxLength"; max: number } + | { type: "integer"; message: string } + | { type: "enum"; values: readonly string[]; label: string } + | { type: "format"; check: (v: string) => boolean; message: string }; + +const FIELD_RULES: Record = { + universityKoreanName: [ + { type: "required", message: "대학명은 필수입니다" }, + { type: "maxLength", max: 100 }, + ], + universityEnglishName: [{ type: "maxLength", max: 200 }], + universityFormatName: [{ type: "maxLength", max: 100 }], + universityHomepageUrl: [{ type: "maxLength", max: 500 }], + universityEnglishCourseUrl: [{ type: "maxLength", max: 500 }], + universityAccommodationUrl: [{ type: "maxLength", max: 500 }], + universityDetailsForLocal: [{ type: "maxLength", max: 1000 }], + studentCapacity: [{ type: "integer", message: "선발 인원은 정수여야 합니다" }], + tuitionFeeType: [{ type: "enum", values: TUITION_FEE_TYPES, label: "등록금 유형" }], + semesterAvailableForDispatch: [ + { + type: "enum", + values: SEMESTER_AVAILABLE_FOR_DISPATCH_VALUES, + label: "파견 가능 학기", + }, + ], + semesterRequirement: [{ type: "maxLength", max: 100 }], + gpaRequirement: [{ type: "maxLength", max: 100 }], + gpaRequirementCriteria: [{ type: "maxLength", max: 100 }], + detailsForLanguage: [{ type: "maxLength", max: 2000 }], + detailsForApply: [{ type: "maxLength", max: 3000 }], + detailsForMajor: [{ type: "maxLength", max: 3000 }], + detailsForAccommodation: [{ type: "maxLength", max: 2000 }], + detailsForEnglishCourse: [{ type: "maxLength", max: 1000 }], + details: [{ type: "maxLength", max: 3000 }], + universityCountryCode: [ + { + type: "format", + check: isValidCountryCode, + message: "유효하지 않은 국가 코드입니다", + }, + ], +}; + +const REQUIRED_FIELDS = UNIV_APPLY_INFO_FIELDS.filter((field) => field.required); + +function getRequiredFieldMessage(label: string): string { + return `필수 필드입니다: ${label}`; +} + +function validateCell(value: string, rules: FieldRule[]): string | undefined { + for (const rule of rules) { + const trimmed = value.trim(); + + if (rule.type === "required") { + if (!trimmed) return rule.message; + continue; + } + + if (!trimmed) continue; + + if (rule.type === "maxLength") { + if (trimmed.length > rule.max) { + return `값이 최대 길이(${rule.max}자)를 초과했습니다: ${trimmed.length}자`; + } + } else if (rule.type === "integer") { + if (!/^\d+$/.test(trimmed)) { + return `${rule.message}: '${value}'`; + } + } else if (rule.type === "enum") { + if (!rule.values.includes(trimmed)) { + return `유효하지 않은 ${rule.label}입니다. 가능한 값: ${rule.values.join(", ")}`; + } + } else if (rule.type === "format") { + if (!rule.check(trimmed)) { + return rule.message; + } + } + } + return undefined; +} + +export function validatePreviewRows(rows: PreviewRow[]): Map { + const errors = new Map(); + + for (const row of rows) { + for (const field of REQUIRED_FIELDS) { + const cell = row.cellsByField[field.field]; + if (!cell?.value.trim()) { + errors.set(`${row.rowNumber}:field:${field.field}`, getRequiredFieldMessage(field.label)); + } + } + + for (const [field, cell] of Object.entries(row.cellsByField)) { + const rules = FIELD_RULES[field]; + if (!rules) continue; + if (errors.has(`${row.rowNumber}:field:${field}`)) continue; + const message = validateCell(cell.value, rules); + if (message) { + errors.set(`${row.rowNumber}:field:${field}`, message); + } + } + } + + return errors; +} + +export function mergeErrorMaps(...maps: Map[]): Map { + const merged = new Map(); + for (const map of maps) { + for (const [key, value] of map) { + merged.set(key, value); + } + } + return merged; +} diff --git a/apps/admin/src/components/layout/AdminSidebar.tsx b/apps/admin/src/components/layout/AdminSidebar.tsx index d4aadf8a..20d620d3 100644 --- a/apps/admin/src/components/layout/AdminSidebar.tsx +++ b/apps/admin/src/components/layout/AdminSidebar.tsx @@ -1,12 +1,32 @@ -import { FileText, FlaskConical, MapPinned, MessageSquare, UserCheck } from "lucide-react"; +import { + Building2, + CalendarDays, + FileText, + FlaskConical, + MapPinned, + MessageSquare, + PlusCircle, + UserCheck, +} from "lucide-react"; import { cn } from "@/lib/utils"; -export type ActiveAdminMenu = "scores" | "mentorApplications" | "regionsCountries" | "bruno" | "chatSocket"; +export type ActiveAdminMenu = + | "scores" + | "mentorApplications" + | "regionsCountries" + | "homeUniversities" + | "terms" + | "univApplyInfos" + | "bruno" + | "chatSocket"; const sideMenus = [ { key: "scores", label: "성적 관리", icon: FileText, to: "/scores" as const }, { key: "mentorApplications", label: "멘토 승격 요청", icon: UserCheck, to: "/mentor-applications" as const }, { key: "regionsCountries", label: "권역/지역 관리", icon: MapPinned, to: "/regions-countries" as const }, + { key: "homeUniversities", label: "협정 대학 관리", icon: Building2, to: "/home-universities" as const }, + { key: "terms", label: "학기 관리", icon: CalendarDays, to: "/terms" as const }, + { key: "univApplyInfos", label: "지원 대학 추가", icon: PlusCircle, to: "/univ-apply-infos" as const }, { key: "bruno", label: "Bruno API", icon: FlaskConical, to: "/bruno" as const }, { key: "chatSocket", label: "채팅 소켓", icon: MessageSquare, to: "/chat-socket" as const }, ] as const; diff --git a/apps/admin/src/lib/api/admin.ts b/apps/admin/src/lib/api/admin.ts index 6ebad569..882d928a 100644 --- a/apps/admin/src/lib/api/admin.ts +++ b/apps/admin/src/lib/api/admin.ts @@ -62,11 +62,63 @@ export interface CountryPayload { regionCode: string; } +export interface HomeUniversityResponse { + id: number; + name: string; + maxChoiceCount: number; +} + +export interface HomeUniversityPayload { + name: string; + maxChoiceCount: number; +} + +export interface TermResponse { + id: number; + label: string; + isCurrent: boolean; +} + +interface AdminTermApiResponse { + id: number; + label?: string | null; + name?: string | null; + isCurrent: boolean; +} + +export interface TermCreatePayload { + name: string; +} + +export interface UnivApplyInfoFieldResponse { + languageTestTypes: string[]; +} + +export interface UnivApplyInfoImportRequest { + termId: number; + homeUniversityId: number; + markdown: string; + columnMappings: Record; +} + +export interface UnivApplyInfoImportResponse { + successCount: number; + createdUniversities: string[]; +} + const assignMentorApplicationUniversity = (mentorApplicationId: string | number, universityId: number) => axiosInstance .post(`/admin/mentor-applications/${mentorApplicationId}/assign-university`, { universityId }) .then((res) => res.data); +export function normalizeTermResponse(term: AdminTermApiResponse): TermResponse { + return { + id: term.id, + label: term.label ?? term.name ?? "", + isCurrent: term.isCurrent, + }; +} + export const adminApi = { getMentorApplicationList: (params: MentorApplicationListParams) => axiosInstance.get("/admin/mentor-applications", { params }).then((res) => res.data), @@ -128,4 +180,30 @@ export const adminApi = { axiosInstance.put(`/admin/countries/${code}`, data).then((res) => res.data), delete지역삭제: (code: string) => axiosInstance.delete(`/admin/countries/${code}`).then((res) => res.data), + + getHomeUniversities: () => + axiosInstance.get("/admin/home-universities").then((res) => res.data), + + createHomeUniversity: (data: HomeUniversityPayload) => + axiosInstance.post("/admin/home-universities", data).then((res) => res.data), + + updateHomeUniversity: (id: number, data: HomeUniversityPayload) => + axiosInstance.put(`/admin/home-universities/${id}`, data).then((res) => res.data), + + deleteHomeUniversity: (id: number) => + axiosInstance.delete(`/admin/home-universities/${id}`).then((res) => res.data), + + getTerms: () => + axiosInstance.get("/admin/terms").then((res) => res.data.map(normalizeTermResponse)), + + createTerm: (data: TermCreatePayload) => + axiosInstance.post("/admin/terms", data).then((res) => normalizeTermResponse(res.data)), + + activateTerm: (id: number) => axiosInstance.patch(`/admin/terms/${id}/activate`).then((res) => res.data), + + getUnivApplyInfoFields: () => + axiosInstance.get("/admin/univ-apply-infos/fields").then((res) => res.data), + + importUnivApplyInfos: (data: UnivApplyInfoImportRequest) => + axiosInstance.post("/admin/univ-apply-infos", data).then((res) => res.data), }; diff --git a/apps/admin/vite.config.ts b/apps/admin/vite.config.ts index 885e34b4..c8f75ce8 100644 --- a/apps/admin/vite.config.ts +++ b/apps/admin/vite.config.ts @@ -4,10 +4,14 @@ import { nitro } from "nitro/vite"; import vinext from "vinext"; import { defineConfig } from "vite"; +const vinextNavShim = fileURLToPath(new URL("node_modules/vinext/dist/shims/navigation.js", import.meta.url)); + const config = defineConfig({ resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), + "next/navigation": vinextNavShim, + "next/navigation.js": vinextNavShim, }, tsconfigPaths: true, }, diff --git a/apps/web/package.json b/apps/web/package.json index 14488662..f0e883ad 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -38,7 +38,7 @@ "linkify-react": "^4.3.2", "linkifyjs": "^4.3.2", "lucide-react": "^0.479.0", - "next": "^16.2.6", + "next": "^16.2.9", "next-render-analyzer": "^0.1.2", "react": "^19.2.6", "react-dom": "^19.2.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a740e0ad..8d70d9f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,7 +40,7 @@ importers: version: 7.2.1 '@tailwindcss/vite': specifier: ^4.0.6 - version: 4.1.18(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.1.18(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) '@tanstack/react-query': specifier: ^5.84.1 version: 5.90.19(react@19.2.6) @@ -92,19 +92,19 @@ importers: version: 1.5.4 '@vitejs/plugin-react': specifier: ^6.0.2 - version: 6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitejs/plugin-rsc': specifier: ^0.5.26 - version: 0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) jsdom: specifier: ^27.0.0 version: 27.4.0 nitro: specifier: 3.0.260522-beta - version: 3.0.260522-beta(chokidar@3.6.0)(dotenv@16.6.1)(jiti@2.6.1)(lru-cache@11.2.5)(rollup@4.55.1)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 3.0.260522-beta(chokidar@3.6.0)(dotenv@16.6.1)(jiti@2.6.1)(lru-cache@11.2.5)(rollup@4.55.1)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) react-server-dom-webpack: specifier: ^19.2.6 - version: 19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)) + version: 19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)) srvx: specifier: ^0.11.15 version: 0.11.15 @@ -113,13 +113,13 @@ importers: version: 5.9.3 vinext: specifier: ^0.0.51 - version: 0.0.51(@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(next@16.2.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.0.51(@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)))(@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)))(next@16.2.9(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)))(react@19.2.6)(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) vite: specifier: ^8.0.14 - version: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/node@22.19.7)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/node@22.19.7)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) web-vitals: specifier: ^5.1.0 version: 5.1.0 @@ -149,7 +149,7 @@ importers: version: 2.20.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@sentry/nextjs': specifier: ^10.22.0 - version: 10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.104.1) + version: 10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.104.1(postcss@8.5.15)) '@solid-connect/ai-inspector': specifier: workspace:^ version: link:../../packages/ai-inspector @@ -264,7 +264,7 @@ importers: version: 5.2.2(react-hook-form@7.71.1(react@19.2.6)) '@next/third-parties': specifier: ^16.2.6 - version: 16.2.6(next@16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 16.2.6(next@16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) '@radix-ui/react-checkbox': specifier: ^1.1.4 version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -282,7 +282,7 @@ importers: version: 2.20.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@sentry/nextjs': specifier: ^10.22.0 - version: 10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.104.1) + version: 10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.104.1(postcss@8.5.6)) '@solid-connect/ai-inspector': specifier: workspace:^ version: link:../../packages/ai-inspector @@ -300,7 +300,7 @@ importers: version: 3.13.18(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@vercel/speed-insights': specifier: ^1.3.1 - version: 1.3.1(next@16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 1.3.1(next@16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) axios: specifier: ^1.6.7 version: 1.13.2 @@ -323,8 +323,8 @@ importers: specifier: ^0.479.0 version: 0.479.0(react@19.2.6) next: - specifier: ^16.2.6 - version: 16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ^16.2.9 + version: 16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-render-analyzer: specifier: ^0.1.2 version: 0.1.2 @@ -1255,6 +1255,9 @@ packages: '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} @@ -1264,156 +1267,312 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.27.2': resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.27.2': resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.27.2': resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.27.2': resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.27.2': resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.27.2': resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.27.2': resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.27.2': resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.27.2': resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.27.2': resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.27.2': resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.27.2': resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.27.2': resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.27.2': resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.27.2': resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.27.2': resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.27.2': resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.27.2': resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.27.2': resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.27.2': resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.27.2': resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.27.2': resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.27.2': resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.27.2': resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.27.2': resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@exodus/bytes@1.11.0': resolution: {integrity: sha512-wO3vd8nsEHdumsXrjGO/v4p6irbg7hy9kvIeR6i2AwylZSk4HJdWgL0FNaVquW1+AweJcdvU1IEpuIWk/WaPnA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -1693,54 +1852,105 @@ packages: '@next/env@16.2.6': resolution: {integrity: sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==} + '@next/env@16.2.9': + resolution: {integrity: sha512-ki5VxxXfzD/9TDe13wyeTKIjQTAwBVpnr8KhRDUr8ltMUq1/NBpWNT5tiPoxiGl+PHM4X2ahSOiPk6iAimIzPg==} + '@next/swc-darwin-arm64@16.2.6': resolution: {integrity: sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] + '@next/swc-darwin-arm64@16.2.9': + resolution: {integrity: sha512-HkfxNYUCmcct0Xsqib5KxqMSHV4AHJq857BNRchyBDs4YS19aHzVfn1kDuBYKqLLQBjXgnkIsjV2Kd4d2wzYhw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@next/swc-darwin-x64@16.2.6': resolution: {integrity: sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] + '@next/swc-darwin-x64@16.2.9': + resolution: {integrity: sha512-7IAtK4MeybpqRV9GRABWEhJ62mOS+rzWOzOTFie4cSEtm12xsoOMJRcECoZx3FHPzFAqN/IJtHqWAFOLfl152w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@next/swc-linux-arm64-gnu@16.2.6': resolution: {integrity: sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-gnu@16.2.9': + resolution: {integrity: sha512-hBD75iWpUtkL9SmQmcRhmLomn9jgkPzCEkbOcLgHymPEKzv+6ONy13RRiIEz/iEObjkS2Jlb5gYS2XGoS3X4rw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-arm64-musl@16.2.6': resolution: {integrity: sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-musl@16.2.9': + resolution: {integrity: sha512-qZTI3pf9SGc/obr8NkQAekBxmp1QK+kVm+VAf3BALLfFAj+1kUhkTxmrWpVos9R/UYIA8AWX2p6cGI5WdwzVUA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-x64-gnu@16.2.6': resolution: {integrity: sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-gnu@16.2.9': + resolution: {integrity: sha512-xm0HfRNX+UkH4R3c18ynswjj5o5uEj/7iI9p9omdtTSIsRCzQqkGMA+10nzJ4EHnYC3as65IMhbbl5fWRUWHYg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-linux-x64-musl@16.2.6': resolution: {integrity: sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-musl@16.2.9': + resolution: {integrity: sha512-QumimHkGEG6vM3PfEDWKyKen03NcqLOkeKB1EfcPe7VxzmEiCa4jNnMyBn/US5zcd/VE1CI+O8Ovb3lfjVHfGw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-win32-arm64-msvc@16.2.6': resolution: {integrity: sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] + '@next/swc-win32-arm64-msvc@16.2.9': + resolution: {integrity: sha512-hzQpKZvw8rAwI6A2uQh6SacCSvNAXaIkPNsWwzqqfRiIMiXMfH936skDhz1OO6KpvdKkJrgHHtqQOq5PIXOvdQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@next/swc-win32-x64-msvc@16.2.6': resolution: {integrity: sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] + '@next/swc-win32-x64-msvc@16.2.9': + resolution: {integrity: sha512-qr2VL3Ce5QrwgO2yh1ujSBawrimjVKX8FGF/cOynmdYKJY0BdHpGVNIRK1tqONB10Vkm25Ub1BD2bkjWs4+96w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@next/third-parties@16.2.6': resolution: {integrity: sha512-PDPIPVj1NX6Taxsl8OJteAUJ7iwR+QrokwWig68eh0cOmuNjC6MBL+ZzBjO8Bv0n/HOSqjGArZpM5KMSUxm+MQ==} peerDependencies: @@ -3006,6 +3216,9 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/google.maps@3.58.1': resolution: {integrity: sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==} @@ -3027,6 +3240,9 @@ packages: '@types/node@20.19.30': resolution: {integrity: sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==} + '@types/node@20.19.43': + resolution: {integrity: sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==} + '@types/node@22.19.7': resolution: {integrity: sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==} @@ -3235,6 +3451,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -3259,6 +3480,9 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -3359,6 +3583,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + baseline-browser-mapping@2.10.37: + resolution: {integrity: sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==} + engines: {node: '>=6.0.0'} + hasBin: true + bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} @@ -3384,6 +3613,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} @@ -3416,6 +3650,9 @@ packages: caniuse-lite@1.0.30001764: resolution: {integrity: sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==} + caniuse-lite@1.0.30001799: + resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} @@ -3741,6 +3978,9 @@ packages: electron-to-chromium@1.5.267: resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + electron-to-chromium@1.5.372: + resolution: {integrity: sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==} + emoji-regex-xs@2.0.1: resolution: {integrity: sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==} engines: {node: '>=10.0.0'} @@ -3758,6 +3998,10 @@ packages: resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} engines: {node: '>=10.13.0'} + enhanced-resolve@5.24.0: + resolution: {integrity: sha512-SkE2t82KlkkxQRVMVLAGKxLfORGQfrkx5dkj+vlgXRVNEdPc4eZcR+J/Fvj8C+yKSFH5L0q3NFlyufOVQnCcYQ==} + engines: {node: '>=10.13.0'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -3815,6 +4059,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -3888,6 +4137,9 @@ packages: fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + fast-xml-builder@1.1.4: resolution: {integrity: sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==} @@ -4012,8 +4264,8 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} - get-tsconfig@4.13.1: - resolution: {integrity: sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} git-raw-commits@4.0.0: resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} @@ -4477,8 +4729,8 @@ packages: linkifyjs@4.3.2: resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==} - loader-runner@4.3.1: - resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + loader-runner@4.3.2: + resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==} engines: {node: '>=6.11.5'} locate-path@6.0.0: @@ -4695,6 +4947,27 @@ packages: sass: optional: true + next@16.2.9: + resolution: {integrity: sha512-MEOJiq/UvuezAdqVSceHbqDgZt1kDw2tpGVOlsdIoJsQdbN2JY2hpVG4xnXGkbdJUOEWhnRfiu/O4Hpc9Juwww==} + engines: {node: '>=20.9.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + nf3@0.3.17: resolution: {integrity: sha512-N9zEWySuJFw+gR0lhS5863YsvNeudOdqRyFvNb+jMXbeTJOdrjDqkCpDginIZfUm0LzT1t1nCRiDeqQm/8kirQ==} @@ -4757,6 +5030,10 @@ packages: node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-releases@2.0.47: + resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} + engines: {node: '>=18'} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -4995,9 +5272,6 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - react-dom@19.2.6: resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} peerDependencies: @@ -5180,8 +5454,10 @@ packages: engines: {node: '>=10'} hasBin: true - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} + engines: {node: '>=10'} + hasBin: true sharp@0.34.5: resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} @@ -5350,28 +5626,59 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + teeny-request@9.0.0: resolution: {integrity: sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==} engines: {node: '>=14'} - terser-webpack-plugin@5.3.16: - resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} + terser-webpack-plugin@5.6.1: + resolution: {integrity: sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==} engines: {node: '>= 10.13.0'} peerDependencies: + '@minify-html/node': '*' '@swc/core': '*' + '@swc/css': '*' + '@swc/html': '*' + clean-css: '*' + cssnano: '*' + csso: '*' esbuild: '*' + html-minifier-terser: '*' + lightningcss: '*' + postcss: '*' uglify-js: '*' webpack: ^5.1.0 peerDependenciesMeta: + '@minify-html/node': + optional: true '@swc/core': optional: true + '@swc/css': + optional: true + '@swc/html': + optional: true + clean-css: + optional: true + cssnano: + optional: true + csso: + optional: true esbuild: optional: true + html-minifier-terser: + optional: true + lightningcss: + optional: true + postcss: + optional: true uglify-js: optional: true - terser@5.46.0: - resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} + terser@5.48.0: + resolution: {integrity: sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==} engines: {node: '>=10'} hasBin: true @@ -5837,8 +6144,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - watchpack@2.5.1: - resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + watchpack@2.5.2: + resolution: {integrity: sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==} engines: {node: '>=10.13.0'} web-streams-polyfill@3.3.3: @@ -5867,6 +6174,10 @@ packages: resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} engines: {node: '>=10.13.0'} + webpack-sources@3.5.0: + resolution: {integrity: sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==} + engines: {node: '>=10.13.0'} + webpack-virtual-modules@0.5.0: resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} @@ -6995,6 +7306,11 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 @@ -7003,81 +7319,159 @@ snapshots: '@esbuild/aix-ppc64@0.27.2': optional: true + '@esbuild/aix-ppc64@0.27.7': + optional: true + '@esbuild/android-arm64@0.27.2': optional: true + '@esbuild/android-arm64@0.27.7': + optional: true + '@esbuild/android-arm@0.27.2': optional: true + '@esbuild/android-arm@0.27.7': + optional: true + '@esbuild/android-x64@0.27.2': optional: true + '@esbuild/android-x64@0.27.7': + optional: true + '@esbuild/darwin-arm64@0.27.2': optional: true + '@esbuild/darwin-arm64@0.27.7': + optional: true + '@esbuild/darwin-x64@0.27.2': optional: true + '@esbuild/darwin-x64@0.27.7': + optional: true + '@esbuild/freebsd-arm64@0.27.2': optional: true + '@esbuild/freebsd-arm64@0.27.7': + optional: true + '@esbuild/freebsd-x64@0.27.2': optional: true + '@esbuild/freebsd-x64@0.27.7': + optional: true + '@esbuild/linux-arm64@0.27.2': optional: true + '@esbuild/linux-arm64@0.27.7': + optional: true + '@esbuild/linux-arm@0.27.2': optional: true + '@esbuild/linux-arm@0.27.7': + optional: true + '@esbuild/linux-ia32@0.27.2': optional: true + '@esbuild/linux-ia32@0.27.7': + optional: true + '@esbuild/linux-loong64@0.27.2': optional: true + '@esbuild/linux-loong64@0.27.7': + optional: true + '@esbuild/linux-mips64el@0.27.2': optional: true + '@esbuild/linux-mips64el@0.27.7': + optional: true + '@esbuild/linux-ppc64@0.27.2': optional: true + '@esbuild/linux-ppc64@0.27.7': + optional: true + '@esbuild/linux-riscv64@0.27.2': optional: true + '@esbuild/linux-riscv64@0.27.7': + optional: true + '@esbuild/linux-s390x@0.27.2': optional: true + '@esbuild/linux-s390x@0.27.7': + optional: true + '@esbuild/linux-x64@0.27.2': optional: true + '@esbuild/linux-x64@0.27.7': + optional: true + '@esbuild/netbsd-arm64@0.27.2': optional: true + '@esbuild/netbsd-arm64@0.27.7': + optional: true + '@esbuild/netbsd-x64@0.27.2': optional: true + '@esbuild/netbsd-x64@0.27.7': + optional: true + '@esbuild/openbsd-arm64@0.27.2': optional: true + '@esbuild/openbsd-arm64@0.27.7': + optional: true + '@esbuild/openbsd-x64@0.27.2': optional: true + '@esbuild/openbsd-x64@0.27.7': + optional: true + '@esbuild/openharmony-arm64@0.27.2': optional: true + '@esbuild/openharmony-arm64@0.27.7': + optional: true + '@esbuild/sunos-x64@0.27.2': optional: true + '@esbuild/sunos-x64@0.27.7': + optional: true + '@esbuild/win32-arm64@0.27.2': optional: true + '@esbuild/win32-arm64@0.27.7': + optional: true + '@esbuild/win32-ia32@0.27.2': optional: true + '@esbuild/win32-ia32@0.27.7': + optional: true + '@esbuild/win32-x64@0.27.2': optional: true + '@esbuild/win32-x64@0.27.7': + optional: true + '@exodus/bytes@1.11.0': {} '@fastify/busboy@3.2.0': {} @@ -7307,7 +7701,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.10.0 + '@emnapi/runtime': 1.11.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -7371,36 +7765,68 @@ snapshots: '@next/env@16.2.6': {} + '@next/env@16.2.9': {} + '@next/swc-darwin-arm64@16.2.6': optional: true + '@next/swc-darwin-arm64@16.2.9': + optional: true + '@next/swc-darwin-x64@16.2.6': optional: true + '@next/swc-darwin-x64@16.2.9': + optional: true + '@next/swc-linux-arm64-gnu@16.2.6': optional: true + '@next/swc-linux-arm64-gnu@16.2.9': + optional: true + '@next/swc-linux-arm64-musl@16.2.6': optional: true + '@next/swc-linux-arm64-musl@16.2.9': + optional: true + '@next/swc-linux-x64-gnu@16.2.6': optional: true + '@next/swc-linux-x64-gnu@16.2.9': + optional: true + '@next/swc-linux-x64-musl@16.2.6': optional: true + '@next/swc-linux-x64-musl@16.2.9': + optional: true + '@next/swc-win32-arm64-msvc@16.2.6': optional: true + '@next/swc-win32-arm64-msvc@16.2.9': + optional: true + '@next/swc-win32-x64-msvc@16.2.6': optional: true + '@next/swc-win32-x64-msvc@16.2.9': + optional: true + '@next/third-parties@16.2.6(next@16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)': dependencies: next: 16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: 19.2.6 third-party-capital: 1.0.20 + '@next/third-parties@16.2.6(next@16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)': + dependencies: + next: 16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + third-party-capital: 1.0.20 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -8267,7 +8693,7 @@ snapshots: '@sentry/core@10.34.0': {} - '@sentry/nextjs@10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.104.1)': + '@sentry/nextjs@10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.104.1(postcss@8.5.15))': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.39.0 @@ -8279,7 +8705,7 @@ snapshots: '@sentry/opentelemetry': 10.34.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0) '@sentry/react': 10.34.0(react@19.2.6) '@sentry/vercel-edge': 10.34.0 - '@sentry/webpack-plugin': 4.6.2(webpack@5.104.1) + '@sentry/webpack-plugin': 4.6.2(webpack@5.104.1(postcss@8.5.15)) next: 16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) rollup: 4.55.1 stacktrace-parser: 0.1.11 @@ -8292,6 +8718,31 @@ snapshots: - supports-color - webpack + '@sentry/nextjs@10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.104.1(postcss@8.5.6))': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.39.0 + '@rollup/plugin-commonjs': 28.0.1(rollup@4.55.1) + '@sentry-internal/browser-utils': 10.34.0 + '@sentry/bundler-plugin-core': 4.6.2 + '@sentry/core': 10.34.0 + '@sentry/node': 10.34.0 + '@sentry/opentelemetry': 10.34.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0) + '@sentry/react': 10.34.0(react@19.2.6) + '@sentry/vercel-edge': 10.34.0 + '@sentry/webpack-plugin': 4.6.2(webpack@5.104.1(postcss@8.5.6)) + next: 16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + rollup: 4.55.1 + stacktrace-parser: 0.1.11 + transitivePeerDependencies: + - '@opentelemetry/context-async-hooks' + - '@opentelemetry/core' + - '@opentelemetry/sdk-trace-base' + - encoding + - react + - supports-color + - webpack + '@sentry/node-core@10.34.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0)': dependencies: '@apm-js-collab/tracing-hooks': 0.3.1 @@ -8369,12 +8820,22 @@ snapshots: '@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0) '@sentry/core': 10.34.0 - '@sentry/webpack-plugin@4.6.2(webpack@5.104.1)': + '@sentry/webpack-plugin@4.6.2(webpack@5.104.1(postcss@8.5.15))': + dependencies: + '@sentry/bundler-plugin-core': 4.6.2 + unplugin: 1.0.1 + uuid: 9.0.1 + webpack: 5.104.1(postcss@8.5.15) + transitivePeerDependencies: + - encoding + - supports-color + + '@sentry/webpack-plugin@4.6.2(webpack@5.104.1(postcss@8.5.6))': dependencies: '@sentry/bundler-plugin-core': 4.6.2 unplugin: 1.0.1 uuid: 9.0.1 - webpack: 5.104.1 + webpack: 5.104.1(postcss@8.5.6) transitivePeerDependencies: - encoding - supports-color @@ -8546,12 +9007,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 - '@tailwindcss/vite@4.1.18(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@tailwindcss/vite@4.1.18(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@tailwindcss/node': 4.1.18 '@tailwindcss/oxide': 4.1.18 tailwindcss: 4.1.18 - vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) '@tanstack/query-core@5.90.19': {} @@ -8630,15 +9091,17 @@ snapshots: '@types/eslint-scope@3.7.7': dependencies: '@types/eslint': 9.6.1 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/eslint@9.6.1': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@types/estree@1.0.8': {} + '@types/estree@1.0.9': {} + '@types/google.maps@3.58.1': {} '@types/json-schema@7.0.15': {} @@ -8661,6 +9124,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@20.19.43': + dependencies: + undici-types: 6.21.0 + '@types/node@22.19.7': dependencies: undici-types: 6.21.0 @@ -8712,13 +9179,13 @@ snapshots: dependencies: unpic: 4.2.2 - '@unpic/react@1.0.2(next@16.2.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@unpic/react@1.0.2(next@16.2.9(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@unpic/core': 1.0.3 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - next: 16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + next: 16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@vercel/og@0.8.6': dependencies: @@ -8730,14 +9197,19 @@ snapshots: next: 16.2.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: 19.2.6 - '@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vercel/speed-insights@1.3.1(next@16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)': + optionalDependencies: + next: 16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + + '@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@rolldown/pluginutils': 1.0.1 - vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: babel-plugin-react-compiler: 1.0.0 - '@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.18 es-module-lexer: 2.1.0 @@ -8748,10 +9220,10 @@ snapshots: srvx: 0.11.15 strip-literal: 3.1.0 turbo-stream: 3.2.0 - vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vitefu: 1.1.3(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.3(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) optionalDependencies: - react-server-dom-webpack: 19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)) + react-server-dom-webpack: 19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)) '@vitest/expect@3.2.4': dependencies: @@ -8761,13 +9233,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@3.2.4': dependencies: @@ -8889,9 +9361,9 @@ snapshots: dependencies: acorn: 8.15.0 - acorn-import-phases@1.0.4(acorn@8.15.0): + acorn-import-phases@1.0.4(acorn@8.17.0): dependencies: - acorn: 8.15.0 + acorn: 8.17.0 acorn-loose@8.5.2: dependencies: @@ -8903,6 +9375,8 @@ snapshots: acorn@8.15.0: {} + acorn@8.17.0: {} + agent-base@6.0.2: dependencies: debug: 4.4.3 @@ -8911,13 +9385,13 @@ snapshots: agent-base@7.1.4: {} - ajv-formats@2.1.1(ajv@8.17.1): + ajv-formats@2.1.1(ajv@8.20.0): optionalDependencies: - ajv: 8.17.1 + ajv: 8.20.0 - ajv-keywords@5.1.0(ajv@8.17.1): + ajv-keywords@5.1.0(ajv@8.20.0): dependencies: - ajv: 8.17.1 + ajv: 8.20.0 fast-deep-equal: 3.1.3 ajv@8.17.1: @@ -8927,6 +9401,13 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -9034,6 +9515,8 @@ snapshots: baseline-browser-mapping@2.10.32: {} + baseline-browser-mapping@2.10.37: {} + bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 @@ -9060,6 +9543,14 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.37 + caniuse-lite: 1.0.30001799 + electron-to-chromium: 1.5.372 + node-releases: 2.0.47 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + buffer-equal-constant-time@1.0.1: {} buffer-from@1.1.2: {} @@ -9081,6 +9572,8 @@ snapshots: caniuse-lite@1.0.30001764: {} + caniuse-lite@1.0.30001799: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -9371,6 +9864,8 @@ snapshots: electron-to-chromium@1.5.267: {} + electron-to-chromium@1.5.372: {} + emoji-regex-xs@2.0.1: {} emoji-regex@8.0.0: {} @@ -9387,6 +9882,11 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.0 + enhanced-resolve@5.24.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + entities@4.5.0: {} entities@6.0.1: {} @@ -9452,6 +9952,36 @@ snapshots: '@esbuild/win32-ia32': 0.27.2 '@esbuild/win32-x64': 0.27.2 + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + optional: true + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -9506,6 +10036,8 @@ snapshots: fast-uri@3.1.0: {} + fast-uri@3.1.2: {} + fast-xml-builder@1.1.4: dependencies: path-expression-matcher: 1.2.0 @@ -9678,7 +10210,7 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 - get-tsconfig@4.13.1: + get-tsconfig@4.14.0: dependencies: resolve-pkg-maps: 1.0.0 optional: true @@ -9933,7 +10465,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 20.19.30 + '@types/node': 20.19.43 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -10145,7 +10677,7 @@ snapshots: linkifyjs@4.3.2: {} - loader-runner@4.3.1: {} + loader-runner@4.3.2: {} locate-path@6.0.0: dependencies: @@ -10325,9 +10857,35 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@16.2.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@next/env': 16.2.9 + '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.10.37 + caniuse-lite: 1.0.30001799 + postcss: 8.4.31 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + styled-jsx: 5.1.6(@babel/core@7.28.6)(react@19.2.6) + optionalDependencies: + '@next/swc-darwin-arm64': 16.2.9 + '@next/swc-darwin-x64': 16.2.9 + '@next/swc-linux-arm64-gnu': 16.2.9 + '@next/swc-linux-arm64-musl': 16.2.9 + '@next/swc-linux-x64-gnu': 16.2.9 + '@next/swc-linux-x64-musl': 16.2.9 + '@next/swc-win32-arm64-msvc': 16.2.9 + '@next/swc-win32-x64-msvc': 16.2.9 + '@opentelemetry/api': 1.9.0 + babel-plugin-react-compiler: 1.0.0 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nf3@0.3.17: {} - nitro@3.0.260522-beta(chokidar@3.6.0)(dotenv@16.6.1)(jiti@2.6.1)(lru-cache@11.2.5)(rollup@4.55.1)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + nitro@3.0.260522-beta(chokidar@3.6.0)(dotenv@16.6.1)(jiti@2.6.1)(lru-cache@11.2.5)(rollup@4.55.1)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: consola: 3.4.2 crossws: 0.4.5(srvx@0.11.15) @@ -10347,7 +10905,7 @@ snapshots: dotenv: 16.6.1 jiti: 2.6.1 rollup: 4.55.1 - vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -10400,6 +10958,8 @@ snapshots: node-releases@2.0.27: {} + node-releases@2.0.47: {} + normalize-path@3.0.0: {} nth-check@2.1.1: @@ -10611,10 +11171,6 @@ snapshots: queue-microtask@1.2.3: {} - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - react-dom@19.2.6(react@19.2.6): dependencies: react: 19.2.6 @@ -10652,13 +11208,13 @@ snapshots: optionalDependencies: '@types/react': 19.2.15 - react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)): + react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)): dependencies: acorn-loose: 8.5.2 neo-async: 2.6.2 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - webpack: 5.104.1(esbuild@0.27.2) + webpack: 5.104.1(esbuild@0.27.7)(lightningcss@1.32.0) webpack-sources: 3.3.3 react-style-singleton@2.2.3(@types/react@19.2.15)(react@19.2.6): @@ -10833,23 +11389,22 @@ snapshots: schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - ajv-keywords: 5.1.0(ajv@8.17.1) + ajv: 8.20.0 + ajv-formats: 2.1.1(ajv@8.20.0) + ajv-keywords: 5.1.0(ajv@8.20.0) semver@6.3.1: {} semver@7.7.3: {} - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 + semver@7.8.4: + optional: true sharp@0.34.5: dependencies: '@img/colour': 1.1.0 detect-libc: 2.1.2 - semver: 7.7.3 + semver: 7.8.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -11062,6 +11617,8 @@ snapshots: tapable@2.3.0: {} + tapable@2.3.3: {} + teeny-request@9.0.0: dependencies: http-proxy-agent: 5.0.0 @@ -11074,30 +11631,41 @@ snapshots: - supports-color optional: true - terser-webpack-plugin@5.3.16(esbuild@0.27.2)(webpack@5.104.1(esbuild@0.27.2)): + terser-webpack-plugin@5.6.1(esbuild@0.27.7)(lightningcss@1.32.0)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.46.0 - webpack: 5.104.1(esbuild@0.27.2) + terser: 5.48.0 + webpack: 5.104.1(esbuild@0.27.7)(lightningcss@1.32.0) optionalDependencies: - esbuild: 0.27.2 + esbuild: 0.27.7 + lightningcss: 1.32.0 - terser-webpack-plugin@5.3.16(webpack@5.104.1): + terser-webpack-plugin@5.6.1(postcss@8.5.15)(webpack@5.104.1(postcss@8.5.15)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.46.0 - webpack: 5.104.1 + terser: 5.48.0 + webpack: 5.104.1(postcss@8.5.15) + optionalDependencies: + postcss: 8.5.15 - terser@5.46.0: + terser-webpack-plugin@5.6.1(postcss@8.5.6)(webpack@5.104.1(postcss@8.5.6)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.48.0 + webpack: 5.104.1(postcss@8.5.6) + optionalDependencies: + postcss: 8.5.6 + + terser@5.48.0: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.15.0 + acorn: 8.17.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -11171,8 +11739,8 @@ snapshots: tsx@4.21.0: dependencies: - esbuild: 0.27.2 - get-tsconfig: 4.13.1 + esbuild: 0.27.7 + get-tsconfig: 4.14.0 optionalDependencies: fsevents: 2.3.3 optional: true @@ -11256,6 +11824,12 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + url-parse@1.5.10: dependencies: querystringify: 2.2.0 @@ -11290,35 +11864,35 @@ snapshots: uuid@9.0.1: {} - vinext@0.0.51(@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(next@16.2.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vinext@0.0.51(@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)))(@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)))(next@16.2.9(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)))(react@19.2.6)(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: - '@unpic/react': 1.0.2(next@16.2.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@unpic/react': 1.0.2(next@16.2.9(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@vercel/og': 0.8.6 - '@vitejs/plugin-react': 6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-react': 6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) image-size: 2.0.2 ipaddr.js: 2.4.0 magic-string: 0.30.21 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) vite-plugin-commonjs: 0.10.4 - vite-tsconfig-paths: 6.1.1(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite-tsconfig-paths: 6.1.1(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) web-vitals: 4.2.4 optionalDependencies: - '@vitejs/plugin-rsc': 0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) - react-server-dom-webpack: 19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)) + '@vitejs/plugin-rsc': 0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) + react-server-dom-webpack: 19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)) transitivePeerDependencies: - next - supports-color - typescript - vite-node@3.2.4(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite-node@3.2.4(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -11335,28 +11909,28 @@ snapshots: vite-plugin-commonjs@0.10.4: dependencies: - acorn: 8.15.0 + acorn: 8.17.0 magic-string: 0.30.21 vite-plugin-dynamic-import: 1.6.0 vite-plugin-dynamic-import@1.6.0: dependencies: - acorn: 8.15.0 + acorn: 8.17.0 es-module-lexer: 1.7.0 fast-glob: 3.3.3 magic-string: 0.30.21 - vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) - vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - typescript - vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) @@ -11369,11 +11943,11 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.32.0 - terser: 5.46.0 + terser: 5.48.0 tsx: 4.21.0 yaml: 2.8.2 - vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -11382,22 +11956,22 @@ snapshots: tinyglobby: 0.2.16 optionalDependencies: '@types/node': 22.19.7 - esbuild: 0.27.2 + esbuild: 0.27.7 fsevents: 2.3.3 jiti: 2.6.1 - terser: 5.46.0 + terser: 5.48.0 tsx: 4.21.0 yaml: 2.8.2 - vitefu@1.1.3(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vitefu@1.1.3(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)): optionalDependencies: - vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) - vitest@3.2.4(@types/node@22.19.7)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vitest@3.2.4(@types/node@22.19.7)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -11415,8 +11989,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vite-node: 3.2.4(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.7 @@ -11439,9 +12013,8 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - watchpack@2.5.1: + watchpack@2.5.2: dependencies: - glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 web-streams-polyfill@3.3.3: {} @@ -11475,70 +12048,131 @@ snapshots: webpack-sources@3.3.3: {} + webpack-sources@3.5.0: {} + webpack-virtual-modules@0.5.0: {} - webpack@5.104.1: + webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0): dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.28.1 + acorn: 8.17.0 + acorn-import-phases: 1.0.4(acorn@8.17.0) + browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.24.0 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 + loader-runner: 4.3.2 mime-types: 2.1.35 neo-async: 2.6.2 schema-utils: 4.3.3 - tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(webpack@5.104.1) - watchpack: 2.5.1 - webpack-sources: 3.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.1(esbuild@0.27.7)(lightningcss@1.32.0)(webpack@5.104.1(esbuild@0.27.7)(lightningcss@1.32.0)) + watchpack: 2.5.2 + webpack-sources: 3.5.0 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - uglify-js - webpack@5.104.1(esbuild@0.27.2): + webpack@5.104.1(postcss@8.5.15): dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.28.1 + acorn: 8.17.0 + acorn-import-phases: 1.0.4(acorn@8.17.0) + browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.24.0 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 + loader-runner: 4.3.2 mime-types: 2.1.35 neo-async: 2.6.2 schema-utils: 4.3.3 - tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(esbuild@0.27.2)(webpack@5.104.1(esbuild@0.27.2)) - watchpack: 2.5.1 - webpack-sources: 3.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.1(postcss@8.5.15)(webpack@5.104.1(postcss@8.5.15)) + watchpack: 2.5.2 + webpack-sources: 3.5.0 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpack@5.104.1(postcss@8.5.6): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.17.0 + acorn-import-phases: 1.0.4(acorn@8.17.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.24.0 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.2 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.1(postcss@8.5.6)(webpack@5.104.1(postcss@8.5.6)) + watchpack: 2.5.2 + webpack-sources: 3.5.0 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - uglify-js websocket-driver@0.7.4:
예: 인하대학교
총 {universities.length.toLocaleString()}건
예: 2026-1
총 {terms.length.toLocaleString()}건
불러오는 중...
협정 대학을 불러오지 못했습니다.
학기 목록을 불러오지 못했습니다.
파이프(|)로 구분된 마크다운 테이블을 붙여넣으세요.
+ 필드 정보를 불러오지 못해 자동 매핑이 비활성화됩니다. +
+ 성공 {importResult.successCount}건 +
신규 등록된 대학 {importResult.createdUniversities.length}개
임포트 미리보기
+ 총 {previewRows.length}개 대학 + {clientErrorRowNumbers.size > 0 && ( + 오류 {clientErrorRowNumbers.size}행 + )} +
{cellError}