@r2digisolutions/components 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. package/README.md +1 -1
  2. package/dist/components/atoms/Checkbox/Checkbox.svelte +10 -3
  3. package/dist/components/atoms/Checkbox/Checkbox.svelte.d.ts +3 -0
  4. package/dist/components/atoms/IconButton/IconButton.svelte +1 -1
  5. package/dist/components/atoms/Input/Input.svelte +17 -2
  6. package/dist/components/atoms/Input/Input.svelte.d.ts +6 -1
  7. package/dist/components/atoms/MarqueeRect/MarqueeRect.svelte +21 -0
  8. package/dist/components/atoms/MarqueeRect/MarqueeRect.svelte.d.ts +8 -0
  9. package/dist/components/atoms/MediaKindIcon/MediaKindIcon.stories.js +8 -0
  10. package/dist/components/atoms/MediaKindIcon/MediaKindIcon.svelte +122 -0
  11. package/dist/components/atoms/MediaKindIcon/MediaKindIcon.svelte.d.ts +11 -0
  12. package/dist/components/atoms/MediaKindIcon/MediaKindIconStory.svelte +12 -0
  13. package/dist/components/atoms/MediaKindIcon/MediaKindIconStory.svelte.d.ts +18 -0
  14. package/dist/components/atoms/PanKnob/PanKnob.stories.d.ts +9 -0
  15. package/dist/components/atoms/PanKnob/PanKnob.stories.js +8 -0
  16. package/dist/components/atoms/PanKnob/PanKnob.svelte +218 -0
  17. package/dist/components/atoms/PanKnob/PanKnob.svelte.d.ts +19 -0
  18. package/dist/components/atoms/PanKnob/PanKnobStory.svelte +15 -0
  19. package/dist/components/atoms/PanKnob/PanKnobStory.svelte.d.ts +3 -0
  20. package/dist/components/atoms/Playhead/Playhead.stories.js +8 -0
  21. package/dist/components/atoms/Playhead/Playhead.svelte +59 -0
  22. package/dist/components/atoms/Playhead/Playhead.svelte.d.ts +13 -0
  23. package/dist/components/atoms/Playhead/PlayheadStory.svelte +9 -0
  24. package/dist/components/atoms/Playhead/PlayheadStory.svelte.d.ts +18 -0
  25. package/dist/components/atoms/Textarea/Textarea.svelte +4 -1
  26. package/dist/components/atoms/Textarea/Textarea.svelte.d.ts +1 -0
  27. package/dist/components/atoms/TimeRuler/TimeRuler.stories.js +8 -0
  28. package/dist/components/atoms/TimeRuler/TimeRuler.svelte +58 -0
  29. package/dist/components/atoms/TimeRuler/TimeRuler.svelte.d.ts +10 -0
  30. package/dist/components/atoms/TimeRuler/TimeRulerStory.svelte +7 -0
  31. package/dist/components/atoms/TimeRuler/TimeRulerStory.svelte.d.ts +18 -0
  32. package/dist/components/atoms/Toggle/Toggle.svelte +1 -1
  33. package/dist/components/atoms/Tooltip/Tooltip.svelte +1 -1
  34. package/dist/components/atoms/TrimHandle/TrimHandle.stories.js +8 -0
  35. package/dist/components/atoms/TrimHandle/TrimHandle.svelte +63 -0
  36. package/dist/components/atoms/TrimHandle/TrimHandle.svelte.d.ts +12 -0
  37. package/dist/components/atoms/TrimHandle/TrimHandleStory.svelte +11 -0
  38. package/dist/components/atoms/TrimHandle/TrimHandleStory.svelte.d.ts +18 -0
  39. package/dist/components/molecules/AiAssistPanel/AiAssistPanel.stories.d.ts +9 -0
  40. package/dist/components/molecules/AiAssistPanel/AiAssistPanel.stories.js +8 -0
  41. package/dist/components/molecules/AiAssistPanel/AiAssistPanel.svelte +102 -0
  42. package/dist/components/molecules/AiAssistPanel/AiAssistPanel.svelte.d.ts +20 -0
  43. package/dist/components/molecules/AiAssistPanel/AiAssistPanelStory.svelte +34 -0
  44. package/dist/components/molecules/AiAssistPanel/AiAssistPanelStory.svelte.d.ts +3 -0
  45. package/dist/components/molecules/BulkActionBar/BulkActionBar.svelte +112 -62
  46. package/dist/components/molecules/BulkActionBar/BulkActionBar.svelte.d.ts +2 -0
  47. package/dist/components/molecules/BulkEditPanel/BulkEditPanel.stories.js +8 -0
  48. package/dist/components/molecules/BulkEditPanel/BulkEditPanel.svelte +117 -0
  49. package/dist/components/molecules/BulkEditPanel/BulkEditPanel.svelte.d.ts +23 -0
  50. package/dist/components/molecules/BulkEditPanel/BulkEditPanelStory.svelte +18 -0
  51. package/dist/components/molecules/BulkEditPanel/BulkEditPanelStory.svelte.d.ts +18 -0
  52. package/dist/components/molecules/CanvasElementsPanel/CanvasElementsPanel.stories.js +8 -0
  53. package/dist/components/molecules/CanvasElementsPanel/CanvasElementsPanel.svelte +858 -0
  54. package/dist/components/molecules/CanvasElementsPanel/CanvasElementsPanel.svelte.d.ts +43 -0
  55. package/dist/components/molecules/CanvasElementsPanel/CanvasElementsPanelStory.svelte +7 -0
  56. package/dist/components/molecules/CanvasElementsPanel/CanvasElementsPanelStory.svelte.d.ts +18 -0
  57. package/dist/components/molecules/CanvasInspector/CanvasInspector.stories.d.ts +9 -0
  58. package/dist/components/molecules/CanvasInspector/CanvasInspector.stories.js +8 -0
  59. package/dist/components/molecules/CanvasInspector/CanvasInspector.svelte +1140 -0
  60. package/dist/components/molecules/CanvasInspector/CanvasInspector.svelte.d.ts +28 -0
  61. package/dist/components/molecules/CanvasInspector/CanvasInspectorStory.svelte +20 -0
  62. package/dist/components/molecules/CanvasInspector/CanvasInspectorStory.svelte.d.ts +3 -0
  63. package/dist/components/molecules/CodeEditor/CodeEditor.svelte +13 -10
  64. package/dist/components/molecules/ColorPicker/ColorPicker.svelte +167 -97
  65. package/dist/components/molecules/ColumnVisibilityMenu/ColumnVisibilityMenu.stories.d.ts +9 -0
  66. package/dist/components/molecules/ColumnVisibilityMenu/ColumnVisibilityMenu.stories.js +8 -0
  67. package/dist/components/molecules/ColumnVisibilityMenu/ColumnVisibilityMenu.svelte +108 -0
  68. package/dist/components/molecules/ColumnVisibilityMenu/ColumnVisibilityMenu.svelte.d.ts +18 -0
  69. package/dist/components/molecules/ColumnVisibilityMenu/ColumnVisibilityMenuStory.svelte +15 -0
  70. package/dist/components/molecules/ColumnVisibilityMenu/ColumnVisibilityMenuStory.svelte.d.ts +3 -0
  71. package/dist/components/molecules/ConditionalFormatPanel/ConditionalFormatPanel.stories.d.ts +9 -0
  72. package/dist/components/molecules/ConditionalFormatPanel/ConditionalFormatPanel.stories.js +8 -0
  73. package/dist/components/molecules/ConditionalFormatPanel/ConditionalFormatPanel.svelte +412 -0
  74. package/dist/components/molecules/ConditionalFormatPanel/ConditionalFormatPanel.svelte.d.ts +14 -0
  75. package/dist/components/molecules/ConditionalFormatPanel/ConditionalFormatPanelStory.svelte +27 -0
  76. package/dist/components/molecules/ConditionalFormatPanel/ConditionalFormatPanelStory.svelte.d.ts +3 -0
  77. package/dist/components/molecules/ConflictResolver/ConflictResolver.stories.js +8 -0
  78. package/dist/components/molecules/ConflictResolver/ConflictResolver.svelte +73 -0
  79. package/dist/components/molecules/ConflictResolver/ConflictResolver.svelte.d.ts +16 -0
  80. package/dist/components/molecules/ConflictResolver/ConflictResolverStory.svelte +11 -0
  81. package/dist/components/molecules/ConflictResolver/ConflictResolverStory.svelte.d.ts +18 -0
  82. package/dist/components/molecules/ContextMenu/ContextMenu.svelte +237 -41
  83. package/dist/components/molecules/ContextMenu/ContextMenu.svelte.d.ts +17 -1
  84. package/dist/components/molecules/DateTimePicker/DateTimePicker.svelte.d.ts +1 -1
  85. package/dist/components/molecules/ExpressionEditor/ExpressionEditor.stories.d.ts +9 -0
  86. package/dist/components/molecules/ExpressionEditor/ExpressionEditor.stories.js +8 -0
  87. package/dist/components/molecules/ExpressionEditor/ExpressionEditor.svelte +56 -0
  88. package/dist/components/molecules/ExpressionEditor/ExpressionEditor.svelte.d.ts +12 -0
  89. package/dist/components/molecules/ExpressionEditor/ExpressionEditorStory.svelte +12 -0
  90. package/dist/components/molecules/ExpressionEditor/ExpressionEditorStory.svelte.d.ts +3 -0
  91. package/dist/components/molecules/FilterList/FilterList.stories.d.ts +9 -0
  92. package/dist/components/molecules/FilterList/FilterList.stories.js +8 -0
  93. package/dist/components/molecules/FilterList/FilterList.svelte +101 -0
  94. package/dist/components/molecules/FilterList/FilterList.svelte.d.ts +18 -0
  95. package/dist/components/molecules/FilterList/FilterListStory.svelte +31 -0
  96. package/dist/components/molecules/FilterList/FilterListStory.svelte.d.ts +3 -0
  97. package/dist/components/molecules/FormDateTimePicker/FormDateTimePicker.svelte.d.ts +1 -1
  98. package/dist/components/molecules/Gauge/Gauge.stories.d.ts +1 -1
  99. package/dist/components/molecules/InfiniteScroll/InfiniteScroll.stories.d.ts +1 -1
  100. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.stories.d.ts +9 -0
  101. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.stories.js +8 -0
  102. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.svelte +94 -0
  103. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.svelte.d.ts +15 -0
  104. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowserStory.svelte +18 -0
  105. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowserStory.svelte.d.ts +3 -0
  106. package/dist/components/molecules/MediaAssetCard/MediaAssetCard.stories.js +8 -0
  107. package/dist/components/molecules/MediaAssetCard/MediaAssetCard.svelte +50 -0
  108. package/dist/components/molecules/MediaAssetCard/MediaAssetCard.svelte.d.ts +11 -0
  109. package/dist/components/molecules/MediaAssetCard/MediaAssetCardStory.svelte +13 -0
  110. package/dist/components/molecules/MediaAssetCard/MediaAssetCardStory.svelte.d.ts +18 -0
  111. package/dist/components/molecules/MediaLayerItem/MediaLayerItem.stories.js +8 -0
  112. package/dist/components/molecules/MediaLayerItem/MediaLayerItem.svelte +380 -0
  113. package/dist/components/molecules/MediaLayerItem/MediaLayerItem.svelte.d.ts +33 -0
  114. package/dist/components/molecules/MediaLayerItem/MediaLayerItemStory.svelte +14 -0
  115. package/dist/components/molecules/MediaLayerItem/MediaLayerItemStory.svelte.d.ts +18 -0
  116. package/dist/components/molecules/MediaLayerList/MediaLayerList.stories.d.ts +9 -0
  117. package/dist/components/molecules/MediaLayerList/MediaLayerList.stories.js +8 -0
  118. package/dist/components/molecules/MediaLayerList/MediaLayerList.svelte +399 -0
  119. package/dist/components/molecules/MediaLayerList/MediaLayerList.svelte.d.ts +37 -0
  120. package/dist/components/molecules/MediaLayerList/MediaLayerListStory.svelte +24 -0
  121. package/dist/components/molecules/MediaLayerList/MediaLayerListStory.svelte.d.ts +3 -0
  122. package/dist/components/molecules/MediaStage/MediaStage.stories.d.ts +9 -0
  123. package/dist/components/molecules/MediaStage/MediaStage.stories.js +8 -0
  124. package/dist/components/molecules/MediaStage/MediaStage.svelte +1498 -0
  125. package/dist/components/molecules/MediaStage/MediaStage.svelte.d.ts +45 -0
  126. package/dist/components/molecules/MediaStage/MediaStageStory.svelte +35 -0
  127. package/dist/components/molecules/MediaStage/MediaStageStory.svelte.d.ts +3 -0
  128. package/dist/components/molecules/MediaTimeline/MediaTimeline.stories.d.ts +9 -0
  129. package/dist/components/molecules/MediaTimeline/MediaTimeline.stories.js +8 -0
  130. package/dist/components/molecules/MediaTimeline/MediaTimeline.svelte +131 -0
  131. package/dist/components/molecules/MediaTimeline/MediaTimeline.svelte.d.ts +19 -0
  132. package/dist/components/molecules/MediaTimeline/MediaTimelineStory.svelte +20 -0
  133. package/dist/components/molecules/MediaTimeline/MediaTimelineStory.svelte.d.ts +3 -0
  134. package/dist/components/molecules/MixerChannel/MixerChannel.stories.d.ts +9 -0
  135. package/dist/components/molecules/MixerChannel/MixerChannel.stories.js +8 -0
  136. package/dist/components/molecules/MixerChannel/MixerChannel.svelte +92 -0
  137. package/dist/components/molecules/MixerChannel/MixerChannel.svelte.d.ts +11 -0
  138. package/dist/components/molecules/MixerChannel/MixerChannelStory.svelte +13 -0
  139. package/dist/components/molecules/MixerChannel/MixerChannelStory.svelte.d.ts +3 -0
  140. package/dist/components/molecules/NodeGraph/GraphBlueprintNode.svelte +454 -0
  141. package/dist/components/molecules/NodeGraph/GraphBlueprintNode.svelte.d.ts +8 -0
  142. package/dist/components/molecules/NodeGraph/GraphFlowBridge.svelte +26 -0
  143. package/dist/components/molecules/NodeGraph/GraphFlowBridge.svelte.d.ts +22 -0
  144. package/dist/components/molecules/NodeGraph/NodeGraph.stories.d.ts +12 -0
  145. package/dist/components/molecules/NodeGraph/NodeGraph.stories.js +9 -0
  146. package/dist/components/molecules/NodeGraph/NodeGraph.svelte +1409 -0
  147. package/dist/components/molecules/NodeGraph/NodeGraph.svelte.d.ts +33 -0
  148. package/dist/components/molecules/NodeGraph/NodeGraphStory.svelte +90 -0
  149. package/dist/components/molecules/NodeGraph/NodeGraphStory.svelte.d.ts +3 -0
  150. package/dist/components/molecules/NodePalette/NodePalette.stories.js +8 -0
  151. package/dist/components/molecules/NodePalette/NodePalette.svelte +86 -0
  152. package/dist/components/molecules/NodePalette/NodePalette.svelte.d.ts +11 -0
  153. package/dist/components/molecules/NodePalette/NodePaletteStory.svelte +11 -0
  154. package/dist/components/molecules/NodePalette/NodePaletteStory.svelte.d.ts +18 -0
  155. package/dist/components/molecules/Poll/Poll.stories.d.ts +1 -1
  156. package/dist/components/molecules/ProgramMonitor/ProgramMonitor.stories.js +8 -0
  157. package/dist/components/molecules/ProgramMonitor/ProgramMonitor.svelte +72 -0
  158. package/dist/components/molecules/ProgramMonitor/ProgramMonitor.svelte.d.ts +12 -0
  159. package/dist/components/molecules/ProgramMonitor/ProgramMonitorStory.svelte +16 -0
  160. package/dist/components/molecules/ProgramMonitor/ProgramMonitorStory.svelte.d.ts +18 -0
  161. package/dist/components/molecules/PropertyField/PropertyField.svelte +57 -3
  162. package/dist/components/molecules/PropertyField/PropertyField.svelte.d.ts +10 -0
  163. package/dist/components/molecules/PropertyField/PropertyFieldStory.svelte +21 -0
  164. package/dist/components/molecules/PropertyGroup/PropertyGroup.svelte +1 -1
  165. package/dist/components/molecules/QueryBuilder/QueryBuilder.stories.d.ts +9 -0
  166. package/dist/components/molecules/QueryBuilder/QueryBuilder.stories.js +8 -0
  167. package/dist/components/molecules/QueryBuilder/QueryBuilder.svelte +52 -0
  168. package/dist/components/molecules/QueryBuilder/QueryBuilder.svelte.d.ts +18 -0
  169. package/dist/components/molecules/QueryBuilder/QueryBuilderStory.svelte +62 -0
  170. package/dist/components/molecules/QueryBuilder/QueryBuilderStory.svelte.d.ts +3 -0
  171. package/dist/components/molecules/RelationPicker/RelationPicker.stories.d.ts +9 -0
  172. package/dist/components/molecules/RelationPicker/RelationPicker.stories.js +8 -0
  173. package/dist/components/molecules/RelationPicker/RelationPicker.svelte +180 -0
  174. package/dist/components/molecules/RelationPicker/RelationPicker.svelte.d.ts +24 -0
  175. package/dist/components/molecules/RelationPicker/RelationPickerStory.svelte +16 -0
  176. package/dist/components/molecules/RelationPicker/RelationPickerStory.svelte.d.ts +3 -0
  177. package/dist/components/molecules/SchemaFieldBuilder/SchemaFieldBuilder.stories.d.ts +9 -0
  178. package/dist/components/molecules/SchemaFieldBuilder/SchemaFieldBuilder.stories.js +8 -0
  179. package/dist/components/molecules/SchemaFieldBuilder/SchemaFieldBuilder.svelte +154 -0
  180. package/dist/components/molecules/SchemaFieldBuilder/SchemaFieldBuilder.svelte.d.ts +12 -0
  181. package/dist/components/molecules/SchemaFieldBuilder/SchemaFieldBuilderStory.svelte +16 -0
  182. package/dist/components/molecules/SchemaFieldBuilder/SchemaFieldBuilderStory.svelte.d.ts +3 -0
  183. package/dist/components/molecules/SecretField/SecretField.stories.d.ts +9 -0
  184. package/dist/components/molecules/SecretField/SecretField.stories.js +8 -0
  185. package/dist/components/molecules/SecretField/SecretField.svelte +58 -0
  186. package/dist/components/molecules/SecretField/SecretField.svelte.d.ts +15 -0
  187. package/dist/components/molecules/SecretField/SecretFieldStory.svelte +8 -0
  188. package/dist/components/molecules/SecretField/SecretFieldStory.svelte.d.ts +3 -0
  189. package/dist/components/molecules/SplitPane/SplitPane.svelte +96 -37
  190. package/dist/components/molecules/SplitPane/SplitPane.svelte.d.ts +10 -2
  191. package/dist/components/molecules/TableToolbar/TableToolbar.svelte.d.ts +1 -1
  192. package/dist/components/molecules/Terminal/Terminal.stories.js +20 -0
  193. package/dist/components/molecules/Terminal/Terminal.svelte +238 -0
  194. package/dist/components/molecules/Terminal/Terminal.svelte.d.ts +19 -0
  195. package/dist/components/molecules/Terminal/TerminalStory.svelte +47 -0
  196. package/dist/components/molecules/Terminal/TerminalStory.svelte.d.ts +6 -0
  197. package/dist/components/molecules/TimelineClip/TimelineClip.stories.js +8 -0
  198. package/dist/components/molecules/TimelineClip/TimelineClip.svelte +116 -0
  199. package/dist/components/molecules/TimelineClip/TimelineClip.svelte.d.ts +15 -0
  200. package/dist/components/molecules/TimelineClip/TimelineClipStory.svelte +18 -0
  201. package/dist/components/molecules/TimelineClip/TimelineClipStory.svelte.d.ts +18 -0
  202. package/dist/components/molecules/TimelineTrack/TimelineTrack.stories.js +8 -0
  203. package/dist/components/molecules/TimelineTrack/TimelineTrack.svelte +56 -0
  204. package/dist/components/molecules/TimelineTrack/TimelineTrack.svelte.d.ts +16 -0
  205. package/dist/components/molecules/TimelineTrack/TimelineTrackStory.svelte +35 -0
  206. package/dist/components/molecules/TimelineTrack/TimelineTrackStory.svelte.d.ts +18 -0
  207. package/dist/components/molecules/TraceWaterfall/TraceWaterfall.stories.js +8 -0
  208. package/dist/components/molecules/TraceWaterfall/TraceWaterfall.svelte +158 -0
  209. package/dist/components/molecules/TraceWaterfall/TraceWaterfall.svelte.d.ts +18 -0
  210. package/dist/components/molecules/TraceWaterfall/TraceWaterfallStory.svelte +55 -0
  211. package/dist/components/molecules/TraceWaterfall/TraceWaterfallStory.svelte.d.ts +18 -0
  212. package/dist/components/molecules/TrackHeader/TrackHeader.stories.d.ts +9 -0
  213. package/dist/components/molecules/TrackHeader/TrackHeader.stories.js +8 -0
  214. package/dist/components/molecules/TrackHeader/TrackHeader.svelte +54 -0
  215. package/dist/components/molecules/TrackHeader/TrackHeader.svelte.d.ts +9 -0
  216. package/dist/components/molecules/TrackHeader/TrackHeaderStory.svelte +10 -0
  217. package/dist/components/molecules/TrackHeader/TrackHeaderStory.svelte.d.ts +3 -0
  218. package/dist/components/molecules/TransportControls/TransportControls.stories.d.ts +9 -0
  219. package/dist/components/molecules/TransportControls/TransportControls.stories.js +8 -0
  220. package/dist/components/molecules/TransportControls/TransportControls.svelte +53 -0
  221. package/dist/components/molecules/TransportControls/TransportControls.svelte.d.ts +12 -0
  222. package/dist/components/molecules/TransportControls/TransportControlsStory.svelte +18 -0
  223. package/dist/components/molecules/TransportControls/TransportControlsStory.svelte.d.ts +3 -0
  224. package/dist/components/molecules/VersionHistoryPanel/VersionHistoryPanel.stories.js +8 -0
  225. package/dist/components/molecules/VersionHistoryPanel/VersionHistoryPanel.svelte +117 -0
  226. package/dist/components/molecules/VersionHistoryPanel/VersionHistoryPanel.svelte.d.ts +20 -0
  227. package/dist/components/molecules/VersionHistoryPanel/VersionHistoryPanelStory.svelte +36 -0
  228. package/dist/components/molecules/VersionHistoryPanel/VersionHistoryPanelStory.svelte.d.ts +18 -0
  229. package/dist/components/molecules/VideoPlayer/VideoPlayer.stories.d.ts +1 -1
  230. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.stories.d.ts +9 -0
  231. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.stories.js +8 -0
  232. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.svelte +59 -0
  233. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.svelte.d.ts +9 -0
  234. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeaderStory.svelte +10 -0
  235. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeaderStory.svelte.d.ts +3 -0
  236. package/dist/components/molecules/WaveformRegion/WaveformRegion.stories.js +8 -0
  237. package/dist/components/molecules/WaveformRegion/WaveformRegion.svelte +82 -0
  238. package/dist/components/molecules/WaveformRegion/WaveformRegion.svelte.d.ts +13 -0
  239. package/dist/components/molecules/WaveformRegion/WaveformRegionStory.svelte +17 -0
  240. package/dist/components/molecules/WaveformRegion/WaveformRegionStory.svelte.d.ts +18 -0
  241. package/dist/components/molecules/WidgetCanvas/WidgetCanvas.svelte +13 -4
  242. package/dist/components/molecules/WidgetCanvas/WidgetCanvas.svelte.d.ts +3 -1
  243. package/dist/components/molecules/WidgetCanvas/widgetCanvasContext.d.ts +2 -0
  244. package/dist/components/molecules/WidgetFrame/WidgetFrame.svelte +206 -37
  245. package/dist/components/molecules/WidgetFrame/WidgetFrame.svelte.d.ts +31 -0
  246. package/dist/components/organisms/AssetPickerPage/AssetPickerPage.svelte.d.ts +1 -1
  247. package/dist/components/organisms/AudioEditor/AudioEditor.stories.d.ts +12 -0
  248. package/dist/components/organisms/AudioEditor/AudioEditor.stories.js +9 -0
  249. package/dist/components/organisms/AudioEditor/AudioEditor.svelte +273 -0
  250. package/dist/components/organisms/AudioEditor/AudioEditor.svelte.d.ts +13 -0
  251. package/dist/components/organisms/AudioEditor/AudioEditorStory.svelte +10 -0
  252. package/dist/components/organisms/AudioEditor/AudioEditorStory.svelte.d.ts +3 -0
  253. package/dist/components/organisms/BacklogPage/BacklogPage.svelte.d.ts +1 -1
  254. package/dist/components/organisms/BlogEditor/BlogEditor.stories.d.ts +12 -0
  255. package/dist/components/organisms/BlogEditor/BlogEditor.stories.js +9 -0
  256. package/dist/components/organisms/BlogEditor/BlogEditor.svelte +1208 -0
  257. package/dist/components/organisms/BlogEditor/BlogEditor.svelte.d.ts +16 -0
  258. package/dist/components/organisms/BlogEditor/BlogEditorStory.svelte +144 -0
  259. package/dist/components/organisms/BlogEditor/BlogEditorStory.svelte.d.ts +3 -0
  260. package/dist/components/organisms/BlogEditor/DemoBlogCard.svelte +28 -0
  261. package/dist/components/organisms/BlogEditor/DemoBlogCard.svelte.d.ts +10 -0
  262. package/dist/components/organisms/BlogEditor/DemoBlogStats.svelte +34 -0
  263. package/dist/components/organisms/BlogEditor/DemoBlogStats.svelte.d.ts +11 -0
  264. package/dist/components/organisms/BlogEditor/DemoBlogWidget.svelte +13 -0
  265. package/dist/components/organisms/BlogEditor/DemoBlogWidget.svelte.d.ts +8 -0
  266. package/dist/components/organisms/BlogRenderer/BlogRenderer.stories.js +8 -0
  267. package/dist/components/organisms/BlogRenderer/BlogRenderer.svelte +469 -0
  268. package/dist/components/organisms/BlogRenderer/BlogRenderer.svelte.d.ts +14 -0
  269. package/dist/components/organisms/BlogRenderer/BlogRendererStory.svelte +20 -0
  270. package/dist/components/organisms/BlogRenderer/BlogRendererStory.svelte.d.ts +18 -0
  271. package/dist/components/organisms/BlueprintEditor/BlueprintEditor.stories.d.ts +12 -0
  272. package/dist/components/organisms/BlueprintEditor/BlueprintEditor.stories.js +9 -0
  273. package/dist/components/organisms/BlueprintEditor/BlueprintEditor.svelte +1012 -0
  274. package/dist/components/organisms/BlueprintEditor/BlueprintEditor.svelte.d.ts +16 -0
  275. package/dist/components/organisms/BlueprintEditor/BlueprintEditorStory.svelte +76 -0
  276. package/dist/components/organisms/BlueprintEditor/BlueprintEditorStory.svelte.d.ts +3 -0
  277. package/dist/components/organisms/CalendarApp/CalendarApp.svelte.d.ts +1 -1
  278. package/dist/components/organisms/CanvasEditor/CanvasEditor.stories.d.ts +12 -0
  279. package/dist/components/organisms/CanvasEditor/CanvasEditor.stories.js +9 -0
  280. package/dist/components/organisms/CanvasEditor/CanvasEditor.svelte +1680 -0
  281. package/dist/components/organisms/CanvasEditor/CanvasEditor.svelte.d.ts +18 -0
  282. package/dist/components/organisms/CanvasEditor/CanvasEditorStory.svelte +329 -0
  283. package/dist/components/organisms/CanvasEditor/CanvasEditorStory.svelte.d.ts +3 -0
  284. package/dist/components/organisms/DashboardBuilderPage/DashboardBuilderPage.svelte.d.ts +1 -1
  285. package/dist/components/organisms/DataGrid/DataGrid.stories.d.ts +65 -0
  286. package/dist/components/organisms/DataGrid/DataGrid.stories.js +95 -0
  287. package/dist/components/organisms/DataGrid/DataGrid.svelte +2264 -0
  288. package/dist/components/organisms/DataGrid/DataGrid.svelte.d.ts +99 -0
  289. package/dist/components/organisms/DataGrid/DataGridStory.svelte +659 -0
  290. package/dist/components/organisms/DataGrid/DataGridStory.svelte.d.ts +11 -0
  291. package/dist/components/organisms/DataGrid/breakpoints.d.ts +10 -0
  292. package/dist/components/organisms/DataGrid/breakpoints.js +20 -0
  293. package/dist/components/organisms/DataGrid/cellEditors.d.ts +8 -0
  294. package/dist/components/organisms/DataGrid/cellEditors.js +59 -0
  295. package/dist/components/organisms/DataGrid/conditionalFormat.d.ts +11 -0
  296. package/dist/components/organisms/DataGrid/conditionalFormat.js +98 -0
  297. package/dist/components/organisms/DataGrid/filterRows.d.ts +5 -0
  298. package/dist/components/organisms/DataGrid/filterRows.js +60 -0
  299. package/dist/components/organisms/DataGrid/marks.d.ts +9 -0
  300. package/dist/components/organisms/DataGrid/marks.js +91 -0
  301. package/dist/components/organisms/DataGrid/types.d.ts +126 -0
  302. package/dist/components/organisms/DataGrid/types.js +21 -0
  303. package/dist/components/organisms/DesktopShell/DesktopShell.svelte.d.ts +1 -1
  304. package/dist/components/organisms/EditorShell/EditorShell.svelte +123 -28
  305. package/dist/components/organisms/EditorShell/EditorShell.svelte.d.ts +21 -1
  306. package/dist/components/organisms/FileUploader/FileUploader.svelte +77 -15
  307. package/dist/components/organisms/FileUploader/FileUploader.svelte.d.ts +11 -0
  308. package/dist/components/organisms/ImportWizard/ImportWizard.stories.js +8 -0
  309. package/dist/components/organisms/ImportWizard/ImportWizard.svelte +209 -0
  310. package/dist/components/organisms/ImportWizard/ImportWizard.svelte.d.ts +22 -0
  311. package/dist/components/organisms/ImportWizard/ImportWizardStory.svelte +16 -0
  312. package/dist/components/organisms/ImportWizard/ImportWizardStory.svelte.d.ts +18 -0
  313. package/dist/components/organisms/ResourceStudio/ResourceStudio.stories.d.ts +33 -0
  314. package/dist/components/organisms/ResourceStudio/ResourceStudio.stories.js +56 -0
  315. package/dist/components/organisms/ResourceStudio/ResourceStudio.svelte +830 -0
  316. package/dist/components/organisms/ResourceStudio/ResourceStudio.svelte.d.ts +68 -0
  317. package/dist/components/organisms/ResourceStudio/ResourceStudioStory.svelte +600 -0
  318. package/dist/components/organisms/ResourceStudio/ResourceStudioStory.svelte.d.ts +7 -0
  319. package/dist/components/organisms/ResourceStudio/fieldsToColumns.d.ts +4 -0
  320. package/dist/components/organisms/ResourceStudio/fieldsToColumns.js +20 -0
  321. package/dist/components/organisms/ResourceStudio/fieldsToSchema.d.ts +6 -0
  322. package/dist/components/organisms/ResourceStudio/fieldsToSchema.js +53 -0
  323. package/dist/components/organisms/ResourceStudio/types.d.ts +69 -0
  324. package/dist/components/organisms/ResourceStudio/types.js +15 -0
  325. package/dist/components/organisms/Scheduler/Scheduler.svelte.d.ts +1 -1
  326. package/dist/components/organisms/SchemaForm/SchemaForm.svelte +10 -3
  327. package/dist/components/organisms/SchemaForm/SchemaForm.svelte.d.ts +1 -0
  328. package/dist/components/organisms/VideoEditor/VideoEditor.stories.d.ts +12 -0
  329. package/dist/components/organisms/VideoEditor/VideoEditor.stories.js +9 -0
  330. package/dist/components/organisms/VideoEditor/VideoEditor.svelte +308 -0
  331. package/dist/components/organisms/VideoEditor/VideoEditor.svelte.d.ts +13 -0
  332. package/dist/components/organisms/VideoEditor/VideoEditorStory.svelte +10 -0
  333. package/dist/components/organisms/VideoEditor/VideoEditorStory.svelte.d.ts +3 -0
  334. package/dist/components/templates/AudioEditorTemplate/AudioEditorTemplate.stories.d.ts +12 -0
  335. package/dist/components/templates/AudioEditorTemplate/AudioEditorTemplate.stories.js +9 -0
  336. package/dist/components/templates/AudioEditorTemplate/AudioEditorTemplate.svelte +22 -0
  337. package/dist/components/templates/AudioEditorTemplate/AudioEditorTemplate.svelte.d.ts +13 -0
  338. package/dist/components/templates/AudioEditorTemplate/AudioEditorTemplateStory.svelte +8 -0
  339. package/dist/components/templates/AudioEditorTemplate/AudioEditorTemplateStory.svelte.d.ts +3 -0
  340. package/dist/components/templates/CanvasEditorTemplate/CanvasEditorTemplate.stories.d.ts +12 -0
  341. package/dist/components/templates/CanvasEditorTemplate/CanvasEditorTemplate.stories.js +9 -0
  342. package/dist/components/templates/CanvasEditorTemplate/CanvasEditorTemplate.svelte +32 -0
  343. package/dist/components/templates/CanvasEditorTemplate/CanvasEditorTemplate.svelte.d.ts +17 -0
  344. package/dist/components/templates/CanvasEditorTemplate/CanvasEditorTemplateStory.svelte +21 -0
  345. package/dist/components/templates/CanvasEditorTemplate/CanvasEditorTemplateStory.svelte.d.ts +3 -0
  346. package/dist/components/templates/ResourceStudioTemplate/ResourceStudioTemplate.stories.d.ts +25 -0
  347. package/dist/components/templates/ResourceStudioTemplate/ResourceStudioTemplate.stories.js +18 -0
  348. package/dist/components/templates/ResourceStudioTemplate/ResourceStudioTemplate.svelte +192 -0
  349. package/dist/components/templates/ResourceStudioTemplate/ResourceStudioTemplate.svelte.d.ts +62 -0
  350. package/dist/components/templates/ResourceStudioTemplate/ResourceStudioTemplateStory.svelte +129 -0
  351. package/dist/components/templates/ResourceStudioTemplate/ResourceStudioTemplateStory.svelte.d.ts +7 -0
  352. package/dist/components/templates/VideoEditorTemplate/VideoEditorTemplate.stories.d.ts +12 -0
  353. package/dist/components/templates/VideoEditorTemplate/VideoEditorTemplate.stories.js +9 -0
  354. package/dist/components/templates/VideoEditorTemplate/VideoEditorTemplate.svelte +22 -0
  355. package/dist/components/templates/VideoEditorTemplate/VideoEditorTemplate.svelte.d.ts +13 -0
  356. package/dist/components/templates/VideoEditorTemplate/VideoEditorTemplateStory.svelte +8 -0
  357. package/dist/components/templates/VideoEditorTemplate/VideoEditorTemplateStory.svelte.d.ts +3 -0
  358. package/dist/index.d.ts +94 -1
  359. package/dist/index.js +68 -0
  360. package/dist/types/xyflow-svelte.d.ts +62 -0
  361. package/dist/utils/audioProject.d.ts +19 -0
  362. package/dist/utils/audioProject.js +70 -0
  363. package/dist/utils/blogDocument.d.ts +175 -0
  364. package/dist/utils/blogDocument.js +220 -0
  365. package/dist/utils/blueprintRuntime.d.ts +34 -0
  366. package/dist/utils/blueprintRuntime.js +289 -0
  367. package/dist/utils/canvasDocument.d.ts +239 -0
  368. package/dist/utils/canvasDocument.js +443 -0
  369. package/dist/utils/canvasExport.d.ts +10 -0
  370. package/dist/utils/canvasExport.js +469 -0
  371. package/dist/utils/canvasHierarchy.d.ts +189 -0
  372. package/dist/utils/canvasHierarchy.js +674 -0
  373. package/dist/utils/canvasHistory.d.ts +19 -0
  374. package/dist/utils/canvasHistory.js +48 -0
  375. package/dist/utils/canvasWidget.d.ts +81 -0
  376. package/dist/utils/canvasWidget.js +597 -0
  377. package/dist/utils/marqueeSelect.d.ts +48 -0
  378. package/dist/utils/marqueeSelect.js +189 -0
  379. package/dist/utils/mediaTime.d.ts +16 -0
  380. package/dist/utils/mediaTime.js +57 -0
  381. package/dist/utils/mediaTracks.d.ts +61 -0
  382. package/dist/utils/mediaTracks.js +102 -0
  383. package/dist/utils/nodeGraph.d.ts +354 -0
  384. package/dist/utils/nodeGraph.js +1453 -0
  385. package/dist/utils/queryBridge.d.ts +18 -0
  386. package/dist/utils/queryBridge.js +118 -0
  387. package/dist/utils/videoSequence.d.ts +13 -0
  388. package/dist/utils/videoSequence.js +63 -0
  389. package/package.json +5 -2
