@preventive/triage 1.0.0-alpha.47 → 1.0.0-alpha.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/client/dependency-paths.d.ts +2 -1
  2. package/client/dependency-paths.js +16 -4
  3. package/common/managed/agent-tasks.ts +12 -14
  4. package/common/managed/github-agents.ts +7 -6
  5. package/out/activity.js +4 -4
  6. package/out/{chunk-NOZJULWS.js → chunk-6LNQTKAV.js} +1 -1
  7. package/out/chunk-7VAWINQF.js +6 -0
  8. package/out/{chunk-5AHIQFFG.js → chunk-C2AVODGZ.js} +1 -1
  9. package/out/{chunk-I2MDGSQX.js → chunk-IO7JTZ6O.js} +1 -1
  10. package/out/{chunk-UENXT2HK.js → chunk-MOACFRJ4.js} +1 -1
  11. package/out/chunk-O6M574JI.js +1 -0
  12. package/out/{chunk-ZCS4UYHI.js → chunk-PBZPYIG7.js} +1 -1
  13. package/out/{chunk-S6U2J62U.js → chunk-PENGGKX7.js} +42 -41
  14. package/out/{chunk-6WF3KNTL.js → chunk-SZD5CW5R.js} +2 -2
  15. package/out/{chunk-SPEFPML6.js → chunk-TQJDYHVE.js} +1 -1
  16. package/out/{chunk-FH24VHSJ.js → chunk-WYLQWYLA.js} +1 -1
  17. package/out/{chunk-VL43BTSO.js → chunk-X6PJAK3T.js} +1 -1
  18. package/out/client-managed-import.js +1 -1
  19. package/out/client-managed.js +26 -26
  20. package/out/compare.js +13 -13
  21. package/out/dialogs.js +17 -17
  22. package/out/graph.js +1 -1
  23. package/out/index.html +7 -7
  24. package/out/scan.js +1 -1
  25. package/out/terminal.js +214 -214
  26. package/out/view.css +1 -1
  27. package/out/view.js +15 -15
  28. package/package.json +8 -5
  29. package/risk/npm/score.js +1 -1
  30. package/server-managed/agent-merges.ts +10 -8
  31. package/server-managed/app-agents.ts +6 -8
  32. package/server-managed/cache-storage.ts +3 -2
  33. package/server-managed/commit-coauthors.ts +7 -2
  34. package/server-managed/commit-lockfiles.ts +22 -21
  35. package/server-managed/db-methods.ts +52 -38
  36. package/server-managed/db-neon.ts +21 -5
  37. package/server-managed/db.ts +2 -0
  38. package/server-managed/dependabot-access.ts +1 -1
  39. package/server-managed/dependency-review-comments.ts +7 -4
  40. package/server-managed/dependency-reviews.ts +71 -33
  41. package/server-managed/github-accounts.ts +28 -1
  42. package/server-managed/github-app.ts +27 -23
  43. package/server-managed/github-graphql.ts +39 -0
  44. package/server-managed/github-issue-links.ts +8 -1
  45. package/server-managed/github-metadata.ts +2 -2
  46. package/server-managed/http-response.ts +28 -10
  47. package/server-managed/http.ts +677 -230
  48. package/server-managed/index.ts +2 -2
  49. package/server-managed/managed-issues.ts +3 -0
  50. package/server-managed/npm-delta.ts +16 -0
  51. package/server-managed/npm-kept.ts +32 -5
  52. package/server-managed/npm-loads.ts +21 -13
  53. package/server-managed/npm-manifest.ts +1 -1
  54. package/server-managed/npm-packages.ts +13 -4
  55. package/server-managed/object-storage.ts +4 -3
  56. package/server-managed/public-workspace.ts +3 -3
  57. package/server-managed/pull-dependencies.ts +84 -36
  58. package/server-managed/pull-dependency-reviews.ts +13 -10
  59. package/server-managed/rename-diff-worker.js +1 -1
  60. package/server-managed/repository-agents.ts +9 -6
  61. package/server-managed/repository-browser.ts +13 -3
  62. package/server-managed/repository-code.ts +153 -7
  63. package/server-managed/repository-dependency-reviews.ts +7 -0
  64. package/server-managed/repository-history.ts +85 -152
  65. package/server-managed/repository-issues.ts +27 -13
  66. package/server-managed/repository-pulse.ts +9 -3
  67. package/server-managed/repository-squashes.ts +145 -0
  68. package/server-managed/request-timing.ts +63 -0
  69. package/server-managed/reviewed-dependencies.ts +3 -2
  70. package/server-managed/session.ts +34 -12
  71. package/server-managed/sql.ts +16 -8
  72. package/server-managed/storage-encryption.ts +16 -8
  73. package/server-managed/storage-maintenance.ts +5 -2
  74. package/server-managed/storage-payload.ts +18 -0
  75. package/server-managed/storage-stores.ts +3 -2
  76. package/server-managed/team-feed.ts +16 -11
  77. package/server-managed/team-npm-scopes.ts +29 -0
  78. package/server-managed/team-reports.ts +68 -16
  79. package/out/chunk-6ANSHRFQ.js +0 -6
  80. package/out/chunk-ZGNMDGSB.js +0 -1
@@ -2,7 +2,7 @@ import type { ServerResponse } from 'node:http'
2
2
  import { setTimeout as delay } from 'node:timers/promises'
3
3
  import type { ManagedHttpDeps } from './http.ts'
4
4
  import type { StoredUser, TeamReportAccessSnapshot } from './db.ts'
5
- import { TeamReportsError, teamSnapshotKey, teamWorkspaceFindingIds } from './team-reports.ts'
5
+ import { TeamReportsError, annotationRevisionDigest, teamAnnotationRevision, teamSnapshotKey, teamWorkspaceFindingIds } from './team-reports.ts'
6
6
  import type { WorkspaceShareFeedState } from './workspace-shares.ts'
7
7
 
8
8
  // Short database reads work across instances without pinning a Neon connection.
@@ -49,7 +49,7 @@ export async function serveTeamFeed(res: ServerResponse, deps: ManagedHttpDeps,
49
49
  export async function serveUserTeamFeed(res: ServerResponse, deps: ManagedHttpDeps,
50
50
  sessionId: string, user: StoredUser, teamId: string | null, options: FeedOptions & { reportId?: string | null } = {}): Promise<void> {
51
51
  let ids: string[] = [], visibilityKey: string | undefined
52
- let focusedKey: string | undefined
52
+ let focused: TeamReportAccessSnapshot | undefined
53
53
  let previousState: { catalog: number; annotations: number } | undefined
54
54
  const checkUser = (current: { user: Pick<StoredUser, 'id' | 'role'> } | null) => {
55
55
  if (!current) throw new TeamReportsError(401, 'unauthenticated')
@@ -61,10 +61,10 @@ export async function serveUserTeamFeed(res: ServerResponse, deps: ManagedHttpDe
61
61
  const state = await deps.db.getFeedState(sessionId, Date.now())
62
62
  checkUser(state)
63
63
  if (state!.catalog === previousState?.catalog && (!teamId || state!.annotations === previousState?.annotations)) return
64
- if (teamId && focusedKey !== undefined && state!.catalog === previousState?.catalog) {
64
+ if (teamId && focused !== undefined && state!.catalog === previousState?.catalog) {
65
65
  // Annotation changes cannot change visibility. Read only this workspace's
66
66
  // IDs, then fence against concurrent access/content changes before sending.
67
- const triage = JSON.stringify([focusedKey, await deps.db.getAnnotationRevision(ids)])
67
+ const triage = await teamAnnotationRevision(deps.db, focused, ids)
68
68
  const after = await deps.db.getFeedState(sessionId, Date.now())
69
69
  checkUser(after)
70
70
  if (after!.catalog !== state!.catalog) return
@@ -103,29 +103,34 @@ export async function serveUserTeamFeed(res: ServerResponse, deps: ManagedHttpDe
103
103
  return
104
104
  }
105
105
  }
106
- if (snapshot.teamId) triage = JSON.stringify([key, await deps.db.getAnnotationRevision(ids)])
106
+ // As GET /api/teams/:id/annotations answers it, so that a client holding
107
+ // that answer knows this tells nothing new.
108
+ if (snapshot.teamId) triage = await teamAnnotationRevision(deps.db, snapshot, ids)
107
109
  const current = await deps.db.getTeamReportAccessSnapshot(sessionId, Date.now(), teamId, options.reportId)
108
110
  // A concurrent access/content change discards only the annotation read.
109
111
  checkUser(current)
110
112
  if (!current || teamSnapshotKey(current) !== key) return
111
113
  publish('triage', triage)
112
- focusedKey = snapshot.teamId ? key : undefined
114
+ focused = snapshot.teamId ? snapshot : undefined
113
115
  const after = await deps.db.getFeedState(sessionId, Date.now())
114
116
  checkUser(after)
115
117
  if (after!.catalog === state!.catalog && after!.annotations === state!.annotations) previousState = state!
116
- }, options)
118
+ }, { ...options, triageRevision: true })
117
119
  }
118
120
 
