@zenfg/inspector 0.1.0-beta.1 → 0.1.0-beta.3

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 (71) hide show
  1. package/README.md +143 -53
  2. package/dist/FrameGraphInspector.d.ts +2 -5
  3. package/dist/FrameGraphInspector.d.ts.map +1 -1
  4. package/dist/FrameGraphInspector.js +16 -38
  5. package/dist/FrameGraphInspector.js.map +1 -1
  6. package/dist/debugCaptureModel.d.ts +9 -4
  7. package/dist/debugCaptureModel.d.ts.map +1 -1
  8. package/dist/debugCaptureModel.js +36 -14
  9. package/dist/debugCaptureModel.js.map +1 -1
  10. package/dist/panelCytoscapeGraphRenderer.d.ts +3 -1
  11. package/dist/panelCytoscapeGraphRenderer.d.ts.map +1 -1
  12. package/dist/panelCytoscapeGraphRenderer.js +40 -19
  13. package/dist/panelCytoscapeGraphRenderer.js.map +1 -1
  14. package/dist/panelDiagnosticsView.js +2 -2
  15. package/dist/panelDiagnosticsView.js.map +1 -1
  16. package/dist/panelGraphLayout.d.ts.map +1 -1
  17. package/dist/panelGraphLayout.js +15 -1
  18. package/dist/panelGraphLayout.js.map +1 -1
  19. package/dist/panelGraphScene.d.ts +14 -26
  20. package/dist/panelGraphScene.d.ts.map +1 -1
  21. package/dist/panelGraphScene.js +141 -195
  22. package/dist/panelGraphScene.js.map +1 -1
  23. package/dist/panelGraphView.d.ts.map +1 -1
  24. package/dist/panelGraphView.js +31 -9
  25. package/dist/panelGraphView.js.map +1 -1
  26. package/dist/panelGraphVisuals.d.ts +7 -3
  27. package/dist/panelGraphVisuals.d.ts.map +1 -1
  28. package/dist/panelGraphVisuals.js +45 -80
  29. package/dist/panelGraphVisuals.js.map +1 -1
  30. package/dist/panelIcons.d.ts +1 -1
  31. package/dist/panelIcons.d.ts.map +1 -1
  32. package/dist/panelIcons.js +1 -0
  33. package/dist/panelIcons.js.map +1 -1
  34. package/dist/panelInspectorView.d.ts +5 -0
  35. package/dist/panelInspectorView.d.ts.map +1 -1
  36. package/dist/panelInspectorView.js +99 -13
  37. package/dist/panelInspectorView.js.map +1 -1
  38. package/dist/panelSelection.js +2 -2
  39. package/dist/panelSelection.js.map +1 -1
  40. package/dist/panelTypes.d.ts +8 -3
  41. package/dist/panelTypes.d.ts.map +1 -1
  42. package/dist/panelTypes.js.map +1 -1
  43. package/dist/panelVisualTheme.d.ts +21 -13
  44. package/dist/panelVisualTheme.d.ts.map +1 -1
  45. package/dist/panelVisualTheme.js +15 -7
  46. package/dist/panelVisualTheme.js.map +1 -1
  47. package/dist/panelWorkbenchHelpers.js +1 -1
  48. package/dist/panelWorkbenchHelpers.js.map +1 -1
  49. package/dist/panelWorkbenchView.d.ts.map +1 -1
  50. package/dist/panelWorkbenchView.js +2 -1
  51. package/dist/panelWorkbenchView.js.map +1 -1
  52. package/dist/styles.d.ts.map +1 -1
  53. package/dist/styles.js +20 -12
  54. package/dist/styles.js.map +1 -1
  55. package/package.json +2 -2
  56. package/src/FrameGraphInspector.ts +17 -39
  57. package/src/debugCaptureModel.ts +44 -19
  58. package/src/panelCytoscapeGraphRenderer.ts +39 -18
  59. package/src/panelDiagnosticsView.ts +3 -3
  60. package/src/panelGraphLayout.ts +15 -1
  61. package/src/panelGraphScene.ts +153 -279
  62. package/src/panelGraphView.ts +31 -9
  63. package/src/panelGraphVisuals.ts +46 -82
  64. package/src/panelIcons.ts +2 -0
  65. package/src/panelInspectorView.ts +104 -16
  66. package/src/panelSelection.ts +2 -2
  67. package/src/panelTypes.ts +9 -3
  68. package/src/panelVisualTheme.ts +18 -7
  69. package/src/panelWorkbenchHelpers.ts +2 -2
  70. package/src/panelWorkbenchView.ts +2 -1
  71. package/src/styles.ts +20 -12
@@ -2,6 +2,24 @@ import { labelNode, labelResource } from "./panelDomHelpers.js";
2
2
  import { createPanelIcon } from "./panelIcons.js";
3
3
  import { resolveSelectedDetail } from "./panelSelection.js";
4
4
  import { createRelationButton, formatEstimatedBytes, formatResourceDescriptor, groupPath, resourceLabel, } from "./panelWorkbenchHelpers.js";