@@ -0,0 +1,1012 @@
1
+ <script lang="ts">
2
+ import Button from '../../atoms/Button/Button.svelte';
3
+ import IconButton from '../../atoms/IconButton/IconButton.svelte';
4
+ import Input from '../../atoms/Input/Input.svelte';
5
+ import EditorShell from '../EditorShell/EditorShell.svelte';
6
+ import NodeGraph from '../../molecules/NodeGraph/NodeGraph.svelte';
7
+ import NodePalette from '../../molecules/NodePalette/NodePalette.svelte';
8
+ import PropertyGroup from '../../molecules/PropertyGroup/PropertyGroup.svelte';
9
+ import PropertyField from '../../molecules/PropertyField/PropertyField.svelte';
10
+ import JSONViewer from '../../molecules/JSONViewer/JSONViewer.svelte';
11
+ import SplitPane from '../../molecules/SplitPane/SplitPane.svelte';
12
+ import Panel from '../../molecules/Panel/Panel.svelte';
13
+ import Boxes from '@lucide/svelte/icons/boxes';
14
+ import Play from '@lucide/svelte/icons/play';
15
+ import Square from '@lucide/svelte/icons/square';
16
+ import Braces from '@lucide/svelte/icons/braces';
17
+ import PanelLeft from '@lucide/svelte/icons/panel-left';
18
+ import PanelRight from '@lucide/svelte/icons/panel-right';
19
+ import PanelBottom from '@lucide/svelte/icons/panel-bottom';
20
+ import CircleAlert from '@lucide/svelte/icons/circle-alert';
21
+ import CircleCheck from '@lucide/svelte/icons/circle-check';
22
+ import {
23
+ DEFAULT_BLUEPRINT_NODE_TYPES,
24
+ alignGraphNodes,
25
+ collapseSelectionToFunction,
26
+ createCommentFromSelection,
27
+ createGraphNode,
28
+ createVarGetNode,
29
+ createVarSetNode,
30
+ defaultValueForPinType,
31
+ distributeGraphNodes,
32
+ emptyBlueprintDocument,
33
+ expandCollapsedGraph,
34
+ filterNodeTypesForGraph,
35
+ pinColor,
36
+ snap,
37
+ validateGraph,
38
+ variablePinColor,
39
+ type BlueprintDocument,
40
+ type BlueprintVariable,
41
+ type GraphNode,
42
+ type GraphNodeContext,
43
+ type GraphNodeTypeDef,
44
+ type GraphValidationIssue,
45
+ type PinDataType
46
+ } from '../../../utils/nodeGraph.js';
47
+ import {
48
+ simulateBlueprint,
49
+ type BlueprintLogEntry
50
+ } from '../../../utils/blueprintRuntime.js';
51
+
52
+ export type { BlueprintDocument, BlueprintVariable };
53
+
54
+ interface BlueprintEditorProps {
55
+ value?: BlueprintDocument;
56
+ nodeTypes?: GraphNodeTypeDef[];
57
+ /** Active graph kind — filters palette / place menu like Unreal BP classes. */
58
+ graphContext?: GraphNodeContext;
59
+ class?: string;
60
+ onchange?: (doc: BlueprintDocument) => void;
61
+ oncompile?: (issues: GraphValidationIssue[]) => void;
62
+ }
63
+
64
+ let {
65
+ value = $bindable(emptyBlueprintDocument()),
66
+ nodeTypes = DEFAULT_BLUEPRINT_NODE_TYPES,
67
+ graphContext = 'event_graph' as GraphNodeContext,
68
+ class: className = '',
69
+ onchange,
70
+ oncompile
71
+ }: BlueprintEditorProps = $props();
72
+
73
+ let selectedId = $state<string | null>(null);
74
+ let selectedIds = $state<string[]>([]);
75
+ let selectedVarId = $state<string | null>(null);
76
+ let issues = $state<GraphValidationIssue[]>([]);
77
+ let showJson = $state(false);
78
+ let showSidebar = $state(true);
79
+ let showInspector = $state(true);
80
+ let showBottom = $state(true);
81
+ let sidebarSize = $state(300);
82
+ let inspectorSize = $state(300);
83
+ let bottomSize = $state(200);
84
+ let varsSize = $state(220);
85
+ let varsCollapsed = $state(false);
86
+ let paletteCollapsed = $state(false);
87
+ let compiledOnce = $state(false);
88
+ let bottomTab = $state<'compiler' | 'output'>('compiler');
89
+ let simulating = $state(false);
90
+ let simAbort: AbortController | null = null;
91
+ let outputLog = $state<BlueprintLogEntry[]>([]);
92
+ let outputScroller = $state<HTMLUListElement | null>(null);
93
+ let outputHovered = $state(false);
94
+
95
+ function scrollOutputToBottom() {
96
+ if (!outputScroller || outputHovered) return;
97
+ outputScroller.scrollTop = outputScroller.scrollHeight;
98
+ }
99
+
100
+ $effect(() => {
101
+ outputLog;
102
+ queueMicrotask(scrollOutputToBottom);
103
+ });
104
+
105
+ const selectedNode = $derived(value.graph.nodes.find((n) => n.id === selectedId) ?? null);
106
+ const selectedGraphNodes = $derived(
107
+ value.graph.nodes.filter((n) => selectedIds.includes(n.id))
108
+ );
109
+ const multiNodeSelection = $derived(selectedGraphNodes.length > 1);
110
+ const selectedVar = $derived(
111
+ (value.variables ?? []).find((v) => v.id === selectedVarId) ?? null
112
+ );
113
+ const paletteTypes = $derived(
114
+ filterNodeTypesForGraph(nodeTypes, { context: graphContext, includeHidden: false })
115
+ );
116
+ const errorCount = $derived(issues.filter((i) => i.level === 'error').length);
117
+ const warnCount = $derived(issues.filter((i) => i.level === 'warning').length);
118
+ const statusOk = $derived(compiledOnce && issues.length === 0);
119
+
120
+ function emit(next: BlueprintDocument) {
121
+ value = next;
122
+ onchange?.(next);
123
+ }
124
+
125
+ function onGraphChange(graph: BlueprintDocument['graph']) {
126
+ emit({ ...value, graph });
127
+ }
128
+
129
+ function onSelect(id: string | null) {
130
+ selectedId = id;
131
+ }
132
+
133
+ function onSelectMany(ids: string[]) {
134
+ selectedIds = ids;
135
+ if (ids.length) selectedVarId = null;
136
+ }
137
+
138
+ function deleteSelectedNodes() {
139
+ if (!selectedGraphNodes.length) return;
140
+ const del = new Set(selectedGraphNodes.map((n) => n.id));
141
+ emit({
142
+ ...value,
143
+ graph: {
144
+ ...value.graph,
145
+ nodes: value.graph.nodes.filter((n) => !del.has(n.id)),
146
+ edges: value.graph.edges.filter((e) => !del.has(e.source) && !del.has(e.target))
147
+ }
148
+ });
149
+ selectedId = null;
150
+ selectedIds = [];
151
+ }
152
+
153
+ function commentSelectedNodes() {
154
+ const ids = selectedGraphNodes.map((n) => n.id);
155
+ const result = createCommentFromSelection(value.graph, ids);
156
+ if (!result) return;
157
+ emit({ ...value, graph: result.doc });
158
+ selectedId = result.commentId;
159
+ selectedIds = [result.commentId, ...ids];
160
+ }
161
+
162
+ function collapseSelectedNodes() {
163
+ const ids = selectedGraphNodes
164
+ .filter((n) => n.type !== 'comment' && n.type !== 'collapsed_graph')
165
+ .map((n) => n.id);
166
+ const result = collapseSelectionToFunction(value.graph, ids);
167
+ if (!result) return;
168
+ emit({ ...value, graph: result.doc });
169
+ selectedId = result.collapsedId;
170
+ selectedIds = [result.collapsedId];
171
+ }
172
+
173
+ function expandSelectedNode() {
174
+ if (!selectedNode || selectedNode.type !== 'collapsed_graph') return;
175
+ const result = expandCollapsedGraph(value.graph, selectedNode.id);
176
+ if (!result) return;
177
+ emit({ ...value, graph: result.doc });
178
+ selectedIds = result.newNodeIds;
179
+ selectedId = result.newNodeIds[0] ?? null;
180
+ }
181
+
182
+ function alignSelected(align: 'left' | 'right' | 'top' | 'bottom' | 'centerX' | 'centerY') {
183
+ const ids = selectedGraphNodes.map((n) => n.id);
184
+ emit({ ...value, graph: alignGraphNodes(value.graph, ids, align) });
185
+ }
186
+
187
+ function distributeSelected(axis: 'horizontal' | 'vertical') {
188
+ const ids = selectedGraphNodes.map((n) => n.id);
189
+ emit({ ...value, graph: distributeGraphNodes(value.graph, ids, axis) });
190
+ }
191
+
192
+ function addFromPalette(nt: GraphNodeTypeDef) {
193
+ const nodes = value.graph.nodes;
194
+ const x = snap(80 + (nodes.length % 5) * 40, 16);
195
+ const y = snap(80 + Math.floor(nodes.length / 5) * 40, 16);
196
+ const n = createGraphNode({ type: nt.type, x, y }, nodeTypes);
197
+ emit({ ...value, graph: { ...value.graph, nodes: [...nodes, n] } });
198
+ selectedId = n.id;
199
+ }
200
+
201
+ function placeVariableOnGraph(variable: BlueprintVariable, kind: 'get' | 'set') {
202
+ const nodes = value.graph.nodes;
203
+ const x = snap(120 + (nodes.length % 4) * 36, 16);
204
+ const y = snap(120 + Math.floor(nodes.length / 4) * 36, 16);
205
+ const n =
206
+ kind === 'get' ? createVarGetNode(variable, { x, y }) : createVarSetNode(variable, { x, y });
207
+ emit({ ...value, graph: { ...value.graph, nodes: [...nodes, n] } });
208
+ selectedId = n.id;
209
+ }
210
+
211
+ function updateSelected(patch: Partial<GraphNode> & { data?: GraphNode['data'] }) {
212
+ if (!selectedNode) return;
213
+ emit({
214
+ ...value,
215
+ graph: {
216
+ ...value.graph,
217
+ nodes: value.graph.nodes.map((n) =>
218
+ n.id === selectedNode.id
219
+ ? {
220
+ ...n,
221
+ ...patch,
222
+ data: { ...n.data, ...patch.data }
223
+ }
224
+ : n
225
+ )
226
+ }
227
+ });
228
+ }
229
+
230
+ function compile() {
231
+ const next = validateGraph(value.graph);
232
+ issues = next;
233
+ compiledOnce = true;
234
+ showBottom = true;
235
+ bottomTab = 'compiler';
236
+ oncompile?.(next);
237
+ }
238
+
239
+ function stopSimulate() {
240
+ simAbort?.abort();
241
+ simAbort = null;
242
+ simulating = false;
243
+ }
244
+
245
+ async function playSimulate() {
246
+ if (simulating) {
247
+ stopSimulate();
248
+ return;
249
+ }
250
+ showBottom = true;
251
+ bottomTab = 'output';
252
+ const ctrl = new AbortController();
253
+ simAbort = ctrl;
254
+ simulating = true;
255
+ try {
256
+ const result = await simulateBlueprint(value, {
257
+ signal: ctrl.signal,
258
+ onLog: (entry) => {
259
+ outputLog = [...outputLog, entry];
260
+ }
261
+ });
262
+ if (result.variables.length) {
263
+ emit({ ...value, variables: result.variables });
264
+ }
265
+ } finally {
266
+ if (simAbort === ctrl) simAbort = null;
267
+ simulating = false;
268
+ }
269
+ }
270
+
271
+ function addVariable() {
272
+ const vars = value.variables ?? [];
273
+ const v: BlueprintVariable = {
274
+ id: `var_${vars.length + 1}`,
275
+ name: `NewVar${vars.length + 1}`,
276
+ dataType: 'bool',
277
+ defaultValue: defaultValueForPinType('bool')
278
+ };
279
+ emit({ ...value, variables: [...vars, v] });
280
+ selectedVarId = v.id;
281
+ }
282
+
283
+ function updateVariable(id: string, patch: Partial<BlueprintVariable>) {
284
+ emit({
285
+ ...value,
286
+ variables: (value.variables ?? []).map((v) => {
287
+ if (v.id !== id) return v;
288
+ const next = { ...v, ...patch };
289
+ if (patch.dataType && patch.dataType !== v.dataType && patch.defaultValue === undefined) {
290
+ next.defaultValue = defaultValueForPinType(patch.dataType);
291
+ }
292
+ return next;
293
+ })
294
+ });
295
+ }
296
+
297
+ function removeVariable(id: string) {
298
+ if (selectedVarId === id) selectedVarId = null;
299
+ emit({
300
+ ...value,
301
+ variables: (value.variables ?? []).filter((v) => v.id !== id)
302
+ });
303
+ }
304
+
305
+ function onVarDragStart(event: DragEvent, v: BlueprintVariable) {
306
+ event.dataTransfer?.setData(
307
+ 'application/x-blueprint-var',
308
+ JSON.stringify({ id: v.id, name: v.name, dataType: v.dataType, defaultValue: v.defaultValue })
309
+ );
310
+ event.dataTransfer?.setData('text/plain', v.name);
311
+ if (event.dataTransfer) event.dataTransfer.effectAllowed = 'copy';
312
+ }
313
+
314
+ function formatDefaultInput(v: BlueprintVariable): string {
315
+ if (v.defaultValue == null) return '';
316
+ return String(v.defaultValue);
317
+ }
318
+ </script>
319
+
320
+ <div class={['flex h-full min-h-0 flex-col bg-surface', className]} data-blueprint-editor>
321
+ <header
322
+ class="flex shrink-0 flex-wrap items-center gap-2 border-b border-border bg-surface-elevated px-2 py-1.5"
323
+ >
324
+ <div
325
+ class="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-brand-50 text-brand-600 ring-1 ring-brand-500/15 dark:bg-brand-950/40 dark:text-brand-300"
326
+ >
327
+ <Boxes class="h-4 w-4" strokeWidth={2} />
328
+ </div>
329
+
330
+ <div class="min-w-0 flex-1 sm:max-w-xs">
331
+ <Input
332
+ value={value.name ?? ''}
333
+ placeholder="Blueprint name"
334
+ size="sm"
335
+ class="font-medium"
336
+ oninput={(e) => emit({ ...value, name: (e.currentTarget as HTMLInputElement).value })}
337
+ />
338
+ </div>
339
+
340
+ <div class="mx-1 hidden h-5 w-px bg-border sm:block" aria-hidden="true"></div>
341
+
342
+ <Button size="sm" onclick={compile}>
343
+ Compile
344
+ </Button>
345
+
346
+ <Button
347
+ size="sm"
348
+ variant={simulating ? 'secondary' : 'primary'}
349
+ onclick={playSimulate}
350
+ title="Simulate Event BeginPlay"
351
+ >
352
+ {#if simulating}
353
+ <Square class="h-3.5 w-3.5" strokeWidth={2.25} />
354
+ Stop
355
+ {:else}
356
+ <Play class="h-3.5 w-3.5" strokeWidth={2.25} />
357
+ Play
358
+ {/if}
359
+ </Button>
360
+
361
+ {#if statusOk}
362
+ <span
363
+ class="inline-flex items-center gap-1 rounded-md bg-emerald-50 px-2 py-1 text-[11px] font-medium text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-300"
364
+ >
365
+ <CircleCheck class="h-3.5 w-3.5" strokeWidth={2.25} />
366
+ Ready
367
+ </span>
368
+ {:else if issues.length}
369
+ <span
370
+ class="inline-flex items-center gap-1.5 rounded-md bg-surface-overlay px-2 py-1 text-[11px] font-medium text-secondary"
371
+ >
372
+ <CircleAlert class="h-3.5 w-3.5 text-amber-500" strokeWidth={2.25} />
373
+ <span class="text-red-600">{errorCount} err</span>
374
+ <span class="text-muted">·</span>
375
+ <span class="text-amber-600">{warnCount} warn</span>
376
+ </span>
377
+ {:else}
378
+ <span class="text-[11px] text-muted">Not compiled</span>
379
+ {/if}
380
+
381
+ <div class="ml-auto flex items-center gap-0.5">
382
+ <IconButton
383
+ size="sm"
384
+ variant={showSidebar ? 'secondary' : 'ghost'}
385
+ label="Toggle palette"
386
+ onclick={() => (showSidebar = !showSidebar)}
387
+ >
388
+ <PanelLeft class="h-4 w-4" />
389
+ </IconButton>
390
+ <IconButton
391
+ size="sm"
392
+ variant={showBottom ? 'secondary' : 'ghost'}
393
+ label="Toggle compiler panel"
394
+ onclick={() => (showBottom = !showBottom)}
395
+ >
396
+ <PanelBottom class="h-4 w-4" />
397
+ </IconButton>
398
+ <IconButton
399
+ size="sm"
400
+ variant={showInspector ? 'secondary' : 'ghost'}
401
+ label="Toggle details"
402
+ onclick={() => (showInspector = !showInspector)}
403
+ >
404
+ <PanelRight class="h-4 w-4" />
405
+ </IconButton>
406
+ <div class="mx-1 h-5 w-px bg-border" aria-hidden="true"></div>
407
+ <IconButton
408
+ size="sm"
409
+ variant={showJson ? 'secondary' : 'ghost'}
410
+ label="Toggle JSON"
411
+ onclick={() => {
412
+ showJson = !showJson;
413
+ if (showJson) showBottom = true;
414
+ }}
415
+ >
416
+ <Braces class="h-4 w-4" />
417
+ </IconButton>
418
+ </div>
419
+ </header>
420
+
421
+ <div class="min-h-0 flex-1">
422
+ <EditorShell
423
+ inspectorTitle="Details"
424
+ workspaceTitle="Event Graph"
425
+ bottomTitle={showJson ? 'JSON' : 'Compiler Results'}
426
+ sizeUnit="px"
427
+ bind:sidebarSize
428
+ bind:inspectorSize
429
+ bind:bottomSize
430
+ sidebarMin={220}
431
+ sidebarMax={420}
432
+ inspectorMin={240}
433
+ inspectorMax={420}
434
+ bottomMin={120}
435
+ bottomMax={360}
436
+ {showSidebar}
437
+ {showInspector}
438
+ {showBottom}
439
+ wrapSidebar={false}
440
+ collapsiblePanels
441
+ revealResizeOnHover
442
+ fullHeight
443
+ class="h-full"
444
+ >
445
+ {#snippet sidebar()}
446
+ <SplitPane
447
+ orientation="vertical"
448
+ bind:size={varsSize}
449
+ sizePane="end"
450
+ unit="px"
451
+ minSize={96}
452
+ maxSize={320}
453
+ startCollapsed={paletteCollapsed}
454
+ endCollapsed={varsCollapsed}
455
+ revealOnHover
456
+ class="h-full"
457
+ >
458
+ {#snippet start()}
459
+ <Panel
460
+ title="Palette"
461
+ collapsible
462
+ bind:collapsed={paletteCollapsed}
463
+ padding="none"
464
+ headerSize="sm"
465
+ >
466
+ <NodePalette
467
+ nodeTypes={paletteTypes}
468
+ title=""
469
+ onselect={addFromPalette}
470
+ class="h-full"
471
+ />
472
+ </Panel>
473
+ {/snippet}
474
+ {#snippet end()}
475
+ <Panel
476
+ title="Variables"
477
+ collapsible
478
+ bind:collapsed={varsCollapsed}
479
+ padding="none"
480
+ headerSize="sm"
481
+ >
482
+ {#snippet actions()}
483
+ <Button size="sm" variant="ghost" onclick={addVariable}>+</Button>
484
+ {/snippet}
485
+ <ul class="space-y-0.5 p-1.5">
486
+ {#each value.variables ?? [] as v (v.id)}
487
+ <li>
488
+ <button
489
+ type="button"
490
+ class={[
491
+ 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left',
492
+ selectedVarId === v.id
493
+ ? 'bg-brand-50 ring-1 ring-brand-500/30 dark:bg-brand-950/30'
494
+ : 'hover:bg-surface-overlay'
495
+ ]}
496
+ draggable="true"
497
+ ondragstart={(e) => onVarDragStart(e, v)}
498
+ onclick={() => {
499
+ selectedVarId = v.id;
500
+ selectedId = null;
501
+ }}
502
+ title="Click to edit in Details · drag onto graph"
503
+ >
504
+ <span
505
+ class="h-2.5 w-2.5 shrink-0 rounded-full"
506
+ style={`background:${variablePinColor(v.dataType)}`}
507
+ ></span>
508
+ <span class="min-w-0 flex-1 truncate text-xs font-medium text-primary"
509
+ >{v.name}</span
510
+ >
511
+ <span class="shrink-0 font-mono text-[10px] text-muted">{v.dataType}</span>
512
+ </button>
513
+ </li>
514
+ {:else}
515
+ <li class="px-2 py-3 text-center text-[11px] text-muted">
516
+ No variables — add one, then edit in Details
517
+ </li>
518
+ {/each}
519
+ </ul>
520
+ </Panel>
521
+ {/snippet}
522
+ </SplitPane>
523
+ {/snippet}
524
+
525
+ {#snippet workspace()}
526
+ <NodeGraph
527
+ value={value.graph}
528
+ {nodeTypes}
529
+ variables={value.variables ?? []}
530
+ {graphContext}
531
+ showToolbar={false}
532
+ showMinimap
533
+ class="h-full min-h-0 rounded-none border-0"
534
+ onchange={onGraphChange}
535
+ onselect={(id) => {
536
+ onSelect(id);
537
+ if (id) selectedVarId = null;
538
+ }}
539
+ onselectmany={onSelectMany}
540
+ onvalidate={(i) => {
541
+ issues = i;
542
+ compiledOnce = true;
543
+ }}
544
+ />
545
+ {/snippet}
546
+
547
+ {#snippet inspector()}
548
+ {#if multiNodeSelection}
549
+ <div class="space-y-1 p-1">
550
+ <PropertyGroup title="Selection" open>
551
+ {#snippet children()}
552
+ <PropertyField label="Nodes">
553
+ {#snippet children()}
554
+ <span class="text-xs font-medium text-primary">
555
+ {selectedGraphNodes.length} selected
556
+ </span>
557
+ {/snippet}
558
+ </PropertyField>
559
+ <PropertyField label="Types">
560
+ {#snippet children()}
561
+ <span class="text-xs text-muted">
562
+ {[...new Set(selectedGraphNodes.map((n) => n.type))].join(', ')}
563
+ </span>
564
+ {/snippet}
565
+ </PropertyField>
566
+ <div class="flex flex-wrap gap-2 px-1 pt-2">
567
+ <Button size="sm" variant="secondary" onclick={deleteSelectedNodes}>
568
+ Delete
569
+ </Button>
570
+ <Button size="sm" variant="secondary" onclick={commentSelectedNodes}>
571
+ Comment
572
+ </Button>
573
+ <Button size="sm" variant="secondary" onclick={collapseSelectedNodes}>
574
+ Collapse
575
+ </Button>
576
+ <Button size="sm" variant="ghost" onclick={() => alignSelected('left')}>
577
+ Align L
578
+ </Button>
579
+ <Button size="sm" variant="ghost" onclick={() => alignSelected('top')}>
580
+ Align T
581
+ </Button>
582
+ {#if selectedGraphNodes.length >= 3}
583
+ <Button
584
+ size="sm"
585
+ variant="ghost"
586
+ onclick={() => distributeSelected('horizontal')}
587
+ >
588
+ Dist X
589
+ </Button>
590
+ {/if}
591
+ </div>
592
+ <p class="px-1 pt-2 text-[11px] text-muted">
593
+ ⌘C/X/V · ⌘Z/Y · F frame · C comment · ⌘G collapse · Alt+drag pin breaks link
594
+ </p>
595
+ {/snippet}
596
+ </PropertyGroup>
597
+ </div>
598
+ {:else if selectedNode}
599
+ <div class="space-y-1 p-1">
600
+ <PropertyGroup title="Node" open>
601
+ {#snippet children()}
602
+ <PropertyField label="Name">
603
+ {#snippet children()}
604
+ <Input
605
+ size="sm"
606
+ value={String(selectedNode.data?.label ?? '')}
607
+ oninput={(e) =>
608
+ updateSelected({
609
+ data: { label: (e.currentTarget as HTMLInputElement).value }
610
+ })}
611
+ />
612
+ {/snippet}
613
+ </PropertyField>
614
+ <PropertyField label="Type">
615
+ {#snippet children()}
616
+ <span class="font-mono text-xs text-muted">{selectedNode.type}</span>
617
+ {/snippet}
618
+ </PropertyField>
619
+ {#if selectedNode.type === 'collapsed_graph'}
620
+ <div class="px-1 pt-1">
621
+ <Button size="sm" variant="secondary" onclick={expandSelectedNode}>
622
+ Expand graph
623
+ </Button>
624
+ </div>
625
+ {/if}
626
+ {#if selectedNode.data?.variableName}
627
+ <PropertyField label="Variable">
628
+ {#snippet children()}
629
+ <span
630
+ class="text-xs font-medium"
631
+ style={`color:${variablePinColor(
632
+ (value.variables ?? []).find(
633
+ (x) => x.id === selectedNode.data?.variableId
634
+ )?.dataType ?? 'any'
635
+ )}`}
636
+ >
637
+ {String(selectedNode.data?.variableName)}
638
+ </span>
639
+ {/snippet}
640
+ </PropertyField>
641
+ {/if}
642
+ <PropertyField label="Description">
643
+ {#snippet children()}
644
+ <Input
645
+ size="sm"
646
+ value={String(selectedNode.data?.description ?? '')}
647
+ oninput={(e) =>
648
+ updateSelected({
649
+ data: { description: (e.currentTarget as HTMLInputElement).value }
650
+ })}
651
+ />
652
+ {/snippet}
653
+ </PropertyField>
654
+ {/snippet}
655
+ </PropertyGroup>
656
+ <PropertyGroup title="Inputs" open>
657
+ {#snippet children()}
658
+ {#each selectedNode.inputs ?? [] as port (port.id)}
659
+ {@const wired = value.graph.edges.some(
660
+ (e) => e.target === selectedNode.id && (e.targetHandle ?? '') === port.id
661
+ )}
662
+ <PropertyField label={port.label ?? port.id}>
663
+ {#snippet children()}
664
+ <span class="flex w-full flex-col gap-1">
665
+ <span class="flex items-center gap-1.5 text-xs text-muted">
666
+ <span
667
+ class="inline-block h-2.5 w-2.5 border border-border"
668
+ class:rounded-full={port.kind !== 'exec'}
669
+ class:rounded-sm={port.kind === 'exec'}
670
+ style={`background:${pinColor(port)}`}
671
+ ></span>
672
+ {port.dataType ?? port.kind ?? 'any'}
673
+ {#if wired}
674
+ <span class="text-[10px] text-muted">· wired</span>
675
+ {/if}
676
+ </span>
677
+ {#if port.kind !== 'exec' && port.dataType !== 'exec' && !wired}
678
+ {#if port.dataType === 'bool'}
679
+ <label class="flex items-center gap-2 text-xs text-secondary">
680
+ <input
681
+ type="checkbox"
682
+ checked={Boolean(port.value)}
683
+ onchange={(e) =>
684
+ updateSelected({
685
+ inputs: (selectedNode.inputs ?? []).map((p) =>
686
+ p.id === port.id
687
+ ? {
688
+ ...p,
689
+ value: (e.currentTarget as HTMLInputElement)
690
+ .checked
691
+ }
692
+ : p
693
+ )
694
+ })}
695
+ />
696
+ {port.value ? 'true' : 'false'}
697
+ </label>
698
+ {:else if port.dataType === 'int' || port.dataType === 'float'}
699
+ <Input
700
+ size="sm"
701
+ type="number"
702
+ value={port.value == null ? '' : String(port.value)}
703
+ oninput={(e) => {
704
+ const raw = (e.currentTarget as HTMLInputElement).value;
705
+ const num =
706
+ port.dataType === 'int'
707
+ ? parseInt(raw, 10)
708
+ : parseFloat(raw);
709
+ updateSelected({
710
+ inputs: (selectedNode.inputs ?? []).map((p) =>
711
+ p.id === port.id
712
+ ? {
713
+ ...p,
714
+ value: Number.isFinite(num) ? num : 0
715
+ }
716
+ : p
717
+ )
718
+ });
719
+ }}
720
+ />
721
+ {:else}
722
+ <Input
723
+ size="sm"
724
+ value={port.value == null ? '' : String(port.value)}
725
+ placeholder="Literal…"
726
+ oninput={(e) =>
727
+ updateSelected({
728
+ inputs: (selectedNode.inputs ?? []).map((p) =>
729
+ p.id === port.id
730
+ ? {
731
+ ...p,
732
+ value: (e.currentTarget as HTMLInputElement).value
733
+ }
734
+ : p
735
+ )
736
+ })}
737
+ />
738
+ {/if}
739
+ {/if}
740
+ </span>
741
+ {/snippet}
742
+ </PropertyField>
743
+ {:else}
744
+ <p class="px-2 py-2 text-xs text-muted">No inputs</p>
745
+ {/each}
746
+ {/snippet}
747
+ </PropertyGroup>
748
+ <PropertyGroup title="Outputs" open>
749
+ {#snippet children()}
750
+ {#each selectedNode.outputs ?? [] as port (port.id)}
751
+ <PropertyField label={port.label ?? port.id}>
752
+ {#snippet children()}
753
+ <span class="flex items-center gap-1.5 text-xs text-muted">
754
+ <span
755
+ class="inline-block h-2.5 w-2.5 border border-border"
756
+ class:rounded-full={port.kind !== 'exec'}
757
+ class:rounded-sm={port.kind === 'exec'}
758
+ style={`background:${pinColor(port)}`}
759
+ ></span>
760
+ {port.dataType ?? port.kind ?? 'any'}
761
+ </span>
762
+ {/snippet}
763
+ </PropertyField>
764
+ {:else}
765
+ <p class="px-2 py-2 text-xs text-muted">No outputs</p>
766
+ {/each}
767
+ {/snippet}
768
+ </PropertyGroup>
769
+ </div>
770
+ {:else if selectedVar}
771
+ <div class="space-y-1 p-1">
772
+ <PropertyGroup title="Variable" open>
773
+ {#snippet children()}
774
+ <PropertyField label="Name">
775
+ {#snippet children()}
776
+ <Input
777
+ size="sm"
778
+ value={selectedVar.name}
779
+ oninput={(e) =>
780
+ updateVariable(selectedVar.id, {
781
+ name: (e.currentTarget as HTMLInputElement).value
782
+ })}
783
+ />
784
+ {/snippet}
785
+ </PropertyField>
786
+ <PropertyField label="Type">
787
+ {#snippet children()}
788
+ <select
789
+ class="w-full rounded-md border border-border bg-surface px-2 py-1.5 text-xs text-primary"
790
+ value={selectedVar.dataType}
791
+ onchange={(e) =>
792
+ updateVariable(selectedVar.id, {
793
+ dataType: (e.currentTarget as HTMLSelectElement).value as PinDataType
794
+ })}
795
+ >
796
+ <option value="bool">bool</option>
797
+ <option value="int">int</option>
798
+ <option value="float">float</option>
799
+ <option value="string">string</option>
800
+ <option value="object">object</option>
801
+ </select>
802
+ {/snippet}
803
+ </PropertyField>
804
+ <PropertyField label="Default">
805
+ {#snippet children()}
806
+ {#if selectedVar.dataType === 'bool'}
807
+ <label class="flex items-center gap-2 text-xs text-secondary">
808
+ <input
809
+ type="checkbox"
810
+ checked={Boolean(selectedVar.defaultValue)}
811
+ onchange={(e) =>
812
+ updateVariable(selectedVar.id, {
813
+ defaultValue: (e.currentTarget as HTMLInputElement).checked
814
+ })}
815
+ />
816
+ {selectedVar.defaultValue ? 'true' : 'false'}
817
+ </label>
818
+ {:else if selectedVar.dataType === 'string'}
819
+ <Input
820
+ size="sm"
821
+ value={formatDefaultInput(selectedVar)}
822
+ oninput={(e) =>
823
+ updateVariable(selectedVar.id, {
824
+ defaultValue: (e.currentTarget as HTMLInputElement).value
825
+ })}
826
+ />
827
+ {:else if selectedVar.dataType === 'int' || selectedVar.dataType === 'float'}
828
+ <Input
829
+ size="sm"
830
+ type="number"
831
+ value={formatDefaultInput(selectedVar)}
832
+ oninput={(e) => {
833
+ const raw = (e.currentTarget as HTMLInputElement).value;
834
+ const num =
835
+ selectedVar.dataType === 'int'
836
+ ? parseInt(raw, 10)
837
+ : parseFloat(raw);
838
+ updateVariable(selectedVar.id, {
839
+ defaultValue: Number.isFinite(num) ? num : 0
840
+ });
841
+ }}
842
+ />
843
+ {:else}
844
+ <span class="text-xs text-muted">null</span>
845
+ {/if}
846
+ {/snippet}
847
+ </PropertyField>
848
+ {/snippet}
849
+ </PropertyGroup>
850
+ <div class="flex flex-wrap gap-2 px-2 py-2">
851
+ <Button
852
+ size="sm"
853
+ variant="secondary"
854
+ onclick={() => placeVariableOnGraph(selectedVar, 'get')}
855
+ >
856
+ Get {selectedVar.name}
857
+ </Button>
858
+ <Button
859
+ size="sm"
860
+ variant="secondary"
861
+ onclick={() => placeVariableOnGraph(selectedVar, 'set')}
862
+ >
863
+ Set {selectedVar.name}
864
+ </Button>
865
+ <Button
866
+ size="sm"
867
+ variant="ghost"
868
+ onclick={() => removeVariable(selectedVar.id)}
869
+ >
870
+ Delete
871
+ </Button>
872
+ </div>
873
+ <p class="px-2 pb-2 text-[11px] text-muted">
874
+ Drag from the Variables list onto the graph, or use Get / Set here.
875
+ </p>
876
+ </div>
877
+ {:else}
878
+ <p class="p-4 text-sm text-muted">Select a node or variable to inspect details.</p>
879
+ {/if}
880
+ {/snippet}
881
+
882
+ {#snippet bottom()}
883
+ {#if showJson}
884
+ <div class="h-full min-h-0 overflow-auto p-2">
885
+ <JSONViewer data={value} />
886
+ </div>
887
+ {:else}
888
+ <div class="flex h-full min-h-0 flex-col">
889
+ <div
890
+ class="flex shrink-0 items-center gap-1 border-b border-border px-2 py-1"
891
+ role="tablist"
892
+ >
893
+ <button
894
+ type="button"
895
+ role="tab"
896
+ aria-selected={bottomTab === 'compiler'}
897
+ class={[
898
+ 'rounded px-2 py-1 text-[11px] font-medium',
899
+ bottomTab === 'compiler'
900
+ ? 'bg-surface-overlay text-primary'
901
+ : 'text-muted hover:text-secondary'
902
+ ]}
903
+ onclick={() => (bottomTab = 'compiler')}
904
+ >
905
+ Compiler
906
+ {#if issues.length}
907
+ <span class="ml-1 text-amber-600">{issues.length}</span>
908
+ {/if}
909
+ </button>
910
+ <button
911
+ type="button"
912
+ role="tab"
913
+ aria-selected={bottomTab === 'output'}
914
+ class={[
915
+ 'rounded px-2 py-1 text-[11px] font-medium',
916
+ bottomTab === 'output'
917
+ ? 'bg-surface-overlay text-primary'
918
+ : 'text-muted hover:text-secondary'
919
+ ]}
920
+ onclick={() => (bottomTab = 'output')}
921
+ >
922
+ Output
923
+ </button>
924
+ </div>
925
+ <div class="min-h-0 flex-1 overflow-hidden">
926
+ {#if bottomTab === 'compiler'}
927
+ {#if !issues.length}
928
+ <p class="p-3 text-xs text-muted">
929
+ {#if compiledOnce}
930
+ Graph is valid. Use <strong class="font-semibold text-primary">Play</strong> to
931
+ simulate BeginPlay and see Print String in Output.
932
+ {:else}
933
+ Click <strong class="font-semibold text-primary">Compile</strong> to validate
934
+ pin types and orphan wires.
935
+ {/if}
936
+ </p>
937
+ {:else}
938
+ <ul class="h-full min-h-0 space-y-1 overflow-auto p-2">
939
+ {#each issues as issue (issue.id)}
940
+ <li
941
+ class={[
942
+ 'rounded-md px-2 py-1.5 text-xs',
943
+ issue.level === 'error'
944
+ ? 'bg-red-50 text-red-700 dark:bg-red-950/40 dark:text-red-300'
945
+ : 'bg-amber-50 text-amber-800 dark:bg-amber-950/40 dark:text-amber-200'
946
+ ]}
947
+ >
948
+ <span class="font-semibold uppercase">{issue.level}</span>
949
+ — {issue.message}
950
+ </li>
951
+ {/each}
952
+ </ul>
953
+ {/if}
954
+ {:else}
955
+ <div class="flex h-full min-h-0 flex-col bg-surface-elevated text-primary">
956
+ <div
957
+ class="flex shrink-0 items-center justify-between border-b border-border bg-surface-overlay px-3 py-1"
958
+ >
959
+ <span class="text-[10px] font-semibold uppercase tracking-wide text-muted"
960
+ >Output Log</span
961
+ >
962
+ <button
963
+ type="button"
964
+ class="text-[11px] text-muted hover:text-primary"
965
+ onclick={() => (outputLog = [])}
966
+ >
967
+ Clear
968
+ </button>
969
+ </div>
970
+ <ul
971
+ bind:this={outputScroller}
972
+ class="min-h-0 flex-1 space-y-0.5 overflow-auto px-3 py-2 font-mono text-xs leading-relaxed"
973
+ onmouseenter={() => (outputHovered = true)}
974
+ onmouseleave={() => {
975
+ outputHovered = false;
976
+ queueMicrotask(scrollOutputToBottom);
977
+ }}
978
+ >
979
+ {#if !outputLog.length}
980
+ <li class="text-muted">Press Play to simulate Event BeginPlay.</li>
981
+ {:else}
982
+ {#each outputLog as entry (entry.id)}
983
+ <li
984
+ class={[
985
+ 'whitespace-pre-wrap break-all',
986
+ entry.level === 'print'
987
+ ? 'font-medium text-sky-700 dark:text-sky-300'
988
+ : entry.level === 'error'
989
+ ? 'text-red-600 dark:text-red-400'
990
+ : entry.level === 'warn'
991
+ ? 'text-amber-700 dark:text-amber-300'
992
+ : 'text-muted'
993
+ ]}
994
+ >
995
+ {#if entry.level === 'print'}
996
+ <span class="text-muted">Print: </span>{entry.text}
997
+ {:else}
998
+ {entry.text}
999
+ {/if}
1000
+ </li>
1001
+ {/each}
1002
+ {/if}
1003
+ </ul>
1004
+ </div>
1005
+ {/if}
1006
+ </div>
1007
+ </div>
1008
+ {/if}
1009
+ {/snippet}
1010
+ </EditorShell>
1011
+ </div>
1012
+ </div>