From efd20aba310cf366693c60b57d1e16cd040ba28f Mon Sep 17 00:00:00 2001 From: UE-DND <100979820+UE-DND@users.noreply.github.com> Date: Tue, 14 Jul 2026 12:04:23 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=F0=9F=92=84=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=8F=B0=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/oidc-clients.json | 0 deploy/docker-compose.yml | 3 + package.json | 9 ++- web/src/App.tsx | 87 +++++++++++++--------- web/src/assets/logo-color.svg | 14 ++++ web/src/assets/logo-mono-light.svg | 14 ++++ web/src/styles.css | 114 +++++++++++++++++++++++++---- 7 files changed, 190 insertions(+), 51 deletions(-) create mode 100644 config/oidc-clients.json create mode 100644 web/src/assets/logo-color.svg create mode 100644 web/src/assets/logo-mono-light.svg diff --git a/config/oidc-clients.json b/config/oidc-clients.json new file mode 100644 index 0000000..e69de29 diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index ef50fa1..271ce6a 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -5,6 +5,7 @@ services: build: context: .. dockerfile: Dockerfile + user: root env_file: - ./.env environment: @@ -41,7 +42,9 @@ services: ports: - "${OIDC_APP_PORT:-3003}:3003" volumes: + - ../:/app - ./oidc-clients.json:${OIDC_CLIENTS_CONFIG_PATH:-/app/config/oidc-clients.json}:ro + command: sh -c "corepack enable && pnpm dev" depends_on: redis: condition: service_healthy diff --git a/package.json b/package.json index 77053d7..2861c61 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,9 @@ "build:ui": "vite build --config web/vite.config.ts", "check:env-source": "node scripts/check-single-env-source.mjs", "dev": "concurrently -k \"pnpm dev:server\" \"pnpm dev:ui\"", - "dev:server": "tsx watch src/main.ts", + "dev:server": "tsx watch --env-file=deploy/.env src/main.ts", "dev:ui": "vite build --watch --config web/vite.config.ts", - "dev:oidc": "tsx watch src/main.ts", + "dev:oidc": "tsx watch --env-file=deploy/.env src/main.ts", "docker:build": "docker build -t cqut-auth-oidc .", "docker:up": "docker compose -f deploy/docker-compose.yml up -d --build", "docker:down": "docker compose -f deploy/docker-compose.yml down", @@ -27,6 +27,11 @@ "format": "prettier --write ." }, "pnpm": { + "supportedArchitectures": { + "os": ["current", "linux"], + "cpu": ["current", "arm64", "x64"], + "libc": ["current", "musl"] + }, "overrides": { "lodash": "^4.18.0", "path-to-regexp": "^8.4.0" diff --git a/web/src/App.tsx b/web/src/App.tsx index ce7d02a..b08668d 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -1,5 +1,7 @@ import { FormEvent, useEffect, useState } from "react"; import useSWR, { SWRConfig } from "swr"; +import logoMonoLight from "./assets/logo-mono-light.svg"; +import logoColor from "./assets/logo-color.svg"; type User = { subjectId: string; @@ -208,38 +210,48 @@ function Login({ } return ( -
-
-

CQUT-AUTH

-

客户端管理

-

- 使用校园统一身份认证账号登录。密码仅用于本次认证,不会被保存。 -

- {error && {error}} -
- - - -
+
+
+
+ + + CQUT-AUTH Logo + +
+
+
+
+
+

登录管理台

+

+ 使用校园统一身份认证账号登录。密码仅用于本次认证,不会被保存。 +

+ {error && {error}} +
+ + + +
+
); @@ -323,9 +335,14 @@ function Dashboard({ return (
-
-

CQUT-AUTH

- 客户端管理 +
+ + + CQUT-AUTH Logo + +
+ 客户端管理 +
diff --git a/web/src/assets/logo-color.svg b/web/src/assets/logo-color.svg new file mode 100644 index 0000000..6df8fcf --- /dev/null +++ b/web/src/assets/logo-color.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + Auth + 统一身份认证与客户端授权管理中心 + diff --git a/web/src/assets/logo-mono-light.svg b/web/src/assets/logo-mono-light.svg new file mode 100644 index 0000000..863feb3 --- /dev/null +++ b/web/src/assets/logo-mono-light.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + Auth + 统一身份认证与客户端授权管理中心 + diff --git a/web/src/styles.css b/web/src/styles.css index f8d8a37..8e8da81 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -96,21 +96,86 @@ code { letter-spacing: 0.12em; margin-bottom: 4px; } -.login-layout { +.login-split-layout { min-height: 100vh; display: grid; - place-items: center; - padding: 24px; - background: - radial-gradient(circle at 80% 10%, #dceef5, transparent 35%), #f7fafc; -} -.login-card { - width: min(100%, 440px); - padding: 32px; - border: 1px solid var(--border); - border-radius: 16px; + grid-template-columns: 1.5fr 1px 1fr; + background: #f7fafc; +} +.login-hero-pane { + display: flex; + align-items: center; + justify-content: center; + padding: 48px; + background: radial-gradient(circle at 30% 30%, #dceef5, transparent 60%), #f7fafc; + position: relative; + overflow: hidden; +} +.login-hero-content { + max-width: 600px; + text-align: left; +} +.hero-logo-img { + height: 80px; + width: auto; + display: block; +} +.login-divider { + background-color: var(--border); + height: 100%; +} +.login-form-pane { + display: flex; + align-items: center; + justify-content: center; + padding: 48px 36px; background: white; } +.login-form-content { + width: 100%; + max-width: 320px; +} +.login-form-content h2 { + font-size: 1.8rem; + font-weight: 750; + margin-bottom: 8px; +} +@media (prefers-color-scheme: dark) { + .login-split-layout { + background: #0f172a; + } + .login-hero-pane { + background: radial-gradient(circle at 30% 30%, #1e293b, transparent 60%), #0f172a; + } + .login-divider { + background-color: #334155; + } + .login-form-pane { + background: #0f172a; + color: #f8fafc; + } +} +@media (max-width: 1024px) { + .login-split-layout { + grid-template-columns: 1.2fr 1px 1fr; + } +} +@media (max-width: 768px) { + .login-split-layout { + grid-template-columns: 1fr; + } + .login-hero-pane { + padding: 36px 24px; + min-height: 35vh; + } + .login-divider { + height: 1px; + width: 100%; + } + .login-form-pane { + padding: 36px 24px 64px; + } +} .stack { display: grid; gap: 16px; @@ -142,11 +207,32 @@ textarea { justify-content: space-between; gap: 24px; padding: 12px max(16px, calc((100vw - 1280px) / 2)); - background: var(--blue-dark); - color: white; + background: white; + color: var(--blue-dark); + border-bottom: 1px solid var(--border); +} +.topbar-brand { + display: flex; + align-items: center; + gap: 16px; +} +.logo-img { + height: 44px; + width: auto; + display: block; } .topbar .eyebrow { - color: #9fc1f9; + color: var(--blue); +} +@media (prefers-color-scheme: dark) { + .topbar { + background: var(--blue-dark); + color: white; + border-bottom: 0; + } + .topbar .eyebrow { + color: #9fc1f9; + } } .user-actions { display: flex; From a504d9967c3f9cdc80e15731e4ef9e42b88c77cb Mon Sep 17 00:00:00 2001 From: UE-DND <100979820+UE-DND@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:41:42 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=F0=9F=94=A7=20=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E6=95=B4=E4=B8=AA=E9=A1=B9=E7=9B=AE=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E5=8F=8A=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/init-env.mjs | 82 +++++++---- src/crypto.ts | 104 ++++++++++---- src/email/resend-email-sender.ts | 23 +-- src/identity/provider-registry.ts | 12 +- src/identity/providers/cqut.crypto.ts | 7 +- src/identity/providers/cqut.provider.test.ts | 62 +++++--- src/identity/providers/cqut.provider.ts | 132 +++++++++++++----- src/identity/providers/mock.provider.ts | 12 +- .../services/identity-link.service.ts | 18 ++- .../interactive-authenticator.service.ts | 24 ++-- .../services/subject-profile.service.ts | 28 ++-- src/identity/store.ts | 14 +- src/identity/types.ts | 4 +- src/identity/utils.ts | 6 +- src/main.ts | 2 +- src/persistence/artifact-cleanup.scheduler.ts | 35 +++-- .../artifact-payload-cipher.service.ts | 9 +- src/persistence/identity.repository.ts | 108 ++++++++++---- src/persistence/rate-limit.service.ts | 29 ++-- src/persistence/signing-key.repository.ts | 48 +++++-- src/request-ip.ts | 56 ++++++-- src/shared/oidc-contracts.ts | 18 +-- src/utils.ts | 6 +- test/artifact-cleanup.scheduler.test.ts | 43 ++++-- test/crypto.test.ts | 12 +- test/rate-limit.service.test.ts | 14 +- test/request-ip.test.ts | 22 +-- 27 files changed, 641 insertions(+), 289 deletions(-) diff --git a/scripts/init-env.mjs b/scripts/init-env.mjs index 5b2cc52..5b11969 100644 --- a/scripts/init-env.mjs +++ b/scripts/init-env.mjs @@ -6,8 +6,14 @@ import { fileURLToPath } from "node:url"; const projectRoot = resolve(dirname(fileURLToPath(import.meta.url)), ".."); const templatePath = resolve(projectRoot, "deploy/.env.example"); const defaultOutputPath = resolve(projectRoot, "deploy/.env"); -const clientsTemplatePath = resolve(projectRoot, "deploy/oidc-clients.json.example"); -const defaultClientsOutputPath = resolve(projectRoot, "deploy/oidc-clients.json"); +const clientsTemplatePath = resolve( + projectRoot, + "deploy/oidc-clients.json.example", +); +const defaultClientsOutputPath = resolve( + projectRoot, + "deploy/oidc-clients.json", +); const allowedProfiles = new Set(["production", "local", "test"]); const args = process.argv.slice(2); @@ -15,7 +21,9 @@ const outputPath = getArgValue("--write"); const force = args.includes("--force"); const printToStdout = args.includes("--stdout"); const profile = getArgValue("--profile") ?? "production"; -const demoBaseUrl = normalizeOptionalAbsoluteUrl(getArgValue("--demo-base-url")); +const demoBaseUrl = normalizeOptionalAbsoluteUrl( + getArgValue("--demo-base-url"), +); const issuerOverride = normalizeOptionalAbsoluteUrl(getArgValue("--issuer")); if (!allowedProfiles.has(profile)) { @@ -28,7 +36,7 @@ const randomReplacements = { OIDC_KEY_ENCRYPTION_SECRET: randomToken(32), OIDC_ARTIFACT_ENCRYPTION_SECRET: randomToken(32), OIDC_COOKIE_KEYS: `${randomToken(32)},${randomToken(32)}`, - OIDC_CSRF_SIGNING_SECRET: randomToken(32) + OIDC_CSRF_SIGNING_SECRET: randomToken(32), }; const profileReplacements = { @@ -40,7 +48,7 @@ const profileReplacements = { OIDC_APP_PORT: "3003", OIDC_AUTO_SEED_SIGNING_KEY: "false", OIDC_EMAIL_VERIFICATION_ENABLED: "true", - OIDC_EMAIL_FROM: "CQUT Auth " + OIDC_EMAIL_FROM: "CQUT Auth ", }, local: { APP_ENV: "development", @@ -50,7 +58,7 @@ const profileReplacements = { OIDC_APP_PORT: "3003", OIDC_AUTO_SEED_SIGNING_KEY: "true", OIDC_EMAIL_VERIFICATION_ENABLED: "true", - OIDC_EMAIL_FROM: "CQUT Auth " + OIDC_EMAIL_FROM: "CQUT Auth ", }, test: { APP_ENV: "test", @@ -60,8 +68,8 @@ const profileReplacements = { OIDC_APP_PORT: "3003", OIDC_AUTO_SEED_SIGNING_KEY: "true", OIDC_EMAIL_VERIFICATION_ENABLED: "true", - OIDC_EMAIL_FROM: "CQUT Auth " - } + OIDC_EMAIL_FROM: "CQUT Auth ", + }, }; const replacements = { @@ -69,9 +77,9 @@ const replacements = { ...profileReplacements[profile], ...(issuerOverride ? { - OIDC_ISSUER: issuerOverride + OIDC_ISSUER: issuerOverride, } - : {}) + : {}), }; const template = readFileSync(templatePath, "utf8"); @@ -102,28 +110,44 @@ if (!printToStdout) { function writeOutput(targetPath) { if (existsSync(targetPath) && !force) { - throw new Error(`Refusing to overwrite existing file: ${targetPath}. Re-run with --force if needed.`); + throw new Error( + `Refusing to overwrite existing file: ${targetPath}. Re-run with --force if needed.`, + ); } writeFileSync(targetPath, `${rendered}\n`, { encoding: "utf8" }); - process.stdout.write(`Initialized deploy env file: ${targetPath} (profile=${profile})\n`); + process.stdout.write( + `Initialized deploy env file: ${targetPath} (profile=${profile})\n`, + ); } function writeClientsConfig(targetPath) { if (existsSync(targetPath) && !force) { - throw new Error(`Refusing to overwrite existing file: ${targetPath}. Re-run with --force if needed.`); + throw new Error( + `Refusing to overwrite existing file: ${targetPath}. Re-run with --force if needed.`, + ); } const template = readFileSync(clientsTemplatePath, "utf8"); const parsedTemplate = JSON.parse(template); - if (!parsedTemplate || !Array.isArray(parsedTemplate.clients) || parsedTemplate.clients.length === 0) { - throw new Error("deploy/oidc-clients.json.example must contain at least one client template"); + if ( + !parsedTemplate || + !Array.isArray(parsedTemplate.clients) || + parsedTemplate.clients.length === 0 + ) { + throw new Error( + "deploy/oidc-clients.json.example must contain at least one client template", + ); } const baseClient = parsedTemplate.clients[0]; - const resolvedDemoBaseUrl = demoBaseUrl ?? defaultDemoBaseUrlForProfile(profile); - const redirectUri = new URL("/callback", ensureTrailingSlash(resolvedDemoBaseUrl)).toString(); + const resolvedDemoBaseUrl = + demoBaseUrl ?? defaultDemoBaseUrlForProfile(profile); + const redirectUri = new URL( + "/callback", + ensureTrailingSlash(resolvedDemoBaseUrl), + ).toString(); const postLogoutRedirectUri = new URL( "/logout-complete", - ensureTrailingSlash(resolvedDemoBaseUrl) + ensureTrailingSlash(resolvedDemoBaseUrl), ).toString(); const renderedClients = { @@ -133,13 +157,19 @@ function writeClientsConfig(targetPath) { clientId: "demo-site", clientSecretDigest: createClientSecretDigest(generatedDemoClientSecret), redirectUris: [redirectUri], - postLogoutRedirectUris: [postLogoutRedirectUri] - } - ] + postLogoutRedirectUris: [postLogoutRedirectUri], + }, + ], }; - writeFileSync(targetPath, `${JSON.stringify(renderedClients, null, 2)}\n`, { encoding: "utf8" }); - process.stdout.write(`Initialized OIDC clients file: ${targetPath} (profile=${profile})\n`); - process.stdout.write(`Demo-site client secret (write down once): ${generatedDemoClientSecret}\n`); + writeFileSync(targetPath, `${JSON.stringify(renderedClients, null, 2)}\n`, { + encoding: "utf8", + }); + process.stdout.write( + `Initialized OIDC clients file: ${targetPath} (profile=${profile})\n`, + ); + process.stdout.write( + `Demo-site client secret (write down once): ${generatedDemoClientSecret}\n`, + ); } function getArgValue(flag) { @@ -189,12 +219,12 @@ function createClientSecretDigest(secret) { N, r, p, - maxmem: 64 * 1024 * 1024 + maxmem: 64 * 1024 * 1024, }); return [ "scrypt", `N=${N},r=${r},p=${p},keylen=${keyLength}`, salt.toString("base64url"), - digest.toString("base64url") + digest.toString("base64url"), ].join("$"); } diff --git a/src/crypto.ts b/src/crypto.ts index 26d0416..d657211 100644 --- a/src/crypto.ts +++ b/src/crypto.ts @@ -4,7 +4,7 @@ import { createHash, scrypt, randomBytes, - timingSafeEqual + timingSafeEqual, } from "node:crypto"; const SCRYPT_DIGEST_PREFIX = "scrypt"; @@ -13,7 +13,7 @@ const SCRYPT_DEFAULTS = { r: 8, p: 1, keyLength: 32, - saltLength: 16 + saltLength: 16, } as const; const ENCRYPTION_SCHEME_VERSION = "v2"; @@ -39,11 +39,15 @@ export const __cryptoTestHooks = { }, derivedKeyCacheKeys() { return [...derivedKeyCache.keys()]; - } + }, }; function encodeBase64Url(raw: Buffer) { - return raw.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); + return raw + .toString("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/g, ""); } function decodeBase64Url(value: string) { @@ -86,7 +90,10 @@ function parseScryptDigest(encodedDigest: string): ParsedScryptDigest | null { if (equalsIndex <= 0) { return null; } - parameterPairs.set(entry.slice(0, equalsIndex), entry.slice(equalsIndex + 1)); + parameterPairs.set( + entry.slice(0, equalsIndex), + entry.slice(equalsIndex + 1), + ); } const N = parsePositiveInteger(parameterPairs.get("N") ?? ""); const r = parsePositiveInteger(parameterPairs.get("r") ?? ""); @@ -107,14 +114,19 @@ function parseScryptDigest(encodedDigest: string): ParsedScryptDigest | null { p, keyLength, salt, - digest + digest, }; } catch { return null; } } -function serializeScryptParams(N: number, r: number, p: number, keyLength: number) { +function serializeScryptParams( + N: number, + r: number, + p: number, + keyLength: number, +) { return `N=${N},r=${r},p=${p},keylen=${keyLength}`; } @@ -125,7 +137,10 @@ function parseScryptParams(encoded: string) { if (equalsIndex <= 0) { return null; } - parameterPairs.set(entry.slice(0, equalsIndex), entry.slice(equalsIndex + 1)); + parameterPairs.set( + entry.slice(0, equalsIndex), + entry.slice(equalsIndex + 1), + ); } const N = parsePositiveInteger(parameterPairs.get("N") ?? ""); const r = parsePositiveInteger(parameterPairs.get("r") ?? ""); @@ -143,7 +158,7 @@ function derivedKeyCacheKey( N: number, r: number, p: number, - keyLength: number + keyLength: number, ) { const secretId = createHash("sha256").update(secret, "utf8").digest("hex"); return `${N}:${r}:${p}:${keyLength}:${encodeBase64Url(salt)}:${secretId}`; @@ -171,11 +186,13 @@ async function deriveScryptKey( r: number, p: number, keyLength: number, - options: DeriveScryptKeyOptions = {} + options: DeriveScryptKeyOptions = {}, ) { const now = Date.now(); const shouldCache = options.cache ?? true; - const cacheKey = shouldCache ? derivedKeyCacheKey(secret, salt, N, r, p, keyLength) : undefined; + const cacheKey = shouldCache + ? derivedKeyCacheKey(secret, salt, N, r, p, keyLength) + : undefined; if (cacheKey) { const cached = derivedKeyCache.get(cacheKey); if (cached && cached.expiresAt > now) { @@ -195,7 +212,7 @@ async function deriveScryptKey( N, r, p, - maxmem: ENCRYPTION_MAX_MEMORY + maxmem: ENCRYPTION_MAX_MEMORY, }, (error, derived) => { if (error) { @@ -203,13 +220,13 @@ async function deriveScryptKey( return; } resolve(derived as Buffer); - } + }, ); }); if (cacheKey) { derivedKeyCache.set(cacheKey, { key, - expiresAt: now + DERIVED_KEY_CACHE_TTL_MS + expiresAt: now + DERIVED_KEY_CACHE_TTL_MS, }); if (derivedKeyCache.size > DERIVED_KEY_CACHE_MAX_ENTRIES) { pruneDerivedKeyCache(now); @@ -223,7 +240,10 @@ function parseEncryptedPayload(ciphertext: string): ParsedEncryptedPayload { if (segments.length !== 5) { throw new Error("invalid ciphertext format"); } - if (segments[0] !== ENCRYPTION_SCHEME_VERSION || segments[1] !== ENCRYPTION_SCHEME_KDF) { + if ( + segments[0] !== ENCRYPTION_SCHEME_VERSION || + segments[1] !== ENCRYPTION_SCHEME_KDF + ) { throw new Error("unsupported ciphertext version"); } const params = parseScryptParams(segments[2] ?? ""); @@ -246,11 +266,13 @@ function parseEncryptedPayload(ciphertext: string): ParsedEncryptedPayload { return { ...params, salt, - encrypted + encrypted, }; } -export async function createClientSecretDigest(secret: string): Promise { +export async function createClientSecretDigest( + secret: string, +): Promise { const salt = randomBytes(SCRYPT_DEFAULTS.saltLength); const digest = await deriveScryptKey( secret, @@ -259,7 +281,7 @@ export async function createClientSecretDigest(secret: string): Promise SCRYPT_DEFAULTS.r, SCRYPT_DEFAULTS.p, SCRYPT_DEFAULTS.keyLength, - { cache: false } + { cache: false }, ); return [ SCRYPT_DIGEST_PREFIX, @@ -267,23 +289,34 @@ export async function createClientSecretDigest(secret: string): Promise SCRYPT_DEFAULTS.N, SCRYPT_DEFAULTS.r, SCRYPT_DEFAULTS.p, - SCRYPT_DEFAULTS.keyLength + SCRYPT_DEFAULTS.keyLength, ), encodeBase64Url(salt), - encodeBase64Url(digest) + encodeBase64Url(digest), ].join("$"); } -export async function verifyClientSecretDigest(secret: string, encodedDigest: string): Promise { +export async function verifyClientSecretDigest( + secret: string, + encodedDigest: string, +): Promise { const parsed = parseScryptDigest(encodedDigest); if (!parsed) { return false; } let computed: Buffer; try { - computed = await deriveScryptKey(secret, parsed.salt, parsed.N, parsed.r, parsed.p, parsed.keyLength, { - cache: false - }); + computed = await deriveScryptKey( + secret, + parsed.salt, + parsed.N, + parsed.r, + parsed.p, + parsed.keyLength, + { + cache: false, + }, + ); } catch { return false; } @@ -293,7 +326,10 @@ export async function verifyClientSecretDigest(secret: string, encodedDigest: st return timingSafeEqual(computed, parsed.digest); } -export async function encryptJson(secret: string, payload: object): Promise { +export async function encryptJson( + secret: string, + payload: object, +): Promise { const salt = randomBytes(SCRYPT_DEFAULTS.saltLength); const iv = randomBytes(12); const key = await deriveScryptKey( @@ -302,7 +338,7 @@ export async function encryptJson(secret: string, payload: object): Promise(secret: string, ciphertext: string): Promise { +export async function decryptJson( + secret: string, + ciphertext: string, +): Promise { const parsed = parseEncryptedPayload(ciphertext); const raw = parsed.encrypted; const iv = raw.subarray(0, 12); @@ -334,10 +373,13 @@ export async function decryptJson(secret: string, ciphertext: string): Promis parsed.N, parsed.r, parsed.p, - parsed.keyLength + parsed.keyLength, ); const decipher = createDecipheriv("aes-256-gcm", key, iv); decipher.setAuthTag(tag); - const plaintext = Buffer.concat([decipher.update(payload), decipher.final()]).toString("utf8"); + const plaintext = Buffer.concat([ + decipher.update(payload), + decipher.final(), + ]).toString("utf8"); return JSON.parse(plaintext) as T; } diff --git a/src/email/resend-email-sender.ts b/src/email/resend-email-sender.ts index 8eb6678..bbf5da4 100644 --- a/src/email/resend-email-sender.ts +++ b/src/email/resend-email-sender.ts @@ -18,12 +18,13 @@ export class ResendEmailSender implements EmailSender { async sendVerificationCode(input: SendVerificationCodeInput): Promise { const ttlMinutes = Math.max(1, Math.ceil(input.expiresInSeconds / 60)); const nowBucket = Math.floor(Date.now() / 60_000); - const { error } = await this.resend.emails.send({ - from: this.from, - to: [input.to], - subject: "CQUT Auth 邮箱验证码", - text: `你的验证码是 ${input.code},${ttlMinutes} 分钟内有效。若非本人操作,请忽略本邮件。`, - html: `
+ const { error } = await this.resend.emails.send( + { + from: this.from, + to: [input.to], + subject: "CQUT Auth 邮箱验证码", + text: `你的验证码是 ${input.code},${ttlMinutes} 分钟内有效。若非本人操作,请忽略本邮件。`, + html: `

CQUT Auth 邮箱验证码

@@ -38,10 +39,12 @@ export class ResendEmailSender implements EmailSender {

若非本人操作,请忽略此邮件。

-
` - }, { - idempotencyKey: `email-verify/${input.interactionUid}/${nowBucket}` - }); +
`, + }, + { + idempotencyKey: `email-verify/${input.interactionUid}/${nowBucket}`, + }, + ); if (error) { throw new Error(`resend email send failed: ${error.message}`); } diff --git a/src/identity/provider-registry.ts b/src/identity/provider-registry.ts index 86607b2..ba593e2 100644 --- a/src/identity/provider-registry.ts +++ b/src/identity/provider-registry.ts @@ -4,12 +4,15 @@ import { IdentityCoreError } from "./errors.js"; export class ProviderRegistry { constructor( private readonly providers: Map, - private readonly currentProviderName?: string + private readonly currentProviderName?: string, ) {} getCurrentProvider(): CampusVerifierProvider { if (!this.currentProviderName) { - throw new IdentityCoreError("provider_not_configured", "current auth provider is not configured"); + throw new IdentityCoreError( + "provider_not_configured", + "current auth provider is not configured", + ); } return this.getByName(this.currentProviderName); } @@ -17,7 +20,10 @@ export class ProviderRegistry { getByName(name: string): CampusVerifierProvider { const provider = this.providers.get(name); if (!provider) { - throw new IdentityCoreError("unknown_provider", `unknown auth provider: ${name}`); + throw new IdentityCoreError( + "unknown_provider", + `unknown auth provider: ${name}`, + ); } return provider; } diff --git a/src/identity/providers/cqut.crypto.ts b/src/identity/providers/cqut.crypto.ts index 0a6da0f..5483b3b 100644 --- a/src/identity/providers/cqut.crypto.ts +++ b/src/identity/providers/cqut.crypto.ts @@ -1,7 +1,6 @@ import { constants, publicEncrypt } from "node:crypto"; -const PUBLIC_KEY = -`-----BEGIN PUBLIC KEY----- +const PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDACwPDxYycdCiNeblZa9LjvDzb iZU1vc9gKRcG/pGjZ/DJkI4HmoUE2r/o6SfB5az3s+H5JDzmOMVQ63hD7LZQGR4k 3iYWnCg3UpQZkZEtFtXBXsQHjKVJqCiEtK+gtxz4WnriDjf+e/CxJ7OD03e7sy5N @@ -12,9 +11,9 @@ function encryptChunk(chunk: string): string { return publicEncrypt( { key: PUBLIC_KEY, - padding: constants.RSA_PKCS1_PADDING + padding: constants.RSA_PKCS1_PADDING, }, - Buffer.from(chunk, "utf8") + Buffer.from(chunk, "utf8"), ).toString("base64"); } diff --git a/src/identity/providers/cqut.provider.test.ts b/src/identity/providers/cqut.provider.test.ts index 97cd27e..9cf655c 100644 --- a/src/identity/providers/cqut.provider.test.ts +++ b/src/identity/providers/cqut.provider.test.ts @@ -16,17 +16,23 @@ test("CqutCampusVerifierProvider uses UIS CAS endpoints only", async () => { const url = new URL(req.url ?? "/", `http://${host}`); requests.push({ method: req.method ?? "GET", - pathWithQuery: `${url.pathname}${url.search}` + pathWithQuery: `${url.pathname}${url.search}`, }); - if (url.pathname === `/center-auth-server/${appCode}/cas/login` && req.method === "GET") { + if ( + url.pathname === `/center-auth-server/${appCode}/cas/login` && + req.method === "GET" + ) { res.setHeader("Set-Cookie", "SOURCEID_TGC=test-tgc; Path=/; HttpOnly"); res.statusCode = 200; res.end("ok"); return; } - if (url.pathname === "/center-auth-server/sso/doLogin" && req.method === "POST") { + if ( + url.pathname === "/center-auth-server/sso/doLogin" && + req.method === "POST" + ) { res.setHeader("Content-Type", "application/json;charset=utf-8"); res.end(JSON.stringify({ code: 200, msg: "登录成功" })); return; @@ -50,13 +56,13 @@ test("CqutCampusVerifierProvider uses UIS CAS endpoints only", async () => { providerTotalTimeoutMs: 10000, uisBaseUrl: baseUrl, casApplicationCode: appCode, - casServiceUrl: `${baseUrl}/ump/common/login/authSourceAuth/auth?applicationCode=${appCode}` + casServiceUrl: `${baseUrl}/ump/common/login/authSourceAuth/auth?applicationCode=${appCode}`, }); try { const identity = await provider.verifyCredentials({ account: TEST_ACCOUNT, - password: TEST_PASSWORD + password: TEST_PASSWORD, }); assert.equal(identity.schoolUid, TEST_ACCOUNT); assert.equal(identity.identityHash, `cqut:${TEST_ACCOUNT}`); @@ -76,23 +82,29 @@ test("CqutCampusVerifierProvider uses UIS CAS endpoints only", async () => { assert.equal(requests.length >= 3, true); assert.equal( requests.some((item) => item.pathWithQuery.includes("/cas/clientredirect")), - false + false, ); assert.equal( - requests.some((item) => item.pathWithQuery.includes(`/center-auth-server/${appCode}/cas/login`)), - true + requests.some((item) => + item.pathWithQuery.includes(`/center-auth-server/${appCode}/cas/login`), + ), + true, ); assert.equal( - requests.some((item) => item.pathWithQuery.startsWith("/center-auth-server/sso/doLogin")), - true + requests.some((item) => + item.pathWithQuery.startsWith("/center-auth-server/sso/doLogin"), + ), + true, ); assert.deepEqual( - requests.map((item) => `${item.method} ${item.pathWithQuery.split("?")[0]}`), + requests.map( + (item) => `${item.method} ${item.pathWithQuery.split("?")[0]}`, + ), [ `GET /center-auth-server/${appCode}/cas/login`, "POST /center-auth-server/sso/doLogin", - `GET /center-auth-server/${appCode}/cas/login` - ] + `GET /center-auth-server/${appCode}/cas/login`, + ], ); }); @@ -106,10 +118,13 @@ test("CqutCampusVerifierProvider retries transient CAS login GET failures", asyn const url = new URL(req.url ?? "/", `http://${host}`); requests.push({ method: req.method ?? "GET", - pathWithQuery: `${url.pathname}${url.search}` + pathWithQuery: `${url.pathname}${url.search}`, }); - if (url.pathname === `/center-auth-server/${appCode}/cas/login` && req.method === "GET") { + if ( + url.pathname === `/center-auth-server/${appCode}/cas/login` && + req.method === "GET" + ) { loginPageAttempts += 1; if (loginPageAttempts === 1) { res.statusCode = 503; @@ -122,7 +137,10 @@ test("CqutCampusVerifierProvider retries transient CAS login GET failures", asyn return; } - if (url.pathname === "/center-auth-server/sso/doLogin" && req.method === "POST") { + if ( + url.pathname === "/center-auth-server/sso/doLogin" && + req.method === "POST" + ) { res.setHeader("Content-Type", "application/json;charset=utf-8"); res.end(JSON.stringify({ code: 200, msg: "登录成功" })); return; @@ -146,13 +164,13 @@ test("CqutCampusVerifierProvider retries transient CAS login GET failures", asyn providerTotalTimeoutMs: 10000, uisBaseUrl: baseUrl, casApplicationCode: appCode, - casServiceUrl: `${baseUrl}/ump/common/login/authSourceAuth/auth?applicationCode=${appCode}` + casServiceUrl: `${baseUrl}/ump/common/login/authSourceAuth/auth?applicationCode=${appCode}`, }); try { const identity = await provider.verifyCredentials({ account: TEST_ACCOUNT, - password: TEST_PASSWORD + password: TEST_PASSWORD, }); assert.equal(identity.schoolUid, TEST_ACCOUNT); assert.equal(identity.studentStatus, "active"); @@ -169,12 +187,14 @@ test("CqutCampusVerifierProvider retries transient CAS login GET failures", asyn } assert.deepEqual( - requests.map((item) => `${item.method} ${item.pathWithQuery.split("?")[0]}`), + requests.map( + (item) => `${item.method} ${item.pathWithQuery.split("?")[0]}`, + ), [ `GET /center-auth-server/${appCode}/cas/login`, `GET /center-auth-server/${appCode}/cas/login`, "POST /center-auth-server/sso/doLogin", - `GET /center-auth-server/${appCode}/cas/login` - ] + `GET /center-auth-server/${appCode}/cas/login`, + ], ); }); diff --git a/src/identity/providers/cqut.provider.ts b/src/identity/providers/cqut.provider.ts index 921fe46..70cca87 100644 --- a/src/identity/providers/cqut.provider.ts +++ b/src/identity/providers/cqut.provider.ts @@ -1,7 +1,11 @@ import axios, { type AxiosInstance, type AxiosResponse } from "axios"; import { wrapper } from "axios-cookiejar-support"; import { CookieJar } from "tough-cookie"; -import type { CampusVerifierProvider, VerificationIdentity, VerifyCredentialsInput } from "../types.js"; +import type { + CampusVerifierProvider, + VerificationIdentity, + VerifyCredentialsInput, +} from "../types.js"; import { IdentityCoreError, RetryableProviderError } from "../errors.js"; import { getSecretParam } from "./cqut.crypto.js"; @@ -19,12 +23,16 @@ export class CqutCampusVerifierProvider implements CampusVerifierProvider { constructor(private readonly options: CqutProviderOptions) {} - async verifyCredentials(input: VerifyCredentialsInput): Promise { + async verifyCredentials( + input: VerifyCredentialsInput, + ): Promise { const abortController = new AbortController(); let timedOut = false; const timeoutHandle = setTimeout(() => { timedOut = true; - abortController.abort(new Error("campus verification exceeded total timeout")); + abortController.abort( + new Error("campus verification exceeded total timeout"), + ); }, this.options.providerTotalTimeoutMs); try { @@ -36,8 +44,8 @@ export class CqutCampusVerifierProvider implements CampusVerifierProvider { withCredentials: true, maxRedirects: 10, timeout: this.options.providerTimeoutMs, - validateStatus: () => true - }) + validateStatus: () => true, + }), ); const serviceUrl = "http://202.202.145.132:80/"; @@ -49,62 +57,87 @@ export class CqutCampusVerifierProvider implements CampusVerifierProvider { name: input.account, pwd: getSecretParam(input.password), universityId: "100005", - verifyCode: null + verifyCode: null, }; const delegatedHeaders = { - Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + Accept: + "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN", "User-Agent": "CQUT-Auth-Service/1.0", - Referer: serviceUrl + Referer: serviceUrl, }; const delegated = await getCasLoginWithRetry(client, { url: `${uisBaseUrl}/center-auth-server/${casApplicationCode}/cas/login`, service: casServiceUrl, applicationCode: casApplicationCode, - headers: delegatedHeaders + headers: delegatedHeaders, }); if (delegated.status >= 500) { throw new RetryableProviderError("delegated service is unavailable"); } - const finalUrl = String(delegated.request?.res?.responseUrl ?? delegated.config.url ?? ""); - const serviceWithDelegatedClientId = new URL(finalUrl).searchParams.get("service") ?? casServiceUrl; + const finalUrl = String( + delegated.request?.res?.responseUrl ?? delegated.config.url ?? "", + ); + const serviceWithDelegatedClientId = + new URL(finalUrl).searchParams.get("service") ?? casServiceUrl; if (!serviceWithDelegatedClientId) { - throw new IdentityCoreError("verification_failed", "failed to obtain delegated service"); + throw new IdentityCoreError( + "verification_failed", + "failed to obtain delegated service", + ); } - const casLoginUrl = resolveCasLoginUrl(uisBaseUrl, finalUrl, casApplicationCode); + const casLoginUrl = resolveCasLoginUrl( + uisBaseUrl, + finalUrl, + casApplicationCode, + ); // Execute credential verification against UIS, then continue CAS login with // the delegated service derived from the same UIS flow. - const loginResponse = await client.post(`${uisBaseUrl}/center-auth-server/sso/doLogin`, loginPayload, { - headers: { - "Content-Type": "application/json, application/json;charset=UTF-8", - Referer: finalUrl - } - }); + const loginResponse = await client.post( + `${uisBaseUrl}/center-auth-server/sso/doLogin`, + loginPayload, + { + headers: { + "Content-Type": "application/json, application/json;charset=UTF-8", + Referer: finalUrl, + }, + }, + ); if (loginResponse.status >= 500) { throw new RetryableProviderError("campus login service is unavailable"); } if (loginResponse.status >= 400 || loginResponse.data?.code !== 200) { - throw new IdentityCoreError("verification_failed", "campus credentials rejected"); + throw new IdentityCoreError( + "verification_failed", + "campus credentials rejected", + ); } const casResponse = await getCasLoginWithRetry(client, { url: casLoginUrl, service: serviceWithDelegatedClientId, - headers: { Referer: finalUrl } + headers: { Referer: finalUrl }, }); if (casResponse.status >= 500) { throw new RetryableProviderError("campus cas service is unavailable"); } - const uiCookies = jar.getCookiesSync(uisBaseUrl).map((cookie) => cookie.key); + const uiCookies = jar + .getCookiesSync(uisBaseUrl) + .map((cookie) => cookie.key); const hasTgc = uiCookies.includes("SOURCEID_TGC"); - const postLoginUrl = String(casResponse.request?.res?.responseUrl ?? casResponse.config.url ?? ""); + const postLoginUrl = String( + casResponse.request?.res?.responseUrl ?? casResponse.config.url ?? "", + ); const redirectedBack = postLoginUrl.includes("ticket="); const portalSuccess = postLoginUrl.includes("/eportal/success.jsp"); if (!hasTgc && !redirectedBack && !portalSuccess) { - throw new IdentityCoreError("verification_failed", "cas session was not established"); + throw new IdentityCoreError( + "verification_failed", + "cas session was not established", + ); } return { @@ -112,7 +145,7 @@ export class CqutCampusVerifierProvider implements CampusVerifierProvider { verified: true, studentStatus: "active", school: this.options.schoolCode, - identityHash: `cqut:${input.account}` + identityHash: `cqut:${input.account}`, }; } catch (error) { if (error instanceof RetryableProviderError) { @@ -123,16 +156,27 @@ export class CqutCampusVerifierProvider implements CampusVerifierProvider { } if (axios.isAxiosError(error)) { if (timedOut) { - throw new RetryableProviderError("campus verification exceeded total timeout"); + throw new RetryableProviderError( + "campus verification exceeded total timeout", + ); } - if (error.code === "ERR_CANCELED" || error.code === "ECONNABORTED" || !error.response) { + if ( + error.code === "ERR_CANCELED" || + error.code === "ECONNABORTED" || + !error.response + ) { const target = - typeof error.config?.url === "string" && error.config.url.trim() ? error.config.url : "campus upstream"; + typeof error.config?.url === "string" && error.config.url.trim() + ? error.config.url + : "campus upstream"; const reason = error.code ? ` (${error.code})` : ""; - throw new RetryableProviderError(`campus upstream request timed out: ${target}${reason}`); + throw new RetryableProviderError( + `campus upstream request timed out: ${target}${reason}`, + ); } } - const message = error instanceof Error ? error.message : "unknown upstream failure"; + const message = + error instanceof Error ? error.message : "unknown upstream failure"; throw new IdentityCoreError("verification_failed", message); } finally { clearTimeout(timeoutHandle); @@ -147,7 +191,7 @@ async function getCasLoginWithRetry( service: string; applicationCode?: string; headers: Record; - } + }, ): Promise { let lastError: unknown; const params: Record = { service: options.service }; @@ -159,12 +203,14 @@ async function getCasLoginWithRetry( try { const response = await client.get(options.url, { params, - headers: options.headers + headers: options.headers, }); if (response.status < 500 || attempt === 2) { return response; } - lastError = new RetryableProviderError("campus cas login returned retryable status"); + lastError = new RetryableProviderError( + "campus cas login returned retryable status", + ); } catch (error) { lastError = error; if (attempt === 2 || !isRetryableAxiosNetworkError(error)) { @@ -174,14 +220,20 @@ async function getCasLoginWithRetry( await sleep(250); } - throw lastError instanceof Error ? lastError : new RetryableProviderError("campus cas login failed"); + throw lastError instanceof Error + ? lastError + : new RetryableProviderError("campus cas login failed"); } function isRetryableAxiosNetworkError(error: unknown): boolean { if (!axios.isAxiosError(error)) { return false; } - return error.code === "ERR_CANCELED" || error.code === "ECONNABORTED" || !error.response; + return ( + error.code === "ERR_CANCELED" || + error.code === "ECONNABORTED" || + !error.response + ); } function sleep(ms: number): Promise { @@ -194,10 +246,16 @@ function normalizeBaseUrl(value: string): string { return value.replace(/\/+$/, ""); } -function resolveCasLoginUrl(uisBaseUrl: string, finalUrl: string, fallbackApplicationCode: string): string { +function resolveCasLoginUrl( + uisBaseUrl: string, + finalUrl: string, + fallbackApplicationCode: string, +): string { try { const parsed = new URL(finalUrl); - const match = parsed.pathname.match(/^\/center-auth-server\/([^/]+)\/cas\/login$/); + const match = parsed.pathname.match( + /^\/center-auth-server\/([^/]+)\/cas\/login$/, + ); if (match?.[1]) { return `${uisBaseUrl}/center-auth-server/${match[1]}/cas/login`; } diff --git a/src/identity/providers/mock.provider.ts b/src/identity/providers/mock.provider.ts index a194c71..f537d80 100644 --- a/src/identity/providers/mock.provider.ts +++ b/src/identity/providers/mock.provider.ts @@ -1,4 +1,8 @@ -import type { CampusVerifierProvider, VerificationIdentity, VerifyCredentialsInput } from "../types.js"; +import type { + CampusVerifierProvider, + VerificationIdentity, + VerifyCredentialsInput, +} from "../types.js"; import { IdentityCoreError } from "../errors.js"; type MockProviderOptions = { @@ -10,7 +14,9 @@ export class MockCampusVerifierProvider implements CampusVerifierProvider { constructor(private readonly options: MockProviderOptions) {} - async verifyCredentials(input: VerifyCredentialsInput): Promise { + async verifyCredentials( + input: VerifyCredentialsInput, + ): Promise { // Keep test/dev flows credential-agnostic: reject only empty password. if (input.password.trim().length === 0) { throw new IdentityCoreError("verification_failed", "verification failed"); @@ -20,7 +26,7 @@ export class MockCampusVerifierProvider implements CampusVerifierProvider { verified: true, studentStatus: "active", school: this.options.schoolCode, - identityHash: `mock:${input.account || "mock-student-001"}` + identityHash: `mock:${input.account || "mock-student-001"}`, }; } } diff --git a/src/identity/services/identity-link.service.ts b/src/identity/services/identity-link.service.ts index dc090d4..b025f19 100644 --- a/src/identity/services/identity-link.service.ts +++ b/src/identity/services/identity-link.service.ts @@ -5,11 +5,15 @@ import { randomId } from "../utils.js"; export class IdentityLinkService { constructor( private readonly store: IdentityStore, - private readonly createSubjectId: () => string = () => randomId("subj") + private readonly createSubjectId: () => string = () => randomId("subj"), ) {} - async linkVerifiedIdentity(input: LinkIdentityInput): Promise { - const identityKey = input.identity.identityHash ?? `${input.provider}:${input.identity.schoolUid}`; + async linkVerifiedIdentity( + input: LinkIdentityInput, + ): Promise { + const identityKey = + input.identity.identityHash ?? + `${input.provider}:${input.identity.schoolUid}`; const now = new Date().toISOString(); const existing = await this.store.findIdentity(input.provider, identityKey); if (existing) { @@ -17,7 +21,7 @@ export class IdentityLinkService { schoolUid: input.identity.schoolUid, currentStudentStatus: input.identity.studentStatus, school: input.identity.school, - updatedAt: now + updatedAt: now, }); } @@ -27,7 +31,7 @@ export class IdentityLinkService { subjectId, status: "active", createdAt: now, - updatedAt: now + updatedAt: now, }, { subjectId, @@ -37,8 +41,8 @@ export class IdentityLinkService { currentStudentStatus: input.identity.studentStatus, school: input.identity.school, createdAt: now, - updatedAt: now - } + updatedAt: now, + }, ); } } diff --git a/src/identity/services/interactive-authenticator.service.ts b/src/identity/services/interactive-authenticator.service.ts index fd1871a..c560f89 100644 --- a/src/identity/services/interactive-authenticator.service.ts +++ b/src/identity/services/interactive-authenticator.service.ts @@ -1,5 +1,8 @@ import type { IdentityStore } from "../store.js"; -import type { AuthenticatedPrincipal, InteractiveLoginInput } from "../types.js"; +import type { + AuthenticatedPrincipal, + InteractiveLoginInput, +} from "../types.js"; import { IdentityCoreError } from "../errors.js"; import { ProviderRegistry } from "../provider-registry.js"; import { IdentityLinkService } from "./identity-link.service.js"; @@ -10,26 +13,31 @@ export class InteractiveAuthenticatorService { private readonly providerRegistry: ProviderRegistry, private readonly identityLinkService: IdentityLinkService, private readonly subjectProfileService: SubjectProfileService, - private readonly store: IdentityStore + private readonly store: IdentityStore, ) {} - async authenticate(input: InteractiveLoginInput): Promise { + async authenticate( + input: InteractiveLoginInput, + ): Promise { if (!input.account || !input.password) { - throw new IdentityCoreError("invalid_request", "missing account or password"); + throw new IdentityCoreError( + "invalid_request", + "missing account or password", + ); } const provider = this.providerRegistry.getByName(input.provider); const identity = await provider.verifyCredentials({ account: input.account, - password: input.password + password: input.password, }); const linkedIdentity = await this.identityLinkService.linkVerifiedIdentity({ provider: input.provider, - identity + identity, }); const profile = await this.subjectProfileService.ensureProfile({ subjectId: linkedIdentity.subjectId, preferredUsername: linkedIdentity.schoolUid, - displayName: `CQUT User ${linkedIdentity.schoolUid}` + displayName: `CQUT User ${linkedIdentity.schoolUid}`, }); const subject = await this.store.findSubject(linkedIdentity.subjectId); if (!subject || subject.status !== "active") { @@ -45,7 +53,7 @@ export class InteractiveAuthenticatorService { emailVerified: profile.emailVerified, preferredUsername: profile.preferredUsername ?? linkedIdentity.schoolUid, ...(profile.email ? { email: profile.email } : {}), - ...(profile.displayName ? { displayName: profile.displayName } : {}) + ...(profile.displayName ? { displayName: profile.displayName } : {}), }; } } diff --git a/src/identity/services/subject-profile.service.ts b/src/identity/services/subject-profile.service.ts index 2044009..74354b2 100644 --- a/src/identity/services/subject-profile.service.ts +++ b/src/identity/services/subject-profile.service.ts @@ -10,7 +10,9 @@ type EnsureProfileInput = { export class SubjectProfileService { constructor(private readonly store: IdentityStore) {} - async ensureProfile(input: EnsureProfileInput): Promise { + async ensureProfile( + input: EnsureProfileInput, + ): Promise { const existing = await this.store.getProfile(input.subjectId); const next: SubjectProfileRecord = { subjectId: input.subjectId, @@ -18,32 +20,42 @@ export class SubjectProfileService { displayName: existing?.displayName ?? input.displayName, emailVerified: existing?.emailVerified ?? false, updatedAt: new Date().toISOString(), - ...(existing?.email ? { email: existing.email } : {}) + ...(existing?.email ? { email: existing.email } : {}), }; return this.store.upsertProfile(next); } - async setEmail(subjectId: string, email: string): Promise { + async setEmail( + subjectId: string, + email: string, + ): Promise { const existing = await this.store.getProfile(subjectId); return this.store.upsertProfile({ subjectId, - ...(existing?.preferredUsername ? { preferredUsername: existing.preferredUsername } : {}), + ...(existing?.preferredUsername + ? { preferredUsername: existing.preferredUsername } + : {}), ...(existing?.displayName ? { displayName: existing.displayName } : {}), email, emailVerified: false, - updatedAt: new Date().toISOString() + updatedAt: new Date().toISOString(), }); } - async setVerifiedEmail(subjectId: string, email: string): Promise { + async setVerifiedEmail( + subjectId: string, + email: string, + ): Promise { const existing = await this.store.getProfile(subjectId); return this.store.upsertProfile({ subjectId, - ...(existing?.preferredUsername ? { preferredUsername: existing.preferredUsername } : {}), + ...(existing?.preferredUsername + ? { preferredUsername: existing.preferredUsername } + : {}), ...(existing?.displayName ? { displayName: existing.displayName } : {}), email, emailVerified: true, - updatedAt: new Date().toISOString() + updatedAt: new Date().toISOString(), }); } } diff --git a/src/identity/store.ts b/src/identity/store.ts index fdad73e..ee341f8 100644 --- a/src/identity/store.ts +++ b/src/identity/store.ts @@ -2,20 +2,26 @@ import type { SubjectIdentityRecord, SubjectProfileRecord, SubjectRecord, - VerificationIdentity + VerificationIdentity, } from "./types.js"; export interface IdentityStore { findSubject(subjectId: string): Promise; - findIdentity(provider: string, identityKey: string): Promise; + findIdentity( + provider: string, + identityKey: string, + ): Promise; createSubjectWithIdentity( subject: SubjectRecord, - identity: SubjectIdentityRecord + identity: SubjectIdentityRecord, ): Promise; updateIdentity( provider: string, identityKey: string, - patch: Pick + patch: Pick< + SubjectIdentityRecord, + "schoolUid" | "currentStudentStatus" | "school" | "updatedAt" + >, ): Promise; getProfile(subjectId: string): Promise; upsertProfile(profile: SubjectProfileRecord): Promise; diff --git a/src/identity/types.ts b/src/identity/types.ts index b9aad28..bcd32ce 100644 --- a/src/identity/types.ts +++ b/src/identity/types.ts @@ -15,7 +15,9 @@ export type VerifyCredentialsInput = { export interface CampusVerifierProvider { readonly name: string; - verifyCredentials(input: VerifyCredentialsInput): Promise; + verifyCredentials( + input: VerifyCredentialsInput, + ): Promise; } export type InteractiveLoginInput = { diff --git a/src/identity/utils.ts b/src/identity/utils.ts index 444e37a..dd24f5e 100644 --- a/src/identity/utils.ts +++ b/src/identity/utils.ts @@ -1,7 +1,11 @@ import { createHash, randomBytes } from "node:crypto"; export function base64Url(buffer: Buffer): string { - return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); + return buffer + .toString("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/g, ""); } export function randomId(prefix: string, size = 18): string { diff --git a/src/main.ts b/src/main.ts index 362d63a..618ad8b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,7 +3,7 @@ import { createOidcApp } from "./app.js"; async function bootstrap() { const { app, state } = await createOidcApp(); console.warn( - "[oidc-op] Managed OIDC profile active: only controlled, allowlisted clients are supported; this deployment is not a general-purpose open ecosystem OP." + "[oidc-op] Managed OIDC profile active: only controlled, allowlisted clients are supported; this deployment is not a general-purpose open ecosystem OP.", ); const server = app.listen(state.config.port); process.on("SIGINT", async () => { diff --git a/src/persistence/artifact-cleanup.scheduler.ts b/src/persistence/artifact-cleanup.scheduler.ts index 2b29bab..711d9a2 100644 --- a/src/persistence/artifact-cleanup.scheduler.ts +++ b/src/persistence/artifact-cleanup.scheduler.ts @@ -15,13 +15,20 @@ type CleanupJob = { command: string; }; -export async function ensureArtifactCleanupJob(pool: Pool, options: ArtifactCleanupOptions) { +export async function ensureArtifactCleanupJob( + pool: Pool, + options: ArtifactCleanupOptions, +) { if (!options.enabled) { - throw new ArtifactCleanupConfigurationError("OIDC_ARTIFACT_CLEANUP_ENABLED must be true"); + throw new ArtifactCleanupConfigurationError( + "OIDC_ARTIFACT_CLEANUP_ENABLED must be true", + ); } const jobName = options.jobName ?? "oidc_artifacts_expired_cleanup"; if (!Number.isInteger(options.batchSize) || options.batchSize <= 0) { - throw new ArtifactCleanupConfigurationError("OIDC_ARTIFACT_CLEANUP_BATCH_SIZE must be a positive integer"); + throw new ArtifactCleanupConfigurationError( + "OIDC_ARTIFACT_CLEANUP_BATCH_SIZE must be a positive integer", + ); } const command = buildCleanupCommand(options.batchSize); const normalizedCommand = normalizeSql(command); @@ -30,30 +37,40 @@ export async function ensureArtifactCleanupJob(pool: Pool, options: ArtifactClea await pool.query("create extension if not exists pg_cron"); } catch (error) { throw new ArtifactCleanupConfigurationError( - `failed to create pg_cron extension: ${error instanceof Error ? error.message : "unknown error"}` + `failed to create pg_cron extension: ${error instanceof Error ? error.message : "unknown error"}`, ); } const extension = await pool.query( - "select extname from pg_extension where extname = 'pg_cron' limit 1" + "select extname from pg_extension where extname = 'pg_cron' limit 1", ); if (extension.rowCount !== 1) { - throw new ArtifactCleanupConfigurationError("pg_cron extension is required but unavailable"); + throw new ArtifactCleanupConfigurationError( + "pg_cron extension is required but unavailable", + ); } const existing = await pool.query( "select jobid, schedule, command from cron.job where jobname = $1 limit 1", - [jobName] + [jobName], ); const current = existing.rows[0] as CleanupJob | undefined; - if (current && current.schedule === options.schedule && normalizeSql(current.command) === normalizedCommand) { + if ( + current && + current.schedule === options.schedule && + normalizeSql(current.command) === normalizedCommand + ) { return; } if (current) { await pool.query("select cron.unschedule($1::bigint)", [current.jobid]); } - await pool.query("select cron.schedule($1, $2, $3)", [jobName, options.schedule, command]); + await pool.query("select cron.schedule($1, $2, $3)", [ + jobName, + options.schedule, + command, + ]); } function buildCleanupCommand(batchSize: number) { diff --git a/src/persistence/artifact-payload-cipher.service.ts b/src/persistence/artifact-payload-cipher.service.ts index 0b101e9..68dc1ba 100644 --- a/src/persistence/artifact-payload-cipher.service.ts +++ b/src/persistence/artifact-payload-cipher.service.ts @@ -9,10 +9,15 @@ export class ArtifactPayloadCipherServiceImpl { } async decryptPayload(ciphertext: string) { - return decryptJson>(this.encryptionSecret, ciphertext); + return decryptJson>( + this.encryptionSecret, + ciphertext, + ); } hashLookupValue(value: string) { - return createHmac("sha256", this.encryptionSecret).update(value).digest("hex"); + return createHmac("sha256", this.encryptionSecret) + .update(value) + .digest("hex"); } } diff --git a/src/persistence/identity.repository.ts b/src/persistence/identity.repository.ts index 386d2ea..efddc87 100644 --- a/src/persistence/identity.repository.ts +++ b/src/persistence/identity.repository.ts @@ -2,7 +2,7 @@ import type { AuthenticatedPrincipal, SubjectIdentityRecord, SubjectProfileRecord, - SubjectRecord + SubjectRecord, } from "../identity/index.js"; import type { Pool } from "pg"; import type { IdentityRepository } from "./contracts.js"; @@ -19,7 +19,10 @@ export class IdentityRepositoryImpl implements IdentityRepository { if (!pool) { return this.subjects.get(subjectId) ?? null; } - const result = await pool.query("select * from subjects where subject_id = $1 limit 1", [subjectId]); + const result = await pool.query( + "select * from subjects where subject_id = $1 limit 1", + [subjectId], + ); const row = result.rows[0]; if (!row) { return null; @@ -28,14 +31,19 @@ export class IdentityRepositoryImpl implements IdentityRepository { subjectId: row.subject_id, status: row.status, createdAt: row.created_at.toISOString(), - updatedAt: row.updated_at.toISOString() + updatedAt: row.updated_at.toISOString(), }; } - async findIdentity(provider: string, identityKey: string): Promise { + async findIdentity( + provider: string, + identityKey: string, + ): Promise { const pool = this.poolProvider(); if (!pool) { - return this.identities.get(this.identityMapKey(provider, identityKey)) ?? null; + return ( + this.identities.get(this.identityMapKey(provider, identityKey)) ?? null + ); } const result = await pool.query( ` @@ -43,19 +51,22 @@ export class IdentityRepositoryImpl implements IdentityRepository { where provider = $1 and identity_key = $2 limit 1 `, - [provider, identityKey] + [provider, identityKey], ); return this.mapIdentityRow(result.rows[0]); } async createSubjectWithIdentity( subject: SubjectRecord, - identity: SubjectIdentityRecord + identity: SubjectIdentityRecord, ): Promise { const pool = this.poolProvider(); if (!pool) { this.subjects.set(subject.subjectId, subject); - this.identities.set(this.identityMapKey(identity.provider, identity.identityKey), identity); + this.identities.set( + this.identityMapKey(identity.provider, identity.identityKey), + identity, + ); return identity; } @@ -67,7 +78,12 @@ export class IdentityRepositoryImpl implements IdentityRepository { insert into subjects (subject_id, status, created_at, updated_at) values ($1, $2, $3::timestamptz, $4::timestamptz) `, - [subject.subjectId, subject.status, subject.createdAt, subject.updatedAt] + [ + subject.subjectId, + subject.status, + subject.createdAt, + subject.updatedAt, + ], ); const identityResult = await client.query( ` @@ -92,15 +108,20 @@ export class IdentityRepositoryImpl implements IdentityRepository { identity.currentStudentStatus, identity.school, identity.createdAt, - identity.updatedAt - ] + identity.updatedAt, + ], ); await client.query("commit"); - return this.mapIdentityRow(identityResult.rows[0]) as SubjectIdentityRecord; + return this.mapIdentityRow( + identityResult.rows[0], + ) as SubjectIdentityRecord; } catch (error) { await client.query("rollback"); if ((error as { code?: string }).code === "23505") { - const existing = await this.findIdentity(identity.provider, identity.identityKey); + const existing = await this.findIdentity( + identity.provider, + identity.identityKey, + ); if (existing) { return existing; } @@ -114,11 +135,16 @@ export class IdentityRepositoryImpl implements IdentityRepository { async updateIdentity( provider: string, identityKey: string, - patch: Pick + patch: Pick< + SubjectIdentityRecord, + "schoolUid" | "currentStudentStatus" | "school" | "updatedAt" + >, ): Promise { const pool = this.poolProvider(); if (!pool) { - const existing = this.identities.get(this.identityMapKey(provider, identityKey)); + const existing = this.identities.get( + this.identityMapKey(provider, identityKey), + ); if (!existing) { throw new Error(`identity not found: ${provider}/${identityKey}`); } @@ -127,7 +153,7 @@ export class IdentityRepositoryImpl implements IdentityRepository { schoolUid: patch.schoolUid, currentStudentStatus: patch.currentStudentStatus, school: patch.school, - updatedAt: patch.updatedAt + updatedAt: patch.updatedAt, }; this.identities.set(this.identityMapKey(provider, identityKey), next); return next; @@ -142,7 +168,14 @@ export class IdentityRepositoryImpl implements IdentityRepository { where provider = $1 and identity_key = $2 returning * `, - [provider, identityKey, patch.schoolUid, patch.currentStudentStatus, patch.school, patch.updatedAt] + [ + provider, + identityKey, + patch.schoolUid, + patch.currentStudentStatus, + patch.school, + patch.updatedAt, + ], ); const row = result.rows[0]; if (!row) { @@ -156,7 +189,10 @@ export class IdentityRepositoryImpl implements IdentityRepository { if (!pool) { return this.profiles.get(subjectId) ?? null; } - const result = await pool.query("select * from subject_profiles where subject_id = $1 limit 1", [subjectId]); + const result = await pool.query( + "select * from subject_profiles where subject_id = $1 limit 1", + [subjectId], + ); const row = result.rows[0]; if (!row) { return null; @@ -167,11 +203,13 @@ export class IdentityRepositoryImpl implements IdentityRepository { displayName: row.display_name ?? undefined, email: row.email ?? undefined, emailVerified: row.email_verified, - updatedAt: row.updated_at.toISOString() + updatedAt: row.updated_at.toISOString(), }; } - async upsertProfile(profile: SubjectProfileRecord): Promise { + async upsertProfile( + profile: SubjectProfileRecord, + ): Promise { const pool = this.poolProvider(); if (!pool) { this.profiles.set(profile.subjectId, profile); @@ -202,8 +240,8 @@ export class IdentityRepositoryImpl implements IdentityRepository { profile.displayName ?? null, profile.email ?? null, profile.emailVerified, - profile.updatedAt - ] + profile.updatedAt, + ], ); const row = result.rows[0]; return { @@ -212,11 +250,13 @@ export class IdentityRepositoryImpl implements IdentityRepository { displayName: row.display_name ?? undefined, email: row.email ?? undefined, emailVerified: row.email_verified, - updatedAt: row.updated_at.toISOString() + updatedAt: row.updated_at.toISOString(), }; } - async findPrincipalBySubjectId(subjectId: string): Promise { + async findPrincipalBySubjectId( + subjectId: string, + ): Promise { const pool = this.poolProvider(); if (!pool) { const subject = this.subjects.get(subjectId); @@ -225,7 +265,9 @@ export class IdentityRepositoryImpl implements IdentityRepository { } const identity = [...this.identities.values()] .filter((candidate) => candidate.subjectId === subjectId) - .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt))[0]; + .sort((left, right) => + right.updatedAt.localeCompare(left.updatedAt), + )[0]; if (!identity) { return null; } @@ -240,7 +282,7 @@ export class IdentityRepositoryImpl implements IdentityRepository { email: profile?.email, emailVerified: profile?.emailVerified ?? false, displayName: profile?.displayName, - preferredUsername: profile?.preferredUsername ?? identity.schoolUid + preferredUsername: profile?.preferredUsername ?? identity.schoolUid, }; } const result = await pool.query( @@ -269,7 +311,7 @@ export class IdentityRepositoryImpl implements IdentityRepository { where s.subject_id = $1 limit 1 `, - [subjectId] + [subjectId], ); const row = result.rows[0]; if (!row || row.status !== "active") { @@ -285,7 +327,7 @@ export class IdentityRepositoryImpl implements IdentityRepository { email: row.email ?? undefined, emailVerified: row.email_verified ?? false, displayName: row.display_name ?? undefined, - preferredUsername: row.preferred_username ?? row.school_uid + preferredUsername: row.preferred_username ?? row.school_uid, }; } @@ -293,7 +335,9 @@ export class IdentityRepositoryImpl implements IdentityRepository { return `${provider}:${identityKey}`; } - private mapIdentityRow(row: Record | undefined): SubjectIdentityRecord | null { + private mapIdentityRow( + row: Record | undefined, + ): SubjectIdentityRecord | null { if (!row) { return null; } @@ -302,10 +346,12 @@ export class IdentityRepositoryImpl implements IdentityRepository { provider: String(row["provider"]), schoolUid: String(row["school_uid"]), identityKey: String(row["identity_key"]), - currentStudentStatus: row["current_student_status"] as SubjectIdentityRecord["currentStudentStatus"], + currentStudentStatus: row[ + "current_student_status" + ] as SubjectIdentityRecord["currentStudentStatus"], school: String(row["school"]), createdAt: (row["created_at"] as Date).toISOString(), - updatedAt: (row["updated_at"] as Date).toISOString() + updatedAt: (row["updated_at"] as Date).toISOString(), }; } } diff --git a/src/persistence/rate-limit.service.ts b/src/persistence/rate-limit.service.ts index b85a0bb..71ebe19 100644 --- a/src/persistence/rate-limit.service.ts +++ b/src/persistence/rate-limit.service.ts @@ -32,7 +32,7 @@ export class RateLimitService { if (!this.config.redisUrl) { if (this.config.rateLimitFailClosed) { this.logger.warn( - "redis unavailable for oidc rate limiting, entering fail-closed mode: REDIS_URL is not configured" + "redis unavailable for oidc rate limiting, entering fail-closed mode: REDIS_URL is not configured", ); this.mode = "fail-closed"; this.memory.clear(); @@ -46,7 +46,7 @@ export class RateLimitService { this.redis = new Redis(this.config.redisUrl, { lazyConnect: true, maxRetriesPerRequest: 1, - retryStrategy: () => null + retryStrategy: () => null, }); this.redis.on("error", () => undefined); await this.redis.connect(); @@ -57,21 +57,25 @@ export class RateLimitService { this.redis = undefined; if (this.config.rateLimitFailClosed) { this.logger.warn( - `redis unavailable for oidc rate limiting, entering fail-closed mode: ${error instanceof Error ? error.message : "unknown error"}` + `redis unavailable for oidc rate limiting, entering fail-closed mode: ${error instanceof Error ? error.message : "unknown error"}`, ); this.mode = "fail-closed"; this.memory.clear(); return; } this.logger.warn( - `redis unavailable for oidc rate limiting, falling back to memory: ${error instanceof Error ? error.message : "unknown error"}` + `redis unavailable for oidc rate limiting, falling back to memory: ${error instanceof Error ? error.message : "unknown error"}`, ); this.mode = "memory"; this.startMemoryCleanup(); } } - async consume(key: string, max: number, windowSeconds: number): Promise { + async consume( + key: string, + max: number, + windowSeconds: number, + ): Promise { if (this.mode === "redis" && this.redis) { try { const result = (await this.redis.eval( @@ -85,17 +89,17 @@ export class RateLimitService { `, 1, key, - windowSeconds + windowSeconds, )) as [number | string, number | string]; const count = Number(result[0]); const ttl = Math.max(1, Number(result[1])); return { allowed: count <= max, - retryAfterSeconds: ttl + retryAfterSeconds: ttl, }; } catch (error) { this.logger.warn( - `redis rate limiting unavailable during consume: ${error instanceof Error ? error.message : "unknown error"}` + `redis rate limiting unavailable during consume: ${error instanceof Error ? error.message : "unknown error"}`, ); if (this.config.rateLimitFailClosed) { this.mode = "fail-closed"; @@ -119,19 +123,22 @@ export class RateLimitService { } this.memory.set(key, { count: 1, - expiresAt: now + windowSeconds * 1000 + expiresAt: now + windowSeconds * 1000, }); this.evictIfOverCapacity(); return { allowed: true, - retryAfterSeconds: windowSeconds + retryAfterSeconds: windowSeconds, }; } existing.count += 1; this.evictIfOverCapacity(); return { allowed: existing.count <= max, - retryAfterSeconds: Math.max(1, Math.ceil((existing.expiresAt - now) / 1000)) + retryAfterSeconds: Math.max( + 1, + Math.ceil((existing.expiresAt - now) / 1000), + ), }; } diff --git a/src/persistence/signing-key.repository.ts b/src/persistence/signing-key.repository.ts index d19a5a4..d165fe1 100644 --- a/src/persistence/signing-key.repository.ts +++ b/src/persistence/signing-key.repository.ts @@ -1,5 +1,8 @@ import type { Pool } from "pg"; -import type { OidcSigningKeyRecord, SigningKeyRepository } from "./contracts.js"; +import type { + OidcSigningKeyRecord, + SigningKeyRepository, +} from "./contracts.js"; import type { JwkCipherServiceImpl } from "./jwk-cipher.service.js"; export class SigningKeyRepositoryImpl implements SigningKeyRepository { @@ -7,10 +10,12 @@ export class SigningKeyRepositoryImpl implements SigningKeyRepository { constructor( private readonly poolProvider: () => Pool | undefined, - private readonly jwkCipherService: JwkCipherServiceImpl + private readonly jwkCipherService: JwkCipherServiceImpl, ) {} - async upsertSigningKey(key: OidcSigningKeyRecord): Promise { + async upsertSigningKey( + key: OidcSigningKeyRecord, + ): Promise { const pool = this.poolProvider(); if (!pool) { this.signingKeys.set(key.kid, key); @@ -48,20 +53,23 @@ export class SigningKeyRepositoryImpl implements SigningKeyRepository { key.status, key.createdAt, key.activatedAt ?? null, - key.retiredAt ?? null - ] + key.retiredAt ?? null, + ], ); return key; } - async listSigningKeys(statuses: Array = ["active", "retiring"]) { + async listSigningKeys( + statuses: Array = ["active", "retiring"], + ) { const pool = this.poolProvider(); if (!pool) { return [...this.signingKeys.values()] .filter((item) => statuses.includes(item.status)) .sort( (left, right) => - left.status.localeCompare(right.status) || right.createdAt.localeCompare(left.createdAt) + left.status.localeCompare(right.status) || + right.createdAt.localeCompare(left.createdAt), ); } const result = await pool.query( @@ -70,7 +78,7 @@ export class SigningKeyRepositoryImpl implements SigningKeyRepository { where status = any($1::text[]) order by case when status = 'active' then 0 else 1 end, created_at desc `, - [statuses] + [statuses], ); return result.rows.map((row: Record) => ({ kid: String(row["kid"]), @@ -80,21 +88,31 @@ export class SigningKeyRepositoryImpl implements SigningKeyRepository { privateJwkCiphertext: String(row["private_jwk_ciphertext"]), status: row["status"] as OidcSigningKeyRecord["status"], createdAt: (row["created_at"] as Date).toISOString(), - activatedAt: row["activated_at"] ? (row["activated_at"] as Date).toISOString() : undefined, - retiredAt: row["retired_at"] ? (row["retired_at"] as Date).toISOString() : undefined + activatedAt: row["activated_at"] + ? (row["activated_at"] as Date).toISOString() + : undefined, + retiredAt: row["retired_at"] + ? (row["retired_at"] as Date).toISOString() + : undefined, })); } - async loadPrivateSigningJwks(statuses: Array = ["active", "retiring"]) { + async loadPrivateSigningJwks( + statuses: Array = ["active", "retiring"], + ) { const keys = await this.listSigningKeys(statuses); const decryptedKeys = await Promise.all( keys.map(async (key) => ({ - ...(await this.jwkCipherService.decryptPrivateJwk(key.privateJwkCiphertext)), + ...(await this.jwkCipherService.decryptPrivateJwk( + key.privateJwkCiphertext, + )), use: key.use, alg: key.alg, - kid: key.kid - })) + kid: key.kid, + })), ); - return decryptedKeys as Array; + return decryptedKeys as Array< + JsonWebKey & { kid: string; alg: string; use: string } + >; } } diff --git a/src/request-ip.ts b/src/request-ip.ts index 7b2e877..2618c4d 100644 --- a/src/request-ip.ts +++ b/src/request-ip.ts @@ -36,7 +36,9 @@ function parseForwardedFor(header: HeaderValue): string[] { .filter((value): value is string => Boolean(value)); } -function parseIpAddress(value: string | undefined): ParsedIpAddress | undefined { +function parseIpAddress( + value: string | undefined, +): ParsedIpAddress | undefined { const normalized = normalizeIp(value)?.replace(/^\[|\]$/g, ""); if (!normalized) { return undefined; @@ -46,30 +48,45 @@ function parseIpAddress(value: string | undefined): ParsedIpAddress | undefined const ipv4Parts = ipv4.split("."); if (ipv4Parts.length === 4) { const octets = ipv4Parts.map((part) => Number(part)); - if (octets.every((octet) => Number.isInteger(octet) && octet >= 0 && octet <= 255)) { + if ( + octets.every( + (octet) => Number.isInteger(octet) && octet >= 0 && octet <= 255, + ) + ) { return { family: 4, - value: (((octets[0]! * 256 + octets[1]!) * 256 + octets[2]!) * 256 + octets[3]!) >>> 0 + value: + (((octets[0]! * 256 + octets[1]!) * 256 + octets[2]!) * 256 + + octets[3]!) >>> + 0, }; } } const zoneIndex = normalized.indexOf("%"); - const withoutZone = zoneIndex >= 0 ? normalized.slice(0, zoneIndex) : normalized; + const withoutZone = + zoneIndex >= 0 ? normalized.slice(0, zoneIndex) : normalized; const sections = withoutZone.split("::"); if (sections.length > 2) { return undefined; } const head = sections[0] ? sections[0].split(":") : []; const tail = sections[1] ? sections[1].split(":") : []; - if (head.some((part) => part.length === 0) || tail.some((part) => part.length === 0)) { + if ( + head.some((part) => part.length === 0) || + tail.some((part) => part.length === 0) + ) { return undefined; } const missing = sections.length === 2 ? 8 - head.length - tail.length : 0; if (missing < 0 || (sections.length === 1 && head.length !== 8)) { return undefined; } - const parts = [...head, ...Array.from({ length: missing }, () => "0"), ...tail]; + const parts = [ + ...head, + ...Array.from({ length: missing }, () => "0"), + ...tail, + ]; if (parts.length !== 8) { return undefined; } @@ -91,7 +108,11 @@ function parseCidr(value: string): ParsedCidr | undefined { } const prefixLength = Number(prefixRaw); const maxPrefix = parsed.family === 4 ? 32 : 128; - if (!Number.isInteger(prefixLength) || prefixLength < 0 || prefixLength > maxPrefix) { + if ( + !Number.isInteger(prefixLength) || + prefixLength < 0 || + prefixLength > maxPrefix + ) { return undefined; } return { ...parsed, prefixLength }; @@ -108,7 +129,7 @@ function ipInCidr(ip: ParsedIpAddress, cidr: ParsedCidr): boolean { } if (ip.family === 6 && cidr.family === 6) { const shift = BigInt(128 - cidr.prefixLength); - return (ip.value >> shift) === (cidr.value >> shift); + return ip.value >> shift === cidr.value >> shift; } return false; } @@ -126,7 +147,7 @@ function isTrustedProxy(remoteAddress: string, cidrs: string[]): boolean { export function resolveTrustedRequestIp( config: Pick, - input: TrustedRequestIpInput + input: TrustedRequestIpInput, ): string { const remoteAddress = normalizeIp(input.remoteAddress) ?? "unknown"; if (config.trustProxyHops <= 0) { @@ -141,25 +162,32 @@ export function resolveTrustedRequestIp( return remoteAddress; } - return forwardedFor[forwardedFor.length - config.trustProxyHops] ?? remoteAddress; + return ( + forwardedFor[forwardedFor.length - config.trustProxyHops] ?? remoteAddress + ); } export function resolveTrustedExpressRequestIp( config: Pick, - request: Pick + request: Pick, ): string { return resolveTrustedRequestIp(config, { headers: request.headers, - remoteAddress: request.socket.remoteAddress + remoteAddress: request.socket.remoteAddress, }); } export function resolveTrustedKoaRequestIp( config: Pick, - ctx: { req?: { headers?: IncomingHttpHeaders; socket?: { remoteAddress?: string | undefined } } } + ctx: { + req?: { + headers?: IncomingHttpHeaders; + socket?: { remoteAddress?: string | undefined }; + }; + }, ): string { return resolveTrustedRequestIp(config, { headers: ctx.req?.headers, - remoteAddress: ctx.req?.socket?.remoteAddress + remoteAddress: ctx.req?.socket?.remoteAddress, }); } diff --git a/src/shared/oidc-contracts.ts b/src/shared/oidc-contracts.ts index e0c9c05..8e2a14b 100644 --- a/src/shared/oidc-contracts.ts +++ b/src/shared/oidc-contracts.ts @@ -4,7 +4,13 @@ export const DEDUPE_SCOPE = "student.dedupe"; export const SUPPORTED_SCOPES = ["student.verify", "student.dedupe"] as const; export type SupportedScope = (typeof SUPPORTED_SCOPES)[number]; -export const OIDC_SCOPES = ["openid", "profile", "email", "offline_access", "student"] as const; +export const OIDC_SCOPES = [ + "openid", + "profile", + "email", + "offline_access", + "student", +] as const; export const DEFAULT_OIDC_SCOPES = ["openid", "profile"] as const; export type OidcScope = (typeof OIDC_SCOPES)[number]; @@ -14,15 +20,11 @@ export const OIDC_CLAIMS = [ "name", "email", "email_verified", - "status" + "status", ] as const; export type OidcClaim = (typeof OIDC_CLAIMS)[number]; -export const STUDENT_STATUS = [ - "active", - "not_student", - "unknown" -] as const; +export const STUDENT_STATUS = ["active", "not_student", "unknown"] as const; export type StudentStatus = (typeof STUDENT_STATUS)[number]; export const API_ERRORS = [ @@ -31,7 +33,7 @@ export const API_ERRORS = [ "invalid_scope", "rate_limited", "verification_failed", - "server_error" + "server_error", ] as const; export type ApiErrorCode = (typeof API_ERRORS)[number]; diff --git a/src/utils.ts b/src/utils.ts index c305341..60619c3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,11 @@ import { createHash, randomBytes } from "node:crypto"; export function base64Url(buffer: Buffer): string { - return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); + return buffer + .toString("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/g, ""); } export function randomId(prefix: string, size = 18): string { diff --git a/test/artifact-cleanup.scheduler.test.ts b/test/artifact-cleanup.scheduler.test.ts index 006970d..2e9550c 100644 --- a/test/artifact-cleanup.scheduler.test.ts +++ b/test/artifact-cleanup.scheduler.test.ts @@ -3,7 +3,7 @@ import test from "node:test"; import type { Pool } from "pg"; import { ensureArtifactCleanupJob, - ArtifactCleanupConfigurationError + ArtifactCleanupConfigurationError, } from "../src/persistence/artifact-cleanup.scheduler.js"; type QueryResult = { @@ -14,14 +14,19 @@ type QueryResult = { class FakePool { readonly calls: Array<{ sql: string; values: unknown[] | undefined }> = []; - constructor(private readonly responder: (sql: string, values: unknown[] | undefined) => QueryResult) {} + constructor( + private readonly responder: ( + sql: string, + values: unknown[] | undefined, + ) => QueryResult, + ) {} async query(sql: string, values?: unknown[]) { this.calls.push({ sql, values }); const result = this.responder(sql, values); return { rowCount: result.rowCount ?? (result.rows ? result.rows.length : 0), - rows: result.rows ?? [] + rows: result.rows ?? [], }; } } @@ -40,10 +45,12 @@ test("ensureArtifactCleanupJob creates cron job when missing", async () => { await ensureArtifactCleanupJob(pool as unknown as Pool, { enabled: true, schedule: "*/5 * * * *", - batchSize: 5000 + batchSize: 5000, }); - const scheduleCall = pool.calls.find((call) => call.sql.includes("cron.schedule")); + const scheduleCall = pool.calls.find((call) => + call.sql.includes("cron.schedule"), + ); assert.ok(scheduleCall); assert.equal(scheduleCall.values?.[0], "oidc_artifacts_expired_cleanup"); assert.equal(scheduleCall.values?.[1], "*/5 * * * *"); @@ -64,9 +71,9 @@ test("ensureArtifactCleanupJob is idempotent when schedule and command match", a jobid: 7, schedule: "*/5 * * * *", command: - "\n WITH doomed AS (\n SELECT id\n FROM oidc_artifacts\n WHERE expires_at IS NOT NULL AND expires_at <= now()\n ORDER BY expires_at ASC\n LIMIT 5000\n )\n DELETE FROM oidc_artifacts AS oa\n USING doomed\n WHERE oa.id = doomed.id\n " - } - ] + "\n WITH doomed AS (\n SELECT id\n FROM oidc_artifacts\n WHERE expires_at IS NOT NULL AND expires_at <= now()\n ORDER BY expires_at ASC\n LIMIT 5000\n )\n DELETE FROM oidc_artifacts AS oa\n USING doomed\n WHERE oa.id = doomed.id\n ", + }, + ], }; } return { rowCount: 1, rows: [] }; @@ -75,11 +82,17 @@ test("ensureArtifactCleanupJob is idempotent when schedule and command match", a await ensureArtifactCleanupJob(pool as unknown as Pool, { enabled: true, schedule: "*/5 * * * *", - batchSize: 5000 + batchSize: 5000, }); - assert.equal(pool.calls.some((call) => call.sql.includes("cron.unschedule")), false); - assert.equal(pool.calls.some((call) => call.sql.includes("cron.schedule")), false); + assert.equal( + pool.calls.some((call) => call.sql.includes("cron.unschedule")), + false, + ); + assert.equal( + pool.calls.some((call) => call.sql.includes("cron.schedule")), + false, + ); }); test("ensureArtifactCleanupJob fails when pg_cron extension is unavailable", async () => { @@ -95,9 +108,9 @@ test("ensureArtifactCleanupJob fails when pg_cron extension is unavailable", asy ensureArtifactCleanupJob(pool as unknown as Pool, { enabled: true, schedule: "*/5 * * * *", - batchSize: 5000 + batchSize: 5000, }), - ArtifactCleanupConfigurationError + ArtifactCleanupConfigurationError, ); }); @@ -109,8 +122,8 @@ test("ensureArtifactCleanupJob rejects invalid batch size", async () => { ensureArtifactCleanupJob(pool as unknown as Pool, { enabled: true, schedule: "*/5 * * * *", - batchSize: 0 + batchSize: 0, }), - ArtifactCleanupConfigurationError + ArtifactCleanupConfigurationError, ); }); diff --git a/test/crypto.test.ts b/test/crypto.test.ts index dcb73da..70877de 100644 --- a/test/crypto.test.ts +++ b/test/crypto.test.ts @@ -5,7 +5,7 @@ import { createClientSecretDigest, decryptJson, encryptJson, - verifyClientSecretDigest + verifyClientSecretDigest, } from "../src/crypto.js"; test("derived key cache keys do not include plaintext secrets", async () => { @@ -17,7 +17,10 @@ test("derived key cache keys do not include plaintext secrets", async () => { const cacheKeys = __cryptoTestHooks.derivedKeyCacheKeys(); assert.ok(cacheKeys.length > 0); - assert.equal(cacheKeys.some((cacheKey) => cacheKey.includes(secret)), false); + assert.equal( + cacheKeys.some((cacheKey) => cacheKey.includes(secret)), + false, + ); }); test("client secret verification does not cache submitted secrets", async () => { @@ -26,7 +29,10 @@ test("client secret verification does not cache submitted secrets", async () => const digest = await createClientSecretDigest(secret); assert.equal(await verifyClientSecretDigest(secret, digest), true); - assert.equal(await verifyClientSecretDigest("wrong-client-secret", digest), false); + assert.equal( + await verifyClientSecretDigest("wrong-client-secret", digest), + false, + ); assert.deepEqual(__cryptoTestHooks.derivedKeyCacheKeys(), []); }); diff --git a/test/rate-limit.service.test.ts b/test/rate-limit.service.test.ts index 5d1af5d..e4f804a 100644 --- a/test/rate-limit.service.test.ts +++ b/test/rate-limit.service.test.ts @@ -9,12 +9,14 @@ function createConfig(overrides: Partial = {}): OidcOpConfig { rateLimitFailClosed: false, rateLimitMemoryMaxKeys: 2, rateLimitMemoryCleanupIntervalSeconds: 3600, - ...overrides + ...overrides, } as unknown as OidcOpConfig; } test("memory fallback evicts oldest key when capacity is exceeded on new insert", async () => { - const service = new RateLimitService(createConfig({ rateLimitMemoryMaxKeys: 2 })); + const service = new RateLimitService( + createConfig({ rateLimitMemoryMaxKeys: 2 }), + ); await service.init(); try { @@ -33,7 +35,9 @@ test("memory fallback evicts oldest key when capacity is exceeded on new insert" }); test("memory fallback keeps FIFO order even when an old key is hit again", async () => { - const service = new RateLimitService(createConfig({ rateLimitMemoryMaxKeys: 2 })); + const service = new RateLimitService( + createConfig({ rateLimitMemoryMaxKeys: 2 }), + ); await service.init(); try { @@ -51,7 +55,9 @@ test("memory fallback keeps FIFO order even when an old key is hit again", async }); test("expired counters and FIFO eviction can coexist without stale key retention", async () => { - const service = new RateLimitService(createConfig({ rateLimitMemoryMaxKeys: 1 })); + const service = new RateLimitService( + createConfig({ rateLimitMemoryMaxKeys: 1 }), + ); await service.init(); const originalNow = Date.now; diff --git a/test/request-ip.test.ts b/test/request-ip.test.ts index 5c01155..dacab8d 100644 --- a/test/request-ip.test.ts +++ b/test/request-ip.test.ts @@ -5,22 +5,22 @@ import { resolveTrustedRequestIp } from "../src/request-ip.js"; test("resolveTrustedRequestIp trusts forwarded-for only from configured proxy cidrs", () => { const config = { trustProxyHops: 1, - trustedProxyCidrs: ["127.0.0.1/32", "10.0.0.0/8", "::1/128"] + trustedProxyCidrs: ["127.0.0.1/32", "10.0.0.0/8", "::1/128"], }; assert.equal( resolveTrustedRequestIp(config, { headers: { "x-forwarded-for": "198.51.100.10" }, - remoteAddress: "127.0.0.1" + remoteAddress: "127.0.0.1", }), - "198.51.100.10" + "198.51.100.10", ); assert.equal( resolveTrustedRequestIp(config, { headers: { "x-forwarded-for": "198.51.100.10" }, - remoteAddress: "203.0.113.250" + remoteAddress: "203.0.113.250", }), - "203.0.113.250" + "203.0.113.250", ); }); @@ -30,10 +30,10 @@ test("resolveTrustedRequestIp still uses the configured trusted hop", () => { { trustProxyHops: 1, trustedProxyCidrs: ["127.0.0.1/32"] }, { headers: { "x-forwarded-for": "203.0.113.1, 198.51.100.50" }, - remoteAddress: "127.0.0.1" - } + remoteAddress: "127.0.0.1", + }, ), - "198.51.100.50" + "198.51.100.50", ); }); @@ -43,9 +43,9 @@ test("resolveTrustedRequestIp supports ipv6 trusted proxy cidrs", () => { { trustProxyHops: 1, trustedProxyCidrs: ["::1/128", "fc00::/7"] }, { headers: { "x-forwarded-for": "198.51.100.20" }, - remoteAddress: "::1" - } + remoteAddress: "::1", + }, ), - "198.51.100.20" + "198.51.100.20", ); }); From d0a1871eb92fa6b7bca439b381df529e8a81cb59 Mon Sep 17 00:00:00 2001 From: UE-DND <100979820+UE-DND@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:41:50 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=8F=B0=E5=89=8D=E7=AB=AF=E4=B8=BA=20React?= =?UTF-8?q?=20+=20Refine=20+=20Antd=20=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 27 +- pnpm-lock.yaml | 5652 +++++++++++++---- web/src/App.test.tsx | 392 +- web/src/App.tsx | 1614 ----- web/src/api/client.ts | 56 + web/src/api/errors.ts | 12 + web/src/api/types.ts | 92 + web/src/app/App.tsx | 52 + .../app/providers/access-control-provider.ts | 159 + web/src/app/providers/auth-provider.ts | 84 + web/src/app/providers/data-provider.ts | 211 + .../app/providers/notification-provider.ts | 16 + web/src/app/resources.ts | 26 + web/src/app/router.tsx | 81 + web/src/assets/logo-color.svg | 4 +- web/src/assets/logo-mono-light.svg | 4 +- .../confirmations/ConfirmActionModal.tsx | 84 + web/src/components/layout/DashboardLayout.tsx | 305 + web/src/components/layout/PermissionGuard.tsx | 33 + web/src/components/revision/RevisionDiff.tsx | 166 + .../components/secret/OneTimeSecretModal.tsx | 97 + web/src/components/status/Tags.tsx | 125 + web/src/contexts/project-context.tsx | 86 + web/src/contexts/theme-context.tsx | 56 + web/src/pages/admin/AdminReviews.tsx | 257 + web/src/pages/audit/ProjectAudit.tsx | 125 + web/src/pages/auth/Login.tsx | 125 + web/src/pages/clients/ClientCreate.tsx | 525 ++ web/src/pages/clients/ClientDetail.tsx | 1122 ++++ web/src/pages/clients/ClientList.tsx | 216 + web/src/pages/members/MemberManager.tsx | 305 + web/src/pages/projects/ProjectList.tsx | 151 + web/src/pages/projects/ProjectOverview.tsx | 166 + web/src/styles.css | 481 -- web/src/theme/theme.ts | 33 + 35 files changed, 9510 insertions(+), 3430 deletions(-) delete mode 100644 web/src/App.tsx create mode 100644 web/src/api/client.ts create mode 100644 web/src/api/errors.ts create mode 100644 web/src/api/types.ts create mode 100644 web/src/app/App.tsx create mode 100644 web/src/app/providers/access-control-provider.ts create mode 100644 web/src/app/providers/auth-provider.ts create mode 100644 web/src/app/providers/data-provider.ts create mode 100644 web/src/app/providers/notification-provider.ts create mode 100644 web/src/app/resources.ts create mode 100644 web/src/app/router.tsx create mode 100644 web/src/components/confirmations/ConfirmActionModal.tsx create mode 100644 web/src/components/layout/DashboardLayout.tsx create mode 100644 web/src/components/layout/PermissionGuard.tsx create mode 100644 web/src/components/revision/RevisionDiff.tsx create mode 100644 web/src/components/secret/OneTimeSecretModal.tsx create mode 100644 web/src/components/status/Tags.tsx create mode 100644 web/src/contexts/project-context.tsx create mode 100644 web/src/contexts/theme-context.tsx create mode 100644 web/src/pages/admin/AdminReviews.tsx create mode 100644 web/src/pages/audit/ProjectAudit.tsx create mode 100644 web/src/pages/auth/Login.tsx create mode 100644 web/src/pages/clients/ClientCreate.tsx create mode 100644 web/src/pages/clients/ClientDetail.tsx create mode 100644 web/src/pages/clients/ClientList.tsx create mode 100644 web/src/pages/members/MemberManager.tsx create mode 100644 web/src/pages/projects/ProjectList.tsx create mode 100644 web/src/pages/projects/ProjectOverview.tsx delete mode 100644 web/src/styles.css create mode 100644 web/src/theme/theme.ts diff --git a/package.json b/package.json index 2861c61..6d12e72 100644 --- a/package.json +++ b/package.json @@ -28,9 +28,19 @@ }, "pnpm": { "supportedArchitectures": { - "os": ["current", "linux"], - "cpu": ["current", "arm64", "x64"], - "libc": ["current", "musl"] + "os": [ + "current", + "linux" + ], + "cpu": [ + "current", + "arm64", + "x64" + ], + "libc": [ + "current", + "musl" + ] }, "overrides": { "lodash": "^4.18.0", @@ -38,8 +48,16 @@ } }, "dependencies": { + "@ant-design/icons": "^5.6.1", + "@ant-design/v5-patch-for-react-19": "^1.0.3", + "@refinedev/antd": "^6.0.3", + "@refinedev/core": "^5.0.12", + "@refinedev/react-router": "^2.0.4", + "@tanstack/react-query": "^5.101.2", + "antd": "^5.29.3", "axios": "^1.18.1", "axios-cookiejar-support": "^6.0.4", + "dayjs": "^1.11.21", "express": "^5.1.0", "ioredis": "^5.8.1", "jose": "^6.2.2", @@ -47,8 +65,9 @@ "pg": "^8.16.3", "react": "^19.1.1", "react-dom": "^19.1.1", + "react-router": "^7.18.1", + "react-router-dom": "^7.18.1", "resend": "^6.10.0", - "swr": "^2.4.2", "tough-cookie": "^5.1.2" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69e4a46..5d29b76 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '9.0' +lockfileVersion: "9.0" settings: autoInstallPeers: true @@ -9,15 +9,38 @@ overrides: path-to-regexp: ^8.4.0 importers: - .: dependencies: + "@ant-design/icons": + specifier: ^5.6.1 + version: 5.6.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/v5-patch-for-react-19": + specifier: ^1.0.3 + version: 1.0.3(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@refinedev/antd": + specifier: ^6.0.3 + version: 6.0.3(@refinedev/core@5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@refinedev/core": + specifier: ^5.0.12 + version: 5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@refinedev/react-router": + specifier: ^2.0.4 + version: 2.0.4(@refinedev/core@5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react-router@7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) + "@tanstack/react-query": + specifier: ^5.101.2 + version: 5.101.2(react@19.2.7) + antd: + specifier: ^5.29.3 + version: 5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) axios: specifier: ^1.18.1 version: 1.18.1 axios-cookiejar-support: specifier: ^6.0.4 version: 6.0.5(axios@1.18.1)(tough-cookie@5.1.2) + dayjs: + specifier: ^1.11.21 + version: 1.11.21 express: specifier: ^5.1.0 version: 5.2.1 @@ -39,35 +62,38 @@ importers: react-dom: specifier: ^19.1.1 version: 19.2.7(react@19.2.7) + react-router: + specifier: ^7.18.1 + version: 7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react-router-dom: + specifier: ^7.18.1 + version: 7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) resend: specifier: ^6.10.0 version: 6.12.2 - swr: - specifier: ^2.4.2 - version: 2.4.2(react@19.2.7) tough-cookie: specifier: ^5.1.2 version: 5.1.2 devDependencies: - '@testing-library/react': + "@testing-library/react": specifier: ^16.3.0 version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@types/express': + "@types/express": specifier: ^5.0.3 version: 5.0.6 - '@types/node': + "@types/node": specifier: ^24.6.0 version: 24.12.2 - '@types/pg': + "@types/pg": specifier: ^8.15.5 version: 8.20.0 - '@types/react': + "@types/react": specifier: ^19.1.16 version: 19.2.17 - '@types/react-dom': + "@types/react-dom": specifier: ^19.1.9 version: 19.2.3(@types/react@19.2.17) - '@types/supertest': + "@types/supertest": specifier: ^6.0.3 version: 6.0.3 concurrently: @@ -96,641 +122,1329 @@ importers: version: 3.2.7(@types/node@24.12.2)(jsdom@27.4.0(@noble/hashes@1.8.0))(tsx@4.20.6) packages: - - '@acemir/cssom@0.9.31': - resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} - - '@asamuzakjp/css-color@4.1.2': - resolution: {integrity: sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==} - - '@asamuzakjp/dom-selector@6.8.1': - resolution: {integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==} - - '@asamuzakjp/nwsapi@2.3.9': - resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} - - '@babel/code-frame@7.29.7': - resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.29.7': - resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} - engines: {node: '>=6.9.0'} - - '@babel/runtime@7.29.7': - resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} - engines: {node: '>=6.9.0'} - - '@csstools/color-helpers@6.1.0': - resolution: {integrity: sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==} - engines: {node: '>=20.19.0'} - - '@csstools/css-calc@3.2.1': - resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} - engines: {node: '>=20.19.0'} + "@acemir/cssom@0.9.31": + resolution: + { + integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==, + } + + "@ant-design/colors@7.2.1": + resolution: + { + integrity: sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==, + } + + "@ant-design/cssinjs-utils@1.1.3": + resolution: + { + integrity: sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==, + } peerDependencies: - '@csstools/css-parser-algorithms': ^4.0.0 - '@csstools/css-tokenizer': ^4.0.0 - - '@csstools/css-color-parser@4.1.9': - resolution: {integrity: sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==} - engines: {node: '>=20.19.0'} + react: ">=16.9.0" + react-dom: ">=16.9.0" + + "@ant-design/cssinjs@1.24.0": + resolution: + { + integrity: sha512-K4cYrJBsgvL+IoozUXYjbT6LHHNt+19a9zkvpBPxLjFHas1UpPM2A5MlhROb0BT8N8WoavM5VsP9MeSeNK/3mg==, + } peerDependencies: - '@csstools/css-parser-algorithms': ^4.0.0 - '@csstools/css-tokenizer': ^4.0.0 - - '@csstools/css-parser-algorithms@4.0.0': - resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} - engines: {node: '>=20.19.0'} + react: ">=16.0.0" + react-dom: ">=16.0.0" + + "@ant-design/fast-color@2.0.6": + resolution: + { + integrity: sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==, + } + engines: { node: ">=8.x" } + + "@ant-design/icons-svg@4.5.0": + resolution: + { + integrity: sha512-1BTUFyKPTBZ53MuTP8s0k5SFEXL7o3VHEOwLgzaoWKwnBeqIcqUtVshc4SKzhI6uACfqhJqBwBUE9FsWR3uULA==, + } + + "@ant-design/icons@5.6.1": + resolution: + { + integrity: sha512-0/xS39c91WjPAZOWsvi1//zjx6kAp4kxWwctR6kuU6p133w8RU0D2dSCvZC19uQyharg/sAvYxGYWl01BbZZfg==, + } + engines: { node: ">=8" } + peerDependencies: + react: ">=16.0.0" + react-dom: ">=16.0.0" + + "@ant-design/pro-layout@7.22.7": + resolution: + { + integrity: sha512-fvmtNA1r9SaasVIQIQt611VSlNxtVxDbQ3e+1GhYQza3tVJi/3gCZuDyfMfTnbLmf3PaW/YvLkn7MqDbzAzoLA==, + } + peerDependencies: + antd: ^4.24.15 || ^5.11.2 + react: ">=17.0.0" + react-dom: ">=17.0.0" + + "@ant-design/pro-provider@2.16.2": + resolution: + { + integrity: sha512-0KmCH1EaOND787Jz6VRMYtLNZmqfT0JPjdUfxhyOxFfnBRfrjyfZgIa6CQoAJLEUMWv57PccWS8wRHVUUk2Yiw==, + } + peerDependencies: + antd: ^4.24.15 || ^5.11.2 + react: ">=17.0.0" + react-dom: ">=17.0.0" + + "@ant-design/pro-utils@2.18.0": + resolution: + { + integrity: sha512-8+ikyrN8L8a8Ph4oeHTOJEiranTj18+9+WHCHjKNdEfukI7Rjn8xpYdLJWb2AUJkb9d4eoAqjd5+k+7w81Df0w==, + } peerDependencies: - '@csstools/css-tokenizer': ^4.0.0 + antd: ^4.24.15 || ^5.11.2 + react: ">=17.0.0" + react-dom: ">=17.0.0" + + "@ant-design/react-slick@1.1.2": + resolution: + { + integrity: sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==, + } + peerDependencies: + react: ">=16.9.0" + + "@ant-design/v5-patch-for-react-19@1.0.3": + resolution: + { + integrity: sha512-iWfZuSUl5kuhqLUw7jJXUQFMMkM7XpW7apmKzQBQHU0cpifYW4A79xIBt9YVO5IBajKpPG5UKP87Ft7Yrw1p/w==, + } + engines: { node: ">=12.x" } + peerDependencies: + antd: ">=5.22.6" + react: ">=19.0.0" + react-dom: ">=19.0.0" + + "@asamuzakjp/css-color@4.1.2": + resolution: + { + integrity: sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==, + } + + "@asamuzakjp/dom-selector@6.8.1": + resolution: + { + integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==, + } + + "@asamuzakjp/nwsapi@2.3.9": + resolution: + { + integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==, + } + + "@babel/code-frame@7.29.7": + resolution: + { + integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.29.7": + resolution: + { + integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==, + } + engines: { node: ">=6.9.0" } + + "@babel/runtime@7.29.7": + resolution: + { + integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==, + } + engines: { node: ">=6.9.0" } + + "@csstools/color-helpers@6.1.0": + resolution: + { + integrity: sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==, + } + engines: { node: ">=20.19.0" } + + "@csstools/css-calc@3.2.1": + resolution: + { + integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==, + } + engines: { node: ">=20.19.0" } + peerDependencies: + "@csstools/css-parser-algorithms": ^4.0.0 + "@csstools/css-tokenizer": ^4.0.0 + + "@csstools/css-color-parser@4.1.9": + resolution: + { + integrity: sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==, + } + engines: { node: ">=20.19.0" } + peerDependencies: + "@csstools/css-parser-algorithms": ^4.0.0 + "@csstools/css-tokenizer": ^4.0.0 + + "@csstools/css-parser-algorithms@4.0.0": + resolution: + { + integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==, + } + engines: { node: ">=20.19.0" } + peerDependencies: + "@csstools/css-tokenizer": ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.6': - resolution: {integrity: sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==} + "@csstools/css-syntax-patches-for-csstree@1.1.6": + resolution: + { + integrity: sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==, + } peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: css-tree: optional: true - '@csstools/css-tokenizer@4.0.0': - resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} - engines: {node: '>=20.19.0'} - - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} - engines: {node: '>=18'} + "@csstools/css-tokenizer@4.0.0": + resolution: + { + integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==, + } + engines: { node: ">=20.19.0" } + + "@ctrl/tinycolor@3.6.1": + resolution: + { + integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==, + } + engines: { node: ">=10" } + + "@emotion/hash@0.8.0": + resolution: + { + integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==, + } + + "@emotion/unitless@0.7.5": + resolution: + { + integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==, + } + + "@esbuild/aix-ppc64@0.25.12": + resolution: + { + integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.28.1': - resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} - engines: {node: '>=18'} + "@esbuild/aix-ppc64@0.28.1": + resolution: + { + integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} - engines: {node: '>=18'} + "@esbuild/android-arm64@0.25.12": + resolution: + { + integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.28.1': - resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} - engines: {node: '>=18'} + "@esbuild/android-arm64@0.28.1": + resolution: + { + integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} - engines: {node: '>=18'} + "@esbuild/android-arm@0.25.12": + resolution: + { + integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==, + } + engines: { node: ">=18" } cpu: [arm] os: [android] - '@esbuild/android-arm@0.28.1': - resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} - engines: {node: '>=18'} + "@esbuild/android-arm@0.28.1": + resolution: + { + integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==, + } + engines: { node: ">=18" } cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} - engines: {node: '>=18'} + "@esbuild/android-x64@0.25.12": + resolution: + { + integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==, + } + engines: { node: ">=18" } cpu: [x64] os: [android] - '@esbuild/android-x64@0.28.1': - resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} - engines: {node: '>=18'} + "@esbuild/android-x64@0.28.1": + resolution: + { + integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==, + } + engines: { node: ">=18" } cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} - engines: {node: '>=18'} + "@esbuild/darwin-arm64@0.25.12": + resolution: + { + integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.28.1': - resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} - engines: {node: '>=18'} + "@esbuild/darwin-arm64@0.28.1": + resolution: + { + integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==, + } + engines: { node: ">=18" } cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} - engines: {node: '>=18'} + "@esbuild/darwin-x64@0.25.12": + resolution: + { + integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==, + } + engines: { node: ">=18" } cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.28.1': - resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} - engines: {node: '>=18'} + "@esbuild/darwin-x64@0.28.1": + resolution: + { + integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} - engines: {node: '>=18'} + "@esbuild/freebsd-arm64@0.25.12": + resolution: + { + integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.28.1': - resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} - engines: {node: '>=18'} + "@esbuild/freebsd-arm64@0.28.1": + resolution: + { + integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==, + } + engines: { node: ">=18" } cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} - engines: {node: '>=18'} + "@esbuild/freebsd-x64@0.25.12": + resolution: + { + integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.28.1': - resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} - engines: {node: '>=18'} + "@esbuild/freebsd-x64@0.28.1": + resolution: + { + integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} - engines: {node: '>=18'} + "@esbuild/linux-arm64@0.25.12": + resolution: + { + integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==, + } + engines: { node: ">=18" } cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.28.1': - resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} - engines: {node: '>=18'} + "@esbuild/linux-arm64@0.28.1": + resolution: + { + integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==, + } + engines: { node: ">=18" } cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} - engines: {node: '>=18'} + "@esbuild/linux-arm@0.25.12": + resolution: + { + integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==, + } + engines: { node: ">=18" } cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.28.1': - resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} - engines: {node: '>=18'} + "@esbuild/linux-arm@0.28.1": + resolution: + { + integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==, + } + engines: { node: ">=18" } cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} - engines: {node: '>=18'} + "@esbuild/linux-ia32@0.25.12": + resolution: + { + integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==, + } + engines: { node: ">=18" } cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.28.1': - resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} - engines: {node: '>=18'} + "@esbuild/linux-ia32@0.28.1": + resolution: + { + integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==, + } + engines: { node: ">=18" } cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} - engines: {node: '>=18'} + "@esbuild/linux-loong64@0.25.12": + resolution: + { + integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==, + } + engines: { node: ">=18" } cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.28.1': - resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} - engines: {node: '>=18'} + "@esbuild/linux-loong64@0.28.1": + resolution: + { + integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==, + } + engines: { node: ">=18" } cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} - engines: {node: '>=18'} + "@esbuild/linux-mips64el@0.25.12": + resolution: + { + integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==, + } + engines: { node: ">=18" } cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.28.1': - resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} - engines: {node: '>=18'} + "@esbuild/linux-mips64el@0.28.1": + resolution: + { + integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==, + } + engines: { node: ">=18" } cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} - engines: {node: '>=18'} + "@esbuild/linux-ppc64@0.25.12": + resolution: + { + integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.28.1': - resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} - engines: {node: '>=18'} + "@esbuild/linux-ppc64@0.28.1": + resolution: + { + integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} - engines: {node: '>=18'} + "@esbuild/linux-riscv64@0.25.12": + resolution: + { + integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==, + } + engines: { node: ">=18" } cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.28.1': - resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} - engines: {node: '>=18'} + "@esbuild/linux-riscv64@0.28.1": + resolution: + { + integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==, + } + engines: { node: ">=18" } cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} - engines: {node: '>=18'} + "@esbuild/linux-s390x@0.25.12": + resolution: + { + integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==, + } + engines: { node: ">=18" } cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.28.1': - resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} - engines: {node: '>=18'} + "@esbuild/linux-s390x@0.28.1": + resolution: + { + integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==, + } + engines: { node: ">=18" } cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} - engines: {node: '>=18'} + "@esbuild/linux-x64@0.25.12": + resolution: + { + integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==, + } + engines: { node: ">=18" } cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.28.1': - resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} - engines: {node: '>=18'} + "@esbuild/linux-x64@0.28.1": + resolution: + { + integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==, + } + engines: { node: ">=18" } cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} - engines: {node: '>=18'} + "@esbuild/netbsd-arm64@0.25.12": + resolution: + { + integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.28.1': - resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} - engines: {node: '>=18'} + "@esbuild/netbsd-arm64@0.28.1": + resolution: + { + integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==, + } + engines: { node: ">=18" } cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} - engines: {node: '>=18'} + "@esbuild/netbsd-x64@0.25.12": + resolution: + { + integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.28.1': - resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} - engines: {node: '>=18'} + "@esbuild/netbsd-x64@0.28.1": + resolution: + { + integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==, + } + engines: { node: ">=18" } cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} - engines: {node: '>=18'} + "@esbuild/openbsd-arm64@0.25.12": + resolution: + { + integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.28.1': - resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} - engines: {node: '>=18'} + "@esbuild/openbsd-arm64@0.28.1": + resolution: + { + integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} - engines: {node: '>=18'} + "@esbuild/openbsd-x64@0.25.12": + resolution: + { + integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==, + } + engines: { node: ">=18" } cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.28.1': - resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} - engines: {node: '>=18'} + "@esbuild/openbsd-x64@0.28.1": + resolution: + { + integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==, + } + engines: { node: ">=18" } cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} + "@esbuild/openharmony-arm64@0.25.12": + resolution: + { + integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.28.1': - resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} - engines: {node: '>=18'} + "@esbuild/openharmony-arm64@0.28.1": + resolution: + { + integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} - engines: {node: '>=18'} + "@esbuild/sunos-x64@0.25.12": + resolution: + { + integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==, + } + engines: { node: ">=18" } cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.28.1': - resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} - engines: {node: '>=18'} + "@esbuild/sunos-x64@0.28.1": + resolution: + { + integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} - engines: {node: '>=18'} + "@esbuild/win32-arm64@0.25.12": + resolution: + { + integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.28.1': - resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} - engines: {node: '>=18'} + "@esbuild/win32-arm64@0.28.1": + resolution: + { + integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==, + } + engines: { node: ">=18" } cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} - engines: {node: '>=18'} + "@esbuild/win32-ia32@0.25.12": + resolution: + { + integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==, + } + engines: { node: ">=18" } cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.28.1': - resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} - engines: {node: '>=18'} + "@esbuild/win32-ia32@0.28.1": + resolution: + { + integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==, + } + engines: { node: ">=18" } cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} - engines: {node: '>=18'} + "@esbuild/win32-x64@0.25.12": + resolution: + { + integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==, + } + engines: { node: ">=18" } cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.28.1': - resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} - engines: {node: '>=18'} + "@esbuild/win32-x64@0.28.1": + resolution: + { + integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==, + } + engines: { node: ">=18" } cpu: [x64] os: [win32] - '@exodus/bytes@1.15.1': - resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + "@exodus/bytes@1.15.1": + resolution: + { + integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } peerDependencies: - '@noble/hashes': ^1.8.0 || ^2.0.0 + "@noble/hashes": ^1.8.0 || ^2.0.0 peerDependenciesMeta: - '@noble/hashes': + "@noble/hashes": optional: true - '@ioredis/commands@1.5.1': - resolution: {integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==} + "@ioredis/commands@1.5.1": + resolution: + { + integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==, + } + + "@jridgewell/sourcemap-codec@1.5.5": + resolution: + { + integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, + } + + "@koa/cors@5.0.0": + resolution: + { + integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==, + } + engines: { node: ">= 14.0.0" } + + "@koa/router@15.4.0": + resolution: + { + integrity: sha512-vKYlXtoCfcAN8z4dHiveYX55rTYOgHEYJNumK1WM9ZAwaArhreGVkyC1LTMGfUQUJyIO/SbwRFBOHeOCY8/MaQ==, + } + engines: { node: ">= 20" } + peerDependencies: + koa: ^2.0.0 || ^3.0.0 - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + "@noble/hashes@1.8.0": + resolution: + { + integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==, + } + engines: { node: ^14.21.3 || >=16 } + + "@paralleldrive/cuid2@2.3.1": + resolution: + { + integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==, + } + + "@rc-component/async-validator@5.1.2": + resolution: + { + integrity: sha512-WYbrZSjzznU1ekD0qFq2qRxt309VoS61MTG5npnFQlKYcoy9IzU8T+ZCIhq5bGAXRbXysABFWTspicMfmWFwow==, + } + engines: { node: ">=14.x" } + + "@rc-component/color-picker@2.0.1": + resolution: + { + integrity: sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + "@rc-component/context@1.4.0": + resolution: + { + integrity: sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + "@rc-component/mini-decimal@1.1.4": + resolution: + { + integrity: sha512-xiuXcaCwyOWpD8a8scdExFl+bntNphAW8XeenL1ig2en0AAZY0Pcp4pC0dI22qJ+NvxKn9RoNIoRdqYU3BLH4w==, + } + engines: { node: ">=8.x" } + + "@rc-component/mutate-observer@1.1.0": + resolution: + { + integrity: sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + "@rc-component/portal@1.1.2": + resolution: + { + integrity: sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + "@rc-component/qrcode@1.1.3": + resolution: + { + integrity: sha512-aGv6alnn4HbDEsURzKP+jv13rbi1VxmAYfBNZr5GKF1iohMNWy5tAVoJ1E3cOvzMB1kbUPvCXchM6zSFlRGPhA==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + "@rc-component/tour@1.15.1": + resolution: + { + integrity: sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + "@rc-component/trigger@2.3.1": + resolution: + { + integrity: sha512-ORENF39PeXTzM+gQEshuk460Z8N4+6DkjpxlpE7Q3gYy1iBpLrx0FOJz3h62ryrJZ/3zCAUIkT1Pb/8hHWpb3A==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + "@refinedev/antd@6.0.3": + resolution: + { + integrity: sha512-adNxHZJuca3TN4y1zXpamspqc0yi5hAqlzveTKAXLDuZ8C546xPdihmpZ/bWGG1fjYzWKLctb3YIoUw6d/WDgA==, + } + engines: { node: ">=20" } + peerDependencies: + "@refinedev/core": ^5.0.0 + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 + antd: ^5.23.0 + dayjs: ^1.10.7 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@koa/cors@5.0.0': - resolution: {integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==} - engines: {node: '>= 14.0.0'} + "@refinedev/core@5.0.12": + resolution: + { + integrity: sha512-9y5Bi9Lb7XyJmM55b8rCeBTDRCBU41p47OymJldasLfrtpUm2EwI+27DjjNpHTOugymiZsIbLlPtHCPQIXBHcg==, + } + engines: { node: ">=20" } + peerDependencies: + "@tanstack/react-query": ^5.81.5 + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@koa/router@15.4.0': - resolution: {integrity: sha512-vKYlXtoCfcAN8z4dHiveYX55rTYOgHEYJNumK1WM9ZAwaArhreGVkyC1LTMGfUQUJyIO/SbwRFBOHeOCY8/MaQ==} - engines: {node: '>= 20'} + "@refinedev/devtools-internal@2.0.2": + resolution: + { + integrity: sha512-1YYizOW1lyy9ep8eQ7TcUPBooKXIlvzTLjLdDArsQwx7P33cn2uXdqM7So5VhlNFXhjOjAKFgrH5c1jleRF8Jg==, + } + engines: { node: ">=20" } peerDependencies: - koa: ^2.0.0 || ^3.0.0 + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@noble/hashes@1.8.0': - resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} - engines: {node: ^14.21.3 || >=16} + "@refinedev/devtools-shared@2.0.2": + resolution: + { + integrity: sha512-3cTjR1mEWn0tHFZBfPD5aVpBGLUhpAkfjqYCwKrijIicr1Utp/j0BqiPRnNqTf+W71HTng3znBpUhnR83u+tuA==, + } + engines: { node: ">=20" } + peerDependencies: + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@paralleldrive/cuid2@2.3.1': - resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==} + "@refinedev/react-router@2.0.4": + resolution: + { + integrity: sha512-5s31Ao2BE0f1XMBnF1bSX1eVOAmU8eelD9EYYeTHGkcPJKZTX+gA8zdtG0GBbLXgpE4l/llfrkMoIc820ruPvQ==, + } + engines: { node: ">=20" } + peerDependencies: + "@refinedev/core": ^5.0.0 + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + react-router: ^7.0.2 + + "@refinedev/ui-types@2.0.1": + resolution: + { + integrity: sha512-Fxsgr2JEsyEVGr5rMvOasQP5tj/1yD2m4M9XqDZQ+65B/ZB/vbkbB5+ltAhNlX2UwX8jr1mo8fnutHBltYxwfA==, + } + engines: { node: ">=20" } + peerDependencies: + "@refinedev/core": ^5.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@rollup/rollup-android-arm-eabi@4.62.2': - resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==} + "@rollup/rollup-android-arm-eabi@4.62.2": + resolution: + { + integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==, + } cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.62.2': - resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==} + "@rollup/rollup-android-arm64@4.62.2": + resolution: + { + integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==, + } cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.62.2': - resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==} + "@rollup/rollup-darwin-arm64@4.62.2": + resolution: + { + integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==, + } cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.62.2': - resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==} + "@rollup/rollup-darwin-x64@4.62.2": + resolution: + { + integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==, + } cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.62.2': - resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==} + "@rollup/rollup-freebsd-arm64@4.62.2": + resolution: + { + integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==, + } cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.62.2': - resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==} + "@rollup/rollup-freebsd-x64@4.62.2": + resolution: + { + integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==, + } cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.62.2': - resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==} + "@rollup/rollup-linux-arm-gnueabihf@4.62.2": + resolution: + { + integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==, + } cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.62.2': - resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==} + "@rollup/rollup-linux-arm-musleabihf@4.62.2": + resolution: + { + integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==, + } cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.62.2': - resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==} + "@rollup/rollup-linux-arm64-gnu@4.62.2": + resolution: + { + integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==, + } cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.62.2': - resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==} + "@rollup/rollup-linux-arm64-musl@4.62.2": + resolution: + { + integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==, + } cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.62.2': - resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==} + "@rollup/rollup-linux-loong64-gnu@4.62.2": + resolution: + { + integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==, + } cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.62.2': - resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==} + "@rollup/rollup-linux-loong64-musl@4.62.2": + resolution: + { + integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==, + } cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.62.2': - resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==} + "@rollup/rollup-linux-ppc64-gnu@4.62.2": + resolution: + { + integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==, + } cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.62.2': - resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==} + "@rollup/rollup-linux-ppc64-musl@4.62.2": + resolution: + { + integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==, + } cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.62.2': - resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==} + "@rollup/rollup-linux-riscv64-gnu@4.62.2": + resolution: + { + integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==, + } cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.62.2': - resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==} + "@rollup/rollup-linux-riscv64-musl@4.62.2": + resolution: + { + integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==, + } cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.62.2': - resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==} + "@rollup/rollup-linux-s390x-gnu@4.62.2": + resolution: + { + integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==, + } cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.62.2': - resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==} + "@rollup/rollup-linux-x64-gnu@4.62.2": + resolution: + { + integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==, + } cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.62.2': - resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==} + "@rollup/rollup-linux-x64-musl@4.62.2": + resolution: + { + integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==, + } cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.62.2': - resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==} + "@rollup/rollup-openbsd-x64@4.62.2": + resolution: + { + integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==, + } cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.62.2': - resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==} + "@rollup/rollup-openharmony-arm64@4.62.2": + resolution: + { + integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==, + } cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.62.2': - resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==} + "@rollup/rollup-win32-arm64-msvc@4.62.2": + resolution: + { + integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==, + } cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.62.2': - resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==} + "@rollup/rollup-win32-ia32-msvc@4.62.2": + resolution: + { + integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==, + } cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.62.2': - resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==} + "@rollup/rollup-win32-x64-gnu@4.62.2": + resolution: + { + integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==, + } cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.62.2': - resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==} + "@rollup/rollup-win32-x64-msvc@4.62.2": + resolution: + { + integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==, + } cpu: [x64] os: [win32] - '@stablelib/base64@1.0.1': - resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} - - '@testing-library/dom@10.4.1': - resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} - engines: {node: '>=18'} - - '@testing-library/react@16.3.2': - resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} - engines: {node: '>=18'} + "@stablelib/base64@1.0.1": + resolution: + { + integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==, + } + + "@tanstack/query-core@5.101.2": + resolution: + { + integrity: sha512-hH5MLoJhF7KaIGd7q3xTXGXvslI+GYlM1Z/35aSHHWaCJWB7XvTSHYuV3eM7tw+aE0mT/xMro4M4Q9rCGHT0lw==, + } + + "@tanstack/react-query@5.101.2": + resolution: + { + integrity: sha512-seDkr6kzGzX1okaaTtZPtgA688CDPlXUz1C6xSg0ESqn04Vuc8tlrYms1s3de+znBqhPVxFRfpAfUf+6XvfPWg==, + } + peerDependencies: + react: ^18 || ^19 + + "@testing-library/dom@10.4.1": + resolution: + { + integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==, + } + engines: { node: ">=18" } + + "@testing-library/react@16.3.2": + resolution: + { + integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==, + } + engines: { node: ">=18" } peerDependencies: - '@testing-library/dom': ^10.0.0 - '@types/react': ^18.0.0 || ^19.0.0 - '@types/react-dom': ^18.0.0 || ^19.0.0 + "@testing-library/dom": ^10.0.0 + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 peerDependenciesMeta: - '@types/react': + "@types/react": optional: true - '@types/react-dom': + "@types/react-dom": optional: true - '@types/aria-query@5.0.4': - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - - '@types/body-parser@1.19.6': - resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/cookiejar@2.1.5': - resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - - '@types/express-serve-static-core@5.1.1': - resolution: {integrity: sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==} - - '@types/express@5.0.6': - resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} - - '@types/http-errors@2.0.5': - resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - - '@types/methods@1.1.4': - resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} - - '@types/node@24.12.2': - resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} - - '@types/pg@8.20.0': - resolution: {integrity: sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==} - - '@types/qs@6.15.0': - resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} - - '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - - '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + "@types/aria-query@5.0.4": + resolution: + { + integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==, + } + + "@types/body-parser@1.19.6": + resolution: + { + integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==, + } + + "@types/chai@5.2.3": + resolution: + { + integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==, + } + + "@types/connect@3.4.38": + resolution: + { + integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==, + } + + "@types/cookiejar@2.1.5": + resolution: + { + integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==, + } + + "@types/deep-eql@4.0.2": + resolution: + { + integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==, + } + + "@types/estree@1.0.9": + resolution: + { + integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==, + } + + "@types/express-serve-static-core@5.1.1": + resolution: + { + integrity: sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==, + } + + "@types/express@5.0.6": + resolution: + { + integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==, + } + + "@types/hast@2.3.10": + resolution: + { + integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==, + } + + "@types/http-errors@2.0.5": + resolution: + { + integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==, + } + + "@types/mdast@3.0.15": + resolution: + { + integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==, + } + + "@types/methods@1.1.4": + resolution: + { + integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==, + } + + "@types/node@24.12.2": + resolution: + { + integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==, + } + + "@types/pg@8.20.0": + resolution: + { + integrity: sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==, + } + + "@types/qs@6.15.0": + resolution: + { + integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==, + } + + "@types/range-parser@1.2.7": + resolution: + { + integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==, + } + + "@types/react-dom@19.2.3": + resolution: + { + integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==, + } peerDependencies: - '@types/react': ^19.2.0 - - '@types/react@19.2.17': - resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} - - '@types/send@1.2.1': - resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} - - '@types/serve-static@2.2.0': - resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==} - - '@types/superagent@8.1.9': - resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} - - '@types/supertest@6.0.3': - resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==} - - '@vitest/expect@3.2.7': - resolution: {integrity: sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==} - - '@vitest/mocker@3.2.7': - resolution: {integrity: sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==} + "@types/react": ^19.2.0 + + "@types/react@19.2.17": + resolution: + { + integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==, + } + + "@types/send@1.2.1": + resolution: + { + integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==, + } + + "@types/serve-static@2.2.0": + resolution: + { + integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==, + } + + "@types/superagent@8.1.9": + resolution: + { + integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==, + } + + "@types/supertest@6.0.3": + resolution: + { + integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==, + } + + "@types/unist@2.0.11": + resolution: + { + integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==, + } + + "@umijs/route-utils@4.0.3": + resolution: + { + integrity: sha512-zPEcYhl1cSfkSRDzzGgoD1mDvGjxoOTJFvkn55srfgdQ3NZe2ZMCScCU6DEnOxuKP1XDVf8pqyqCDVd2+RCQIw==, + } + + "@umijs/use-params@1.0.9": + resolution: + { + integrity: sha512-QlN0RJSBVQBwLRNxbxjQ5qzqYIGn+K7USppMoIOVlf7fxXHsnQZ2bEsa6Pm74bt6DVQxpUE8HqvdStn6Y9FV1w==, + } + peerDependencies: + react: "*" + + "@vitest/expect@3.2.7": + resolution: + { + integrity: sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==, + } + + "@vitest/mocker@3.2.7": + resolution: + { + integrity: sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==, + } peerDependencies: msw: ^2.4.9 vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 @@ -740,310 +1454,645 @@ packages: vite: optional: true - '@vitest/pretty-format@3.2.7': - resolution: {integrity: sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==} - - '@vitest/runner@3.2.7': - resolution: {integrity: sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==} - - '@vitest/snapshot@3.2.7': - resolution: {integrity: sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==} - - '@vitest/spy@3.2.7': - resolution: {integrity: sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==} - - '@vitest/utils@3.2.7': - resolution: {integrity: sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==} + "@vitest/pretty-format@3.2.7": + resolution: + { + integrity: sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==, + } + + "@vitest/runner@3.2.7": + resolution: + { + integrity: sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==, + } + + "@vitest/snapshot@3.2.7": + resolution: + { + integrity: sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==, + } + + "@vitest/spy@3.2.7": + resolution: + { + integrity: sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==, + } + + "@vitest/utils@3.2.7": + resolution: + { + integrity: sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==, + } accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==, + } + engines: { node: ">= 0.6" } accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==, + } + engines: { node: ">= 0.6" } agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + resolution: + { + integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, + } + engines: { node: ">= 6.0.0" } agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==, + } + engines: { node: ">= 14" } ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: ">=8" } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: ">=8" } ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, + } + engines: { node: ">=10" } + + antd@5.29.3: + resolution: + { + integrity: sha512-3DdbGCa9tWAJGcCJ6rzR8EJFsv2CtyEbkVabZE14pfgUHfCicWCj0/QzQVLDYg8CPfQk9BH7fHCoTXHTy7MP/A==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + resolution: + { + integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==, + } asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + resolution: + { + integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==, + } assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==, + } + engines: { node: ">=12" } asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } axios-cookiejar-support@6.0.5: - resolution: {integrity: sha512-ldPOQCJWB0ipugkTNVB8QRl/5L2UgfmVNVQtS9en1JQJ1wW588PqAmymnwmmgc12HLDzDtsJ28xE2ppj4rD4ng==} - engines: {node: '>=20.0.0'} + resolution: + { + integrity: sha512-ldPOQCJWB0ipugkTNVB8QRl/5L2UgfmVNVQtS9en1JQJ1wW588PqAmymnwmmgc12HLDzDtsJ28xE2ppj4rD4ng==, + } + engines: { node: ">=20.0.0" } peerDependencies: - axios: '>=0.20.0' - tough-cookie: '>=4.0.0' + axios: ">=0.20.0" + tough-cookie: ">=4.0.0" axios@1.18.1: - resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} + resolution: + { + integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==, + } + + bail@1.0.5: + resolution: + { + integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==, + } bidi-js@1.0.3: - resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + resolution: + { + integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==, + } body-parser@2.2.2: - resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==, + } + engines: { node: ">=18" } bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, + } + engines: { node: ">= 0.8" } cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, + } + engines: { node: ">=8" } call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==, + } + engines: { node: ">= 0.4" } call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==, + } + engines: { node: ">= 0.4" } + + ccount@1.1.0: + resolution: + { + integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==, + } chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==, + } + engines: { node: ">=18" } chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: ">=10" } + + character-entities-legacy@1.1.4: + resolution: + { + integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==, + } + + character-entities@1.2.4: + resolution: + { + integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==, + } + + character-reference-invalid@1.1.4: + resolution: + { + integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==, + } check-error@2.1.3: - resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} - engines: {node: '>= 16'} + resolution: + { + integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==, + } + engines: { node: ">= 16" } + + classnames@2.5.1: + resolution: + { + integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==, + } cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: ">=12" } cluster-key-slot@1.1.2: - resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==, + } + engines: { node: ">=0.10.0" } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: ">=7.0.0" } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: ">= 0.8" } + + comma-separated-tokens@1.0.8: + resolution: + { + integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==, + } component-emitter@1.3.1: - resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + resolution: + { + integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==, + } + + compute-scroll-into-view@3.1.1: + resolution: + { + integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==, + } concurrently@9.2.4: - resolution: {integrity: sha512-TZ0CEhyzvFjgtAvHTusDMgj7wNdihCh7LLLrzdUOXIhdlnL2JBBGA9eJxR24rtqgmdjh3OA3hrN1rCHj6HM8qA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-TZ0CEhyzvFjgtAvHTusDMgj7wNdihCh7LLLrzdUOXIhdlnL2JBBGA9eJxR24rtqgmdjh3OA3hrN1rCHj6HM8qA==, + } + engines: { node: ">=18" } hasBin: true content-disposition@1.0.1: - resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==, + } + engines: { node: ">=18" } content-disposition@1.1.0: - resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==, + } + engines: { node: ">=18" } content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, + } + engines: { node: ">= 0.6" } cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} + resolution: + { + integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==, + } + engines: { node: ">=6.6.0" } cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==, + } + engines: { node: ">= 0.6" } + + cookie@1.1.1: + resolution: + { + integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==, + } + engines: { node: ">=18" } cookiejar@2.1.4: - resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + resolution: + { + integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==, + } cookies@0.9.1: - resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==, + } + engines: { node: ">= 0.8" } + + copy-to-clipboard@3.3.3: + resolution: + { + integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==, + } css-tree@3.2.1: - resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + resolution: + { + integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==, + } + engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0 } cssstyle@5.3.7: - resolution: {integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==, + } + engines: { node: ">=20" } csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + resolution: + { + integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, + } data-urls@6.0.1: - resolution: {integrity: sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==, + } + engines: { node: ">=20" } + + dayjs@1.11.21: + resolution: + { + integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==, + } debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, + } + engines: { node: ">=6.0" } peerDependencies: - supports-color: '*' + supports-color: "*" peerDependenciesMeta: supports-color: optional: true decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + resolution: + { + integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==, + } deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==, + } + engines: { node: ">=6" } deep-equal@1.0.1: - resolution: {integrity: sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==} + resolution: + { + integrity: sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==, + } delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: ">=0.4.0" } delegates@1.0.0: - resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + resolution: + { + integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==, + } denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} + resolution: + { + integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==, + } + engines: { node: ">=0.10" } depd@1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==, + } + engines: { node: ">= 0.6" } depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, + } + engines: { node: ">= 0.8" } dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, + } + engines: { node: ">=6" } destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + resolution: + { + integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==, + } + engines: { node: ">= 0.8", npm: 1.2.8000 || >= 1.4.16 } dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + resolution: + { + integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==, + } dom-accessibility-api@0.5.16: - resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + resolution: + { + integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==, + } dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==, + } + engines: { node: ">= 0.4" } ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + resolution: + { + integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, + } emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==, + } + engines: { node: ">= 0.8" } entities@8.0.0: - resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} - engines: {node: '>=20.19.0'} + resolution: + { + integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==, + } + engines: { node: ">=20.19.0" } + + error-stack-parser@2.1.4: + resolution: + { + integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==, + } es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, + } + engines: { node: ">= 0.4" } es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, + } + engines: { node: ">= 0.4" } es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + resolution: + { + integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==, + } es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==, + } + engines: { node: ">= 0.4" } es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==, + } + engines: { node: ">= 0.4" } esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==, + } + engines: { node: ">=18" } hasBin: true esbuild@0.28.1: - resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==, + } + engines: { node: ">=18" } hasBin: true escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, + } + engines: { node: ">=6" } escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + resolution: + { + integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, + } + + escape-string-regexp@4.0.0: + resolution: + { + integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, + } + engines: { node: ">=10" } estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + resolution: + { + integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, + } eta@4.5.1: - resolution: {integrity: sha512-EaNCGm+8XEIU7YNcc+THptWAO5NfKBHHARxt+wxZljj9bTr/+arRoOm9/MpGt4n6xn9fLnPFRSoLD0WFYGFUxQ==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-EaNCGm+8XEIU7YNcc+THptWAO5NfKBHHARxt+wxZljj9bTr/+arRoOm9/MpGt4n6xn9fLnPFRSoLD0WFYGFUxQ==, + } + engines: { node: ">=20" } etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, + } + engines: { node: ">= 0.6" } expect-type@1.4.0: - resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==, + } + engines: { node: ">=12.0.0" } express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==, + } + engines: { node: ">= 18" } + + extend@3.0.2: + resolution: + { + integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==, + } fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + resolution: + { + integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==, + } fast-sha256@1.3.0: - resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} + resolution: + { + integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==, + } fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, + } + engines: { node: ">=12.0.0" } peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -1051,92 +2100,155 @@ packages: optional: true finalhandler@2.1.1: - resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} - engines: {node: '>= 18.0.0'} + resolution: + { + integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==, + } + engines: { node: ">= 18.0.0" } follow-redirects@1.16.0: - resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==, + } + engines: { node: ">=4.0" } peerDependencies: - debug: '*' + debug: "*" peerDependenciesMeta: debug: optional: true form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==, + } + engines: { node: ">= 6" } formidable@3.5.4: - resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==, + } + engines: { node: ">=14.0.0" } forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, + } + engines: { node: ">= 0.6" } fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==, + } + engines: { node: ">= 0.6" } fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==, + } + engines: { node: ">= 0.8" } fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==, + } + engines: { node: ">= 0.4" } get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==, + } + engines: { node: ">= 0.4" } get-tsconfig@4.14.0: - resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + resolution: + { + integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==, + } gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==, + } + engines: { node: ">= 0.4" } has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: ">=8" } has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==, + } + engines: { node: ">= 0.4" } has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==, + } + engines: { node: ">= 0.4" } hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==, + } + engines: { node: ">= 0.4" } html-encoding-sniffer@6.0.0: - resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } http-assert@1.5.0: - resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==, + } + engines: { node: ">= 0.8" } http-cookie-agent@7.0.3: - resolution: {integrity: sha512-EeZo7CGhfqPW6R006rJa4QtZZUpBygDa2HZH3DJqsTzTjyRE6foDBVQIv/pjVsxHC8z2GIdbB1Hvn9SRorP3WQ==} - engines: {node: '>=20.0.0'} + resolution: + { + integrity: sha512-EeZo7CGhfqPW6R006rJa4QtZZUpBygDa2HZH3DJqsTzTjyRE6foDBVQIv/pjVsxHC8z2GIdbB1Hvn9SRorP3WQ==, + } + engines: { node: ">=20.0.0" } peerDependencies: tough-cookie: ^4.0.0 || ^5.0.0 || ^6.0.0 undici: ^7.0.0 @@ -1145,62 +2257,154 @@ packages: optional: true http-errors@1.8.1: - resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==, + } + engines: { node: ">= 0.6" } http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==, + } + engines: { node: ">= 0.8" } http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==, + } + engines: { node: ">= 14" } https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, + } + engines: { node: ">= 6" } https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==, + } + engines: { node: ">= 14" } iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==, + } + engines: { node: ">=0.10.0" } inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } + + inline-style-parser@0.1.1: + resolution: + { + integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==, + } ioredis@5.10.1: - resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} - engines: {node: '>=12.22.0'} + resolution: + { + integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==, + } + engines: { node: ">=12.22.0" } ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, + } + engines: { node: ">= 0.10" } + + is-alphabetical@1.0.4: + resolution: + { + integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==, + } + + is-alphanumerical@1.0.4: + resolution: + { + integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==, + } + + is-buffer@2.0.5: + resolution: + { + integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==, + } + engines: { node: ">=4" } + + is-decimal@1.0.4: + resolution: + { + integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==, + } is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: ">=8" } + + is-hexadecimal@1.0.4: + resolution: + { + integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==, + } + + is-plain-obj@2.1.0: + resolution: + { + integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==, + } + engines: { node: ">=8" } is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + resolution: + { + integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==, + } is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + resolution: + { + integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==, + } jose@6.2.2: - resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + resolution: + { + integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==, + } js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + resolution: + { + integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==, + } jsdom@27.4.0: - resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } peerDependencies: canvas: ^3.0.0 peerDependenciesMeta: @@ -1208,516 +2412,1631 @@ packages: optional: true jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, + } + engines: { node: ">=6" } hasBin: true + json2mq@0.2.0: + resolution: + { + integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==, + } + keygrip@1.1.0: - resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==, + } + engines: { node: ">= 0.6" } koa-compose@4.1.0: - resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} + resolution: + { + integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==, + } koa@3.2.0: - resolution: {integrity: sha512-TrM4/tnNY7uJ1aW55sIIa+dqBvc4V14WRIAlGcWat9wV5pRS9Wr5Zk2ZTjQP1jtfIHDoHiSbPuV08P0fUZo2pg==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-TrM4/tnNY7uJ1aW55sIIa+dqBvc4V14WRIAlGcWat9wV5pRS9Wr5Zk2ZTjQP1jtfIHDoHiSbPuV08P0fUZo2pg==, + } + engines: { node: ">= 18" } + + lodash-es@4.18.1: + resolution: + { + integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==, + } lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + resolution: + { + integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==, + } lodash.isarguments@3.1.0: - resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + resolution: + { + integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==, + } + + lodash@4.18.1: + resolution: + { + integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==, + } + + longest-streak@2.0.4: + resolution: + { + integrity: sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==, + } + + loose-envify@1.4.0: + resolution: + { + integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==, + } + hasBin: true loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + resolution: + { + integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==, + } lru-cache@11.5.2: - resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==, + } + engines: { node: 20 || >=22 } lz-string@1.5.0: - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + resolution: + { + integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==, + } hasBin: true magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + resolution: + { + integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, + } + + markdown-table@2.0.0: + resolution: + { + integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==, + } math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==, + } + engines: { node: ">= 0.4" } + + mdast-util-definitions@4.0.0: + resolution: + { + integrity: sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==, + } + + mdast-util-find-and-replace@1.1.1: + resolution: + { + integrity: sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==, + } + + mdast-util-from-markdown@0.8.5: + resolution: + { + integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==, + } + + mdast-util-gfm-autolink-literal@0.1.3: + resolution: + { + integrity: sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==, + } + + mdast-util-gfm-strikethrough@0.2.3: + resolution: + { + integrity: sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==, + } + + mdast-util-gfm-table@0.1.6: + resolution: + { + integrity: sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==, + } + + mdast-util-gfm-task-list-item@0.1.6: + resolution: + { + integrity: sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==, + } + + mdast-util-gfm@0.1.2: + resolution: + { + integrity: sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==, + } + + mdast-util-to-hast@10.2.0: + resolution: + { + integrity: sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==, + } + + mdast-util-to-markdown@0.6.5: + resolution: + { + integrity: sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==, + } + + mdast-util-to-string@2.0.0: + resolution: + { + integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==, + } mdn-data@2.27.1: - resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + resolution: + { + integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==, + } + + mdurl@1.0.1: + resolution: + { + integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==, + } media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==, + } + engines: { node: ">= 0.8" } merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==, + } + engines: { node: ">=18" } methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==, + } + engines: { node: ">= 0.6" } + + micromark-extension-gfm-autolink-literal@0.5.7: + resolution: + { + integrity: sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==, + } + + micromark-extension-gfm-strikethrough@0.6.5: + resolution: + { + integrity: sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==, + } + + micromark-extension-gfm-table@0.4.3: + resolution: + { + integrity: sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==, + } + + micromark-extension-gfm-tagfilter@0.3.0: + resolution: + { + integrity: sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==, + } + + micromark-extension-gfm-task-list-item@0.3.3: + resolution: + { + integrity: sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==, + } + + micromark-extension-gfm@0.3.3: + resolution: + { + integrity: sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==, + } + + micromark@2.11.4: + resolution: + { + integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==, + } mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: ">= 0.6" } mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==, + } + engines: { node: ">= 0.6" } mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: ">= 0.6" } mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==, + } + engines: { node: ">=18" } mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} + resolution: + { + integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==, + } + engines: { node: ">=4.0.0" } hasBin: true ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } nanoid@3.3.16: - resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { + integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true nanoid@5.1.9: - resolution: {integrity: sha512-ZUvP7KeBLe3OZ1ypw6dI/TzYJuvHP77IM4Ry73waSQTLn8/g8rpdjfyVAh7t1/+FjBtG4lCP42MEbDxOsRpBMw==} - engines: {node: ^18 || >=20} + resolution: + { + integrity: sha512-ZUvP7KeBLe3OZ1ypw6dI/TzYJuvHP77IM4Ry73waSQTLn8/g8rpdjfyVAh7t1/+FjBtG4lCP42MEbDxOsRpBMw==, + } + engines: { node: ^18 || >=20 } hasBin: true negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, + } + engines: { node: ">= 0.6" } negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==, + } + engines: { node: ">= 0.6" } + + object-assign@4.1.1: + resolution: + { + integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, + } + engines: { node: ">=0.10.0" } object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==, + } + engines: { node: ">= 0.4" } oidc-provider@9.8.2: - resolution: {integrity: sha512-Iu/VahRoAhgmzKdvqSX/4ZzrG11Zf6NHuhu1wLkoblBnMUIwud++D2lftK8jV/gLhRl3Fppa3RINYCf/675cjw==} + resolution: + { + integrity: sha512-Iu/VahRoAhgmzKdvqSX/4ZzrG11Zf6NHuhu1wLkoblBnMUIwud++D2lftK8jV/gLhRl3Fppa3RINYCf/675cjw==, + } on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, + } + engines: { node: ">= 0.8" } once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } + + papaparse@5.5.4: + resolution: + { + integrity: sha512-SwzWD9gl/ElwYLCI0nUja1mFJzjq2D8ziShfNBa7zCHzkOozeOGDwHWQ+tvCzEZcewecWZ5U7kUopDnG+DFYEQ==, + } + + parse-entities@2.0.0: + resolution: + { + integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==, + } parse5@8.0.1: - resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + resolution: + { + integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==, + } parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, + } + engines: { node: ">= 0.8" } path-to-regexp@8.4.2: - resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + resolution: + { + integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==, + } pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + resolution: + { + integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, + } pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} + resolution: + { + integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==, + } + engines: { node: ">= 14.16" } pg-cloudflare@1.3.0: - resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} + resolution: + { + integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==, + } pg-connection-string@2.12.0: - resolution: {integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==} + resolution: + { + integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==, + } pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} + resolution: + { + integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==, + } + engines: { node: ">=4.0.0" } pg-pool@3.13.0: - resolution: {integrity: sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==} + resolution: + { + integrity: sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==, + } peerDependencies: - pg: '>=8.0' + pg: ">=8.0" pg-protocol@1.13.0: - resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} + resolution: + { + integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==, + } pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==, + } + engines: { node: ">=4" } pg@8.20.0: - resolution: {integrity: sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==} - engines: {node: '>= 16.0.0'} + resolution: + { + integrity: sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==, + } + engines: { node: ">= 16.0.0" } peerDependencies: - pg-native: '>=3.0.1' + pg-native: ">=3.0.1" peerDependenciesMeta: pg-native: optional: true pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + resolution: + { + integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==, + } picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } picomatch@4.0.5: - resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==, + } + engines: { node: ">=12" } + + pluralize@8.0.0: + resolution: + { + integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==, + } + engines: { node: ">=4" } postal-mime@2.7.4: - resolution: {integrity: sha512-0WdnFQYUrPGGTFu1uOqD2s7omwua8xaeYGdO6rb88oD5yJ/4pPHDA4sdWqfD8wQVfCny563n/HQS7zTFft+f/g==} + resolution: + { + integrity: sha512-0WdnFQYUrPGGTFu1uOqD2s7omwua8xaeYGdO6rb88oD5yJ/4pPHDA4sdWqfD8wQVfCny563n/HQS7zTFft+f/g==, + } postcss@8.5.18: - resolution: {integrity: sha512-xdB1oSLHbz1vRWgCDalrCqEFTWzFlhqFC5tIHLMOSUIjhm3XXQ1qrFy8S/ESr1JYRRXqM3c1QFiMZUJdUTqyMQ==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { + integrity: sha512-xdB1oSLHbz1vRWgCDalrCqEFTWzFlhqFC5tIHLMOSUIjhm3XXQ1qrFy8S/ESr1JYRRXqM3c1QFiMZUJdUTqyMQ==, + } + engines: { node: ^10 || ^12 || >=14 } postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==, + } + engines: { node: ">=4" } postgres-bytea@1.0.1: - resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==, + } + engines: { node: ">=0.10.0" } postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==, + } + engines: { node: ">=0.10.0" } postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==, + } + engines: { node: ">=0.10.0" } prettier@3.8.3: - resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==, + } + engines: { node: ">=14" } hasBin: true pretty-format@27.5.1: - resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + resolution: + { + integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==, + } + engines: { node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0 } + + prop-types@15.8.1: + resolution: + { + integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==, + } + + property-information@5.6.0: + resolution: + { + integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==, + } proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, + } + engines: { node: ">= 0.10" } proxy-from-env@2.1.0: - resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==, + } + engines: { node: ">=10" } punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, + } + engines: { node: ">=6" } qs@6.15.1: - resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==, + } + engines: { node: ">=0.6" } quick-lru@7.3.0: - resolution: {integrity: sha512-k9lSsjl36EJdK7I06v7APZCbyGT2vMTsYSRX1Q2nbYmnkBqgUhRkAuzH08Ciotteu/PLJmIF2+tti7o3C/ts2g==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-k9lSsjl36EJdK7I06v7APZCbyGT2vMTsYSRX1Q2nbYmnkBqgUhRkAuzH08Ciotteu/PLJmIF2+tti7o3C/ts2g==, + } + engines: { node: ">=18" } range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==, + } + engines: { node: ">= 0.6" } raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==, + } + engines: { node: ">= 0.10" } + + rc-cascader@3.34.0: + resolution: + { + integrity: sha512-KpXypcvju9ptjW9FaN2NFcA2QH9E9LHKq169Y0eWtH4e/wHQ5Wh5qZakAgvb8EKZ736WZ3B0zLLOBsrsja5Dag==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-checkbox@3.5.0: + resolution: + { + integrity: sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-collapse@3.9.0: + resolution: + { + integrity: sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-dialog@9.6.0: + resolution: + { + integrity: sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-drawer@7.3.0: + resolution: + { + integrity: sha512-DX6CIgiBWNpJIMGFO8BAISFkxiuKitoizooj4BDyee8/SnBn0zwO2FHrNDpqqepj0E/TFTDpmEBCyFuTgC7MOg==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-dropdown@4.2.1: + resolution: + { + integrity: sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==, + } + peerDependencies: + react: ">=16.11.0" + react-dom: ">=16.11.0" + + rc-field-form@2.7.1: + resolution: + { + integrity: sha512-vKeSifSJ6HoLaAB+B8aq/Qgm8a3dyxROzCtKNCsBQgiverpc4kWDQihoUwzUj+zNWJOykwSY4dNX3QrGwtVb9A==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-image@7.12.0: + resolution: + { + integrity: sha512-cZ3HTyyckPnNnUb9/DRqduqzLfrQRyi+CdHjdqgsyDpI3Ln5UX1kXnAhPBSJj9pVRzwRFgqkN7p9b6HBDjmu/Q==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-input-number@9.5.0: + resolution: + { + integrity: sha512-bKaEvB5tHebUURAEXw35LDcnRZLq3x1k7GxfAqBMzmpHkDGzjAtnUL8y4y5N15rIFIg5IJgwr211jInl3cipag==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-input@1.8.0: + resolution: + { + integrity: sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==, + } + peerDependencies: + react: ">=16.0.0" + react-dom: ">=16.0.0" + + rc-mentions@2.20.0: + resolution: + { + integrity: sha512-w8HCMZEh3f0nR8ZEd466ATqmXFCMGMN5UFCzEUL0bM/nGw/wOS2GgRzKBcm19K++jDyuWCOJOdgcKGXU3fXfbQ==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-menu@9.16.1: + resolution: + { + integrity: sha512-ghHx6/6Dvp+fw8CJhDUHFHDJ84hJE3BXNCzSgLdmNiFErWSOaZNsihDAsKq9ByTALo/xkNIwtDFGIl6r+RPXBg==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-motion@2.9.5: + resolution: + { + integrity: sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-notification@5.6.4: + resolution: + { + integrity: sha512-KcS4O6B4qzM3KH7lkwOB7ooLPZ4b6J+VMmQgT51VZCeEcmghdeR4IrMcFq0LG+RPdnbe/ArT086tGM8Snimgiw==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-overflow@1.5.0: + resolution: + { + integrity: sha512-Lm/v9h0LymeUYJf0x39OveU52InkdRXqnn2aYXfWmo8WdOonIKB2kfau+GF0fWq6jPgtdO9yMqveGcK6aIhJmg==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-pagination@5.1.0: + resolution: + { + integrity: sha512-8416Yip/+eclTFdHXLKTxZvn70duYVGTvUUWbckCCZoIl3jagqke3GLsFrMs0bsQBikiYpZLD9206Ej4SOdOXQ==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-picker@4.11.3: + resolution: + { + integrity: sha512-MJ5teb7FlNE0NFHTncxXQ62Y5lytq6sh5nUw0iH8OkHL/TjARSEvSHpr940pWgjGANpjCwyMdvsEV55l5tYNSg==, + } + engines: { node: ">=8.x" } + peerDependencies: + date-fns: ">= 2.x" + dayjs: ">= 1.x" + luxon: ">= 3.x" + moment: ">= 2.x" + react: ">=16.9.0" + react-dom: ">=16.9.0" + peerDependenciesMeta: + date-fns: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + + rc-progress@4.0.0: + resolution: + { + integrity: sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-rate@2.13.1: + resolution: + { + integrity: sha512-QUhQ9ivQ8Gy7mtMZPAjLbxBt5y9GRp65VcUyGUMF3N3fhiftivPHdpuDIaWIMOTEprAjZPC08bls1dQB+I1F2Q==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-resize-observer@1.4.3: + resolution: + { + integrity: sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-segmented@2.7.1: + resolution: + { + integrity: sha512-izj1Nw/Dw2Vb7EVr+D/E9lUTkBe+kKC+SAFSU9zqr7WV2W5Ktaa9Gc7cB2jTqgk8GROJayltaec+DBlYKc6d+g==, + } + peerDependencies: + react: ">=16.0.0" + react-dom: ">=16.0.0" + + rc-select@14.16.8: + resolution: + { + integrity: sha512-NOV5BZa1wZrsdkKaiK7LHRuo5ZjZYMDxPP6/1+09+FB4KoNi8jcG1ZqLE3AVCxEsYMBe65OBx71wFoHRTP3LRg==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: "*" + react-dom: "*" + + rc-slider@11.1.9: + resolution: + { + integrity: sha512-h8IknhzSh3FEM9u8ivkskh+Ef4Yo4JRIY2nj7MrH6GQmrwV6mcpJf5/4KgH5JaVI1H3E52yCdpOlVyGZIeph5A==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-steps@6.0.1: + resolution: + { + integrity: sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-switch@4.1.0: + resolution: + { + integrity: sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-table@7.54.0: + resolution: + { + integrity: sha512-/wDTkki6wBTjwylwAGjpLKYklKo9YgjZwAU77+7ME5mBoS32Q4nAwoqhA2lSge6fobLW3Tap6uc5xfwaL2p0Sw==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-tabs@15.7.0: + resolution: + { + integrity: sha512-ZepiE+6fmozYdWf/9gVp7k56PKHB1YYoDsKeQA1CBlJ/POIhjkcYiv0AGP0w2Jhzftd3AVvZP/K+V+Lpi2ankA==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-textarea@1.10.2: + resolution: + { + integrity: sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-tooltip@6.4.0: + resolution: + { + integrity: sha512-kqyivim5cp8I5RkHmpsp1Nn/Wk+1oeloMv9c7LXNgDxUpGm+RbXJGL+OPvDlcRnx9DBeOe4wyOIl4OKUERyH1g==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-tree-select@5.27.0: + resolution: + { + integrity: sha512-2qTBTzwIT7LRI1o7zLyrCzmo5tQanmyGbSaGTIf7sYimCklAToVVfpMC6OAldSKolcnjorBYPNSKQqJmN3TCww==, + } + peerDependencies: + react: "*" + react-dom: "*" + + rc-tree@5.13.1: + resolution: + { + integrity: sha512-FNhIefhftobCdUJshO7M8uZTA9F4OPGVXqGfZkkD/5soDeOhwO06T/aKTrg0WD8gRg/pyfq+ql3aMymLHCTC4A==, + } + engines: { node: ">=10.x" } + peerDependencies: + react: "*" + react-dom: "*" + + rc-upload@4.11.0: + resolution: + { + integrity: sha512-ZUyT//2JAehfHzjWowqROcwYJKnZkIUGWaTE/VogVrepSl7AFNbQf4+zGfX4zl9Vrj/Jm8scLO0R6UlPDKK4wA==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-util@5.44.4: + resolution: + { + integrity: sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + + rc-virtual-list@3.19.2: + resolution: + { + integrity: sha512-Ys6NcjwGkuwkeaWBDqfI3xWuZ7rDiQXlH1o2zLfFzATfEgXcqpk8CkgMfbJD81McqjcJVez25a3kPxCR807evA==, + } + engines: { node: ">=8.x" } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" react-dom@19.2.7: - resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} + resolution: + { + integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==, + } peerDependencies: react: ^19.2.7 + react-is@16.13.1: + resolution: + { + integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==, + } + react-is@17.0.2: - resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + resolution: + { + integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==, + } + + react-is@18.3.1: + resolution: + { + integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, + } + + react-markdown@6.0.3: + resolution: + { + integrity: sha512-kQbpWiMoBHnj9myLlmZG9T1JdoT/OEyHK7hqM6CqFT14MAkgWiWBUYijLyBmxbntaN6dCDicPcUhWhci1QYodg==, + } + peerDependencies: + "@types/react": ">=16" + react: ">=16" + + react-router-dom@7.18.1: + resolution: + { + integrity: sha512-KaZh+X/6UtEp28x51AUYZDMg9NGoz2ja3dNHa+ta/tk40vCzKhQ/RypCWBMLbmDr6//E24Vv5uPsrqXFozdkAg==, + } + engines: { node: ">=20.0.0" } + peerDependencies: + react: ">=18" + react-dom: ">=18" + + react-router@7.18.1: + resolution: + { + integrity: sha512-GDLgg3i3uM0aeJO3Fm+TCS+sDQ7gu12T6x0qdTEzcwqEfleci7JwugVNIF3U//0FWKnJT7ptG+20B2jfDqnZAg==, + } + engines: { node: ">=20.0.0" } + peerDependencies: + react: ">=18" + react-dom: ">=18" + peerDependenciesMeta: + react-dom: + optional: true react@19.2.7: - resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==, + } + engines: { node: ">=0.10.0" } redis-errors@1.2.0: - resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==, + } + engines: { node: ">=4" } redis-parser@3.0.0: - resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==, + } + engines: { node: ">=4" } + + remark-gfm@1.0.0: + resolution: + { + integrity: sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==, + } + + remark-parse@9.0.0: + resolution: + { + integrity: sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==, + } + + remark-rehype@8.1.0: + resolution: + { + integrity: sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA==, + } + + repeat-string@1.6.1: + resolution: + { + integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==, + } + engines: { node: ">=0.10" } require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: ">=0.10.0" } require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, + } + engines: { node: ">=0.10.0" } resend@6.12.2: - resolution: {integrity: sha512-xwgmU4b0OqoabJsIoK/x0Whk0Fcs3bpbK4i/DEWPiE5hYJHyHl0TbB6QbI3gIr+bLdLUJ1GYm/fe41aVFuHXgw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-xwgmU4b0OqoabJsIoK/x0Whk0Fcs3bpbK4i/DEWPiE5hYJHyHl0TbB6QbI3gIr+bLdLUJ1GYm/fe41aVFuHXgw==, + } + engines: { node: ">=20" } peerDependencies: - '@react-email/render': '*' + "@react-email/render": "*" peerDependenciesMeta: - '@react-email/render': + "@react-email/render": optional: true + resize-observer-polyfill@1.5.1: + resolution: + { + integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==, + } + resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolution: + { + integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, + } rollup@4.62.2: - resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + resolution: + { + integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==, + } + engines: { node: ">=18.0.0", npm: ">=8.0.0" } hasBin: true router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==, + } + engines: { node: ">= 18" } rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + resolution: + { + integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==, + } + + safe-stable-stringify@2.5.0: + resolution: + { + integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==, + } + engines: { node: ">=10" } safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} + resolution: + { + integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==, + } + engines: { node: ">=v12.22.7" } scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + resolution: + { + integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==, + } + + scroll-into-view-if-needed@3.1.0: + resolution: + { + integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==, + } send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==, + } + engines: { node: ">= 18" } serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==, + } + engines: { node: ">= 18" } + + set-cookie-parser@2.7.2: + resolution: + { + integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==, + } setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + resolution: + { + integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, + } shell-quote@1.9.0: - resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==, + } + engines: { node: ">= 0.4" } side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==, + } + engines: { node: ">= 0.4" } side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==, + } + engines: { node: ">= 0.4" } side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==, + } + engines: { node: ">= 0.4" } side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==, + } + engines: { node: ">= 0.4" } siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + resolution: + { + integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, + } source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: ">=0.10.0" } + + space-separated-tokens@1.1.5: + resolution: + { + integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==, + } split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} + resolution: + { + integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==, + } + engines: { node: ">= 10.x" } stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + resolution: + { + integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, + } + + stackframe@1.3.4: + resolution: + { + integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==, + } standard-as-callback@2.1.0: - resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + resolution: + { + integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==, + } standardwebhooks@1.0.0: - resolution: {integrity: sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==} + resolution: + { + integrity: sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==, + } statuses@1.5.0: - resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==, + } + engines: { node: ">= 0.6" } statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==, + } + engines: { node: ">= 0.8" } std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + resolution: + { + integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==, + } + + string-convert@0.2.1: + resolution: + { + integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==, + } string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: ">=8" } strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: ">=8" } strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + resolution: + { + integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==, + } + + style-to-object@0.3.0: + resolution: + { + integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==, + } + + stylis@4.4.0: + resolution: + { + integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==, + } + + sunflower-antd@1.0.0-beta.3: + resolution: + { + integrity: sha512-SAdjHgNemTFNxUF/QJ2KdC0x6wWpY1EsMJMo+F5KIHCDRsUUahjAIldoK+ejH00rPgUoCOhAHQ/ob/J7eyZ5qg==, + } + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" superagent@10.3.0: - resolution: {integrity: sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==} - engines: {node: '>=14.18.0'} + resolution: + { + integrity: sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==, + } + engines: { node: ">=14.18.0" } supertest@7.2.2: - resolution: {integrity: sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==} - engines: {node: '>=14.18.0'} + resolution: + { + integrity: sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==, + } + engines: { node: ">=14.18.0" } supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: ">=8" } supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, + } + engines: { node: ">=10" } svix@1.90.0: - resolution: {integrity: sha512-ljkZuyy2+IBEoESkIpn8sLM+sxJHQcPxlZFxU+nVDhltNfUMisMBzWX/UR8SjEnzoI28ZjCzMbmYAPwSTucoMw==} + resolution: + { + integrity: sha512-ljkZuyy2+IBEoESkIpn8sLM+sxJHQcPxlZFxU+nVDhltNfUMisMBzWX/UR8SjEnzoI28ZjCzMbmYAPwSTucoMw==, + } swr@2.4.2: - resolution: {integrity: sha512-ej644Y2bvkIajfR32KGeSSdBXQW+ScjGjkybZgSE7kFpk9eGnV44XY9FJylXi+W75pavSX1PVNB57W5EbhGIYw==} + resolution: + { + integrity: sha512-ej644Y2bvkIajfR32KGeSSdBXQW+ScjGjkybZgSE7kFpk9eGnV44XY9FJylXi+W75pavSX1PVNB57W5EbhGIYw==, + } peerDependencies: react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + resolution: + { + integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==, + } + + throttle-debounce@5.0.2: + resolution: + { + integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==, + } + engines: { node: ">=12.22" } tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + resolution: + { + integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==, + } tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + resolution: + { + integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==, + } tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==, + } + engines: { node: ">=12.0.0" } tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} + resolution: + { + integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==, + } + engines: { node: ^18.0.0 || >=20.0.0 } tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==, + } + engines: { node: ">=14.0.0" } tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==, + } + engines: { node: ">=14.0.0" } tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + resolution: + { + integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==, + } tldts-core@7.4.8: - resolution: {integrity: sha512-c1P7u0EhACHj7lPy4MJm8iTFEU8+nB0LCtddH0fhP7noaVoXAqafMtOOeX+ulpuPBqnrRgRhw494RICT3mbhnw==} + resolution: + { + integrity: sha512-c1P7u0EhACHj7lPy4MJm8iTFEU8+nB0LCtddH0fhP7noaVoXAqafMtOOeX+ulpuPBqnrRgRhw494RICT3mbhnw==, + } tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + resolution: + { + integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==, + } hasBin: true tldts@7.4.8: - resolution: {integrity: sha512-htwgN/8KRB3z3vnC0BOETVh2m499g5GmyTK9Wq5JBLX3FNz6tSBveAd+fQhzy9hkjif8vy2jwDMR1sGhLtZl2A==} + resolution: + { + integrity: sha512-htwgN/8KRB3z3vnC0BOETVh2m499g5GmyTK9Wq5JBLX3FNz6tSBveAd+fQhzy9hkjif8vy2jwDMR1sGhLtZl2A==, + } hasBin: true + toggle-selection@1.0.6: + resolution: + { + integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==, + } + toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, + } + engines: { node: ">=0.6" } tough-cookie@5.1.2: - resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==, + } + engines: { node: ">=16" } tough-cookie@6.0.2: - resolution: {integrity: sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==, + } + engines: { node: ">=16" } tr46@6.0.0: - resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==, + } + engines: { node: ">=20" } tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + resolution: + { + integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==, + } hasBin: true + trough@1.0.5: + resolution: + { + integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==, + } + tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + resolution: + { + integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, + } tsscmp@1.0.6: - resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} - engines: {node: '>=0.6.x'} + resolution: + { + integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==, + } + engines: { node: ">=0.6.x" } tsx@4.20.6: - resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==, + } + engines: { node: ">=18.0.0" } hasBin: true type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==, + } + engines: { node: ">= 0.6" } typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==, + } + engines: { node: ">=14.17" } hasBin: true undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + resolution: + { + integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==, + } + + unified@9.2.2: + resolution: + { + integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==, + } + + unist-builder@2.0.3: + resolution: + { + integrity: sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==, + } + + unist-util-generated@1.1.6: + resolution: + { + integrity: sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==, + } + + unist-util-is@4.1.0: + resolution: + { + integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==, + } + + unist-util-position@3.1.0: + resolution: + { + integrity: sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==, + } + + unist-util-stringify-position@2.0.3: + resolution: + { + integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==, + } + + unist-util-visit-parents@3.1.1: + resolution: + { + integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==, + } + + unist-util-visit@2.0.3: + resolution: + { + integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==, + } unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, + } + engines: { node: ">= 0.8" } use-sync-external-store@1.6.0: - resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + resolution: + { + integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==, + } peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 uuid@10.0.0: - resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + resolution: + { + integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==, + } hasBin: true vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, + } + engines: { node: ">= 0.8" } + + vfile-message@2.0.4: + resolution: + { + integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==, + } + + vfile@4.2.1: + resolution: + { + integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==, + } vite-node@3.2.4: - resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + resolution: + { + integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==, + } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } hasBin: true vite@7.3.6: - resolution: {integrity: sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" less: ^4.0.0 lightningcss: ^1.21.0 sass: ^1.70.0 sass-embedded: ^1.70.0 - stylus: '>=0.54.8' + stylus: ">=0.54.8" sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 peerDependenciesMeta: - '@types/node': + "@types/node": optional: true jiti: optional: true @@ -1741,27 +4060,30 @@ packages: optional: true vitest@3.2.7: - resolution: {integrity: sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + resolution: + { + integrity: sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==, + } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } hasBin: true peerDependencies: - '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.7 - '@vitest/ui': 3.2.7 - happy-dom: '*' - jsdom: '*' + "@edge-runtime/vm": "*" + "@types/debug": ^4.1.12 + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@vitest/browser": 3.2.7 + "@vitest/ui": 3.2.7 + happy-dom: "*" + jsdom: "*" peerDependenciesMeta: - '@edge-runtime/vm': + "@edge-runtime/vm": optional: true - '@types/debug': + "@types/debug": optional: true - '@types/node': + "@types/node": optional: true - '@vitest/browser': + "@vitest/browser": optional: true - '@vitest/ui': + "@vitest/ui": optional: true happy-dom: optional: true @@ -1769,43 +4091,82 @@ packages: optional: true w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==, + } + engines: { node: ">=18" } + + warn-once@0.1.1: + resolution: + { + integrity: sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==, + } + + warning@4.0.3: + resolution: + { + integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==, + } webidl-conversions@8.0.1: - resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==, + } + engines: { node: ">=20" } whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==, + } + engines: { node: ">=18" } whatwg-mimetype@5.0.0: - resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==, + } + engines: { node: ">=20" } whatwg-url@15.1.0: - resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==, + } + engines: { node: ">=20" } why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==, + } + engines: { node: ">=8" } hasBin: true wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: ">=10" } wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } ws@8.21.0: - resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==, + } + engines: { node: ">=10.0.0" } peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' + utf-8-validate: ">=5.0.2" peerDependenciesMeta: bufferutil: optional: true @@ -1813,253 +4174,386 @@ packages: optional: true xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==, + } + engines: { node: ">=18" } xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + resolution: + { + integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==, + } xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} + resolution: + { + integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==, + } + engines: { node: ">=0.4" } y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: ">=10" } yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: ">=12" } yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, + } + engines: { node: ">=12" } + + zwitch@1.0.5: + resolution: + { + integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==, + } snapshots: + "@acemir/cssom@0.9.31": {} + + "@ant-design/colors@7.2.1": + dependencies: + "@ant-design/fast-color": 2.0.6 + + "@ant-design/cssinjs-utils@1.1.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@ant-design/cssinjs": 1.24.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@babel/runtime": 7.29.7 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@ant-design/cssinjs@1.24.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@babel/runtime": 7.29.7 + "@emotion/hash": 0.8.0 + "@emotion/unitless": 0.7.5 + classnames: 2.5.1 + csstype: 3.2.3 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + stylis: 4.4.0 + + "@ant-design/fast-color@2.0.6": + dependencies: + "@babel/runtime": 7.29.7 + + "@ant-design/icons-svg@4.5.0": {} + + "@ant-design/icons@5.6.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@ant-design/colors": 7.2.1 + "@ant-design/icons-svg": 4.5.0 + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@ant-design/pro-layout@7.22.7(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@ant-design/cssinjs": 1.24.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/icons": 5.6.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/pro-provider": 2.16.2(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/pro-utils": 2.18.0(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@babel/runtime": 7.29.7 + "@umijs/route-utils": 4.0.3 + "@umijs/use-params": 1.0.9(react@19.2.7) + antd: 5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + lodash: 4.18.1 + lodash-es: 4.18.1 + path-to-regexp: 8.4.2 + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + swr: 2.4.2(react@19.2.7) + warning: 4.0.3 + + "@ant-design/pro-provider@2.16.2(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@ant-design/cssinjs": 1.24.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@babel/runtime": 7.29.7 + "@ctrl/tinycolor": 3.6.1 + antd: 5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + dayjs: 1.11.21 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + swr: 2.4.2(react@19.2.7) + + "@ant-design/pro-utils@2.18.0(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@ant-design/icons": 5.6.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/pro-provider": 2.16.2(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@babel/runtime": 7.29.7 + antd: 5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + dayjs: 1.11.21 + lodash: 4.18.1 + lodash-es: 4.18.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + safe-stable-stringify: 2.5.0 + swr: 2.4.2(react@19.2.7) + + "@ant-design/react-slick@1.1.2(react@19.2.7)": + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + json2mq: 0.2.0 + react: 19.2.7 + resize-observer-polyfill: 1.5.1 + throttle-debounce: 5.0.2 - '@acemir/cssom@0.9.31': {} + "@ant-design/v5-patch-for-react-19@1.0.3(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + antd: 5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@asamuzakjp/css-color@4.1.2': + "@asamuzakjp/css-color@4.1.2": dependencies: - '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.1.9(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + "@csstools/css-calc": 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + "@csstools/css-color-parser": 4.1.9(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + "@csstools/css-parser-algorithms": 4.0.0(@csstools/css-tokenizer@4.0.0) + "@csstools/css-tokenizer": 4.0.0 lru-cache: 11.5.2 - '@asamuzakjp/dom-selector@6.8.1': + "@asamuzakjp/dom-selector@6.8.1": dependencies: - '@asamuzakjp/nwsapi': 2.3.9 + "@asamuzakjp/nwsapi": 2.3.9 bidi-js: 1.0.3 css-tree: 3.2.1 is-potential-custom-element-name: 1.0.1 lru-cache: 11.5.2 - '@asamuzakjp/nwsapi@2.3.9': {} + "@asamuzakjp/nwsapi@2.3.9": {} - '@babel/code-frame@7.29.7': + "@babel/code-frame@7.29.7": dependencies: - '@babel/helper-validator-identifier': 7.29.7 + "@babel/helper-validator-identifier": 7.29.7 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/helper-validator-identifier@7.29.7': {} + "@babel/helper-validator-identifier@7.29.7": {} - '@babel/runtime@7.29.7': {} + "@babel/runtime@7.29.7": {} - '@csstools/color-helpers@6.1.0': {} + "@csstools/color-helpers@6.1.0": {} - '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + "@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)": dependencies: - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + "@csstools/css-parser-algorithms": 4.0.0(@csstools/css-tokenizer@4.0.0) + "@csstools/css-tokenizer": 4.0.0 - '@csstools/css-color-parser@4.1.9(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + "@csstools/css-color-parser@4.1.9(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)": dependencies: - '@csstools/color-helpers': 6.1.0 - '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + "@csstools/color-helpers": 6.1.0 + "@csstools/css-calc": 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + "@csstools/css-parser-algorithms": 4.0.0(@csstools/css-tokenizer@4.0.0) + "@csstools/css-tokenizer": 4.0.0 - '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + "@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)": dependencies: - '@csstools/css-tokenizer': 4.0.0 + "@csstools/css-tokenizer": 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.6(css-tree@3.2.1)': + "@csstools/css-syntax-patches-for-csstree@1.1.6(css-tree@3.2.1)": optionalDependencies: css-tree: 3.2.1 - '@csstools/css-tokenizer@4.0.0': {} + "@csstools/css-tokenizer@4.0.0": {} + + "@ctrl/tinycolor@3.6.1": {} - '@esbuild/aix-ppc64@0.25.12': + "@emotion/hash@0.8.0": {} + + "@emotion/unitless@0.7.5": {} + + "@esbuild/aix-ppc64@0.25.12": optional: true - '@esbuild/aix-ppc64@0.28.1': + "@esbuild/aix-ppc64@0.28.1": optional: true - '@esbuild/android-arm64@0.25.12': + "@esbuild/android-arm64@0.25.12": optional: true - '@esbuild/android-arm64@0.28.1': + "@esbuild/android-arm64@0.28.1": optional: true - '@esbuild/android-arm@0.25.12': + "@esbuild/android-arm@0.25.12": optional: true - '@esbuild/android-arm@0.28.1': + "@esbuild/android-arm@0.28.1": optional: true - '@esbuild/android-x64@0.25.12': + "@esbuild/android-x64@0.25.12": optional: true - '@esbuild/android-x64@0.28.1': + "@esbuild/android-x64@0.28.1": optional: true - '@esbuild/darwin-arm64@0.25.12': + "@esbuild/darwin-arm64@0.25.12": optional: true - '@esbuild/darwin-arm64@0.28.1': + "@esbuild/darwin-arm64@0.28.1": optional: true - '@esbuild/darwin-x64@0.25.12': + "@esbuild/darwin-x64@0.25.12": optional: true - '@esbuild/darwin-x64@0.28.1': + "@esbuild/darwin-x64@0.28.1": optional: true - '@esbuild/freebsd-arm64@0.25.12': + "@esbuild/freebsd-arm64@0.25.12": optional: true - '@esbuild/freebsd-arm64@0.28.1': + "@esbuild/freebsd-arm64@0.28.1": optional: true - '@esbuild/freebsd-x64@0.25.12': + "@esbuild/freebsd-x64@0.25.12": optional: true - '@esbuild/freebsd-x64@0.28.1': + "@esbuild/freebsd-x64@0.28.1": optional: true - '@esbuild/linux-arm64@0.25.12': + "@esbuild/linux-arm64@0.25.12": optional: true - '@esbuild/linux-arm64@0.28.1': + "@esbuild/linux-arm64@0.28.1": optional: true - '@esbuild/linux-arm@0.25.12': + "@esbuild/linux-arm@0.25.12": optional: true - '@esbuild/linux-arm@0.28.1': + "@esbuild/linux-arm@0.28.1": optional: true - '@esbuild/linux-ia32@0.25.12': + "@esbuild/linux-ia32@0.25.12": optional: true - '@esbuild/linux-ia32@0.28.1': + "@esbuild/linux-ia32@0.28.1": optional: true - '@esbuild/linux-loong64@0.25.12': + "@esbuild/linux-loong64@0.25.12": optional: true - '@esbuild/linux-loong64@0.28.1': + "@esbuild/linux-loong64@0.28.1": optional: true - '@esbuild/linux-mips64el@0.25.12': + "@esbuild/linux-mips64el@0.25.12": optional: true - '@esbuild/linux-mips64el@0.28.1': + "@esbuild/linux-mips64el@0.28.1": optional: true - '@esbuild/linux-ppc64@0.25.12': + "@esbuild/linux-ppc64@0.25.12": optional: true - '@esbuild/linux-ppc64@0.28.1': + "@esbuild/linux-ppc64@0.28.1": optional: true - '@esbuild/linux-riscv64@0.25.12': + "@esbuild/linux-riscv64@0.25.12": optional: true - '@esbuild/linux-riscv64@0.28.1': + "@esbuild/linux-riscv64@0.28.1": optional: true - '@esbuild/linux-s390x@0.25.12': + "@esbuild/linux-s390x@0.25.12": optional: true - '@esbuild/linux-s390x@0.28.1': + "@esbuild/linux-s390x@0.28.1": optional: true - '@esbuild/linux-x64@0.25.12': + "@esbuild/linux-x64@0.25.12": optional: true - '@esbuild/linux-x64@0.28.1': + "@esbuild/linux-x64@0.28.1": optional: true - '@esbuild/netbsd-arm64@0.25.12': + "@esbuild/netbsd-arm64@0.25.12": optional: true - '@esbuild/netbsd-arm64@0.28.1': + "@esbuild/netbsd-arm64@0.28.1": optional: true - '@esbuild/netbsd-x64@0.25.12': + "@esbuild/netbsd-x64@0.25.12": optional: true - '@esbuild/netbsd-x64@0.28.1': + "@esbuild/netbsd-x64@0.28.1": optional: true - '@esbuild/openbsd-arm64@0.25.12': + "@esbuild/openbsd-arm64@0.25.12": optional: true - '@esbuild/openbsd-arm64@0.28.1': + "@esbuild/openbsd-arm64@0.28.1": optional: true - '@esbuild/openbsd-x64@0.25.12': + "@esbuild/openbsd-x64@0.25.12": optional: true - '@esbuild/openbsd-x64@0.28.1': + "@esbuild/openbsd-x64@0.28.1": optional: true - '@esbuild/openharmony-arm64@0.25.12': + "@esbuild/openharmony-arm64@0.25.12": optional: true - '@esbuild/openharmony-arm64@0.28.1': + "@esbuild/openharmony-arm64@0.28.1": optional: true - '@esbuild/sunos-x64@0.25.12': + "@esbuild/sunos-x64@0.25.12": optional: true - '@esbuild/sunos-x64@0.28.1': + "@esbuild/sunos-x64@0.28.1": optional: true - '@esbuild/win32-arm64@0.25.12': + "@esbuild/win32-arm64@0.25.12": optional: true - '@esbuild/win32-arm64@0.28.1': + "@esbuild/win32-arm64@0.28.1": optional: true - '@esbuild/win32-ia32@0.25.12': + "@esbuild/win32-ia32@0.25.12": optional: true - '@esbuild/win32-ia32@0.28.1': + "@esbuild/win32-ia32@0.28.1": optional: true - '@esbuild/win32-x64@0.25.12': + "@esbuild/win32-x64@0.25.12": optional: true - '@esbuild/win32-x64@0.28.1': + "@esbuild/win32-x64@0.28.1": optional: true - '@exodus/bytes@1.15.1(@noble/hashes@1.8.0)': + "@exodus/bytes@1.15.1(@noble/hashes@1.8.0)": optionalDependencies: - '@noble/hashes': 1.8.0 + "@noble/hashes": 1.8.0 - '@ioredis/commands@1.5.1': {} + "@ioredis/commands@1.5.1": {} - '@jridgewell/sourcemap-codec@1.5.5': {} + "@jridgewell/sourcemap-codec@1.5.5": {} - '@koa/cors@5.0.0': + "@koa/cors@5.0.0": dependencies: vary: 1.1.2 - '@koa/router@15.4.0(koa@3.2.0)': + "@koa/router@15.4.0(koa@3.2.0)": dependencies: debug: 4.4.3 http-errors: 2.0.1 @@ -2069,231 +4563,394 @@ snapshots: transitivePeerDependencies: - supports-color - '@noble/hashes@1.8.0': {} + "@noble/hashes@1.8.0": {} + + "@paralleldrive/cuid2@2.3.1": + dependencies: + "@noble/hashes": 1.8.0 + + "@rc-component/async-validator@5.1.2": + dependencies: + "@babel/runtime": 7.29.7 + + "@rc-component/color-picker@2.0.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@ant-design/fast-color": 2.0.6 + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@rc-component/context@1.4.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@babel/runtime": 7.29.7 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@rc-component/mini-decimal@1.1.4": + dependencies: + "@babel/runtime": 7.29.7 + + "@rc-component/mutate-observer@1.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@rc-component/portal@1.1.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@rc-component/qrcode@1.1.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@babel/runtime": 7.29.7 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@rc-component/tour@1.15.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/portal": 1.1.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@rc-component/trigger": 2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@rc-component/trigger@2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/portal": 1.1.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@refinedev/antd@6.0.3(@refinedev/core@5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@ant-design/icons": 5.6.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/pro-layout": 7.22.7(antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@refinedev/core": 5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@refinedev/ui-types": 2.0.1(@refinedev/core@5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@tanstack/react-query": 5.101.2(react@19.2.7) + "@types/react": 19.2.17 + "@types/react-dom": 19.2.3(@types/react@19.2.17) + antd: 5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + dayjs: 1.11.21 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-markdown: 6.0.3(@types/react@19.2.17)(react@19.2.7) + remark-gfm: 1.0.0 + sunflower-antd: 1.0.0-beta.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + "@refinedev/core@5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@refinedev/devtools-internal": 2.0.2(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@tanstack/react-query": 5.101.2(react@19.2.7) + "@types/react": 19.2.17 + "@types/react-dom": 19.2.3(@types/react@19.2.17) + lodash: 4.18.1 + lodash-es: 4.18.1 + papaparse: 5.5.4 + pluralize: 8.0.0 + qs: 6.15.1 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + tslib: 2.8.1 + warn-once: 0.1.1 + + "@refinedev/devtools-internal@2.0.2(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@refinedev/devtools-shared": 2.0.2(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@tanstack/react-query": 5.101.2(react@19.2.7) + "@types/react": 19.2.17 + "@types/react-dom": 19.2.3(@types/react@19.2.17) + error-stack-parser: 2.1.4 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@refinedev/devtools-shared@2.0.2(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": + dependencies: + "@tanstack/react-query": 5.101.2(react@19.2.7) + "@types/react": 19.2.17 + "@types/react-dom": 19.2.3(@types/react@19.2.17) + error-stack-parser: 2.1.4 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + "@refinedev/react-router@2.0.4(@refinedev/core@5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react-router@7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)": + dependencies: + "@refinedev/core": 5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@types/react": 19.2.17 + "@types/react-dom": 19.2.3(@types/react@19.2.17) + qs: 6.15.1 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-router: 7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@paralleldrive/cuid2@2.3.1': + "@refinedev/ui-types@2.0.1(@refinedev/core@5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": dependencies: - '@noble/hashes': 1.8.0 + "@refinedev/core": 5.0.12(@tanstack/react-query@5.101.2(react@19.2.7))(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + dayjs: 1.11.21 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + tslib: 2.8.1 - '@rollup/rollup-android-arm-eabi@4.62.2': + "@rollup/rollup-android-arm-eabi@4.62.2": optional: true - '@rollup/rollup-android-arm64@4.62.2': + "@rollup/rollup-android-arm64@4.62.2": optional: true - '@rollup/rollup-darwin-arm64@4.62.2': + "@rollup/rollup-darwin-arm64@4.62.2": optional: true - '@rollup/rollup-darwin-x64@4.62.2': + "@rollup/rollup-darwin-x64@4.62.2": optional: true - '@rollup/rollup-freebsd-arm64@4.62.2': + "@rollup/rollup-freebsd-arm64@4.62.2": optional: true - '@rollup/rollup-freebsd-x64@4.62.2': + "@rollup/rollup-freebsd-x64@4.62.2": optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.62.2': + "@rollup/rollup-linux-arm-gnueabihf@4.62.2": optional: true - '@rollup/rollup-linux-arm-musleabihf@4.62.2': + "@rollup/rollup-linux-arm-musleabihf@4.62.2": optional: true - '@rollup/rollup-linux-arm64-gnu@4.62.2': + "@rollup/rollup-linux-arm64-gnu@4.62.2": optional: true - '@rollup/rollup-linux-arm64-musl@4.62.2': + "@rollup/rollup-linux-arm64-musl@4.62.2": optional: true - '@rollup/rollup-linux-loong64-gnu@4.62.2': + "@rollup/rollup-linux-loong64-gnu@4.62.2": optional: true - '@rollup/rollup-linux-loong64-musl@4.62.2': + "@rollup/rollup-linux-loong64-musl@4.62.2": optional: true - '@rollup/rollup-linux-ppc64-gnu@4.62.2': + "@rollup/rollup-linux-ppc64-gnu@4.62.2": optional: true - '@rollup/rollup-linux-ppc64-musl@4.62.2': + "@rollup/rollup-linux-ppc64-musl@4.62.2": optional: true - '@rollup/rollup-linux-riscv64-gnu@4.62.2': + "@rollup/rollup-linux-riscv64-gnu@4.62.2": optional: true - '@rollup/rollup-linux-riscv64-musl@4.62.2': + "@rollup/rollup-linux-riscv64-musl@4.62.2": optional: true - '@rollup/rollup-linux-s390x-gnu@4.62.2': + "@rollup/rollup-linux-s390x-gnu@4.62.2": optional: true - '@rollup/rollup-linux-x64-gnu@4.62.2': + "@rollup/rollup-linux-x64-gnu@4.62.2": optional: true - '@rollup/rollup-linux-x64-musl@4.62.2': + "@rollup/rollup-linux-x64-musl@4.62.2": optional: true - '@rollup/rollup-openbsd-x64@4.62.2': + "@rollup/rollup-openbsd-x64@4.62.2": optional: true - '@rollup/rollup-openharmony-arm64@4.62.2': + "@rollup/rollup-openharmony-arm64@4.62.2": optional: true - '@rollup/rollup-win32-arm64-msvc@4.62.2': + "@rollup/rollup-win32-arm64-msvc@4.62.2": optional: true - '@rollup/rollup-win32-ia32-msvc@4.62.2': + "@rollup/rollup-win32-ia32-msvc@4.62.2": optional: true - '@rollup/rollup-win32-x64-gnu@4.62.2': + "@rollup/rollup-win32-x64-gnu@4.62.2": optional: true - '@rollup/rollup-win32-x64-msvc@4.62.2': + "@rollup/rollup-win32-x64-msvc@4.62.2": optional: true - '@stablelib/base64@1.0.1': {} + "@stablelib/base64@1.0.1": {} - '@testing-library/dom@10.4.1': + "@tanstack/query-core@5.101.2": {} + + "@tanstack/react-query@5.101.2(react@19.2.7)": + dependencies: + "@tanstack/query-core": 5.101.2 + react: 19.2.7 + + "@testing-library/dom@10.4.1": dependencies: - '@babel/code-frame': 7.29.7 - '@babel/runtime': 7.29.7 - '@types/aria-query': 5.0.4 + "@babel/code-frame": 7.29.7 + "@babel/runtime": 7.29.7 + "@types/aria-query": 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 lz-string: 1.5.0 picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + "@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)": dependencies: - '@babel/runtime': 7.29.7 - '@testing-library/dom': 10.4.1 + "@babel/runtime": 7.29.7 + "@testing-library/dom": 10.4.1 react: 19.2.7 react-dom: 19.2.7(react@19.2.7) optionalDependencies: - '@types/react': 19.2.17 - '@types/react-dom': 19.2.3(@types/react@19.2.17) + "@types/react": 19.2.17 + "@types/react-dom": 19.2.3(@types/react@19.2.17) - '@types/aria-query@5.0.4': {} + "@types/aria-query@5.0.4": {} - '@types/body-parser@1.19.6': + "@types/body-parser@1.19.6": dependencies: - '@types/connect': 3.4.38 - '@types/node': 24.12.2 + "@types/connect": 3.4.38 + "@types/node": 24.12.2 - '@types/chai@5.2.3': + "@types/chai@5.2.3": dependencies: - '@types/deep-eql': 4.0.2 + "@types/deep-eql": 4.0.2 assertion-error: 2.0.1 - '@types/connect@3.4.38': + "@types/connect@3.4.38": dependencies: - '@types/node': 24.12.2 + "@types/node": 24.12.2 - '@types/cookiejar@2.1.5': {} + "@types/cookiejar@2.1.5": {} - '@types/deep-eql@4.0.2': {} + "@types/deep-eql@4.0.2": {} - '@types/estree@1.0.9': {} + "@types/estree@1.0.9": {} - '@types/express-serve-static-core@5.1.1': + "@types/express-serve-static-core@5.1.1": dependencies: - '@types/node': 24.12.2 - '@types/qs': 6.15.0 - '@types/range-parser': 1.2.7 - '@types/send': 1.2.1 + "@types/node": 24.12.2 + "@types/qs": 6.15.0 + "@types/range-parser": 1.2.7 + "@types/send": 1.2.1 - '@types/express@5.0.6': + "@types/express@5.0.6": dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.1.1 - '@types/serve-static': 2.2.0 + "@types/body-parser": 1.19.6 + "@types/express-serve-static-core": 5.1.1 + "@types/serve-static": 2.2.0 - '@types/http-errors@2.0.5': {} + "@types/hast@2.3.10": + dependencies: + "@types/unist": 2.0.11 + + "@types/http-errors@2.0.5": {} + + "@types/mdast@3.0.15": + dependencies: + "@types/unist": 2.0.11 - '@types/methods@1.1.4': {} + "@types/methods@1.1.4": {} - '@types/node@24.12.2': + "@types/node@24.12.2": dependencies: undici-types: 7.16.0 - '@types/pg@8.20.0': + "@types/pg@8.20.0": dependencies: - '@types/node': 24.12.2 + "@types/node": 24.12.2 pg-protocol: 1.13.0 pg-types: 2.2.0 - '@types/qs@6.15.0': {} + "@types/qs@6.15.0": {} - '@types/range-parser@1.2.7': {} + "@types/range-parser@1.2.7": {} - '@types/react-dom@19.2.3(@types/react@19.2.17)': + "@types/react-dom@19.2.3(@types/react@19.2.17)": dependencies: - '@types/react': 19.2.17 + "@types/react": 19.2.17 - '@types/react@19.2.17': + "@types/react@19.2.17": dependencies: csstype: 3.2.3 - '@types/send@1.2.1': + "@types/send@1.2.1": dependencies: - '@types/node': 24.12.2 + "@types/node": 24.12.2 - '@types/serve-static@2.2.0': + "@types/serve-static@2.2.0": dependencies: - '@types/http-errors': 2.0.5 - '@types/node': 24.12.2 + "@types/http-errors": 2.0.5 + "@types/node": 24.12.2 - '@types/superagent@8.1.9': + "@types/superagent@8.1.9": dependencies: - '@types/cookiejar': 2.1.5 - '@types/methods': 1.1.4 - '@types/node': 24.12.2 + "@types/cookiejar": 2.1.5 + "@types/methods": 1.1.4 + "@types/node": 24.12.2 form-data: 4.0.5 - '@types/supertest@6.0.3': + "@types/supertest@6.0.3": dependencies: - '@types/methods': 1.1.4 - '@types/superagent': 8.1.9 + "@types/methods": 1.1.4 + "@types/superagent": 8.1.9 - '@vitest/expect@3.2.7': + "@types/unist@2.0.11": {} + + "@umijs/route-utils@4.0.3": {} + + "@umijs/use-params@1.0.9(react@19.2.7)": + dependencies: + react: 19.2.7 + + "@vitest/expect@3.2.7": dependencies: - '@types/chai': 5.2.3 - '@vitest/spy': 3.2.7 - '@vitest/utils': 3.2.7 + "@types/chai": 5.2.3 + "@vitest/spy": 3.2.7 + "@vitest/utils": 3.2.7 chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.7(vite@7.3.6(@types/node@24.12.2)(tsx@4.20.6))': + "@vitest/mocker@3.2.7(vite@7.3.6(@types/node@24.12.2)(tsx@4.20.6))": dependencies: - '@vitest/spy': 3.2.7 + "@vitest/spy": 3.2.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: vite: 7.3.6(@types/node@24.12.2)(tsx@4.20.6) - '@vitest/pretty-format@3.2.7': + "@vitest/pretty-format@3.2.7": dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.2.7': + "@vitest/runner@3.2.7": dependencies: - '@vitest/utils': 3.2.7 + "@vitest/utils": 3.2.7 pathe: 2.0.3 strip-literal: 3.1.0 - '@vitest/snapshot@3.2.7': + "@vitest/snapshot@3.2.7": dependencies: - '@vitest/pretty-format': 3.2.7 + "@vitest/pretty-format": 3.2.7 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@3.2.7': + "@vitest/spy@3.2.7": dependencies: tinyspy: 4.0.4 - '@vitest/utils@3.2.7': + "@vitest/utils@3.2.7": dependencies: - '@vitest/pretty-format': 3.2.7 + "@vitest/pretty-format": 3.2.7 loupe: 3.2.1 tinyrainbow: 2.0.0 @@ -2323,9 +4980,67 @@ snapshots: ansi-styles@5.2.0: {} - aria-query@5.3.0: - dependencies: - dequal: 2.0.3 + antd@5.29.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@ant-design/colors": 7.2.1 + "@ant-design/cssinjs": 1.24.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/cssinjs-utils": 1.1.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/fast-color": 2.0.6 + "@ant-design/icons": 5.6.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@ant-design/react-slick": 1.1.2(react@19.2.7) + "@babel/runtime": 7.29.7 + "@rc-component/color-picker": 2.0.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@rc-component/mutate-observer": 1.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@rc-component/qrcode": 1.1.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@rc-component/tour": 1.15.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + "@rc-component/trigger": 2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + copy-to-clipboard: 3.3.3 + dayjs: 1.11.21 + rc-cascader: 3.34.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-checkbox: 3.5.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-collapse: 3.9.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-dialog: 9.6.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-drawer: 7.3.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-dropdown: 4.2.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-field-form: 2.7.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-image: 7.12.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-input: 1.8.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-input-number: 9.5.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-mentions: 2.20.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-menu: 9.16.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-notification: 5.6.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-pagination: 5.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-picker: 4.11.3(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-progress: 4.0.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-rate: 2.13.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-segmented: 2.7.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-select: 14.16.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-slider: 11.1.9(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-steps: 6.0.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-switch: 4.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-table: 7.54.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-tabs: 15.7.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-textarea: 1.10.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-tooltip: 6.4.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-tree: 5.13.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-tree-select: 5.27.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-upload: 4.11.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + scroll-into-view-if-needed: 3.1.0 + throttle-debounce: 5.0.2 + transitivePeerDependencies: + - date-fns + - luxon + - moment + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 asap@2.0.6: {} @@ -2351,6 +5066,8 @@ snapshots: - debug - supports-color + bail@1.0.5: {} + bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 @@ -2383,6 +5100,8 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + ccount@1.1.0: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -2396,8 +5115,16 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + character-entities-legacy@1.1.4: {} + + character-entities@1.2.4: {} + + character-reference-invalid@1.1.4: {} + check-error@2.1.3: {} + classnames@2.5.1: {} + cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -2416,8 +5143,12 @@ snapshots: dependencies: delayed-stream: 1.0.0 + comma-separated-tokens@1.0.8: {} + component-emitter@1.3.1: {} + compute-scroll-into-view@3.1.1: {} + concurrently@9.2.4: dependencies: chalk: 4.1.2 @@ -2437,6 +5168,8 @@ snapshots: cookie@0.7.2: {} + cookie@1.1.1: {} + cookiejar@2.1.4: {} cookies@0.9.1: @@ -2444,6 +5177,10 @@ snapshots: depd: 2.0.0 keygrip: 1.1.0 + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + css-tree@3.2.1: dependencies: mdn-data: 2.27.1 @@ -2451,8 +5188,8 @@ snapshots: cssstyle@5.3.7: dependencies: - '@asamuzakjp/css-color': 4.1.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.6(css-tree@3.2.1) + "@asamuzakjp/css-color": 4.1.2 + "@csstools/css-syntax-patches-for-csstree": 1.1.6(css-tree@3.2.1) css-tree: 3.2.1 lru-cache: 11.5.2 @@ -2463,6 +5200,8 @@ snapshots: whatwg-mimetype: 5.0.0 whatwg-url: 15.1.0 + dayjs@1.11.21: {} + debug@4.4.3: dependencies: ms: 2.1.3 @@ -2508,6 +5247,10 @@ snapshots: entities@8.0.0: {} + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -2527,69 +5270,71 @@ snapshots: esbuild@0.25.12: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.12 - '@esbuild/android-arm': 0.25.12 - '@esbuild/android-arm64': 0.25.12 - '@esbuild/android-x64': 0.25.12 - '@esbuild/darwin-arm64': 0.25.12 - '@esbuild/darwin-x64': 0.25.12 - '@esbuild/freebsd-arm64': 0.25.12 - '@esbuild/freebsd-x64': 0.25.12 - '@esbuild/linux-arm': 0.25.12 - '@esbuild/linux-arm64': 0.25.12 - '@esbuild/linux-ia32': 0.25.12 - '@esbuild/linux-loong64': 0.25.12 - '@esbuild/linux-mips64el': 0.25.12 - '@esbuild/linux-ppc64': 0.25.12 - '@esbuild/linux-riscv64': 0.25.12 - '@esbuild/linux-s390x': 0.25.12 - '@esbuild/linux-x64': 0.25.12 - '@esbuild/netbsd-arm64': 0.25.12 - '@esbuild/netbsd-x64': 0.25.12 - '@esbuild/openbsd-arm64': 0.25.12 - '@esbuild/openbsd-x64': 0.25.12 - '@esbuild/openharmony-arm64': 0.25.12 - '@esbuild/sunos-x64': 0.25.12 - '@esbuild/win32-arm64': 0.25.12 - '@esbuild/win32-ia32': 0.25.12 - '@esbuild/win32-x64': 0.25.12 + "@esbuild/aix-ppc64": 0.25.12 + "@esbuild/android-arm": 0.25.12 + "@esbuild/android-arm64": 0.25.12 + "@esbuild/android-x64": 0.25.12 + "@esbuild/darwin-arm64": 0.25.12 + "@esbuild/darwin-x64": 0.25.12 + "@esbuild/freebsd-arm64": 0.25.12 + "@esbuild/freebsd-x64": 0.25.12 + "@esbuild/linux-arm": 0.25.12 + "@esbuild/linux-arm64": 0.25.12 + "@esbuild/linux-ia32": 0.25.12 + "@esbuild/linux-loong64": 0.25.12 + "@esbuild/linux-mips64el": 0.25.12 + "@esbuild/linux-ppc64": 0.25.12 + "@esbuild/linux-riscv64": 0.25.12 + "@esbuild/linux-s390x": 0.25.12 + "@esbuild/linux-x64": 0.25.12 + "@esbuild/netbsd-arm64": 0.25.12 + "@esbuild/netbsd-x64": 0.25.12 + "@esbuild/openbsd-arm64": 0.25.12 + "@esbuild/openbsd-x64": 0.25.12 + "@esbuild/openharmony-arm64": 0.25.12 + "@esbuild/sunos-x64": 0.25.12 + "@esbuild/win32-arm64": 0.25.12 + "@esbuild/win32-ia32": 0.25.12 + "@esbuild/win32-x64": 0.25.12 esbuild@0.28.1: optionalDependencies: - '@esbuild/aix-ppc64': 0.28.1 - '@esbuild/android-arm': 0.28.1 - '@esbuild/android-arm64': 0.28.1 - '@esbuild/android-x64': 0.28.1 - '@esbuild/darwin-arm64': 0.28.1 - '@esbuild/darwin-x64': 0.28.1 - '@esbuild/freebsd-arm64': 0.28.1 - '@esbuild/freebsd-x64': 0.28.1 - '@esbuild/linux-arm': 0.28.1 - '@esbuild/linux-arm64': 0.28.1 - '@esbuild/linux-ia32': 0.28.1 - '@esbuild/linux-loong64': 0.28.1 - '@esbuild/linux-mips64el': 0.28.1 - '@esbuild/linux-ppc64': 0.28.1 - '@esbuild/linux-riscv64': 0.28.1 - '@esbuild/linux-s390x': 0.28.1 - '@esbuild/linux-x64': 0.28.1 - '@esbuild/netbsd-arm64': 0.28.1 - '@esbuild/netbsd-x64': 0.28.1 - '@esbuild/openbsd-arm64': 0.28.1 - '@esbuild/openbsd-x64': 0.28.1 - '@esbuild/openharmony-arm64': 0.28.1 - '@esbuild/sunos-x64': 0.28.1 - '@esbuild/win32-arm64': 0.28.1 - '@esbuild/win32-ia32': 0.28.1 - '@esbuild/win32-x64': 0.28.1 + "@esbuild/aix-ppc64": 0.28.1 + "@esbuild/android-arm": 0.28.1 + "@esbuild/android-arm64": 0.28.1 + "@esbuild/android-x64": 0.28.1 + "@esbuild/darwin-arm64": 0.28.1 + "@esbuild/darwin-x64": 0.28.1 + "@esbuild/freebsd-arm64": 0.28.1 + "@esbuild/freebsd-x64": 0.28.1 + "@esbuild/linux-arm": 0.28.1 + "@esbuild/linux-arm64": 0.28.1 + "@esbuild/linux-ia32": 0.28.1 + "@esbuild/linux-loong64": 0.28.1 + "@esbuild/linux-mips64el": 0.28.1 + "@esbuild/linux-ppc64": 0.28.1 + "@esbuild/linux-riscv64": 0.28.1 + "@esbuild/linux-s390x": 0.28.1 + "@esbuild/linux-x64": 0.28.1 + "@esbuild/netbsd-arm64": 0.28.1 + "@esbuild/netbsd-x64": 0.28.1 + "@esbuild/openbsd-arm64": 0.28.1 + "@esbuild/openbsd-x64": 0.28.1 + "@esbuild/openharmony-arm64": 0.28.1 + "@esbuild/sunos-x64": 0.28.1 + "@esbuild/win32-arm64": 0.28.1 + "@esbuild/win32-ia32": 0.28.1 + "@esbuild/win32-x64": 0.28.1 escalade@3.2.0: {} escape-html@1.0.3: {} + escape-string-regexp@4.0.0: {} + estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 eta@4.5.1: {} @@ -2630,6 +5375,8 @@ snapshots: transitivePeerDependencies: - supports-color + extend@3.0.2: {} + fast-safe-stringify@2.1.1: {} fast-sha256@1.3.0: {} @@ -2661,7 +5408,7 @@ snapshots: formidable@3.5.4: dependencies: - '@paralleldrive/cuid2': 2.3.1 + "@paralleldrive/cuid2": 2.3.1 dezalgo: 1.0.4 once: 1.4.0 @@ -2716,9 +5463,9 @@ snapshots: html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): dependencies: - '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0) + "@exodus/bytes": 1.15.1(@noble/hashes@1.8.0) transitivePeerDependencies: - - '@noble/hashes' + - "@noble/hashes" http-assert@1.5.0: dependencies: @@ -2773,9 +5520,11 @@ snapshots: inherits@2.0.4: {} + inline-style-parser@0.1.1: {} + ioredis@5.10.1: dependencies: - '@ioredis/commands': 1.5.1 + "@ioredis/commands": 1.5.1 cluster-key-slot: 1.1.2 debug: 4.4.3 denque: 2.1.0 @@ -2789,8 +5538,23 @@ snapshots: ipaddr.js@1.9.1: {} + is-alphabetical@1.0.4: {} + + is-alphanumerical@1.0.4: + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + + is-buffer@2.0.5: {} + + is-decimal@1.0.4: {} + is-fullwidth-code-point@3.0.0: {} + is-hexadecimal@1.0.4: {} + + is-plain-obj@2.1.0: {} + is-potential-custom-element-name@1.0.1: {} is-promise@4.0.0: {} @@ -2803,9 +5567,9 @@ snapshots: jsdom@27.4.0(@noble/hashes@1.8.0): dependencies: - '@acemir/cssom': 0.9.31 - '@asamuzakjp/dom-selector': 6.8.1 - '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0) + "@acemir/cssom": 0.9.31 + "@asamuzakjp/dom-selector": 6.8.1 + "@exodus/bytes": 1.15.1(@noble/hashes@1.8.0) cssstyle: 5.3.7 data-urls: 6.0.1 decimal.js: 10.6.0 @@ -2824,13 +5588,17 @@ snapshots: ws: 8.21.0 xml-name-validator: 5.0.0 transitivePeerDependencies: - - '@noble/hashes' + - "@noble/hashes" - bufferutil - supports-color - utf-8-validate jsesc@3.1.0: {} + json2mq@0.2.0: + dependencies: + string-convert: 0.2.1 + keygrip@1.1.0: dependencies: tsscmp: 1.0.6 @@ -2858,10 +5626,20 @@ snapshots: type-is: 2.0.1 vary: 1.1.2 + lodash-es@4.18.1: {} + lodash.defaults@4.2.0: {} lodash.isarguments@3.1.0: {} + lodash@4.18.1: {} + + longest-streak@2.0.4: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + loupe@3.2.1: {} lru-cache@11.5.2: {} @@ -2870,18 +5648,141 @@ snapshots: magic-string@0.30.21: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + "@jridgewell/sourcemap-codec": 1.5.5 + + markdown-table@2.0.0: + dependencies: + repeat-string: 1.6.1 math-intrinsics@1.1.0: {} + mdast-util-definitions@4.0.0: + dependencies: + unist-util-visit: 2.0.3 + + mdast-util-find-and-replace@1.1.1: + dependencies: + escape-string-regexp: 4.0.0 + unist-util-is: 4.1.0 + unist-util-visit-parents: 3.1.1 + + mdast-util-from-markdown@0.8.5: + dependencies: + "@types/mdast": 3.0.15 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@0.1.3: + dependencies: + ccount: 1.1.0 + mdast-util-find-and-replace: 1.1.1 + micromark: 2.11.4 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@0.2.3: + dependencies: + mdast-util-to-markdown: 0.6.5 + + mdast-util-gfm-table@0.1.6: + dependencies: + markdown-table: 2.0.0 + mdast-util-to-markdown: 0.6.5 + + mdast-util-gfm-task-list-item@0.1.6: + dependencies: + mdast-util-to-markdown: 0.6.5 + + mdast-util-gfm@0.1.2: + dependencies: + mdast-util-gfm-autolink-literal: 0.1.3 + mdast-util-gfm-strikethrough: 0.2.3 + mdast-util-gfm-table: 0.1.6 + mdast-util-gfm-task-list-item: 0.1.6 + mdast-util-to-markdown: 0.6.5 + transitivePeerDependencies: + - supports-color + + mdast-util-to-hast@10.2.0: + dependencies: + "@types/mdast": 3.0.15 + "@types/unist": 2.0.11 + mdast-util-definitions: 4.0.0 + mdurl: 1.0.1 + unist-builder: 2.0.3 + unist-util-generated: 1.1.6 + unist-util-position: 3.1.0 + unist-util-visit: 2.0.3 + + mdast-util-to-markdown@0.6.5: + dependencies: + "@types/unist": 2.0.11 + longest-streak: 2.0.4 + mdast-util-to-string: 2.0.0 + parse-entities: 2.0.0 + repeat-string: 1.6.1 + zwitch: 1.0.5 + + mdast-util-to-string@2.0.0: {} + mdn-data@2.27.1: {} + mdurl@1.0.1: {} + media-typer@1.1.0: {} merge-descriptors@2.0.0: {} methods@1.1.2: {} + micromark-extension-gfm-autolink-literal@0.5.7: + dependencies: + micromark: 2.11.4 + transitivePeerDependencies: + - supports-color + + micromark-extension-gfm-strikethrough@0.6.5: + dependencies: + micromark: 2.11.4 + transitivePeerDependencies: + - supports-color + + micromark-extension-gfm-table@0.4.3: + dependencies: + micromark: 2.11.4 + transitivePeerDependencies: + - supports-color + + micromark-extension-gfm-tagfilter@0.3.0: {} + + micromark-extension-gfm-task-list-item@0.3.3: + dependencies: + micromark: 2.11.4 + transitivePeerDependencies: + - supports-color + + micromark-extension-gfm@0.3.3: + dependencies: + micromark: 2.11.4 + micromark-extension-gfm-autolink-literal: 0.5.7 + micromark-extension-gfm-strikethrough: 0.6.5 + micromark-extension-gfm-table: 0.4.3 + micromark-extension-gfm-tagfilter: 0.3.0 + micromark-extension-gfm-task-list-item: 0.3.3 + transitivePeerDependencies: + - supports-color + + micromark@2.11.4: + dependencies: + debug: 4.4.3 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + mime-db@1.52.0: {} mime-db@1.54.0: {} @@ -2906,12 +5807,14 @@ snapshots: negotiator@1.0.0: {} + object-assign@4.1.1: {} + object-inspect@1.13.4: {} oidc-provider@9.8.2: dependencies: - '@koa/cors': 5.0.0 - '@koa/router': 15.4.0(koa@3.2.0) + "@koa/cors": 5.0.0 + "@koa/router": 15.4.0(koa@3.2.0) debug: 4.4.3 eta: 4.5.1 jose: 6.2.2 @@ -2931,6 +5834,17 @@ snapshots: dependencies: wrappy: 1.0.2 + papaparse@5.5.4: {} + + parse-entities@2.0.0: + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + parse5@8.0.1: dependencies: entities: 8.0.0 @@ -2982,6 +5896,8 @@ snapshots: picomatch@4.0.5: {} + pluralize@8.0.0: {} + postal-mime@2.7.4: {} postcss@8.5.18: @@ -3008,6 +5924,16 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-information@5.6.0: + dependencies: + xtend: 4.0.2 + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -3032,13 +5958,370 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 + rc-cascader@3.34.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-select: 14.16.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-tree: 5.13.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-checkbox@3.5.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-collapse@3.9.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-dialog@9.6.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/portal": 1.1.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-drawer@7.3.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/portal": 1.1.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-dropdown@4.2.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/trigger": 2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-field-form@2.7.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/async-validator": 5.1.2 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-image@7.12.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/portal": 1.1.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-dialog: 9.6.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-input-number@9.5.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/mini-decimal": 1.1.4 + classnames: 2.5.1 + rc-input: 1.8.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-input@1.8.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-mentions@2.20.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/trigger": 2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-input: 1.8.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-menu: 9.16.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-textarea: 1.10.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-menu@9.16.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/trigger": 2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-overflow: 1.5.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-motion@2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-notification@5.6.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-overflow@1.5.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-pagination@5.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-picker@4.11.3(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/trigger": 2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-overflow: 1.5.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + dayjs: 1.11.21 + + rc-progress@4.0.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-rate@2.13.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-resize-observer@1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + resize-observer-polyfill: 1.5.1 + + rc-segmented@2.7.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-select@14.16.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/trigger": 2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-overflow: 1.5.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-virtual-list: 3.19.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-slider@11.1.9(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-steps@6.0.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-switch@4.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-table@7.54.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/context": 1.4.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-virtual-list: 3.19.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-tabs@15.7.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-dropdown: 4.2.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-menu: 9.16.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-textarea@1.10.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-input: 1.8.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-tooltip@6.4.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + "@rc-component/trigger": 2.3.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-tree-select@5.27.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-select: 14.16.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-tree: 5.13.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-tree@5.13.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-virtual-list: 3.19.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-upload@4.11.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + rc-util@5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-is: 18.3.1 + + rc-virtual-list@3.19.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + "@babel/runtime": 7.29.7 + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + rc-util: 5.44.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-dom@19.2.7(react@19.2.7): dependencies: react: 19.2.7 scheduler: 0.27.0 + react-is@16.13.1: {} + react-is@17.0.2: {} + react-is@18.3.1: {} + + react-markdown@6.0.3(@types/react@19.2.17)(react@19.2.7): + dependencies: + "@types/hast": 2.3.10 + "@types/react": 19.2.17 + "@types/unist": 2.0.11 + comma-separated-tokens: 1.0.8 + prop-types: 15.8.1 + property-information: 5.6.0 + react: 19.2.7 + react-is: 17.0.2 + remark-parse: 9.0.0 + remark-rehype: 8.1.0 + space-separated-tokens: 1.1.5 + style-to-object: 0.3.0 + unified: 9.2.2 + unist-util-visit: 2.0.3 + vfile: 4.2.1 + transitivePeerDependencies: + - supports-color + + react-router-dom@7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-router: 7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + + react-router@7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + cookie: 1.1.1 + react: 19.2.7 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.7(react@19.2.7) + react@19.2.7: {} redis-errors@1.2.0: {} @@ -3047,6 +6330,25 @@ snapshots: dependencies: redis-errors: 1.2.0 + remark-gfm@1.0.0: + dependencies: + mdast-util-gfm: 0.1.2 + micromark-extension-gfm: 0.3.3 + transitivePeerDependencies: + - supports-color + + remark-parse@9.0.0: + dependencies: + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@8.1.0: + dependencies: + mdast-util-to-hast: 10.2.0 + + repeat-string@1.6.1: {} + require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -3056,37 +6358,39 @@ snapshots: postal-mime: 2.7.4 svix: 1.90.0 + resize-observer-polyfill@1.5.1: {} + resolve-pkg-maps@1.0.0: {} rollup@4.62.2: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.62.2 - '@rollup/rollup-android-arm64': 4.62.2 - '@rollup/rollup-darwin-arm64': 4.62.2 - '@rollup/rollup-darwin-x64': 4.62.2 - '@rollup/rollup-freebsd-arm64': 4.62.2 - '@rollup/rollup-freebsd-x64': 4.62.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.62.2 - '@rollup/rollup-linux-arm-musleabihf': 4.62.2 - '@rollup/rollup-linux-arm64-gnu': 4.62.2 - '@rollup/rollup-linux-arm64-musl': 4.62.2 - '@rollup/rollup-linux-loong64-gnu': 4.62.2 - '@rollup/rollup-linux-loong64-musl': 4.62.2 - '@rollup/rollup-linux-ppc64-gnu': 4.62.2 - '@rollup/rollup-linux-ppc64-musl': 4.62.2 - '@rollup/rollup-linux-riscv64-gnu': 4.62.2 - '@rollup/rollup-linux-riscv64-musl': 4.62.2 - '@rollup/rollup-linux-s390x-gnu': 4.62.2 - '@rollup/rollup-linux-x64-gnu': 4.62.2 - '@rollup/rollup-linux-x64-musl': 4.62.2 - '@rollup/rollup-openbsd-x64': 4.62.2 - '@rollup/rollup-openharmony-arm64': 4.62.2 - '@rollup/rollup-win32-arm64-msvc': 4.62.2 - '@rollup/rollup-win32-ia32-msvc': 4.62.2 - '@rollup/rollup-win32-x64-gnu': 4.62.2 - '@rollup/rollup-win32-x64-msvc': 4.62.2 + "@rollup/rollup-android-arm-eabi": 4.62.2 + "@rollup/rollup-android-arm64": 4.62.2 + "@rollup/rollup-darwin-arm64": 4.62.2 + "@rollup/rollup-darwin-x64": 4.62.2 + "@rollup/rollup-freebsd-arm64": 4.62.2 + "@rollup/rollup-freebsd-x64": 4.62.2 + "@rollup/rollup-linux-arm-gnueabihf": 4.62.2 + "@rollup/rollup-linux-arm-musleabihf": 4.62.2 + "@rollup/rollup-linux-arm64-gnu": 4.62.2 + "@rollup/rollup-linux-arm64-musl": 4.62.2 + "@rollup/rollup-linux-loong64-gnu": 4.62.2 + "@rollup/rollup-linux-loong64-musl": 4.62.2 + "@rollup/rollup-linux-ppc64-gnu": 4.62.2 + "@rollup/rollup-linux-ppc64-musl": 4.62.2 + "@rollup/rollup-linux-riscv64-gnu": 4.62.2 + "@rollup/rollup-linux-riscv64-musl": 4.62.2 + "@rollup/rollup-linux-s390x-gnu": 4.62.2 + "@rollup/rollup-linux-x64-gnu": 4.62.2 + "@rollup/rollup-linux-x64-musl": 4.62.2 + "@rollup/rollup-openbsd-x64": 4.62.2 + "@rollup/rollup-openharmony-arm64": 4.62.2 + "@rollup/rollup-win32-arm64-msvc": 4.62.2 + "@rollup/rollup-win32-ia32-msvc": 4.62.2 + "@rollup/rollup-win32-x64-gnu": 4.62.2 + "@rollup/rollup-win32-x64-msvc": 4.62.2 fsevents: 2.3.3 router@2.2.0: @@ -3103,6 +6407,8 @@ snapshots: dependencies: tslib: 2.8.1 + safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} saxes@6.0.0: @@ -3111,6 +6417,10 @@ snapshots: scheduler@0.27.0: {} + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + send@1.2.1: dependencies: debug: 4.4.3 @@ -3136,6 +6446,8 @@ snapshots: transitivePeerDependencies: - supports-color + set-cookie-parser@2.7.2: {} + setprototypeof@1.2.0: {} shell-quote@1.9.0: {} @@ -3172,15 +6484,19 @@ snapshots: source-map-js@1.2.1: {} + space-separated-tokens@1.1.5: {} + split2@4.2.0: {} stackback@0.0.2: {} + stackframe@1.3.4: {} + standard-as-callback@2.1.0: {} standardwebhooks@1.0.0: dependencies: - '@stablelib/base64': 1.0.1 + "@stablelib/base64": 1.0.1 fast-sha256: 1.3.0 statuses@1.5.0: {} @@ -3189,6 +6505,8 @@ snapshots: std-env@3.10.0: {} + string-convert@0.2.1: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -3203,6 +6521,17 @@ snapshots: dependencies: js-tokens: 9.0.1 + style-to-object@0.3.0: + dependencies: + inline-style-parser: 0.1.1 + + stylis@4.4.0: {} + + sunflower-antd@1.0.0-beta.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + superagent@10.3.0: dependencies: component-emitter: 1.3.1 @@ -3246,6 +6575,8 @@ snapshots: symbol-tree@3.2.4: {} + throttle-debounce@5.0.2: {} + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -3273,6 +6604,8 @@ snapshots: dependencies: tldts-core: 7.4.8 + toggle-selection@1.0.6: {} + toidentifier@1.0.1: {} tough-cookie@5.1.2: @@ -3289,6 +6622,8 @@ snapshots: tree-kill@1.2.2: {} + trough@1.0.5: {} + tslib@2.8.1: {} tsscmp@1.0.6: {} @@ -3310,6 +6645,39 @@ snapshots: undici-types@7.16.0: {} + unified@9.2.2: + dependencies: + "@types/unist": 2.0.11 + bail: 1.0.5 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 2.1.0 + trough: 1.0.5 + vfile: 4.2.1 + + unist-builder@2.0.3: {} + + unist-util-generated@1.1.6: {} + + unist-util-is@4.1.0: {} + + unist-util-position@3.1.0: {} + + unist-util-stringify-position@2.0.3: + dependencies: + "@types/unist": 2.0.11 + + unist-util-visit-parents@3.1.1: + dependencies: + "@types/unist": 2.0.11 + unist-util-is: 4.1.0 + + unist-util-visit@2.0.3: + dependencies: + "@types/unist": 2.0.11 + unist-util-is: 4.1.0 + unist-util-visit-parents: 3.1.1 + unpipe@1.0.0: {} use-sync-external-store@1.6.0(react@19.2.7): @@ -3320,6 +6688,18 @@ snapshots: vary@1.1.2: {} + vfile-message@2.0.4: + dependencies: + "@types/unist": 2.0.11 + unist-util-stringify-position: 2.0.3 + + vfile@4.2.1: + dependencies: + "@types/unist": 2.0.11 + is-buffer: 2.0.5 + unist-util-stringify-position: 2.0.3 + vfile-message: 2.0.4 + vite-node@3.2.4(@types/node@24.12.2)(tsx@4.20.6): dependencies: cac: 6.7.14 @@ -3328,7 +6708,7 @@ snapshots: pathe: 2.0.3 vite: 7.3.6(@types/node@24.12.2)(tsx@4.20.6) transitivePeerDependencies: - - '@types/node' + - "@types/node" - jiti - less - lightningcss @@ -3350,20 +6730,20 @@ snapshots: rollup: 4.62.2 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 24.12.2 + "@types/node": 24.12.2 fsevents: 2.3.3 tsx: 4.20.6 vitest@3.2.7(@types/node@24.12.2)(jsdom@27.4.0(@noble/hashes@1.8.0))(tsx@4.20.6): dependencies: - '@types/chai': 5.2.3 - '@vitest/expect': 3.2.7 - '@vitest/mocker': 3.2.7(vite@7.3.6(@types/node@24.12.2)(tsx@4.20.6)) - '@vitest/pretty-format': 3.2.7 - '@vitest/runner': 3.2.7 - '@vitest/snapshot': 3.2.7 - '@vitest/spy': 3.2.7 - '@vitest/utils': 3.2.7 + "@types/chai": 5.2.3 + "@vitest/expect": 3.2.7 + "@vitest/mocker": 3.2.7(vite@7.3.6(@types/node@24.12.2)(tsx@4.20.6)) + "@vitest/pretty-format": 3.2.7 + "@vitest/runner": 3.2.7 + "@vitest/snapshot": 3.2.7 + "@vitest/spy": 3.2.7 + "@vitest/utils": 3.2.7 chai: 5.3.3 debug: 4.4.3 expect-type: 1.4.0 @@ -3380,7 +6760,7 @@ snapshots: vite-node: 3.2.4(@types/node@24.12.2)(tsx@4.20.6) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.12.2 + "@types/node": 24.12.2 jsdom: 27.4.0(@noble/hashes@1.8.0) transitivePeerDependencies: - jiti @@ -3400,6 +6780,12 @@ snapshots: dependencies: xml-name-validator: 5.0.0 + warn-once@0.1.1: {} + + warning@4.0.3: + dependencies: + loose-envify: 1.4.0 + webidl-conversions@8.0.1: {} whatwg-mimetype@4.0.0: {} @@ -3445,3 +6831,5 @@ snapshots: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 + + zwitch@1.0.5: {} diff --git a/web/src/App.test.tsx b/web/src/App.test.tsx index 29c7a4e..e54549c 100644 --- a/web/src/App.test.tsx +++ b/web/src/App.test.tsx @@ -3,15 +3,37 @@ import { fireEvent, render, screen, - within, waitFor, } from "@testing-library/react"; -import { afterEach, expect, test, vi } from "vitest"; -import { App } from "./App"; +import { afterEach, beforeEach, expect, test, vi } from "vitest"; +import React from "react"; +import { App } from "./app/App"; + +// Global mutable authentication state for mocking +let apiAuthenticated = true; + +// Mock matchMedia for Ant Design layout components in jsdom environment +beforeEach(() => { + apiAuthenticated = true; // reset to default + Object.defineProperty(window, "matchMedia", { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // Deprecated + removeListener: vi.fn(), // Deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }); +}); afterEach(() => { cleanup(); vi.unstubAllGlobals(); + vi.clearAllMocks(); }); const ownerCapabilities = [ @@ -73,18 +95,31 @@ function mockApi( clients?: ReturnType[]; } = {}, ) { - const calls: Array<{ path: string; method: string }> = []; + const calls: Array<{ path: string; method: string; body?: any }> = []; const projects = options.projects ?? [project()]; + vi.stubGlobal( "fetch", vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { const path = String(input); const method = init?.method ?? "GET"; - calls.push({ path, method }); - const body = path.endsWith("/auth/context") - ? { + let body: any = undefined; + if (init?.body) { + try { + body = JSON.parse(init.body as string); + } catch { + // Ignored + } + } + calls.push({ path, method, body }); + + let responseBody: any = {}; + + if (path.endsWith("/auth/context")) { + if (apiAuthenticated) { + responseBody = { authenticated: true, - csrfToken: "csrf", + csrfToken: "csrf-token-123", clientSecretPolicy: { defaultGraceSeconds: 3600, maxGraceSeconds: 7200, @@ -94,37 +129,129 @@ function mockApi( displayName: "Owner", isAdmin: !!options.isAdmin, }, - } - : path.endsWith("/projects") && method === "GET" - ? { projects } - : path.endsWith("/members") - ? { - members: options.members ?? [ - { - projectId: "project_one", - subjectId: "subj_owner", - role: "owner", - createdAt: "2026-07-13T00:00:00.000Z", - updatedAt: "2026-07-13T00:00:00.000Z", - }, - ], - } - : path.endsWith("/secrets/rotate") - ? { secret: { value: "rotated-secret" }, client: client() } - : path.endsWith("/admin/reviews") - ? { clients: [client()] } - : path.includes("/clients") && method === "GET" - ? { - clients: options.clients ?? [ - client({ - projectId: path.includes("project_two") - ? "project_two" - : "project_one", - }), - ], - } - : { project: projects[0], client: client() }; - return new Response(JSON.stringify(body), { + }; + } else { + responseBody = { + authenticated: false, + csrfToken: "csrf-token-123", + }; + } + } else if (path.endsWith("/auth/login")) { + responseBody = { + authenticated: true, + csrfToken: "csrf-token-123", + user: { + subjectId: "subj_owner", + displayName: "Owner", + isAdmin: !!options.isAdmin, + }, + clientSecretPolicy: { + defaultGraceSeconds: 3600, + maxGraceSeconds: 7200, + }, + }; + } else if (path.endsWith("/auth/logout")) { + responseBody = {}; + } else if (path.endsWith("/projects") && method === "GET") { + responseBody = { projects }; + } else if (path.endsWith("/projects") && method === "POST") { + responseBody = { + project: { + projectId: "project_new", + name: body?.name || "New Project", + description: body?.description || "", + status: "active", + version: 1, + role: "owner", + capabilities: ownerCapabilities, + }, + }; + } else if (path.includes("/members") && method === "GET") { + responseBody = { + members: options.members ?? [ + { + projectId: "project_one", + subjectId: "subj_owner", + role: "owner", + createdAt: "2026-07-13T00:00:00.000Z", + updatedAt: "2026-07-13T00:00:00.000Z", + }, + ], + }; + } else if (path.includes("/members") && method === "POST") { + responseBody = { project: project() }; + } else if (path.includes("/members/") && method === "PATCH") { + responseBody = { project: project() }; + } else if (path.includes("/members/") && method === "DELETE") { + responseBody = { project: project() }; + } else if (path.includes("/ownership/transfer") && method === "POST") { + responseBody = { project: project() }; + } else if (path.includes("/audit-logs")) { + responseBody = { + auditLogs: [ + { + id: 1, + projectId: "project_one", + clientId: "active-web", + subjectId: "subj_owner", + action: "client_created", + details: { ip: "127.0.0.1" }, + createdAt: "2026-07-13T00:00:00.000Z", + }, + ], + }; + } else if (path.endsWith("/clients") && method === "GET") { + responseBody = { + clients: options.clients ?? [client()], + }; + } else if (path.endsWith("/clients") && method === "POST") { + responseBody = { + client: client({ clientId: "new-client" }), + clientSecret: + body?.clientType === "web" + ? "new-client-secret-plaintext" + : undefined, + }; + } else if (path.includes("/clients/") && method === "GET") { + responseBody = { + client: (options.clients ?? [client()])[0], + }; + } else if (path.includes("/secrets/rotate") && method === "POST") { + responseBody = { + secret: { value: "rotated-secret-plaintext" }, + }; + } else if (path.includes("/secrets/") && method === "POST") { + responseBody = { client: client() }; + } else if (path.includes("/authorizations/revoke") && method === "POST") { + responseBody = { client: client() }; + } else if (path.includes("/disable") && method === "POST") { + responseBody = { client: client({ lifecycleStatus: "disabled" }) }; + } else if (path.endsWith("/admin/reviews") && method === "GET") { + responseBody = { + clients: [ + client({ + proposedRevision: { + revisionId: 2, + revisionNumber: 2, + status: "pending", + version: 1, + redirectUris: ["https://new-uri.com"], + postLogoutRedirectUris: [], + scopeWhitelist: ["openid"], + rejectionReason: null, + }, + }), + ], + }; + } else if (path.includes("/approve") && method === "POST") { + responseBody = { client: client() }; + } else if (path.includes("/reject") && method === "POST") { + responseBody = { client: client() }; + } else { + responseBody = {}; + } + + return new Response(JSON.stringify(responseBody), { status: 200, headers: { "Content-Type": "application/json" }, }); @@ -133,180 +260,55 @@ function mockApi( return calls; } -test("shows project switcher, members, and project clients for owners", async () => { +test("redirects to login when unauthenticated", async () => { + apiAuthenticated = false; mockApi(); + window.history.pushState({}, "", "/manage/projects"); render(); - expect( - await screen.findByRole("button", { name: "Project One · owner" }), - ).toBeTruthy(); - expect(await screen.findByText("subj_owner")).toBeTruthy(); - expect(await screen.findByText("Active Web")).toBeTruthy(); - expect(screen.getByRole("button", { name: "创建客户端" })).toBeTruthy(); - expect(screen.getByRole("button", { name: "添加成员" })).toBeTruthy(); -}); - -test("switches the client list to the selected project", async () => { - const calls = mockApi({ - projects: [ - project(), - project({ projectId: "project_two", name: "Project Two" }), - ], + await waitFor(() => { + expect(screen.getByRole("heading", { name: "登录管理台" })).toBeTruthy(); }); - render(); - fireEvent.click( - await screen.findByRole("button", { name: "Project Two · owner" }), - ); - await waitFor(() => - expect( - calls.some((call) => call.path.endsWith("/projects/project_two/clients")), - ).toBe(true), - ); }); -test("viewer receives a read-only project view", async () => { - mockApi({ projects: [project({ role: "viewer", capabilities: ["view"] })] }); - render(); - expect(await screen.findByText("Active Web")).toBeTruthy(); - expect(screen.queryByRole("button", { name: "创建客户端" })).toBeNull(); - expect(screen.queryByRole("button", { name: "添加成员" })).toBeNull(); - fireEvent.click(screen.getByRole("button", { name: "查看详情" })); - expect(screen.queryByRole("button", { name: "保存基本信息" })).toBeNull(); -}); - -test("member addition uses the project version and nested endpoint", async () => { +test("handles successful login and redirects to projects", async () => { + apiAuthenticated = false; const calls = mockApi(); + window.history.pushState({}, "", "/manage/login"); render(); - const input = await screen.findByLabelText("Subject ID"); - fireEvent.change(input, { target: { value: "subj_new" } }); - fireEvent.click(screen.getByRole("button", { name: "添加成员" })); - await waitFor(() => - expect( - calls.some( - (call) => - call.path.endsWith("/projects/project_one/members") && - call.method === "POST", - ), - ).toBe(true), - ); -}); -test("administrators can open the global review view", async () => { - const calls = mockApi({ isAdmin: true }); - render(); - fireEvent.click(await screen.findByRole("button", { name: "待审核" })); - await waitFor(() => - expect(calls.some((call) => call.path.endsWith("/admin/reviews"))).toBe( - true, - ), - ); -}); + const accountInput = await screen.findByPlaceholderText("学号/工号"); + const passwordInput = screen.getByPlaceholderText("密码"); + const submitButton = screen.getByRole("button", { name: "登录管理台" }); + + fireEvent.change(accountInput, { target: { value: "admin" } }); + fireEvent.change(passwordInput, { target: { value: "password" } }); + + // Set auth state to true before submitting the form + apiAuthenticated = true; + fireEvent.click(submitButton); -test("owner can change roles, delete members, and transfer ownership", async () => { - const calls = mockApi({ - members: [ - { - projectId: "project_one", - subjectId: "subj_owner", - role: "owner", - createdAt: "2026-07-13T00:00:00.000Z", - updatedAt: "2026-07-13T00:00:00.000Z", - }, - { - projectId: "project_one", - subjectId: "subj_member", - role: "viewer", - createdAt: "2026-07-13T00:00:00.000Z", - updatedAt: "2026-07-13T00:00:00.000Z", - }, - ], - }); - render(); - const role = await screen.findByLabelText("subj_member 角色"); - fireEvent.change(role, { target: { value: "maintainer" } }); - const row = screen.getByText("subj_member").closest("tr")!; - fireEvent.click(within(row).getByRole("button", { name: "转移所有权" })); - fireEvent.click(within(row).getByRole("button", { name: "删除" })); await waitFor(() => { expect( calls.some( - (call) => - call.path.endsWith("/projects/project_one/members/subj_member") && - call.method === "PATCH", - ), - ).toBe(true); - expect( - calls.some( - (call) => - call.path.endsWith("/projects/project_one/ownership/transfer") && - call.method === "POST", - ), - ).toBe(true); - expect( - calls.some( - (call) => - call.path.endsWith("/projects/project_one/members/subj_member") && - call.method === "DELETE", + (call) => call.path.endsWith("/auth/login") && call.method === "POST", ), ).toBe(true); }); }); -test("owner can archive a project", async () => { - const calls = mockApi(); - vi.spyOn(window, "confirm").mockReturnValue(true); - render(); - fireEvent.click(await screen.findByRole("button", { name: "归档项目" })); - await waitFor(() => - expect( - calls.some( - (call) => - call.path.endsWith("/projects/project_one") && - call.method === "PATCH", - ), - ).toBe(true), - ); -}); - -test("client security actions remain available after project UI refactor", async () => { - const calls = mockApi({ - clients: [ - client({ - secrets: [ - { - secretId: "secret_one", - status: "active", - createdAt: "2026-07-13T00:00:00.000Z", - expiresAt: null, - revokedAt: null, - version: 1, - }, - ], - }), +test("shows project list and handles switching", async () => { + mockApi({ + projects: [ + project({ projectId: "p1", name: "Project One" }), + project({ projectId: "p2", name: "Project Two" }), ], }); - vi.spyOn(window, "confirm").mockReturnValue(true); + window.history.pushState({}, "", "/manage/projects"); render(); - fireEvent.click(await screen.findByRole("button", { name: "查看详情" })); - fireEvent.click(await screen.findByRole("button", { name: "撤销 Secret" })); - await waitFor(() => - expect( - calls.some((call) => call.path.endsWith("/secrets/secret_one/revoke")), - ).toBe(true), - ); - fireEvent.click(screen.getByRole("button", { name: "轮换 Secret" })); - await waitFor(() => - expect(calls.some((call) => call.path.endsWith("/secrets/rotate"))).toBe( - true, - ), - ); - fireEvent.click(screen.getByRole("button", { name: "撤销全部授权" })); - await waitFor(() => - expect( - calls.some((call) => call.path.endsWith("/authorizations/revoke")), - ).toBe(true), - ); - fireEvent.click(screen.getByRole("button", { name: "紧急停用客户端" })); - await waitFor(() => - expect(calls.some((call) => call.path.endsWith("/disable"))).toBe(true), - ); + + // Should render active project Sider details + expect(await screen.findByText("Project One (当前)")).toBeTruthy(); + // Should render projects table with unique link roles + expect((await screen.findAllByText("Project One")).length).toBeGreaterThan(0); + expect(await screen.findByText("Project Two")).toBeTruthy(); }); diff --git a/web/src/App.tsx b/web/src/App.tsx deleted file mode 100644 index b08668d..0000000 --- a/web/src/App.tsx +++ /dev/null @@ -1,1614 +0,0 @@ -import { FormEvent, useEffect, useState } from "react"; -import useSWR, { SWRConfig } from "swr"; -import logoMonoLight from "./assets/logo-mono-light.svg"; -import logoColor from "./assets/logo-color.svg"; - -type User = { - subjectId: string; - displayName: string; - isAdmin: boolean; -}; -type AuthContext = - | { authenticated: false; csrfToken: string } - | { - authenticated: true; - csrfToken: string; - user: User; - clientSecretPolicy: { - defaultGraceSeconds: number; - maxGraceSeconds: number; - }; - }; -type Client = { - clientId: string; - projectId: string; - createdBySubjectId: string | null; - displayName: string; - description: string; - clientType: "web" | "spa"; - lifecycleStatus: "draft" | "active" | "disabled"; - activeRevision: ClientRevision | null; - proposedRevision: ClientRevision | null; - updatedAt: string; - clientVersion: number; - secrets: ClientSecret[]; -}; -type ProjectAction = - | "view" - | "manage_project" - | "manage_members" - | "write_client" - | "rotate_secret" - | "revoke_authorizations" - | "revoke_secret" - | "disable_client" - | "review"; -type Project = { - projectId: string; - name: string; - description: string; - status: "active" | "archived"; - version: number; - role: "owner" | "maintainer" | "viewer" | null; - capabilities: ProjectAction[]; -}; -type ProjectMember = { - projectId: string; - subjectId: string; - role: "owner" | "maintainer" | "viewer"; - createdAt: string; - updatedAt: string; -}; -type ClientSecret = { - secretId: string; - status: "active" | "retiring" | "revoked"; - createdAt: string; - expiresAt: string | null; - revokedAt: string | null; - version: number; -}; -type ClientRevision = { - revisionId: number; - revisionNumber: number; - status: "draft" | "pending" | "approved" | "rejected"; - redirectUris: string[]; - postLogoutRedirectUris: string[]; - scopeWhitelist: string[]; - rejectionReason: string | null; - version: number; -}; -type ClientFormValue = Pick< - Client, - "clientType" | "displayName" | "description" -> & - Pick< - ClientRevision, - "redirectUris" | "postLogoutRedirectUris" | "scopeWhitelist" - >; - -const emptyClient: ClientFormValue = { - clientType: "web", - displayName: "", - description: "", - redirectUris: [], - postLogoutRedirectUris: [], - scopeWhitelist: ["openid", "profile"], -}; -const emptyClients: Client[] = []; -const clientScopes = [ - "openid", - "profile", - "email", - "student", - "offline_access", -]; - -class ApiError extends Error { - constructor( - message: string, - readonly status: number, - ) { - super(message); - } -} - -async function api( - path: string, - options: RequestInit = {}, - csrfToken?: string, -): Promise { - const headers = new Headers(options.headers); - if (options.body) headers.set("Content-Type", "application/json"); - if (csrfToken) headers.set("X-CSRF-Token", csrfToken); - const response = await fetch(`/api/management${path}`, { - ...options, - headers, - }); - if (!response.ok) { - const body = (await response.json().catch(() => ({}))) as { - error_description?: string; - }; - throw new ApiError( - body.error_description ?? "请求失败,请稍后重试。", - response.status, - ); - } - return response.status === 204 - ? (undefined as T) - : ((await response.json()) as T); -} - -const swrConfiguration = { - provider: () => new Map(), -}; - -export function App() { - return ( - - - - ); -} - -function ManagementApp() { - const { - data: context, - error, - mutate: updateContext, - } = useSWR("/auth/context", api); - - if (error && !context) - return ( - - ); - if (!context) return ; - if (!context.authenticated) { - return ( - void updateContext(value, { revalidate: false })} - /> - ); - } - return ; -} - -function Login({ - context, - onLogin, -}: { - context: AuthContext & { authenticated: false }; - onLogin: (value: AuthContext) => void; -}) { - const [account, setAccount] = useState(""); - const [password, setPassword] = useState(""); - const [error, setError] = useState(""); - const [busy, setBusy] = useState(false); - - async function submit(event: FormEvent) { - event.preventDefault(); - setBusy(true); - setError(""); - try { - onLogin( - await api( - "/auth/login", - { method: "POST", body: JSON.stringify({ account, password }) }, - context.csrfToken, - ), - ); - } catch (reason) { - setError(reason instanceof Error ? reason.message : "登录失败,请重试。"); - } finally { - setBusy(false); - } - } - - return ( -
-
-
- - - CQUT-AUTH Logo - -
-
-
-
-
-

登录管理台

-

- 使用校园统一身份认证账号登录。密码仅用于本次认证,不会被保存。 -

- {error && {error}} -
- - - -
-
-
-
- ); -} - -function Dashboard({ - context, -}: { - context: AuthContext & { authenticated: true }; -}) { - const [tab, setTab] = useState<"clients" | "reviews">("clients"); - const [selectedProjectId, setSelectedProjectId] = useState( - null, - ); - const [selectedClientId, setSelectedClientId] = useState(null); - const [creating, setCreating] = useState(false); - const [secret, setSecret] = useState<{ - clientId: string; - value: string; - } | null>(null); - const [notice, setNotice] = useState(""); - const [actionError, setActionError] = useState(""); - - const { data: projectsData, mutate: refreshProjects } = useSWR<{ - projects: Project[]; - }>("/projects", api); - const projects = projectsData?.projects ?? []; - const selectedProject = - projects.find((project) => project.projectId === selectedProjectId) ?? null; - useEffect(() => { - if (!selectedProjectId && projects.length) - setSelectedProjectId(projects[0]!.projectId); - }, [projects, selectedProjectId]); - const endpoint = - tab === "reviews" - ? "/admin/reviews" - : selectedProjectId - ? `/projects/${encodeURIComponent(selectedProjectId)}/clients` - : null; - const { - data, - error: clientsError, - isLoading, - mutate: refreshClients, - } = useSWR<{ clients: Client[] }>(endpoint, api); - const clients = data?.clients ?? emptyClients; - const selected = - clients.find((client) => client.clientId === selectedClientId) ?? null; - const clientProject = selected - ? (projects.find((project) => project.projectId === selected.projectId) ?? - null) - : selectedProject; - const error = - actionError || - (clientsError instanceof Error - ? clientsError.message - : clientsError - ? "客户端列表加载失败。" - : ""); - - async function mutateClient(path: string, body: object, success: string) { - setActionError(""); - try { - await api( - path, - { method: "POST", body: JSON.stringify(body) }, - context.csrfToken, - ); - setNotice(success); - await refreshClients(); - } catch (reason) { - setActionError(reason instanceof Error ? reason.message : "操作失败。"); - } - } - - async function logout() { - await api("/auth/logout", { method: "POST" }, context.csrfToken); - window.location.assign("/manage"); - } - - return ( -
-
-
- - - CQUT-AUTH Logo - -
- 客户端管理 -
-
-
- - {context.user.displayName} - {context.user.isAdmin && 管理员} - - -
-
-
- - {tab === "clients" && ( -
-
-

项目

- -
-
- {projects.map((project) => ( - - ))} -
- {selectedProject && ( -

- {selectedProject.description || "暂无描述"} ·{" "} - {selectedProject.status} -

- )} - {selectedProject?.capabilities.includes("manage_project") && ( -
- - -
- )} - {selectedProject?.capabilities.includes("manage_members") && ( - { - await refreshProjects(); - }} - /> - )} -
- )} -
-
-

{tab === "reviews" ? "审核客户端" : "OIDC 客户端"}

-

- Subject ID:{context.user.subjectId} -

-
- {tab !== "reviews" && - selectedProject?.capabilities.includes("write_client") && ( - - )} -
- {notice && {notice}} - {error && {error}} - {secret && ( - setSecret(null)} /> - )} - {creating && selectedProject && ( - setCreating(false)} - onSubmit={async (value) => { - const result = await api<{ - client: Client; - clientSecret?: string; - }>( - `/projects/${encodeURIComponent(selectedProject.projectId)}/clients`, - { method: "POST", body: JSON.stringify(value) }, - context.csrfToken, - ); - setCreating(false); - setNotice("客户端草稿已创建,请确认配置后提交审核。"); - if (result.clientSecret) - setSecret({ - clientId: result.client.clientId, - value: result.clientSecret, - }); - await refreshClients(); - }} - /> - )} - {selected && !creating && clientProject && ( - <> - - { - setNotice(message); - await refreshClients(); - }} - onRotated={async (value) => { - setSecret({ clientId: selected.clientId, value }); - setNotice("Client Secret 已轮换,请立即安全保存新 Secret。"); - await refreshClients(); - }} - /> - setSelectedClientId(null)} - onSubmit={async (value) => { - try { - if ( - value.displayName === selected.displayName && - value.description === selected.description - ) - throw new Error("至少修改一项基本信息。"); - await api( - `/projects/${encodeURIComponent(selected.projectId)}/clients/${encodeURIComponent(selected.clientId)}`, - { - method: "PATCH", - body: JSON.stringify({ - displayName: value.displayName, - description: value.description, - clientVersion: selected.clientVersion, - }), - }, - context.csrfToken, - ); - setNotice("客户端基本信息已保存。"); - await refreshClients(); - } catch (reason) { - if (reason instanceof ApiError && reason.status === 409) - throw new Error( - "客户端已被其他操作更新,请关闭编辑器并重新加载。", - ); - throw reason; - } - }} - /> - setSelectedClientId(null)} - onSubmit={async (value) => { - try { - const baseRevision = - selected.proposedRevision ?? selected.activeRevision; - if ( - !baseRevision || - !configurationChanged(value, baseRevision) - ) - throw new Error("至少修改一项 OIDC 配置。"); - await api( - `/projects/${encodeURIComponent(selected.projectId)}/clients/${encodeURIComponent(selected.clientId)}/revision`, - { - method: "PUT", - body: JSON.stringify({ - redirectUris: value.redirectUris, - postLogoutRedirectUris: value.postLogoutRedirectUris, - scopeWhitelist: value.scopeWhitelist, - ...(selected.proposedRevision?.status === "draft" - ? { - revisionId: selected.proposedRevision.revisionId, - revisionVersion: - selected.proposedRevision.version, - } - : {}), - }), - }, - context.csrfToken, - ); - setNotice("OIDC 配置已保存。"); - await refreshClients(); - } catch (reason) { - if (reason instanceof ApiError && reason.status === 409) - throw new Error( - "客户端已被其他操作更新,请关闭编辑器并重新加载。", - ); - throw reason; - } - }} - extraActions={ - <> - {selected.proposedRevision?.status === "draft" && ( - - )} - {selected.proposedRevision?.status === "pending" && ( - - )} - {selected.lifecycleStatus !== "disabled" && - clientProject?.capabilities.includes("disable_client") && ( - - )} - {context.user.isAdmin && - selected.proposedRevision?.status === "pending" && - selected.lifecycleStatus !== "disabled" && ( - <> - - - - )} - - } - /> - - )} - {!creating && !selected && ( - setSelectedClientId(client.clientId)} - /> - )} -
-
- ); -} - -function MemberManager({ - project, - currentSubjectId, - csrfToken, - onChanged, -}: { - project: Project; - currentSubjectId: string; - csrfToken: string; - onChanged: () => Promise; -}) { - const endpoint = `/projects/${encodeURIComponent(project.projectId)}/members`; - const { data, mutate } = useSWR<{ members: ProjectMember[] }>(endpoint, api); - const [subjectId, setSubjectId] = useState(""); - const [role, setRole] = useState("viewer"); - const members = data?.members ?? []; - - async function changed(action: Promise) { - await action; - await onChanged(); - await mutate(); - } - - return ( -
-

团队成员

-
{ - event.preventDefault(); - void changed( - api( - endpoint, - { - method: "POST", - body: JSON.stringify({ - subjectId, - role, - expectedProjectVersion: project.version, - }), - }, - csrfToken, - ), - ).then(() => setSubjectId("")); - }} - > - - - -
-
- - - - - - - - - - {members.map((member) => ( - - - - - - ))} - -
Subject ID角色操作
- {member.subjectId} - - - - {member.subjectId !== currentSubjectId && - member.role !== "owner" && ( - - )} - -
-
-
- ); -} - -function ClientEditor({ - title, - initial, - submitLabel, - onSubmit, - onCancel, - disabled, - allowTypeChange, - section = "all", - configurationDisabled, - sensitiveNotice, - rejectionReason, - extraActions, -}: { - title: string; - initial: ClientFormValue; - submitLabel: string; - onSubmit: (value: ClientFormValue) => Promise; - onCancel: () => void; - disabled?: boolean; - allowTypeChange?: boolean; - section?: "all" | "metadata" | "configuration"; - configurationDisabled?: boolean; - sensitiveNotice?: boolean; - rejectionReason?: string | null; - extraActions?: React.ReactNode; -}) { - const showMetadata = section !== "configuration"; - const showConfiguration = section !== "metadata"; - const [value, setValue] = useState(initial); - const [redirects, setRedirects] = useState(() => - initial.redirectUris.join("\n"), - ); - const [logoutRedirects, setLogoutRedirects] = useState(() => - initial.postLogoutRedirectUris.join("\n"), - ); - const [error, setError] = useState(""); - const [busy, setBusy] = useState(false); - async function submit(event: FormEvent) { - event.preventDefault(); - setBusy(true); - setError(""); - try { - await onSubmit({ - ...value, - redirectUris: lines(redirects), - postLogoutRedirectUris: lines(logoutRedirects), - }); - } catch (reason) { - setError(reason instanceof Error ? reason.message : "保存失败。"); - } finally { - setBusy(false); - } - } - return ( -
-
-

{title}

- -
- {rejectionReason && ( - 最近一次拒绝原因:{rejectionReason} - )} - {sensitiveNotice && ( - - Redirect URI、Logout URI 和 Scope - 的修改审核通过后生效;审核期间继续使用当前生效配置。 - - )} - {error && {error}} -
- {showMetadata && ( - <> - - -