symbiote-ui 0.3.0-alpha.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 (322) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE +21 -0
  3. package/README.md +76 -0
  4. package/canvas/AutoLayout.js +731 -0
  5. package/canvas/Breadcrumb/Breadcrumb.css.js +75 -0
  6. package/canvas/Breadcrumb/Breadcrumb.js +96 -0
  7. package/canvas/Breadcrumb/Breadcrumb.tpl.js +7 -0
  8. package/canvas/CanvasConnectionRenderer.js +971 -0
  9. package/canvas/CanvasGraph/CanvasGraph.css.js +29 -0
  10. package/canvas/CanvasGraph/CanvasGraph.js +1697 -0
  11. package/canvas/CanvasGraph/CanvasGraphDrawState.js +280 -0
  12. package/canvas/CanvasGraph/CanvasGraphGeometry.js +194 -0
  13. package/canvas/CanvasViewport.js +550 -0
  14. package/canvas/ConnectionRenderer.js +1283 -0
  15. package/canvas/FlowSimulator.js +326 -0
  16. package/canvas/ForceLayout.js +226 -0
  17. package/canvas/ForceWorker.js +1303 -0
  18. package/canvas/FrameManager.js +223 -0
  19. package/canvas/GraphExplorerShell/GraphExplorerShell.css.js +136 -0
  20. package/canvas/GraphExplorerShell/GraphExplorerShell.js +129 -0
  21. package/canvas/GraphExplorerShell/GraphExplorerShell.tpl.js +12 -0
  22. package/canvas/GraphTabs/GraphTabs.css.js +101 -0
  23. package/canvas/GraphTabs/GraphTabs.js +189 -0
  24. package/canvas/GraphTabs/GraphTabs.tpl.js +12 -0
  25. package/canvas/LODManager.js +88 -0
  26. package/canvas/Minimap/Minimap.css.js +73 -0
  27. package/canvas/Minimap/Minimap.js +210 -0
  28. package/canvas/Minimap/Minimap.tpl.js +7 -0
  29. package/canvas/NodeCanvas/NodeCanvas.css.js +398 -0
  30. package/canvas/NodeCanvas/NodeCanvas.js +1499 -0
  31. package/canvas/NodeCanvas/NodeCanvas.tpl.js +22 -0
  32. package/canvas/NodeSearch/NodeSearch.css.js +97 -0
  33. package/canvas/NodeSearch/NodeSearch.js +140 -0
  34. package/canvas/NodeSearch/NodeSearch.tpl.js +25 -0
  35. package/canvas/NodeViewManager.js +748 -0
  36. package/canvas/PcbRouteDiagnostics.js +463 -0
  37. package/canvas/PcbRouter.js +1127 -0
  38. package/canvas/PinExpansion.js +134 -0
  39. package/canvas/PseudoConnection.js +84 -0
  40. package/canvas/SelectionSync.js +163 -0
  41. package/canvas/SubgraphManager.js +203 -0
  42. package/canvas/SubgraphRouter.js +452 -0
  43. package/canvas/ViewportActions.js +473 -0
  44. package/canvas/graph-explorer.js +339 -0
  45. package/canvas/graph-layout.js +148 -0
  46. package/canvas/graph-model.js +68 -0
  47. package/canvas/html-in-canvas.js +202 -0
  48. package/canvas/project-graph-builder.js +440 -0
  49. package/canvas/project-graph-model.js +183 -0
  50. package/chat/ChatComposer/ChatComposer.css.js +652 -0
  51. package/chat/ChatComposer/ChatComposer.js +304 -0
  52. package/chat/ChatList/ChatList.css.js +102 -0
  53. package/chat/ChatList/ChatList.js +99 -0
  54. package/chat/ChatList/ChatList.tpl.js +20 -0
  55. package/chat/ChatListItem/ChatListItem.css.js +117 -0
  56. package/chat/ChatListItem/ChatListItem.js +32 -0
  57. package/chat/ChatListItem/ChatListItem.tpl.js +17 -0
  58. package/chat/ChatMessageItem/ChatMessageItem.css.js +628 -0
  59. package/chat/ChatMessageItem/ChatMessageItem.js +156 -0
  60. package/chat/ChatSidebar/ChatSidebar.css.js +150 -0
  61. package/chat/ChatSidebar/ChatSidebar.js +230 -0
  62. package/chat/ChatSidebar/ChatSidebar.tpl.js +18 -0
  63. package/chat/ChatSidebar/constants.js +11 -0
  64. package/chat/ChatSidebarItem/ChatSidebarItem.css.js +445 -0
  65. package/chat/ChatSidebarItem/ChatSidebarItem.js +304 -0
  66. package/chat/ChatTranscript/ChatTranscript.css.js +90 -0
  67. package/chat/ChatTranscript/ChatTranscript.js +244 -0
  68. package/chat/chat-context.js +123 -0
  69. package/chat/message-model.js +156 -0
  70. package/cli.js +20 -0
  71. package/control/Button/Button.css.js +93 -0
  72. package/control/Button/Button.js +78 -0
  73. package/control/Button/Button.tpl.js +3 -0
  74. package/control/Field/Field.css.js +91 -0
  75. package/control/Field/Field.js +17 -0
  76. package/control/Field/Field.tpl.js +3 -0
  77. package/core/Connection.js +47 -0
  78. package/core/Editor.js +449 -0
  79. package/core/Frame.js +33 -0
  80. package/core/GraphMermaid.js +348 -0
  81. package/core/GraphText.js +228 -0
  82. package/core/Node.js +145 -0
  83. package/core/Portal.js +106 -0
  84. package/core/Socket.js +187 -0
  85. package/core/SubgraphNode.js +121 -0
  86. package/core/base-path.js +55 -0
  87. package/core/dom-utils.js +14 -0
  88. package/core/index.js +18 -0
  89. package/core/local-cache.js +26 -0
  90. package/core/state-sync.js +227 -0
  91. package/custom-elements.json +6380 -0
  92. package/discover.js +240 -0
  93. package/display/Badge/Badge.css.js +44 -0
  94. package/display/Badge/Badge.js +17 -0
  95. package/display/Badge/Badge.tpl.js +3 -0
  96. package/display/Banner/Banner.css.js +61 -0
  97. package/display/Banner/Banner.js +17 -0
  98. package/display/Banner/Banner.tpl.js +3 -0
  99. package/display/CodeBlock/CodeBlock.css.js +194 -0
  100. package/display/CodeBlock/CodeBlock.js +220 -0
  101. package/display/CodeBlock/CodeBlock.tpl.js +11 -0
  102. package/display/DataTable/DataTable.css.js +101 -0
  103. package/display/DataTable/DataTable.js +136 -0
  104. package/display/DataTable/DataTable.tpl.js +13 -0
  105. package/display/EmptyState/EmptyState.css.js +33 -0
  106. package/display/EmptyState/EmptyState.js +17 -0
  107. package/display/EmptyState/EmptyState.tpl.js +3 -0
  108. package/display/EventFeed/EventFeed.css.js +145 -0
  109. package/display/EventFeed/EventFeed.js +64 -0
  110. package/display/EventFeed/EventFeed.tpl.js +14 -0
  111. package/display/EventFeed/EventFeedItem.js +116 -0
  112. package/display/EventFeed/EventFeedItem.tpl.js +22 -0
  113. package/display/LoadingOverlay/LoadingOverlay.css.js +91 -0
  114. package/display/LoadingOverlay/LoadingOverlay.js +48 -0
  115. package/display/LoadingOverlay/LoadingOverlay.tpl.js +12 -0
  116. package/display/Metric/Metric.css.js +60 -0
  117. package/display/Metric/Metric.js +17 -0
  118. package/display/Metric/Metric.tpl.js +6 -0
  119. package/display/OutputGraphPreview/OutputGraphPreview.css.js +122 -0
  120. package/display/OutputGraphPreview/OutputGraphPreview.js +89 -0
  121. package/display/OutputGraphPreview/OutputGraphPreview.tpl.js +13 -0
  122. package/display/OutputListPreview/OutputListPreview.css.js +109 -0
  123. package/display/OutputListPreview/OutputListPreview.js +77 -0
  124. package/display/OutputListPreview/OutputListPreview.tpl.js +13 -0
  125. package/display/SourceEditor/SourceEditor.css.js +39 -0
  126. package/display/SourceEditor/SourceEditor.js +129 -0
  127. package/display/SourceEditor/SourceEditor.tpl.js +10 -0
  128. package/display/SourceViewer/SourceViewer.css.js +80 -0
  129. package/display/SourceViewer/SourceViewer.js +418 -0
  130. package/display/SourceViewer/SourceViewer.tpl.js +17 -0
  131. package/display/StatusRibbon/StatusRibbon.css.js +73 -0
  132. package/display/StatusRibbon/StatusRibbon.js +87 -0
  133. package/display/StatusRibbon/StatusRibbon.tpl.js +7 -0
  134. package/display/event-feed-adapter.js +72 -0
  135. package/display/format-utils.js +29 -0
  136. package/display/highlight.js +659 -0
  137. package/display/icons.js +37 -0
  138. package/display/markdown-formatter.js +60 -0
  139. package/display/network-approval-page.js +487 -0
  140. package/display/output-preview.js +261 -0
  141. package/effects/CellBg/CellBg.css.js +33 -0
  142. package/effects/CellBg/CellBg.js +410 -0
  143. package/effects/CellBg/CellBg.tpl.js +5 -0
  144. package/graph/canvas-adapter.js +223 -0
  145. package/graph/graph-algorithms.js +31 -0
  146. package/graph/index.js +46 -0
  147. package/graph/model.js +176 -0
  148. package/graph/project-graph-build.js +66 -0
  149. package/graph/project-graph-metadata.js +253 -0
  150. package/graph/project-package.js +128 -0
  151. package/graph/project-runtime.js +116 -0
  152. package/graph/project-transaction.js +284 -0
  153. package/graph/skeleton-utils.js +84 -0
  154. package/graph/theme-contract.js +36 -0
  155. package/graph/transaction-parser.js +56 -0
  156. package/icons/MaterialSymbols.js +69 -0
  157. package/icons/material-symbols-outlined-400.ttf +0 -0
  158. package/icons/material-symbols.css +24 -0
  159. package/index.js +95 -0
  160. package/inspector/InspectorPanel/InspectorPanel.css.js +375 -0
  161. package/inspector/InspectorPanel/InspectorPanel.js +368 -0
  162. package/inspector/InspectorPanel/InspectorPanel.tpl.js +96 -0
  163. package/inspector/TemplatePreview/TemplatePreview.css.js +104 -0
  164. package/inspector/TemplatePreview/TemplatePreview.js +145 -0
  165. package/inspector/TemplatePreview/TemplatePreview.tpl.js +33 -0
  166. package/interactions/ConnectFlow.js +304 -0
  167. package/interactions/Drag.js +104 -0
  168. package/interactions/Selector.js +133 -0
  169. package/interactions/SnapGrid.js +66 -0
  170. package/interactions/Zoom.js +139 -0
  171. package/layout/ActionZone/ActionZone.css.js +88 -0
  172. package/layout/ActionZone/ActionZone.js +261 -0
  173. package/layout/ActionZone/ActionZone.tpl.js +11 -0
  174. package/layout/CrossLayoutPortalBridge/CrossLayoutPortalBridge.js +255 -0
  175. package/layout/Layout/Layout.css.js +91 -0
  176. package/layout/Layout/Layout.js +637 -0
  177. package/layout/Layout/Layout.tpl.js +27 -0
  178. package/layout/LayoutNode/LayoutNode.css.js +302 -0
  179. package/layout/LayoutNode/LayoutNode.js +509 -0
  180. package/layout/LayoutNode/LayoutNode.tpl.js +39 -0
  181. package/layout/LayoutPreview/LayoutPreview.css.js +46 -0
  182. package/layout/LayoutPreview/LayoutPreview.js +102 -0
  183. package/layout/LayoutPreview/LayoutPreview.tpl.js +6 -0
  184. package/layout/LayoutRouter/LayoutRouter.js +274 -0
  185. package/layout/LayoutRouter/SectionRegistry.js +135 -0
  186. package/layout/LayoutRouter/routerSync.js +250 -0
  187. package/layout/LayoutSidebar/LayoutSidebar.css.js +411 -0
  188. package/layout/LayoutSidebar/LayoutSidebar.js +368 -0
  189. package/layout/LayoutSidebar/LayoutSidebar.tpl.js +26 -0
  190. package/layout/LayoutSidebar/SidebarSection.css.js +20 -0
  191. package/layout/LayoutSidebar/SidebarSection.js +184 -0
  192. package/layout/LayoutSidebar/SidebarSection.tpl.js +22 -0
  193. package/layout/LayoutTree.js +373 -0
  194. package/layout/PanelMenu/PanelMenu.css.js +43 -0
  195. package/layout/PanelMenu/PanelMenu.js +95 -0
  196. package/layout/PanelMenu/PanelMenu.tpl.js +17 -0
  197. package/layout/ProjectTabs/ProjectTabs.css.js +188 -0
  198. package/layout/ProjectTabs/ProjectTabs.js +77 -0
  199. package/layout/ProjectTabs/ProjectTabs.tpl.js +15 -0
  200. package/layout/index.js +40 -0
  201. package/list/ListDetailShell/ListDetailShell.css.js +128 -0
  202. package/list/ListDetailShell/ListDetailShell.js +72 -0
  203. package/list/ListDetailShell/ListDetailShell.tpl.js +36 -0
  204. package/list/ListItem/ListItem.css.js +111 -0
  205. package/list/ListItem/ListItem.js +66 -0
  206. package/list/ListItem/ListItem.tpl.js +18 -0
  207. package/locale/index.js +503 -0
  208. package/manifest/component-registry.js +2446 -0
  209. package/manifest/graph-schema.js +285 -0
  210. package/manifest/index.js +6 -0
  211. package/manifest/project-schema-catalog.js +246 -0
  212. package/manifest/rule-catalog.js +201 -0
  213. package/manifest/theme-catalog.js +2149 -0
  214. package/manifest/ui-schema-catalog.js +334 -0
  215. package/menu/ContextMenu/ContextMenu.css.js +61 -0
  216. package/menu/ContextMenu/ContextMenu.js +82 -0
  217. package/menu/ContextMenu/ContextMenu.tpl.js +19 -0
  218. package/navigation/QuickOpen/QuickOpen.css.js +92 -0
  219. package/navigation/QuickOpen/QuickOpen.js +185 -0
  220. package/navigation/QuickOpen/QuickOpen.tpl.js +15 -0
  221. package/navigation/quick-open-utils.js +101 -0
  222. package/node/CtrlItem/CtrlItem.css.js +41 -0
  223. package/node/CtrlItem/CtrlItem.js +24 -0
  224. package/node/CtrlItem/CtrlItem.tpl.js +17 -0
  225. package/node/GraphFrame/GraphFrame.css.js +66 -0
  226. package/node/GraphFrame/GraphFrame.js +32 -0
  227. package/node/GraphFrame/GraphFrame.tpl.js +13 -0
  228. package/node/GraphNode/GraphNode.css.js +815 -0
  229. package/node/GraphNode/GraphNode.js +173 -0
  230. package/node/GraphNode/GraphNode.tpl.js +33 -0
  231. package/node/NodeCallout/NodeCallout.css.js +91 -0
  232. package/node/NodeCallout/NodeCallout.js +281 -0
  233. package/node/NodeCallout/NodeCallout.tpl.js +8 -0
  234. package/node/NodeSocket/NodeSocket.css.js +68 -0
  235. package/node/NodeSocket/NodeSocket.js +26 -0
  236. package/node/NodeSocket/NodeSocket.tpl.js +7 -0
  237. package/node/PortItem/PortItem.css.js +93 -0
  238. package/node/PortItem/PortItem.js +87 -0
  239. package/node/PortItem/PortItem.tpl.js +10 -0
  240. package/package.json +165 -0
  241. package/palette/PaletteBrowser/PaletteBrowser.css.js +143 -0
  242. package/palette/PaletteBrowser/PaletteBrowser.js +152 -0
  243. package/palette/PaletteBrowser/PaletteBrowser.tpl.js +23 -0
  244. package/plugins/History.js +408 -0
  245. package/plugins/Readonly.js +60 -0
  246. package/rules/symbiote-3x.json +170 -0
  247. package/schemas/component-descriptor-v1.json +91 -0
  248. package/schemas/component-descriptor-v2.json +145 -0
  249. package/schemas/graph-model-v1.json +179 -0
  250. package/schemas/graph-v1.json +91 -0
  251. package/schemas/project-package-v1.json +102 -0
  252. package/schemas/project-transaction-v1.json +114 -0
  253. package/schemas/runtime-ui-v1.json +80 -0
  254. package/schemas/theme-rule-block-v1.json +73 -0
  255. package/shapes/CircleShape.js +79 -0
  256. package/shapes/CommentShape.js +35 -0
  257. package/shapes/DiamondShape.js +130 -0
  258. package/shapes/NodeShape.js +79 -0
  259. package/shapes/PillShape.js +91 -0
  260. package/shapes/RectShape.js +84 -0
  261. package/shapes/SVGShape.js +525 -0
  262. package/shapes/index.js +63 -0
  263. package/surface/Card/Card.css.js +57 -0
  264. package/surface/Card/Card.js +17 -0
  265. package/surface/Card/Card.tpl.js +3 -0
  266. package/themes/Palette.js +30 -0
  267. package/themes/Skin.js +113 -0
  268. package/themes/Theme.js +82 -0
  269. package/themes/carbon.js +135 -0
  270. package/themes/dark.js +140 -0
  271. package/themes/default-dark.js +714 -0
  272. package/themes/default-provider.css +635 -0
  273. package/themes/default-provider.js +718 -0
  274. package/themes/ebook.js +136 -0
  275. package/themes/grey.js +137 -0
  276. package/themes/light.js +139 -0
  277. package/themes/neon.js +138 -0
  278. package/themes/pcb.js +273 -0
  279. package/themes/synthwave.js +138 -0
  280. package/tokens/base.json +29 -0
  281. package/tokens/themes/carbon.json +11 -0
  282. package/tokens/themes/dark.json +12 -0
  283. package/tokens/themes/default-dark.json +1543 -0
  284. package/tokens/themes/default-provider.json +1543 -0
  285. package/tokens/themes/ebook.json +11 -0
  286. package/tokens/themes/grey.json +11 -0
  287. package/tokens/themes/light.json +12 -0
  288. package/tokens/themes/neon.json +11 -0
  289. package/tokens/themes/pcb.json +11 -0
  290. package/tokens/themes/synthwave.json +11 -0
  291. package/toolbar/QuickToolbar/QuickToolbar.css.js +152 -0
  292. package/toolbar/QuickToolbar/QuickToolbar.js +529 -0
  293. package/toolbar/QuickToolbar/QuickToolbar.tpl.js +34 -0
  294. package/tree/TreePanel/TreePanel.css.js +112 -0
  295. package/tree/TreePanel/TreePanel.js +147 -0
  296. package/tree/TreePanel/TreePanel.tpl.js +18 -0
  297. package/tree/TreeView/TreeView.css.js +122 -0
  298. package/tree/TreeView/TreeView.js +365 -0
  299. package/tree/TreeView/TreeView.tpl.js +10 -0
  300. package/ui/dialogs.js +221 -0
  301. package/ui/host-adapters.js +114 -0
  302. package/ui/index.js +660 -0
  303. package/ui/locale.js +50 -0
  304. package/ui/overlay-stack.js +89 -0
  305. package/ui/shared-styles.js +26 -0
  306. package/webmcp.js +37 -0
  307. package/xr/deep-graph.js +646 -0
  308. package/xr/emulation.js +198 -0
  309. package/xr/gesture.js +228 -0
  310. package/xr/html-canvas-renderer.js +472 -0
  311. package/xr/index.js +15 -0
  312. package/xr/layout-projection.js +1046 -0
  313. package/xr/panel-frame.js +128 -0
  314. package/xr/panel-host.js +267 -0
  315. package/xr/pointer.js +258 -0
  316. package/xr/scene-controller.js +242 -0
  317. package/xr/spatial-scene.js +212 -0
  318. package/xr/theme-bridge.js +105 -0
  319. package/xr/three-webxr-adapter.js +3439 -0
  320. package/xr/webgl-layer-renderer.js +419 -0
  321. package/xr/webxr.js +679 -0
  322. package/xr/workbench.js +516 -0
