diff --git a/apps/api/src/cloud-security/finding-exceptions.spec.ts b/apps/api/src/cloud-security/finding-exceptions.spec.ts index 36e2b1507a..cd0f9f4eb7 100644 --- a/apps/api/src/cloud-security/finding-exceptions.spec.ts +++ b/apps/api/src/cloud-security/finding-exceptions.spec.ts @@ -20,6 +20,30 @@ describe('ActiveExceptionSet', () => { expect(set.has('c2', 'aws-s3-public-access', 'bucket-1')).toBe(false); expect(set.size).toBe(1); }); + + it('exposes excepted resourceIds grouped by (connectionId, checkId)', () => { + const set = new ActiveExceptionSet([ + ActiveExceptionSet.key('c1', 'check-a', 'r1'), + ActiveExceptionSet.key('c1', 'check-a', 'r2'), + ActiveExceptionSet.key('c1', 'check-b', 'r3'), + ]); + expect(new Set(set.exceptedResourceIds('c1', 'check-a'))).toEqual( + new Set(['r1', 'r2']), + ); + expect(set.exceptedResourceIds('c1', 'check-b')).toEqual(['r3']); + // Nothing excepted for this pair → empty (callers skip the count query). + expect(set.exceptedResourceIds('c1', 'check-c')).toEqual([]); + expect(set.exceptedResourceIds('c2', 'check-a')).toEqual([]); + }); + + it('reconstructs resourceIds that themselves contain the "::" delimiter', () => { + const resourceId = 'arn:aws:s3:::my::weird::bucket'; + const set = new ActiveExceptionSet([ + ActiveExceptionSet.key('c1', 'check-a', resourceId), + ]); + expect(set.has('c1', 'check-a', resourceId)).toBe(true); + expect(set.exceptedResourceIds('c1', 'check-a')).toEqual([resourceId]); + }); }); describe('loadActiveExceptionSet', () => { diff --git a/apps/api/src/cloud-security/finding-exceptions.ts b/apps/api/src/cloud-security/finding-exceptions.ts index a63158188a..f18ea9c31a 100644 --- a/apps/api/src/cloud-security/finding-exceptions.ts +++ b/apps/api/src/cloud-security/finding-exceptions.ts @@ -18,9 +18,31 @@ import { db } from '@db'; */ export class ActiveExceptionSet { private readonly keys: Set; + /** + * Excepted resourceIds grouped by `connectionId::checkId`. Lets a caller + * count a run's excepted failures with a targeted query instead of loading + * every result row into memory. + */ + private readonly resourceIdsByConnCheck: Map>; constructor(keys: Iterable) { this.keys = new Set(keys); + this.resourceIdsByConnCheck = new Map(); + for (const key of this.keys) { + // key = `${connectionId}::${checkId}::${resourceId}`. A resourceId can + // itself contain "::", so take the first two segments and rejoin the + // rest — reconstructing exactly the resourceId used to build the key. + const parts = key.split('::'); + if (parts.length < 3) continue; + const groupKey = `${parts[0]}::${parts[1]}`; + const resourceId = parts.slice(2).join('::'); + let ids = this.resourceIdsByConnCheck.get(groupKey); + if (!ids) { + ids = new Set(); + this.resourceIdsByConnCheck.set(groupKey, ids); + } + ids.add(resourceId); + } } /** Canonical key. The only place this format is defined. */ @@ -41,6 +63,18 @@ export class ActiveExceptionSet { ActiveExceptionSet.key(connectionId, checkId, resourceId), ); } + + /** + * The excepted resourceIds for a (connection, check) pair. Empty when nothing + * is excepted for that pair — callers use this to skip the count query + * entirely (the common case: no exceptions). + */ + exceptedResourceIds(connectionId: string, checkId: string): string[] { + const ids = this.resourceIdsByConnCheck.get( + `${connectionId}::${checkId}`, + ); + return ids ? Array.from(ids) : []; + } } /** diff --git a/apps/api/src/integration-platform/controllers/task-integrations.controller.spec.ts b/apps/api/src/integration-platform/controllers/task-integrations.controller.spec.ts index ccb2f529ac..f833fbd001 100644 --- a/apps/api/src/integration-platform/controllers/task-integrations.controller.spec.ts +++ b/apps/api/src/integration-platform/controllers/task-integrations.controller.spec.ts @@ -169,6 +169,7 @@ describe('TaskIntegrationsController', () => { complete: jest.fn(), addResults: jest.fn(), findLatestPerConnectionAndCheckByTask: jest.fn(), + countExceptedFailures: jest.fn(), }; const mockCredentialVaultService = { getDecryptedCredentials: jest.fn() }; const mockOAuthCredentialsService = { @@ -229,6 +230,9 @@ describe('TaskIntegrationsController', () => { ); mockCheckRunRepository.complete.mockResolvedValue({}); mockCheckRunRepository.addResults.mockResolvedValue({}); + // Default: nothing excepted (no count query needed). Exception tests + // override this to the exact excepted-failure count for the run. + mockCheckRunRepository.countExceptedFailures.mockResolvedValue(0); mockCredentialVaultService.getDecryptedCredentials.mockResolvedValue( VALID_CREDS, ); @@ -564,6 +568,10 @@ describe('TaskIntegrationsController', () => { resourceId: 'reports-bucket', }, ]); + // The excepted-failure count is now computed via a targeted query (the + // full result set is no longer loaded). reports-bucket is the one + // excepted failing result for this run. + mockCheckRunRepository.countExceptedFailures.mockResolvedValue(1); const { runs } = await controller.getTaskCheckRuns('task_1', 'org_1'); @@ -571,6 +579,12 @@ describe('TaskIntegrationsController', () => { expect(runs[0].exceptedCount).toBe(1); expect(runs[0].status).toBe('success'); expect(runs[0].results[0].excepted).toBe(true); + // Exact count is computed via the targeted query, scoped to this run's + // excepted resourceIds (not by loading + filtering every result). + expect(mockCheckRunRepository.countExceptedFailures).toHaveBeenCalledWith( + 'icr_1', + ['reports-bucket'], + ); }); it('keeps an execution-error run as failed (no findings, not excepted)', async () => { @@ -621,5 +635,108 @@ describe('TaskIntegrationsController', () => { mockCheckRunRepository.findLatestPerConnectionAndCheckByTask, ).not.toHaveBeenCalled(); }); + + it('bounds a run with a huge result set + logs so the payload stays small (CS-588)', async () => { + // Defense-in-depth response cap: even if a run somehow carries a large + // result/log set, the serialized response is bounded (results per + // category, evidence size, log count) while the run's summary counts stay + // accurate. The PRIMARY fix — never LOADING all result rows from the DB — + // lives in CheckRunRepository.findLatestPerConnectionAndCheckByTask and is + // covered in check-run.repository.spec.ts. + const HUGE = 5000; + const results = [ + // First finding carries an oversized evidence blob. + { + id: 'icx_finding_0', + passed: false, + resourceType: 'firebase-user', + resourceId: 'user_0', + title: 'finding 0', + description: 'd', + severity: 'high', + remediation: 'fix', + evidence: { blob: 'x'.repeat(30_000) }, + collectedAt: new Date(), + }, + ...Array.from({ length: HUGE - 1 }, (_, i) => ({ + id: `icx_finding_${i + 1}`, + passed: false, + resourceType: 'firebase-user', + resourceId: `user_f_${i + 1}`, + title: 'finding', + description: 'd', + severity: 'high', + remediation: 'fix', + evidence: { ok: true }, + collectedAt: new Date(), + })), + ...Array.from({ length: HUGE }, (_, i) => ({ + id: `icx_pass_${i}`, + passed: true, + resourceType: 'firebase-user', + resourceId: `user_p_${i}`, + title: 'passing', + description: 'd', + evidence: { ok: true }, + collectedAt: new Date(), + })), + ]; + const logs = Array.from({ length: HUGE }, (_, i) => ({ + level: 'info', + message: `log ${i}`, + timestamp: new Date().toISOString(), + })); + + mockCheckRunRepository.findLatestPerConnectionAndCheckByTask.mockResolvedValue( + [ + { + id: 'icr_huge', + checkId: 'firebase-employee-access', + checkName: 'Employee Access', + status: 'failed', + startedAt: new Date(), + completedAt: new Date(), + durationMs: 10, + totalChecked: HUGE * 2, + passedCount: HUGE, + failedCount: HUGE, + errorMessage: null, + logs, + connectionId: 'conn_1', + createdAt: new Date(), + results, + connection: { + id: 'conn_1', + metadata: { connectionName: 'Firebase' }, + provider: { slug: 'firebase', name: 'Firebase' }, + }, + }, + ], + ); + + const { runs } = await controller.getTaskCheckRuns('task_1', 'org_1'); + + // Result detail is bounded (a few findings + a few passing), NOT 10000. + expect(runs[0].results.length).toBeLessThanOrEqual(15); + expect(runs[0].results.length).toBeLessThan(results.length); + // Logs are bounded too. + expect(Array.isArray(runs[0].logs)).toBe(true); + if (Array.isArray(runs[0].logs)) { + expect(runs[0].logs.length).toBeLessThanOrEqual(100); + } + // Summary counts remain authoritative (computed from the full set). + expect(runs[0].passedCount).toBe(HUGE); + expect(runs[0].failedCount).toBe(HUGE); + expect(runs[0].exceptedCount).toBe(0); + // The oversized evidence blob is replaced with a compact placeholder. + const shippedFinding = runs[0].results.find( + (r) => r.id === 'icx_finding_0', + ); + expect(shippedFinding).toBeDefined(); + expect(shippedFinding?.evidence).toMatchObject({ truncated: true }); + // Normal small evidence is left intact. + const shippedPass = runs[0].results.find((r) => r.passed); + expect(shippedPass?.evidence).toEqual({ ok: true }); + }); }); }); diff --git a/apps/api/src/integration-platform/controllers/task-integrations.controller.ts b/apps/api/src/integration-platform/controllers/task-integrations.controller.ts index 253dbf75ec..480f889220 100644 --- a/apps/api/src/integration-platform/controllers/task-integrations.controller.ts +++ b/apps/api/src/integration-platform/controllers/task-integrations.controller.ts @@ -43,6 +43,11 @@ import { countEffectiveFailures, decideTaskStatus, } from '../utils/task-check-evaluation'; +import { + capEvidence, + capLogs, + capResultsForList, +} from '../utils/run-history-limits'; import { db } from '@db'; import type { IntegrationConnection, Prisma } from '@db'; @@ -768,11 +773,31 @@ export class TaskIntegrationsController { // untouched in the DB; this only affects the response. const exceptions = await loadActiveExceptionSet(organizationId); - return { - runs: runs.map((run) => { + const mappedRuns = await Promise.all( + runs.map(async (run) => { const provider = getProviderSummary(run.connection); - const results = run.results.map((r) => ({ + // `run.results` is a BOUNDED, findings-first sample — the repo caps how + // many rows it loads per run (a check can produce tens of thousands, so + // loading them all hangs/OOMs the request). The effective failure count + // is therefore computed EXACTLY via a targeted count query over the + // full set, NOT by filtering this sample. The query is skipped when + // this (connection, check) has no exceptions — the common case. + const exceptedResourceIds = exceptions.exceptedResourceIds( + run.connectionId, + run.checkId, + ); + const exceptedCount = + await this.checkRunRepository.countExceptedFailures( + run.id, + exceptedResourceIds, + ); + + // Tag each sampled result with whether it's excepted (for display); + // authoritative totals come from the run's summary columns + + // exceptedCount above. Cap evidence so one oversized blob can't bloat + // the payload that the browser must parse + render. + const sample = run.results.map((r) => ({ id: r.id, passed: r.passed, resourceType: r.resourceType, @@ -787,8 +812,11 @@ export class TaskIntegrationsController { !r.passed && exceptions.has(run.connectionId, run.checkId, r.resourceId), })); + const results = capResultsForList(sample).map((r) => ({ + ...r, + evidence: capEvidence(r.evidence), + })); - const exceptedCount = results.filter((r) => r.excepted).length; const effectiveFailed = Math.max(0, run.failedCount - exceptedCount); // Only downgrade failed → success when the failures were actually // EXCEPTED. A failed run with no findings (e.g. an execution error, @@ -812,7 +840,7 @@ export class TaskIntegrationsController { failedCount: effectiveFailed, exceptedCount, errorMessage: run.errorMessage, - logs: run.logs, + logs: capLogs(run.logs), connectionId: run.connectionId, connectionLabel: getConnectionLabel(run.connection), provider: { @@ -823,6 +851,8 @@ export class TaskIntegrationsController { createdAt: run.createdAt, }; }), - }; + ); + + return { runs: mappedRuns }; } } diff --git a/apps/api/src/integration-platform/repositories/check-run.repository.spec.ts b/apps/api/src/integration-platform/repositories/check-run.repository.spec.ts index a2f5eaf816..e6d886b19e 100644 --- a/apps/api/src/integration-platform/repositories/check-run.repository.spec.ts +++ b/apps/api/src/integration-platform/repositories/check-run.repository.spec.ts @@ -4,6 +4,9 @@ jest.mock('@db', () => ({ groupBy: jest.fn(), findMany: jest.fn(), }, + integrationCheckResult: { + count: jest.fn(), + }, }, })); @@ -18,6 +21,9 @@ const mockedCheckRun = db.integrationCheckRun as unknown as { }; const mockGroupBy = mockedCheckRun.groupBy; const mockFindMany = mockedCheckRun.findMany; +const mockResultCount = ( + db.integrationCheckResult as unknown as { count: jest.Mock } +).count; function makeRun(opts: { id: string; @@ -162,6 +168,45 @@ describe('CheckRunRepository.findLatestPerConnectionAndCheckByTask', () => { } }); + it('loads a BOUNDED, findings-first result window per run — never all results (CS-588)', async () => { + // A check can produce tens of thousands of results (e.g. a Firebase B2C + // tenant, one per auth user). Eager-loading every result (`results: true`) + // hydrates the whole set into memory and hangs/OOMs the request. Both + // queries must instead use a per-run `take` so the DB caps the load. + mockGroupBy.mockResolvedValue([ + { + connectionId: 'A', + checkId: 'firebase-employee-access', + _max: { createdAt: new Date('2026-06-09T15:00:00Z') }, + }, + ]); + mockFindMany.mockResolvedValue([ + makeRun({ + id: 'rA', + connectionId: 'A', + createdAt: '2026-06-09T15:00:00Z', + }), + ]); + + await repo.findLatestPerConnectionAndCheckByTask('task_1'); + + expect(mockFindMany.mock.calls.length).toBeGreaterThan(0); + for (const call of mockFindMany.mock.calls) { + const resultsInclude = call[0].include.results; + // NOT `results: true` (which loads every row). + expect(resultsInclude).not.toBe(true); + // A finite per-run cap is applied at the DB. + expect(typeof resultsInclude.take).toBe('number'); + expect(resultsInclude.take).toBeGreaterThan(0); + expect(resultsInclude.take).toBeLessThanOrEqual(100); + // Findings-first so the UI's findings still surface when truncated. + expect(resultsInclude.orderBy).toEqual([ + { passed: 'asc' }, + { collectedAt: 'asc' }, + ]); + } + }); + it('clamps an oversized historyPerGroup to the cap (no unbounded read)', async () => { mockGroupBy.mockResolvedValue([ { @@ -205,3 +250,32 @@ describe('CheckRunRepository.findLatestPerConnectionAndCheckByTask', () => { expect(recentCall?.[0].take).toBe(1 * 5); // default 5 }); }); + +describe('CheckRunRepository.countExceptedFailures', () => { + const repo = new CheckRunRepository(); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('short-circuits (no query) when there are no excepted resourceIds', async () => { + const result = await repo.countExceptedFailures('icr_1', []); + expect(result).toBe(0); + expect(mockResultCount).not.toHaveBeenCalled(); + }); + + it('counts only this run’s FAILING results matching the excepted resourceIds', async () => { + mockResultCount.mockResolvedValue(2); + + const result = await repo.countExceptedFailures('icr_1', ['b1', 'b2']); + + expect(result).toBe(2); + expect(mockResultCount).toHaveBeenCalledWith({ + where: { + checkRunId: 'icr_1', + passed: false, + resourceId: { in: ['b1', 'b2'] }, + }, + }); + }); +}); diff --git a/apps/api/src/integration-platform/repositories/check-run.repository.ts b/apps/api/src/integration-platform/repositories/check-run.repository.ts index b66fec86e4..6887e708ec 100644 --- a/apps/api/src/integration-platform/repositories/check-run.repository.ts +++ b/apps/api/src/integration-platform/repositories/check-run.repository.ts @@ -6,6 +6,19 @@ import type { Prisma } from '@db'; const DEFAULT_HISTORY_PER_GROUP = 5; const MAX_HISTORY_PER_GROUP = 50; +/** + * Max result rows loaded PER RUN for the task run-history view. A single check + * can legitimately produce tens of thousands of results — e.g. a Firebase B2C + * tenant whose check yields one result per auth user. Eager-loading them all + * (`results: true`) hydrates the entire set into memory for every run in the + * window, which hangs or OOMs the request (the task UI then never loads). The + * UI only renders a few results per category, so we load a small findings-first + * window. Authoritative totals come from the run's summary columns + a targeted + * exception count (see {@link CheckRunRepository.countExceptedFailures}), never + * from this sample. + */ +const DISPLAY_RESULTS_PER_RUN = 30; + export interface CreateCheckRunDto { connectionId: string; taskId?: string; @@ -180,10 +193,18 @@ export class CheckRunRepository { ? Math.min(historyPerGroup, MAX_HISTORY_PER_GROUP) : DEFAULT_HISTORY_PER_GROUP; + // Bounded, findings-first result load. `take` is applied PER RUN by Prisma + // (correlated limit at the DB), so a run with a huge result set can never + // pull more than DISPLAY_RESULTS_PER_RUN rows. Failing first (`passed asc`) + // so the UI's findings always surface even when truncated; passing fills + // any remaining slots. const include = { - results: true, + results: { + take: DISPLAY_RESULTS_PER_RUN, + orderBy: [{ passed: 'asc' }, { collectedAt: 'asc' }], + }, connection: { include: { provider: true } }, - } as const; + } satisfies Prisma.IntegrationCheckRunInclude; const where = { taskId, @@ -236,6 +257,28 @@ export class CheckRunRepository { ); } + /** + * Count a run's FAILING results whose resourceId is under an active exception. + * Lets the task UI compute the effective (non-excepted) failure count exactly + * WITHOUT loading every result row — only the bounded display sample is + * hydrated; this count covers the full set. `resourceIds` is the excepted set + * for the run's (connection, check); callers pass an empty list (and skip the + * call) when nothing is excepted, which is the common case. + */ + async countExceptedFailures( + runId: string, + resourceIds: string[], + ): Promise { + if (resourceIds.length === 0) return 0; + return db.integrationCheckResult.count({ + where: { + checkRunId: runId, + passed: false, + resourceId: { in: resourceIds }, + }, + }); + } + /** * Get the latest check run for a specific check on a task */ diff --git a/apps/api/src/integration-platform/utils/run-history-limits.spec.ts b/apps/api/src/integration-platform/utils/run-history-limits.spec.ts new file mode 100644 index 0000000000..86d380a498 --- /dev/null +++ b/apps/api/src/integration-platform/utils/run-history-limits.spec.ts @@ -0,0 +1,97 @@ +import { + MAX_EVIDENCE_BYTES, + MAX_LOGS_PER_RUN, + MAX_RESULTS_PER_CATEGORY, + capEvidence, + capLogs, + capResultsForList, +} from './run-history-limits'; + +describe('run-history-limits', () => { + describe('capResultsForList', () => { + const make = (passed: boolean, excepted: boolean, id: number) => ({ + id, + passed, + excepted, + }); + + it('caps each category to MAX_RESULTS_PER_CATEGORY', () => { + const results = [ + ...Array.from({ length: 5000 }, (_, i) => make(false, false, i)), // findings + ...Array.from({ length: 5000 }, (_, i) => make(true, false, i)), // passing + ...Array.from({ length: 50 }, (_, i) => make(false, true, i)), // excepted + ]; + + const capped = capResultsForList(results); + + const findings = capped.filter((r) => !r.passed && !r.excepted); + const passing = capped.filter((r) => r.passed); + const excepted = capped.filter((r) => r.excepted); + + expect(findings).toHaveLength(MAX_RESULTS_PER_CATEGORY); + expect(passing).toHaveLength(MAX_RESULTS_PER_CATEGORY); + expect(excepted).toHaveLength(MAX_RESULTS_PER_CATEGORY); + expect(capped.length).toBe(MAX_RESULTS_PER_CATEGORY * 3); + }); + + it('preserves input order within each category', () => { + const results = [ + make(false, false, 1), + make(false, false, 2), + make(false, false, 3), + ]; + expect(capResultsForList(results).map((r) => r.id)).toEqual([1, 2, 3]); + }); + + it('returns everything when under the cap', () => { + const results = [make(false, false, 1), make(true, false, 2)]; + expect(capResultsForList(results)).toHaveLength(2); + }); + + it('handles an empty array', () => { + expect(capResultsForList([])).toEqual([]); + }); + }); + + describe('capEvidence', () => { + it('passes through null and undefined unchanged', () => { + expect(capEvidence(null)).toBeNull(); + expect(capEvidence(undefined)).toBeUndefined(); + }); + + it('leaves normal-sized evidence intact', () => { + const evidence = { user: 'jane', roles: ['admin'] }; + expect(capEvidence(evidence)).toBe(evidence); + }); + + it('replaces oversized evidence with a compact placeholder', () => { + const big = { blob: 'x'.repeat(MAX_EVIDENCE_BYTES + 1) }; + const capped = capEvidence(big) as { + truncated?: boolean; + sizeBytes?: number; + }; + expect(capped.truncated).toBe(true); + expect(capped.sizeBytes).toBeGreaterThan(MAX_EVIDENCE_BYTES); + // The huge original blob is NOT carried over. + expect(JSON.stringify(capped).length).toBeLessThan(MAX_EVIDENCE_BYTES); + }); + }); + + describe('capLogs', () => { + it('slices a long log array to MAX_LOGS_PER_RUN', () => { + const logs = Array.from({ length: 5000 }, (_, i) => ({ message: `${i}` })); + const capped = capLogs(logs); + expect(Array.isArray(capped)).toBe(true); + expect((capped as unknown[]).length).toBe(MAX_LOGS_PER_RUN); + }); + + it('passes through a short log array unchanged', () => { + const logs = [{ message: 'a' }, { message: 'b' }]; + expect(capLogs(logs)).toHaveLength(2); + }); + + it('passes through non-array values (null) untouched', () => { + expect(capLogs(null)).toBeNull(); + }); + }); +}); diff --git a/apps/api/src/integration-platform/utils/run-history-limits.ts b/apps/api/src/integration-platform/utils/run-history-limits.ts new file mode 100644 index 0000000000..801ed570b3 --- /dev/null +++ b/apps/api/src/integration-platform/utils/run-history-limits.ts @@ -0,0 +1,93 @@ +import type { Prisma } from '@db'; + +/** + * Caps applied to a check run before it is serialized into the `/runs` list + * response. + * + * A single check can legitimately produce an enormous result set — e.g. a + * Firebase B2C tenant whose "employee access" check enumerates tens of + * thousands of auth users (one IntegrationCheckResult per user, each with its + * own `evidence` blob) plus a long `logs` array. Shipping all of that for every + * run in the history window yields a multi-MB payload the browser must + * download, `JSON.parse`, and hold in the SWR cache — which OOM-crashes the + * renderer ("Aw, Snap!"). + * + * The run's summary counts (passedCount / failedCount / exceptedCount) are + * authoritative and computed from the FULL result set before trimming, so the + * UI still shows true totals and a correct "+N more" — only the per-result + * detail it actually renders is shipped. + */ + +/** Per category (findings / excepted / passing) — the UI shows at most 3. */ +export const MAX_RESULTS_PER_CATEGORY = 5; + +/** Max log entries shipped per run. */ +export const MAX_LOGS_PER_RUN = 100; + +/** + * Max serialized size (chars) of a single result's evidence before it is + * replaced with a compact placeholder. Generous so normal evidence is left + * untouched; only a pathologically large blob is trimmed. + */ +export const MAX_EVIDENCE_BYTES = 20_000; + +type CategorizableResult = { passed: boolean; excepted: boolean }; + +/** + * Keep at most {@link MAX_RESULTS_PER_CATEGORY} results from each of the three + * categories the UI renders (findings, excepted, passing), preserving input + * order within each category. Bounds the result array regardless of how many + * rows the check produced. + */ +export function capResultsForList( + results: T[], +): T[] { + const findings: T[] = []; + const excepted: T[] = []; + const passing: T[] = []; + + for (const r of results) { + const bucket = r.passed ? passing : r.excepted ? excepted : findings; + if (bucket.length < MAX_RESULTS_PER_CATEGORY) bucket.push(r); + } + + return [...findings, ...excepted, ...passing]; +} + +/** + * Replace an oversized evidence blob with a compact placeholder so a single + * pathologically large result (e.g. one aggregate result whose evidence is the + * full user list) can't blow up the payload or the JSON tree the UI renders. + */ +export function capEvidence( + evidence: Prisma.JsonValue | null | undefined, +): Prisma.JsonValue | null | undefined { + if (evidence === null || evidence === undefined) return evidence; + + let serialized: string; + try { + serialized = JSON.stringify(evidence); + } catch { + // Non-serializable (shouldn't happen for stored JSON) — leave as-is. + return evidence; + } + if (serialized.length <= MAX_EVIDENCE_BYTES) return evidence; + + return { + truncated: true, + message: + 'Evidence is too large to display here. Re-run or export the check to view the full data.', + sizeBytes: serialized.length, + }; +} + +/** + * Bound the per-run log array. Logs are an unstructured JSON value; only an + * array is trimmed — anything else is passed through untouched. + */ +export function capLogs( + logs: Prisma.JsonValue | null | undefined, +): Prisma.JsonValue | null | undefined { + if (Array.isArray(logs)) return logs.slice(0, MAX_LOGS_PER_RUN); + return logs; +} diff --git a/apps/app/package.json b/apps/app/package.json index 3103e15404..29da583801 100644 --- a/apps/app/package.json +++ b/apps/app/package.json @@ -19,8 +19,6 @@ "@azure/core-rest-pipeline": "^1.21.0", "@browserbasehq/sdk": "2.6.0", "@browserbasehq/stagehand": "^3.0.5", - "@calcom/atoms": "^1.0.102-framer", - "@calcom/embed-react": "^1.5.3", "@date-fns/tz": "^1.2.0", "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", @@ -32,7 +30,6 @@ "@hookform/resolvers": "^5.1.1", "@mendable/firecrawl-js": "^1.24.0", "@monaco-editor/react": "^4.7.0", - "@nangohq/frontend": "^0.53.2", "@novu/api": "^3.15.0", "@novu/nextjs": "^3.10.1", "@number-flow/react": "^0.5.9", diff --git a/apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.test.tsx b/apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.test.tsx index a03c669176..2d1ae27fc0 100644 --- a/apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.test.tsx +++ b/apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.test.tsx @@ -258,6 +258,37 @@ describe('PermissionMatrix', () => { expect(RESOURCES.find((r) => r.key === 'pentest')).toBeDefined(); }); }); + + // CS-591: the role editor exposed no toggle for the `secret` resource, so + // admins could not grant secrets access to custom roles. Users were told to + // use "Integrations write", which only grants `integration:*` — the Secrets + // page then 403s on GET /v1/secrets (RequirePermission('secret','read')) and + // renders empty. The matrix must surface a dedicated Secrets toggle. + describe('Secrets management (CS-591)', () => { + it('includes secret resource in RESOURCES list', () => { + expect(RESOURCES.find((r) => r.key === 'secret')).toBeDefined(); + }); + + it('renders a Secrets row in the matrix', () => { + const mockOnChange = vi.fn(); + render(); + + expect(screen.getByText('Secrets')).toBeInTheDocument(); + }); + + it('maps Write to full secret CRUD including read (unblocks the Secrets page)', () => { + // accessLevelToPermissions is exactly what handleAccessChange calls when + // an admin picks "Write"; it must include 'read' so the assigned user + // passes RequirePermission('secret','read') on GET /v1/secrets. + expect(accessLevelToPermissions('secret', 'edit')).toEqual([ + 'create', 'read', 'update', 'delete', + ]); + }); + + it('maps Read (view) to secret:read', () => { + expect(accessLevelToPermissions('secret', 'view')).toEqual(['read']); + }); + }); }); describe('Utility Functions', () => { diff --git a/apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.tsx b/apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.tsx index d9fac52325..0b08e9f058 100644 --- a/apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.tsx +++ b/apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.tsx @@ -34,6 +34,7 @@ const RESOURCE_LABELS: Record = questionnaire: { label: 'Questionnaires', description: 'Manage security questionnaires' }, integration: { label: 'Integrations', description: 'Manage third-party integrations' }, apiKey: { label: 'API Keys', description: 'Manage API keys for programmatic access' }, + secret: { label: 'Secrets', description: 'Manage secrets and encrypted credentials for automations' }, trust: { label: 'Trust Center', description: 'Manage trust portal settings and access requests' }, pentest: { label: 'Penetration Tests', description: 'Manage penetration testing activities' }, }; @@ -45,7 +46,7 @@ const RESOURCE_SECTIONS: Array<{ label: string; keys: string[] }> = [ keys: [ 'organization', 'member', 'control', 'evidence', 'policy', 'risk', 'vendor', 'task', 'framework', 'audit', 'finding', 'questionnaire', - 'integration', 'apiKey', 'trust', + 'integration', 'apiKey', 'secret', 'trust', ], }, { diff --git a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/check-run-history.tsx b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/check-run-history.tsx index 3e96910182..42901c60fe 100644 --- a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/check-run-history.tsx +++ b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/check-run-history.tsx @@ -160,6 +160,18 @@ export function CheckRunItem({ const excepted = run.results.filter((r) => r.excepted); const passing = run.results.filter((r) => r.passed); + // `run.results` is capped server-side — a check can produce tens of thousands + // of results (e.g. a Firebase B2C tenant) which would otherwise ship a + // multi-MB payload and OOM the browser. Show the first few from the (bounded) + // array, but derive the "+N more" counts from the run's authoritative summary + // counts so the totals are still correct. + const shownFindings = findings.slice(0, 3); + const shownExcepted = excepted.slice(0, 3); + const shownPassing = passing.slice(0, 3); + const moreFindings = Math.max(0, run.failedCount - shownFindings.length); + const moreExcepted = Math.max(0, (run.exceptedCount ?? 0) - shownExcepted.length); + const morePassing = Math.max(0, run.passedCount - shownPassing.length); + const statusColor = hasError ? 'text-destructive' : hasFailed ? 'text-warning' : 'text-primary'; const statusText = hasError ? 'Error' : hasFailed ? 'Issues Found' : 'Passed'; @@ -226,9 +238,9 @@ export function CheckRunItem({ )} {/* Findings */} - {findings.length > 0 && ( + {shownFindings.length > 0 && (
- {findings.slice(0, 3).map((finding) => ( + {shownFindings.map((finding) => (

{finding.title}

@@ -263,9 +275,9 @@ export function CheckRunItem({ )}
))} - {findings.length > 3 && ( + {moreFindings > 0 && (

- +{findings.length - 3} more issues + +{moreFindings} more issues

)}
@@ -273,9 +285,9 @@ export function CheckRunItem({ {/* Excepted - failing findings the customer marked as an exception. Shown muted (not an issue) so it's clear the exception applied. */} - {excepted.length > 0 && ( + {shownExcepted.length > 0 && (
- {excepted.slice(0, 3).map((finding) => ( + {shownExcepted.map((finding) => (

{finding.title}

@@ -290,22 +302,22 @@ export function CheckRunItem({
))} - {excepted.length > 3 && ( + {moreExcepted > 0 && (

- +{excepted.length - 3} more excepted + +{moreExcepted} more excepted

)}
)} {/* Passing Results - always show when there are passing results */} - {passing.length > 0 && ( -
+ {shownPassing.length > 0 && ( +
- ✓ {passing.length} passed + ✓ {run.passedCount} passed
- {passing.slice(0, 3).map((result) => ( + {shownPassing.map((result) => (

{result.title}

@@ -330,9 +342,9 @@ export function CheckRunItem({ )}
))} - {passing.length > 3 && ( + {morePassing > 0 && (

- +{passing.length - 3} more passed + +{morePassing} more passed

)}
diff --git a/apps/app/src/components/calendar-embed.tsx b/apps/app/src/components/calendar-embed.tsx deleted file mode 100644 index 84144722f1..0000000000 --- a/apps/app/src/components/calendar-embed.tsx +++ /dev/null @@ -1,21 +0,0 @@ -'use client'; - -import Cal, { getCalApi } from '@calcom/embed-react'; -import { useEffect } from 'react'; - -export default function CalendarEmbed() { - useEffect(() => { - (async () => { - const cal = await getCalApi({ namespace: 'comp-ai-demo' }); - cal('ui', { hideEventTypeDetails: false, layout: 'month_view' }); - })(); - }, []); - - return ( - - ); -} diff --git a/apps/app/src/components/comments/CommentContentView.test.tsx b/apps/app/src/components/comments/CommentContentView.test.tsx new file mode 100644 index 0000000000..0cfd7daaf9 --- /dev/null +++ b/apps/app/src/components/comments/CommentContentView.test.tsx @@ -0,0 +1,55 @@ +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { render, screen } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; + +// The TipTap editor instance is irrelevant to the plain-text render branch +// exercised here, so stub it out to keep the test light and deterministic. +vi.mock('@tiptap/react', () => ({ + useEditor: () => null, + EditorContent: () => null, +})); + +vi.mock('@trycompai/ui/editor', () => ({ + validateAndFixTipTapContent: (content: unknown) => content, + createMentionExtension: () => ({}), +})); + +vi.mock('@trycompai/ui/editor/extensions', () => ({ + defaultExtensions: () => [], +})); + +vi.mock('@/hooks/use-organization-members', () => ({ + useOrganizationMembers: () => ({ members: [] }), +})); + +import { CommentContentView } from './CommentContentView'; + +// Regression for CS-592: a long, space-less URL pasted into a finding comment +// rendered as a single unbreakable token and overflowed the comment card / sheet +// horizontally (the comment column is a flex `min-w:auto` item, so the break +// must shrink min-content — `break-all` / `overflow-wrap: anywhere`, not +// `break-word`). +describe('CommentContentView', () => { + const longUrl = + 'https://app.trycomp.ai/org_0ab47745b0c0b2c/tasks/tsk_6916cd97cc6f4c40bca83199'; + + it('renders plain-text URLs as links that can wrap instead of overflowing', () => { + // A non-JSON string takes the plain-text render branch. + render(); + + const link = screen.getByRole('link', { name: longUrl }); + expect(link).toHaveAttribute('href', longUrl); + expect(link).toHaveClass('break-all'); + }); + + it('breaks long URLs inside rendered TipTap (.ProseMirror) content', () => { + // The TipTap render branch styles links via the global editor stylesheet, + // which cannot be exercised through jsdom layout — guard the rule directly. + const css = readFileSync(resolve(process.cwd(), 'src/styles/editor.css'), 'utf8'); + const linkRule = css.match(/\.ProseMirror a\s*\{([\s\S]*?)\}/); + + expect(linkRule).not.toBeNull(); + expect(linkRule?.[1]).toContain('overflow-wrap: anywhere'); + }); +}); diff --git a/apps/app/src/components/comments/CommentContentView.tsx b/apps/app/src/components/comments/CommentContentView.tsx index 68fa0fd981..c5c88238a8 100644 --- a/apps/app/src/components/comments/CommentContentView.tsx +++ b/apps/app/src/components/comments/CommentContentView.tsx @@ -137,7 +137,7 @@ export function CommentContentView({ href={href} target="_blank" rel="noopener noreferrer" - className="text-primary underline" + className="text-primary underline break-all" > {part} diff --git a/apps/app/src/styles/editor.css b/apps/app/src/styles/editor.css index 74ae2b88b3..448d3ed914 100644 --- a/apps/app/src/styles/editor.css +++ b/apps/app/src/styles/editor.css @@ -212,6 +212,11 @@ pre .hljs-strong { /* Links */ .ProseMirror a { @apply text-primary underline underline-offset-2; + /* Break long, space-less URLs so they wrap instead of overflowing the + container horizontally. `anywhere` (not `break-word`) is required so the + break opportunities shrink min-content, letting flex `min-w:auto` + ancestors (e.g. the comment column) collapse rather than overflow. */ + overflow-wrap: anywhere; } /* Horizontal rule */ diff --git a/bun.lock b/bun.lock index 72c79fa38c..4f6c5c8a66 100644 --- a/bun.lock +++ b/bun.lock @@ -238,8 +238,6 @@ "@azure/core-rest-pipeline": "^1.21.0", "@browserbasehq/sdk": "2.6.0", "@browserbasehq/stagehand": "^3.0.5", - "@calcom/atoms": "^1.0.102-framer", - "@calcom/embed-react": "^1.5.3", "@date-fns/tz": "^1.2.0", "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", @@ -251,7 +249,6 @@ "@hookform/resolvers": "^5.1.1", "@mendable/firecrawl-js": "^1.24.0", "@monaco-editor/react": "^4.7.0", - "@nangohq/frontend": "^0.53.2", "@novu/api": "^3.15.0", "@novu/nextjs": "^3.10.1", "@number-flow/react": "^0.5.9", @@ -1227,14 +1224,6 @@ "@bugsnag/cuid": ["@bugsnag/cuid@3.2.2", "", {}, "sha512-7onuYLTMqMmHE9BBPG0YER4nFsU1rB+me1/YIeMusqcLbVbKKuG9u9+BDVDpje5e0llkkrVNOKYwmzM9DRIo7A=="], - "@calcom/atoms": ["@calcom/atoms@1.12.1", "", { "dependencies": { "@radix-ui/react-dialog-atoms": "npm:@radix-ui/react-dialog@^1.0.4", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.1.0", "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-tooltip-atoms": "npm:@radix-ui/react-tooltip@^1.0.0", "@tanstack/react-query": "^5.17.15", "class-variance-authority": "^0.4.0", "clsx": "^2.0.0", "dompurify": "^3.2.3", "marked": "^15.0.3", "react-use": "^17.4.2", "tailwind-merge": "^1.13.2", "tailwindcss": "^3.3.3", "tailwindcss-animate": "^1.0.6" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "typescript": "^5.0.0" } }, "sha512-QrI8oFkcnRAjvvlPkyNm4wS81QSeZhNl6I4MdD9Mao46fSBmoQ9cLmKou9v8WdaENOcg5klvWMyc/DL5qq2Qlg=="], - - "@calcom/embed-core": ["@calcom/embed-core@1.5.3", "", {}, "sha512-GeId9gaByJ5EWiPmuvelZOvFWPOTWkcWZr5vGTCbIUTX125oE5yn0n8lDF1MJk5Xj1WO+/dk9jKIE08Ad9ytiQ=="], - - "@calcom/embed-react": ["@calcom/embed-react@1.5.3", "", { "dependencies": { "@calcom/embed-core": "1.5.3", "@calcom/embed-snippet": "1.3.3" }, "peerDependencies": { "react": "^18.2.0 || ^19.0.0", "react-dom": "^18.2.0 || ^19.0.0" } }, "sha512-JCgge04pc8fhdvUmPNVLhW8/lCWK+AAziKecKWWPfv1nn2s+qKP2BwsEAnxhxK9yPOBgE1EIEgmYkrrNB1iajA=="], - - "@calcom/embed-snippet": ["@calcom/embed-snippet@1.3.3", "", { "dependencies": { "@calcom/embed-core": "1.5.3" } }, "sha512-pqqKaeLB8R6BvyegcpI9gAyY6Xyx1bKYfWvIGOvIbTpguWyM1BBBVcT9DCeGe8Zw7Ujp5K56ci7isRUrT2Uadg=="], - "@carbon/icon-helpers": ["@carbon/icon-helpers@10.75.0", "", { "dependencies": { "@ibm/telemetry-js": "^1.5.0" } }, "sha512-WD5zGVE0onRVWHNW+VTf3xM/+WVE2LXuFnNMio6Jf56HqjzNCWLOM2oRRBuDpmtQmDoOUPfCEj8fHgwx3N6CCQ=="], "@carbon/icons-react": ["@carbon/icons-react@11.79.0", "", { "dependencies": { "@carbon/icon-helpers": "^10.75.0", "@ibm/telemetry-js": "^1.5.0", "prop-types": "^15.8.1" }, "peerDependencies": { "react": ">=16" } }, "sha512-560qV1R5xkaZtL6XbGeABoeXTL46CnJi01aeR6/XYW0yRxhHw7yLkdcahOrCBDJClg3X9n+2Xs/XddW9KorB9Q=="], @@ -1735,10 +1724,6 @@ "@mswjs/interceptors": ["@mswjs/interceptors@0.41.8", "", { "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", "@open-draft/until": "^2.0.0", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "strict-event-emitter": "^0.5.1" } }, "sha512-pRLMNKTSGRoLq+KnEB/7OY5vijw1XmcheAAOiv6pj7W1FG32kAGqj1C/RK/cqxRGr1Fh+zBi8sDur8kj3EQv6A=="], - "@nangohq/frontend": ["@nangohq/frontend@0.53.2", "", { "dependencies": { "@nangohq/types": "0.53.2" } }, "sha512-ZSNY9jHVuF/Qfsu8TJBK3tujsxO+Qi7dHWNFt316Mq3g4od9MwuHefTEs0EtfpUTCB18hNE05QOQWCuD8zO8Aw=="], - - "@nangohq/types": ["@nangohq/types@0.53.2", "", { "dependencies": { "axios": "^1.7.9", "json-schema": "0.4.0", "type-fest": "4.32.0" } }, "sha512-G7oC4QsJrmLjAWQmvB7gY8hE0UMr8PofAY/pPsk/0sHIM1YWeealBI7RiPeN4UluArT7w+OoUvMQd+jtrTh9Lw=="], - "@napi-rs/canvas": ["@napi-rs/canvas@0.1.80", "", { "optionalDependencies": { "@napi-rs/canvas-android-arm64": "0.1.80", "@napi-rs/canvas-darwin-arm64": "0.1.80", "@napi-rs/canvas-darwin-x64": "0.1.80", "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.80", "@napi-rs/canvas-linux-arm64-gnu": "0.1.80", "@napi-rs/canvas-linux-arm64-musl": "0.1.80", "@napi-rs/canvas-linux-riscv64-gnu": "0.1.80", "@napi-rs/canvas-linux-x64-gnu": "0.1.80", "@napi-rs/canvas-linux-x64-musl": "0.1.80", "@napi-rs/canvas-win32-x64-msvc": "0.1.80" } }, "sha512-DxuT1ClnIPts1kQx8FBmkk4BQDTfI5kIzywAaMjQSXfNnra5UFU9PwurXrl+Je3bJ6BGsp/zmshVVFbCmyI+ww=="], "@napi-rs/canvas-android-arm64": ["@napi-rs/canvas-android-arm64@0.1.80", "", { "os": "android", "cpu": "arm64" }, "sha512-sk7xhN/MoXeuExlggf91pNziBxLPVUqF2CAVnB57KLG/pz7+U5TKG8eXdc3pm0d7Od0WreB6ZKLj37sX9muGOQ=="], @@ -2085,8 +2070,6 @@ "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], - "@radix-ui/react-dialog-atoms": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], - "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], @@ -2147,8 +2130,6 @@ "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="], - "@radix-ui/react-tooltip-atoms": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="], - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], @@ -2917,8 +2898,6 @@ "@types/jest": ["@types/jest@30.0.0", "", { "dependencies": { "expect": "^30.0.0", "pretty-format": "^30.0.0" } }, "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA=="], - "@types/js-cookie": ["@types/js-cookie@2.2.7", "", {}, "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA=="], - "@types/json-logic-js": ["@types/json-logic-js@2.0.8", "", {}, "sha512-WgNsDPuTPKYXl0Jh0IfoCoJoAGGYZt5qzpmjuLSEg7r0cKp/kWtWp0HAsVepyPSPyXiHo6uXp/B/kW/2J1fa2Q=="], "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], @@ -3195,8 +3174,6 @@ "@xmldom/xmldom": ["@xmldom/xmldom@0.8.13", "", {}, "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw=="], - "@xobotyi/scrollbar-width": ["@xobotyi/scrollbar-width@1.9.5", "", {}, "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ=="], - "@xtuc/ieee754": ["@xtuc/ieee754@1.2.0", "", {}, "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="], "@xtuc/long": ["@xtuc/long@4.2.2", "", {}, "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="], @@ -3495,8 +3472,6 @@ "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], - "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], - "camera-controls": ["camera-controls@3.1.2", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA=="], "caniuse-lite": ["caniuse-lite@1.0.30001791", "", {}, "sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ=="], @@ -3673,8 +3648,6 @@ "copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="], - "copy-to-clipboard": ["copy-to-clipboard@3.3.3", "", { "dependencies": { "toggle-selection": "^1.0.6" } }, "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA=="], - "core-js": ["core-js@3.49.0", "", {}, "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg=="], "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], @@ -3705,14 +3678,10 @@ "crypto-random-string": ["crypto-random-string@4.0.0", "", { "dependencies": { "type-fest": "^1.0.1" } }, "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA=="], - "css-in-js-utils": ["css-in-js-utils@3.1.0", "", { "dependencies": { "hyphenate-style-name": "^1.0.3" } }, "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A=="], - "css-line-break": ["css-line-break@2.1.0", "", { "dependencies": { "utrie": "^1.0.2" } }, "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w=="], "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], - "css-tree": ["css-tree@1.1.3", "", { "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" } }, "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q=="], - "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], "css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="], @@ -3897,8 +3866,6 @@ "dezalgo": ["dezalgo@1.0.4", "", { "dependencies": { "asap": "^2.0.0", "wrappy": "1" } }, "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig=="], - "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], - "diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="], "dingbat-to-unicode": ["dingbat-to-unicode@1.0.1", "", {}, "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w=="], @@ -3911,8 +3878,6 @@ "discord.js": ["discord.js@14.26.4", "", { "dependencies": { "@discordjs/builders": "^1.14.1", "@discordjs/collection": "1.5.3", "@discordjs/formatters": "^0.6.2", "@discordjs/rest": "^2.6.1", "@discordjs/util": "^1.2.0", "@discordjs/ws": "^1.2.3", "@sapphire/snowflake": "3.5.3", "discord-api-types": "^0.38.40", "fast-deep-equal": "3.1.3", "lodash.snakecase": "4.1.1", "magic-bytes.js": "^1.13.0", "tslib": "^2.6.3", "undici": "6.24.1" } }, "sha512-4oBp8tc6Kf8IDBwAHhbsMaAqx1b5fob9SNasZT7V6yyyUydoO5i5fGuX7TmvRtR+q/WgKRnRViRoAWnG7fNyvA=="], - "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], - "dmg-builder": ["dmg-builder@25.1.8", "", { "dependencies": { "app-builder-lib": "25.1.8", "builder-util": "25.1.7", "builder-util-runtime": "9.2.10", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "optionalDependencies": { "dmg-license": "^1.0.11" } }, "sha512-NoXo6Liy2heSklTI5OIZbCgXC1RzrDQsZkeEwXhdOro3FT1VBOvbubvscdPnjVuQ4AMwwv61oaH96AbiYg9EnQ=="], "dmg-license": ["dmg-license@1.0.11", "", { "dependencies": { "@types/plist": "^3.0.1", "@types/verror": "^1.10.3", "ajv": "^6.10.0", "crc": "^3.8.0", "iconv-corefoundation": "^1.1.7", "plist": "^3.0.4", "smart-buffer": "^4.0.2", "verror": "^1.10.0" }, "os": "darwin", "bin": { "dmg-license": "bin/dmg-license.js" } }, "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q=="], @@ -4029,8 +3994,6 @@ "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], - "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], - "es-abstract": ["es-abstract@1.24.2", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg=="], "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], @@ -4179,8 +4142,6 @@ "fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="], - "fast-shallow-equal": ["fast-shallow-equal@1.0.0", "", {}, "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw=="], - "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="], "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="], @@ -4193,8 +4154,6 @@ "fast-xml-parser": ["fast-xml-parser@5.7.2", "", { "dependencies": { "@nodable/entities": "^2.1.0", "fast-xml-builder": "^1.1.5", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w=="], - "fastest-stable-stringify": ["fastest-stable-stringify@2.0.2", "", {}, "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q=="], - "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], "fault": ["fault@1.0.4", "", { "dependencies": { "format": "^0.2.0" } }, "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA=="], @@ -4509,8 +4468,6 @@ "husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="], - "hyphenate-style-name": ["hyphenate-style-name@1.1.0", "", {}, "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="], - "iconv-corefoundation": ["iconv-corefoundation@1.1.7", "", { "dependencies": { "cli-truncate": "^2.1.0", "node-addon-api": "^1.6.3" }, "os": "darwin" }, "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ=="], "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], @@ -4547,8 +4504,6 @@ "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], - "inline-style-prefixer": ["inline-style-prefixer@7.0.1", "", { "dependencies": { "css-in-js-utils": "^3.1.0" } }, "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw=="], - "input-otp": ["input-otp@1.4.2", "", { "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA=="], "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], @@ -4763,8 +4718,6 @@ "joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="], - "js-cookie": ["js-cookie@2.2.1", "", {}, "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ=="], - "js-tiktoken": ["js-tiktoken@1.0.21", "", { "dependencies": { "base64-js": "^1.5.1" } }, "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -5069,8 +5022,6 @@ "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], - "mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="], - "mdurl": ["mdurl@2.0.0", "", {}, "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="], "media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], @@ -5243,8 +5194,6 @@ "named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "^1.1.0" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="], - "nano-css": ["nano-css@5.6.2", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "css-tree": "^1.1.2", "csstype": "^3.1.2", "fastest-stable-stringify": "^2.0.2", "inline-style-prefixer": "^7.0.1", "rtl-css-js": "^1.16.1", "stacktrace-js": "^2.0.2", "stylis": "^4.3.0" }, "peerDependencies": { "react": "*", "react-dom": "*" } }, "sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw=="], - "nanoid": ["nanoid@5.1.11", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg=="], "nanostores": ["nanostores@1.3.0", "", {}, "sha512-XPUa/jz+P1oJvN9VBxw4L9MtdFfaH3DAryqPssqhb2kXjmb9npz0dly6rCsgFWOPr4Yg9mTfM3MDZgZZ+7A3lA=="], @@ -5551,14 +5500,8 @@ "postcss": ["postcss@8.5.14", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg=="], - "postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="], - - "postcss-js": ["postcss-js@4.1.0", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw=="], - "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], - "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="], - "postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="], "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], @@ -5761,10 +5704,6 @@ "react-transition-group": ["react-transition-group@4.4.5", "", { "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", "prop-types": "^15.6.2" }, "peerDependencies": { "react": ">=16.6.0", "react-dom": ">=16.6.0" } }, "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g=="], - "react-universal-interface": ["react-universal-interface@0.6.2", "", { "peerDependencies": { "react": "*", "tslib": "*" } }, "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw=="], - - "react-use": ["react-use@17.6.0", "", { "dependencies": { "@types/js-cookie": "^2.2.6", "@xobotyi/scrollbar-width": "^1.9.5", "copy-to-clipboard": "^3.3.1", "fast-deep-equal": "^3.1.3", "fast-shallow-equal": "^1.0.0", "js-cookie": "^2.2.1", "nano-css": "^5.6.2", "react-universal-interface": "^0.6.2", "resize-observer-polyfill": "^1.5.1", "screenfull": "^5.1.0", "set-harmonic-interval": "^1.0.1", "throttle-debounce": "^3.0.1", "ts-easing": "^0.2.0", "tslib": "^2.1.0" }, "peerDependencies": { "react": "*", "react-dom": "*" } }, "sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g=="], - "react-use-draggable-scroll": ["react-use-draggable-scroll@0.4.7", "", { "peerDependencies": { "react": ">=16" } }, "sha512-6gCxGPO9WV5dIsBaDrgUKBaac8CY07PkygcArfajijYSNDwAq0girDRjaBuF1+lRqQryoLFQfpVaV2u/Yh6CrQ=="], "react-use-measure": ["react-use-measure@2.1.7", "", { "peerDependencies": { "react": ">=16.13", "react-dom": ">=16.13" }, "optionalPeers": ["react-dom"] }, "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg=="], @@ -5773,8 +5712,6 @@ "read-binary-file-arch": ["read-binary-file-arch@1.0.6", "", { "dependencies": { "debug": "^4.3.4" }, "bin": { "read-binary-file-arch": "cli.js" } }, "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg=="], - "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], - "read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="], "read-pkg": ["read-pkg@10.1.0", "", { "dependencies": { "@types/normalize-package-data": "^2.4.4", "normalize-package-data": "^8.0.0", "parse-json": "^8.3.0", "type-fest": "^5.4.4", "unicorn-magic": "^0.4.0" } }, "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg=="], @@ -5857,8 +5794,6 @@ "resend": ["resend@6.12.2", "", { "dependencies": { "postal-mime": "2.7.4", "svix": "1.90.0" }, "peerDependencies": { "@react-email/render": "*" }, "optionalPeers": ["@react-email/render"] }, "sha512-xwgmU4b0OqoabJsIoK/x0Whk0Fcs3bpbK4i/DEWPiE5hYJHyHl0TbB6QbI3gIr+bLdLUJ1GYm/fe41aVFuHXgw=="], - "resize-observer-polyfill": ["resize-observer-polyfill@1.5.1", "", {}, "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="], - "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], "resolve-alpn": ["resolve-alpn@1.2.1", "", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], @@ -5901,8 +5836,6 @@ "rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="], - "rtl-css-js": ["rtl-css-js@1.16.1", "", { "dependencies": { "@babel/runtime": "^7.1.2" } }, "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg=="], - "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], "run-exclusive": ["run-exclusive@2.2.19", "", { "dependencies": { "minimal-polyfills": "^2.2.3" } }, "sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA=="], @@ -5935,8 +5868,6 @@ "schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="], - "screenfull": ["screenfull@5.2.0", "", {}, "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA=="], - "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], "secure-json-parse": ["secure-json-parse@4.1.0", "", {}, "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA=="], @@ -5979,8 +5910,6 @@ "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="], - "set-harmonic-interval": ["set-harmonic-interval@1.0.1", "", {}, "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g=="], - "set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="], "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], @@ -6089,20 +6018,12 @@ "stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="], - "stack-generator": ["stack-generator@2.0.10", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ=="], - "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="], "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], "stackblur-canvas": ["stackblur-canvas@2.7.0", "", {}, "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ=="], - "stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="], - - "stacktrace-gps": ["stacktrace-gps@3.1.2", "", { "dependencies": { "source-map": "0.5.6", "stackframe": "^1.3.4" } }, "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ=="], - - "stacktrace-js": ["stacktrace-js@2.0.2", "", { "dependencies": { "error-stack-parser": "^2.0.6", "stack-generator": "^2.0.5", "stacktrace-gps": "^3.0.4" } }, "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg=="], - "stacktrace-parser": ["stacktrace-parser@0.1.11", "", { "dependencies": { "type-fest": "^0.7.1" } }, "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg=="], "standardwebhooks": ["standardwebhooks@1.0.0", "", { "dependencies": { "@stablelib/base64": "^1.0.0", "fast-sha256": "^1.3.0" } }, "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg=="], @@ -6285,8 +6206,6 @@ "three-stdlib": ["three-stdlib@2.36.1", "", { "dependencies": { "@types/draco3d": "^1.4.0", "@types/offscreencanvas": "^2019.6.4", "@types/webxr": "^0.5.2", "draco3d": "^1.4.1", "fflate": "^0.6.9", "potpack": "^1.0.1" }, "peerDependencies": { "three": ">=0.128.0" } }, "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg=="], - "throttle-debounce": ["throttle-debounce@3.0.1", "", {}, "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg=="], - "throttleit": ["throttleit@2.1.0", "", {}, "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw=="], "through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="], @@ -6331,8 +6250,6 @@ "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], - "toggle-selection": ["toggle-selection@1.0.6", "", {}, "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="], - "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="], @@ -6369,8 +6286,6 @@ "ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="], - "ts-easing": ["ts-easing@0.2.0", "", {}, "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ=="], - "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], "ts-jest": ["ts-jest@29.4.9", "", { "dependencies": { "bs-logger": "^0.2.6", "fast-json-stable-stringify": "^2.1.0", "handlebars": "^4.7.9", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", "semver": "^7.7.4", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", "@jest/transform": "^29.0.0 || ^30.0.0", "@jest/types": "^29.0.0 || ^30.0.0", "babel-jest": "^29.0.0 || ^30.0.0", "jest": "^29.0.0 || ^30.0.0", "jest-util": "^29.0.0 || ^30.0.0", "typescript": ">=4.3 <7" }, "optionalPeers": ["@babel/core", "@jest/transform", "@jest/types", "babel-jest", "jest-util"], "bin": { "ts-jest": "cli.js" } }, "sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ=="], @@ -6861,12 +6776,6 @@ "@browserbasehq/stagehand/uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="], - "@calcom/atoms/class-variance-authority": ["class-variance-authority@0.4.0", "", { "peerDependencies": { "typescript": ">= 4.5.5 < 5" }, "optionalPeers": ["typescript"] }, "sha512-74enNN8O9ZNieycac/y8FxqgyzZhZbxmCitAtAeUrLPlxjSd5zA7LfpprmxEcOmQBnaGs5hYhiSGnJ0mqrtBLQ=="], - - "@calcom/atoms/tailwind-merge": ["tailwind-merge@1.14.0", "", {}, "sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ=="], - - "@calcom/atoms/tailwindcss": ["tailwindcss@3.4.19", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ=="], - "@commitlint/config-validator/ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], "@commitlint/format/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], @@ -7009,8 +6918,6 @@ "@mswjs/interceptors/@open-draft/deferred-promise": ["@open-draft/deferred-promise@2.2.0", "", {}, "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA=="], - "@nangohq/types/type-fest": ["type-fest@4.32.0", "", {}, "sha512-rfgpoi08xagF3JSdtJlCwMq9DGNDE0IMh3Mkpc1wUypg9vPi786AiqeBBKcqvIkq42azsBM85N490fyZjeUftw=="], - "@nestjs/cli/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], "@nestjs/cli/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], @@ -7201,8 +7108,6 @@ "@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@radix-ui/react-dialog-atoms/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@radix-ui/react-menu/@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="], "@radix-ui/react-menu/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], @@ -7241,8 +7146,6 @@ "@radix-ui/react-tooltip/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@radix-ui/react-tooltip-atoms/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@react-email/components/@react-email/render": ["@react-email/render@1.1.2", "", { "dependencies": { "html-to-text": "^9.0.5", "prettier": "^3.5.3", "react-promise-suspense": "^0.3.4" }, "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-RnRehYN3v9gVlNMehHPHhyp2RQo7+pSkHDtXPvg3s0GbzM9SQMW4Qrf8GRNvtpLC4gsI+Wt0VatNRUFqjvevbw=="], "@react-three/fiber/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], @@ -7553,8 +7456,6 @@ "crypto-random-string/type-fest": ["type-fest@1.4.0", "", {}, "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="], - "css-tree/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="], "d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], @@ -8209,8 +8110,6 @@ "postcss/nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], - "postcss-nested/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], - "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], "prisma/@prisma/config": ["@prisma/config@7.6.0", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.20.0", "empathic": "2.0.0" } }, "sha512-MuAz1MK4PeG5/03YzfzX3CnFVHQ6qePGwUpQRzPzX5tT0ffJ3Tzi9zJZbBc+VzEGFCM8ghW/gTVDR85Syjt+Yw=="], @@ -8247,8 +8146,6 @@ "react-syntax-highlighter/refractor": ["refractor@3.6.0", "", { "dependencies": { "hastscript": "^6.0.0", "parse-entities": "^2.0.0", "prismjs": "~1.27.0" } }, "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA=="], - "read-cache/pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], - "read-package-up/read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], "read-pkg/type-fest": ["type-fest@5.6.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA=="], @@ -8333,8 +8230,6 @@ "stack-utils/escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="], - "stacktrace-gps/source-map": ["source-map@0.5.6", "", {}, "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA=="], - "stacktrace-parser/type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], "stats-gl/three": ["three@0.170.0", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="], @@ -8535,14 +8430,6 @@ "@browserbasehq/stagehand/puppeteer-core/devtools-protocol": ["devtools-protocol@0.0.1312386", "", {}, "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA=="], - "@calcom/atoms/tailwindcss/arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], - - "@calcom/atoms/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], - - "@calcom/atoms/tailwindcss/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], - - "@calcom/atoms/tailwindcss/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], - "@commitlint/config-validator/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "@commitlint/parse/conventional-commits-parser/meow": ["meow@12.1.1", "", {}, "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw=="], @@ -9631,10 +9518,6 @@ "@browserbasehq/stagehand/puppeteer-core/chromium-bidi/zod": ["zod@3.23.8", "", {}, "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="], - "@calcom/atoms/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - - "@calcom/atoms/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - "@commitlint/top-level/find-up/locate-path/p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="], "@dub/embed-react/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.20.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g=="], @@ -10351,8 +10234,6 @@ "@aws-sdk/client-s3-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.30", "", { "dependencies": { "@aws-sdk/types": "^3.973.9", "@smithy/signature-v4": "^5.4.5", "@smithy/types": "^4.14.2", "tslib": "^2.6.2" } }, "sha512-HULDLMVzkmTSEv6//7kx2kRevp/VYUpm8hJNNFbmhxDn0fUiGTxVcM9yg31TukvTq8nyOBDUN2gH0o5IRbKjdw=="], - "@calcom/atoms/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "@commitlint/top-level/find-up/locate-path/p-locate/p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="], "@electron/rebuild/node-gyp/glob/minimatch/brace-expansion": ["brace-expansion@1.1.14", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g=="],