@zenfg/inspector 0.1.0-beta.3 → 0.1.0

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 (172) hide show
  1. package/GUIDE.md +182 -0
  2. package/README.md +61 -89
  3. package/THEMING.md +124 -0
  4. package/dist/FrameGraphInspector.d.ts +23 -4
  5. package/dist/FrameGraphInspector.d.ts.map +1 -1
  6. package/dist/FrameGraphInspector.js +137 -29
  7. package/dist/FrameGraphInspector.js.map +1 -1
  8. package/dist/capture.d.ts +5 -0
  9. package/dist/capture.d.ts.map +1 -0
  10. package/dist/capture.js +2 -0
  11. package/dist/capture.js.map +1 -0
  12. package/dist/debugCaptureModel.d.ts +19 -0
  13. package/dist/debugCaptureModel.d.ts.map +1 -1
  14. package/dist/debugCaptureModel.js +36 -2
  15. package/dist/debugCaptureModel.js.map +1 -1
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/panelAliasAnalysis.d.ts +1 -0
  20. package/dist/panelAliasAnalysis.d.ts.map +1 -1
  21. package/dist/panelAliasAnalysis.js +23 -54
  22. package/dist/panelAliasAnalysis.js.map +1 -1
  23. package/dist/panelCytoscapeGraphRenderer.d.ts +15 -2
  24. package/dist/panelCytoscapeGraphRenderer.d.ts.map +1 -1
  25. package/dist/panelCytoscapeGraphRenderer.js +145 -23
  26. package/dist/panelCytoscapeGraphRenderer.js.map +1 -1
  27. package/dist/panelDetailLayout.d.ts +27 -0
  28. package/dist/panelDetailLayout.d.ts.map +1 -0
  29. package/dist/panelDetailLayout.js +174 -0
  30. package/dist/panelDetailLayout.js.map +1 -0
  31. package/dist/panelDetailStyles.d.ts +2 -0
  32. package/dist/panelDetailStyles.d.ts.map +1 -0
  33. package/dist/panelDetailStyles.js +57 -0
  34. package/dist/panelDetailStyles.js.map +1 -0
  35. package/dist/panelDiagnosticsView.d.ts +10 -1
  36. package/dist/panelDiagnosticsView.d.ts.map +1 -1
  37. package/dist/panelDiagnosticsView.js +166 -57
  38. package/dist/panelDiagnosticsView.js.map +1 -1
  39. package/dist/panelDomHelpers.d.ts.map +1 -1
  40. package/dist/panelDomHelpers.js +6 -5
  41. package/dist/panelDomHelpers.js.map +1 -1
  42. package/dist/panelGraphLayout.d.ts +3 -2
  43. package/dist/panelGraphLayout.d.ts.map +1 -1
  44. package/dist/panelGraphLayout.js +6 -5
  45. package/dist/panelGraphLayout.js.map +1 -1
  46. package/dist/panelGraphRenderer.d.ts +10 -0
  47. package/dist/panelGraphRenderer.d.ts.map +1 -1
  48. package/dist/panelGraphRenderer.js.map +1 -1
  49. package/dist/panelGraphScene.d.ts +1 -0
  50. package/dist/panelGraphScene.d.ts.map +1 -1
  51. package/dist/panelGraphScene.js +69 -32
  52. package/dist/panelGraphScene.js.map +1 -1
  53. package/dist/panelGraphSearch.d.ts +16 -0
  54. package/dist/panelGraphSearch.d.ts.map +1 -0
  55. package/dist/panelGraphSearch.js +93 -0
  56. package/dist/panelGraphSearch.js.map +1 -0
  57. package/dist/panelGraphView.d.ts +82 -0
  58. package/dist/panelGraphView.d.ts.map +1 -1
  59. package/dist/panelGraphView.js +15 -4
  60. package/dist/panelGraphView.js.map +1 -1
  61. package/dist/panelGraphVisuals.d.ts +14 -6
  62. package/dist/panelGraphVisuals.d.ts.map +1 -1
  63. package/dist/panelGraphVisuals.js +126 -51
  64. package/dist/panelGraphVisuals.js.map +1 -1
  65. package/dist/panelInspectorView.d.ts +8 -0
  66. package/dist/panelInspectorView.d.ts.map +1 -1
  67. package/dist/panelInspectorView.js +242 -48
  68. package/dist/panelInspectorView.js.map +1 -1
  69. package/dist/panelListStyles.d.ts +3 -0
  70. package/dist/panelListStyles.d.ts.map +1 -0
  71. package/dist/panelListStyles.js +155 -0
  72. package/dist/panelListStyles.js.map +1 -0
  73. package/dist/panelMemoryStyles.d.ts +3 -0
  74. package/dist/panelMemoryStyles.d.ts.map +1 -0
  75. package/dist/panelMemoryStyles.js +42 -0
  76. package/dist/panelMemoryStyles.js.map +1 -0
  77. package/dist/panelMemoryView.d.ts +13 -1
  78. package/dist/panelMemoryView.d.ts.map +1 -1
  79. package/dist/panelMemoryView.js +161 -41
  80. package/dist/panelMemoryView.js.map +1 -1
  81. package/dist/panelPassesView.d.ts +15 -0
  82. package/dist/panelPassesView.d.ts.map +1 -1
  83. package/dist/panelPassesView.js +202 -72
  84. package/dist/panelPassesView.js.map +1 -1
  85. package/dist/panelRawView.d.ts +15 -0
  86. package/dist/panelRawView.d.ts.map +1 -0
  87. package/dist/panelRawView.js +105 -0
  88. package/dist/panelRawView.js.map +1 -0
  89. package/dist/panelResourcesView.d.ts +8 -0
  90. package/dist/panelResourcesView.d.ts.map +1 -1
  91. package/dist/panelResourcesView.js +62 -31
  92. package/dist/panelResourcesView.js.map +1 -1
  93. package/dist/panelSelection.d.ts +9 -1
  94. package/dist/panelSelection.d.ts.map +1 -1
  95. package/dist/panelSelection.js +34 -4
  96. package/dist/panelSelection.js.map +1 -1
  97. package/dist/panelTheme.d.ts +13 -0
  98. package/dist/panelTheme.d.ts.map +1 -0
  99. package/dist/panelTheme.js +104 -0
  100. package/dist/panelTheme.js.map +1 -0
  101. package/dist/panelTypes.d.ts +10 -1
  102. package/dist/panelTypes.d.ts.map +1 -1
  103. package/dist/panelTypes.js.map +1 -1
  104. package/dist/panelVisualTheme.d.ts +147 -50
  105. package/dist/panelVisualTheme.d.ts.map +1 -1
  106. package/dist/panelVisualTheme.js +34 -44
  107. package/dist/panelVisualTheme.js.map +1 -1
  108. package/dist/panelWorkbenchHelpers.d.ts +12 -1
  109. package/dist/panelWorkbenchHelpers.d.ts.map +1 -1
  110. package/dist/panelWorkbenchHelpers.js +62 -1
  111. package/dist/panelWorkbenchHelpers.js.map +1 -1
  112. package/dist/panelWorkbenchStyles.d.ts +2 -0
  113. package/dist/panelWorkbenchStyles.d.ts.map +1 -0
  114. package/dist/panelWorkbenchStyles.js +101 -0
  115. package/dist/panelWorkbenchStyles.js.map +1 -0
  116. package/dist/panelWorkbenchView.d.ts +16 -0
  117. package/dist/panelWorkbenchView.d.ts.map +1 -1
  118. package/dist/panelWorkbenchView.js +228 -50
  119. package/dist/panelWorkbenchView.js.map +1 -1
  120. package/dist/query.js.map +1 -1
  121. package/dist/styles.d.ts.map +1 -1
  122. package/dist/styles.js +147 -195
  123. package/dist/styles.js.map +1 -1
  124. package/dist/theme.d.ts +22 -0
  125. package/dist/theme.d.ts.map +1 -0
  126. package/dist/theme.js +10 -0
  127. package/dist/theme.js.map +1 -0
  128. package/dist/themeDefinitions.d.ts +251 -0
  129. package/dist/themeDefinitions.d.ts.map +1 -0
  130. package/dist/themeDefinitions.js +96 -0
  131. package/dist/themeDefinitions.js.map +1 -0
  132. package/dist/themePalette.d.ts +66 -0
  133. package/dist/themePalette.d.ts.map +1 -0
  134. package/dist/themePalette.js +37 -0
  135. package/dist/themePalette.js.map +1 -0
  136. package/dist/themes.css +165 -0
  137. package/package.json +44 -10
  138. package/src/FrameGraphInspector.ts +130 -31
  139. package/src/capture.ts +4 -0
  140. package/src/debugCaptureModel.ts +53 -2
  141. package/src/index.ts +6 -2
  142. package/src/panelAliasAnalysis.ts +24 -70
  143. package/src/panelCytoscapeGraphRenderer.ts +140 -23
  144. package/src/panelDetailLayout.ts +155 -0
  145. package/src/panelDetailStyles.ts +56 -0
  146. package/src/panelDiagnosticsView.ts +166 -85
  147. package/src/panelDomHelpers.ts +4 -5
  148. package/src/panelGraphLayout.ts +6 -5
  149. package/src/panelGraphRenderer.ts +7 -0
  150. package/src/panelGraphScene.ts +68 -30
  151. package/src/panelGraphSearch.ts +96 -0
  152. package/src/panelGraphView.ts +14 -4
  153. package/src/panelGraphVisuals.ts +122 -52
  154. package/src/panelInspectorView.ts +227 -48
  155. package/src/panelListStyles.ts +154 -0
  156. package/src/panelMemoryStyles.ts +41 -0
  157. package/src/panelMemoryView.ts +178 -53
  158. package/src/panelPassesView.ts +190 -137
  159. package/src/panelRawView.ts +99 -0
  160. package/src/panelResourcesView.ts +69 -56
  161. package/src/panelSelection.ts +37 -5
  162. package/src/panelTheme.ts +85 -0
  163. package/src/panelTypes.ts +7 -1
  164. package/src/panelVisualTheme.ts +38 -49
  165. package/src/panelWorkbenchHelpers.ts +60 -2
  166. package/src/panelWorkbenchStyles.ts +100 -0
  167. package/src/panelWorkbenchView.ts +201 -52
  168. package/src/query.ts +11 -11
  169. package/src/styles.ts +148 -195
  170. package/src/theme.ts +24 -0
  171. package/src/themeDefinitions.ts +103 -0
  172. package/src/themePalette.ts +44 -0
@@ -1,10 +1,10 @@
1
+ import { InspectorThemeController, resolveGraphTheme } from "./panelTheme.js";
1
2
  import { FrameGraphSnapshotValidationError, decodeFrameGraphSnapshot, parseFrameGraphSnapshot, stringifyFrameGraphSnapshot, } from '@zenfg/snapshot';
2
3
  import { createDebugViewModel, } from "./debugCaptureModel.js";
3
4
  import { createToolbarButton } from "./panelDomHelpers.js";
4
- import { createPanelIcon } from "./panelIcons.js";
5
- import { destroyGraph, fitGraph, } from "./panelGraphView.js";
6
- import { graphGroupElementId } from "./panelGraphScene.js";
7
- import { selectionExists } from "./panelSelection.js";
5
+ import { destroyGraph, fitGraph, resolveGraphScene, renderGraphLegend, } from "./panelGraphView.js";
6
+ import { graphGroupElementId, selectionKey } from "./panelGraphScene.js";
7
+ import { resolveNodeSelection, selectionExists } from "./panelSelection.js";
8
8
  import { ensureFrameGraphInspectorStyles } from "./styles.js";
9
9
  import { sameSelection } from "./panelWorkbenchHelpers.js";
10
10
  import { FrameGraphDebugWorkbench } from "./panelWorkbenchView.js";