5
+ function formatAccessFacts(access) {
6
+ return [
7
+ access.mode, access.access,
8
+ ...(access.mode === 'write' ? [access.contents, `producesValue: ${access.producesValue}`] : []),
9
+ ...(access.bufferRange ? [`bytes ${access.bufferRange.offset}–${access.bufferRange.size === undefined ? 'end' : access.bufferRange.offset + access.bufferRange.size}`] : []),
10
+ ...(access.textureRegion ? [JSON.stringify(access.textureRegion)] : []),
11
+ ...(access.textureViewId ? [`view ${access.textureViewId}`] : []),
12
+ ].join(' · ');
13
+ }
14
+ function formatRootRange(root) {
15
+ if (!root.range)
16
+ return 'Range unavailable';
17
+ if (root.range.kind === 'buffer')
18
+ return `bytes ${root.range.offset}–${root.range.offset + root.range.size}`;
19
+ return root.range.regions.map((region) => `mip ${region.baseMipLevel}+${region.mipLevelCount} · ${region.baseDepthSlice === undefined
20
+ ? `layers ${region.baseArrayLayer}+${region.arrayLayerCount}`
21
+ : `depth ${region.baseDepthSlice}+${region.depthSliceCount}`} · ${region.aspect}`).join('; ');
22
+ }
5
23
  export class InspectorView {
6
24
  callbacks;
7
25
  onOpenChange;
@@ -14,6 +32,7 @@ export class InspectorView {
14
32
  selected;
15
33
  activeTab = 'summary';
16
34
  open = true;
35
+ hoveredLink;
17
36
  constructor(callbacks, onOpenChange, idPrefix) {
18
37
  this.callbacks = callbacks;
19
38
  this.onOpenChange = onOpenChange;
@@ -58,6 +77,9 @@ export class InspectorView {
58
77
  this.render();
59
78
  }
60
79
  setSelection(selected, reveal = true) {
80
+ if (selected?.kind === 'resource'
81
+ && (this.selected?.kind !== 'resource' || this.selected.id !== selected.id))
82
+ this.activeTab = 'summary';
61
83
  this.selected = selected;
62
84
  if (selected && reveal)
63
85
  this.setOpen(true);
@@ -66,6 +88,8 @@ export class InspectorView {
66
88
  setOpen(open) {
67
89
  if (this.open === open)
68
90
  return;
91
+ if (!open)
92
+ this.clearLinkHover();
69
93
  this.open = open;
70
94
  this.updateOpenState();
71
95
  this.onOpenChange(open);
@@ -78,6 +102,7 @@ export class InspectorView {
78
102
  this.root.classList.toggle('open', this.open);
79
103
  }
80
104
  render() {
105
+ this.clearLinkHover();
81
106
  for (const [tab, button] of this.tabs) {
82
107
  const active = tab === this.activeTab;
83
108
  button.classList.toggle('active', active);
@@ -122,7 +147,7 @@ export class InspectorView {
122
147
  return resource ? labelResource(resource) : `Resource #${selection.id}`;
123
148
  }
124
149
  case 'allocation': return `Allocation #${selection.id}`;
125
- case 'root': return `Retention root #${selection.index}`;
150
+ case 'root': return 'Output root';
126
151
  case 'culled': return `Culled node #${selection.index}`;
127
152
  case 'segment': return `Segment #${selection.index}`;
128
153
  }
@@ -185,11 +210,16 @@ export class InspectorView {
185
210
  ]);
186
211
  }
187
212
  case 'root': {
188
- const root = snapshot.roots[selection.index];
213
+ const root = snapshot.roots.find((root) => root.key === selection.key);
189
214
  return this.summary(root ? [
190
215
  ['Reason', root.reason],
191
216
  ['Node', root.nodeId === undefined ? '-' : `#${root.nodeId}`],
192
- ['Resource', root.resource ? labelResource(root.resource) : '-'],
217
+ ['Resource', root.resource ? this.viewResourceButton(snapshot, root.resource.id) : '-'],
218
+ ...(root.reason === 'side-effect' ? [] : [
219
+ ['Range', root.range ? JSON.stringify(root.range) : 'Unavailable in Legacy capture'],
220
+ ['Initial contents', root.resolution ? String(root.resolution.usesInitialContents) : 'Unavailable in Legacy capture'],
221
+ ['Producers', root.resolution ? root.resolution.producerNodeIds.join(', ') || 'None' : 'Unavailable in Legacy capture'],
222
+ ]),
193
223
  ] : []);
194
224
  }
195
225
  case 'culled': {
@@ -233,7 +263,10 @@ export class InspectorView {
233
263
  case 'group': {
234
264
  const group = snapshot.groupByPathKey.get(selection.pathKey);
235
265
  if (group) {
236
- host.append(this.resourceRelations('Inputs', group.summary.inputResources), this.resourceRelations('Outputs', group.summary.outputResources));
266
+ host.append(this.resourceRelations('Inputs', group.summary.inputResources), this.resourceRelations('Outputs', group.summary.outputResources), this.relationGroup('Output roots', group.summary.outputRoots.map((root) => [
267
+ `${root.resource ? labelResource(root.resource) : '-'} · ${root.reason} · ${root.range ? JSON.stringify(root.range) : 'Range unavailable'}`,
268
+ { kind: 'root', key: root.key },
269
+ ])));
237
270
  }
238
271
  break;
239
272
  }
@@ -245,11 +278,17 @@ export class InspectorView {
245
278
  const nodeSelection = this.accessNodeSelection(snapshot, access.nodeId);
246
279
  if (nodeSelection)
247
280
  passRelations.push([
248
- `${access.mode} · ${this.accessNodeLabel(snapshot, access.nodeId)} · ${access.access}`,
281
+ this.accessNodeLabel(snapshot, access.nodeId),
249
282
  nodeSelection,
283
+ formatAccessFacts(access),
250
284
  ]);
251
285
  }
252
286
  host.appendChild(this.relationGroup('Pass accesses', passRelations));
287
+ const roots = snapshot.roots.filter((root) => root.resource?.id === selection.id);
288
+ if (roots.length)
289
+ host.appendChild(this.relationGroup('Output roots', roots.map((root) => [
290
+ `${root.reason} · ${formatRootRange(root)}`, { kind: 'root', key: root.key },
291
+ ])));
253
292
  if (resource?.physicalResourceId !== undefined)
254
293
  host.appendChild(this.relationGroup('Allocation', [
255
294
  [`#${resource.physicalResourceId}`, { kind: 'allocation', id: resource.physicalResourceId }],
@@ -265,15 +304,19 @@ export class InspectorView {
265
304
  break;
266
305
  }
267
306
  case 'root': {
268
- const root = snapshot.roots[selection.index];
307
+ const root = snapshot.roots.find((root) => root.key === selection.key);
269
308
  const relations = [];
270
309
  if (root?.nodeId !== undefined && snapshot.nodeById.has(root.nodeId))
271
310
  relations.push([
272
311
  this.accessNodeLabel(snapshot, root.nodeId), { kind: 'node', id: root.nodeId },
273
312
  ]);
274
313
  if (root?.resource)
275
- relations.push([labelResource(root.resource), { kind: 'resource', id: root.resource.id }]);
276
- host.appendChild(this.relationGroup('Retained object', relations));
314
+ host.appendChild(this.relationGroup('Resource', [[labelResource(root.resource), { kind: 'resource', id: root.resource.id }]]));
315
+ if (root?.resource && root.resolution?.usesInitialContents)
316
+ relations.push([`Initial contents · ${labelResource(root.resource)}`, { kind: 'resource', id: root.resource.id }]);
317
+ for (const id of root?.resolution?.producerNodeIds ?? [])
318
+ relations.push([this.accessNodeLabel(snapshot, id), { kind: 'node', id }]);
319
+ host.appendChild(this.relationGroup('Output sources', relations));
277
320
  break;
278
321
  }
279
322
  case 'culled': {
@@ -302,8 +345,9 @@ export class InspectorView {
302
345
  }
303
346
  accessRelations(title, accesses) {
304
347
  return this.relationGroup(title, accesses.map((access) => [
305
- `${labelResource(access.resource)} · ${access.access}${access.mode === 'write' ? ` · ${access.contents}` : ''}`,
348
+ labelResource(access.resource),
306
349
  { kind: 'resource', id: access.resource.id },
350
+ formatAccessFacts(access),
307
351
  ]));
308
352
  }
309
353
  resourceRelations(title, resources) {
@@ -316,8 +360,20 @@ export class InspectorView {
316
360
  const heading = document.createElement('h3');
317
361
  heading.textContent = `${title} ${relations.length}`;
318
362
  section.appendChild(heading);
319
- for (const [label, selection] of relations) {
320
- section.appendChild(createRelationButton(label, selection, this.callbacks.onSelect));
363
+ for (const [label, selection, description] of relations) {
364
+ const link = this.createDetailLink(label, selection);
365
+ if (description === undefined) {
366
+ section.appendChild(link);
367
+ }
368
+ else {
369
+ const entry = document.createElement('div');
370
+ entry.className = 'zenfg-inspector-relation-entry';
371
+ const metadata = document.createElement('span');
372
+ metadata.className = 'zenfg-inspector-muted';
373
+ metadata.textContent = description;
374
+ entry.append(link, metadata);
375
+ section.appendChild(entry);
376
+ }
321
377
  }
322
378
  if (relations.length === 0) {
323
379
  const empty = document.createElement('span');
@@ -327,6 +383,31 @@ export class InspectorView {
327
383
  }
328
384
  return section;
329
385
  }
386
+ selectRelated(selection) {
387
+ this.clearLinkHover();
388
+ this.callbacks.onSelect(selection);
389
+ }
390
+ viewResourceButton(snapshot, resourceId) {
391
+ return this.createDetailLink(`View resource · ${resourceLabel(snapshot, resourceId)}`, { kind: 'resource', id: resourceId });
392
+ }
393
+ createDetailLink(label, selection) {
394
+ const link = createRelationButton(label, selection, (target) => this.selectRelated(target));
395
+ link.addEventListener('mouseenter', () => {
396
+ this.hoveredLink = link;
397
+ this.callbacks.onHover(selection);
398
+ });
399
+ link.addEventListener('mouseleave', () => {
400
+ if (this.hoveredLink === link)
401
+ this.clearLinkHover();
402
+ });
403
+ return link;
404
+ }
405
+ clearLinkHover() {
406
+ if (!this.hoveredLink)
407
+ return;
408
+ this.hoveredLink = undefined;
409
+ this.callbacks.onHover(undefined);
410
+ }
330
411
  summary(rows) {
331
412
  const summary = document.createElement('dl');
332
413
  summary.className = 'zenfg-inspector-inspector-summary';
@@ -334,8 +415,13 @@ export class InspectorView {
334
415
  const term = document.createElement('dt');
335
416
  term.textContent = label;
336
417
  const description = document.createElement('dd');
337
- description.textContent = value;
338
- description.title = value;
418
+ if (typeof value === 'string') {
419
+ description.textContent = value;
420
+ description.title = value;
421
+ }
422
+ else {
423
+ description.appendChild(value);
424
+ }
339
425
  summary.append(term, description);
340
426
  }
341
427
  return summary;
@@ -1 +1 @@
1
- {"version":3,"file":"panelInspectorView.js","sourceRoot":"","sources":["../src/panelInspectorView.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,SAAS,EACT,aAAa,GAEb,MAAM,4BAA4B,CAAC;AAEpC,MAAM,OAAO,aAAa;IAYP;IACA;IAZT,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,GAAG,IAAI,GAAG,EAAmC,CAAC;IAC3D,QAAQ,CAAuC;IAC/C,QAAQ,CAAwB;IAChC,SAAS,GAAiB,SAAS,CAAC;IACpC,IAAI,GAAG,IAAI,CAAC;IAEpB,YACkB,SAA6B,EAC7B,YAAqC,EACtD,QAAgB;QAFC,cAAS,GAAT,SAAS,CAAoB;QAC7B,iBAAY,GAAZ,YAAY,CAAyB;QAGtD,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,2BAA2B,CAAC;QAClD,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;QACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC/C,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC;QACtB,KAAK,CAAC,SAAS,GAAG,iCAAiC,CAAC;QACpD,KAAK,CAAC,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5C,KAAK,CAAC,KAAK,GAAG,iBAAiB,CAAC;QAChC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;QACpD,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAEjC,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,gCAAgC,CAAC;QAC1D,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;QAC3D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAU,EAAE,CAAC;YAC1G,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;YACvB,MAAM,CAAC,EAAE,GAAG,GAAG,QAAQ,cAAc,GAAG,MAAM,CAAC;YAC/C,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC;YAC3B,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACnC,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,GAAG,QAAQ,kBAAkB,CAAC,CAAC;YACpE,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;gBACrC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;gBACrB,IAAI,CAAC,MAAM,EAAE,CAAC;YACf,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,QAAQ,kBAAkB,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,mCAAmC,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IAED,WAAW,CAAC,QAAkC;QAC7C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IAED,YAAY,CAAC,QAA+B,EAAE,MAAM,GAAG,IAAI;QAC1D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,QAAQ,IAAI,MAAM;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IAED,OAAO,CAAC,IAAa;QACpB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAEO,eAAe;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAEO,MAAM;QACb,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC,SAAS,CAAC;YACtC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAChE,IAAI,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;YACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAC1C,KAAK,CAAC,SAAS,GAAG,uBAAuB,CAAC;YAC1C,KAAK,CAAC,WAAW,GAAG,4EAA4E,CAAC;YACjG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO;QACR,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC1C,GAAG,CAAC,SAAS,GAAG,4BAA4B,CAAC;YAC7C,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACrF,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;aAAM,IAAI,IAAI,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClE,CAAC;IACF,CAAC;IAEO,cAAc,CAAC,QAAkC,EAAE,SAAoB;QAC9E,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACxB,KAAK,MAAM,CAAC,CAAC,CAAC;gBACb,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACjD,OAAO,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,CAAC,EAAE,EAAE,CAAC;YACzD,CAAC;YACD,KAAK,OAAO,CAAC,CAAC,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,IAAI,OAAO,CAAC;YACtF,KAAK,UAAU,CAAC,CAAC,CAAC;gBACjB,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACzD,OAAO,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,SAAS,CAAC,EAAE,EAAE,CAAC;YACzE,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,OAAO,eAAe,SAAS,CAAC,EAAE,EAAE,CAAC;YACxD,KAAK,MAAM,CAAC,CAAC,OAAO,mBAAmB,SAAS,CAAC,KAAK,EAAE,CAAC;YACzD,KAAK,QAAQ,CAAC,CAAC,OAAO,gBAAgB,SAAS,CAAC,KAAK,EAAE,CAAC;YACxD,KAAK,SAAS,CAAC,CAAC,OAAO,YAAY,SAAS,CAAC,KAAK,EAAE,CAAC;QACtD,CAAC;IACF,CAAC;IAEO,aAAa,CAAC,QAAkC,EAAE,SAAoB;QAC7E,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACxB,KAAK,MAAM,CAAC,CAAC,CAAC;gBACb,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,IAAI;oBAAE,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACtD,OAAO,IAAI,CAAC,OAAO,CAAC;oBACnB,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;oBACnB,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC7B,CAAC,OAAO,EAAE,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;oBACjD,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;oBAChE,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;oBACjK,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,YAAY,IAAI,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC;oBACzE,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;iBAC/C,CAAC,CAAC;YACJ,CAAC;YACD,KAAK,OAAO,CAAC,CAAC,CAAC;gBACd,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBAC7D,IAAI,CAAC,KAAK;oBAAE,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACpC,OAAO,IAAI,CAAC,OAAO,CAAC;oBACnB,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAChC,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;oBACrD,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;oBACjD,CAAC,cAAc,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,IAAI,KAAK,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC;oBAC5F,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;oBAC7E,CAAC,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;oBAC9D,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;iBACzD,CAAC,CAAC;YACJ,CAAC;YACD,KAAK,UAAU,CAAC,CAAC,CAAC;gBACjB,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACzD,IAAI,CAAC,QAAQ;oBAAE,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACvC,OAAO,IAAI,CAAC,OAAO,CAAC;oBACnB,CAAC,eAAe,EAAE,GAAG,QAAQ,CAAC,IAAI,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;oBAC1D,CAAC,OAAO,EAAE,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;oBACrD,CAAC,YAAY,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;oBAClD,CAAC,WAAW,EAAE,oBAAoB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;oBAC/D,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;oBACpG,CAAC,YAAY,EAAE,QAAQ,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;oBACnG,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;iBAChD,CAAC,CAAC;YACJ,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBACnB,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBAC7D,IAAI,CAAC,UAAU;oBAAE,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACzC,OAAO,IAAI,CAAC,OAAO,CAAC;oBACnB,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC;oBACzB,CAAC,qBAAqB,EAAE,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;oBAChE,CAAC,WAAW,EAAE,oBAAoB,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;oBACjE,CAAC,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oBAC5D,CAAC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;iBACnG,CAAC,CAAC;YACJ,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACb,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC7C,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC1B,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;oBACvB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC7D,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;iBAChE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACT,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACrD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC5B,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBAChC,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;oBAC1B,CAAC,OAAO,EAAE,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBACxD,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;oBACzB,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,YAAY,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC;iBACvF,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACT,CAAC;YACD,KAAK,SAAS,CAAC,CAAC,CAAC;gBAChB,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC7D,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC7B,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,iBAAiB,CAAC;oBAC3F,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;oBACzC,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,KAAK,qBAAqB;4BACjD,CAAC,CAAC,4EAA4E;4BAC9E,CAAC,CAAC,6CAA6C,CAAC;iBACjD,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACT,CAAC;QACF,CAAC;IACF,CAAC;IAEO,eAAe,CAAC,QAAkC,EAAE,SAAoB;QAC/E,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,qCAAqC,CAAC;QACvD,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACxB,KAAK,MAAM,CAAC,CAAC,CAAC;gBACb,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACjD,IAAI,IAAI,EAAE,CAAC;oBACV,IAAI,CAAC,MAAM,CACV,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EACzC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAC3C,CAAC;oBACF,MAAM,OAAO,GAAG,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACtD,IAAI,OAAO;wBAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;4BAC3D,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;yBAChF,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACP,CAAC;YACD,KAAK,OAAO,CAAC,CAAC,CAAC;gBACd,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBAC7D,IAAI,KAAK,EAAE,CAAC;oBACX,IAAI,CAAC,MAAM,CACV,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAC9D,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAChE,CAAC;gBACH,CAAC;gBACD,MAAM;YACP,CAAC;YACD,KAAK,UAAU,CAAC,CAAC,CAAC;gBACjB,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACzD,MAAM,QAAQ,GAAG,QAAQ,CAAC,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;gBACvE,MAAM,aAAa,GAAwC,EAAE,CAAC;gBAC9D,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;oBAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;oBACxE,IAAI,aAAa;wBAAE,aAAa,CAAC,IAAI,CAAC;4BACrC,GAAG,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE;4BACtF,aAAa;yBACb,CAAC,CAAC;gBACJ,CAAC;gBACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,CAAC;gBACrE,IAAI,QAAQ,EAAE,kBAAkB,KAAK,SAAS;oBAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE;wBACjG,CAAC,IAAI,QAAQ,CAAC,kBAAkB,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,QAAQ,CAAC,kBAAkB,EAAE,CAAC;qBAC5F,CAAC,CAAC,CAAC;gBACJ,MAAM;YACP,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBACnB,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBAC7D,IAAI,UAAU;oBAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;wBAC3G,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;qBACrD,CAAC,CAAC,CAAC,CAAC;gBACL,MAAM;YACP,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACb,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC7C,MAAM,SAAS,GAAwC,EAAE,CAAC;gBAC1D,IAAI,IAAI,EAAE,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;oBAAE,SAAS,CAAC,IAAI,CAAC;wBACpF,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE;qBAC9E,CAAC,CAAC;gBACH,IAAI,IAAI,EAAE,QAAQ;oBAAE,SAAS,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC/G,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC,CAAC;gBACnE,MAAM;YACP,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACrD,IAAI,MAAM;oBAAE,IAAI,CAAC,MAAM,CACtB,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAChD,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAClD,CAAC;gBACF,MAAM;YACP,CAAC;YACD,KAAK,SAAS,CAAC,CAAC,CAAC;gBAChB,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC7D,IAAI,OAAO;oBAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;wBACzF,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBACvC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACL,MAAM;YACP,CAAC;QACF,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAC1C,KAAK,CAAC,SAAS,GAAG,uBAAuB,CAAC;YAC1C,KAAK,CAAC,WAAW,GAAG,qBAAqB,CAAC;YAC1C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,eAAe,CAAC,KAAa,EAAE,QAA0C;QAChF,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YACzD,GAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/G,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE;SAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,iBAAiB,CAAC,KAAa,EAAE,SAAgD;QACxF,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC5D,aAAa,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;SAC9D,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,KAAa,EAAE,SAAoD;QACxF,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7C,OAAO,CAAC,WAAW,GAAG,GAAG,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACrD,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC7B,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,SAAS,EAAE,CAAC;YAC5C,OAAO,CAAC,WAAW,CAAC,oBAAoB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC7C,KAAK,CAAC,SAAS,GAAG,uBAAuB,CAAC;YAC1C,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;YAC3B,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAEO,OAAO,CAAC,IAA4C;QAC3D,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7C,OAAO,CAAC,SAAS,GAAG,mCAAmC,CAAC;QACxD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACjD,WAAW,CAAC,WAAW,GAAG,KAAK,CAAC;YAChC,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;YAC1B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAEO,eAAe,CAAC,QAAkC,EAAE,MAAc;QACzE,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,IAAI;YAAE,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACtF,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAC;IACzE,CAAC;IAEO,mBAAmB,CAAC,QAAkC,EAAE,MAAc;QAC7E,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QAC1F,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC1D,CAAC;CACD","sourcesContent":["import type {\n\tFrameGraphDebugAccess,\n\tFrameGraphDebugResourceRef,\n\tFrameGraphDebugViewModel,\n} from './debugCaptureModel.ts';\nimport { labelNode, labelResource } from './panelDomHelpers.ts';\nimport { createPanelIcon } from './panelIcons.ts';\nimport { resolveSelectedDetail } from './panelSelection.ts';\nimport type { InspectorTab, Selection } from './panelTypes.ts';\nimport {\n\tcreateRelationButton,\n\tformatEstimatedBytes,\n\tformatResourceDescriptor,\n\tgroupPath,\n\tresourceLabel,\n\ttype WorkbenchCallbacks,\n} from './panelWorkbenchHelpers.ts';\n\nexport class InspectorView {\n\treadonly root = document.createElement('aside');\n\tprivate readonly title = document.createElement('strong');\n\tprivate readonly tabList = document.createElement('div');\n\tprivate readonly content = document.createElement('div');\n\tprivate readonly tabs = new Map<InspectorTab, HTMLButtonElement>();\n\tprivate snapshot: FrameGraphDebugViewModel | undefined;\n\tprivate selected: Selection | undefined;\n\tprivate activeTab: InspectorTab = 'summary';\n\tprivate open = true;\n\n\tconstructor(\n\t\tprivate readonly callbacks: WorkbenchCallbacks,\n\t\tprivate readonly onOpenChange: (open: boolean) => void,\n\t\tidPrefix: string,\n\t) {\n\t\tthis.root.className = 'zenfg-inspector-inspector';\n\t\tthis.root.setAttribute('aria-label', 'Selection inspector');\n\t\tconst header = document.createElement('header');\n\t\tthis.title.textContent = 'Inspector';\n\t\tconst close = document.createElement('button');\n\t\tclose.type = 'button';\n\t\tclose.className = 'zenfg-inspector-inspector-close';\n\t\tclose.appendChild(createPanelIcon('close'));\r\n\t\tclose.title = 'Close inspector';\n\t\tclose.setAttribute('aria-label', 'Close inspector');\n\t\tclose.addEventListener('click', () => this.setOpen(false));\n\t\theader.append(this.title, close);\n\n\t\tthis.tabList.className = 'zenfg-inspector-inspector-tabs';\n\t\tthis.tabList.setAttribute('role', 'tablist');\n\t\tthis.tabList.setAttribute('aria-label', 'Inspector views');\n\t\tfor (const [tab, label] of [['summary', 'Summary'], ['relations', 'Relations'], ['raw', 'Raw']] as const) {\n\t\t\tconst button = document.createElement('button');\n\t\t\tbutton.type = 'button';\n\t\t\tbutton.id = `${idPrefix}-inspector-${tab}-tab`;\n\t\t\tbutton.textContent = label;\n\t\t\tbutton.setAttribute('role', 'tab');\n\t\t\tbutton.setAttribute('aria-controls', `${idPrefix}-inspector-panel`);\n\t\t\tbutton.addEventListener('click', () => {\n\t\t\t\tthis.activeTab = tab;\n\t\t\t\tthis.render();\n\t\t\t});\n\t\t\tthis.tabs.set(tab, button);\n\t\t\tthis.tabList.appendChild(button);\n\t\t}\n\t\tthis.content.id = `${idPrefix}-inspector-panel`;\n\t\tthis.content.className = 'zenfg-inspector-inspector-content';\n\t\tthis.content.setAttribute('role', 'tabpanel');\n\t\tthis.root.append(header, this.tabList, this.content);\n\t\tthis.updateOpenState();\n\t\tthis.render();\n\t}\n\n\tsetSnapshot(snapshot: FrameGraphDebugViewModel): void {\n\t\tthis.snapshot = snapshot;\n\t\tthis.render();\n\t}\n\n\tsetSelection(selected: Selection | undefined, reveal = true): void {\n\t\tthis.selected = selected;\n\t\tif (selected && reveal) this.setOpen(true);\n\t\tthis.render();\n\t}\n\n\tsetOpen(open: boolean): void {\n\t\tif (this.open === open) return;\n\t\tthis.open = open;\n\t\tthis.updateOpenState();\n\t\tthis.onOpenChange(open);\n\t}\n\n\tget isOpen(): boolean {\n\t\treturn this.open;\n\t}\n\n\tprivate updateOpenState(): void {\n\t\tthis.root.hidden = !this.open;\n\t\tthis.root.classList.toggle('open', this.open);\n\t}\n\n\tprivate render(): void {\n\t\tfor (const [tab, button] of this.tabs) {\n\t\t\tconst active = tab === this.activeTab;\n\t\t\tbutton.classList.toggle('active', active);\n\t\t\tbutton.setAttribute('aria-selected', active ? 'true' : 'false');\n\t\t\tif (active) this.content.setAttribute('aria-labelledby', button.id);\n\t\t}\n\t\tconst snapshot = this.snapshot;\n\t\tconst selected = this.selected;\n\t\tthis.content.replaceChildren();\n\t\tif (!snapshot || !selected) {\n\t\t\tthis.title.textContent = 'Inspector';\n\t\t\tconst empty = document.createElement('p');\n\t\t\tempty.className = 'zenfg-inspector-muted';\n\t\t\tempty.textContent = 'Select a pass, group, resource, allocation, root, culled node, or segment.';\n\t\t\tthis.content.appendChild(empty);\n\t\t\treturn;\n\t\t}\n\t\tthis.title.textContent = this.selectionTitle(snapshot, selected);\n\t\tif (this.activeTab === 'raw') {\n\t\t\tconst raw = document.createElement('pre');\n\t\t\traw.className = 'zenfg-inspector-raw-detail';\n\t\t\traw.textContent = JSON.stringify(resolveSelectedDetail(snapshot, selected), null, 2);\n\t\t\tthis.content.appendChild(raw);\n\t\t} else if (this.activeTab === 'relations') {\n\t\t\tthis.content.appendChild(this.createRelations(snapshot, selected));\n\t\t} else {\n\t\t\tthis.content.appendChild(this.createSummary(snapshot, selected));\n\t\t}\n\t}\n\n\tprivate selectionTitle(snapshot: FrameGraphDebugViewModel, selection: Selection): string {\n\t\tswitch (selection.kind) {\n\t\t\tcase 'node': {\n\t\t\t\tconst node = snapshot.nodeById.get(selection.id);\n\t\t\t\treturn node ? labelNode(node) : `Pass #${selection.id}`;\n\t\t\t}\n\t\t\tcase 'group': return snapshot.groupByPathKey.get(selection.pathKey)?.label ?? 'Group';\n\t\t\tcase 'resource': {\n\t\t\t\tconst resource = snapshot.resourceById.get(selection.id);\n\t\t\t\treturn resource ? labelResource(resource) : `Resource #${selection.id}`;\n\t\t\t}\n\t\t\tcase 'allocation': return `Allocation #${selection.id}`;\n\t\t\tcase 'root': return `Retention root #${selection.index}`;\n\t\t\tcase 'culled': return `Culled node #${selection.index}`;\n\t\t\tcase 'segment': return `Segment #${selection.index}`;\n\t\t}\n\t}\n\n\tprivate createSummary(snapshot: FrameGraphDebugViewModel, selection: Selection): HTMLElement {\n\t\tswitch (selection.kind) {\n\t\t\tcase 'node': {\n\t\t\t\tconst node = snapshot.nodeById.get(selection.id);\n\t\t\t\tif (!node) return this.summary([]);\n\t\t\t\tconst segment = snapshot.segmentByNodeId.get(node.id);\n\t\t\t\treturn this.summary([\n\t\t\t\t\t['Kind', node.kind],\n\t\t\t\t\t['Order', String(node.order)],\n\t\t\t\t\t['Group', groupPath(snapshot, node.debugGroupId)],\n\t\t\t\t\t['Segment', segment ? `#${segment.index} ${segment.kind}` : '-'],\n\t\t\t\t\t['GPU', node.kind === 'external-submission' ? 'Opaque' : node.gpuDurationMicros === undefined ? 'Not timed' : `${(node.gpuDurationMicros / 1000).toFixed(3)} ms`],\n\t\t\t\t\t['Accesses', `${node.reads.length} reads · ${node.writes.length} writes`],\n\t\t\t\t\t['Side effect', node.sideEffect ? 'yes' : 'no'],\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcase 'group': {\n\t\t\t\tconst group = snapshot.groupByPathKey.get(selection.pathKey);\n\t\t\t\tif (!group) return this.summary([]);\n\t\t\t\treturn this.summary([\n\t\t\t\t\t['Path', group.path.join(' / ')],\n\t\t\t\t\t['Retained', String(group.summary.retainedNodeCount)],\n\t\t\t\t\t['Culled', String(group.summary.culledNodeCount)],\n\t\t\t\t\t['GPU coverage', `${group.summary.timedNodeCount}/${group.summary.timingEligibleNodeCount}`],\n\t\t\t\t\t['GPU work', `${(group.summary.gpuWorkDurationMicros / 1000).toFixed(3)} ms`],\n\t\t\t\t\t['Allocations', String(group.summary.physicalAllocationCount)],\n\t\t\t\t\t['Segments', String(group.summary.executionSegmentCount)],\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcase 'resource': {\n\t\t\t\tconst resource = snapshot.resourceById.get(selection.id);\n\t\t\t\tif (!resource) return this.summary([]);\n\t\t\t\treturn this.summary([\n\t\t\t\t\t['Kind / origin', `${resource.kind} · ${resource.origin}`],\n\t\t\t\t\t['Group', groupPath(snapshot, resource.debugGroupId)],\n\t\t\t\t\t['Descriptor', formatResourceDescriptor(resource)],\n\t\t\t\t\t['Estimated', formatEstimatedBytes(resource.estimatedByteSize)],\n\t\t\t\t\t['Lifetime', resource.lifetime ? `${resource.lifetime.firstUse}–${resource.lifetime.lastUse}` : '-'],\n\t\t\t\t\t['Allocation', resource.physicalResourceId === undefined ? '-' : `#${resource.physicalResourceId}`],\n\t\t\t\t\t['Usage', resource.usageFlags.join(', ') || '-'],\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcase 'allocation': {\n\t\t\t\tconst allocation = snapshot.allocationById.get(selection.id);\n\t\t\t\tif (!allocation) return this.summary([]);\n\t\t\t\treturn this.summary([\n\t\t\t\t\t['Kind', allocation.kind],\n\t\t\t\t\t['Compatibility class', String(allocation.compatibilityClassId)],\n\t\t\t\t\t['Estimated', formatEstimatedBytes(allocation.estimatedByteSize)],\n\t\t\t\t\t['Logical resources', String(allocation.resourceIds.length)],\n\t\t\t\t\t['Alias', allocation.resourceIds.length > 1 ? `yes · ×${allocation.resourceIds.length}` : 'single'],\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcase 'root': {\n\t\t\t\tconst root = snapshot.roots[selection.index];\n\t\t\t\treturn this.summary(root ? [\n\t\t\t\t\t['Reason', root.reason],\n\t\t\t\t\t['Node', root.nodeId === undefined ? '-' : `#${root.nodeId}`],\n\t\t\t\t\t['Resource', root.resource ? labelResource(root.resource) : '-'],\n\t\t\t\t] : []);\n\t\t\t}\n\t\t\tcase 'culled': {\n\t\t\t\tconst culled = snapshot.culledNodes[selection.index];\n\t\t\t\treturn this.summary(culled ? [\n\t\t\t\t\t['Node', labelNode(culled.node)],\n\t\t\t\t\t['Kind', culled.node.kind],\n\t\t\t\t\t['Group', groupPath(snapshot, culled.node.debugGroupId)],\n\t\t\t\t\t['Reason', culled.reason],\n\t\t\t\t\t['Accesses', `${culled.node.reads.length} reads · ${culled.node.writes.length} writes`],\n\t\t\t\t] : []);\n\t\t\t}\n\t\t\tcase 'segment': {\n\t\t\t\tconst segment = snapshot.segmentByIndex.get(selection.index);\n\t\t\t\treturn this.summary(segment ? [\n\t\t\t\t\t['Kind', segment.kind === 'frame-graph' ? 'FrameGraph command segment' : 'Opaque interval'],\n\t\t\t\t\t['Nodes', String(segment.nodeIds.length)],\n\t\t\t\t\t['Meaning', segment.kind === 'external-submission'\n\t\t\t\t\t\t? 'Boundary around external work; not an actual third-party submission count.'\n\t\t\t\t\t\t: 'Contiguous FrameGraph-encoded command work.'],\n\t\t\t\t] : []);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate createRelations(snapshot: FrameGraphDebugViewModel, selection: Selection): HTMLElement {\n\t\tconst host = document.createElement('div');\n\t\thost.className = 'zenfg-inspector-inspector-relations';\n\t\tswitch (selection.kind) {\n\t\t\tcase 'node': {\n\t\t\t\tconst node = snapshot.nodeById.get(selection.id);\n\t\t\t\tif (node) {\n\t\t\t\t\thost.append(\n\t\t\t\t\t\tthis.accessRelations('Reads', node.reads),\n\t\t\t\t\t\tthis.accessRelations('Writes', node.writes),\n\t\t\t\t\t);\n\t\t\t\t\tconst segment = snapshot.segmentByNodeId.get(node.id);\n\t\t\t\t\tif (segment) host.appendChild(this.relationGroup('Segment', [\n\t\t\t\t\t\t[`#${segment.index} ${segment.kind}`, { kind: 'segment', index: segment.index }],\n\t\t\t\t\t]));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'group': {\n\t\t\t\tconst group = snapshot.groupByPathKey.get(selection.pathKey);\n\t\t\t\tif (group) {\n\t\t\t\t\thost.append(\n\t\t\t\t\t\tthis.resourceRelations('Inputs', group.summary.inputResources),\n\t\t\t\t\t\tthis.resourceRelations('Outputs', group.summary.outputResources),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'resource': {\n\t\t\t\tconst resource = snapshot.resourceById.get(selection.id);\n\t\t\t\tconst accesses = snapshot.accessesByResourceId.get(selection.id) ?? [];\n\t\t\t\tconst passRelations: Array<readonly [string, Selection]> = [];\n\t\t\t\tfor (const access of accesses) {\n\t\t\t\t\tconst nodeSelection = this.accessNodeSelection(snapshot, access.nodeId);\n\t\t\t\t\tif (nodeSelection) passRelations.push([\n\t\t\t\t\t\t`${access.mode} · ${this.accessNodeLabel(snapshot, access.nodeId)} · ${access.access}`,\n\t\t\t\t\t\tnodeSelection,\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t\thost.appendChild(this.relationGroup('Pass accesses', passRelations));\n\t\t\t\tif (resource?.physicalResourceId !== undefined) host.appendChild(this.relationGroup('Allocation', [\n\t\t\t\t\t[`#${resource.physicalResourceId}`, { kind: 'allocation', id: resource.physicalResourceId }],\n\t\t\t\t]));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'allocation': {\n\t\t\t\tconst allocation = snapshot.allocationById.get(selection.id);\n\t\t\t\tif (allocation) host.appendChild(this.relationGroup('Logical resources', allocation.resourceIds.map((id) => [\n\t\t\t\t\tresourceLabel(snapshot, id), { kind: 'resource', id },\n\t\t\t\t])));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'root': {\n\t\t\t\tconst root = snapshot.roots[selection.index];\n\t\t\t\tconst relations: Array<readonly [string, Selection]> = [];\n\t\t\t\tif (root?.nodeId !== undefined && snapshot.nodeById.has(root.nodeId)) relations.push([\n\t\t\t\t\tthis.accessNodeLabel(snapshot, root.nodeId), { kind: 'node', id: root.nodeId },\n\t\t\t\t]);\n\t\t\t\tif (root?.resource) relations.push([labelResource(root.resource), { kind: 'resource', id: root.resource.id }]);\n\t\t\t\thost.appendChild(this.relationGroup('Retained object', relations));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'culled': {\n\t\t\t\tconst culled = snapshot.culledNodes[selection.index];\n\t\t\t\tif (culled) host.append(\n\t\t\t\t\tthis.accessRelations('Reads', culled.node.reads),\n\t\t\t\t\tthis.accessRelations('Writes', culled.node.writes),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'segment': {\n\t\t\t\tconst segment = snapshot.segmentByIndex.get(selection.index);\n\t\t\t\tif (segment) host.appendChild(this.relationGroup('Passes', segment.nodeIds.flatMap((id) => {\n\t\t\t\t\tconst node = snapshot.nodeById.get(id);\n\t\t\t\t\treturn node ? [[labelNode(node), { kind: 'node', id }] as const] : [];\n\t\t\t\t})));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (host.childElementCount === 0) {\n\t\t\tconst empty = document.createElement('p');\n\t\t\tempty.className = 'zenfg-inspector-muted';\n\t\t\tempty.textContent = 'No related objects.';\n\t\t\thost.appendChild(empty);\n\t\t}\n\t\treturn host;\n\t}\n\n\tprivate accessRelations(title: string, accesses: readonly FrameGraphDebugAccess[]): HTMLElement {\n\t\treturn this.relationGroup(title, accesses.map((access) => [\n\t\t\t`${labelResource(access.resource)} · ${access.access}${access.mode === 'write' ? ` · ${access.contents}` : ''}`,\n\t\t\t{ kind: 'resource', id: access.resource.id },\n\t\t]));\n\t}\n\n\tprivate resourceRelations(title: string, resources: readonly FrameGraphDebugResourceRef[]): HTMLElement {\n\t\treturn this.relationGroup(title, resources.map((resource) => [\n\t\t\tlabelResource(resource), { kind: 'resource', id: resource.id },\n\t\t]));\n\t}\n\n\tprivate relationGroup(title: string, relations: readonly (readonly [string, Selection])[]): HTMLElement {\n\t\tconst section = document.createElement('section');\n\t\tconst heading = document.createElement('h3');\n\t\theading.textContent = `${title} ${relations.length}`;\n\t\tsection.appendChild(heading);\n\t\tfor (const [label, selection] of relations) {\n\t\t\tsection.appendChild(createRelationButton(label, selection, this.callbacks.onSelect));\n\t\t}\n\t\tif (relations.length === 0) {\n\t\t\tconst empty = document.createElement('span');\n\t\t\tempty.className = 'zenfg-inspector-muted';\n\t\t\tempty.textContent = 'None';\n\t\t\tsection.appendChild(empty);\n\t\t}\n\t\treturn section;\n\t}\n\n\tprivate summary(rows: readonly (readonly [string, string])[]): HTMLElement {\n\t\tconst summary = document.createElement('dl');\n\t\tsummary.className = 'zenfg-inspector-inspector-summary';\n\t\tfor (const [label, value] of rows) {\n\t\t\tconst term = document.createElement('dt');\n\t\t\tterm.textContent = label;\n\t\t\tconst description = document.createElement('dd');\n\t\t\tdescription.textContent = value;\n\t\t\tdescription.title = value;\n\t\t\tsummary.append(term, description);\n\t\t}\n\t\treturn summary;\n\t}\n\n\tprivate accessNodeLabel(snapshot: FrameGraphDebugViewModel, nodeId: string): string {\n\t\tconst node = snapshot.nodeById.get(nodeId);\n\t\tif (node) return labelNode(node);\n\t\tconst culled = snapshot.culledNodes.find((candidate) => candidate.node.id === nodeId);\n\t\treturn culled ? `${labelNode(culled.node)} (culled)` : `node-${nodeId}`;\n\t}\n\n\tprivate accessNodeSelection(snapshot: FrameGraphDebugViewModel, nodeId: string): Selection | undefined {\n\t\tif (snapshot.nodeById.has(nodeId)) return { kind: 'node', id: nodeId };\n\t\tconst index = snapshot.culledNodes.findIndex((candidate) => candidate.node.id === nodeId);\n\t\treturn index < 0 ? undefined : { kind: 'culled', index };\n\t}\n}\n"]}
1
+ {"version":3,"file":"panelInspectorView.js","sourceRoot":"","sources":["../src/panelInspectorView.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tFrameGraphDebugAccess,\n\tFrameGraphDebugRoot,\n\tFrameGraphDebugResourceRef,\n\tFrameGraphDebugViewModel,\n} from './debugCaptureModel.ts';\nimport { labelNode, labelResource } from './panelDomHelpers.ts';\nimport { createPanelIcon } from './panelIcons.ts';\nimport { resolveSelectedDetail } from './panelSelection.ts';\nimport type { InspectorTab, Selection } from './panelTypes.ts';\nimport {\n\tcreateRelationButton,\n\tformatEstimatedBytes,\n\tformatResourceDescriptor,\n\tgroupPath,\n\tresourceLabel,\n\ttype WorkbenchCallbacks,\n} from './panelWorkbenchHelpers.ts';\n\ntype DetailRelation = readonly [label: string, selection: Selection, description?: string];\n\nfunction formatAccessFacts(access: FrameGraphDebugAccess): string {\n\treturn [\n\t\taccess.mode, access.access,\n\t\t...(access.mode === 'write' ? [access.contents, `producesValue: ${access.producesValue}`] : []),\n\t\t...(access.bufferRange ? [`bytes ${access.bufferRange.offset}–${access.bufferRange.size === undefined ? 'end' : access.bufferRange.offset + access.bufferRange.size}`] : []),\n\t\t...(access.textureRegion ? [JSON.stringify(access.textureRegion)] : []),\n\t\t...(access.textureViewId ? [`view ${access.textureViewId}`] : []),\n\t].join(' · ');\n}\n\nfunction formatRootRange(root: FrameGraphDebugRoot): string {\n\tif (!root.range) return 'Range unavailable';\n\tif (root.range.kind === 'buffer') return `bytes ${root.range.offset}–${root.range.offset + root.range.size}`;\n\treturn root.range.regions.map((region) =>\n\t\t`mip ${region.baseMipLevel}+${region.mipLevelCount} · ${region.baseDepthSlice === undefined\n\t\t\t? `layers ${region.baseArrayLayer}+${region.arrayLayerCount}`\n\t\t\t: `depth ${region.baseDepthSlice}+${region.depthSliceCount}`} · ${region.aspect}`,\n\t).join('; ');\n}\n\nexport class InspectorView {\n\treadonly root = document.createElement('aside');\n\tprivate readonly title = document.createElement('strong');\n\tprivate readonly tabList = document.createElement('div');\n\tprivate readonly content = document.createElement('div');\n\tprivate readonly tabs = new Map<InspectorTab, HTMLButtonElement>();\n\tprivate snapshot: FrameGraphDebugViewModel | undefined;\n\tprivate selected: Selection | undefined;\n\tprivate activeTab: InspectorTab = 'summary';\n\tprivate open = true;\n\tprivate hoveredLink: HTMLButtonElement | undefined;\n\n\tconstructor(\n\t\tprivate readonly callbacks: WorkbenchCallbacks,\n\t\tprivate readonly onOpenChange: (open: boolean) => void,\n\t\tidPrefix: string,\n\t) {\n\t\tthis.root.className = 'zenfg-inspector-inspector';\n\t\tthis.root.setAttribute('aria-label', 'Selection inspector');\n\t\tconst header = document.createElement('header');\n\t\tthis.title.textContent = 'Inspector';\n\t\tconst close = document.createElement('button');\n\t\tclose.type = 'button';\n\t\tclose.className = 'zenfg-inspector-inspector-close';\n\t\tclose.appendChild(createPanelIcon('close'));\n\t\tclose.title = 'Close inspector';\n\t\tclose.setAttribute('aria-label', 'Close inspector');\n\t\tclose.addEventListener('click', () => this.setOpen(false));\n\t\theader.append(this.title, close);\n\n\t\tthis.tabList.className = 'zenfg-inspector-inspector-tabs';\n\t\tthis.tabList.setAttribute('role', 'tablist');\n\t\tthis.tabList.setAttribute('aria-label', 'Inspector views');\n\t\tfor (const [tab, label] of [['summary', 'Summary'], ['relations', 'Relations'], ['raw', 'Raw']] as const) {\n\t\t\tconst button = document.createElement('button');\n\t\t\tbutton.type = 'button';\n\t\t\tbutton.id = `${idPrefix}-inspector-${tab}-tab`;\n\t\t\tbutton.textContent = label;\n\t\t\tbutton.setAttribute('role', 'tab');\n\t\t\tbutton.setAttribute('aria-controls', `${idPrefix}-inspector-panel`);\n\t\t\tbutton.addEventListener('click', () => {\n\t\t\t\tthis.activeTab = tab;\n\t\t\t\tthis.render();\n\t\t\t});\n\t\t\tthis.tabs.set(tab, button);\n\t\t\tthis.tabList.appendChild(button);\n\t\t}\n\t\tthis.content.id = `${idPrefix}-inspector-panel`;\n\t\tthis.content.className = 'zenfg-inspector-inspector-content';\n\t\tthis.content.setAttribute('role', 'tabpanel');\n\t\tthis.root.append(header, this.tabList, this.content);\n\t\tthis.updateOpenState();\n\t\tthis.render();\n\t}\n\n\tsetSnapshot(snapshot: FrameGraphDebugViewModel): void {\n\t\tthis.snapshot = snapshot;\n\t\tthis.render();\n\t}\n\n\tsetSelection(selected: Selection | undefined, reveal = true): void {\n\t\tif (selected?.kind === 'resource'\n\t\t\t&& (this.selected?.kind !== 'resource' || this.selected.id !== selected.id)) this.activeTab = 'summary';\n\t\tthis.selected = selected;\n\t\tif (selected && reveal) this.setOpen(true);\n\t\tthis.render();\n\t}\n\n\tsetOpen(open: boolean): void {\n\t\tif (this.open === open) return;\n\t\tif (!open) this.clearLinkHover();\n\t\tthis.open = open;\n\t\tthis.updateOpenState();\n\t\tthis.onOpenChange(open);\n\t}\n\n\tget isOpen(): boolean {\n\t\treturn this.open;\n\t}\n\n\tprivate updateOpenState(): void {\n\t\tthis.root.hidden = !this.open;\n\t\tthis.root.classList.toggle('open', this.open);\n\t}\n\n\tprivate render(): void {\n\t\tthis.clearLinkHover();\n\t\tfor (const [tab, button] of this.tabs) {\n\t\t\tconst active = tab === this.activeTab;\n\t\t\tbutton.classList.toggle('active', active);\n\t\t\tbutton.setAttribute('aria-selected', active ? 'true' : 'false');\n\t\t\tif (active) this.content.setAttribute('aria-labelledby', button.id);\n\t\t}\n\t\tconst snapshot = this.snapshot;\n\t\tconst selected = this.selected;\n\t\tthis.content.replaceChildren();\n\t\tif (!snapshot || !selected) {\n\t\t\tthis.title.textContent = 'Inspector';\n\t\t\tconst empty = document.createElement('p');\n\t\t\tempty.className = 'zenfg-inspector-muted';\n\t\t\tempty.textContent = 'Select a pass, group, resource, allocation, root, culled node, or segment.';\n\t\t\tthis.content.appendChild(empty);\n\t\t\treturn;\n\t\t}\n\t\tthis.title.textContent = this.selectionTitle(snapshot, selected);\n\t\tif (this.activeTab === 'raw') {\n\t\t\tconst raw = document.createElement('pre');\n\t\t\traw.className = 'zenfg-inspector-raw-detail';\n\t\t\traw.textContent = JSON.stringify(resolveSelectedDetail(snapshot, selected), null, 2);\n\t\t\tthis.content.appendChild(raw);\n\t\t} else if (this.activeTab === 'relations') {\n\t\t\tthis.content.appendChild(this.createRelations(snapshot, selected));\n\t\t} else {\n\t\t\tthis.content.appendChild(this.createSummary(snapshot, selected));\n\t\t}\n\t}\n\n\tprivate selectionTitle(snapshot: FrameGraphDebugViewModel, selection: Selection): string {\n\t\tswitch (selection.kind) {\n\t\t\tcase 'node': {\n\t\t\t\tconst node = snapshot.nodeById.get(selection.id);\n\t\t\t\treturn node ? labelNode(node) : `Pass #${selection.id}`;\n\t\t\t}\n\t\t\tcase 'group': return snapshot.groupByPathKey.get(selection.pathKey)?.label ?? 'Group';\n\t\t\tcase 'resource': {\n\t\t\t\tconst resource = snapshot.resourceById.get(selection.id);\n\t\t\t\treturn resource ? labelResource(resource) : `Resource #${selection.id}`;\n\t\t\t}\n\t\t\tcase 'allocation': return `Allocation #${selection.id}`;\n\t\t\tcase 'root': return 'Output root';\n\t\t\tcase 'culled': return `Culled node #${selection.index}`;\n\t\t\tcase 'segment': return `Segment #${selection.index}`;\n\t\t}\n\t}\n\n\tprivate createSummary(snapshot: FrameGraphDebugViewModel, selection: Selection): HTMLElement {\n\t\tswitch (selection.kind) {\n\t\t\tcase 'node': {\n\t\t\t\tconst node = snapshot.nodeById.get(selection.id);\n\t\t\t\tif (!node) return this.summary([]);\n\t\t\t\tconst segment = snapshot.segmentByNodeId.get(node.id);\n\t\t\t\treturn this.summary([\n\t\t\t\t\t['Kind', node.kind],\n\t\t\t\t\t['Order', String(node.order)],\n\t\t\t\t\t['Group', groupPath(snapshot, node.debugGroupId)],\n\t\t\t\t\t['Segment', segment ? `#${segment.index} ${segment.kind}` : '-'],\n\t\t\t\t\t['GPU', node.kind === 'external-submission' ? 'Opaque' : node.gpuDurationMicros === undefined ? 'Not timed' : `${(node.gpuDurationMicros / 1000).toFixed(3)} ms`],\n\t\t\t\t\t['Accesses', `${node.reads.length} reads · ${node.writes.length} writes`],\n\t\t\t\t\t['Side effect', node.sideEffect ? 'yes' : 'no'],\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcase 'group': {\n\t\t\t\tconst group = snapshot.groupByPathKey.get(selection.pathKey);\n\t\t\t\tif (!group) return this.summary([]);\n\t\t\t\treturn this.summary([\n\t\t\t\t\t['Path', group.path.join(' / ')],\n\t\t\t\t\t['Retained', String(group.summary.retainedNodeCount)],\n\t\t\t\t\t['Culled', String(group.summary.culledNodeCount)],\n\t\t\t\t\t['GPU coverage', `${group.summary.timedNodeCount}/${group.summary.timingEligibleNodeCount}`],\n\t\t\t\t\t['GPU work', `${(group.summary.gpuWorkDurationMicros / 1000).toFixed(3)} ms`],\n\t\t\t\t\t['Allocations', String(group.summary.physicalAllocationCount)],\n\t\t\t\t\t['Segments', String(group.summary.executionSegmentCount)],\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcase 'resource': {\n\t\t\t\tconst resource = snapshot.resourceById.get(selection.id);\n\t\t\t\tif (!resource) return this.summary([]);\n\t\t\t\treturn this.summary([\n\t\t\t\t\t['Kind / origin', `${resource.kind} · ${resource.origin}`],\n\t\t\t\t\t['Group', groupPath(snapshot, resource.debugGroupId)],\n\t\t\t\t\t['Descriptor', formatResourceDescriptor(resource)],\n\t\t\t\t\t['Estimated', formatEstimatedBytes(resource.estimatedByteSize)],\n\t\t\t\t\t['Lifetime', resource.lifetime ? `${resource.lifetime.firstUse}–${resource.lifetime.lastUse}` : '-'],\n\t\t\t\t\t['Allocation', resource.physicalResourceId === undefined ? '-' : `#${resource.physicalResourceId}`],\n\t\t\t\t\t['Usage', resource.usageFlags.join(', ') || '-'],\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcase 'allocation': {\n\t\t\t\tconst allocation = snapshot.allocationById.get(selection.id);\n\t\t\t\tif (!allocation) return this.summary([]);\n\t\t\t\treturn this.summary([\n\t\t\t\t\t['Kind', allocation.kind],\n\t\t\t\t\t['Compatibility class', String(allocation.compatibilityClassId)],\n\t\t\t\t\t['Estimated', formatEstimatedBytes(allocation.estimatedByteSize)],\n\t\t\t\t\t['Logical resources', String(allocation.resourceIds.length)],\n\t\t\t\t\t['Alias', allocation.resourceIds.length > 1 ? `yes · ×${allocation.resourceIds.length}` : 'single'],\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcase 'root': {\n\t\t\t\tconst root = snapshot.roots.find((root) => root.key === selection.key);\n\t\t\t\treturn this.summary(root ? [\n\t\t\t\t\t['Reason', root.reason],\n\t\t\t\t\t['Node', root.nodeId === undefined ? '-' : `#${root.nodeId}`],\n\t\t\t\t\t['Resource', root.resource ? this.viewResourceButton(snapshot, root.resource.id) : '-'],\n\t\t\t\t\t...(root.reason === 'side-effect' ? [] : [\n\t\t\t\t\t\t['Range', root.range ? JSON.stringify(root.range) : 'Unavailable in Legacy capture'],\n\t\t\t\t\t\t['Initial contents', root.resolution ? String(root.resolution.usesInitialContents) : 'Unavailable in Legacy capture'],\n\t\t\t\t\t\t['Producers', root.resolution ? root.resolution.producerNodeIds.join(', ') || 'None' : 'Unavailable in Legacy capture'],\n\t\t\t\t\t] as [string, string][]),\n\t\t\t\t] : []);\n\t\t\t}\n\t\t\tcase 'culled': {\n\t\t\t\tconst culled = snapshot.culledNodes[selection.index];\n\t\t\t\treturn this.summary(culled ? [\n\t\t\t\t\t['Node', labelNode(culled.node)],\n\t\t\t\t\t['Kind', culled.node.kind],\n\t\t\t\t\t['Group', groupPath(snapshot, culled.node.debugGroupId)],\n\t\t\t\t\t['Reason', culled.reason],\n\t\t\t\t\t['Accesses', `${culled.node.reads.length} reads · ${culled.node.writes.length} writes`],\n\t\t\t\t] : []);\n\t\t\t}\n\t\t\tcase 'segment': {\n\t\t\t\tconst segment = snapshot.segmentByIndex.get(selection.index);\n\t\t\t\treturn this.summary(segment ? [\n\t\t\t\t\t['Kind', segment.kind === 'frame-graph' ? 'FrameGraph command segment' : 'Opaque interval'],\n\t\t\t\t\t['Nodes', String(segment.nodeIds.length)],\n\t\t\t\t\t['Meaning', segment.kind === 'external-submission'\n\t\t\t\t\t\t? 'Boundary around external work; not an actual third-party submission count.'\n\t\t\t\t\t\t: 'Contiguous FrameGraph-encoded command work.'],\n\t\t\t\t] : []);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate createRelations(snapshot: FrameGraphDebugViewModel, selection: Selection): HTMLElement {\n\t\tconst host = document.createElement('div');\n\t\thost.className = 'zenfg-inspector-inspector-relations';\n\t\tswitch (selection.kind) {\n\t\t\tcase 'node': {\n\t\t\t\tconst node = snapshot.nodeById.get(selection.id);\n\t\t\t\tif (node) {\n\t\t\t\t\thost.append(\n\t\t\t\t\t\tthis.accessRelations('Reads', node.reads),\n\t\t\t\t\t\tthis.accessRelations('Writes', node.writes),\n\t\t\t\t\t);\n\t\t\t\t\tconst segment = snapshot.segmentByNodeId.get(node.id);\n\t\t\t\t\tif (segment) host.appendChild(this.relationGroup('Segment', [\n\t\t\t\t\t\t[`#${segment.index} ${segment.kind}`, { kind: 'segment', index: segment.index }],\n\t\t\t\t\t]));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'group': {\n\t\t\t\tconst group = snapshot.groupByPathKey.get(selection.pathKey);\n\t\t\t\tif (group) {\n\t\t\t\t\thost.append(\n\t\t\t\t\t\tthis.resourceRelations('Inputs', group.summary.inputResources),\n\t\t\t\t\t\tthis.resourceRelations('Outputs', group.summary.outputResources),\n\t\t\t\t\t\tthis.relationGroup('Output roots', group.summary.outputRoots.map((root) => [\n\t\t\t\t\t\t\t`${root.resource ? labelResource(root.resource) : '-'} · ${root.reason} · ${root.range ? JSON.stringify(root.range) : 'Range unavailable'}`,\n\t\t\t\t\t\t\t{ kind: 'root', key: root.key },\n\t\t\t\t\t\t])),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'resource': {\n\t\t\t\tconst resource = snapshot.resourceById.get(selection.id);\n\t\t\t\tconst accesses = snapshot.accessesByResourceId.get(selection.id) ?? [];\n\t\t\t\tconst passRelations: DetailRelation[] = [];\n\t\t\t\tfor (const access of accesses) {\n\t\t\t\t\tconst nodeSelection = this.accessNodeSelection(snapshot, access.nodeId);\n\t\t\t\t\tif (nodeSelection) passRelations.push([\n\t\t\t\t\t\tthis.accessNodeLabel(snapshot, access.nodeId),\n\t\t\t\t\t\tnodeSelection,\n\t\t\t\t\t\tformatAccessFacts(access),\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t\thost.appendChild(this.relationGroup('Pass accesses', passRelations));\n\t\t\t\tconst roots = snapshot.roots.filter((root) => root.resource?.id === selection.id);\n\t\t\t\tif (roots.length) host.appendChild(this.relationGroup('Output roots', roots.map((root) => [\n\t\t\t\t\t`${root.reason} · ${formatRootRange(root)}`, { kind: 'root', key: root.key },\n\t\t\t\t])));\n\t\t\t\tif (resource?.physicalResourceId !== undefined) host.appendChild(this.relationGroup('Allocation', [\n\t\t\t\t\t[`#${resource.physicalResourceId}`, { kind: 'allocation', id: resource.physicalResourceId }],\n\t\t\t\t]));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'allocation': {\n\t\t\t\tconst allocation = snapshot.allocationById.get(selection.id);\n\t\t\t\tif (allocation) host.appendChild(this.relationGroup('Logical resources', allocation.resourceIds.map((id) => [\n\t\t\t\t\tresourceLabel(snapshot, id), { kind: 'resource', id },\n\t\t\t\t])));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'root': {\n\t\t\t\tconst root = snapshot.roots.find((root) => root.key === selection.key);\n\t\t\t\tconst relations: Array<readonly [string, Selection]> = [];\n\t\t\t\tif (root?.nodeId !== undefined && snapshot.nodeById.has(root.nodeId)) relations.push([\n\t\t\t\t\tthis.accessNodeLabel(snapshot, root.nodeId), { kind: 'node', id: root.nodeId },\n\t\t\t\t]);\n\t\t\t\tif (root?.resource) host.appendChild(this.relationGroup('Resource', [[labelResource(root.resource), { kind: 'resource', id: root.resource.id }]]));\n\t\t\t\tif (root?.resource && root.resolution?.usesInitialContents) relations.push([`Initial contents · ${labelResource(root.resource)}`, { kind: 'resource', id: root.resource.id }]);\n\t\t\t\tfor (const id of root?.resolution?.producerNodeIds ?? []) relations.push([this.accessNodeLabel(snapshot, id), { kind: 'node', id }]);\n\t\t\t\thost.appendChild(this.relationGroup('Output sources', relations));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'culled': {\n\t\t\t\tconst culled = snapshot.culledNodes[selection.index];\n\t\t\t\tif (culled) host.append(\n\t\t\t\t\tthis.accessRelations('Reads', culled.node.reads),\n\t\t\t\t\tthis.accessRelations('Writes', culled.node.writes),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'segment': {\n\t\t\t\tconst segment = snapshot.segmentByIndex.get(selection.index);\n\t\t\t\tif (segment) host.appendChild(this.relationGroup('Passes', segment.nodeIds.flatMap((id) => {\n\t\t\t\t\tconst node = snapshot.nodeById.get(id);\n\t\t\t\t\treturn node ? [[labelNode(node), { kind: 'node', id }] as const] : [];\n\t\t\t\t})));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (host.childElementCount === 0) {\n\t\t\tconst empty = document.createElement('p');\n\t\t\tempty.className = 'zenfg-inspector-muted';\n\t\t\tempty.textContent = 'No related objects.';\n\t\t\thost.appendChild(empty);\n\t\t}\n\t\treturn host;\n\t}\n\n\tprivate accessRelations(title: string, accesses: readonly FrameGraphDebugAccess[]): HTMLElement {\n\t\treturn this.relationGroup(title, accesses.map((access) => [\n\t\t\tlabelResource(access.resource),\n\t\t\t{ kind: 'resource', id: access.resource.id },\n\t\t\tformatAccessFacts(access),\n\t\t]));\n\t}\n\n\tprivate resourceRelations(title: string, resources: readonly FrameGraphDebugResourceRef[]): HTMLElement {\n\t\treturn this.relationGroup(title, resources.map((resource) => [\n\t\t\tlabelResource(resource), { kind: 'resource', id: resource.id },\n\t\t]));\n\t}\n\n\tprivate relationGroup(title: string, relations: readonly DetailRelation[]): HTMLElement {\n\t\tconst section = document.createElement('section');\n\t\tconst heading = document.createElement('h3');\n\t\theading.textContent = `${title} ${relations.length}`;\n\t\tsection.appendChild(heading);\n\t\tfor (const [label, selection, description] of relations) {\n\t\t\tconst link = this.createDetailLink(label, selection);\n\t\t\tif (description === undefined) {\n\t\t\t\tsection.appendChild(link);\n\t\t\t} else {\n\t\t\t\tconst entry = document.createElement('div');\n\t\t\t\tentry.className = 'zenfg-inspector-relation-entry';\n\t\t\t\tconst metadata = document.createElement('span');\n\t\t\t\tmetadata.className = 'zenfg-inspector-muted';\n\t\t\t\tmetadata.textContent = description;\n\t\t\t\tentry.append(link, metadata);\n\t\t\t\tsection.appendChild(entry);\n\t\t\t}\n\t\t}\n\t\tif (relations.length === 0) {\n\t\t\tconst empty = document.createElement('span');\n\t\t\tempty.className = 'zenfg-inspector-muted';\n\t\t\tempty.textContent = 'None';\n\t\t\tsection.appendChild(empty);\n\t\t}\n\t\treturn section;\n\t}\n\n\tprivate selectRelated(selection: Selection): void {\n\t\tthis.clearLinkHover();\n\t\tthis.callbacks.onSelect(selection);\n\t}\n\n\tprivate viewResourceButton(snapshot: FrameGraphDebugViewModel, resourceId: string): HTMLButtonElement {\n\t\treturn this.createDetailLink(`View resource · ${resourceLabel(snapshot, resourceId)}`,\n\t\t\t{ kind: 'resource', id: resourceId });\n\t}\n\n\tprivate createDetailLink(label: string, selection: Selection): HTMLButtonElement {\n\t\tconst link = createRelationButton(label, selection, (target) => this.selectRelated(target));\n\t\tlink.addEventListener('mouseenter', () => {\n\t\t\tthis.hoveredLink = link;\n\t\t\tthis.callbacks.onHover(selection);\n\t\t});\n\t\tlink.addEventListener('mouseleave', () => {\n\t\t\tif (this.hoveredLink === link) this.clearLinkHover();\n\t\t});\n\t\treturn link;\n\t}\n\n\tprivate clearLinkHover(): void {\n\t\tif (!this.hoveredLink) return;\n\t\tthis.hoveredLink = undefined;\n\t\tthis.callbacks.onHover(undefined);\n\t}\n\n\tprivate summary(rows: readonly (readonly [string, string | HTMLElement])[]): HTMLElement {\n\t\tconst summary = document.createElement('dl');\n\t\tsummary.className = 'zenfg-inspector-inspector-summary';\n\t\tfor (const [label, value] of rows) {\n\t\t\tconst term = document.createElement('dt');\n\t\t\tterm.textContent = label;\n\t\t\tconst description = document.createElement('dd');\n\t\t\tif (typeof value === 'string') {\n\t\t\t\tdescription.textContent = value;\n\t\t\t\tdescription.title = value;\n\t\t\t} else {\n\t\t\t\tdescription.appendChild(value);\n\t\t\t}\n\t\t\tsummary.append(term, description);\n\t\t}\n\t\treturn summary;\n\t}\n\n\tprivate accessNodeLabel(snapshot: FrameGraphDebugViewModel, nodeId: string): string {\n\t\tconst node = snapshot.nodeById.get(nodeId);\n\t\tif (node) return labelNode(node);\n\t\tconst culled = snapshot.culledNodes.find((candidate) => candidate.node.id === nodeId);\n\t\treturn culled ? `${labelNode(culled.node)} (culled)` : `node-${nodeId}`;\n\t}\n\n\tprivate accessNodeSelection(snapshot: FrameGraphDebugViewModel, nodeId: string): Selection | undefined {\n\t\tif (snapshot.nodeById.has(nodeId)) return { kind: 'node', id: nodeId };\n\t\tconst index = snapshot.culledNodes.findIndex((candidate) => candidate.node.id === nodeId);\n\t\treturn index < 0 ? undefined : { kind: 'culled', index };\n\t}\n}\n"]}
@@ -20,7 +20,7 @@ export function resolveSelectedDetail(snapshot, selected) {
20
20
  case 'group':
21
21
  return snapshot.groupByPathKey.get(selected.pathKey);
22
22
  case 'root':
23
- return snapshot.roots[selected.index];
23
+ return snapshot.roots.find((root) => root.key === selected.key);
24
24
  case 'culled': {
25
25
  const culled = snapshot.culledNodes[selected.index];
26
26
  return culled ? {
@@ -47,7 +47,7 @@ export function selectionExists(snapshot, selected) {
47
47
  case 'resource':
48
48
  return snapshot.resourceById.has(selected.id);
49
49
  case 'root':
50
- return isValidIndex(selected.index, snapshot.roots.length);
50
+ return snapshot.roots.filter((root) => root.key === selected.key).length === 1;
51
51
  case 'culled':
52
52
  return isValidIndex(selected.index, snapshot.culledNodes.length);
53
53
  case 'allocation':
@@ -1 +1 @@
1
- {"version":3,"file":"panelSelection.js","sourceRoot":"","sources":["../src/panelSelection.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,qBAAqB,CACpC,QAAkC,EAClC,QAA+B;IAE/B,IAAI,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE/B,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,CAAC,CAAC;YACb,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAChD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACnE,OAAO,IAAI;gBACV,CAAC,CAAC;oBACD,GAAG,IAAI;oBACP,cAAc,EAAE,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC;oBAC3D,gBAAgB;oBAChB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;oBACxE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;iBAC1E;gBACD,CAAC,CAAC,SAAS,CAAC;QACd,CAAC;QACD,KAAK,UAAU;YACd,OAAO,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACrD,KAAK,OAAO;YACX,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACtD,KAAK,MAAM;YACV,OAAO,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACvC,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACpD,OAAO,MAAM,CAAC,CAAC,CAAC;gBACf,GAAG,MAAM;gBACT,IAAI,EAAE;oBACL,GAAG,MAAM,CAAC,IAAI;oBACd,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;oBAC/E,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;iBACjF;aACD,CAAC,CAAC,CAAC,SAAS,CAAC;QACf,CAAC;QACD,KAAK,YAAY;YAChB,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACjD,KAAK,SAAS;YACb,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;AACF,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAkC,EAAE,QAAmB;IACtF,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM;YACV,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC3C,KAAK,OAAO;YACX,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACtD,KAAK,UAAU;YACd,OAAO,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC/C,KAAK,MAAM;YACV,OAAO,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5D,KAAK,QAAQ;YACZ,OAAO,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClE,KAAK,YAAY;YAChB,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACjD,KAAK,SAAS;YACb,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;AACF,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAkC,EAAE,UAAkB;IACpF,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,QAAQ,GAAG,CAAC,QAAQ,CAAC,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;SACpE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACzD,OAAO;QACN,GAAG,QAAQ;QACX,cAAc,EAAE,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC;QAC/D,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC;QAC5D,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC;KAC1D,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC3B,QAAkC,EAClC,MAAe;IAEf,OAAO,MAAM,CAAC,aAAa,KAAK,SAAS;QACxC,CAAC,CAAC,MAAM;QACR,CAAC,CAAC;YACD,GAAG,MAAM;YACT,WAAW,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC;SAC/D,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,QAAkC,EAAE,OAA2B;IACtF,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IACtC,OAAO,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;AAC3E,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,MAAc;IAClD,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,MAAM,CAAC;AAChE,CAAC","sourcesContent":["import type { FrameGraphDebugViewModel } from './debugCaptureModel.ts';\nimport type { Selection } from './panelTypes.ts';\n\nexport function resolveSelectedDetail(\n\tsnapshot: FrameGraphDebugViewModel,\n\tselected: Selection | undefined,\n): unknown {\n\tif (!selected) return snapshot;\n\n\tswitch (selected.kind) {\n\t\tcase 'node': {\n\t\t\tconst node = snapshot.nodeById.get(selected.id);\n\t\t\tconst executionSegment = snapshot.segmentByNodeId.get(selected.id);\n\t\t\treturn node\n\t\t\t\t? {\n\t\t\t\t\t...node,\n\t\t\t\t\tdebugGroupPath: debugGroupPath(snapshot, node.debugGroupId),\n\t\t\t\t\texecutionSegment,\n\t\t\t\t\treads: node.reads.map((access) => resolveAccessDetail(snapshot, access)),\n\t\t\t\t\twrites: node.writes.map((access) => resolveAccessDetail(snapshot, access)),\n\t\t\t\t}\n\t\t\t\t: undefined;\n\t\t}\n\t\tcase 'resource':\n\t\t\treturn resolveResourceDetail(snapshot, selected.id);\n\t\tcase 'group':\n\t\t\treturn snapshot.groupByPathKey.get(selected.pathKey);\n\t\tcase 'root':\n\t\t\treturn snapshot.roots[selected.index];\n\t\tcase 'culled': {\n\t\t\tconst culled = snapshot.culledNodes[selected.index];\n\t\t\treturn culled ? {\n\t\t\t\t...culled,\n\t\t\t\tnode: {\n\t\t\t\t\t...culled.node,\n\t\t\t\t\treads: culled.node.reads.map((access) => resolveAccessDetail(snapshot, access)),\n\t\t\t\t\twrites: culled.node.writes.map((access) => resolveAccessDetail(snapshot, access)),\n\t\t\t\t},\n\t\t\t} : undefined;\n\t\t}\n\t\tcase 'allocation':\n\t\t\treturn snapshot.allocationById.get(selected.id);\n\t\tcase 'segment':\n\t\t\treturn snapshot.segmentByIndex.get(selected.index);\n\t}\n}\n\nexport function selectionExists(snapshot: FrameGraphDebugViewModel, selected: Selection): boolean {\n\tswitch (selected.kind) {\n\t\tcase 'node':\n\t\t\treturn snapshot.nodeById.has(selected.id);\n\t\tcase 'group':\n\t\t\treturn snapshot.groupByPathKey.has(selected.pathKey);\n\t\tcase 'resource':\n\t\t\treturn snapshot.resourceById.has(selected.id);\n\t\tcase 'root':\n\t\t\treturn isValidIndex(selected.index, snapshot.roots.length);\n\t\tcase 'culled':\n\t\t\treturn isValidIndex(selected.index, snapshot.culledNodes.length);\n\t\tcase 'allocation':\n\t\t\treturn snapshot.allocationById.has(selected.id);\n\t\tcase 'segment':\n\t\t\treturn snapshot.segmentByIndex.has(selected.index);\n\t}\n}\n\nfunction resolveResourceDetail(snapshot: FrameGraphDebugViewModel, resourceId: string): unknown {\n\tconst resource = snapshot.resourceById.get(resourceId);\n\tif (!resource) return undefined;\n\tconst accesses = (snapshot.accessesByResourceId.get(resourceId) ?? [])\n\t\t.map((access) => resolveAccessDetail(snapshot, access));\n\treturn {\n\t\t...resource,\n\t\tdebugGroupPath: debugGroupPath(snapshot, resource.debugGroupId),\n\t\twrites: accesses.filter((access) => access.mode === 'write'),\n\t\treads: accesses.filter((access) => access.mode === 'read'),\n\t};\n}\n\nfunction resolveAccessDetail<TAccess extends { readonly textureViewId?: string }>(\n\tsnapshot: FrameGraphDebugViewModel,\n\taccess: TAccess,\n): TAccess & { readonly textureView?: FrameGraphDebugViewModel['protocol']['graph']['textureViews'][number] } {\n\treturn access.textureViewId === undefined\n\t\t? access\n\t\t: {\n\t\t\t...access,\n\t\t\ttextureView: snapshot.textureViewById.get(access.textureViewId),\n\t\t};\n}\n\nfunction debugGroupPath(snapshot: FrameGraphDebugViewModel, groupId: string | undefined): string {\n\tif (groupId === undefined) return '-';\n\treturn snapshot.groupById.get(groupId)?.path.join(' / ') ?? `#${groupId}`;\n}\n\nfunction isValidIndex(index: number, length: number): boolean {\n\treturn Number.isInteger(index) && index >= 0 && index < length;\n}\n"]}
1
+ {"version":3,"file":"panelSelection.js","sourceRoot":"","sources":["../src/panelSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameGraphDebugViewModel } from './debugCaptureModel.ts';\nimport type { Selection } from './panelTypes.ts';\n\nexport function resolveSelectedDetail(\n\tsnapshot: FrameGraphDebugViewModel,\n\tselected: Selection | undefined,\n): unknown {\n\tif (!selected) return snapshot;\n\n\tswitch (selected.kind) {\n\t\tcase 'node': {\n\t\t\tconst node = snapshot.nodeById.get(selected.id);\n\t\t\tconst executionSegment = snapshot.segmentByNodeId.get(selected.id);\n\t\t\treturn node\n\t\t\t\t? {\n\t\t\t\t\t...node,\n\t\t\t\t\tdebugGroupPath: debugGroupPath(snapshot, node.debugGroupId),\n\t\t\t\t\texecutionSegment,\n\t\t\t\t\treads: node.reads.map((access) => resolveAccessDetail(snapshot, access)),\n\t\t\t\t\twrites: node.writes.map((access) => resolveAccessDetail(snapshot, access)),\n\t\t\t\t}\n\t\t\t\t: undefined;\n\t\t}\n\t\tcase 'resource':\n\t\t\treturn resolveResourceDetail(snapshot, selected.id);\n\t\tcase 'group':\n\t\t\treturn snapshot.groupByPathKey.get(selected.pathKey);\n\t\tcase 'root':\n\t\t\treturn snapshot.roots.find((root) => root.key === selected.key);\n\t\tcase 'culled': {\n\t\t\tconst culled = snapshot.culledNodes[selected.index];\n\t\t\treturn culled ? {\n\t\t\t\t...culled,\n\t\t\t\tnode: {\n\t\t\t\t\t...culled.node,\n\t\t\t\t\treads: culled.node.reads.map((access) => resolveAccessDetail(snapshot, access)),\n\t\t\t\t\twrites: culled.node.writes.map((access) => resolveAccessDetail(snapshot, access)),\n\t\t\t\t},\n\t\t\t} : undefined;\n\t\t}\n\t\tcase 'allocation':\n\t\t\treturn snapshot.allocationById.get(selected.id);\n\t\tcase 'segment':\n\t\t\treturn snapshot.segmentByIndex.get(selected.index);\n\t}\n}\n\nexport function selectionExists(snapshot: FrameGraphDebugViewModel, selected: Selection): boolean {\n\tswitch (selected.kind) {\n\t\tcase 'node':\n\t\t\treturn snapshot.nodeById.has(selected.id);\n\t\tcase 'group':\n\t\t\treturn snapshot.groupByPathKey.has(selected.pathKey);\n\t\tcase 'resource':\n\t\t\treturn snapshot.resourceById.has(selected.id);\n\t\tcase 'root':\n\t\t\treturn snapshot.roots.filter((root) => root.key === selected.key).length === 1;\n\t\tcase 'culled':\n\t\t\treturn isValidIndex(selected.index, snapshot.culledNodes.length);\n\t\tcase 'allocation':\n\t\t\treturn snapshot.allocationById.has(selected.id);\n\t\tcase 'segment':\n\t\t\treturn snapshot.segmentByIndex.has(selected.index);\n\t}\n}\n\nfunction resolveResourceDetail(snapshot: FrameGraphDebugViewModel, resourceId: string): unknown {\n\tconst resource = snapshot.resourceById.get(resourceId);\n\tif (!resource) return undefined;\n\tconst accesses = (snapshot.accessesByResourceId.get(resourceId) ?? [])\n\t\t.map((access) => resolveAccessDetail(snapshot, access));\n\treturn {\n\t\t...resource,\n\t\tdebugGroupPath: debugGroupPath(snapshot, resource.debugGroupId),\n\t\twrites: accesses.filter((access) => access.mode === 'write'),\n\t\treads: accesses.filter((access) => access.mode === 'read'),\n\t};\n}\n\nfunction resolveAccessDetail<TAccess extends { readonly textureViewId?: string }>(\n\tsnapshot: FrameGraphDebugViewModel,\n\taccess: TAccess,\n): TAccess & { readonly textureView?: FrameGraphDebugViewModel['protocol']['graph']['textureViews'][number] } {\n\treturn access.textureViewId === undefined\n\t\t? access\n\t\t: {\n\t\t\t...access,\n\t\t\ttextureView: snapshot.textureViewById.get(access.textureViewId),\n\t\t};\n}\n\nfunction debugGroupPath(snapshot: FrameGraphDebugViewModel, groupId: string | undefined): string {\n\tif (groupId === undefined) return '-';\n\treturn snapshot.groupById.get(groupId)?.path.join(' / ') ?? `#${groupId}`;\n}\n\nfunction isValidIndex(index: number, length: number): boolean {\n\treturn Number.isInteger(index) && index >= 0 && index < length;\n}\n"]}
@@ -1,4 +1,11 @@
1
1
  import type { GraphRenderer } from './panelGraphRenderer.ts';
2
+ import type { FrameGraphDebugEdge } from './debugCaptureModel.ts';
3
+ export type GraphFlowRelation = {
4
+ readonly role: 'declaration' | 'value' | 'ordering' | 'output-producer' | 'output-initial';
5
+ readonly nodeIds: readonly string[];
6
+ readonly rootKey?: string;
7
+ readonly dependency?: FrameGraphDebugEdge;
8
+ };
2
9
  export type Selection = {
3
10
  kind: 'node';
4
11
  id: string;
@@ -10,7 +17,7 @@ export type Selection = {
10
17
  id: string;
11
18
  } | {
12
19
  kind: 'root';
13
- index: number;
20
+ key: string;
14
21
  } | {
15
22
  kind: 'culled';
16
23
  index: number;
@@ -24,13 +31,11 @@ export type Selection = {
24
31
  export type WorkbenchTab = 'overview' | 'graph' | 'passes' | 'resources' | 'memory' | 'diagnostics';
25
32
  export type PassesSubview = 'list' | 'groups';
26
33
  export type InspectorTab = 'summary' | 'relations' | 'raw';
27
- export type GraphViewMode = 'passes' | 'resources';
28
34
  export type GraphViewState = {
29
35
  readonly host: HTMLElement;
30
36
  readonly toolbar: HTMLElement;
31
37
  readonly legend?: HTMLElement;
32
38
  readonly layoutElementBudget?: number;
33
- graphMode: GraphViewMode;
34
39
  groupsEnabled: boolean;
35
40
  readonly expandedGroupPaths: Set<string>;
36
41
  renderer?: GraphRenderer;
@@ -1 +1 @@
1
- {"version":3,"file":"panelTypes.d.ts","sourceRoot":"","sources":["../src/panelTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,MAAM,SAAS,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,aAAa,CAAC;AACpG,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AAC9C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,KAAK,CAAC;AAC3D,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEnD,MAAM,MAAM,cAAc,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACnC,SAAS,EAAE,aAAa,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACxC,CAAC"}
1
+ {"version":3,"file":"panelTypes.d.ts","sourceRoot":"","sources":["../src/panelTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAElE,MAAM,MAAM,iBAAiB,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAC3F,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,SAAS,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,aAAa,CAAC;AACpG,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AAC9C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,KAAK,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACnC,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACxC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"panelTypes.js","sourceRoot":"","sources":["../src/panelTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { GraphRenderer } from './panelGraphRenderer.ts';\n\nexport type Selection =\n | { kind: 'node'; id: string }\n | { kind: 'group'; pathKey: string }\n | { kind: 'resource'; id: string }\n | { kind: 'root'; index: number }\n | { kind: 'culled'; index: number }\n | { kind: 'allocation'; id: string }\n | { kind: 'segment'; index: number };\n\nexport type WorkbenchTab = 'overview' | 'graph' | 'passes' | 'resources' | 'memory' | 'diagnostics';\nexport type PassesSubview = 'list' | 'groups';\nexport type InspectorTab = 'summary' | 'relations' | 'raw';\nexport type GraphViewMode = 'passes' | 'resources';\n\nexport type GraphViewState = {\n readonly host: HTMLElement;\n readonly toolbar: HTMLElement;\n readonly legend?: HTMLElement;\n\treadonly layoutElementBudget?: number;\n graphMode: GraphViewMode;\n groupsEnabled: boolean;\n readonly expandedGroupPaths: Set<string>;\n renderer?: GraphRenderer;\n fitOnNextRender: boolean;\n anchorElementIdOnNextRender?: string;\n};\n"]}
1
+ {"version":3,"file":"panelTypes.js","sourceRoot":"","sources":["../src/panelTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { GraphRenderer } from './panelGraphRenderer.ts';\nimport type { FrameGraphDebugEdge } from './debugCaptureModel.ts';\n\nexport type GraphFlowRelation = {\n readonly role: 'declaration' | 'value' | 'ordering' | 'output-producer' | 'output-initial';\n readonly nodeIds: readonly string[];\n readonly rootKey?: string;\n readonly dependency?: FrameGraphDebugEdge;\n};\n\nexport type Selection =\n | { kind: 'node'; id: string }\n | { kind: 'group'; pathKey: string }\n | { kind: 'resource'; id: string }\n | { kind: 'root'; key: string }\n | { kind: 'culled'; index: number }\n | { kind: 'allocation'; id: string }\n | { kind: 'segment'; index: number };\n\nexport type WorkbenchTab = 'overview' | 'graph' | 'passes' | 'resources' | 'memory' | 'diagnostics';\nexport type PassesSubview = 'list' | 'groups';\nexport type InspectorTab = 'summary' | 'relations' | 'raw';\n\nexport type GraphViewState = {\n readonly host: HTMLElement;\n readonly toolbar: HTMLElement;\n readonly legend?: HTMLElement;\n\treadonly layoutElementBudget?: number;\n groupsEnabled: boolean;\n readonly expandedGroupPaths: Set<string>;\n renderer?: GraphRenderer;\n fitOnNextRender: boolean;\n anchorElementIdOnNextRender?: string;\n};\n"]}
@@ -22,28 +22,36 @@ export declare const GRAPH_VISUAL_THEME: {
22
22
  readonly text: "#e6edf3";
23
23
  readonly muted: "#8b98a5";
24
24
  readonly render: {
25
- readonly stroke: "#34d399";
26
- readonly fill: "#12342b";
25
+ stroke: string;
26
+ fill: string;
27
27
  };
28
28
  readonly compute: {
29
- readonly stroke: "#60a5fa";
30
- readonly fill: "#162c46";
29
+ stroke: string;
30
+ fill: string;
31
31
  };
32
32
  readonly copy: {
33
- readonly stroke: "#fbbf24";
34
- readonly fill: "#3a2d12";
33
+ stroke: string;
34
+ fill: string;
35
35
  };
36
36
  readonly clear: {
37
- readonly stroke: "#94a3b8";
38
- readonly fill: "#25303a";
37
+ stroke: string;
38
+ fill: string;
39
39
  };
40
40
  readonly command: {
41
- readonly stroke: "#c084fc";
42
- readonly fill: "#322044";
41
+ stroke: string;
42
+ fill: string;
43
43
  };
44
44
  readonly external: {
45
- readonly stroke: "#fb923c";
46
- readonly fill: "#402318";
45
+ stroke: string;
46
+ fill: string;
47
+ };
48
+ readonly declaration: {
49
+ stroke: string;
50
+ fill: string;
51
+ };
52
+ readonly output: {
53
+ stroke: string;
54
+ fill: string;
47
55
  };
48
56
  readonly texture: {
49
57
  readonly stroke: "#f472b6";
@@ -60,7 +68,7 @@ export declare const GRAPH_VISUAL_THEME: {
60
68
  };
61
69
  readonly dependency: {
62
70
  readonly value: "#94a3b8";
63
- readonly ordering: "#64748b";
71
+ readonly ordering: "#8593a6";
64
72
  };
65
73
  readonly access: {
66
74
  readonly read: "#2dd4bf";
@@ -1 +1 @@
1
- {"version":3,"file":"panelVisualTheme.d.ts","sourceRoot":"","sources":["../src/panelVisualTheme.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;CAgBjC,CAAC;AAEX,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoBrB,CAAC"}
1
+ {"version":3,"file":"panelVisualTheme.d.ts","sourceRoot":"","sources":["../src/panelVisualTheme.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;CAgBjC,CAAC;AAWX,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsBrB,CAAC"}
@@ -15,22 +15,30 @@ export const FRAME_GRAPH_DEBUG_VISUAL_THEME = {
15
15
  fontUi: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
16
16
  fontMono: 'ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace',
17
17
  };
18
+ function category(stroke) {
19
+ const canvas = FRAME_GRAPH_DEBUG_VISUAL_THEME.canvas;
20
+ const fill = '#' + [1, 3, 5].map((offset) => Math.round(parseInt(stroke.slice(offset, offset + 2), 16) * 0.18
21
+ + parseInt(canvas.slice(offset, offset + 2), 16) * 0.82).toString(16).padStart(2, '0')).join('');
22
+ return { stroke, fill };
23
+ }
18
24
  export const GRAPH_VISUAL_THEME = {
19
25
  canvas: FRAME_GRAPH_DEBUG_VISUAL_THEME.canvas,
20
26
  surface: FRAME_GRAPH_DEBUG_VISUAL_THEME.surface,
21
27
  surfaceRaised: FRAME_GRAPH_DEBUG_VISUAL_THEME.surfaceRaised,
22
28
  text: FRAME_GRAPH_DEBUG_VISUAL_THEME.text,
23
29
  muted: FRAME_GRAPH_DEBUG_VISUAL_THEME.muted,
24
- render: { stroke: '#34d399', fill: '#12342b' },
25
- compute: { stroke: '#60a5fa', fill: '#162c46' },
26
- copy: { stroke: '#fbbf24', fill: '#3a2d12' },
27
- clear: { stroke: '#94a3b8', fill: '#25303a' },
28
- command: { stroke: '#c084fc', fill: '#322044' },
29
- external: { stroke: '#fb923c', fill: '#402318' },
30
+ render: category('#57C785'),
31
+ compute: category('#9AA5FF'),
32
+ copy: category('#F2CD60'),
33
+ clear: category('#C4CF89'),
34
+ command: category('#CF91E8'),
35
+ external: category('#F29A67'),
36
+ declaration: category('#B9AB94'),
37
+ output: category('#EC91AE'),
30
38
  texture: { stroke: '#f472b6', fill: '#3c1f32' },
31
39
  buffer: { stroke: '#2dd4bf', fill: '#123632' },
32
40
  group: { stroke: '#64748b', fill: '#141c29', alternateFill: '#172033' },
33
- dependency: { value: '#94a3b8', ordering: '#64748b' },
41
+ dependency: { value: '#94a3b8', ordering: '#8593a6' },
34
42
  access: { read: '#2dd4bf', write: '#f59e0b' },
35
43
  selected: FRAME_GRAPH_DEBUG_VISUAL_THEME.accent,
36
44
  hover: '#cbd5e1',