121
+ // With `triageRevision`, a triage event tells its revision's digest, as the
122
+ // focused team's annotations answer it; else none, as a public share's.
119
123
  async function serveFeed(res: ServerResponse, deps: ManagedHttpDeps, read: (publish: Publish) => Promise<void>,
120
- { pollMs = TEAM_FEED_POLL_MS, lifetimeMs = TEAM_FEED_LIFETIME_MS }: FeedOptions): Promise<void> {
124
+ { pollMs = TEAM_FEED_POLL_MS, lifetimeMs = TEAM_FEED_LIFETIME_MS, triageRevision = false }: FeedOptions & { triageRevision?: boolean }): Promise<void> {
121
125
  const controller = new AbortController()
122
126
  const close = () => controller.abort()
123
127
  res.once('close', close)
124
128
  const deadline = setTimeout(close, lifetimeMs)
125
129
  const stopped = () => controller.signal.aborted || res.destroyed || deps.isShuttingDown()
126
130
  // Notifications carry no annotation bodies, finding IDs, or global cursors.
127
- // The catalog's opaque version lets clients reuse an identical REST snapshot;
128
- // every connection still confirms current access, including after reconnects.
131
+ // The catalog's opaque version, and a focused team's annotation revision's
132
+ // digest, let clients reuse an identical REST snapshot; every connection
133
+ // still confirms current access, including after reconnects.
129
134
  function write(frame: string): boolean {
130
135
  if (stopped()) return false
131
136
  if (res.write(frame)) return true
@@ -145,7 +150,7 @@ async function serveFeed(res: ServerResponse, deps: ManagedHttpDeps, read: (publ
145
150
  if (stopped()) return false
146
151
  if (revision === undefined) { previous.delete(event); return true }
147
152
  if (revision === previous.get(event)) return true
148
- const data = event === 'teams' ? JSON.stringify({ revision }) : '{}'
153
+ const data = event === 'teams' ? JSON.stringify({ revision }) : triageRevision ? JSON.stringify({ revision: annotationRevisionDigest(revision) }) : '{}'
149
154
  if (!write(`event: ${event}\ndata: ${data}\n\n`)) return false
150
155
  previous.set(event, revision)
151
156
  heartbeat = Date.now()
@@ -2,6 +2,8 @@
2
2
  // scope's private packages in the npm viewer (npm-packages.ts), as admins and
3
3
  // managers may read any. Hidden teams grant nothing, as for their content.
4
4
  import { MAX_TEAM_NPM_SCOPES, normalizeNpmScope } from '../common/managed/npm-packages.js'
5
+ import type { Role } from '../common/managed/roles.ts'
6
+ import { gathered, reviewsIn } from './dependency-reviews.ts'
5
7
  import { ManagedMutationError } from './management.ts'
6
8
  import type { ManagedSql } from './sql.ts'
7
9
 
@@ -23,7 +25,15 @@ export interface TeamNpmScopeStore {
23
25
  // Whether any visible team lists the scope: whoever reads its packages,
24
26
  // they are the instance's own, whose new releases aren't flagged (http.ts).
25
27
  hasTeamNpmScope(scope: string): Promise<boolean>
28
+ // Who session `sessionId` names now, as readSession reads it, their own
29
+ // or, where `viewerSessionId` names an admin's own one, a view of it: their
30
+ // role, the scopes their teams list (listUserNpmScopes), and whether they
31
+ // read the dependency reviews published to team `teamId`
32
+ // (dependency-reviews.ts reviewsIn); in one statement, as a list of a
33
+ // team's reviews asks again once npm is read. Null where it names none.
34
+ getNpmReviewReader(sessionId: string, viewerSessionId: string | null, now: number, teamId: string): Promise<NpmReviewReader | null>
26
35
  }
36
+ export interface NpmReviewReader { id: string; role: Role; scopes: string[]; readsTeam: boolean }
27
37
 
28
38
  // Each distinct scope, normalized; a list with one npm could not publish
29
39
  // under, or too many, is refused whole.
@@ -68,6 +78,7 @@ export function teamNpmScopeMethods(db: ManagedSql): TeamNpmScopeStore {
68
78
  WHERE tu.user_id = ? ORDER BY ns.scope`).all(userId) as { scope: string }[]
69
79
  return rows.map(row => row.scope)
70
80
  },
81
+ getNpmReviewReader: (sessionId, viewerSessionId, now, teamId) => npmReviewReader(db, sessionId, viewerSessionId, now, teamId),
71
82
  async hasTeamNpmScope(scope) {
72
83
  return !!await db.prepare(`SELECT 1 AS listed FROM managed_team_npm_scope ns
73
84
  JOIN managed_team t ON t.id = ns.team_id AND t.hidden = 0
@@ -75,3 +86,21 @@ export function teamNpmScopeMethods(db: ManagedSql): TeamNpmScopeStore {
75
86
  },
76
87
  }
77
88
  }
89
+
90
+ // getNpmReviewReader's statement, its session held to what readSession's
91
+ // own are (db-methods.ts selectOwnSessionStmt, selectViewSessionStmt).
92
+ async function npmReviewReader(db: ManagedSql, sessionId: string, viewerSessionId: string | null, now: number, teamId: string): Promise<NpmReviewReader | null> {
93
+ const row = await db.prepare(`WITH reader AS (
94
+ SELECT u.id AS id, u.role AS role FROM managed_session s JOIN managed_user u ON u.id = s.user_id
95
+ WHERE s.id = ? AND s.expires_at > ? AND ((? IS NULL AND s.viewer_session IS NULL) OR (s.viewer_session = ? AND EXISTS (
96
+ SELECT 1 FROM managed_session p JOIN managed_user a ON a.id = p.user_id
97
+ WHERE p.id = s.viewer_session AND p.expires_at > ? AND p.viewer_session IS NULL AND a.role = 'admin')))
98
+ )
99
+ SELECT v.id AS id, v.role AS role,
100
+ (SELECT json_group_array(x.scope ORDER BY x.scope) FROM (SELECT DISTINCT ns.scope AS scope FROM managed_team_user tu
101
+ JOIN managed_team t ON t.id = tu.team_id AND t.hidden = 0 JOIN managed_team_npm_scope ns ON ns.team_id = tu.team_id
102
+ WHERE tu.user_id = v.id) x) AS scopes,
103
+ CASE WHEN EXISTS (SELECT 1 FROM managed_team t JOIN managed_user u ON u.id = v.id WHERE t.id = ? AND ${reviewsIn(false)}) THEN 1 ELSE 0 END AS readsTeam
104
+ FROM reader v`).get(sessionId, now, viewerSessionId, viewerSessionId, now, teamId) as { id: string; role: Role; scopes: unknown; readsTeam: unknown } | undefined
105
+ return row ? { id: row.id, role: row.role, scopes: gathered<string>(row.scopes), readsTeam: Number(row.readsTeam) === 1 } : null
106
+ }
@@ -2,10 +2,12 @@
2
2
  // Bounded snapshots retain filtered content and visibility for repeated reads.
3
3
  import { mergeLinkGroups } from './link-reports.ts'
4
4
  import { Buffer } from 'node:buffer'
5
+ import { createHash } from 'node:crypto'
5
6
  import { backfillFindingIds, reportEntries, stampSecurityGroups } from '@preventive/report'
6
7
  import { managedFindingSourcePaths, readManagedReport } from '../common/managed/report-content.ts'
7
8
  import { filterReportData, projectFinding } from '../common/managed/report-filter.ts'
8
9
  import { revalidationLinks, securityLinks } from '../common/security-links.js'
10
+ import { treeDependencyDirectory } from '../client/dependency-paths.js'
9
11
  import type { BlobStore } from './blob-store.ts'
10
12
  import type { ManagedDb, TeamReportAccessSnapshot } from './db.ts'
11
13
  import { triageWireEntry } from './triage-response.ts'
@@ -20,23 +22,26 @@ const VISIBILITY_CACHE_MAX_ITEMS = 250_000
20
22
  const VISIBILITY_CACHE_MAX_SNAPSHOTS = 32
21
23
  const caches = new WeakMap<ManagedDb, Map<string, Visibility>>()
22
24
  const REPORT_CACHE_BYTES = 16 * 1024 * 1024
23
- const reportCaches = new WeakMap<ManagedDb, Map<string, Buffer>>()
25
+ // A workspace's encoded reports, and its reports' file trees apart.
26
+ type EncodedWorkspace = { reports: Buffer; trees: Buffer }
27
+ const reportCaches = new WeakMap<ManagedDb, Map<string, EncodedWorkspace>>()
28
+ const encodedBytes = ({ reports, trees }: EncodedWorkspace) => reports.length + trees.length
24
29
  // A workspace's report reads at once. Its reports' sizes are bounded together
25
30
  // before any is read, and each is held parsed till the build ends, so more at
26
31
  // once costs only the raw bytes in flight: a cold build of a team's reports
27
32
  // is so many storage round trips one after another.
28
33
  const WORKSPACE_READS_AT_ONCE = 16
29
- function retainReports(db: ManagedDb, key: string, bytes: Buffer) {
30
- if (bytes.length > REPORT_CACHE_BYTES) return
34
+ function retainReports(db: ManagedDb, key: string, encoded: EncodedWorkspace) {
35
+ if (encodedBytes(encoded) > REPORT_CACHE_BYTES) return
31
36
  let cache = reportCaches.get(db)
32
37
  if (!cache) { cache = new Map(); reportCaches.set(db, cache) }
33
38
  cache.delete(key)
34
- let total = bytes.length + [...cache.values()].reduce((sum, value) => sum + value.length, 0)
39
+ let total = encodedBytes(encoded) + [...cache.values()].reduce((sum, value) => sum + encodedBytes(value), 0)
35
40
  for (const [oldest, value] of cache) {
36
41
  if (total <= REPORT_CACHE_BYTES && cache.size < VISIBILITY_CACHE_MAX_SNAPSHOTS) break
37
- cache.delete(oldest); total -= value.length
42
+ cache.delete(oldest); total -= encodedBytes(value)
38
43
  }
39
- cache.set(key, bytes)
44
+ cache.set(key, encoded)
40
45
  }
41
46
  function visibilityWeight(visible: Visibility): number {
42
47
  return [...visible.values()].reduce((sum, v) => sum + v.ids.size + v.sourcePaths.size, 0)
@@ -92,7 +97,26 @@ function linksOf(data: unknown): string[][] | null {
92
97
  if (!record.links.every(ids => Array.isArray(ids) && ids.every(id => typeof id === 'string'))) throw new TeamReportsError(422, 'unreadable-links')
93
98
  return record.links
94
99
  }
95
- async function buildTeamWorkspace(db: ManagedDb, store: BlobStore, snapshot: TeamReportAccessSnapshot): Promise<{ body: Buffer; visible: Visibility }> {
100
+ // A report's file tree goes apart, asked for by its graph or Files alone
101
+ // (loadTeamTreesResponse). The report tells in its place how many files it
102
+ // holds (`treeFiles`) and the dependency directory it names
103
+ // (`treeDependencies`), which classifies findings as the tree itself would
104
+ // (client/dependency-paths.js). Each file's is sent without the hash of its
105
+ // tree (`treeHash`), which no team view reads.
106
+ function withoutTree(report: TeamReport): string | null {
107
+ const tree = (report.data as { tree?: unknown } | null)?.tree
108
+ if (!tree || typeof tree !== 'object' || Array.isArray(tree)) return null
109
+ const { tree: _tree, ...data } = report.data as Finding
110
+ const named = treeDependencyDirectory(tree)
111
+ report.data = { ...data, treeFiles: Object.keys(tree).length, ...(named ? { treeDependencies: named } : {}) }
112
+ const files = Object.entries(tree).map(([file, entry]) => {
113
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return [file, entry]
114
+ const { treeHash: _treeHash, ...kept } = entry as Finding
115
+ return [file, kept]
116
+ })
117
+ return `${JSON.stringify(report.id)}:${JSON.stringify(Object.fromEntries(files))}`
118
+ }
119
+ async function buildTeamWorkspace(db: ManagedDb, store: BlobStore, snapshot: TeamReportAccessSnapshot): Promise<EncodedWorkspace & { visible: Visibility }> {
96
120
  if (snapshot.reports.length > MAX_REPORT_QUERY_COUNT || snapshot.reports.reduce((n, r) => n + r.byteSize, 0) > MAX_REPORT_QUERY_BYTES) throw new TeamReportsError(413, 'batch-too-large')
97
121
  const reports: TeamReport[] = []
98
122
  let inputBytes = 0, next = 0
@@ -143,7 +167,9 @@ async function buildTeamWorkspace(db: ManagedDb, store: BlobStore, snapshot: Tea
143
167
  // document even though its referenced findings are outside this response.
144
168
  if (links && !snapshot.hiddenReportId) report.data = { source: 'links', findings: [], links: links.map(ids => [...new Set(ids.filter(id => allIds.has(id)))]).filter(ids => ids.length >= 2) }
145
169
  }
146
- let outputBytes = 14
170
+ const trees = Buffer.from(`{"trees":{${reports.map(withoutTree).filter(tree => tree !== null).join(',')}}}`)
171
+ // Bounded together, as when the trees were sent with their reports.
172
+ let outputBytes = 14 + trees.length
147
173
  const parts = [Buffer.from('{"reports":[')]
148
174
  for (const [index, report] of reports.entries()) {
149
175
  const bytes = Buffer.from(JSON.stringify(report))
@@ -156,10 +182,10 @@ async function buildTeamWorkspace(db: ManagedDb, store: BlobStore, snapshot: Tea
156
182
  const suffix = Buffer.from(links.length > 0 ? `],"links":${JSON.stringify(links)}}` : ']}')
157
183
  if (outputBytes + suffix.length > MAX_REPORT_QUERY_BYTES) throw new TeamReportsError(413, 'batch-too-large')
158
184
  parts.push(suffix)
159
- const body = Buffer.concat(parts)
185
+ const encoded = { reports: Buffer.concat(parts), trees }
160
186
  retainVisibility(db, workspaceKey(snapshot), visible)
161
- retainReports(db, workspaceKey(snapshot), body)
162
- return { body, visible }
187
+ retainReports(db, workspaceKey(snapshot), encoded)
188
+ return { ...encoded, visible }
163
189
  }
164
190
  const pendingWorkspaces = new WeakMap<ManagedDb, Map<string, ReturnType<typeof buildTeamWorkspace>>>()
165
191
  async function loadTeamWorkspace(db: ManagedDb, store: BlobStore, snapshot: TeamReportAccessSnapshot) {
@@ -176,7 +202,13 @@ async function loadTeamWorkspace(db: ManagedDb, store: BlobStore, snapshot: Team
176
202
  // Warm HTTP reads need neither a parsed copy nor another serialization pass.
177
203
  export async function loadTeamReportsResponse(db: ManagedDb, store: BlobStore, snapshot: TeamReportAccessSnapshot): Promise<Buffer> {
178
204
  const cached = reportCaches.get(db)?.get(workspaceKey(snapshot))
179
- return cached ?? (await loadTeamWorkspace(db, store, snapshot)).body
205
+ return cached?.reports ?? (await loadTeamWorkspace(db, store, snapshot)).reports
206
+ }
207
+ // The workspace's reports' file trees, by report ID (withoutTree), for the
208
+ // same snapshot as its reports and with the same recheck before sending.
209
+ export async function loadTeamTreesResponse(db: ManagedDb, store: BlobStore, snapshot: TeamReportAccessSnapshot): Promise<Buffer> {
210
+ const cached = reportCaches.get(db)?.get(workspaceKey(snapshot))
211
+ return cached?.trees ?? (await loadTeamWorkspace(db, store, snapshot)).trees
180
212
  }
181
213
  export async function loadTeamReports(db: ManagedDb, store: BlobStore, snapshot: TeamReportAccessSnapshot): Promise<TeamReport[]> {
182
214
  // Object consumers get their own copy, including when sharing a cold load.
@@ -197,6 +229,19 @@ export async function teamWorkspaceFindingIds(db: ManagedDb, store: BlobStore, s
197
229
  for (const report of (await teamVisibility(db, store, snapshot)).values()) for (const id of report.ids) ids.add(id)
198
230
  return ids
199
231
  }
232
+
233
+ // What a focused team's annotations are at, for the snapshot reading them, as
234
+ // its feed tells it (team-feed.ts serveUserTeamFeed) and its annotations
235
+ // answer it (loadTeamAnnotations): the snapshot's key and the revision of
236
+ // every visible finding's annotations (getAnnotationRevision), its workspace's
237
+ // findings being `ids` (teamWorkspaceFindingIds).
238
+ export async function teamAnnotationRevision(db: ManagedDb, snapshot: TeamReportAccessSnapshot, ids: readonly string[]): Promise<string> {
239
+ return JSON.stringify([teamSnapshotKey(snapshot), await db.getAnnotationRevision(ids)])
240
+ }
241
+
242
+ // A revision as the client is told it: a digest, telling only whether what it
243
+ // covers changed, none of the finding IDs, batches or issues it is read from.
244
+ export const annotationRevisionDigest = (revision: string): string => createHash('sha256').update(revision).digest('base64url')
200
245
  export async function teamReportVisibility(db: ManagedDb, store: BlobStore, snapshot: TeamReportAccessSnapshot, reportId: string): Promise<ReportVisibility> {
201
246
  if (!snapshot.reports.some(r => r.id === reportId)) throw new TeamReportsError(404, 'no-report')
202
247
  const visible = await teamVisibility(db, store, snapshot)
@@ -223,18 +268,25 @@ export async function teamSourcePaths(db: ManagedDb, store: BlobStore, sessionId
223
268
 
224
269
  // Serialize shared annotation bodies once. Reports carry only the annotated
225
270
  // finding IDs visible in that report; callers revalidate access before sending.
271
+ // With them, the digest of the revision the whole workspace's are at, as the
272
+ // team's feed tells it (`revision`), read before them: a write between leaves
273
+ // it older than what is sent, so the feed's next differs and the client reads
274
+ // again, never the reverse.
226
275
  export async function loadTeamAnnotations(db: ManagedDb, store: BlobStore, snapshot: TeamReportAccessSnapshot, reportId: string | null = null) {
227
276
  // Restrict annotation reads only after classifying the complete workspace:
228
277
  // links and findings in other reports can affect this report's visibility.
229
- const visible = reportId === null ? await teamVisibility(db, store, snapshot)
230
- : new Map([[reportId, await teamReportVisibility(db, store, snapshot, reportId)]])
231
- const ids = new Set<string>()
278
+ if (reportId !== null && !snapshot.reports.some(r => r.id === reportId)) throw new TeamReportsError(404, 'no-report')
279
+ const workspace = await teamVisibility(db, store, snapshot)
280
+ const visible = reportId === null ? workspace : new Map([[reportId, workspace.get(reportId)!]])
281
+ const all = new Set<string>(), ids = new Set<string>()
232
282
  for (const report of visible.values()) for (const id of report.ids) ids.add(id)
283
+ for (const report of workspace.values()) for (const id of report.ids) all.add(id)
284
+ const revision = await teamAnnotationRevision(db, snapshot, [...all])
233
285
  const { triage, comments, issues: savedIssues } = await db.getAnnotations([...ids])
234
286
  const issues = Object.fromEntries(visibleManagedIssues(savedIssues, snapshot)
235
287
  .map(issue => [issue.findingId, { url: issue.issueUrl!, autoFix: issue.autoFixUrl }]))
236
288
  const entries = Object.fromEntries(triage.map(row => [row.findingId, triageWireEntry(row)]))
237
289
  const annotated = new Set([...triage.map(row => row.findingId), ...comments.map(comment => comment.findingId), ...Object.keys(issues)])
238
290
  const reports = Object.fromEntries([...visible].map(([id, report]) => [id, [...report.ids].filter(finding => annotated.has(finding))]))
239
- return { reports, entries, comments, issues }
291
+ return { reports, entries, comments, issues, revision: annotationRevisionDigest(revision) }
240
292
  }
@@ -1,6 +0,0 @@
1
- import{a as e}from"./chunk-SXV2T5C4.js";import{b as t}from"./chunk-TUII34K2.js";var n=new Set([`module`,`commonjs`,`json`,`module-typescript`,`commonjs-typescript`]),r=new Set([`solidity`,`php`,`shell`,`rust`]),i=new Set([`java`,`kotlin`,`gradle`,`objc`,`objcpp`,`swift`,`c`,`cpp`,`c-header`,`cpp-header`,`ruby`,`python`,`cmake`,`podspec`,`podfile`,`podfile-lock`,`template`,`xml`,`env`,`fastlane`,`pbxproj`]),a=new Set([`resource`,`resource:base64`]),o=new Set([`stat:file`,`stat:directory`]),s=new Set([...n,...r,...i,...a,`patch`,`directory`,...o]),c=e=>o.has(e),l=e=>e===`directory`||e===`stat:directory`?`directory`:`file`;function u(e,t,n){if(e===t)return e;let r=c(e);if(r!==c(t)&&l(e)===l(t))return r?t:e;throw Error(`format conflict for '${n}' ('${t}' vs '${e}')`)}function d(e,t){return t===``?e:e===`.`?t:`${e}/${t}`}var f=/^(?=[A-Za-z0-9-]{1,39}\/)[A-Za-z0-9](?:-?[A-Za-z0-9])*\/(?!\.\.?$)[\w.-]{1,100}$/u,p=/^(?!\.\.?(?:\/|$))[\w.~@+-]+(?:\/(?!\.\.?(?:\/|$))[\w.~@+-]+)*$/u,m=/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u,h={github:e=>typeof e==`string`&&f.test(e),directory:e=>typeof e==`string`&&e.length<=1024&&(e===``||p.test(e)),commit:e=>typeof e==`string`&&m.test(e)},ee=(e,t)=>e?.toLowerCase()===t?.toLowerCase(),g=(e,t,n)=>{if(e===void 0)return;x(e)||y(!1,`${n} must be an object`);for(let r of Object.keys(e))Object.hasOwn(t,r)||y(!1,`unknown ${n} key '${r}'`);let r=Object.entries(t).map(([t,r])=>typeof r==`object`?[t,g(e[t],r,`${n}.${t}`)]:(e[t]!==void 0&&!r(e[t])&&y(!1,`invalid ${n}.${t}: ${JSON.stringify(e[t])}`),[t,e[t]])).filter(([,e])=>e!==void 0);return r.length===0?void 0:Object.freeze(S(r))},_=(e,t=`bundle repo`)=>g(e,h,t),te=(e,t)=>t??(k(e)?`npm`:void 0),ne=(e,{ecosystem:t,repo:n},r)=>{if(n===void 0)return;te(e,t)===void 0&&y(!1,`${r}: '${e}' is no dependency's bucket, and carries no repo`);let i=_(n,`${r} module '${e}' repo`);return i?.github===void 0&&y(!1,`${r} module '${e}' repo has no github`),i},v=({name:e,version:t,ecosystem:n,repo:r,files:i})=>({name:e,version:t,...n===void 0?{}:{ecosystem:n},...r===void 0?{}:{repo:r},files:i});function re({name:e,version:t,ecosystem:n,repo:r,files:i},a,o){return y(n===void 0||typeof n==`string`),v({name:e,version:t??void 0,ecosystem:n,repo:ne(a,{ecosystem:n,repo:r},o),files:S(Object.entries(i))})}function ie(e,{scope:t=`full`}={}){let n=new Set;for(let[r,{files:i}]of e)if(t===`full`||k(r))for(let e of Object.keys(i))n.add(d(r,e));return n}function ae(e,{what:t,files:n,formats:r,scope:i}){if(e.includes(`\\`))return`holds a '\\'`;if(T(e))return`escapes the root`;if(i!==`full`&&!k(e))return`is outside node_modules, which a '${i}'-scope ${t} does not record`;if(!n.has(e))return`names no file the ${t} records`;let a=r.get(e);return a===`directory`?`is a directory capture, not a file`:c(a)?`is a payload-free '${a}' record, not a file`:null}function oe(e,{what:t,files:n,formats:r,scope:i}){for(let a of e){let e=ae(a,{what:t,files:n,formats:r,scope:i});y(e===null,`${t}: executable entry '${a}' ${e}`)}}function se(e,{what:t,files:n,formats:r,scope:i=`full`}){if(e===void 0)return new Set;let a=`${t}: executable`;y(Array.isArray(e),`${a} must be an array of file paths`);let o=new Set;for(let t of e)y(typeof t==`string`&&t!==``,`${a} entry must be a non-empty string`),y(!o.has(t),`${a} entry '${t}' is listed twice`),o.add(t);return oe(o,{what:t,files:n,formats:r,scope:i}),o}function ce(e,{what:t,modules:n,formats:r,scope:i}){if(e.size!==0)return oe(e,{what:t,files:ie(n,{scope:i}),formats:r,scope:i}),C(e)}function y(e,t){if(!e)throw Error(t)}function le(e,t){let[n,r]=[e.split(`/`),t.split(`/`)];for(;n.length>0&&n[0]===r[0];)n.shift(),r.shift();if(n.length===0&&r.length===0)return 0;if(n.length<2)return r.length<2&&n>r?1:-1;if(r.length<2)return 1;if(n[0]===`*`)return-1;if(r[0]===`*`||n[0]===`node_modules`)return 1;if(r[0]===`node_modules`)return-1;let[i,a]=[n,r].map(e=>e.join(String.fromCodePoint(0)));if(i<a)return-1;if(i>a)return 1;throw Error(`Unreachable`)}var b=(e,t)=>le(e[0],t[0]),x=e=>e&&[null,Object.prototype].includes(Object.getPrototypeOf(e)),S=e=>Object.setPrototypeOf(Object.fromEntries(e),null),C=e=>[...e].toSorted(le),w=(e,{sorted:t=!0}={})=>S((t?[...e].toSorted(b):[...e]).map(([e,n])=>[e,n instanceof Map?w(n,{sorted:t}):n])),ue=(e,t)=>e.get(t)??e.set(t,new Map).get(t),de=e=>new Map(Object.entries(e).map(([e,t])=>[e,x(t)?de(t):t]));function T(e){if(e.startsWith(`/`))return!0;if(!e.includes(`..`))return!1;let t=0;for(let n of e.split(`/`))if(n!==`.`&&n!==``){if(n!==`..`)t++;else if(--t<0)return!0}return!1}var fe=e=>e.includes(`\\`)||T(e),E=(e,t)=>y(!fe(e),`${t}: path '${e}' escapes the root or holds a '\\'`),pe=(e,t)=>y(typeof e==`string`&&e!==``&&!fe(e),`${t}: invalid entry ${JSON.stringify(e)}`);function me(e,t){y(Array.isArray(e),`${t}: entries must be an array of file paths`);let n=new Set;for(let r of e)pe(r,t),y(!n.has(r),`${t}: entry '${r}' is listed twice`),n.add(r);return n}function he(e,t){for(let n of e)pe(n,t);return C(e)}function ge(e,t){E(e,`formats`),y(s.has(t),`unknown format '${t}' for ${e}`)}function _e(e){y(x(e));let t=new Map;for(let[n,r]of Object.entries(e)){ge(n,r);let e=n===``?`.`:n;y(!t.has(e),`duplicate format key '${e}'`),t.set(e,r)}return t}function ve(e){for(let[t,n]of e)ge(t,n);return w(e)}function ye(e){for(let[,t]of e){y(t instanceof Map);for(let[e,n]of t){E(e,`imports`),y(n instanceof Map);for(let[,e]of n){if(typeof e==`string`){E(e,`imports`);continue}y(e instanceof Map&&e.size>0,`import target must be a file or a non-empty {platform: file} map`);for(let[t,n]of e)y(typeof t==`string`&&t.length>0&&!t.includes(`/`),`invalid platform key '${t}'`),y(typeof n==`string`),E(n,`imports`)}}}}function be(e){y(x(e));let t=de(e);return ye(t),t}function xe(e){return ye(e),w(e)}function Se(e,{skipEmpty:t=!1,repo:n=!0,what:r}={}){let i={modules:[],sources:[]};for(let[a,o]of e){if(t&&Object.keys(o.files).length===0)continue;let e=k(a);e&&y(o.name&&o.version&&o.files);let s=S(Object.entries(o.files).toSorted(b));i[e?`modules`:`sources`].push([a,v({...o,repo:n?ne(a,o,r):void 0,files:s})])}return{modules:S(i.modules.toSorted(b)),sources:S(i.sources.toSorted(b))}}function Ce(e,t){let n=e instanceof Map;if(n!==t instanceof Map)return!1;if(!n)return e===t;if(e.size!==t.size)return!1;for(let[n,r]of e)if(t.get(n)!==r)return!1;return!0}var we=e=>e instanceof Map?`{${[...e].map(([e,t])=>`${e}: ${t}`).join(`, `)}}`:e;function Te(e,t,n){let r=new Map,i=e=>{for(let[t,i]of e){let e=ue(r,t);for(let[t,r]of i){let i=ue(e,t);for(let[e,a]of r)i.has(e)?y(Ce(i.get(e),a),`${n}: import '${e}' from '${t}' resolves differently ('${we(i.get(e))}' vs '${we(a)}')`):i.set(e,a instanceof Map?new Map(a):a)}}};return i(e),i(t),r}function Ee(e,t,n){let r=new Map,i=e=>{for(let[t,i]of e){let e=r.get(t);if(e===void 0){r.set(t,i);continue}try{r.set(t,u(i,e,t))}catch(e){throw Error(`${n}: ${e.message}`,{cause:e})}}};return i(e),i(t),r}function De(e,t,n,r){if(e.size===0)return new Set(t);let i=ie(n,{scope:r}),a=new Set(t);for(let t of e)i.has(t)||a.add(t);return a}var Oe=/(?:^|\/)\.{0,2}(?:\/|$)/u;function D(e,t,n){let r=d(e,t);return(r!==`.`||t!==``)&&Oe.test(r)&&y(!1,`${n}: non-canonical file key ${JSON.stringify(r)}`),r.includes(`\\`)&&y(!1,`${n}: file key '${r}' holds a '\\', which no path may`),r}function O(e,t,n){let r=new Map;for(let[i,{files:a}]of e){typeof i!=`string`&&y(!1,`${t}: bucket dir ${String(i)} is not a string`),E(i,t);for(let e of Object.keys(a)){let a=D(i,e,t),o=r.get(a);o!==void 0&&n(a,o,i),r.set(a,i)}}return r}var ke=(e,t)=>n=>y(!1,`duplicate file key '${n}' across ${e} buckets -- module bucketing changed between writes (a workspace package without a version now owns its own bucket); regenerate the ${t}`);function Ae(e,t,n){let r=new Map,i=e=>{for(let[t,i]of e){let e=r.get(t);if(e===void 0){r.set(t,v({...i,files:Object.assign(Object.create(null),i.files)}));continue}y(e.name===i.name,`${n}: module '${t}' name mismatch ('${e.name}' vs '${i.name}')`),y(e.version===i.version,`${n}: module '${t}' version mismatch ('${e.version}' vs '${i.version}')`+(e.version==null==(i.version==null)?``:` -- an artifact from an older stasis may record a placeholder version for a workspace package without one; regenerate it (bundle=replace / lock=replace)`)),y(e.ecosystem===i.ecosystem,`${n}: module '${t}' ecosystem mismatch ('${e.ecosystem??`(none)`}' vs '${i.ecosystem??`(none)`}')`),e.repo===void 0&&i.repo!==void 0&&r.set(t,v({...e,repo:i.repo}));for(let[r,a]of Object.entries(i.files))Object.hasOwn(e.files,r)?y(e.files[r]===a,`${n}: content mismatch for '${d(t,r)}'`):e.files[r]=a}};return i(e),i(t),O(r,n,(e,t,r)=>y(!1,`${n}: file '${e}' is bucketed under both '${t}' and '${r}' -- module bucketing changed between the artifacts (a workspace package without a version now owns its own bucket); regenerate the artifact (bundle=replace / lock=replace)`)),r}function k(e){return e.split(`/`).includes(`node_modules`)}function je(e){let t=e.length;for(;(t=e.lastIndexOf(`node_modules/`,t-1))!==-1;)if(t===0||e[t-1]===`/`)return t;return-1}function Me(e){let t=je(e);if(t===-1)return null;let n=t+13,r=e.slice(n).split(`/`),i=r[0].startsWith(`@`)?2:1;if(r.length<=i||r.slice(0,i).some(e=>!e))return null;let a=r.slice(0,i).join(`/`);return{dir:e.slice(0,n)+a,rel:r.slice(i).join(`/`),name:a}}var A=1,Ne=0,Pe=ke(`bundle`,`artifact (bundle=replace)`),Fe=e=>Me(e)??{dir:`.`,rel:e===`.`?``:e,name:null};function Ie(){throw Error(`bundle: file contents are not retained by this contents-free Bundle`)}var Le=(e,{files:t,...n})=>{let r=Object.create(null);for(let[n,i]of Object.entries(t))typeof i!=`symbol`&&y(!1,`bundle: file '${d(e,n)}' is not a placeholder`),Object.defineProperty(r,n,{get:Ie,enumerable:!0});return{...n,files:Object.freeze(r)}},j=(e,t)=>{if(e===void 0&&t===void 0)return;let n=new Map;for(let r of[e,t])for(let[e,t]of Object.entries(r??{})){if(!Array.isArray(t))continue;let r=n.get(e);r===void 0&&n.set(e,r=new Set);for(let e of t)r.add(e)}return S([...n.keys()].toSorted().map(e=>[e,C(n.get(e))]))},Re=(e,t)=>Object.hasOwn(h,e)&&h[e](t),ze=(e,t)=>e?.github===void 0||!ee(e.github,t?.github)?void 0:S(Object.keys(h).filter(n=>e[n]!==void 0&&(n===`github`||e[n]===t[n])).map(t=>[t,e[t]])),Be=e=>{if(!x(e)||e.root!==!0||Object.hasOwn(e,`directory`))return e;let{root:t,...n}=e;return n},Ve=e=>typeof e==`string`&&/^[\w.+@/~'!()*-]+$/u.test(e),M={name:Ve,version:Ve},He={npm:M,composer:M,cargo:M},Ue=(e,t)=>S(Object.keys(He).map(n=>{let[r,i]=[e?.[n],t?.[n]];return[n,r?.name!==void 0&&r.name===i?.name?S(Object.entries(r).filter(([e,t])=>t===i[e])):void 0]})),N=class e{static VERSION=A;version=A;config;entries;modules;formats;imports;executable;reason;#e;get repo(){return this.#e}set repo(e){this.#e=_(e)}#t;get package(){return this.#t}set package(e){this.#t=g(e,He,`bundle package`)}constructor({config:e={scope:`full`},entries:t,modules:n,formats:r,imports:i,executable:a,reason:o,repo:s,package:c,version:l=A}={}){y([Ne,A].includes(l)),y([`node_modules`,`full`].includes(e.scope)),this.version=l,this.config=e,this.entries=t??new Set,this.modules=n??new Map,this.formats=r??new Map,this.imports=i??new Map,this.executable=a??new Set,this.reason=o,this.repo=_(s),this.package=c}get sources(){let e=new Map;for(let[t,{files:n}]of this.modules)for(let[r,i]of Object.entries(n))e.set(d(t,r),i);return e}static isResourceFormat(e){return e===`resource`||e===`resource:base64`||e===`directory`}get hasCode(){for(let[t,{files:n}]of this.modules)for(let r of Object.keys(n))if(!e.isResourceFormat(this.formats.get(d(t,r))))return!0;return!1}static parse(t){return e.fromJSON(JSON.parse(t))}static fileKeyAt(e){let[t,n,r,i]=e;if(typeof n==`string`){if(e.length===2&&t===`sources`){let e=Fe(n);return D(e.dir,e.rel,`bundle`)}if(e.length===4&&(t===`sources`||t===`modules`)&&r===`files`&&typeof i==`string`)return D(n,i,`bundle`)}}static fromJSON(t,{contents:n=!0}={}){y(t.version===A||t.version===Ne),y([`node_modules`,`full`].includes(t.config?.scope));let r=_e(t.formats),i=new Map,a=new Set;if(t.version===A){let e=t.config.scope===`full`;if(t.modules!==void 0){y(typeof t.modules==`object`&&t.modules!==null);for(let[e,n]of Object.entries(t.modules))y(k(e)),E(e,`bundle`),y(n?.name&&n.version&&n.files),i.set(e,re(n,e,`bundle`))}if(e){y(t.sources&&typeof t.sources==`object`);for(let[e,n]of Object.entries(t.sources))y(!k(e)),E(e,`bundle`),y(n?.name&&n.files),i.set(e,re(n,e,`bundle`));t.entries!==void 0&&(a=me(t.entries,`bundle`))}else y(t.entries===void 0),y(t.sources===void 0)}else{y(t.sources);for(let[e,n]of Object.entries(t.sources)){E(e,`bundle`);let{dir:t,rel:r,name:a}=Fe(e);y(!T(t)&&!T(r)),i.has(t)||i.set(t,{name:a,version:null,files:Object.create(null)});let{files:o}=i.get(t);y(!Object.hasOwn(o,r),`bundle: duplicate file key '.' (v0 '' and '.')`),o[r]=n}}let o=O(i,`bundle`,Pe),s=be(t.imports);if(!n)for(let[e,t]of i)i.set(e,Le(e,t));return new e({version:t.version,config:t.config,entries:a,modules:i,formats:r,imports:s,executable:t.version===A?se(t.executable,{what:`bundle`,files:o,formats:r,scope:t.config.scope}):new Set,reason:x(t.reason)?t.reason:void 0,repo:Be(t.repo),package:t.package})}serialize(){O(this.modules,`bundle`,Pe);let{modules:e,sources:t}=Se(this.modules,{skipEmpty:!0,what:`bundle`}),n=this.config.scope===`full`,r={version:A,config:this.config};this.repo!==void 0&&(r.repo=this.repo),this.package!==void 0&&(r.package=this.package),n&&(r.entries=he(this.entries,`bundle`)),r.formats=ve(this.formats),r.imports=xe(this.imports);let i=ce(this.executable,{what:`bundle`,modules:this.modules,formats:this.formats,scope:this.config.scope});return i!==void 0&&(r.executable=i),this.reason!==void 0&&(r.reason=j(this.reason,void 0)),n&&(r.sources=t),r.modules=e,JSON.stringify(r,void 0,2)}withReason(t){let{version:n,config:r,entries:i,modules:a,formats:o,imports:s,executable:c,repo:l,package:u}=this,d=j(this.reason,{[t]:[...this.sources.keys()]});return new e({version:n,config:r,entries:i,modules:a,formats:o,imports:s,executable:c,reason:d,repo:l,package:u})}merge(t){return y(this.config.scope===t.config.scope,`bundle merge: scope mismatch ('${this.config.scope}' vs '${t.config.scope}')`),new e({config:{scope:this.config.scope},entries:new Set([...this.entries,...t.entries]),modules:Ae(this.modules,t.modules,`bundle merge`),formats:Ee(this.formats,t.formats,`bundle merge`),imports:Te(this.imports,t.imports,`bundle merge`),executable:De(this.executable,t.executable,t.modules,this.config.scope),reason:j(this.reason,t.reason),repo:ze(this.repo,t.repo),package:Ue(this.package,t.package)})}},We={__proto__:null,js:`javascript`,mjs:`javascript`,cjs:`javascript`,jsx:`jsx`,ts:`typescript`,mts:`typescript`,cts:`typescript`,tsx:`tsx`,json:`json`,css:`css`,html:`markup`,htm:`markup`,xml:`markup`,svg:`markup`,yml:`yaml`,yaml:`yaml`,sh:`bash`,bash:`bash`,md:`markdown`,markdown:`markdown`,sol:`solidity`,php:`php`,phtml:`php`,rs:`rust`,rb:`ruby`,py:`python`,pyw:`python`,pyi:`python`,java:`java`,cpp:`cpp`,cc:`cpp`,cxx:`cpp`,"c++":`cpp`,hpp:`cpp`,hh:`cpp`,hxx:`cpp`,"h++":`cpp`,h:`cpp`,c:`c`,m:`objectivec`,mm:`objectivec`},Ge={__proto__:null,module:`javascript`,commonjs:`javascript`,"module-typescript":`typescript`,"commonjs-typescript":`typescript`,json:`json`,solidity:`solidity`,php:`php`,shell:`bash`,rust:`rust`,java:`java`,objc:`objectivec`,objcpp:`objectivec`,c:`c`,"c-header":`c`,cpp:`cpp`,"cpp-header":`cpp`,ruby:`ruby`,podspec:`ruby`,podfile:`ruby`,fastlane:`ruby`,"podfile-lock":`yaml`,xml:`markup`};function Ke(e){if(typeof e!=`string`)return!1;let t=e.length-1,n=0;for(;n<t&&/\s/u.test(e[n]);)n++;for(;t>n&&/\s/u.test(e[t]);)t--;return n<t&&e[n]===`{`&&e[t]===`}`}function qe(e,t,n){if(typeof t==`string`&&Ge[t])return Ge[t];if(typeof e!=`string`)return null;let r=e.slice(e.lastIndexOf(`/`)+1),i=r.lastIndexOf(`.`);if(i<=0)return null;let a=r.slice(i+1).toLowerCase();return a===`map`?Ke(n)?`json`:null:We[a]??null}var Je=/^webpack(?:-internal)?:\/\/[^/]*\//u,Ye=/^[a-z][\d+.a-z-]*:/iu,Xe=/^file:/iu,Ze=/^(?:file|ftp|https?|wss?):/iu,Qe=/^(?:[a-z][\d+.a-z-]*:\/\/[^/]*\/?|\/\/[^/]+\/|[a-z]:\/|\/)?/iu,P=e=>Qe.exec(e)[0],F=e=>P(e).includes(`://`),I=e=>e.replace(F(e)?/[#?].*$/su:/\?.*$/su,``),$e=e=>e.slice(e.lastIndexOf(`/`)+1),L=(e,t)=>URL.parse(e,t)?.href??null;function R(e){let t=P(e),n=t.includes(`://`)&&L(e);if(n)return n;let r=[];for(let n of e.slice(t.length).split(`/`))n===``||n===`.`||(n===`..`?r.length>0&&r.at(-1)!==`..`?r.pop():t||r.push(`..`):r.push(n));let i=/^[a-z]:\/$/iu.test(t)?t.toUpperCase():t.startsWith(`//`)?t.toLowerCase():t;return i?i.replace(/\/?$/u,`/`)+r.join(`/`):r.join(`/`)||`.`}function et(e,t){let n=P(t);return F(e)&&!n.includes(`:`)?L(t,e)??R(`${e}/../${t}`):R(n===`/`?P(e).replace(/\/?$/u,``)+t:n?t:`${e}/../${t}`)}function tt(e){try{return decodeURIComponent(e)}catch{return e}}function z(e,t){let n=e.replaceAll(`\\`,`/`);if(Je.test(n))return R(n.replace(Je,``));let r=Ze.test(n)?L(n)??n:n,i=/^file:\/\/([^/#]*)([^#]*)/isu.exec(r);if(i){let[,e,t]=i;return R(tt(e&&e.toLowerCase()!==`localhost`?`//${e}${t}`:t).replace(/^\/(?=[a-z]:\/)/iu,``))}if(Ye.test(r)&&!P(r).includes(`:`))return r;if(t===void 0)return R(r);if(Xe.test(t)&&!P(r))return z(L(r,t)??r);let a=z(t);return P(r)&&!F(a)?R(r):et(a,r)}var nt=/^(?:@[\dA-Za-z~-][\w.~-]*\/)?[\dA-Za-z~-][\w.~-]*$/u;function B(e){let t=e.split(`/`).slice(0,e.startsWith(`@`)?2:1).join(`/`);return nt.test(t)?t:null}var rt=new Set([`.pnpm`,`.bun`,`.deno`]),it=/^\d+\.\d+\.\d+(?:-[\d.a-z-]+)?(?:\+[\d.a-z-]+)?$/iu;function at(e,t){let n=`${t.replace(`/`,`+`)}@`,r=e.startsWith(n)?e.slice(n.length).split(/[(_]/u)[0]:null;return it.test(r)?r:null}function ot(e){let t=I(e).split(`/`),n=t.lastIndexOf(`node_modules`),r=n<0?null:B(t.slice(n+1).join(`/`));if(r===null)return null;let i=n+1+r.split(`/`).length;if(i>=t.length||t.slice(i).includes(``))return null;let a=t.slice(0,i).join(`/`);return{name:r,version:rt.has(t[n-2])?at(t[n-1],r):null,root:a,path:e.slice(a.length+1)}}var st=new Map([[`js`,`jsx`],[`mjs`,`jsx`],[`cjs`,`jsx`],[`jsx`,`jsx`],[`es`,`jsx`],[`es6`,`jsx`],[`ts`,`ts`],[`mts`,`ts`],[`cts`,`ts`],[`tsx`,`tsx`],[`json`,`json`]]);function ct(e){let t=$e(I(e));return/^[\w-]+$/u.test(t)?`jsx`:st.get(/\.([\da-z]+)$/iu.exec(t)?.[1].toLowerCase())??null}var lt=[`.js`,`.mjs`,`.cjs`,`.jsx`,`.ts`,`.tsx`,`.mts`,`.cts`,`.json`],ut=[`.ios`,`.android`,`.web`];function dt(e){let t=e.map(e=>/\.[a-z]+(?=\.\w+$)/u.exec($e(I(e.path??``)))?.[0]),[[n,r],[,i]]=ut.map(e=>[e,t.filter(t=>t===e).length]).toSorted((e,t)=>t[1]-e[1]);return[...r===i?[]:[n],`.native`,``,`.browser`,`.node`]}var ft=new Map([[`.js`,[`.ts`,`.tsx`]],[`.jsx`,[`.tsx`]],[`.mjs`,[`.mts`]],[`.cjs`,[`.cts`]]]),pt=[`index`,`main`,`browser`,`node`],mt=[``,`src/`,`lib/`,`dist/`,`build/`],ht=new Set([`lib`,`dist`,`build`,`out`,`esm`,`cjs`]);function*gt(e,t){yield e;let n=/\.[^./]+$/u.exec(e)?.[0];for(let t of ft.get(n)??[])yield e.slice(0,-n.length)+t;for(let n of e.endsWith(`/`)?[`${e}index`]:[e,`${e}/index`])for(let e of lt)for(let r of t)yield n+r+e;if(n)for(let r of t.filter(Boolean))yield e.slice(0,-n.length)+r+n}function*_t(e){let t=e;for(;;){t.startsWith(`src/`)||(yield`src/${t}`),t!==e&&(yield t);let n=t.indexOf(`/`);if(n<0||!ht.has(t.slice(0,n)))return;t=t.slice(n+1)}}function vt(e){let t=new Map,n=new Map,r=new Map;for(let i of e)i.path!==null&&t.set(i.path,i),i.package&&(n.set(i.package.name,(n.get(i.package.name)??new Set).add(i.package.root)),(r.get(i.package.root)??r.set(i.package.root,[]).get(i.package.root)).push(i));return{byPath:t,roots:n,byRoot:r,platforms:dt(e),found:new Map}}function V(e,t){if(!e.found.has(t)){let n=I(t),r=gt(n,e.platforms).map(e=>e+t.slice(n.length));e.found.set(t,e.byPath.get(r.find(t=>e.byPath.has(t)))??null)}return e.found.get(t)}function yt(e,t,n){let r=e.roots.get(n);if(!r)return null;let i=t.path.split(`/`);for(let e=i.length-1;e>=0;e--){let t=[...i.slice(0,e),`node_modules`,n].join(`/`);if(r.has(t))return t}return r.size===1?[...r][0]:null}var bt=new Set(`assert.async_hooks.buffer.child_process.cluster.console.constants.crypto.dgram.diagnostics_channel.dns.domain.events.fs.http.http2.https.inspector.module.net.os.path.perf_hooks.process.punycode.querystring.readline.repl.stream.string_decoder.sys.timers.tls.trace_events.tty.url.util.v8.vm.wasi.worker_threads.zlib._http_agent._http_client._http_common._http_incoming._http_outgoing._http_server._stream_duplex._stream_passthrough._stream_readable._stream_transform._stream_wrap._stream_writable._tls_common._tls_wrap.assert/strict.dns/promises.fs/promises.inspector/promises.path/posix.path/win32.readline/promises.stream/consumers.stream/promises.stream/web.timers/promises.util/types`.split(`.`));function xt(e){if(e.startsWith(`node:`)||bt.has(e))return{builtin:!0};let t=B(I(e));return t===null?{}:{package:t}}function St(){let e=[],t=new Map,n=(n,r,i)=>{let a=t.get(n)??t.set(n,new Set).get(n);a.has(r)||(a.add(r),e.push(i))};return{edges:e,add:n,link:(e,t,r)=>{e&&t&&t!==e&&n(e,t,{from:e,to:t,kind:r})}}}function Ct(e,t){for(let n of pt)for(let r of mt){let i=V(e,`${t}/${r}${n}`);if(i)return i}let n=e.byRoot.get(t);return n?.length===1?n[0]:null}function wt(e,t,n,r){return/^\/[^?]/u.test(n)?V(e,t+n)??_t(n.slice(1)).map(n=>V(e,`${t}/${n}`)).find(Boolean):V(e,t+n)??r(e,t)}function Tt(e,t,n,r=Ct){let i=/^(?:\.{1,2}|[a-z]:)?\\/iu.test(n)?n.replaceAll(`\\`,`/`):n,a=Ze.test(i);if(a||/^(?:\.{1,2}(?:\/|$)|\/|[a-z]:\/)/iu.test(i)||F(i)){let n=a?z(i):et(t.path,i),r=V(e,n);return r?{to:r}:{to:null,path:n}}if(Ye.test(i)&&e.byPath.has(i))return{to:e.byPath.get(i)};let o=B(I(n)),s=o===null?null:yt(e,t,o);if(s===null)return{to:null,...xt(n)};let c=wt(e,s,n.slice(o.length),r);return c?{to:c}:{to:null,package:o}}var H=class extends Error{name=`SourceMapError`},Et=new Uint8Array(128).fill(255);for(let[e,t]of[...`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/,;`].entries())Et[t.codePointAt(0)]=e;function U(e){let t=new Int32Array(e.length*2);return t.set(e),t}function Dt(e){let{starts:t,columns:n,sources:r,names:i}=e;for(let e=0;e+1<t.length;e++){let[a,o]=[t[e],t[e+1]],s=a+1;for(;s<o&&n[s-1]<=n[s];)s++;if(s>=o)continue;let c=Array.from(n.subarray(a,o),(e,t)=>[e,r[a+t],i[a+t]]).sort((e,t)=>e[0]-t[0]);for(let[e,[t,o,s]]of c.entries())[n[a+e],r[a+e],i[a+e]]=[t,o,s]}return e}function Ot(e){let t=[0],n=new Int32Array(1024),r=new Int32Array(1024),i=new Int32Array(1024),a=0;for(let{mappings:o,files:s,line:c,column:l,names:u,nameCount:d}of e){if(typeof o!=`string`)throw new H(`mappings is not a string`);for(;t.length<=c;)t.push(a);let e=[0,0,0,0,0],f=0,p=0,m=1,h=l;for(let c=0;c<=o.length;c++){let l=c<o.length?Et[o.codePointAt(c)]??255:64;if(l<32){if(p+=l*m,f===5)throw new H(`mappings: a segment of more than 5 fields at ${c}`);e[f++]+=p%2?(1-p)/2:p/2,p=0,m=1;continue}if(l<64){if(p+=(l-32)*m,m*=32,m>2**30)throw new H(`mappings: a value at ${c} runs past 32 bits`);continue}if(l===255)throw new H(`mappings: ${JSON.stringify(o[c])} at ${c} is not a base64 digit`);if(m!==1)throw new H(`mappings: the value before ${c} is cut off`);if(f>0){if(f===2||f===3)throw new H(`mappings: a segment of ${f} fields before ${c}`);let t=f===1?-1:s[e[1]];if(t===void 0)throw new H(`mappings: source ${e[1]} before ${c} is not in sources`);if(e[0]<0)throw new H(`mappings: a negative generated column before ${c}`);a===n.length&&([n,r,i]=[U(n),U(r),U(i)]),n[a]=e[0]+h,r[a]=t,i[a++]=f===5&&e[4]>=0&&e[4]<d?u+e[4]:-1,f=0}l===65&&(t.push(a),e[0]=0,h=0)}}return t.push(a),Dt({starts:Int32Array.from(t),columns:n.slice(0,a),sources:r.slice(0,a),names:i.slice(0,a)})}var kt=new WeakMap,At=e=>kt.get(e),W=e=>typeof e==`object`&&!!e&&!Array.isArray(e);function G(e,t){if(!e)throw new H(t)}function jt(e,t){if(e===void 0)return[];G(Array.isArray(e),`${t} is not an array`);for(let n of e)G(typeof n==`string`||n===null,`${t} holds ${JSON.stringify(n)}`);return e}function Mt(e,t,n,r){let i=e.bySource.get(t);if(i!==void 0)return e.files[i].content??=n,e.files[i].ignored||=r,i;let a=t===null?null:z(t,e.mapPath);return e.files.push({source:t,path:a,package:a===null?null:ot(a),content:n,ignored:r}),t!==null&&e.bySource.set(t,e.files.length-1),e.files.length-1}function Nt(e,t,n,r){G(e.version===3,`version ${JSON.stringify(e.version)} is not 3`),G(e.sourceRoot===void 0||typeof e.sourceRoot==`string`,`sourceRoot is not a string`);let i=jt(e.sources,`sources`),a=jt(e.sourcesContent,`sourcesContent`),o=e.ignoreList??e.x_google_ignoreList??[];G(Array.isArray(o)&&o.every(e=>Number.isInteger(e)&&e>=0&&e<i.length),`ignoreList is not a list of indices into sources`);let s=new Set(o),c=e.sourceRoot?e.sourceRoot.replace(/\/?$/u,`/`):``,l=i.map((e,n)=>Mt(t,e===null?null:c+e,a[n]??null,s.has(n))),u=Array.isArray(e.names)?e.names:[];t.parts.push({mappings:e.mappings,files:l,line:n,column:r,names:t.names.length,nameCount:u.length}),t.names.push(...u)}function Pt(e,t){G(e.version===3,`version ${JSON.stringify(e.version)} is not 3`),G(Array.isArray(e.sections),`sections is not an array`);for(let[n,r]of e.sections.entries()){let{offset:i,map:a}=W(r)?r:{};G(W(i)&&[i.line,i.column].every(e=>Number.isInteger(e)&&e>=0),`sections[${n}].offset is not a line and a column`),G(W(a)&&a.sections===void 0,`sections[${n}].map is not a plain source map`);let o=e.sections[n-1]?.offset;G(!o||o.line<i.line||o.line===i.line&&o.column<=i.column,`sections[${n}] starts before sections[${n-1}]`),Nt(a,t,i.line,i.column)}}function Ft(e,t={}){if(!W(t))throw TypeError(`readSourceMap: options is not an object`);if(t.path!==void 0&&typeof t.path!=`string`)throw TypeError(`readSourceMap: options.path is not a string`);let n=e;if(typeof e==`string`||e instanceof Uint8Array)try{let t=typeof e==`string`?e:new TextDecoder(`utf-8`,{fatal:!0}).decode(e);n=JSON.parse(t.replace(/^\)\]\}'[^\n]*\n/u,``))}catch(e){throw new H(`not JSON: ${e.message}`,{cause:e})}G(W(n),`not a JSON object`);let r={files:[],bySource:new Map,mapPath:t.path,parts:[],names:[]};n.sections===void 0?Nt(n,r,0,0):Pt(n,r);let i={files:r.files};return kt.set(i,{...Ot(r.parts),nameList:r.names}),i}var It=/\r\n?|[\n\u2028\u2029]/gu;function Lt(e){let t=[0];for(let n of e.matchAll(It))t.push(n.index+n[0].length);return t}function Rt(e,t,n,r){let[i,a]=[t,n];for(;i<a;){let t=i+a>>1;e[t]<=r?i=t+1:a=t}return i-1}function K(e,t){let n=Rt(e,0,e.length,t);return[n,t-e[n]]}function zt(e,[t,n]){if(t>=e.starts.length-1)return-1;let r=e.starts[t],i=Rt(e.columns,r,e.starts[t+1],n);return i<r?-1:i}function Bt(e,t,n,r){let i=At(e),a=K(t,n),[o,s]=K(t,r),c=new Map,l=zt(i,a);for(let e=a[0];e<=o&&e<i.starts.length-1;e++){let t=e===a[0]&&l>=0?l:i.starts[e];for(let n=t;n<i.starts[e+1];n++){let t=i.sources[n];if(e===o&&i.columns[n]>=s)break;t>=0&&c.set(t,(c.get(t)??0)+1)}}let[u]=[...c].reduce((e,t)=>t[1]>e[1]?t:e,[-1,0]);return u<0?null:e.files[u]}var q=/\s+/uy,Vt=`
2
- \r\u2028\u2029`,Ht=/[\n\r\u2028\u2029]/gu,Ut=/[\n\r\u2028\u2029]/u,J=/[\w$\u0080-￿]+/uy,Wt=new Set([`return`,`typeof`,`instanceof`,`in`,`of`,`new`,`delete`,`void`,`throw`,`case`,`default`,`extends`,`do`,`else`,`yield`,`await`]),Gt=new Set([`if`,`while`,`for`,`with`]),Kt=new Set([`break`,`continue`,`debugger`]),qt=new Set([`(`,`[`,"${",`,`,`=`,`:`,`?`,`!`,`~`,`+`,`-`,`*`,`/`,`%`,`&`,`|`,`^`,`<`,`>`]);function Jt(e,t){return e?.type===`word`?t&&[`return`,`yield`].includes(e.value)?!1:Wt.has(e.value)&&![`do`,`else`].includes(e.value):qt.has(e?.value)}function Yt(e){let t=e.at(-1);return t?.type===`word`&&(Gt.has(t.value)||t.value===`await`&&e.at(-2)?.value===`for`)}function Xt(e){return e?e.type===`word`?Wt.has(e.value)||Kt.has(e.value)||e.label===!0:e.value===`)`?e.control:e.value===`}`?!e.object:e.type===`punctuator`&&![`++`,`--`,`]`].includes(e.value):!0}var Zt=(e,t)=>e.startsWith(`\r
3
- `,t+1)?3:2,Qt=/\\(?:u\{([\da-f]+)\}|u([\da-f]{4})|x([\da-f]{2})|([0-3][0-7]{0,2}|[4-7][0-7]?)|(\r\n|[\n\r\u2028\u2029])|(.))/giu,$t={b:`\b`,f:`\f`,n:`
4
- `,r:`\r`,t:` `,v:`\v`};function en(e){return e.includes(`\\`)?e.replace(Qt,(e,t,n,r,i,a,o)=>{if(a!==void 0)return``;if(i!==void 0)return String.fromCodePoint(Number.parseInt(i,8));let s=Number.parseInt(t??n??r,16);return Number.isNaN(s)?$t[o]??o:String.fromCodePoint(Math.min(s,1114111))}):e}function tn(e,t){let n=e[t],r=t+1;for(;r<e.length&&e[r]!==n&&!Vt.includes(e[r]);)r+=e[r]===`\\`?Zt(e,r):1;return[e[r]===n?en(e.slice(t+1,r)):null,r+1]}function nn(e,t){let n=t+1,r=!1;for(;n<e.length&&!Vt.includes(e[n])&&(r||e[n]!==`/`);)e[n]===`\\`?n++:e[n]===`[`?r=!0:e[n]===`]`&&(r=!1),n++;return J.lastIndex=n+1,J.test(e)?J.lastIndex:n+1}function rn(e,t,n){for(let r=t;r<e.length;r++)if(e[r]===`\\`)r++;else{if(e[r]==="`")return r+1;if(e[r]===`$`&&e[r+1]===`{`)return n.push(`template`),r+2}return e.length}function an(e){let t=[],n=[],r=[],i=0,a=0;for(;i<e.length;){let o=t.length;if(q.lastIndex=i,q.test(e)&&(i=q.lastIndex),i>=e.length)break;let s=e[i],c=e[i+1];if(J.lastIndex=i,s===`/`&&c===`/`)Ht.lastIndex=i+2,i=Ht.test(e)?Ht.lastIndex-1:e.length;else if(s===`/`&&c===`*`){let t=e.indexOf(`*/`,i+2);i=t<0?e.length:t+2}else if(s===`"`||s===`'`){let[n,r]=tn(e,i);t.push({type:`string`,value:n}),i=r}else if(s==="`"||s===`}`&&n.at(-1)===`template`){s===`}`&&n.pop();let r=n.length,a=rn(e,i+1,n),o=s==="`"&&n.length===r&&e[a-1]==="`";t.push({type:`string`,value:o?en(e.slice(i+1,a-1)):null}),n.length>r&&t.push({type:`punctuator`,value:"${"}),i=a}else if(s===`/`&&Xt(t.at(-1)))i=nn(e,i),t.push({type:`regex`});else if(J.test(e)){let n=Kt.has(t.at(-1)?.value)&&!Ut.test(e.slice(a,i));t.push({type:`word`,value:e.slice(i,J.lastIndex),...n&&{label:n}}),i=J.lastIndex}else{s===`{`&&n.push(Jt(t.at(-1),Ut.test(e.slice(a,i)))?`object`:`block`);let o=s===`}`?n.pop():void 0;s===`(`&&r.push(Yt(t));let l=(s===`+`||s===`-`)&&c===s||s===`=`&&c===`>`?s+c:s;t.push({type:`punctuator`,value:l,...s===`)`&&{control:r.pop()===!0},...s===`}`&&{object:o===`object`}}),i+=l.length}t.length>o&&(a=i)}return t}var on=e=>e?.type===`string`&&e.value!==null,sn=new Set([`type`,`typeof`]),cn=(e,t)=>e[t+1]?.type===`word`&&(e[t+1].value!==`as`||e[t+2]?.type!==`word`||e[t+2].value===`as`);function ln(e,t){let n=!1;for(let r=t+1;r<e.length&&e[r].value!==`}`;r++)if(!(r>t+1&&e[r-1].value!==`,`)){if(!sn.has(e[r].value)||!cn(e,r))return!1;n=!0}return n}function un(e,t){for(let n=t;n<e.length;n++){let{value:r}=e[n];if(r===`;`||n>t&&(r===`import`||r===`export`))return null;if(r===`from`&&on(e[n+1]))return e[n+1].value}return null}function dn(e,t){let[n,r,i]=[e[t].value,e[t+1],e[t+2]],a=n===`import`?`import`:`export-from`;if(n===`import`&&on(r))return{kind:a,specifier:r.value};if(sn.has(r?.value)&&![`,`,`from`].includes(i?.value)||r?.value===`{`&&ln(e,t+1)||n===`export`&&![`{`,`*`].includes(r?.value)||n===`import`&&r?.type!==`word`&&![`{`,`*`].includes(r?.value))return null;let o=un(e,t+1);return o===null?null:{kind:a,specifier:o}}function fn(e,t){let[n,r]=[e[t+2],e[t+3]];if(n?.value!==`)`)return on(n)&&[`)`,`,`].includes(r?.value)?n.value:null}function pn(e,t=new Set){let n=an(e),r=[];for(let[e,i]of n.entries()){if(i.type!==`word`||[`.`,`#`,`function`].includes(n[e-1]?.value)||n[e-1]?.value===`=`&&n[e-3]?.value===`type`&&n[e-4]?.value===`import`)continue;let a=n[e+1]?.value===`(`,o=a?fn(n,e):void 0;if((i.value===`require`||t.has(i.value))&&o!==void 0)r.push({kind:`require`,specifier:o,...i.value!==`require`&&{callee:i.value}});else if(i.value===`import`&&a)o!==void 0&&r.push({kind:`dynamic-import`,specifier:o});else if(i.value===`import`||i.value===`export`){let t=dn(n,e);t&&r.push(t)}}return r}var mn=/^[\w$]*__d\(/gmu,hn=([e,t,n,...r])=>(typeof e==`number`||typeof e==`string`)&&(t===void 0||typeof t==`object`)&&(n===void 0||typeof n==`string`)&&r.length===0;function gn(e){let t=/\);?\s*$/u.exec(e)?.index,n=null,r=t===void 0?-1:e.lastIndexOf(`},`,t);for(;r>=0&&/[\d"]/u.test(e[r+2]);){let i;try{i=JSON.parse(`[${e.slice(r+2,t)}]`)}catch{break}if(!hn(i))break;n=i,r=r>0?e.lastIndexOf(`},`,r-1):-1}return n}function _n(e){let t=/^[^(]*\(\s*(?:function\s*[\w$]*\s*)?\(([^)]*)\)/u.exec(e)?.[1].split(`,`).slice(1,4).map(e=>e.trim().replaceAll(`$`,`\\$`));if(!t?.length)return[];let n=e.matchAll(RegExp(`(?<=[^\\w$.#]|\\.\\.\\.)(?:${t.join(`|`)})\\((\\d+|"(?:[^"\\\\]|\\\\.)*")[,)]`,`gu`));return[...new Set([...n].map(e=>JSON.parse(e[1])))]}function vn(e,t){if(Array.isArray(e))return e;let n=Object.entries(e??{}).filter(([e])=>/^\d+$/u.test(e)).map(([,e])=>e);return n.length>0?n:_n(t)}function yn(e,t){let n=new Map(t.files.map((e,t)=>[e,t])),r=e.flatMap((e,t)=>e.file?[{k:t,at:n.get(e.file)}]:[]);for(let n=0;n<(r[0]?.k??0);n++)e[n].file=t.files[r[0].at-r[0].k+n]??null;for(let[n,{k:i,at:a}]of r.entries()){let o=r[n+1];if(!(o&&o.at-a!==o.k-i))for(let n=i+1;n<(o?.k??e.length);n++)e[n].file=t.files[a+n-i]??null}}function bn(e,t){let n=[...e.matchAll(mn)].map(e=>e.index);if(n.length===0)return null;let r=Lt(e),i=t=>e.slice(r[t],r[t+1]),a=[];for(let[o,s]of n.entries()){let[c]=K(r,s),[l]=K(r,(n[o+1]??e.length)-1),u=gn(i(l));for(;!u&&l>c;)u=gn(i(--l));if(!u)throw Error(`bundleEdges: the Metro module at line ${c+1} ends in no define params`);let d=r[l+1]??e.length;a.push({id:u[0],file:Bt(t,r,s,d),dependencies:vn(u[1],e.slice(s,d))})}yn(a,t);let o=new Map(a.map(e=>[e.id,e])),{edges:s,link:c}=St();for(let{file:e,dependencies:t}of a)for(let n of t)c(e,o.get(n)?.file,`dependency`);return s}var xn=e=>e.path!==null&&![`json`,null].includes(ct(e.path)),Sn=e=>e.path!==null&&ct(e.path)===null;function Cn(e){let t=/^_([A-Za-z]+)\d+$/u.exec(e)?.[1];if(t)return[t,`interopRequireDefault`];let n=/^_(interopRequire(?:Default|Wildcard)|jsx(?:Dev)?Runtime|callSuper)$/u.exec(e)?.[1];return n===`callSuper`?[`getPrototypeOf`,`possibleConstructorReturn`,`interopRequireDefault`]:n?[n]:[]}var wn={jsxRuntime:`react/jsx-runtime`,jsxDevRuntime:`react/jsx-dev-runtime`};function Tn(e){let{sources:t,names:n,nameList:r}=At(e),i=new Map,a=new Map,o=e.files.map(()=>new Set);for(let e=0;e<n.length;e++)n[e]<0||t[e]<0||(a.has(n[e])||a.set(n[e],Cn(r[n[e]]).length>0),a.get(n[e])&&o[t[e]].add(r[n[e]]));for(let[t,n]of o.entries()){if(n.size===0)continue;let r=e.files[t],a=new Set(Array.from((r.content??``).matchAll(/(?:function|var|let|const)\s+(_[A-Za-z]+\d*)\b/gu),e=>e[1])),o=[...n].filter(e=>!a.has(e)&&!a.has(e.replace(/\d+$/u,``))).flatMap(Cn);o.length>0&&i.set(r,o.map(e=>wn[e]??`@babel/runtime/helpers/${e}`))}return i}function En(e,t){let n=new Map;for(let[r,i]of e){let e=n.get(r)??n.set(r,new Map).get(r);for(let n of i)e.set(n,Tt(t,r,n,()=>null))}let r=new Set([...n.values()].flatMap(e=>[...e.values()].map(e=>e.to))),i=(e,n)=>t.byRoot.get(n).find(e=>!r.has(e))??t.byRoot.get(n)[0];return(e,r)=>{let a=n.get(e)?.get(r);return a?.to?a:Tt(t,e,r,i)}}var Dn=e=>/(?:^|\/)__prelude__$/u.test(e.source??``),On=e=>e?.package?.name===`metro-runtime`&&e.package.path===`src/polyfills/require.js`;function kn(e){if(!e.files.some(Dn)&&!On(e.files[0]))return null;if(!e.files.some(e=>e.content!==null&&!Dn(e)&&!On(e)))throw Error("bundleEdges: the Metro map carries no sourcesContent, which its edges are read from; pass the bundle as `code`");let t=vt(e.files),n=e.files[e.files.findIndex(Sn)+1],r=e.files.find(e=>e.package?.name===`metro-runtime`&&e.package.path===`src/modules/asyncRequire.js`),i=new Map(e.files.filter(e=>e.content!==null&&xn(e)).map(e=>[e,pn(e.content)])),a=Tn(e),o=En([...[...i].map(([e,t])=>[e,t.flatMap(({specifier:e})=>e===null?[]:[e])]),...a],t),{edges:s,add:c,link:l}=St();for(let t of e.files){Sn(t)&&l(t,n,`dependency`);for(let{kind:e,specifier:n}of i.get(t)??[]){let i=n===null?{to:null}:o(t,n);i.to!==t&&c(t,`${e}\0${JSON.stringify(n)}`,{from:t,kind:e,specifier:n,...i}),e===`dynamic-import`&&l(t,r,`dependency`)}for(let e of a.get(t)??[])l(t,o(t,e).to,`dependency`)}return s}var An=(e,t)=>t==null?kn(e):bn(t,e);function jn(e,t){let n=An(e,t);if(!n)throw Error(`bundleEdges: not a Metro ${t==null?`map`:`bundle`}; edges-lite.js reads only those, edges.js reads others`);return{edges:n}}function Mn(e){let t=JSON.parse(e.replace(/^\)\]\}'[^\n]*\n/u,``)),n=Ft(t),r=t.sections?t.sections.reduce((e,t)=>e+(t.map.names?.length??0),0):t.names?.length??null;return{json:{version:t.version,file:t.file,sourceRoot:t.sourceRoot},map:n,namesCount:r}}function Nn(e){if(e.map)return e.map.files.flatMap(e=>e.source===null?[]:[[e.source,e.content]]);let t=e.json?.sourcesContent??[];return(e.json?.sources??[]).map((e,n)=>[e,t[n]??null])}function Pn(e,t){let n=new Map;for(let{from:r,to:i,specifier:a}of t(e).edges){if(r.source===null||i?.source==null||i.source===r.source)continue;let e=typeof a==`string`?[r.source,i.source,a]:[r.source,i.source];n.set(e.join(`\0`),e)}return[...n.values()]}function Fn(e){try{return jn(e)}catch{return{edges:[]}}}var In=Object.freeze([]);function Ln(e){return e?.edges?e.edges:e?.map?(e.edges=Pn(e.map,Fn),e.edges):In}var Rn=new WeakMap,zn=new WeakMap;function Bn(e){let t=Ln(e);if(!Rn.has(t)){let e=new Map;for(let[n,r]of t)e.has(n)||e.set(n,new Set),e.get(n).add(r);Rn.set(t,e)}return Rn.get(t)}function Vn(e){let t=Ln(e);if(!zn.has(t)){let e=new Map;for(let[n,r,i]of t)i!==void 0&&(e.has(n)||e.set(n,new Map),e.get(n).set(i,r));zn.set(t,e)}return zn.get(t)}var Hn=new WeakMap,Un=new WeakMap,Wn=new WeakMap,Gn=new WeakMap,Kn=new WeakMap,Y=new WeakMap;function X(e){if(e?.metadataOnly)return new Map;let t=e?.bundle??e?.json;if(t&&Hn.has(t))return Hn.get(t);let n=new Map;if(!e)return n;if(e.kind===`stasis`){if(!e.bundle)return n;let t=e.bundle.formats;for(let[r,i]of e.bundle.sources)typeof i==`string`&&(N.isResourceFormat(t?.get(r))||n.set(r,i))}else if(e.kind===`sourcemap`)for(let[t,r]of Nn(e))typeof r==`string`&&n.set(t,r);return t&&Hn.set(t,n),n}function qn(e){let t=1;for(let n=e.indexOf(`
5
- `);n!==-1;n=e.indexOf(`
6
- `,n+1))t++;return t}var Jn=new WeakMap;function Yn(e){let t=Jn.get(e);if(!t){let n=[...e.keys()].toSorted();t={paths:n,numbers:new Map(n.map((e,t)=>[e,t+1]))},Jn.set(e,t)}return t}function Xn(e,t){let n=Array.isArray(t)?t:[];return{integrity:e.integrity,kind:`sourcemap`,size:e.size,json:{version:3,sources:n.map(([e])=>e),sourcesContent:n.map(([,,e])=>typeof e==`string`?e:null)},fileSizes:new Map(n.map(([e,t])=>[e,t])),npmBinaries:new Map(n.filter(([,,e,t])=>typeof e!=`string`&&typeof t==`string`).map(([e,t,,n])=>[e,{size:t,digest:n}]))}}function Zn(e){let t=e?.bundle??e?.json;if(t&&Un.has(t))return Un.get(t);let n=new Map(X(e));for(let[t,r]of e?.npmBinaries??[])n.set(t,{format:`digest`,...r});if(e?.kind===`stasis`&&e.bundle){let t=e.bundle.formats;for(let[r,i]of e.bundle.sources){if(typeof i!=`string`)continue;let e=t?.get(r);e===`resource`?n.set(r,i):e===`resource:base64`&&n.set(r,{format:`base64`,data:i})}}return t&&Un.set(t,n),n}var Qn=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`;function $n(e){let t=e.endsWith(`=`);if(t?e.length%4!=0||e.at(-3)===`=`:e.length%4==1)return null;let n=t?e.slice(0,e.endsWith(`==`)?-2:-1):e;if(/[^A-Za-z0-9+/]/u.test(n))return null;let r=n.length%4;return r>1&&Qn.indexOf(n.at(-1))&(r===2?15:3)?null:Math.floor(n.length*3/4)}function er(e){return typeof e==`string`?t(e):e?.format===`digest`?e.size:e?.format===`base64`?$n(e.data):null}function Z(e){if(e?.fileSizes)return e.fileSizes;let t=e?.bundle??e?.json;if(t&&Wn.has(t))return Wn.get(t);let n=new Map,r=Zn(e),i=e?.kind===`stasis`?e.bundle?.sources.keys():e&&Nn(e).map(([e])=>e);for(let e of i??[])n.set(e,er(r.get(e)));return t&&Wn.set(t,n),n}function tr(e){if(e?.metadataOnly)return e.unsizedFiles??new Set;let t=Z(e);if(Y.has(t))return Y.get(t);let n=new Set;for(let r of Zn(e).keys())t.get(r)===null&&n.add(r);return Y.set(t,n),n}function nr(e){let t=Z(e);if(Kn.has(t))return Kn.get(t);let n=tr(e),r=e?.kind===`stasis`?e.bundle?.formats:null,i=new Map;for(let[a,o]of t)o===null&&!n.has(a)||i.set(a,N.isResourceFormat(r?.get(a))||e?.npmBinaries?.has(a)?`resource`:`source`);return Kn.set(t,i),i}function rr(e){let t=Z(e),n=e?.kind===`stasis`?e.bundle?.formats:null;if(!n||n.size===0)return t;if(Gn.has(t))return Gn.get(t);let r=new Map;for(let[e,i]of t)N.isResourceFormat(n.get(e))||r.set(e,i);return Gn.set(t,r),r}var ir=new WeakMap;function ar(e){if(e?.kind!==`stasis`||!e.bundle?.modules)return null;if(ir.has(e.bundle))return ir.get(e.bundle);let t=new Map;for(let[n,r]of e.bundle.modules)for(let e of Object.keys(r.files))t.set(n===`.`?e:`${n}/${e}`,n);return ir.set(e.bundle,t),t}function or(e,t=null,n=(e,t)=>t.name){let r=new Map;if(e?.kind!==`stasis`||!e.bundle?.modules)return r;let i=t===null?null:ar(e),a=t===null?null:new Set([...t].map(e=>i?.get(e)));for(let[t,i]of e.bundle.modules){if(a&&!a.has(t)||!t.includes(`node_modules`)||!i?.name||typeof i.version!=`string`||!i.version)continue;let e=n(t,i),o=r.get(e);o||(o=new Set,r.set(e,o)),o.add(i.version)}return r}var sr=Object.freeze({javascript:`JavaScript`,jsx:`JSX`,typescript:`TypeScript`,tsx:`TSX`,json:`JSON`,css:`CSS`,markup:`HTML`,yaml:`YAML`,bash:`Shell`,markdown:`Markdown`,solidity:`Solidity`,php:`PHP`,rust:`Rust`,ruby:`Ruby`,java:`Java`,cpp:`C++`,c:`C`,objectivec:`Objective-C`,python:`Python`,go:`Go`,kotlin:`Kotlin`,swift:`Swift`,dart:`Dart`,sql:`SQL`,lua:`Lua`,csharp:`C#`,scala:`Scala`,vue:`Vue`,svelte:`Svelte`}),cr=Object.freeze({py:`python`,pyw:`python`,go:`go`,kt:`kotlin`,kts:`kotlin`,swift:`swift`,dart:`dart`,sql:`sql`,lua:`lua`,cs:`csharp`,scala:`scala`,sc:`scala`,vue:`vue`,svelte:`svelte`});function lr(e){let t=typeof e==`string`?e.slice(e.lastIndexOf(`/`)+1):``,n=t.lastIndexOf(`.`),r=n>0?t.slice(n+1).trim().toLowerCase():``,i=qe(e)??cr[r];return i?{key:i,label:sr[i]??i}:r?{key:`extension:${r}`,label:`.${r}`}:{key:`other`,label:`Other`}}function ur(e,t){let n=new Map,r=0,i=0;for(let[a,o]of e){let e=lr(a),s=n.get(e.key)??{...e,files:0,lines:0,bytes:0};s.files++,s.lines+=o,s.bytes+=t.get(a)??0,n.set(e.key,s),i+=o,r+=t.get(a)??0}return{files:e.size,lines:i,bytes:r,languages:[...n.values()].toSorted((e,t)=>t.lines-e.lines||e.label.localeCompare(t.label))}}var dr=6,Q=new WeakMap,fr=new Set([`terminal`,`code`,`search`,`compare`]);function pr(e,t=null){return!!t||fr.has(e)}var mr=/^sha512-[A-Za-z0-9+/]{86}==$/u;function hr(t){if(t.fileHashes)return Promise.resolve(t.fileHashes);if(Q.has(t))return Q.get(t);let n=(async()=>{let n=[...X(t)],r=new Map;for(let t=0;t<n.length;t+=32){let i=await Promise.all(n.slice(t,t+32).map(async([t,n])=>[t,await e(n)]));for(let[e,t]of i)r.set(e,t)}return t.fileHashes=r,r})();return Q.set(t,n),n.catch(()=>Q.delete(t)),n}function gr(e){if(typeof e!=`string`)return 0;let t=/\S/gu,n=/[\r\n]/gu,r=0;for(;t.test(e)&&(r++,n.lastIndex=t.lastIndex,n.test(e));)t.lastIndex=n.lastIndex;return r}function _r(e){return e.lineCounts??=new Map([...X(e)].map(([e,t])=>[e,gr(t)]))}function $(e){return e instanceof Map?Object.fromEntries([...e].map(([e,t])=>[e,$(t)])):e}async function vr(e){let n=await hr(e),r=Z(e),i=_r(e),a={version:dr,integrity:e.integrity,kind:e.kind,size:e.size,codeStats:ur(i,r),files:[...r].map(([e,t])=>[e,t,n.get(e)??null,i.get(e)??null])},o=tr(e);if(o.size>0&&(a.unsized=[...o]),e.kind===`sourcemap`){let{version:n,file:r,sourceRoot:i,names:o}=e.json,s=Nn(e);a.json={version:n,file:r,sourceRoot:i,sources:s.map(([e])=>e)},a.sourceSizes=s.map(([,e])=>typeof e==`string`?t(e):null),a.namesCount=e.namesCount??o?.length??null;let c=new Map(a.files.map(([e],t)=>[e,t]));a.edges=Ln(e).map(([e,t,...n])=>[c.get(e),c.get(t),...n])}else{let t=e.bundle,n={version:t.version,config:t.config,repo:t.repo,package:t.package,formats:$(t.formats),imports:$(t.imports),reason:t.reason,executable:[...t.executable]};if(t.version===0)n.sources=Object.fromEntries([...r.keys()].map(e=>[e,null]));else{let e={},r={};for(let[n,i]of t.modules){let t=n.split(`/`).includes(`node_modules`)?e:r;Object.defineProperty(t,n,{enumerable:!0,value:{name:i.name,version:i.version,ecosystem:i.ecosystem,repo:i.repo,files:Object.fromEntries(Object.keys(i.files).map(e=>[e,null]))}})}n.modules=e,t.config.scope===`full`&&(n.sources=r,n.entries=[...t.entries])}a.bundle=n}return a}function yr(e,t){if(![1,2,3,4,5,dr].includes(e?.version)||e.integrity!==t||![`stasis`,`sourcemap`].includes(e.kind)||!Number.isSafeInteger(e.size)||e.size<0||!Array.isArray(e.files))throw Error(`Invalid bundle metadata`);let n=e.version!==dr,r=e.version===1,i=new Map,a=new Map,o=new Map;for(let t of e.files){if(!Array.isArray(t)||t.length!==4&&!(r&&t.length===3))throw Error(`Invalid bundle metadata file`);let[e,n,s,c]=t;if(typeof e!=`string`||a.has(e)||n!==null&&(!Number.isSafeInteger(n)||n<0)||s!==null&&(typeof s!=`string`||!mr.test(s))||n===null&&s!==null||r&&n!==null&&s===null||c!=null&&(!Number.isSafeInteger(c)||c<0))throw Error(`Invalid bundle metadata file`);a.set(e,n),s!==null&&i.set(e,s),c!=null&&o.set(e,c)}let s=new Set(e.unsized??[]);if(e.unsized!==void 0&&(r||!Array.isArray(e.unsized)||s.size!==e.unsized.length)||[...s].some(e=>typeof e!=`string`||!a.has(e)||a.get(e)!==null))throw Error(`Invalid bundle metadata`);let c={integrity:t,kind:e.kind,size:e.size,metadataOnly:!0,fileSizes:a,fileHashes:i,lineCounts:o,unsizedFiles:s,stale:n};if(e.kind===`stasis`){c.bundle=N.fromJSON(e.bundle);let t=c.bundle.sources;if(t.size!==a.size||[...t.keys()].some(e=>!a.has(e)))throw Error(`Invalid bundle metadata inventory`);let n=c.bundle.formats;if(!r&&[...a].some(([e,t])=>i.has(e)!==(t!==null&&!N.isResourceFormat(n.get(e))))||[...s].some(e=>n.get(e)!==`resource:base64`))throw Error(`Invalid bundle metadata inventory`)}else{if(!e.json||typeof e.json!=`object`||![null,void 0].includes(e.namesCount)&&(!Number.isSafeInteger(e.namesCount)||e.namesCount<0))throw Error(`Invalid sourcemap metadata`);if(!Array.isArray(e.json.sources)||e.json.sources.some(e=>!a.has(e))||!Array.isArray(e.sourceSizes)||e.sourceSizes.length!==e.json.sources.length||e.sourceSizes.some(e=>e!==null&&(!Number.isSafeInteger(e)||e<0))||[...a].some(([e,t])=>i.has(e)!==(t!==null))||s.size>0)throw Error(`Invalid sourcemap inventory`);c.json=e.json,c.sourceSizes=e.sourceSizes,c.namesCount=e.namesCount,e.edges!==void 0&&(c.edges=br(e.edges,e.files))}if(e.codeStats===void 0)c.codeStats=ur(o,a);else{let t=e.codeStats,n=e=>Number.isSafeInteger(e)&&e>=0;if(!t||![t.files,t.lines,t.bytes].every(n)||!Array.isArray(t.languages)||t.languages.some(e=>!e||typeof e.key!=`string`||typeof e.label!=`string`||![e.files,e.lines,e.bytes].every(n)))throw Error(`Invalid bundle code stats`);c.codeStats=t}return c}function br(e,t){if(!Array.isArray(e))throw Error(`Invalid sourcemap edges`);return e.map(e=>{if(!Array.isArray(e)||![2,3].includes(e.length)||e[0]===e[1]||e.length===3&&typeof e[2]!=`string`||e.slice(0,2).some(e=>!Number.isSafeInteger(e)||e<0||e>=t.length))throw Error(`Invalid sourcemap edges`);return[t[e[0]][0],t[e[1]][0],...e.slice(2)]})}function xr(e,{integrity:t,kind:n,size:r}){if(n===`stasis`)return{integrity:t,kind:n,size:r,bundle:N.parse(e)};if(n!==`sourcemap`)throw Error(`Unsupported bundle format`);return{integrity:t,kind:n,size:r,...Mn(e)}}export{Re as a,N as b,qe as c,Bn as d,Vn as e,X as f,qn as g,Yn as h,Xn as i,Zn as j,er as k,Z as l,nr as m,rr as n,ar as o,or as p,ur as q,pr as r,hr as s,gr as t,_r as u,vr as v,yr as w,xr as x};
@@ -1 +0,0 @@
1
- import{b as e}from"./chunk-NRPC74AM.js";import{a as t,d as n,f as r,h as i}from"./chunk-7C7DWL7I.js";import{d as a}from"./chunk-PNHBZGDD.js";import{a as o,b as s}from"./chunk-I2MDGSQX.js";import{c}from"./chunk-BC2UCLFJ.js";import{C as l,D as u,G as d,J as f,K as p,L as m,O as h,q as g}from"./chunk-SXV2T5C4.js";import{a as _}from"./chunk-TUII34K2.js";function v(e,t){let n=s([{groups:[e],tree:t.tree}]);for(let r of e)l(r,t),r.isApp??=g(r,r.source??t.source),r._depsDirectory=n}function y(e,t){return!(e.isApp??g(e,e._source??e.source))&&o(e.file,e._depsDirectory??t??s([{groups:[[e]]}]))}function ee(e,n,r){let i=t(n);return i===`ignored`&&y(e,r)?void 0:i}function b(e,n,a,o){let s=n.id??String(n._id),c=n._reportName??``;y(n,o)&&(a===`ignored`||a===`untriaged`)?(t(e.get(s))!==`ignored`&&r(e,s,{triage:void 0}),i(e,s,c,a===`ignored`,!0)):(r(e,s,{triage:a===`untriaged`?void 0:a}),a!==`ignored`&&a!==`untriaged`&&i(e,s,c,!1))}function x(e,a){let o=new Set;for(let t of e.values()){let e=t?.ignoredReports;if(!e?.length)continue;let r=new Set(e).size!==e.length;for(let i of e)(r||!n(t,i))&&o.add(i)}if(o.size===0)return!1;let c=!1;for(let l of a){let a=(l.groups??[]).flat();if(!a.some(e=>o.has(e._reportName??l.name??l.fileName??``)))continue;let u=s([l]),d=e=>({...e,_source:e._source??e.source??l.source}),f=new Set(a.filter(e=>y(d(e),u)).map(e=>e.id??String(e._id)));for(let o of a){let a=o.id??String(o._id),s=o._reportName??l.name??l.fileName??``,p=e.get(a);p?.ignoredReports?.includes(s)&&(n(p,s)||y(d(o),u)||(t(p)||(c=r(e,a,{triage:`ignored`})||c),f.has(a)||(c=i(e,a,s,!1)||c)))}for(let t of a){if(!y(d(t),u))continue;let n=t.id??String(t._id),r=t._reportName??l.name??l.fileName??``;e.get(n)?.ignoredReports?.includes(r)&&(c=i(e,n,r,!0,!0)||c)}}return c}async function S(e,t){let r=new Set(Object.values(e??{}).flatMap(e=>Array.isArray(e?.ignoredReports)?e.ignoredReports.filter(t=>typeof t==`string`&&!n(e,t)):[])),i=[];for(let e of r){let n;try{let r=await t(e);if(typeof r!=`string`)continue;n=await h(r)}catch{continue}n&&i.push({...n.data,name:e,groups:[n.findings]})}return i}async function C(e,t){if(e!=null&&(typeof e!=`object`||Array.isArray(e)))return{entries:e,changed:!1};let n=new Map(Object.entries(e??{})),r=x(n,await S(e,t));return{entries:Object.fromEntries(n),changed:r}}var w=`links`;function T(e){if(typeof e==`string`)return e.length>0?e:null;if(!e||typeof e!=`object`||Array.isArray(e))return null;let{id:t}=e;return typeof t==`string`&&t.length>0?t:null}function E(e){if(typeof e==`string`&&!/^\s*\[/u.test(e))return null;let t;try{t=JSON.parse(e)}catch{return null}if(!Array.isArray(t)||t.length===0)return null;let n=[],r=0;for(let e of t){if(!Array.isArray(e))return null;let t=new Set;for(let n of e){let e=T(n);if(e===null)return null;c(e)?t.add(e):r++}t.size>1&&n.push([...t])}return{groups:n,skipped:r}}function D(e){let t=new Set;for(let n of e)for(let e of n)t.add(e);return t.size}function te(e,t){for(let n of e)for(let e of n){let r=t.get(e);r||t.set(e,r=new Set);for(let t of n)t!==e&&r.add(t)}return t}var O=1,k=16,A=12,j=1+k+A+16,M=1+k+A;async function N(e,t){let n=await crypto.subtle.importKey(`raw`,_(e),`PBKDF2`,!1,[`deriveKey`]);return crypto.subtle.deriveKey({name:`PBKDF2`,hash:`SHA-256`,salt:t,iterations:3e6},n,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`])}function P(e){return!(e instanceof Uint8Array)||e.length<j?!1:e[0]===O}async function F(e,t){if(!(e instanceof Uint8Array))throw TypeError(`encryptWithPassword: plaintext Uint8Array required`);if(typeof t!=`string`||!t)throw TypeError(`encryptWithPassword: password required`);let n=new Uint8Array(M+e.length+16);n[0]=O,crypto.getRandomValues(n.subarray(1,1+k)),crypto.getRandomValues(n.subarray(1+k,M));let r=n.subarray(1,1+k),i=n.subarray(1+k,M),a=await N(t,r),o=new Uint8Array(await crypto.subtle.encrypt({name:`AES-GCM`,iv:i,additionalData:n.subarray(0,M)},a,e));return n.set(o,M),n}async function ne(e,t){if(typeof t!=`string`||!t)throw TypeError(`tryDecryptWithPassword: password required`);if(!(e instanceof Uint8Array)||e.length<j||e[0]!==O)return{ok:!1,reason:`malformed`};let n=e.subarray(1,1+k),r=e.subarray(1+k,M),i=e.subarray(M),a=await N(t,n),o;try{o=new Uint8Array(await crypto.subtle.decrypt({name:`AES-GCM`,iv:r,additionalData:e.subarray(0,M)},a,i))}catch{return{ok:!1,reason:`wrong-password`}}return{ok:!0,plaintext:o}}async function I(e,t,n){if(!n||typeof n.malformedMsg!=`string`||typeof n.wrongPasswordMsg!=`string`)throw TypeError(`decryptWithPasswordOrThrow: { malformedMsg, wrongPasswordMsg } strings required`);let r=await ne(e,t);if(r.ok)return r.plaintext;throw r.reason===`wrong-password`?Error(n.wrongPasswordMsg):Error(n.malformedMsg)}var L=P,R=F;function z(e,t){return I(e,t,{malformedMsg:`malformed encrypted bundle`,wrongPasswordMsg:`wrong password or corrupt bundle`})}var B=1,V=1024,H=1024,U=200,W=104857600,G=Math.ceil(W*4/3)+16,K=512,q=64;function J(e){if(!e||typeof e!=`object`)return`payload is not an object`;if(e.version!==B)return`unsupported export version: ${e.version}`;if(!e.workspace||typeof e.workspace!=`object`)return`workspace metadata missing`;if(typeof e.workspace.id!=`string`)return`workspace.id must be a string`;if(typeof e.workspace.name!=`string`)return`workspace.name must be a string`;if(typeof e.workspace.privateKey!=`string`)return`workspace.privateKey must be a string`;if(e.workspace.createdAt!==void 0&&!Number.isFinite(e.workspace.createdAt))return`workspace.createdAt must be a finite number or omitted`;if(!Array.isArray(e.reports))return`reports field must be an array`;if(e.reports.length>H)return`reports count (${e.reports.length}) exceeds cap (${H})`;if(e.bundles!==void 0){if(!Array.isArray(e.bundles))return`bundles field must be an array when present`;if(e.bundles.length>V)return`bundles count (${e.bundles.length}) exceeds cap (${V})`;for(let t of e.bundles){if(typeof t!=`string`)return`bundles entries must be strings`;if(t.length>U)return`bundle integrity exceeds per-entry length cap (${U})`}}if(e.bundleBlobs!==void 0){if(!Array.isArray(e.bundleBlobs))return`bundleBlobs field must be an array when present`;if(e.bundleBlobs.length>q)return`bundleBlobs count (${e.bundleBlobs.length}) exceeds cap (${q})`;for(let t of e.bundleBlobs){if(!t||typeof t!=`object`||Array.isArray(t))return`bundleBlobs entries must be objects`;if(typeof t.integrity!=`string`||t.integrity.length===0)return`bundleBlobs.integrity must be a non-empty string`;if(t.integrity.length>U)return`bundleBlobs.integrity exceeds per-entry length cap (${U})`;if(typeof t.name!=`string`||t.name.length===0)return`bundleBlobs.name must be a non-empty string`;if(t.name.length>K)return`bundleBlobs.name exceeds per-entry length cap (${K})`;if(t.name.includes(`\0`))return`bundleBlobs.name cannot contain NUL`;if(typeof t.data!=`string`)return`bundleBlobs.data must be a base64 string`;if(t.data.length>G)return`bundleBlobs.data exceeds per-blob size cap (${W} bytes raw)`}}return null}async function Y(e){return new Uint8Array(await e.arrayBuffer())}async function X(e,t){if(L(e)){if(typeof t!=`string`||!t)throw TypeError(`parseWorkspaceBundleBytes: password required for encrypted bundle`);let n=await z(e,t);try{return Z(await a(n))}catch(e){throw Error(`wrong password or corrupt bundle`,{cause:e})}}let n;try{n=await a(e)}catch(e){throw Error(`gzip decompression failed: ${e.message}`,{cause:e})}return Z(n)}function Z(e){let t;try{t=JSON.parse(e)}catch(e){throw Error(`payload is not JSON: ${e.message}`,{cause:e})}let n=J(t);if(n===null)return t;let r=n.includes(`exceeds cap`);throw Error(r?n:`not a deepview workspace export: ${n}`)}function Q(e,t){let n=e.trimStart().startsWith(`[`)?E(e):null;if(n)return{data:{source:`links`,findings:[],links:n.groups},format:`links`,reason:null};let r=m(e);if(r.data!=null||p(e,t)!==`codex`)return r;try{return{data:{type:`security`,source:`codex-security`,findings:d(e).flatMap(e=>e.data.findings)},format:`codex`,reason:null}}catch(e){return{data:null,format:null,reason:e instanceof Error?e.message:`Invalid Codex CSV`}}}function re(e,t){let n=Q(e,t);return n.data==null?Promise.resolve(null):h(JSON.stringify(n.data))}function ie(e){let t=new Set;for(let n of e){if(!n||typeof n!=`object`)continue;let e=n;typeof e.file==`string`&&e.file&&t.add(e.file);for(let n of Array.isArray(e.evidence)?e.evidence:[])typeof n?.file==`string`&&n.file&&t.add(n.file)}return t}function $(e){let t=(f(e)??[]).flat().filter(e=>typeof e==`object`&&!!e),n=s([{groups:[t],tree:e?.tree}]);return{directory:n,own:t.filter(e=>!o(e.file,n))}}function ae(e){let t=new Map;for(let n of $(e).own){let e=u(n);e&&t.set(e.toLowerCase(),e)}return t.size===1?[...t.values()][0]:null}function oe(t){let{directory:n,own:r}=$(t);return e([...ie(r)].filter(e=>!o(e,n)))}var se=[`inprogress`,`fixed`,`invalid`,`deleted`,`ignored`];function ce(e){return typeof e==`string`&&se.includes(e)}function le(e){if(e===null)return null;if(typeof e!=`object`||Array.isArray(e))return`invalid`;let t=e,n={},r=t.color;if(r!=null){if(typeof r!=`string`||r.length>50)return`invalid`;r!==``&&(n.color=r)}let i=t.triage;if(i!=null){if(!ce(i))return`invalid`;n.triage=i}for(let e of[`comment`,`fix`]){let r=t[e];if(r!=null){if(typeof r!=`string`||r.length>1e4)return`invalid`;r!==``&&(n[e]=r)}}let a=t.flagged;if(a!=null){if(typeof a!=`boolean`)return`invalid`;n.flagged=a}return n}export{v as a,y as b,ee as c,b as d,x as e,S as f,C as g,w as h,E as i,D as j,te as k,F as l,I as m,L as n,R as o,H as p,Y as q,X as r,Z as s,Q as t,re as u,ae as v,oe as w,le as x};