@@ -30,10 +30,12 @@ const DEFAULT_BRANDING = 'ZenFG Inspector';
30
30
  export class FrameGraphInspector {
31
31
  /** Root element owned by this inspector instance. */
32
32
  dom = document.createElement('section');
33
+ themeController = new InspectorThemeController(this.dom);
33
34
  body = document.createElement('div');
34
35
  content = document.createElement('div');
35
36
  dropOverlay = document.createElement('div');
36
37
  groupsButton;
38
+ declarationsButton;
37
39
  collapseGroupsButton;
38
40
  graphView;
39
41
  workbench;
@@ -54,6 +56,7 @@ export class FrameGraphInspector {
54
56
  copyFeedbackTimeout;
55
57
  maxImportBytes;
56
58
  dragDepth = 0;
59
+ revealRevision = 0;
57
60
  handleDragEnter = (event) => {
58
61
  if (!isFileDrag(event))
59
62
  return;
@@ -117,8 +120,10 @@ export class FrameGraphInspector {
117
120
  host: document.createElement('div'),
118
121
  toolbar: document.createElement('div'),
119
122
  legend: graphLegend,
123
+ refreshTheme: () => this.refreshTheme(),
120
124
  layoutElementBudget: normalizeLimit(options.maxGraphElements, DEFAULT_MAX_GRAPH_ELEMENTS, 'maxGraphElements'),
121
125
  groupsEnabled: true,
126
+ showResourceDeclarations: true,
122
127
  expandedGroupPaths: new Set(),
123
128
  fitOnNextRender: true,
124
129
  };
@@ -126,17 +131,20 @@ export class FrameGraphInspector {
126
131
  this.graphView.toolbar.className = 'zenfg-inspector-graph-toolbar';
127
132
  this.graphView.toolbar.setAttribute('role', 'toolbar');
128
133
  this.graphView.toolbar.setAttribute('aria-label', 'Frame graph view controls');
134
+ this.declarationsButton = createToolbarButton('Declarations', 'Show resource declaration nodes', () => this.toggleDeclarations());
129
135
  this.groupsButton = createToolbarButton('Groups', 'Toggle diagnostic group projection', () => this.toggleGroups());
130
136
  this.collapseGroupsButton = createToolbarButton('Collapse All', 'Collapse every diagnostic group', () => this.collapseAllGroups());
131
137
  const actionControls = document.createElement('div');
132
138
  actionControls.className = 'zenfg-inspector-graph-action-controls';
133
- actionControls.append(this.groupsButton, this.collapseGroupsButton, createGraphIconButton('fit', 'Fit graph to view', () => fitGraph(this.graphView)));
134
- this.graphView.toolbar.append(graphLegend, actionControls);
139
+ actionControls.append(this.declarationsButton, this.groupsButton, this.collapseGroupsButton, createToolbarButton('Fit', 'Fit graph to view', () => fitGraph(this.graphView)));
140
+ this.graphView.toolbar.append(actionControls);
135
141
  const callbacks = {
136
142
  onSelect: (selection) => this.handleSelect(selection),
137
143
  onHover: (selection) => this.handleHover(selection),
138
144
  onGroupToggle: (pathKey) => this.toggleGroup(pathKey),
139
145
  isGroupExpanded: (pathKey) => this.graphView.expandedGroupPaths.has(pathKey),
146
+ onReveal: (selection, tab) => this.handleReveal(selection, tab),
147
+ onNavigate: (tab, filter) => this.workbench.navigate(tab, filter),
140
148
  };
141
149
  this.workbench = new FrameGraphDebugWorkbench(this.graphView, callbacks, {
142
150
  onCapture: () => { void this.captureSnapshot(); },
@@ -158,20 +166,53 @@ export class FrameGraphInspector {
158
166
  this.updateCaptureActions();
159
167
  this.updateGraphControls();
160
168
  this.showEmptyState();
161
- queueMicrotask(() => this.maybeAutoCapture());
169
+ if (options.theme)
170
+ this.setTheme(options.theme);
171
+ queueMicrotask(() => { if (!this.destroyed) {
172
+ this.refreshTheme();
173
+ this.maybeAutoCapture();
174
+ } });
175
+ }
176
+ /** Replace API-applied variables on this instance, then synchronize graph styles.
177
+ * Pass null to restore host CSS and defaults. Does not change capture or interaction state.
178
+ */
179
+ setTheme(theme) {
180
+ if (this.destroyed)
181
+ return;
182
+ this.themeController.apply(theme);
183
+ this.refreshTheme();
184
+ }
185
+ /** Re-read final CSS values after external CSS changes and refresh graph and legend.
186
+ * Does not write theme variables, recapture, fit, or rebuild the component.
187
+ */
188
+ refreshTheme() {
189
+ if (this.destroyed)
190
+ return;
191
+ const theme = resolveGraphTheme(this.dom);
192
+ this.graphView.theme = theme;
193
+ this.graphView.renderer?.setTheme?.(theme);
194
+ if (this.viewModel)
195
+ renderGraphLegend(this.graphView.legend, this.viewModel, theme, this.graphView.showResourceDeclarations);
162
196
  }
163
197
  /**
164
198
  * Replaces or removes the live-capture provider.
165
199
  *
166
200
  * @remarks Installing a provider may immediately begin an asynchronous
167
- * capture when no snapshot is displayed.
201
+ * capture when no snapshot is displayed. Replacing or removing a provider
202
+ * invalidates its pending capture results without cancelling the provider
203
+ * promise. An already displayed snapshot and any pending import are preserved.
168
204
  */
169
205
  setCaptureSnapshotProvider(provider) {
170
- const changed = this.captureSnapshotCallback !== provider;
206
+ if (this.destroyed || this.captureSnapshotCallback === provider)
207
+ return;
208
+ if (this.capturing) {
209
+ this.operationRevision += 1;
210
+ this.capturing = false;
211
+ }
171
212
  this.captureSnapshotCallback = provider;
172
- if (changed && !this.viewModel)
213
+ if (!this.viewModel)
173
214
  this.initialAutoCaptureAttempted = false;
174
- if (!provider && !this.viewModel)
215
+ if (!provider && !this.viewModel && !this.importing)
175
216
  this.showEmptyState();
176
217
  this.updateCaptureActions();
177
218
  this.maybeAutoCapture();
@@ -199,7 +240,8 @@ export class FrameGraphInspector {
199
240
  this.workbench.showEmptyState('capturing', 'Capturing the next rendered frame…');
200
241
  this.updateCaptureActions();
201
242
  try {
202
- const snapshot = await this.captureSnapshotCallback();
243
+ const request = { timing: 'both' };
244
+ const snapshot = await this.captureSnapshotCallback(request);
203
245
  if (this.destroyed || revision !== this.operationRevision)
204
246
  return;
205
247
  if (!snapshot) {
@@ -226,9 +268,9 @@ export class FrameGraphInspector {
226
268
  }
227
269
  }
228
270
  /**
229
- * Validates and synchronously displays a programmatic Snapshot 1.1 value.
271
+ * Validates and synchronously displays a programmatic Snapshot 1.2 value.
230
272
  *
231
- * @throws {@link FrameGraphSnapshotValidationError} if `snapshot` is invalid.
273
+ * @throws {@link @zenfg/snapshot!index.FrameGraphSnapshotValidationError | FrameGraphSnapshotValidationError} if `snapshot` is invalid.
232
274
  */
233
275
  setSnapshot(snapshot) {
234
276
  if (this.destroyed)
@@ -280,10 +322,17 @@ export class FrameGraphInspector {
280
322
  });
281
323
  const sourceFormat = decoded.snapshot.capture.migration?.sourceFormat;
282
324
  if (sourceFormat) {
283
- const sourceLabel = sourceFormat === 'legacy-v0' ? 'Legacy V0' : 'Legacy Candidate V1';
325
+ // The current import format can differ from retained historical provenance.
326
+ const sourceLabel = {
327
+ 'legacy-v0': 'Legacy V0',
328
+ 'legacy-candidate-v1': 'Legacy Candidate V1',
329
+ 'snapshot-v1.1': 'Snapshot 1.1',
330
+ }[decoded.migrated && decoded.source !== 'v1' ? decoded.source : sourceFormat];
331
+ const version = decoded.snapshot.version;
332
+ const targetLabel = `Snapshot ${version.major}.${version.minor}`;
284
333
  this.statusMessage = decoded.migrated
285
- ? `Imported ${sourceLabel} and migrated it to ZenFG Snapshot V1.`
286
- : `Imported Snapshot V1 with ${sourceLabel} migration provenance.`;
334
+ ? `Imported ${sourceLabel} and migrated it to ZenFG ${targetLabel}.`
335
+ : `Imported ${targetLabel} with ${sourceLabel} migration provenance.`;
287
336
  this.statusTone = 'neutral';
288
337
  }
289
338
  }
@@ -363,15 +412,17 @@ export class FrameGraphInspector {
363
412
  this.protocolSnapshot = snapshot;
364
413
  this.viewModel = viewModel;
365
414
  this.graphView.fitOnNextRender = true;
415
+ this.graphView.captureRevision = (this.graphView.captureRevision ?? 0) + 1;
416
+ this.graphView.revealOnNextRender = undefined;
417
+ this.graphView.renderer?.cancelReveal?.();
366
418
  this.hovered = undefined;
367
419
  this.initialAutoCaptureAttempted = true;
368
420
  this.statusMessage = undefined;
369
421
  this.statusTone = 'neutral';
370
- if (!this.selected || !selectionExists(viewModel, this.selected)) {
371
- this.selected = viewModel.nodes[0]
372
- ? { kind: 'node', id: viewModel.nodes[0].id }
373
- : undefined;
374
- }
422
+ if (this.selected?.kind === 'node' || this.selected?.kind === 'culled')
423
+ this.selected = resolveNodeSelection(viewModel, this.selected.id);
424
+ else if (this.selected && !selectionExists(viewModel, this.selected))
425
+ this.selected = undefined;
375
426
  this.workbench.setSnapshot(viewModel, this.selected);
376
427
  this.updateCaptureActions();
377
428
  this.updateGraphControls();
@@ -393,7 +444,9 @@ export class FrameGraphInspector {
393
444
  this.dom.removeEventListener('dragleave', this.handleDragLeave);
394
445
  this.dom.removeEventListener('dragend', this.handleDragEnd);
395
446
  this.dom.removeEventListener('drop', this.handleDrop);
447
+ this.themeController.destroy();
396
448
  destroyGraph(this.graphView);
449
+ this.workbench.destroy();
397
450
  this.dom.remove();
398
451
  }
399
452
  updateCaptureActions() {
@@ -420,9 +473,54 @@ export class FrameGraphInspector {
420
473
  void this.captureSnapshot();
421
474
  }
422
475
  handleSelect(selection) {
476
+ if (!this.viewModel || !selectionExists(this.viewModel, selection))
477
+ return;
423
478
  this.selected = selection;
424
479
  this.workbench.setSelection(selection);
425
480
  }
481
+ handleReveal(selection, tab) {
482
+ const snapshot = this.viewModel;
483
+ if (!snapshot || !selectionExists(snapshot, selection))
484
+ return;
485
+ if (tab === 'graph') {
486
+ const expanded = new Set(this.graphView.expandedGroupPaths);
487
+ const groupsEnabled = this.graphView.groupsEnabled;
488
+ const showResourceDeclarations = this.graphView.showResourceDeclarations;
489
+ if (selection.kind === 'resource')
490
+ this.graphView.showResourceDeclarations = true;
491
+ if (selection.kind === 'group')
492
+ this.graphView.groupsEnabled = true;
493
+ let groupId;
494
+ if (selection.kind === 'node')
495
+ groupId = snapshot.nodeById.get(selection.id)?.debugGroupId;
496
+ else if (selection.kind === 'resource')
497
+ groupId = snapshot.resourceById.get(selection.id)?.debugGroupId;
498
+ else if (selection.kind === 'group')
499
+ groupId = snapshot.groupByPathKey.get(selection.pathKey)?.parentId;
500
+ if (this.graphView.groupsEnabled && groupId) {
501
+ for (const id of snapshot.groupById.get(groupId)?.ancestorIds ?? []) {
502
+ const group = snapshot.groupById.get(id);
503
+ if (group)
504
+ this.graphView.expandedGroupPaths.add(group.pathKey);
505
+ }
506
+ }
507
+ const scene = resolveGraphScene(this.graphView, snapshot);
508
+ const availableIds = new Set([...scene.nodes, ...scene.edges].map((entry) => entry.id));
509
+ if (!(scene.interaction.primaryElementIdsBySelection.get(selectionKey(selection))?.some((id) => availableIds.has(id)))) {
510
+ this.graphView.groupsEnabled = groupsEnabled;
511
+ this.graphView.showResourceDeclarations = showResourceDeclarations;
512
+ this.graphView.expandedGroupPaths.clear();
513
+ for (const path of expanded)
514
+ this.graphView.expandedGroupPaths.add(path);
515
+ this.workbench.showNavigationIssue(selection.kind === 'culled' ? 'Culled passes are not part of Frame Flow.' : 'This object has no representation in Frame Flow.', selection);
516
+ return;
517
+ }
518
+ this.graphView.revealOnNextRender = { selection, revision: ++this.revealRevision };
519
+ this.updateGraphControls();
520
+ }
521
+ this.handleSelect(selection);
522
+ this.workbench.reveal(selection, tab);
523
+ }
426
524
  handleHover(selection) {
427
525
  if (!this.viewModel || sameSelection(this.hovered, selection))
428
526
  return;
@@ -430,13 +528,28 @@ export class FrameGraphInspector {
430
528
  this.workbench.setHovered(selection);
431
529
  }
432
530
  updateGraphControls() {
531
+ const showDeclarations = this.graphView.showResourceDeclarations ?? true;
532
+ this.declarationsButton.classList.toggle('active', showDeclarations);
533
+ this.declarationsButton.setAttribute('aria-pressed', String(showDeclarations));
433
534
  const hasGroups = (this.viewModel?.debugGroups.length ?? 0) > 0;
434
535
  this.groupsButton.disabled = !hasGroups;
536
+ this.groupsButton.hidden = !hasGroups;
537
+ this.collapseGroupsButton.hidden = !hasGroups;
435
538
  this.groupsButton.classList.toggle('active', hasGroups && this.graphView.groupsEnabled);
436
539
  this.groupsButton.setAttribute('aria-pressed', hasGroups && this.graphView.groupsEnabled ? 'true' : 'false');
437
540
  const hasExpanded = this.viewModel?.debugGroups.some((group) => this.graphView.expandedGroupPaths.has(group.pathKey)) ?? false;
438
541
  this.collapseGroupsButton.disabled = !hasGroups || !this.graphView.groupsEnabled || !hasExpanded;
439
542
  }
543
+ toggleDeclarations() {
544
+ this.handleHover(undefined);
545
+ this.graphView.showResourceDeclarations = !(this.graphView.showResourceDeclarations ?? true);
546
+ this.graphView.renderer?.cancelReveal?.();
547
+ this.graphView.revealOnNextRender = undefined;
548
+ this.graphView.anchorElementIdOnNextRender = undefined;
549
+ this.graphView.fitOnNextRender = true;
550
+ this.updateGraphControls();
551
+ this.workbench.refreshGraphStructure();
552
+ }
440
553
  toggleGroups() {
441
554
  if (!this.viewModel?.debugGroups.length)
442
555
  return;
@@ -499,14 +612,9 @@ export class FrameGraphInspector {
499
612
  export function mountFrameGraphInspector(host, options) {
500
613
  const inspector = new FrameGraphInspector(options);
501
614
  host.appendChild(inspector.dom);
615
+ inspector.refreshTheme();
502
616
  return inspector;
503
617
  }
504
- function createGraphIconButton(icon, title, onClick) {
505
- const button = createToolbarButton('', title, onClick);
506
- button.classList.add('zenfg-inspector-icon-button');
507
- button.appendChild(createPanelIcon(icon));
508
- return button;
509
- }
510
618
  async function writeTextToClipboard(text) {
511
619
  if (navigator.clipboard?.writeText) {
512
620
  await navigator.clipboard.writeText(text);
@@ -545,7 +653,7 @@ function formatImportLimit(bytes) {
545
653
  : `${bytes} bytes`;
546
654
  }
547
655
  function formatIssues(issues) {
548
- return issues.slice(0, 3).map((issue) => `${issue.path || '/'}: ${issue.message}`).join('; ');
656
+ return issues.map((issue) => `${issue.path || '/'}: ${issue.message}`).join('\n');
549
657
  }
550
658
  function isFileDrag(event) {
551
659
  return Array.from(event.dataTransfer?.types ?? []).includes('Files');
@@ -1 +1 @@
1
- {"version":3,"file":"FrameGraphInspector.js","sourceRoot":"","sources":["../src/FrameGraphInspector.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tFrameGraphSnapshotValidationError,\n\tdecodeFrameGraphSnapshot,\n\tparseFrameGraphSnapshot,\n\tstringifyFrameGraphSnapshot,\n\ttype FrameGraphSnapshot,\n} from '@zenfg/snapshot';\nimport {\n\tcreateDebugViewModel,\n\ttype FrameGraphDebugSnapshotSource,\n\ttype FrameGraphDebugViewModel,\n} from './debugCaptureModel.ts';\nimport { createToolbarButton } from './panelDomHelpers.ts';\nimport { createPanelIcon } from './panelIcons.ts';\nimport {\n\tdestroyGraph,\n\tfitGraph,\n} from './panelGraphView.ts';\nimport { graphGroupElementId } from './panelGraphScene.ts';\nimport { selectionExists } from './panelSelection.ts';\nimport type { GraphViewState, Selection } from './panelTypes.ts';\nimport { ensureFrameGraphInspectorStyles } from './styles.ts';\nimport { sameSelection, type WorkbenchCallbacks } from './panelWorkbenchHelpers.ts';\nimport { FrameGraphDebugWorkbench } from './panelWorkbenchView.ts';\n\n/** Construction and safety limits for an embedded {@link FrameGraphInspector}. */\nexport type FrameGraphInspectorOptions = {\n\t/**\n\t * Product label shown in the workbench command bar. Pass `false` to hide\n\t * visible branding while retaining the inspector's accessible name.\n\t *\n\t * @defaultValue `\"ZenFG Inspector\"`\n\t */\n\tbranding?: string | false;\n\t/**\n\t * Produces a live snapshot when capture is requested. The inspector awaits\n\t * promises and displays thrown or rejected errors in its status area.\n\t */\n\tcaptureSnapshot?: () => FrameGraphSnapshot | undefined | Promise<FrameGraphSnapshot | undefined>;\n\t/**\n\t * Maximum accepted import size in bytes.\n\t *\n\t * @defaultValue `67108864` (64 MiB)\n\t */\n\tmaxImportBytes?: number;\n\t/**\n\t * Maximum graph nodes plus edges accepted by automatic layout.\n\t *\n\t * @defaultValue `5000`\n\t */\n\tmaxGraphElements?: number;\n};\n\nconst DEFAULT_MAX_IMPORT_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_MAX_GRAPH_ELEMENTS = 5_000;\nconst DEFAULT_BRANDING = 'ZenFG Inspector';\n\n/**\n * Browser lifecycle controller for one embeddable FrameGraph inspector.\n *\n * @remarks The constructor creates, but does not append, {@link dom}. Use\n * {@link mountFrameGraphInspector} for the common append-and-return workflow.\n * Async capture, import, and clipboard failures are reported in the UI. Call\n * {@link destroy} when the controller is no longer needed.\n *\n * @example\n * ```ts\n * const inspector = new FrameGraphInspector({ captureSnapshot: capture });\n * document.body.append(inspector.dom);\n * // Later:\n * inspector.destroy();\n * ```\n */\nexport class FrameGraphInspector {\n\t/** Root element owned by this inspector instance. */\n\treadonly dom = document.createElement('section');\n\n\tprivate readonly body = document.createElement('div');\n\tprivate readonly content = document.createElement('div');\n\tprivate readonly dropOverlay = document.createElement('div');\n\tprivate readonly groupsButton: HTMLButtonElement;\n\tprivate readonly collapseGroupsButton: HTMLButtonElement;\n\tprivate readonly graphView: GraphViewState;\n\tprivate readonly workbench: FrameGraphDebugWorkbench;\n\tprivate captureSnapshotCallback: FrameGraphInspectorOptions['captureSnapshot'];\n\tprivate protocolSnapshot: FrameGraphSnapshot | undefined;\n\tprivate operationRevision = 0;\n\tprivate viewModel: FrameGraphDebugViewModel | undefined;\n\tprivate selected: Selection | undefined;\n\tprivate hovered: Selection | undefined;\n\tprivate capturing = false;\n\tprivate importing = false;\n\tprivate copying = false;\n\tprivate copied = false;\n\tprivate initialAutoCaptureAttempted = false;\n\tprivate statusMessage: string | undefined;\n\tprivate statusTone: 'neutral' | 'error' = 'neutral';\n\tprivate destroyed = false;\n\tprivate copyFeedbackTimeout: number | undefined;\n\tprivate readonly maxImportBytes: number;\n\tprivate dragDepth = 0;\n\tprivate readonly handleDragEnter = (event: DragEvent): void => {\n\t\tif (!isFileDrag(event)) return;\n\t\tevent.preventDefault();\n\t\tthis.dragDepth += 1;\n\t\tthis.setDropActive(true);\n\t};\n\tprivate readonly handleDragOver = (event: DragEvent): void => {\n\t\tif (!isFileDrag(event)) return;\n\t\tevent.preventDefault();\n\t\tif (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n\t\tthis.setDropActive(true);\n\t};\n\tprivate readonly handleDragLeave = (event: DragEvent): void => {\n\t\tif (!isFileDrag(event) && this.dragDepth === 0) return;\n\t\tthis.dragDepth = Math.max(0, this.dragDepth - 1);\n\t\tif (this.dragDepth === 0) this.setDropActive(false);\n\t};\n\tprivate readonly handleDragEnd = (): void => this.clearDropState();\n\tprivate readonly handleDrop = (event: DragEvent): void => {\n\t\tconst file = event.dataTransfer?.files?.[0];\n\t\tif (!file) return;\n\t\tevent.preventDefault();\n\t\tthis.clearDropState();\n\t\tvoid this.importSnapshot(file);\n\t};\n\n\t/**\n\t * Creates a detached inspector UI.\n\t *\n\t * @throws If a configured numeric limit is not a non-negative safe integer,\n\t * or if browser DOM globals are unavailable.\n\t */\n\tconstructor(options: FrameGraphInspectorOptions = {}) {\n\t\tensureFrameGraphInspectorStyles();\n\t\tthis.captureSnapshotCallback = options.captureSnapshot;\n\t\tthis.maxImportBytes = normalizeMaxImportBytes(options.maxImportBytes);\n\t\tconst branding = options.branding ?? DEFAULT_BRANDING;\n\t\tthis.dom.className = 'zenfg-inspector';\n\t\tthis.dom.id = createInspectorId();\n\t\tthis.dom.setAttribute('role', 'region');\n\t\tthis.dom.setAttribute('aria-label', branding === false ? DEFAULT_BRANDING : branding);\n\t\tthis.body.className = 'zenfg-inspector-body';\n\t\tthis.content.className = 'zenfg-inspector-content';\n\t\tthis.dropOverlay.className = 'zenfg-inspector-drop-overlay';\n\t\tthis.dropOverlay.hidden = true;\n\t\tthis.dropOverlay.setAttribute('aria-hidden', 'true');\n\t\tconst dropTitle = document.createElement('strong');\n\t\tdropTitle.textContent = 'Drop snapshot to open';\n\t\tconst dropDetail = document.createElement('span');\n\t\tdropDetail.textContent = 'The first file will be imported locally.';\n\t\tthis.dropOverlay.append(dropTitle, dropDetail);\n\n\t\tconst graphLegend = document.createElement('div');\n\t\tgraphLegend.className = 'zenfg-inspector-graph-legend';\n\t\tgraphLegend.setAttribute('aria-label', 'Graph legend');\n\t\tthis.graphView = {\n\t\t\thost: document.createElement('div'),\n\t\t\ttoolbar: document.createElement('div'),\n\t\t\tlegend: graphLegend,\n\t\t\tlayoutElementBudget: normalizeLimit(options.maxGraphElements, DEFAULT_MAX_GRAPH_ELEMENTS, 'maxGraphElements'),\n\t\t\tgroupsEnabled: true,\n\t\t\texpandedGroupPaths: new Set(),\n\t\t\tfitOnNextRender: true,\n\t\t};\n\t\tthis.graphView.host.className = 'zenfg-inspector-graph';\n\t\tthis.graphView.toolbar.className = 'zenfg-inspector-graph-toolbar';\n\t\tthis.graphView.toolbar.setAttribute('role', 'toolbar');\n\t\tthis.graphView.toolbar.setAttribute('aria-label', 'Frame graph view controls');\n\n\t\tthis.groupsButton = createToolbarButton('Groups', 'Toggle diagnostic group projection', () => this.toggleGroups());\n\t\tthis.collapseGroupsButton = createToolbarButton('Collapse All', 'Collapse every diagnostic group', () => this.collapseAllGroups());\n\n\t\tconst actionControls = document.createElement('div');\n\t\tactionControls.className = 'zenfg-inspector-graph-action-controls';\n\t\tactionControls.append(\n\t\t\tthis.groupsButton,\n\t\t\tthis.collapseGroupsButton,\n\t\t\tcreateGraphIconButton('fit', 'Fit graph to view', () => fitGraph(this.graphView)),\n\t\t);\n\t\tthis.graphView.toolbar.append(graphLegend, actionControls);\n\n\t\tconst callbacks: WorkbenchCallbacks = {\n\t\t\tonSelect: (selection) => this.handleSelect(selection),\n\t\t\tonHover: (selection) => this.handleHover(selection),\n\t\t\tonGroupToggle: (pathKey) => this.toggleGroup(pathKey),\n\t\t\tisGroupExpanded: (pathKey) => this.graphView.expandedGroupPaths.has(pathKey),\n\t\t};\n\t\tthis.workbench = new FrameGraphDebugWorkbench(this.graphView, callbacks, {\n\t\t\tonCapture: () => { void this.captureSnapshot(); },\n\t\t\tonImport: (file) => { void this.importSnapshot(file); },\n\t\t\tonDownload: () => this.downloadSnapshot(),\n\t\t\tonCopyJson: () => { void this.copySnapshotJson(); },\n\t\t}, {\n\t\t\tbranding,\n\t\t\tidPrefix: this.dom.id,\n\t\t});\n\t\tthis.content.append(this.workbench.root);\n\t\tthis.body.appendChild(this.content);\n\t\tthis.dom.append(this.body, this.dropOverlay);\n\t\tthis.dom.addEventListener('dragenter', this.handleDragEnter);\n\t\tthis.dom.addEventListener('dragover', this.handleDragOver);\n\t\tthis.dom.addEventListener('dragleave', this.handleDragLeave);\n\t\tthis.dom.addEventListener('dragend', this.handleDragEnd);\n\t\tthis.dom.addEventListener('drop', this.handleDrop);\n\t\tthis.updateCaptureActions();\n\t\tthis.updateGraphControls();\n\t\tthis.showEmptyState();\n\t\tqueueMicrotask(() => this.maybeAutoCapture());\n\t}\n\n\t/**\n\t * Replaces or removes the live-capture provider.\n\t *\n\t * @remarks Installing a provider may immediately begin an asynchronous\n\t * capture when no snapshot is displayed.\n\t */\n\tsetCaptureSnapshotProvider(provider: FrameGraphInspectorOptions['captureSnapshot']): void {\n\t\tconst changed = this.captureSnapshotCallback !== provider;\n\t\tthis.captureSnapshotCallback = provider;\n\t\tif (changed && !this.viewModel) this.initialAutoCaptureAttempted = false;\n\t\tif (!provider && !this.viewModel) this.showEmptyState();\n\t\tthis.updateCaptureActions();\n\t\tthis.maybeAutoCapture();\n\t}\n\n\t/**\n\t * Requests and displays a live snapshot from the configured provider.\n\t *\n\t * @remarks Concurrent requests are coalesced. Provider errors, invalid\n\t * snapshots, and an unavailable provider are displayed in the inspector and\n\t * do not reject the returned promise.\n\t */\n\tasync captureSnapshot(): Promise<void> {\n\t\tif (this.destroyed || this.capturing) return;\n\t\tif (!this.captureSnapshotCallback) {\n\t\t\tthis.reportCaptureIssue('Waiting for a FrameGraph capture source.');\n\t\t\treturn;\n\t\t}\n\t\tconst revision = ++this.operationRevision;\n\t\tthis.importing = false;\n\t\tthis.capturing = true;\n\t\tthis.statusMessage = undefined;\n\t\tthis.statusTone = 'neutral';\n\t\tif (!this.viewModel) this.workbench.showEmptyState('capturing', 'Capturing the next rendered frame…');\n\t\tthis.updateCaptureActions();\n\t\ttry {\n\t\t\tconst snapshot = await this.captureSnapshotCallback();\n\t\t\tif (this.destroyed || revision !== this.operationRevision) return;\n\t\t\tif (!snapshot) {\n\t\t\t\tthis.reportCaptureIssue('No snapshot was produced. Capture again when rendering is active.');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst decoded = decodeFrameGraphSnapshot(snapshot);\n\t\t\tif (!decoded.ok) {\n\t\t\t\tthis.reportCaptureIssue(`Failed to capture FrameGraph: ${formatIssues(decoded.issues)}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.applySnapshot(decoded.snapshot, { kind: 'live', label: 'Live Capture' });\n\t\t}\n\t\tcatch (error) {\n\t\t\tif (!this.destroyed && revision === this.operationRevision) {\n\t\t\t\tthis.reportCaptureIssue(`Failed to capture FrameGraph: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\tif (revision === this.operationRevision) this.capturing = false;\n\t\t\tif (!this.destroyed && revision === this.operationRevision) this.updateCaptureActions();\n\t\t}\n\t}\n\n\t/**\n\t * Validates and synchronously displays a programmatic Snapshot 1.1 value.\n\t *\n\t * @throws {@link FrameGraphSnapshotValidationError} if `snapshot` is invalid.\n\t */\n\tsetSnapshot(snapshot: FrameGraphSnapshot): void {\n\t\tif (this.destroyed) return;\n\t\tthis.operationRevision += 1;\n\t\tthis.capturing = false;\n\t\tthis.importing = false;\n\t\tconst decoded = decodeFrameGraphSnapshot(snapshot);\n\t\tif (!decoded.ok) throw new FrameGraphSnapshotValidationError(decoded.issues);\n\t\tthis.applySnapshot(decoded.snapshot, { kind: 'programmatic', label: 'Programmatic' });\n\t}\n\n\t/** Returns the currently displayed canonical snapshot, if any. */\n\tgetSnapshot(): FrameGraphSnapshot | undefined {\n\t\treturn this.protocolSnapshot;\n\t}\n\n\t/**\n\t * Reads, migrates, validates, and displays a snapshot JSON file.\n\t *\n\t * @remarks Files above `maxImportBytes`, read failures, invalid JSON, and\n\t * validation failures are displayed in the UI and do not reject the promise.\n\t */\n\tasync importSnapshot(file: File): Promise<void> {\n\t\tif (this.destroyed) return;\n\t\tconst revision = ++this.operationRevision;\n\t\tthis.capturing = false;\n\t\tthis.importing = false;\n\t\tif (file.size > this.maxImportBytes) {\n\t\t\tthis.reportCaptureIssue(`Import exceeds the ${formatImportLimit(this.maxImportBytes)} limit.`);\n\t\t\treturn;\n\t\t}\n\t\tthis.importing = true;\n\t\tthis.statusMessage = undefined;\n\t\tthis.statusTone = 'neutral';\n\t\tthis.updateCaptureActions();\n\t\ttry {\n\t\t\tconst text = await file.text();\n\t\t\tif (this.destroyed || revision !== this.operationRevision) return;\n\t\t\tconst decoded = parseFrameGraphSnapshot(text);\n\t\t\tif (!decoded.ok) {\n\t\t\t\tthis.reportCaptureIssue(`Failed to import snapshot: ${formatIssues(decoded.issues)}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.applySnapshot(decoded.snapshot, {\n\t\t\t\tkind: 'file',\n\t\t\t\tlabel: file.name || 'Imported JSON',\n\t\t\t});\n\t\t\tconst sourceFormat = decoded.snapshot.capture.migration?.sourceFormat;\n\t\t\tif (sourceFormat) {\n\t\t\t\tconst sourceLabel = sourceFormat === 'legacy-v0' ? 'Legacy V0' : 'Legacy Candidate V1';\n\t\t\t\tthis.statusMessage = decoded.migrated\n\t\t\t\t\t? `Imported ${sourceLabel} and migrated it to ZenFG Snapshot V1.`\n\t\t\t\t\t: `Imported Snapshot V1 with ${sourceLabel} migration provenance.`;\n\t\t\t\tthis.statusTone = 'neutral';\n\t\t\t}\n\t\t}\n\t\tcatch (error) {\n\t\t\tif (!this.destroyed && revision === this.operationRevision) {\n\t\t\t\tthis.reportCaptureIssue(`Failed to import snapshot: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\tif (revision === this.operationRevision) this.importing = false;\n\t\t\tif (!this.destroyed && revision === this.operationRevision) this.updateCaptureActions();\n\t\t}\n\t}\n\n\t/** Downloads the displayed snapshot as pretty-printed canonical JSON. */\n\tdownloadSnapshot(): void {\n\t\tif (this.destroyed || !this.protocolSnapshot) return;\n\t\tconst json = stringifyFrameGraphSnapshot(this.protocolSnapshot, { pretty: true });\n\t\tconst url = URL.createObjectURL(new Blob([json], { type: 'application/json;charset=utf-8' }));\n\t\tconst anchor = document.createElement('a');\n\t\tanchor.href = url;\n\t\tanchor.download = `frame-graph-${this.protocolSnapshot.capture.frameIndex}.fgsnapshot.json`;\n\t\tanchor.click();\n\t\tURL.revokeObjectURL(url);\n\t}\n\n\t/**\n\t * Copies the displayed snapshot as pretty-printed canonical JSON.\n\t *\n\t * @remarks Clipboard failures are shown in the UI and do not reject the\n\t * returned promise. A legacy `document.execCommand` fallback is used when the\n\t * async Clipboard API is unavailable.\n\t */\n\tasync copySnapshotJson(): Promise<void> {\n\t\tif (this.destroyed || this.copying || !this.protocolSnapshot) return;\n\t\tconst snapshot = this.protocolSnapshot;\n\t\tconst revision = this.operationRevision;\n\t\tthis.copying = true;\n\t\tthis.copied = false;\n\t\tthis.statusMessage = undefined;\n\t\tthis.statusTone = 'neutral';\n\t\tthis.updateCaptureActions();\n\t\ttry {\n\t\t\tawait writeTextToClipboard(stringifyFrameGraphSnapshot(snapshot, { pretty: true }));\n\t\t\tif (this.destroyed || revision !== this.operationRevision) return;\n\t\t\tthis.copied = true;\n\t\t\tif (this.copyFeedbackTimeout !== undefined) window.clearTimeout(this.copyFeedbackTimeout);\n\t\t\tthis.copyFeedbackTimeout = window.setTimeout(() => {\n\t\t\t\tthis.copied = false;\n\t\t\t\tthis.copyFeedbackTimeout = undefined;\n\t\t\t\tthis.updateCaptureActions();\n\t\t\t}, 1200);\n\t\t}\n\t\tcatch (error) {\n\t\t\tif (!this.destroyed && revision === this.operationRevision) {\n\t\t\t\tthis.statusMessage = `Failed to copy snapshot: ${error instanceof Error ? error.message : String(error)}`;\n\t\t\t}\n\t\t\tconsole.warn('Failed to copy FrameGraph Snapshot.', error);\n\t\t}\n\t\tfinally {\n\t\t\tthis.copying = false;\n\t\t\tif (!this.destroyed) this.updateCaptureActions();\n\t\t}\n\t}\n\n\tprivate applySnapshot(snapshot: FrameGraphSnapshot, source: FrameGraphDebugSnapshotSource): void {\n\t\tconst viewModel = createDebugViewModel(snapshot, source);\n\t\tthis.copied = false;\n\t\tif (this.copyFeedbackTimeout !== undefined) {\n\t\t\twindow.clearTimeout(this.copyFeedbackTimeout);\n\t\t\tthis.copyFeedbackTimeout = undefined;\n\t\t}\n\t\tthis.protocolSnapshot = snapshot;\n\t\tthis.viewModel = viewModel;\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.hovered = undefined;\n\t\tthis.initialAutoCaptureAttempted = true;\n\t\tthis.statusMessage = undefined;\n\t\tthis.statusTone = 'neutral';\n\t\tif (!this.selected || !selectionExists(viewModel, this.selected)) {\n\t\t\tthis.selected = viewModel.nodes[0]\n\t\t\t\t? { kind: 'node', id: viewModel.nodes[0].id }\n\t\t\t\t: undefined;\n\t\t}\n\t\tthis.workbench.setSnapshot(viewModel, this.selected);\n\t\tthis.updateCaptureActions();\n\t\tthis.updateGraphControls();\n\t}\n\n\t/**\n\t * Idempotently cancels pending UI results, releases graph resources, and\n\t * removes the inspector workbench. Do not reuse the controller afterward.\n\t */\n\tdestroy(): void {\n\t\tif (this.destroyed) return;\n\t\tthis.destroyed = true;\n\t\tthis.operationRevision += 1;\n\t\tif (this.copyFeedbackTimeout !== undefined) window.clearTimeout(this.copyFeedbackTimeout);\n\t\tthis.clearDropState();\n\t\tthis.dom.removeEventListener('dragenter', this.handleDragEnter);\n\t\tthis.dom.removeEventListener('dragover', this.handleDragOver);\n\t\tthis.dom.removeEventListener('dragleave', this.handleDragLeave);\n\t\tthis.dom.removeEventListener('dragend', this.handleDragEnd);\n\t\tthis.dom.removeEventListener('drop', this.handleDrop);\n\t\tdestroyGraph(this.graphView);\n\t\tthis.dom.remove();\n\t}\n\n\tprivate updateCaptureActions(): void {\n\t\tthis.workbench.setSnapshotActionState({\n\t\t\tproviderAvailable: Boolean(this.captureSnapshotCallback),\n\t\t\thasCapture: Boolean(this.viewModel),\n\t\t\tcapturing: this.capturing,\n\t\t\timporting: this.importing,\n\t\t\tcopying: this.copying,\n\t\t\tcopied: this.copied,\n\t\t\tmessage: this.viewModel ? this.statusMessage : undefined,\n\t\t\tmessageTone: this.statusTone,\n\t\t});\n\t}\n\n\tprivate maybeAutoCapture(): void {\n\t\tif (\n\t\t\tthis.destroyed\n\t\t\t|| this.viewModel\n\t\t\t|| this.initialAutoCaptureAttempted\n\t\t\t|| this.capturing\n\t\t\t|| this.importing\n\t\t\t|| !this.captureSnapshotCallback\n\t\t) return;\n\t\tthis.initialAutoCaptureAttempted = true;\n\t\tvoid this.captureSnapshot();\n\t}\n\tprivate handleSelect(selection: Selection): void {\n\t\tthis.selected = selection;\n\t\tthis.workbench.setSelection(selection);\n\t}\n\n\tprivate handleHover(selection: Selection | undefined): void {\n\t\tif (!this.viewModel || sameSelection(this.hovered, selection)) return;\n\t\tthis.hovered = selection;\n\t\tthis.workbench.setHovered(selection);\n\t}\n\n\tprivate updateGraphControls(): void {\n\t\tconst hasGroups = (this.viewModel?.debugGroups.length ?? 0) > 0;\n\t\tthis.groupsButton.disabled = !hasGroups;\n\t\tthis.groupsButton.classList.toggle('active', hasGroups && this.graphView.groupsEnabled);\n\t\tthis.groupsButton.setAttribute('aria-pressed', hasGroups && this.graphView.groupsEnabled ? 'true' : 'false');\n\t\tconst hasExpanded = this.viewModel?.debugGroups.some((group) => this.graphView.expandedGroupPaths.has(group.pathKey)) ?? false;\n\t\tthis.collapseGroupsButton.disabled = !hasGroups || !this.graphView.groupsEnabled || !hasExpanded;\n\t}\n\n\tprivate toggleGroups(): void {\n\t\tif (!this.viewModel?.debugGroups.length) return;\n\t\tthis.handleHover(undefined);\n\t\tthis.graphView.groupsEnabled = !this.graphView.groupsEnabled;\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.updateGraphControls();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate toggleGroup(pathKey: string): void {\n\t\tthis.handleHover(undefined);\n\t\tif (this.graphView.expandedGroupPaths.has(pathKey)) this.graphView.expandedGroupPaths.delete(pathKey);\n\t\telse this.graphView.expandedGroupPaths.add(pathKey);\n\t\tthis.graphView.anchorElementIdOnNextRender = graphGroupElementId(pathKey);\n\t\tthis.updateGraphControls();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate collapseAllGroups(): void {\n\t\tif (this.graphView.expandedGroupPaths.size === 0) return;\n\t\tthis.handleHover(undefined);\n\t\tthis.graphView.expandedGroupPaths.clear();\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.updateGraphControls();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate showEmptyState(): void {\n\t\tconst providerAvailable = Boolean(this.captureSnapshotCallback);\n\t\tthis.workbench.showEmptyState(\n\t\t\t'empty',\n\t\t\tproviderAvailable\n\t\t\t\t? 'No capture yet. Use Capture to request the next rendered frame.'\n\t\t\t\t: 'Drop a ZenFG Snapshot here or choose Import.',\n\t\t\tproviderAvailable ? undefined : 'Files are processed locally in your browser.',\n\t\t);\n\t}\n\n\tprivate setDropActive(active: boolean): void {\n\t\tif (this.destroyed) return;\n\t\tthis.dropOverlay.hidden = !active;\n\t\tthis.dom.classList.toggle('drop-active', active);\n\t}\n\n\tprivate clearDropState(): void {\n\t\tthis.dragDepth = 0;\n\t\tthis.dropOverlay.hidden = true;\n\t\tthis.dom.classList.remove('drop-active');\n\t}\n\n\tprivate reportCaptureIssue(message: string): void {\n\t\tthis.statusMessage = message;\n\t\tthis.statusTone = 'error';\n\t\tif (!this.viewModel) this.workbench.showEmptyState('error', message);\n\t\tthis.updateCaptureActions();\n\t}\n}\n\n/**\n * Creates an inspector, appends its root element to `host`, and returns its\n * lifecycle controller.\n *\n * @throws If inspector construction fails; see {@link FrameGraphInspector}.\n */\nexport function mountFrameGraphInspector(host: HTMLElement, options?: FrameGraphInspectorOptions): FrameGraphInspector {\n\tconst inspector = new FrameGraphInspector(options);\n\thost.appendChild(inspector.dom);\n\treturn inspector;\n}\n\nfunction createGraphIconButton(icon: 'fit', title: string, onClick: () => void): HTMLButtonElement {\n\tconst button = createToolbarButton('', title, onClick);\n\tbutton.classList.add('zenfg-inspector-icon-button');\n\tbutton.appendChild(createPanelIcon(icon));\n\treturn button;\n}\n\nasync function writeTextToClipboard(text: string): Promise<void> {\n\tif (navigator.clipboard?.writeText) {\n\t\tawait navigator.clipboard.writeText(text);\n\t\treturn;\n\t}\n\tconst textArea = document.createElement('textarea');\n\ttextArea.value = text;\n\ttextArea.setAttribute('readonly', 'true');\n\ttextArea.style.position = 'fixed';\n\ttextArea.style.left = '-9999px';\n\ttextArea.style.top = '0';\n\tdocument.body.appendChild(textArea);\n\ttextArea.select();\n\ttry {\n\t\tif (!document.execCommand('copy')) throw new Error('document.execCommand(\"copy\") returned false.');\n\t}\n\tfinally {\n\t\ttextArea.remove();\n\t}\n}\n\nfunction normalizeMaxImportBytes(value: number | undefined): number {\n\treturn normalizeLimit(value, DEFAULT_MAX_IMPORT_BYTES, 'maxImportBytes');\n}\n\nfunction normalizeLimit(value: number | undefined, fallback: number, name: string): number {\n\tif (value === undefined) return fallback;\n\tif (!Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new Error(`${name} must be a non-negative safe integer.`);\n\t}\n\treturn value;\n}\n\nfunction formatImportLimit(bytes: number): string {\n\treturn bytes >= 1024 * 1024 && bytes % (1024 * 1024) === 0\n\t\t? `${bytes / (1024 * 1024)} MiB`\n\t\t: `${bytes} bytes`;\n}\n\nfunction formatIssues(issues: readonly { readonly path: string; readonly message: string }[]): string {\n\treturn issues.slice(0, 3).map((issue) => `${issue.path || '/'}: ${issue.message}`).join('; ');\n}\n\nfunction isFileDrag(event: DragEvent): boolean {\n\treturn Array.from(event.dataTransfer?.types ?? []).includes('Files');\n}\n\nlet nextInspectorId = 0;\nfunction createInspectorId(): string {\n\tnextInspectorId += 1;\n\treturn `zenfg-inspector-${nextInspectorId}`;\n}\n"]}
1
+ {"version":3,"file":"FrameGraphInspector.js","sourceRoot":"","sources":["../src/FrameGraphInspector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EACN,iCAAiC,EACjC,wBAAwB,EACxB,uBAAuB,EACvB,2BAA2B,GAE3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,oBAAoB,GAGpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EACN,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE5E,OAAO,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,aAAa,EAA2B,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAgCnE,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAClD,MAAM,0BAA0B,GAAG,KAAK,CAAC;AACzC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAE3C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,mBAAmB;IAC/B,qDAAqD;IAC5C,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAChC,eAAe,GAAG,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEzD,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACxC,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5C,YAAY,CAAoB;IAChC,kBAAkB,CAAoB;IACtC,oBAAoB,CAAoB;IACxC,SAAS,CAAiB;IAC1B,SAAS,CAA2B;IAC7C,uBAAuB,CAAgD;IACvE,gBAAgB,CAAiC;IACjD,iBAAiB,GAAG,CAAC,CAAC;IACtB,SAAS,CAAuC;IAChD,QAAQ,CAAwB;IAChC,OAAO,CAAwB;IAC/B,SAAS,GAAG,KAAK,CAAC;IAClB,SAAS,GAAG,KAAK,CAAC;IAClB,OAAO,GAAG,KAAK,CAAC;IAChB,MAAM,GAAG,KAAK,CAAC;IACf,2BAA2B,GAAG,KAAK,CAAC;IACpC,aAAa,CAAqB;IAClC,UAAU,GAAwB,SAAS,CAAC;IAC5C,SAAS,GAAG,KAAK,CAAC;IAClB,mBAAmB,CAAqB;IAC/B,cAAc,CAAS;IAChC,SAAS,GAAG,CAAC,CAAC;IACd,cAAc,GAAG,CAAC,CAAC;IACV,eAAe,GAAG,CAAC,KAAgB,EAAQ,EAAE;QAC7D,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO;QAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;QACpB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC;IACe,cAAc,GAAG,CAAC,KAAgB,EAAQ,EAAE;QAC5D,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO;QAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,YAAY;YAAE,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,MAAM,CAAC;QAC/D,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC;IACe,eAAe,GAAG,CAAC,KAAgB,EAAQ,EAAE;QAC7D,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC;YAAE,OAAO;QACvD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QACjD,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC;YAAE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC;IACe,aAAa,GAAG,GAAS,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;IAClD,UAAU,GAAG,CAAC,KAAgB,EAAQ,EAAE;QACxD,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF;;;;;OAKG;IACH,YAAY,UAAsC,EAAE;QACnD,+BAA+B,EAAE,CAAC;QAClC,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,uBAAuB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,gBAAgB,CAAC;QACtD,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,iBAAiB,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,iBAAiB,EAAE,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtF,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,sBAAsB,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,yBAAyB,CAAC;QACnD,IAAI,CAAC,WAAW,CAAC,SAAS,GAAG,8BAA8B,CAAC;QAC5D,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACnD,SAAS,CAAC,WAAW,GAAG,uBAAuB,CAAC;QAChD,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAClD,UAAU,CAAC,WAAW,GAAG,0CAA0C,CAAC;QACpE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAE/C,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClD,WAAW,CAAC,SAAS,GAAG,8BAA8B,CAAC;QACvD,WAAW,CAAC,YAAY,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,GAAG;YAChB,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;YACnC,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;YACtC,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE;YACvC,mBAAmB,EAAE,cAAc,CAAC,OAAO,CAAC,gBAAgB,EAAE,0BAA0B,EAAE,kBAAkB,CAAC;YAC7G,aAAa,EAAE,IAAI;YACnB,wBAAwB,EAAE,IAAI;YAC9B,kBAAkB,EAAE,IAAI,GAAG,EAAE;YAC7B,eAAe,EAAE,IAAI;SACrB,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,GAAG,uBAAuB,CAAC;QACxD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,GAAG,+BAA+B,CAAC;QACnE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,2BAA2B,CAAC,CAAC;QAE/E,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,cAAc,EAAE,iCAAiC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;QAClI,IAAI,CAAC,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,oCAAoC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QACnH,IAAI,CAAC,oBAAoB,GAAG,mBAAmB,CAAC,cAAc,EAAE,iCAAiC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAEnI,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrD,cAAc,CAAC,SAAS,GAAG,uCAAuC,CAAC;QACnE,cAAc,CAAC,MAAM,CACpB,IAAI,CAAC,kBAAkB,EACvB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,oBAAoB,EACzB,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAC/E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAE9C,MAAM,SAAS,GAAuB;YACrC,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC;YACrD,OAAO,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;YACnD,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;YACrD,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC;YAC5E,QAAQ,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC;YAC/D,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;SACjE,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,wBAAwB,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE;YACxE,SAAS,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;YACjD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvD,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE;YACzC,UAAU,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;SACnD,EAAE;YACF,QAAQ;YACR,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE;SACrB,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC7D,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC7D,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACzD,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,OAAO,CAAC,KAAK;YAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChD,cAAc,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClG,CAAC;IAEE;;OAEG;IACH,QAAQ,CAAC,KAA4B;QACjC,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,YAAY,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,YAAY;QACR,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,SAAS;YAAE,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;IACjI,CAAC;IAEJ;;;;;;;OAOG;IACH,0BAA0B,CAAC,QAAuD;QACjF,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,uBAAuB,KAAK,QAAQ;YAAE,OAAO;QACxE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;YAC5B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,uBAAuB,GAAG,QAAQ,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,2BAA2B,GAAG,KAAK,CAAC;QAC9D,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,cAAc,EAAE,CAAC;QAC3E,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,eAAe;QACpB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC7C,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACnC,IAAI,CAAC,kBAAkB,CAAC,0CAA0C,CAAC,CAAC;YACpE,OAAO;QACR,CAAC;QACD,MAAM,QAAQ,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,WAAW,EAAE,oCAAoC,CAAC,CAAC;QACtG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC;YACJ,MAAM,OAAO,GAA6B,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC7D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;YAC7D,IAAI,IAAI,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB;gBAAE,OAAO;YAClE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,IAAI,CAAC,kBAAkB,CAAC,mEAAmE,CAAC,CAAC;gBAC7F,OAAO;YACR,CAAC;YACD,MAAM,OAAO,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;YACnD,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBACjB,IAAI,CAAC,kBAAkB,CAAC,iCAAiC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACzF,OAAO;YACR,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC5D,IAAI,CAAC,kBAAkB,CAAC,iCAAiC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACpH,CAAC;QACF,CAAC;gBACO,CAAC;YACR,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB;gBAAE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YAChE,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB;gBAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACzF,CAAC;IACF,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,QAA4B;QACvC,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,MAAM,OAAO,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,MAAM,IAAI,iCAAiC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7E,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,kEAAkE;IAClE,WAAW;QACV,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,IAAU;QAC9B,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,MAAM,QAAQ,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACrC,IAAI,CAAC,kBAAkB,CAAC,sBAAsB,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YAC/F,OAAO;QACR,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB;gBAAE,OAAO;YAClE,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBACjB,IAAI,CAAC,kBAAkB,CAAC,8BAA8B,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACtF,OAAO;YACR,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACpC,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,eAAe;aACnC,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC;YACtE,IAAI,YAAY,EAAE,CAAC;gBAClB,4EAA4E;gBAC5E,MAAM,WAAW,GAAG;oBACnB,WAAW,EAAE,WAAW;oBACxB,qBAAqB,EAAE,qBAAqB;oBAC5C,eAAe,EAAE,cAAc;iBAC/B,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;gBAC/E,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACzC,MAAM,WAAW,GAAG,YAAY,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBACjE,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,QAAQ;oBACpC,CAAC,CAAC,YAAY,WAAW,6BAA6B,WAAW,GAAG;oBACpE,CAAC,CAAC,YAAY,WAAW,SAAS,WAAW,wBAAwB,CAAC;gBACvE,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;YAC7B,CAAC;QACF,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC5D,IAAI,CAAC,kBAAkB,CAAC,8BAA8B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACjH,CAAC;QACF,CAAC;gBACO,CAAC;YACR,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB;gBAAE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YAChE,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB;gBAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACzF,CAAC;IACF,CAAC;IAED,yEAAyE;IACzE,gBAAgB;QACf,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QACrD,MAAM,IAAI,GAAG,2BAA2B,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC,CAAC,CAAC;QAC9F,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC;QAClB,MAAM,CAAC,QAAQ,GAAG,eAAe,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,kBAAkB,CAAC;QAC5F,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,gBAAgB;QACrB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC;YACJ,MAAM,oBAAoB,CAAC,2BAA2B,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACpF,IAAI,IAAI,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB;gBAAE,OAAO;YAClE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,IAAI,CAAC,mBAAmB,KAAK,SAAS;gBAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC1F,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;gBACjD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;gBACpB,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;gBACrC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC7B,CAAC,EAAE,IAAI,CAAC,CAAC;QACV,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC5D,IAAI,CAAC,aAAa,GAAG,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3G,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;QAC5D,CAAC;gBACO,CAAC;YACR,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClD,CAAC;IACF,CAAC;IAEO,aAAa,CAAC,QAA4B,EAAE,MAAqC;QACxF,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,IAAI,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;YAC5C,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC9C,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;QACtC,CAAC;QACD,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,CAAC,eAAe,GAAG,IAAI,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3E,IAAI,CAAC,SAAS,CAAC,kBAAkB,GAAG,SAAS,CAAC;QAC9C,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,CAAC;QAC1C,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC;QACxC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;aACrI,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAChG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,OAAO;QACN,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,mBAAmB,KAAK,SAAS;YAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC1F,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAChE,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9D,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAChE,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;QAC/B,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IACnB,CAAC;IAEO,oBAAoB;QAC3B,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC;YACrC,iBAAiB,EAAE,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC;YACxD,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YACnC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;YACxD,WAAW,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;IACJ,CAAC;IAEO,gBAAgB;QACvB,IACC,IAAI,CAAC,SAAS;eACX,IAAI,CAAC,SAAS;eACd,IAAI,CAAC,2BAA2B;eAChC,IAAI,CAAC,SAAS;eACd,IAAI,CAAC,SAAS;eACd,CAAC,IAAI,CAAC,uBAAuB;YAC/B,OAAO;QACT,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC;QACxC,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;IAC7B,CAAC;IACO,YAAY,CAAC,SAAoB;QACxC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC;YAAE,OAAO;QAC3E,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAEO,YAAY,CAAC,SAAoB,EAAE,GAAiB;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,QAAQ,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC;YAAE,OAAO;QAC/D,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YAC5D,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;YACnD,MAAM,wBAAwB,GAAG,IAAI,CAAC,SAAS,CAAC,wBAAwB,CAAC;YACzE,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU;gBAAE,IAAI,CAAC,SAAS,CAAC,wBAAwB,GAAG,IAAI,CAAC;YAClF,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO;gBAAE,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC;YACpE,IAAI,OAA2B,CAAC;YAChC,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC;iBACtF,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU;gBAAE,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC;iBACnG,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC;YACxG,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,OAAO,EAAE,CAAC;gBAC7C,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC;oBACrE,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACzC,IAAI,KAAK;wBAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACjE,CAAC;YACF,CAAC;YACD,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC1D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YACxF,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxH,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,aAAa,CAAC;gBAC7C,IAAI,CAAC,SAAS,CAAC,wBAAwB,GAAG,wBAAwB,CAAC;gBACnE,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;gBAC1C,KAAK,MAAM,IAAI,IAAI,QAAQ;oBAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACzE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,2CAA2C,CAAC,CAAC,CAAC,kDAAkD,EAAE,SAAS,CAAC,CAAC;gBAC9K,OAAO;YACR,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,kBAAkB,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;YACnF,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IAEO,WAAW,CAAC,SAAgC;QACnD,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC;YAAE,OAAO;QACtE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAEO,mBAAmB;QAC1B,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,wBAAwB,IAAI,IAAI,CAAC;QACzE,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QACrE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAChE,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,CAAC,SAAS,CAAC;QACxC,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC;QACtC,IAAI,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC;QAC9C,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACxF,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,cAAc,EAAE,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC7G,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC;QAC/H,IAAI,CAAC,oBAAoB,CAAC,QAAQ,GAAG,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,CAAC,WAAW,CAAC;IAClG,CAAC;IAEO,kBAAkB;QACzB,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,wBAAwB,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,wBAAwB,IAAI,IAAI,CAAC,CAAC;QAC7F,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,CAAC;QAC1C,IAAI,CAAC,SAAS,CAAC,kBAAkB,GAAG,SAAS,CAAC;QAC9C,IAAI,CAAC,SAAS,CAAC,2BAA2B,GAAG,SAAS,CAAC;QACvD,IAAI,CAAC,SAAS,CAAC,eAAe,GAAG,IAAI,CAAC;QACtC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAC;IACxC,CAAC;IAEO,YAAY;QACnB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM;YAAE,OAAO;QAChD,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;QAC7D,IAAI,CAAC,SAAS,CAAC,eAAe,GAAG,IAAI,CAAC;QACtC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAC;IACxC,CAAC;IAEO,WAAW,CAAC,OAAe;QAClC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;;YACjG,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS,CAAC,2BAA2B,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC1E,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAC;IACxC,CAAC;IAEO,iBAAiB;QACxB,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QACzD,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAC1C,IAAI,CAAC,SAAS,CAAC,eAAe,GAAG,IAAI,CAAC;QACtC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAC;IACxC,CAAC;IAEO,cAAc;QACrB,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAChE,IAAI,CAAC,SAAS,CAAC,cAAc,CAC5B,OAAO,EACP,iBAAiB;YAChB,CAAC,CAAC,iEAAiE;YACnE,CAAC,CAAC,8CAA8C,EACjD,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,8CAA8C,CAC9E,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,MAAe;QACpC,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAEO,cAAc;QACrB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC1C,CAAC;IAEO,kBAAkB,CAAC,OAAe;QACzC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrE,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC7B,CAAC;CACD;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAiB,EAAE,OAAoC;IAC/F,MAAM,SAAS,GAAG,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAChC,SAAS,CAAC,YAAY,EAAE,CAAC;IACzB,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC;QACpC,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO;IACR,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC;QACJ,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACpG,CAAC;YACO,CAAC;QACR,QAAQ,CAAC,MAAM,EAAE,CAAC;IACnB,CAAC;AACF,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAyB;IACzD,OAAO,cAAc,CAAC,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,cAAc,CAAC,KAAyB,EAAE,QAAgB,EAAE,IAAY;IAChF,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,uCAAuC,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACvC,OAAO,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACzD,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM;QAChC,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC;AACrB,CAAC;AAED,SAAS,YAAY,CAAC,MAAsE;IAC3F,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,GAAG,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,UAAU,CAAC,KAAgB;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,IAAI,eAAe,GAAG,CAAC,CAAC;AACxB,SAAS,iBAAiB;IACzB,eAAe,IAAI,CAAC,CAAC;IACrB,OAAO,mBAAmB,eAAe,EAAE,CAAC;AAC7C,CAAC","sourcesContent":["import type { FrameGraphCaptureRequest } from './capture.ts';\nimport type { InspectorTheme } from './theme.ts';\nimport { InspectorThemeController, resolveGraphTheme } from './panelTheme.ts';\nimport {\n\tFrameGraphSnapshotValidationError,\n\tdecodeFrameGraphSnapshot,\n\tparseFrameGraphSnapshot,\n\tstringifyFrameGraphSnapshot,\n\ttype FrameGraphSnapshot,\n} from '@zenfg/snapshot';\nimport {\n\tcreateDebugViewModel,\n\ttype FrameGraphDebugSnapshotSource,\n\ttype FrameGraphDebugViewModel,\n} from './debugCaptureModel.ts';\nimport { createToolbarButton } from './panelDomHelpers.ts';\nimport {\n\tdestroyGraph,\n\tfitGraph,\n\tresolveGraphScene,\n\trenderGraphLegend,\n} from './panelGraphView.ts';\nimport { graphGroupElementId, selectionKey } from './panelGraphScene.ts';\nimport { resolveNodeSelection, selectionExists } from './panelSelection.ts';\nimport type { GraphViewState, Selection, WorkbenchTab } from './panelTypes.ts';\nimport { ensureFrameGraphInspectorStyles } from './styles.ts';\nimport { sameSelection, type WorkbenchCallbacks } from './panelWorkbenchHelpers.ts';\nimport { FrameGraphDebugWorkbench } from './panelWorkbenchView.ts';\n\n/** Construction and safety limits for an embedded {@link FrameGraphInspector}. */\nexport type FrameGraphInspectorOptions = {\n\t/** Optional CSS theme. Without one, host variables inherit over the Storm defaults. */\n\ttheme?: InspectorTheme;\n\t/**\n\t * Product label shown in the workbench command bar. Pass `false` to hide\n\t * visible branding while retaining the inspector's accessible name.\n\t *\n\t * @defaultValue `\"ZenFG Inspector\"`\n\t */\n\tbranding?: string | false;\n\t/**\n\t * Produces a live snapshot when capture is requested. The inspector awaits\n\t * promises and displays thrown or rejected errors in its status area.\n\t */\n\tcaptureSnapshot?: (request: FrameGraphCaptureRequest) => FrameGraphSnapshot | undefined | Promise<FrameGraphSnapshot | undefined>;\n\t/**\n\t * Maximum accepted import size in bytes.\n\t *\n\t * @defaultValue `67108864` (64 MiB)\n\t */\n\tmaxImportBytes?: number;\n\t/**\n\t * Maximum graph nodes plus edges accepted by automatic layout.\n\t *\n\t * @defaultValue `5000`\n\t */\n\tmaxGraphElements?: number;\n};\n\nconst DEFAULT_MAX_IMPORT_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_MAX_GRAPH_ELEMENTS = 5_000;\nconst DEFAULT_BRANDING = 'ZenFG Inspector';\n\n/**\n * Browser lifecycle controller for one embeddable FrameGraph inspector.\n *\n * @remarks The constructor creates, but does not append, {@link dom}. Use\n * {@link mountFrameGraphInspector} for the common append-and-return workflow.\n * Async capture, import, and clipboard failures are reported in the UI. Call\n * {@link destroy} when the controller is no longer needed.\n *\n * @example\n * ```ts\n * const inspector = new FrameGraphInspector({ captureSnapshot: capture });\n * document.body.append(inspector.dom);\n * // Later:\n * inspector.destroy();\n * ```\n */\nexport class FrameGraphInspector {\n\t/** Root element owned by this inspector instance. */\n\treadonly dom = document.createElement('section');\n\tprivate readonly themeController = new InspectorThemeController(this.dom);\n\n\tprivate readonly body = document.createElement('div');\n\tprivate readonly content = document.createElement('div');\n\tprivate readonly dropOverlay = document.createElement('div');\n\tprivate readonly groupsButton: HTMLButtonElement;\n\tprivate readonly declarationsButton: HTMLButtonElement;\n\tprivate readonly collapseGroupsButton: HTMLButtonElement;\n\tprivate readonly graphView: GraphViewState;\n\tprivate readonly workbench: FrameGraphDebugWorkbench;\n\tprivate captureSnapshotCallback: FrameGraphInspectorOptions['captureSnapshot'];\n\tprivate protocolSnapshot: FrameGraphSnapshot | undefined;\n\tprivate operationRevision = 0;\n\tprivate viewModel: FrameGraphDebugViewModel | undefined;\n\tprivate selected: Selection | undefined;\n\tprivate hovered: Selection | undefined;\n\tprivate capturing = false;\n\tprivate importing = false;\n\tprivate copying = false;\n\tprivate copied = false;\n\tprivate initialAutoCaptureAttempted = false;\n\tprivate statusMessage: string | undefined;\n\tprivate statusTone: 'neutral' | 'error' = 'neutral';\n\tprivate destroyed = false;\n\tprivate copyFeedbackTimeout: number | undefined;\n\tprivate readonly maxImportBytes: number;\n\tprivate dragDepth = 0;\n\tprivate revealRevision = 0;\n\tprivate readonly handleDragEnter = (event: DragEvent): void => {\n\t\tif (!isFileDrag(event)) return;\n\t\tevent.preventDefault();\n\t\tthis.dragDepth += 1;\n\t\tthis.setDropActive(true);\n\t};\n\tprivate readonly handleDragOver = (event: DragEvent): void => {\n\t\tif (!isFileDrag(event)) return;\n\t\tevent.preventDefault();\n\t\tif (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n\t\tthis.setDropActive(true);\n\t};\n\tprivate readonly handleDragLeave = (event: DragEvent): void => {\n\t\tif (!isFileDrag(event) && this.dragDepth === 0) return;\n\t\tthis.dragDepth = Math.max(0, this.dragDepth - 1);\n\t\tif (this.dragDepth === 0) this.setDropActive(false);\n\t};\n\tprivate readonly handleDragEnd = (): void => this.clearDropState();\n\tprivate readonly handleDrop = (event: DragEvent): void => {\n\t\tconst file = event.dataTransfer?.files?.[0];\n\t\tif (!file) return;\n\t\tevent.preventDefault();\n\t\tthis.clearDropState();\n\t\tvoid this.importSnapshot(file);\n\t};\n\n\t/**\n\t * Creates a detached inspector UI.\n\t *\n\t * @throws If a configured numeric limit is not a non-negative safe integer,\n\t * or if browser DOM globals are unavailable.\n\t */\n\tconstructor(options: FrameGraphInspectorOptions = {}) {\n\t\tensureFrameGraphInspectorStyles();\n\t\tthis.captureSnapshotCallback = options.captureSnapshot;\n\t\tthis.maxImportBytes = normalizeMaxImportBytes(options.maxImportBytes);\n\t\tconst branding = options.branding ?? DEFAULT_BRANDING;\n\t\tthis.dom.className = 'zenfg-inspector';\n\t\tthis.dom.id = createInspectorId();\n\t\tthis.dom.setAttribute('role', 'region');\n\t\tthis.dom.setAttribute('aria-label', branding === false ? DEFAULT_BRANDING : branding);\n\t\tthis.body.className = 'zenfg-inspector-body';\n\t\tthis.content.className = 'zenfg-inspector-content';\n\t\tthis.dropOverlay.className = 'zenfg-inspector-drop-overlay';\n\t\tthis.dropOverlay.hidden = true;\n\t\tthis.dropOverlay.setAttribute('aria-hidden', 'true');\n\t\tconst dropTitle = document.createElement('strong');\n\t\tdropTitle.textContent = 'Drop snapshot to open';\n\t\tconst dropDetail = document.createElement('span');\n\t\tdropDetail.textContent = 'The first file will be imported locally.';\n\t\tthis.dropOverlay.append(dropTitle, dropDetail);\n\n\t\tconst graphLegend = document.createElement('div');\n\t\tgraphLegend.className = 'zenfg-inspector-graph-legend';\n\t\tgraphLegend.setAttribute('aria-label', 'Graph legend');\n\t\tthis.graphView = {\n\t\t\thost: document.createElement('div'),\n\t\t\ttoolbar: document.createElement('div'),\n\t\t\tlegend: graphLegend,\n\t\t\trefreshTheme: () => this.refreshTheme(),\n\t\t\tlayoutElementBudget: normalizeLimit(options.maxGraphElements, DEFAULT_MAX_GRAPH_ELEMENTS, 'maxGraphElements'),\n\t\t\tgroupsEnabled: true,\n\t\t\tshowResourceDeclarations: true,\n\t\t\texpandedGroupPaths: new Set(),\n\t\t\tfitOnNextRender: true,\n\t\t};\n\t\tthis.graphView.host.className = 'zenfg-inspector-graph';\n\t\tthis.graphView.toolbar.className = 'zenfg-inspector-graph-toolbar';\n\t\tthis.graphView.toolbar.setAttribute('role', 'toolbar');\n\t\tthis.graphView.toolbar.setAttribute('aria-label', 'Frame graph view controls');\n\n\t\tthis.declarationsButton = createToolbarButton('Declarations', 'Show resource declaration nodes', () => this.toggleDeclarations());\n\t\tthis.groupsButton = createToolbarButton('Groups', 'Toggle diagnostic group projection', () => this.toggleGroups());\n\t\tthis.collapseGroupsButton = createToolbarButton('Collapse All', 'Collapse every diagnostic group', () => this.collapseAllGroups());\n\n\t\tconst actionControls = document.createElement('div');\n\t\tactionControls.className = 'zenfg-inspector-graph-action-controls';\n\t\tactionControls.append(\n\t\t\tthis.declarationsButton,\n\t\t\tthis.groupsButton,\n\t\t\tthis.collapseGroupsButton,\n\t\t\tcreateToolbarButton('Fit', 'Fit graph to view', () => fitGraph(this.graphView)),\n\t\t);\n\t\tthis.graphView.toolbar.append(actionControls);\n\n\t\tconst callbacks: WorkbenchCallbacks = {\n\t\t\tonSelect: (selection) => this.handleSelect(selection),\n\t\t\tonHover: (selection) => this.handleHover(selection),\n\t\t\tonGroupToggle: (pathKey) => this.toggleGroup(pathKey),\n\t\t\tisGroupExpanded: (pathKey) => this.graphView.expandedGroupPaths.has(pathKey),\n\t\t\tonReveal: (selection, tab) => this.handleReveal(selection, tab),\n\t\t\tonNavigate: (tab, filter) => this.workbench.navigate(tab, filter),\n\t\t};\n\t\tthis.workbench = new FrameGraphDebugWorkbench(this.graphView, callbacks, {\n\t\t\tonCapture: () => { void this.captureSnapshot(); },\n\t\t\tonImport: (file) => { void this.importSnapshot(file); },\n\t\t\tonDownload: () => this.downloadSnapshot(),\n\t\t\tonCopyJson: () => { void this.copySnapshotJson(); },\n\t\t}, {\n\t\t\tbranding,\n\t\t\tidPrefix: this.dom.id,\n\t\t});\n\t\tthis.content.append(this.workbench.root);\n\t\tthis.body.appendChild(this.content);\n\t\tthis.dom.append(this.body, this.dropOverlay);\n\t\tthis.dom.addEventListener('dragenter', this.handleDragEnter);\n\t\tthis.dom.addEventListener('dragover', this.handleDragOver);\n\t\tthis.dom.addEventListener('dragleave', this.handleDragLeave);\n\t\tthis.dom.addEventListener('dragend', this.handleDragEnd);\n\t\tthis.dom.addEventListener('drop', this.handleDrop);\n\t\tthis.updateCaptureActions();\n\t\tthis.updateGraphControls();\n\t\tthis.showEmptyState();\n\t\tif (options.theme) this.setTheme(options.theme);\n\t\tqueueMicrotask(() => { if (!this.destroyed) { this.refreshTheme(); this.maybeAutoCapture(); } });\n\t}\n\n /** Replace API-applied variables on this instance, then synchronize graph styles.\n * Pass null to restore host CSS and defaults. Does not change capture or interaction state.\n */\n setTheme(theme: InspectorTheme | null): void {\n if (this.destroyed) return;\n this.themeController.apply(theme);\n this.refreshTheme();\n }\n\n /** Re-read final CSS values after external CSS changes and refresh graph and legend.\n * Does not write theme variables, recapture, fit, or rebuild the component.\n */\n refreshTheme(): void {\n if (this.destroyed) return;\n const theme = resolveGraphTheme(this.dom);\n this.graphView.theme = theme;\n this.graphView.renderer?.setTheme?.(theme);\n if (this.viewModel) renderGraphLegend(this.graphView.legend, this.viewModel, theme, this.graphView.showResourceDeclarations);\n }\n\n\t/**\n\t * Replaces or removes the live-capture provider.\n\t *\n\t * @remarks Installing a provider may immediately begin an asynchronous\n\t * capture when no snapshot is displayed. Replacing or removing a provider\n\t * invalidates its pending capture results without cancelling the provider\n\t * promise. An already displayed snapshot and any pending import are preserved.\n\t */\n\tsetCaptureSnapshotProvider(provider: FrameGraphInspectorOptions['captureSnapshot']): void {\n\t\tif (this.destroyed || this.captureSnapshotCallback === provider) return;\n\t\tif (this.capturing) {\n\t\t\tthis.operationRevision += 1;\n\t\t\tthis.capturing = false;\n\t\t}\n\t\tthis.captureSnapshotCallback = provider;\n\t\tif (!this.viewModel) this.initialAutoCaptureAttempted = false;\n\t\tif (!provider && !this.viewModel && !this.importing) this.showEmptyState();\n\t\tthis.updateCaptureActions();\n\t\tthis.maybeAutoCapture();\n\t}\n\n\t/**\n\t * Requests and displays a live snapshot from the configured provider.\n\t *\n\t * @remarks Concurrent requests are coalesced. Provider errors, invalid\n\t * snapshots, and an unavailable provider are displayed in the inspector and\n\t * do not reject the returned promise.\n\t */\n\tasync captureSnapshot(): Promise<void> {\n\t\tif (this.destroyed || this.capturing) return;\n\t\tif (!this.captureSnapshotCallback) {\n\t\t\tthis.reportCaptureIssue('Waiting for a FrameGraph capture source.');\n\t\t\treturn;\n\t\t}\n\t\tconst revision = ++this.operationRevision;\n\t\tthis.importing = false;\n\t\tthis.capturing = true;\n\t\tthis.statusMessage = undefined;\n\t\tthis.statusTone = 'neutral';\n\t\tif (!this.viewModel) this.workbench.showEmptyState('capturing', 'Capturing the next rendered frame…');\n\t\tthis.updateCaptureActions();\n\t\ttry {\n\t\t\tconst request: FrameGraphCaptureRequest = { timing: 'both' };\n\t\t\tconst snapshot = await this.captureSnapshotCallback(request);\n\t\t\tif (this.destroyed || revision !== this.operationRevision) return;\n\t\t\tif (!snapshot) {\n\t\t\t\tthis.reportCaptureIssue('No snapshot was produced. Capture again when rendering is active.');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst decoded = decodeFrameGraphSnapshot(snapshot);\n\t\t\tif (!decoded.ok) {\n\t\t\t\tthis.reportCaptureIssue(`Failed to capture FrameGraph: ${formatIssues(decoded.issues)}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.applySnapshot(decoded.snapshot, { kind: 'live', label: 'Live Capture' });\n\t\t}\n\t\tcatch (error) {\n\t\t\tif (!this.destroyed && revision === this.operationRevision) {\n\t\t\t\tthis.reportCaptureIssue(`Failed to capture FrameGraph: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\tif (revision === this.operationRevision) this.capturing = false;\n\t\t\tif (!this.destroyed && revision === this.operationRevision) this.updateCaptureActions();\n\t\t}\n\t}\n\n\t/**\n\t * Validates and synchronously displays a programmatic Snapshot 1.2 value.\n\t *\n\t * @throws {@link @zenfg/snapshot!index.FrameGraphSnapshotValidationError | FrameGraphSnapshotValidationError} if `snapshot` is invalid.\n\t */\n\tsetSnapshot(snapshot: FrameGraphSnapshot): void {\n\t\tif (this.destroyed) return;\n\t\tthis.operationRevision += 1;\n\t\tthis.capturing = false;\n\t\tthis.importing = false;\n\t\tconst decoded = decodeFrameGraphSnapshot(snapshot);\n\t\tif (!decoded.ok) throw new FrameGraphSnapshotValidationError(decoded.issues);\n\t\tthis.applySnapshot(decoded.snapshot, { kind: 'programmatic', label: 'Programmatic' });\n\t}\n\n\t/** Returns the currently displayed canonical snapshot, if any. */\n\tgetSnapshot(): FrameGraphSnapshot | undefined {\n\t\treturn this.protocolSnapshot;\n\t}\n\n\t/**\n\t * Reads, migrates, validates, and displays a snapshot JSON file.\n\t *\n\t * @remarks Files above `maxImportBytes`, read failures, invalid JSON, and\n\t * validation failures are displayed in the UI and do not reject the promise.\n\t */\n\tasync importSnapshot(file: File): Promise<void> {\n\t\tif (this.destroyed) return;\n\t\tconst revision = ++this.operationRevision;\n\t\tthis.capturing = false;\n\t\tthis.importing = false;\n\t\tif (file.size > this.maxImportBytes) {\n\t\t\tthis.reportCaptureIssue(`Import exceeds the ${formatImportLimit(this.maxImportBytes)} limit.`);\n\t\t\treturn;\n\t\t}\n\t\tthis.importing = true;\n\t\tthis.statusMessage = undefined;\n\t\tthis.statusTone = 'neutral';\n\t\tthis.updateCaptureActions();\n\t\ttry {\n\t\t\tconst text = await file.text();\n\t\t\tif (this.destroyed || revision !== this.operationRevision) return;\n\t\t\tconst decoded = parseFrameGraphSnapshot(text);\n\t\t\tif (!decoded.ok) {\n\t\t\t\tthis.reportCaptureIssue(`Failed to import snapshot: ${formatIssues(decoded.issues)}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.applySnapshot(decoded.snapshot, {\n\t\t\t\tkind: 'file',\n\t\t\t\tlabel: file.name || 'Imported JSON',\n\t\t\t});\n\t\t\tconst sourceFormat = decoded.snapshot.capture.migration?.sourceFormat;\n\t\t\tif (sourceFormat) {\n\t\t\t\t// The current import format can differ from retained historical provenance.\n\t\t\t\tconst sourceLabel = {\n\t\t\t\t\t'legacy-v0': 'Legacy V0',\n\t\t\t\t\t'legacy-candidate-v1': 'Legacy Candidate V1',\n\t\t\t\t\t'snapshot-v1.1': 'Snapshot 1.1',\n\t\t\t\t}[decoded.migrated && decoded.source !== 'v1' ? decoded.source : sourceFormat];\n\t\t\t\tconst version = decoded.snapshot.version;\n\t\t\t\tconst targetLabel = `Snapshot ${version.major}.${version.minor}`;\n\t\t\t\tthis.statusMessage = decoded.migrated\n\t\t\t\t\t? `Imported ${sourceLabel} and migrated it to ZenFG ${targetLabel}.`\n\t\t\t\t\t: `Imported ${targetLabel} with ${sourceLabel} migration provenance.`;\n\t\t\t\tthis.statusTone = 'neutral';\n\t\t\t}\n\t\t}\n\t\tcatch (error) {\n\t\t\tif (!this.destroyed && revision === this.operationRevision) {\n\t\t\t\tthis.reportCaptureIssue(`Failed to import snapshot: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\tif (revision === this.operationRevision) this.importing = false;\n\t\t\tif (!this.destroyed && revision === this.operationRevision) this.updateCaptureActions();\n\t\t}\n\t}\n\n\t/** Downloads the displayed snapshot as pretty-printed canonical JSON. */\n\tdownloadSnapshot(): void {\n\t\tif (this.destroyed || !this.protocolSnapshot) return;\n\t\tconst json = stringifyFrameGraphSnapshot(this.protocolSnapshot, { pretty: true });\n\t\tconst url = URL.createObjectURL(new Blob([json], { type: 'application/json;charset=utf-8' }));\n\t\tconst anchor = document.createElement('a');\n\t\tanchor.href = url;\n\t\tanchor.download = `frame-graph-${this.protocolSnapshot.capture.frameIndex}.fgsnapshot.json`;\n\t\tanchor.click();\n\t\tURL.revokeObjectURL(url);\n\t}\n\n\t/**\n\t * Copies the displayed snapshot as pretty-printed canonical JSON.\n\t *\n\t * @remarks Clipboard failures are shown in the UI and do not reject the\n\t * returned promise. A legacy `document.execCommand` fallback is used when the\n\t * async Clipboard API is unavailable.\n\t */\n\tasync copySnapshotJson(): Promise<void> {\n\t\tif (this.destroyed || this.copying || !this.protocolSnapshot) return;\n\t\tconst snapshot = this.protocolSnapshot;\n\t\tconst revision = this.operationRevision;\n\t\tthis.copying = true;\n\t\tthis.copied = false;\n\t\tthis.statusMessage = undefined;\n\t\tthis.statusTone = 'neutral';\n\t\tthis.updateCaptureActions();\n\t\ttry {\n\t\t\tawait writeTextToClipboard(stringifyFrameGraphSnapshot(snapshot, { pretty: true }));\n\t\t\tif (this.destroyed || revision !== this.operationRevision) return;\n\t\t\tthis.copied = true;\n\t\t\tif (this.copyFeedbackTimeout !== undefined) window.clearTimeout(this.copyFeedbackTimeout);\n\t\t\tthis.copyFeedbackTimeout = window.setTimeout(() => {\n\t\t\t\tthis.copied = false;\n\t\t\t\tthis.copyFeedbackTimeout = undefined;\n\t\t\t\tthis.updateCaptureActions();\n\t\t\t}, 1200);\n\t\t}\n\t\tcatch (error) {\n\t\t\tif (!this.destroyed && revision === this.operationRevision) {\n\t\t\t\tthis.statusMessage = `Failed to copy snapshot: ${error instanceof Error ? error.message : String(error)}`;\n\t\t\t}\n\t\t\tconsole.warn('Failed to copy FrameGraph Snapshot.', error);\n\t\t}\n\t\tfinally {\n\t\t\tthis.copying = false;\n\t\t\tif (!this.destroyed) this.updateCaptureActions();\n\t\t}\n\t}\n\n\tprivate applySnapshot(snapshot: FrameGraphSnapshot, source: FrameGraphDebugSnapshotSource): void {\n\t\tconst viewModel = createDebugViewModel(snapshot, source);\n\t\tthis.copied = false;\n\t\tif (this.copyFeedbackTimeout !== undefined) {\n\t\t\twindow.clearTimeout(this.copyFeedbackTimeout);\n\t\t\tthis.copyFeedbackTimeout = undefined;\n\t\t}\n\t\tthis.protocolSnapshot = snapshot;\n\t\tthis.viewModel = viewModel;\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.graphView.captureRevision = (this.graphView.captureRevision ?? 0) + 1;\n\t\tthis.graphView.revealOnNextRender = undefined;\n\t\tthis.graphView.renderer?.cancelReveal?.();\n\t\tthis.hovered = undefined;\n\t\tthis.initialAutoCaptureAttempted = true;\n\t\tthis.statusMessage = undefined;\n\t\tthis.statusTone = 'neutral';\n\t\tif (this.selected?.kind === 'node' || this.selected?.kind === 'culled') this.selected = resolveNodeSelection(viewModel, this.selected.id);\n\t\telse if (this.selected && !selectionExists(viewModel, this.selected)) this.selected = undefined;\n\t\tthis.workbench.setSnapshot(viewModel, this.selected);\n\t\tthis.updateCaptureActions();\n\t\tthis.updateGraphControls();\n\t}\n\n\t/**\n\t * Idempotently cancels pending UI results, releases graph resources, and\n\t * removes the inspector workbench. Do not reuse the controller afterward.\n\t */\n\tdestroy(): void {\n\t\tif (this.destroyed) return;\n\t\tthis.destroyed = true;\n\t\tthis.operationRevision += 1;\n\t\tif (this.copyFeedbackTimeout !== undefined) window.clearTimeout(this.copyFeedbackTimeout);\n\t\tthis.clearDropState();\n\t\tthis.dom.removeEventListener('dragenter', this.handleDragEnter);\n\t\tthis.dom.removeEventListener('dragover', this.handleDragOver);\n\t\tthis.dom.removeEventListener('dragleave', this.handleDragLeave);\n\t\tthis.dom.removeEventListener('dragend', this.handleDragEnd);\n\t\tthis.dom.removeEventListener('drop', this.handleDrop);\n\t\tthis.themeController.destroy();\n\t\tdestroyGraph(this.graphView);\n\t\tthis.workbench.destroy();\n\t\tthis.dom.remove();\n\t}\n\n\tprivate updateCaptureActions(): void {\n\t\tthis.workbench.setSnapshotActionState({\n\t\t\tproviderAvailable: Boolean(this.captureSnapshotCallback),\n\t\t\thasCapture: Boolean(this.viewModel),\n\t\t\tcapturing: this.capturing,\n\t\t\timporting: this.importing,\n\t\t\tcopying: this.copying,\n\t\t\tcopied: this.copied,\n\t\t\tmessage: this.viewModel ? this.statusMessage : undefined,\n\t\t\tmessageTone: this.statusTone,\n\t\t});\n\t}\n\n\tprivate maybeAutoCapture(): void {\n\t\tif (\n\t\t\tthis.destroyed\n\t\t\t|| this.viewModel\n\t\t\t|| this.initialAutoCaptureAttempted\n\t\t\t|| this.capturing\n\t\t\t|| this.importing\n\t\t\t|| !this.captureSnapshotCallback\n\t\t) return;\n\t\tthis.initialAutoCaptureAttempted = true;\n\t\tvoid this.captureSnapshot();\n\t}\n\tprivate handleSelect(selection: Selection): void {\n\t\tif (!this.viewModel || !selectionExists(this.viewModel, selection)) return;\n\t\tthis.selected = selection;\n\t\tthis.workbench.setSelection(selection);\n\t}\n\n\tprivate handleReveal(selection: Selection, tab: WorkbenchTab): void {\n\t\tconst snapshot = this.viewModel;\n\t\tif (!snapshot || !selectionExists(snapshot, selection)) return;\n\t\tif (tab === 'graph') {\n\t\t\tconst expanded = new Set(this.graphView.expandedGroupPaths);\n\t\t\tconst groupsEnabled = this.graphView.groupsEnabled;\n\t\t\tconst showResourceDeclarations = this.graphView.showResourceDeclarations;\n\t\t\tif (selection.kind === 'resource') this.graphView.showResourceDeclarations = true;\n\t\t\tif (selection.kind === 'group') this.graphView.groupsEnabled = true;\n\t\t\tlet groupId: string | undefined;\n\t\t\tif (selection.kind === 'node') groupId = snapshot.nodeById.get(selection.id)?.debugGroupId;\n\t\t\telse if (selection.kind === 'resource') groupId = snapshot.resourceById.get(selection.id)?.debugGroupId;\n\t\t\telse if (selection.kind === 'group') groupId = snapshot.groupByPathKey.get(selection.pathKey)?.parentId;\n\t\t\tif (this.graphView.groupsEnabled && groupId) {\n\t\t\t\tfor (const id of snapshot.groupById.get(groupId)?.ancestorIds ?? []) {\n\t\t\t\t\tconst group = snapshot.groupById.get(id);\n\t\t\t\t\tif (group) this.graphView.expandedGroupPaths.add(group.pathKey);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst scene = resolveGraphScene(this.graphView, snapshot);\n\t\t\tconst availableIds = new Set([...scene.nodes, ...scene.edges].map((entry) => entry.id));\n\t\t\tif (!(scene.interaction.primaryElementIdsBySelection.get(selectionKey(selection))?.some((id) => availableIds.has(id)))) {\n\t\t\t\tthis.graphView.groupsEnabled = groupsEnabled;\n\t\t\t\tthis.graphView.showResourceDeclarations = showResourceDeclarations;\n\t\t\t\tthis.graphView.expandedGroupPaths.clear();\n\t\t\t\tfor (const path of expanded) this.graphView.expandedGroupPaths.add(path);\n\t\t\t\tthis.workbench.showNavigationIssue(selection.kind === 'culled' ? 'Culled passes are not part of Frame Flow.' : 'This object has no representation in Frame Flow.', selection);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.graphView.revealOnNextRender = { selection, revision: ++this.revealRevision };\n\t\t\tthis.updateGraphControls();\n\t\t}\n\t\tthis.handleSelect(selection);\n\t\tthis.workbench.reveal(selection, tab);\n\t}\n\n\tprivate handleHover(selection: Selection | undefined): void {\n\t\tif (!this.viewModel || sameSelection(this.hovered, selection)) return;\n\t\tthis.hovered = selection;\n\t\tthis.workbench.setHovered(selection);\n\t}\n\n\tprivate updateGraphControls(): void {\n\t\tconst showDeclarations = this.graphView.showResourceDeclarations ?? true;\n\t\tthis.declarationsButton.classList.toggle('active', showDeclarations);\n\t\tthis.declarationsButton.setAttribute('aria-pressed', String(showDeclarations));\n\t\tconst hasGroups = (this.viewModel?.debugGroups.length ?? 0) > 0;\n\t\tthis.groupsButton.disabled = !hasGroups;\n\t\tthis.groupsButton.hidden = !hasGroups;\n\t\tthis.collapseGroupsButton.hidden = !hasGroups;\n\t\tthis.groupsButton.classList.toggle('active', hasGroups && this.graphView.groupsEnabled);\n\t\tthis.groupsButton.setAttribute('aria-pressed', hasGroups && this.graphView.groupsEnabled ? 'true' : 'false');\n\t\tconst hasExpanded = this.viewModel?.debugGroups.some((group) => this.graphView.expandedGroupPaths.has(group.pathKey)) ?? false;\n\t\tthis.collapseGroupsButton.disabled = !hasGroups || !this.graphView.groupsEnabled || !hasExpanded;\n\t}\n\n\tprivate toggleDeclarations(): void {\n\t\tthis.handleHover(undefined);\n\t\tthis.graphView.showResourceDeclarations = !(this.graphView.showResourceDeclarations ?? true);\n\t\tthis.graphView.renderer?.cancelReveal?.();\n\t\tthis.graphView.revealOnNextRender = undefined;\n\t\tthis.graphView.anchorElementIdOnNextRender = undefined;\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.updateGraphControls();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate toggleGroups(): void {\n\t\tif (!this.viewModel?.debugGroups.length) return;\n\t\tthis.handleHover(undefined);\n\t\tthis.graphView.groupsEnabled = !this.graphView.groupsEnabled;\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.updateGraphControls();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate toggleGroup(pathKey: string): void {\n\t\tthis.handleHover(undefined);\n\t\tif (this.graphView.expandedGroupPaths.has(pathKey)) this.graphView.expandedGroupPaths.delete(pathKey);\n\t\telse this.graphView.expandedGroupPaths.add(pathKey);\n\t\tthis.graphView.anchorElementIdOnNextRender = graphGroupElementId(pathKey);\n\t\tthis.updateGraphControls();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate collapseAllGroups(): void {\n\t\tif (this.graphView.expandedGroupPaths.size === 0) return;\n\t\tthis.handleHover(undefined);\n\t\tthis.graphView.expandedGroupPaths.clear();\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.updateGraphControls();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate showEmptyState(): void {\n\t\tconst providerAvailable = Boolean(this.captureSnapshotCallback);\n\t\tthis.workbench.showEmptyState(\n\t\t\t'empty',\n\t\t\tproviderAvailable\n\t\t\t\t? 'No capture yet. Use Capture to request the next rendered frame.'\n\t\t\t\t: 'Drop a ZenFG Snapshot here or choose Import.',\n\t\t\tproviderAvailable ? undefined : 'Files are processed locally in your browser.',\n\t\t);\n\t}\n\n\tprivate setDropActive(active: boolean): void {\n\t\tif (this.destroyed) return;\n\t\tthis.dropOverlay.hidden = !active;\n\t\tthis.dom.classList.toggle('drop-active', active);\n\t}\n\n\tprivate clearDropState(): void {\n\t\tthis.dragDepth = 0;\n\t\tthis.dropOverlay.hidden = true;\n\t\tthis.dom.classList.remove('drop-active');\n\t}\n\n\tprivate reportCaptureIssue(message: string): void {\n\t\tthis.statusMessage = message;\n\t\tthis.statusTone = 'error';\n\t\tif (!this.viewModel) this.workbench.showEmptyState('error', message);\n\t\tthis.updateCaptureActions();\n\t}\n}\n\n/**\n * Creates an inspector, appends its root element to `host`, and returns its\n * lifecycle controller.\n *\n * @throws If inspector construction fails; see {@link FrameGraphInspector}.\n */\nexport function mountFrameGraphInspector(host: HTMLElement, options?: FrameGraphInspectorOptions): FrameGraphInspector {\n\tconst inspector = new FrameGraphInspector(options);\n\thost.appendChild(inspector.dom);\n\tinspector.refreshTheme();\n\treturn inspector;\n}\n\nasync function writeTextToClipboard(text: string): Promise<void> {\n\tif (navigator.clipboard?.writeText) {\n\t\tawait navigator.clipboard.writeText(text);\n\t\treturn;\n\t}\n\tconst textArea = document.createElement('textarea');\n\ttextArea.value = text;\n\ttextArea.setAttribute('readonly', 'true');\n\ttextArea.style.position = 'fixed';\n\ttextArea.style.left = '-9999px';\n\ttextArea.style.top = '0';\n\tdocument.body.appendChild(textArea);\n\ttextArea.select();\n\ttry {\n\t\tif (!document.execCommand('copy')) throw new Error('document.execCommand(\"copy\") returned false.');\n\t}\n\tfinally {\n\t\ttextArea.remove();\n\t}\n}\n\nfunction normalizeMaxImportBytes(value: number | undefined): number {\n\treturn normalizeLimit(value, DEFAULT_MAX_IMPORT_BYTES, 'maxImportBytes');\n}\n\nfunction normalizeLimit(value: number | undefined, fallback: number, name: string): number {\n\tif (value === undefined) return fallback;\n\tif (!Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new Error(`${name} must be a non-negative safe integer.`);\n\t}\n\treturn value;\n}\n\nfunction formatImportLimit(bytes: number): string {\n\treturn bytes >= 1024 * 1024 && bytes % (1024 * 1024) === 0\n\t\t? `${bytes / (1024 * 1024)} MiB`\n\t\t: `${bytes} bytes`;\n}\n\nfunction formatIssues(issues: readonly { readonly path: string; readonly message: string }[]): string {\n\treturn issues.map((issue) => `${issue.path || '/'}: ${issue.message}`).join('\\n');\n}\n\nfunction isFileDrag(event: DragEvent): boolean {\n\treturn Array.from(event.dataTransfer?.types ?? []).includes('Files');\n}\n\nlet nextInspectorId = 0;\nfunction createInspectorId(): string {\n\tnextInspectorId += 1;\n\treturn `zenfg-inspector-${nextInspectorId}`;\n}\n"]}
@@ -0,0 +1,5 @@
1
+ /** Requested timing families for the next live capture; never changes imported data. */
2
+ export type FrameGraphCaptureRequest = {
3
+ readonly timing: 'cpu' | 'gpu' | 'both';
4
+ };
5
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;CACxC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"","sourcesContent":["/** Requested timing families for the next live capture; never changes imported data. */\nexport type FrameGraphCaptureRequest = {\n\treadonly timing: 'cpu' | 'gpu' | 'both';\n};\n"]}
@@ -34,6 +34,7 @@ export type FrameGraphDebugNode = {
34
34
  readonly sideEffect: boolean;
35
35
  readonly debugGroupId?: string;
36
36
  readonly gpuDurationMicros?: number;
37
+ readonly cpuDurationMicros?: number;
37
38
  readonly reads: readonly FrameGraphDebugAccess[];
38
39
  readonly writes: readonly FrameGraphDebugAccess[];
39
40
  };
@@ -87,6 +88,8 @@ export type FrameGraphDebugGroupSummary = {
87
88
  readonly externalSubmissionCount: number;
88
89
  readonly gpuWorkDurationMicros: number;
89
90
  readonly timedNodeCount: number;
91
+ readonly cpuTimedNodeCount: number;
92
+ readonly cpuWorkDurationMicros: number;
90
93
  readonly timingEligibleNodeCount: number;
91
94
  };
92
95
  export type FrameGraphDebugGroup = {
@@ -104,12 +107,23 @@ export type FrameGraphDebugGroup = {
104
107
  export type FrameGraphDebugMetrics = {
105
108
  readonly timingEligibleNodeCount: number;
106
109
  readonly timedNodeCount: number;
110
+ readonly cpuTimedNodeCount: number;
111
+ readonly cpuWorkDurationMicros: number;
107
112
  readonly slowestNode?: FrameGraphDebugNode;
108
113
  readonly transientEstimatedByteSize?: number;
109
114
  readonly logicalCapacityBytes?: number;
110
115
  readonly physicalEstimatedBytes?: number;
111
116
  readonly aliasReuseBytes?: number;
112
117
  readonly aliasedAllocationCount: number;
118
+ readonly estimatedCoverage: {
119
+ readonly transient: EstimateCoverage;
120
+ readonly logical: EstimateCoverage;
121
+ readonly physical: EstimateCoverage;
122
+ };
123
+ };
124
+ export type EstimateCoverage = {
125
+ readonly known: number;
126
+ readonly total: number;
113
127
  };
114
128
  export type FrameGraphDebugSnapshotSource = {
115
129
  readonly kind: 'live' | 'file' | 'programmatic';
@@ -131,6 +145,10 @@ export type FrameGraphDebugViewModel = {
131
145
  readonly executionSegments: readonly FrameGraphDebugExecutionSegment[];
132
146
  readonly textureViewById: ReadonlyMap<string, FrameGraphSnapshot['graph']['textureViews'][number]>;
133
147
  readonly nodeById: ReadonlyMap<string, FrameGraphDebugNode>;
148
+ readonly canonicalNodeById: ReadonlyMap<string, FrameGraphSnapshot['graph']['nodes'][number]>;
149
+ readonly culledById: ReadonlyMap<string, FrameGraphDebugCulledNode>;
150
+ readonly diagnosticsByNodeId: ReadonlyMap<string, readonly FrameGraphSnapshot['diagnostics'][number][]>;
151
+ readonly diagnosticsByResourceId: ReadonlyMap<string, readonly FrameGraphSnapshot['diagnostics'][number][]>;
134
152
  readonly resourceById: ReadonlyMap<string, FrameGraphDebugResource>;
135
153
  readonly groupById: ReadonlyMap<string, FrameGraphDebugGroup>;
136
154
  readonly groupByPathKey: ReadonlyMap<string, FrameGraphDebugGroup>;
@@ -140,6 +158,7 @@ export type FrameGraphDebugViewModel = {
140
158
  readonly segmentByNodeId: ReadonlyMap<string, FrameGraphDebugExecutionSegment>;
141
159
  readonly segmentByIndex: ReadonlyMap<number, FrameGraphDebugExecutionSegment>;
142
160
  readonly metrics: FrameGraphDebugMetrics;
161
+ readonly cpuProfiling: FrameGraphSnapshot['timings']['cpu'];
143
162
  readonly profiling: {
144
163
  readonly status: 'available';
145
164
  readonly frameIndex: number;