@@ -0,0 +1,516 @@
1
+ import { redactXRDiagnosticUrl } from './webxr.js';
2
+ import { createXRPanelFrame } from './panel-frame.js';
3
+
4
+ function objectOr(value) {
5
+ return value && typeof value === 'object' ? value : {};
6
+ }
7
+
8
+ function arrayOr(value) {
9
+ return Array.isArray(value) ? value : [];
10
+ }
11
+
12
+ function numberOr(value, fallback = 0) {
13
+ let number = Number(value);
14
+ return Number.isFinite(number) ? number : fallback;
15
+ }
16
+
17
+ function resolveDocument(options = {}) {
18
+ let documentRef = options.document || globalThis.document;
19
+ if (!documentRef?.createElement) {
20
+ return { ok: false, reason: 'document-unavailable', document: null };
21
+ }
22
+ return { ok: true, document: documentRef };
23
+ }
24
+
25
+ function addClass(element, className) {
26
+ if (!element || !className) return;
27
+ if (element.classList?.add) {
28
+ element.classList.add(...String(className).split(/\s+/).filter(Boolean));
29
+ return;
30
+ }
31
+ element.className = [element.className, className].filter(Boolean).join(' ');
32
+ }
33
+
34
+ function setDataset(element, name, value) {
35
+ if (!element?.dataset) return;
36
+ element.dataset[name] = String(value);
37
+ }
38
+
39
+ function setStyleProperty(element, name, value) {
40
+ if (!element?.style || value == null) return;
41
+ if (typeof element.style.setProperty === 'function') {
42
+ element.style.setProperty(name, String(value));
43
+ } else {
44
+ element.style[name] = String(value);
45
+ }
46
+ }
47
+
48
+ function applyPanelMaterialVars(element, panel, options = {}) {
49
+ if (!options.legacyMaterialVars || !panel?.material) return;
50
+ setStyleProperty(element, '--psl-panel-bg', panel.material.background);
51
+ setStyleProperty(element, '--psl-panel-border', panel.material.border);
52
+ setStyleProperty(element, '--psl-panel-radius', panel.material.radius);
53
+ setStyleProperty(element, '--psl-panel-shadow', panel.material.shadow);
54
+ }
55
+
56
+ function appendNode(parent, child) {
57
+ if (!parent || !child) return;
58
+ if (typeof parent.append === 'function') parent.append(child);
59
+ else if (typeof parent.appendChild === 'function') parent.appendChild(child);
60
+ }
61
+
62
+ function replaceChildren(parent, ...children) {
63
+ if (!parent) return;
64
+ if (typeof parent.replaceChildren === 'function') {
65
+ parent.replaceChildren(...children);
66
+ return;
67
+ }
68
+ parent.children = [];
69
+ appendNode(parent, ...children);
70
+ }
71
+
72
+ function panelComponentName(panel = {}) {
73
+ return panel.component || panel.panelType || 'panel';
74
+ }
75
+
76
+ function createSourceCanvas(documentRef, panel, options = {}) {
77
+ let canvas = documentRef.createElement('canvas');
78
+ addClass(canvas, options.className || 'sn-xr-panel-source-canvas');
79
+ canvas.width = Math.round(panel?.contentViewport?.width || options.width || 960);
80
+ canvas.height = Math.round(panel?.contentViewport?.height || options.height || 540);
81
+ setDataset(canvas, 'preview', options.preview || 'source');
82
+ return canvas;
83
+ }
84
+
85
+ function createPanelShell(documentRef, panel, options = {}) {
86
+ let elementName = options.elementName || 'section';
87
+ let node = documentRef.createElement(elementName);
88
+ addClass(node, options.className || 'sn-xr-panel');
89
+ setDataset(node, 'panelId', panel?.id || '');
90
+ setDataset(node, 'component', panelComponentName(panel));
91
+ setDataset(node, 'hit', Boolean(options.activePanelId && options.activePanelId === panel?.id));
92
+ setDataset(node, 'gesture', options.gesture || 'read-only');
93
+ let frame = createXRPanelFrame(panel, options.frame || {});
94
+ setDataset(node, 'frame', frame.version);
95
+ setDataset(node, 'frameState', Object.entries(frame.state)
96
+ .filter(([, enabled]) => enabled)
97
+ .map(([name]) => name)
98
+ .join(' ') || 'idle');
99
+ applyPanelMaterialVars(node, panel, options);
100
+ return node;
101
+ }
102
+
103
+ function createFallbackElement(documentRef, panel, reason, options = {}) {
104
+ let fallback = documentRef.createElement('section');
105
+ addClass(fallback, options.fallbackClassName || 'sn-xr-panel-fallback');
106
+ setDataset(fallback, 'reason', reason || 'panel-build-failed');
107
+ fallback.textContent = options.text || `XR panel fallback: ${reason || 'panel-build-failed'}`;
108
+ if (fallback.setAttribute) fallback.setAttribute('role', 'note');
109
+ return fallback;
110
+ }
111
+
112
+ function summarizeDeepGraph(deepGraph) {
113
+ if (!deepGraph) return null;
114
+ let diagnostics = objectOr(deepGraph.diagnostics);
115
+ let previewSummary = objectOr(deepGraph.previewSummary);
116
+ return {
117
+ nodeCount: numberOr(diagnostics.nodeCount),
118
+ edgeCount: numberOr(diagnostics.edgeCount),
119
+ connectedNodeCount: numberOr(diagnostics.connectedNodeCount),
120
+ edgeTypes: objectOr(diagnostics.edgeTypes),
121
+ focusNodeId: diagnostics.focusNodeId || null,
122
+ focus: diagnostics.focus || null,
123
+ previewStatus: previewSummary.status || null,
124
+ previewNodes: objectOr(previewSummary.nodes),
125
+ previewEdges: objectOr(previewSummary.edges),
126
+ previewFocus: previewSummary.focus || null,
127
+ };
128
+ }
129
+
130
+ function summarizeLayerFrame(layerFrame) {
131
+ let frame = objectOr(layerFrame);
132
+ let textureQuality = arrayOr(frame.textureQuality);
133
+ return {
134
+ rendered: Boolean(frame.rendered),
135
+ reason: frame.reason || null,
136
+ lowQualityCount: arrayOr(frame.lowQualityPanels).length,
137
+ textureTargetCount: textureQuality.filter((item) => item?.status === 'target').length,
138
+ textureTotalCount: textureQuality.length,
139
+ };
140
+ }
141
+
142
+ function summarizeGeometry(geometrySummaries) {
143
+ let summaries = arrayOr(geometrySummaries);
144
+ return {
145
+ count: summaries.length,
146
+ comfortWarnings: summaries.filter((summary) => summary?.poseComfort?.status === 'warning').length,
147
+ adjustedPanels: summaries.filter((summary) => summary?.poseAdjustment?.adjusted).length,
148
+ facingWarnings: summaries.filter((summary) => summary?.facing?.status === 'warning').length,
149
+ rotatedPanels: summaries.filter((summary) => summary?.rotationAdjustment?.adjusted).length,
150
+ };
151
+ }
152
+
153
+ export function createXRSpatialWorkbenchSummary(options = {}) {
154
+ let panels = arrayOr(options.panels);
155
+ let controllerState = objectOr(options.controllerState);
156
+ let rendererState = objectOr(options.rendererState);
157
+ let panelHostState = objectOr(options.panelHostState);
158
+ let threeSessionDiagnostics = objectOr(options.threeSessionDiagnostics);
159
+ let threeDiagnostics = objectOr(options.threeDiagnostics || threeSessionDiagnostics.adapter);
160
+ let htmlCanvasSupport = objectOr(options.htmlCanvasSupport);
161
+ let htmlDiagnostics = objectOr({
162
+ ...objectOr(htmlCanvasSupport.diagnostics),
163
+ ...objectOr(options.htmlCanvasDiagnostics),
164
+ });
165
+ let themeSnapshot = objectOr(options.themeSnapshot);
166
+ let textureGate = objectOr(options.textureGate);
167
+ let sceneQuality = objectOr(options.sceneQuality);
168
+ let readiness = objectOr(options.readiness);
169
+ let launch = objectOr(options.launch);
170
+ let launchGate = objectOr(options.launchGate);
171
+ let support = objectOr(options.support);
172
+ let rayCounters = objectOr(threeDiagnostics.controller?.counters);
173
+ let threeHover = objectOr(threeSessionDiagnostics.hover);
174
+ let threeDrag = objectOr(threeDiagnostics.controller?.diagnostics?.drag || threeSessionDiagnostics.drag);
175
+ let layerFrame = summarizeLayerFrame(options.layerFrame);
176
+ let geometry = summarizeGeometry(options.geometrySummaries);
177
+ let activeHit = objectOr(options.activeHit);
178
+ let tokenValues = Object.values(objectOr(themeSnapshot.tokens));
179
+ let mode = controllerState.renderMode === 'webxr-session'
180
+ ? 'webxr-session'
181
+ : threeSessionDiagnostics.active ? 'webxr-session'
182
+ : htmlCanvasSupport.supported ? 'html-in-canvas' : 'dom-live-fallback';
183
+ let renderer = threeSessionDiagnostics.active
184
+ ? options.threeAdapterName || threeDiagnostics.name || 'three-webxr'
185
+ : rendererState.preferredMode || htmlCanvasSupport.preferredMode || 'unsupported';
186
+
187
+ return {
188
+ version: 'xr-spatial-workbench-summary-v1',
189
+ source: options.source || null,
190
+ panels: {
191
+ total: panels.length,
192
+ live: numberOr(panelHostState.mounted),
193
+ errors: arrayOr(options.panelBuildErrors).length,
194
+ },
195
+ deepGraph: summarizeDeepGraph(options.deepGraph),
196
+ space: options.coordinateSystem || options.scene?.coordinateSystem || null,
197
+ mode,
198
+ renderer,
199
+ three: {
200
+ adapter: options.threeAdapterName || threeDiagnostics.name || null,
201
+ panels: numberOr(threeDiagnostics.panelCount),
202
+ renderedPanels: numberOr(threeDiagnostics.renderedPanelCount),
203
+ diagnosticPanels: numberOr(threeDiagnostics.diagnosticPanelCount),
204
+ frames: numberOr(threeSessionDiagnostics.frames),
205
+ hits: numberOr(rayCounters.hits),
206
+ misses: numberOr(rayCounters.misses),
207
+ raySource: threeDiagnostics.controller?.raySource || null,
208
+ dragMisses: numberOr(rayCounters.dragMisses),
209
+ hover: threeHover.panelId
210
+ ? {
211
+ panelId: threeHover.panelId,
212
+ frameTarget: threeHover.frameTarget || null,
213
+ }
214
+ : null,
215
+ drag: threeDrag.panelId || threeDrag.active
216
+ ? {
217
+ active: Boolean(threeDrag.active),
218
+ panelId: threeDrag.panelId || null,
219
+ frameTarget: threeDrag.frameTarget || null,
220
+ size: threeDrag.size || null,
221
+ resize: threeDrag.resize || null,
222
+ }
223
+ : null,
224
+ },
225
+ htmlCanvas: {
226
+ supported: Boolean(htmlDiagnostics.supported),
227
+ recommendation: htmlDiagnostics.recommendation || null,
228
+ availability: htmlDiagnostics.availability || null,
229
+ textureUploadAvailable: Boolean(htmlDiagnostics.textureUploadAvailable),
230
+ threeTexture: htmlDiagnostics.threeTexture || null,
231
+ preferredMode: htmlCanvasSupport.preferredMode || null,
232
+ },
233
+ canvasPreview: options.canvasPreviewResult || null,
234
+ layerFrame,
235
+ texture: {
236
+ ...textureGate,
237
+ quality: {
238
+ target: layerFrame.textureTargetCount,
239
+ total: layerFrame.textureTotalCount,
240
+ },
241
+ },
242
+ sceneQuality,
243
+ readiness,
244
+ geometry,
245
+ theme: {
246
+ scope: themeSnapshot.themeScope || null,
247
+ resolvedTokens: tokenValues.filter(Boolean).length,
248
+ totalTokens: Object.keys(objectOr(themeSnapshot.tokens)).length,
249
+ },
250
+ support: {
251
+ status: support.supported ? 'available' : support.fallback || 'unsupported',
252
+ modes: support.modes || null,
253
+ },
254
+ launch: {
255
+ canLaunch: Boolean(launch.canLaunch),
256
+ mode: launch.mode || null,
257
+ reason: launch.reason || null,
258
+ },
259
+ launchGate,
260
+ error: options.error || null,
261
+ pointer: activeHit.panelId
262
+ ? {
263
+ panelId: activeHit.panelId,
264
+ x: numberOr(activeHit.point?.x),
265
+ y: numberOr(activeHit.point?.y),
266
+ }
267
+ : null,
268
+ gesture: {
269
+ status: options.gestureState?.status || (activeHit.panelId ? 'select' : 'read-only'),
270
+ panelId: options.gestureState?.panelId || null,
271
+ },
272
+ lastTransactionId: options.lastTransactionId || null,
273
+ };
274
+ }
275
+
276
+ export function createXRWorkbenchDiagnosticPayload(options = {}) {
277
+ let launch = objectOr(options.launch);
278
+ let details = objectOr(options.details);
279
+ let htmlCanvas = options.htmlCanvas ?? details.htmlCanvas ?? null;
280
+ let texture = options.texture ?? details.texture ?? null;
281
+ let launchGate = options.launchGate ?? details.launchGate ?? null;
282
+ let sceneQuality = options.sceneQuality ?? details.sceneQuality ?? null;
283
+ let readiness = options.readiness ?? details.readiness ?? null;
284
+ let visual = options.visual ?? details.visual ?? null;
285
+ let visualReadiness = options.visualReadiness ?? details.visualReadiness ?? null;
286
+ let interactionReadiness = options.interactionReadiness ?? details.interactionReadiness ?? null;
287
+ let surface = objectOr(options.surface);
288
+
289
+ return {
290
+ version: 'xr-workbench-diagnostic-payload-v1',
291
+ event: options.event || 'xr-diagnostic',
292
+ pageUrl: redactXRDiagnosticUrl(options.pageUrl || ''),
293
+ secureContext: Boolean(options.secureContext),
294
+ navigatorXr: Boolean(options.navigatorXr),
295
+ modes: options.modes || null,
296
+ launch: {
297
+ canLaunch: Boolean(launch.canLaunch),
298
+ mode: launch.mode || null,
299
+ reason: launch.reason || null,
300
+ },
301
+ clientId: options.clientId || null,
302
+ attemptId: options.attemptId || details.attemptId || null,
303
+ surface: {
304
+ surfaceKind: surface.surfaceKind || null,
305
+ entrypoint: surface.entrypoint || null,
306
+ projectId: surface.projectId || null,
307
+ targetSection: surface.targetSection || null,
308
+ panelContentKind: surface.panelContentKind || null,
309
+ },
310
+ session: options.session || null,
311
+ error: options.error || null,
312
+ details: {
313
+ ...details,
314
+ htmlCanvas,
315
+ texture,
316
+ launchGate,
317
+ sceneQuality,
318
+ readiness,
319
+ visual,
320
+ visualReadiness,
321
+ interactionReadiness,
322
+ },
323
+ };
324
+ }
325
+
326
+ export function createXRDomPanelSourceHost(options = {}) {
327
+ let documentState = resolveDocument(options);
328
+ let documentRef = documentState.document;
329
+ let panelHost = options.panelHost || null;
330
+ let sourcePanelHost = options.sourcePanelHost || null;
331
+ let htmlCanvasRenderer = options.htmlCanvasRenderer || options.renderer || null;
332
+ let classNames = {
333
+ panel: 'sn-xr-panel',
334
+ live: 'sn-xr-panel-live',
335
+ canvas: 'sn-xr-panel-source-canvas',
336
+ source: 'sn-xr-panel-source',
337
+ fallback: 'sn-xr-panel-fallback',
338
+ ...(options.classNames || {}),
339
+ };
340
+ let state = {
341
+ scene: null,
342
+ themeSnapshot: options.themeSnapshot || null,
343
+ mounted: 0,
344
+ prepared: 0,
345
+ errors: [],
346
+ panelIds: [],
347
+ lastPreview: null,
348
+ };
349
+
350
+ function requireReady() {
351
+ if (!documentState.ok) return { ok: false, reason: documentState.reason };
352
+ if (!panelHost?.mountPanel) return { ok: false, reason: 'panel-host-unavailable' };
353
+ if (!sourcePanelHost?.mountPanel) return { ok: false, reason: 'source-panel-host-unavailable' };
354
+ if (!htmlCanvasRenderer?.preparePanel) return { ok: false, reason: 'html-canvas-renderer-unavailable' };
355
+ return { ok: true };
356
+ }
357
+
358
+ function setScene(scene, sceneOptions = {}) {
359
+ state.scene = scene || null;
360
+ state.themeSnapshot = sceneOptions.themeSnapshot || state.themeSnapshot || null;
361
+ state.mounted = 0;
362
+ state.prepared = 0;
363
+ state.errors = [];
364
+ state.panelIds = [];
365
+ panelHost?.setScene?.(state.scene, { themeSnapshot: state.themeSnapshot });
366
+ sourcePanelHost?.setScene?.(state.scene, { themeSnapshot: state.themeSnapshot });
367
+ return getState();
368
+ }
369
+
370
+ function mountPreviewPanel(panel, mountOptions = {}) {
371
+ let ready = requireReady();
372
+ if (!ready.ok) {
373
+ return {
374
+ ok: false,
375
+ reason: ready.reason,
376
+ panelId: panel?.id || null,
377
+ node: createErrorPanel(panel, ready.reason),
378
+ };
379
+ }
380
+
381
+ try {
382
+ let node = createPanelShell(documentRef, panel, {
383
+ className: classNames.panel,
384
+ activePanelId: mountOptions.activePanelId,
385
+ legacyMaterialVars: options.legacyMaterialVars,
386
+ });
387
+ let live = documentRef.createElement('div');
388
+ addClass(live, classNames.live);
389
+ appendNode(node, live);
390
+ let sourceCanvas = createSourceCanvas(documentRef, panel, {
391
+ className: classNames.canvas,
392
+ preview: mountOptions.renderCanvasPreview ? 'visible' : 'source',
393
+ });
394
+ appendNode(node, sourceCanvas);
395
+
396
+ let liveElement = panelHost.mountPanel(panel, live);
397
+ let sourceElement = sourcePanelHost.mountPanel(panel, sourceCanvas);
398
+ let prepared = htmlCanvasRenderer.preparePanel(sourceElement, panel, { canvas: sourceCanvas });
399
+ setDataset(node, 'canvas', prepared.supported ? 'prepared' : 'fallback');
400
+
401
+ let previewResult = null;
402
+ if (mountOptions.renderCanvasPreview && typeof htmlCanvasRenderer.renderPanelPreview === 'function') {
403
+ try {
404
+ previewResult = htmlCanvasRenderer.renderPanelPreview(panel.id, sourceCanvas, {
405
+ width: sourceCanvas.width,
406
+ height: sourceCanvas.height,
407
+ });
408
+ } catch (error) {
409
+ previewResult = {
410
+ rendered: false,
411
+ panelId: panel.id,
412
+ mode: 'canvas2d',
413
+ reason: error?.name || 'canvas-preview-failed',
414
+ message: error?.message || '',
415
+ };
416
+ }
417
+ state.lastPreview = previewResult;
418
+ if (previewResult?.rendered) {
419
+ setDataset(sourceCanvas, 'preview', 'visible');
420
+ setDataset(node, 'canvas', 'rendered');
421
+ }
422
+ }
423
+
424
+ state.mounted += 1;
425
+ if (prepared.prepared) state.prepared += 1;
426
+ state.panelIds.push(panel.id);
427
+ return {
428
+ ok: true,
429
+ panelId: panel.id,
430
+ node,
431
+ live,
432
+ liveElement,
433
+ sourceCanvas,
434
+ sourceElement,
435
+ prepared,
436
+ previewResult,
437
+ };
438
+ } catch (error) {
439
+ let failure = {
440
+ panelId: panel?.id || null,
441
+ reason: error?.name || 'panel-build-failed',
442
+ message: error?.message || '',
443
+ };
444
+ state.errors.push(failure);
445
+ return {
446
+ ok: false,
447
+ ...failure,
448
+ error,
449
+ node: createErrorPanel(panel, error),
450
+ };
451
+ }
452
+ }
453
+
454
+ function createErrorPanel(panel, error) {
455
+ if (!documentRef) return null;
456
+ let reason = typeof error === 'string' ? error : error?.name || 'panel-build-failed';
457
+ let node = createPanelShell(documentRef, panel, {
458
+ className: classNames.panel,
459
+ legacyMaterialVars: options.legacyMaterialVars,
460
+ });
461
+ setDataset(node, 'error', reason);
462
+ let live = documentRef.createElement('div');
463
+ addClass(live, classNames.live);
464
+ let fallback = createFallbackElement(documentRef, panel, reason, {
465
+ fallbackClassName: classNames.fallback,
466
+ });
467
+ appendNode(live, fallback);
468
+ appendNode(node, live);
469
+ return node;
470
+ }
471
+
472
+ function prepareLayerSources(sceneOrPanels, canvas, prepareOptions = {}) {
473
+ let ready = requireReady();
474
+ let panels = Array.isArray(sceneOrPanels)
475
+ ? sceneOrPanels
476
+ : arrayOr(sceneOrPanels?.panels || state.scene?.panels);
477
+ if (!ready.ok) return { ok: false, reason: ready.reason, prepared: 0, total: panels.length };
478
+ if (!canvas) return { ok: false, reason: 'canvas-unavailable', prepared: 0, total: panels.length };
479
+ sourcePanelHost?.setScene?.(state.scene, { themeSnapshot: state.themeSnapshot });
480
+ canvas.replaceChildren?.();
481
+ let records = [];
482
+ for (let panel of panels) {
483
+ let sourceContainer = documentRef.createElement('div');
484
+ let sourceElement = sourcePanelHost.mountPanel(panel, sourceContainer);
485
+ addClass(sourceElement, prepareOptions.sourceClassName || classNames.source);
486
+ appendNode(canvas, sourceElement);
487
+ let prepared = htmlCanvasRenderer.preparePanel(sourceElement, panel, { canvas });
488
+ records.push({ panelId: panel.id, prepared });
489
+ }
490
+ return {
491
+ ok: true,
492
+ prepared: records.filter((record) => record.prepared?.prepared).length,
493
+ total: panels.length,
494
+ records,
495
+ };
496
+ }
497
+
498
+ function getState() {
499
+ return {
500
+ ...state,
501
+ panelHost: panelHost?.getState?.() || null,
502
+ sourcePanelHost: sourcePanelHost?.getState?.() || null,
503
+ renderer: htmlCanvasRenderer?.getState?.() || null,
504
+ };
505
+ }
506
+
507
+ return {
508
+ setScene,
509
+ mountPreviewPanel,
510
+ createErrorPanel,
511
+ prepareLayerSources,
512
+ getState,
513
+ };
514
+ }
515
+
516
+ export const createXRDomPanelWorkbench = createXRDomPanelSourceHost;