@zenfg/inspector 0.1.0-beta.2 → 0.1.0-beta.4

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 +60 -26
  3. package/THEMING.md +124 -0
  4. package/dist/FrameGraphInspector.d.ts +24 -8
  5. package/dist/FrameGraphInspector.d.ts.map +1 -1
  6. package/dist/FrameGraphInspector.js +151 -65
  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 +28 -4
  13. package/dist/debugCaptureModel.d.ts.map +1 -1
  14. package/dist/debugCaptureModel.js +72 -16
  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 +18 -3
  24. package/dist/panelCytoscapeGraphRenderer.d.ts.map +1 -1
  25. package/dist/panelCytoscapeGraphRenderer.js +183 -41
  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 +167 -58
  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 +20 -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 +15 -26
  50. package/dist/panelGraphScene.d.ts.map +1 -1
  51. package/dist/panelGraphScene.js +191 -208
  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 +42 -9
  60. package/dist/panelGraphView.js.map +1 -1
  61. package/dist/panelGraphVisuals.d.ts +18 -6
  62. package/dist/panelGraphVisuals.d.ts.map +1 -1
  63. package/dist/panelGraphVisuals.js +156 -116
  64. package/dist/panelGraphVisuals.js.map +1 -1
  65. package/dist/panelInspectorView.d.ts +13 -0
  66. package/dist/panelInspectorView.d.ts.map +1 -1
  67. package/dist/panelInspectorView.js +326 -46
  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 +36 -6
  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 +18 -4
  102. package/dist/panelTypes.d.ts.map +1 -1
  103. package/dist/panelTypes.js.map +1 -1
  104. package/dist/panelVisualTheme.d.ts +176 -71
  105. package/dist/panelVisualTheme.d.ts.map +1 -1
  106. package/dist/panelVisualTheme.js +34 -36
  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 +63 -2
  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 +161 -205
  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 +145 -68
  139. package/src/capture.ts +4 -0
  140. package/src/debugCaptureModel.ts +97 -21
  141. package/src/index.ts +6 -2
  142. package/src/panelAliasAnalysis.ts +24 -70
  143. package/src/panelCytoscapeGraphRenderer.ts +177 -40
  144. package/src/panelDetailLayout.ts +155 -0
  145. package/src/panelDetailStyles.ts +56 -0
  146. package/src/panelDiagnosticsView.ts +167 -86
  147. package/src/panelDomHelpers.ts +4 -5
  148. package/src/panelGraphLayout.ts +20 -5
  149. package/src/panelGraphRenderer.ts +7 -0
  150. package/src/panelGraphScene.ts +204 -292
  151. package/src/panelGraphSearch.ts +96 -0
  152. package/src/panelGraphView.ts +41 -9
  153. package/src/panelGraphVisuals.ts +152 -118
  154. package/src/panelInspectorView.ts +315 -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 +39 -7
  162. package/src/panelTheme.ts +85 -0
  163. package/src/panelTypes.ts +16 -4
  164. package/src/panelVisualTheme.ts +38 -38
  165. package/src/panelWorkbenchHelpers.ts +62 -4
  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 +162 -205
  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,12 +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
- passesGraphModeButton;
37
- resourcesGraphModeButton;
38
37
  groupsButton;
38
+ declarationsButton;
39
39
  collapseGroupsButton;
40
40
  graphView;
41
41
  workbench;
@@ -56,6 +56,7 @@ export class FrameGraphInspector {
56
56
  copyFeedbackTimeout;
57
57
  maxImportBytes;
58
58
  dragDepth = 0;
59
+ revealRevision = 0;
59
60
  handleDragEnter = (event) => {
60
61
  if (!isFileDrag(event))
61
62
  return;
@@ -119,9 +120,10 @@ export class FrameGraphInspector {
119
120
  host: document.createElement('div'),
120
121
  toolbar: document.createElement('div'),
121
122
  legend: graphLegend,
123
+ refreshTheme: () => this.refreshTheme(),
122
124
  layoutElementBudget: normalizeLimit(options.maxGraphElements, DEFAULT_MAX_GRAPH_ELEMENTS, 'maxGraphElements'),
123
- graphMode: 'passes',
124
125
  groupsEnabled: true,
126
+ showResourceDeclarations: true,
125
127
  expandedGroupPaths: new Set(),
126
128
  fitOnNextRender: true,
127
129
  };
@@ -129,26 +131,20 @@ export class FrameGraphInspector {
129
131
  this.graphView.toolbar.className = 'zenfg-inspector-graph-toolbar';
130
132
  this.graphView.toolbar.setAttribute('role', 'toolbar');
131
133
  this.graphView.toolbar.setAttribute('aria-label', 'Frame graph view controls');
132
- this.passesGraphModeButton = createToolbarButton('Pass dependency', 'Show pass dependency graph', () => this.setGraphMode('passes'));
133
- this.resourcesGraphModeButton = createToolbarButton('Resource access', 'Show resource access graph', () => this.setGraphMode('resources'));
134
+ this.declarationsButton = createToolbarButton('Declarations', 'Show resource declaration nodes', () => this.toggleDeclarations());
134
135
  this.groupsButton = createToolbarButton('Groups', 'Toggle diagnostic group projection', () => this.toggleGroups());
135
136
  this.collapseGroupsButton = createToolbarButton('Collapse All', 'Collapse every diagnostic group', () => this.collapseAllGroups());
136
- this.passesGraphModeButton.classList.add('zenfg-inspector-mode-button');
137
- this.resourcesGraphModeButton.classList.add('zenfg-inspector-mode-button');
138
- const modeControls = document.createElement('div');
139
- modeControls.className = 'zenfg-inspector-graph-mode-controls';
140
- modeControls.setAttribute('role', 'group');
141
- modeControls.setAttribute('aria-label', 'Graph mode');
142
- modeControls.append(this.passesGraphModeButton, this.resourcesGraphModeButton);
143
137
  const actionControls = document.createElement('div');
144
138
  actionControls.className = 'zenfg-inspector-graph-action-controls';
145
- actionControls.append(this.groupsButton, this.collapseGroupsButton, createGraphIconButton('fit', 'Fit graph to view', () => fitGraph(this.graphView)));
146
- this.graphView.toolbar.append(modeControls, 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);
147
141
  const callbacks = {
148
142
  onSelect: (selection) => this.handleSelect(selection),
149
143
  onHover: (selection) => this.handleHover(selection),
150
144
  onGroupToggle: (pathKey) => this.toggleGroup(pathKey),
151
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),
152
148
  };
153
149
  this.workbench = new FrameGraphDebugWorkbench(this.graphView, callbacks, {
154
150
  onCapture: () => { void this.captureSnapshot(); },
@@ -168,22 +164,55 @@ export class FrameGraphInspector {
168
164
  this.dom.addEventListener('dragend', this.handleDragEnd);
169
165
  this.dom.addEventListener('drop', this.handleDrop);
170
166
  this.updateCaptureActions();
171
- this.updateGraphModeButtonState();
167
+ this.updateGraphControls();
172
168
  this.showEmptyState();
173
- 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);
174
196
  }
175
197
  /**
176
198
  * Replaces or removes the live-capture provider.
177
199
  *
178
200
  * @remarks Installing a provider may immediately begin an asynchronous
179
- * 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.
180
204
  */
181
205
  setCaptureSnapshotProvider(provider) {
182
- 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
+ }
183
212
  this.captureSnapshotCallback = provider;
184
- if (changed && !this.viewModel)
213
+ if (!this.viewModel)
185
214
  this.initialAutoCaptureAttempted = false;
186
- if (!provider && !this.viewModel)
215
+ if (!provider && !this.viewModel && !this.importing)
187
216
  this.showEmptyState();
188
217
  this.updateCaptureActions();
189
218
  this.maybeAutoCapture();
@@ -211,7 +240,8 @@ export class FrameGraphInspector {
211
240
  this.workbench.showEmptyState('capturing', 'Capturing the next rendered frame…');
212
241
  this.updateCaptureActions();
213
242
  try {
214
- const snapshot = await this.captureSnapshotCallback();
243
+ const request = { timing: 'both' };
244
+ const snapshot = await this.captureSnapshotCallback(request);
215
245
  if (this.destroyed || revision !== this.operationRevision)
216
246
  return;
217
247
  if (!snapshot) {
@@ -238,9 +268,9 @@ export class FrameGraphInspector {
238
268
  }
239
269
  }
240
270
  /**
241
- * Validates and synchronously displays a programmatic Snapshot 1.0 value.
271
+ * Validates and synchronously displays a programmatic Snapshot 1.2 value.
242
272
  *
243
- * @throws {@link FrameGraphSnapshotValidationError} if `snapshot` is invalid.
273
+ * @throws {@link @zenfg/snapshot!index.FrameGraphSnapshotValidationError | FrameGraphSnapshotValidationError} if `snapshot` is invalid.
244
274
  */
245
275
  setSnapshot(snapshot) {
246
276
  if (this.destroyed)
@@ -292,10 +322,17 @@ export class FrameGraphInspector {
292
322
  });
293
323
  const sourceFormat = decoded.snapshot.capture.migration?.sourceFormat;
294
324
  if (sourceFormat) {
295
- 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}`;
296
333
  this.statusMessage = decoded.migrated
297
- ? `Imported ${sourceLabel} and migrated it to ZenFG Snapshot V1.`
298
- : `Imported Snapshot V1 with ${sourceLabel} migration provenance.`;
334
+ ? `Imported ${sourceLabel} and migrated it to ZenFG ${targetLabel}.`
335
+ : `Imported ${targetLabel} with ${sourceLabel} migration provenance.`;
299
336
  this.statusTone = 'neutral';
300
337
  }
301
338
  }
@@ -375,18 +412,20 @@ export class FrameGraphInspector {
375
412
  this.protocolSnapshot = snapshot;
376
413
  this.viewModel = viewModel;
377
414
  this.graphView.fitOnNextRender = true;
415
+ this.graphView.captureRevision = (this.graphView.captureRevision ?? 0) + 1;
416
+ this.graphView.revealOnNextRender = undefined;
417
+ this.graphView.renderer?.cancelReveal?.();
378
418
  this.hovered = undefined;
379
419
  this.initialAutoCaptureAttempted = true;
380
420
  this.statusMessage = undefined;
381
421
  this.statusTone = 'neutral';
382
- if (!this.selected || !selectionExists(viewModel, this.selected)) {
383
- this.selected = viewModel.nodes[0]
384
- ? { kind: 'node', id: viewModel.nodes[0].id }
385
- : undefined;
386
- }
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;
387
426
  this.workbench.setSnapshot(viewModel, this.selected);
388
427
  this.updateCaptureActions();
389
- this.updateGraphModeButtonState();
428
+ this.updateGraphControls();
390
429
  }
391
430
  /**
392
431
  * Idempotently cancels pending UI results, releases graph resources, and
@@ -405,7 +444,9 @@ export class FrameGraphInspector {
405
444
  this.dom.removeEventListener('dragleave', this.handleDragLeave);
406
445
  this.dom.removeEventListener('dragend', this.handleDragEnd);
407
446
  this.dom.removeEventListener('drop', this.handleDrop);
447
+ this.themeController.destroy();
408
448
  destroyGraph(this.graphView);
449
+ this.workbench.destroy();
409
450
  this.dom.remove();
410
451
  }
411
452
  updateCaptureActions() {
@@ -432,59 +473,109 @@ export class FrameGraphInspector {
432
473
  void this.captureSnapshot();
433
474
  }
434
475
  handleSelect(selection) {
476
+ if (!this.viewModel || !selectionExists(this.viewModel, selection))
477
+ return;
435
478
  this.selected = selection;
436
479
  this.workbench.setSelection(selection);
437
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
+ }
438
524
  handleHover(selection) {
439
525
  if (!this.viewModel || sameSelection(this.hovered, selection))
440
526
  return;
441
527
  this.hovered = selection;
442
528
  this.workbench.setHovered(selection);
443
529
  }
444
- setGraphMode(mode) {
445
- if (this.graphView.graphMode === mode)
446
- return;
447
- this.graphView.graphMode = mode;
448
- this.graphView.fitOnNextRender = true;
449
- this.updateGraphModeButtonState();
450
- this.workbench.refreshGraphStructure();
451
- }
452
- updateGraphModeButtonState() {
453
- const passesActive = this.graphView.graphMode === 'passes';
530
+ updateGraphControls() {
531
+ const showDeclarations = this.graphView.showResourceDeclarations ?? true;
532
+ this.declarationsButton.classList.toggle('active', showDeclarations);
533
+ this.declarationsButton.setAttribute('aria-pressed', String(showDeclarations));
454
534
  const hasGroups = (this.viewModel?.debugGroups.length ?? 0) > 0;
455
- this.passesGraphModeButton.classList.toggle('active', passesActive);
456
- this.resourcesGraphModeButton.classList.toggle('active', !passesActive);
457
- this.passesGraphModeButton.setAttribute('aria-pressed', passesActive ? 'true' : 'false');
458
- this.resourcesGraphModeButton.setAttribute('aria-pressed', passesActive ? 'false' : 'true');
459
- this.groupsButton.disabled = !passesActive || !hasGroups;
460
- this.groupsButton.classList.toggle('active', passesActive && hasGroups && this.graphView.groupsEnabled);
461
- this.groupsButton.setAttribute('aria-pressed', passesActive && hasGroups && this.graphView.groupsEnabled ? 'true' : 'false');
535
+ this.groupsButton.disabled = !hasGroups;
536
+ this.groupsButton.hidden = !hasGroups;
537
+ this.collapseGroupsButton.hidden = !hasGroups;
538
+ this.groupsButton.classList.toggle('active', hasGroups && this.graphView.groupsEnabled);
539
+ this.groupsButton.setAttribute('aria-pressed', hasGroups && this.graphView.groupsEnabled ? 'true' : 'false');
462
540
  const hasExpanded = this.viewModel?.debugGroups.some((group) => this.graphView.expandedGroupPaths.has(group.pathKey)) ?? false;
463
- this.collapseGroupsButton.disabled = !passesActive || !hasGroups || !this.graphView.groupsEnabled || !hasExpanded;
541
+ this.collapseGroupsButton.disabled = !hasGroups || !this.graphView.groupsEnabled || !hasExpanded;
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();
464
552
  }
465
553
  toggleGroups() {
466
- if (this.graphView.graphMode !== 'passes' || !this.viewModel?.debugGroups.length)
554
+ if (!this.viewModel?.debugGroups.length)
467
555
  return;
556
+ this.handleHover(undefined);
468
557
  this.graphView.groupsEnabled = !this.graphView.groupsEnabled;
469
558
  this.graphView.fitOnNextRender = true;
470
- this.updateGraphModeButtonState();
559
+ this.updateGraphControls();
471
560
  this.workbench.refreshGraphStructure();
472
561
  }
473
562
  toggleGroup(pathKey) {
563
+ this.handleHover(undefined);
474
564
  if (this.graphView.expandedGroupPaths.has(pathKey))
475
565
  this.graphView.expandedGroupPaths.delete(pathKey);
476
566
  else
477
567
  this.graphView.expandedGroupPaths.add(pathKey);
478
568
  this.graphView.anchorElementIdOnNextRender = graphGroupElementId(pathKey);
479
- this.updateGraphModeButtonState();
569
+ this.updateGraphControls();
480
570
  this.workbench.refreshGraphStructure();
481
571
  }
482
572
  collapseAllGroups() {
483
573
  if (this.graphView.expandedGroupPaths.size === 0)
484
574
  return;
575
+ this.handleHover(undefined);
485
576
  this.graphView.expandedGroupPaths.clear();
486
577
  this.graphView.fitOnNextRender = true;
487
- this.updateGraphModeButtonState();
578
+ this.updateGraphControls();
488
579
  this.workbench.refreshGraphStructure();
489
580
  }
490
581
  showEmptyState() {
@@ -521,14 +612,9 @@ export class FrameGraphInspector {
521
612
  export function mountFrameGraphInspector(host, options) {
522
613
  const inspector = new FrameGraphInspector(options);
523
614
  host.appendChild(inspector.dom);
615
+ inspector.refreshTheme();
524
616
  return inspector;
525
617
  }
526
- function createGraphIconButton(icon, title, onClick) {
527
- const button = createToolbarButton('', title, onClick);
528
- button.classList.add('zenfg-inspector-icon-button');
529
- button.appendChild(createPanelIcon(icon));
530
- return button;
531
- }
532
618
  async function writeTextToClipboard(text) {
533
619
  if (navigator.clipboard?.writeText) {
534
620
  await navigator.clipboard.writeText(text);
@@ -567,7 +653,7 @@ function formatImportLimit(bytes) {
567
653
  : `${bytes} bytes`;
568
654
  }
569
655
  function formatIssues(issues) {
570
- return issues.slice(0, 3).map((issue) => `${issue.path || '/'}: ${issue.message}`).join('; ');
656
+ return issues.map((issue) => `${issue.path || '/'}: ${issue.message}`).join('\n');
571
657
  }
572
658
  function isFileDrag(event) {
573
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 passesGraphModeButton: HTMLButtonElement;\n\tprivate readonly resourcesGraphModeButton: HTMLButtonElement;\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\tgraphMode: 'passes',\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.passesGraphModeButton = createToolbarButton('Pass dependency', 'Show pass dependency graph', () => this.setGraphMode('passes'));\n\t\tthis.resourcesGraphModeButton = createToolbarButton('Resource access', 'Show resource access graph', () => this.setGraphMode('resources'));\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\t\tthis.passesGraphModeButton.classList.add('zenfg-inspector-mode-button');\n\t\tthis.resourcesGraphModeButton.classList.add('zenfg-inspector-mode-button');\n\n\t\tconst modeControls = document.createElement('div');\n\t\tmodeControls.className = 'zenfg-inspector-graph-mode-controls';\n\t\tmodeControls.setAttribute('role', 'group');\n\t\tmodeControls.setAttribute('aria-label', 'Graph mode');\n\t\tmodeControls.append(this.passesGraphModeButton, this.resourcesGraphModeButton);\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(modeControls, 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.updateGraphModeButtonState();\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.0 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.updateGraphModeButtonState();\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 setGraphMode(mode: GraphViewState['graphMode']): void {\n\t\tif (this.graphView.graphMode === mode) return;\n\t\tthis.graphView.graphMode = mode;\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.updateGraphModeButtonState();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate updateGraphModeButtonState(): void {\n\t\tconst passesActive = this.graphView.graphMode === 'passes';\n\t\tconst hasGroups = (this.viewModel?.debugGroups.length ?? 0) > 0;\n\t\tthis.passesGraphModeButton.classList.toggle('active', passesActive);\n\t\tthis.resourcesGraphModeButton.classList.toggle('active', !passesActive);\n\t\tthis.passesGraphModeButton.setAttribute('aria-pressed', passesActive ? 'true' : 'false');\n\t\tthis.resourcesGraphModeButton.setAttribute('aria-pressed', passesActive ? 'false' : 'true');\n\t\tthis.groupsButton.disabled = !passesActive || !hasGroups;\n\t\tthis.groupsButton.classList.toggle('active', passesActive && hasGroups && this.graphView.groupsEnabled);\n\t\tthis.groupsButton.setAttribute('aria-pressed', passesActive && 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 = !passesActive || !hasGroups || !this.graphView.groupsEnabled || !hasExpanded;\n\t}\n\n\tprivate toggleGroups(): void {\n\t\tif (this.graphView.graphMode !== 'passes' || !this.viewModel?.debugGroups.length) return;\n\t\tthis.graphView.groupsEnabled = !this.graphView.groupsEnabled;\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.updateGraphModeButtonState();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate toggleGroup(pathKey: string): void {\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.updateGraphModeButtonState();\n\t\tthis.workbench.refreshGraphStructure();\n\t}\n\n\tprivate collapseAllGroups(): void {\n\t\tif (this.graphView.expandedGroupPaths.size === 0) return;\n\t\tthis.graphView.expandedGroupPaths.clear();\n\t\tthis.graphView.fitOnNextRender = true;\n\t\tthis.updateGraphModeButtonState();\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":"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","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