@peter.prib/renderengine 0.0.0-stage → 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 (451) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -2
  3. package/REFERENCE.md +2198 -0
  4. package/dist/renderengine-workspace.umd.js +46905 -0
  5. package/dist/renderengine.umd.js +42223 -0
  6. package/examples/archimate.html +66 -0
  7. package/examples/diagram-editor.html +51 -0
  8. package/package.json +65 -4
  9. package/src/BaseRenderer.js +57 -0
  10. package/src/CanvasRenderer.js +194 -0
  11. package/src/Mat4.js +111 -0
  12. package/src/OrbitCamera.js +57 -0
  13. package/src/RendererFactory.js +50 -0
  14. package/src/SVGRenderer.js +439 -0
  15. package/src/archimate.js +723 -0
  16. package/src/archimateArchiFormat.js +1693 -0
  17. package/src/archimateArchiTypes.js +72 -0
  18. package/src/archimateArchive.js +140 -0
  19. package/src/archimateCSV.js +127 -0
  20. package/src/archimateDrawio.js +182 -0
  21. package/src/archimateExchangeFormat.js +546 -0
  22. package/src/archimateRelationshipTable.js +93 -0
  23. package/src/archimateSpecializations.js +161 -0
  24. package/src/chartCatalog.js +589 -0
  25. package/src/charting/ArchimateDiagramEditor.js +1624 -0
  26. package/src/charting/ArchimateSpecializationSelector.js +134 -0
  27. package/src/charting/Axis.js +68 -0
  28. package/src/charting/CameraSeeder.js +30 -0
  29. package/src/charting/CatalogDialog.js +92 -0
  30. package/src/charting/Chart.js +37 -0
  31. package/src/charting/Chart3D.js +99 -0
  32. package/src/charting/ChartBox.js +80 -0
  33. package/src/charting/ChartData.js +27 -0
  34. package/src/charting/ChartRegistry.js +76 -0
  35. package/src/charting/CheckboxTreeSelector.js +304 -0
  36. package/src/charting/ColorField.js +107 -0
  37. package/src/charting/ColorPalette.js +88 -0
  38. package/src/charting/CommandHistory.js +176 -0
  39. package/src/charting/DataFilter.js +52 -0
  40. package/src/charting/Diagram.js +36 -0
  41. package/src/charting/Diagram3D.js +29 -0
  42. package/src/charting/DiagramClipboard.js +31 -0
  43. package/src/charting/DiagramEditor.js +3330 -0
  44. package/src/charting/DiagramEditorCommand.js +110 -0
  45. package/src/charting/DiagramEditorCommands.js +237 -0
  46. package/src/charting/DiagramEditorEdgeCommands.js +142 -0
  47. package/src/charting/DiagramEditorState.js +98 -0
  48. package/src/charting/DiagramRegistry.js +86 -0
  49. package/src/charting/DiagramTypeRegistry.js +326 -0
  50. package/src/charting/DiagramViewPropertiesDialog.js +46 -0
  51. package/src/charting/Edge.js +113 -0
  52. package/src/charting/ErrorBars.js +37 -0
  53. package/src/charting/FilterSystem.js +285 -0
  54. package/src/charting/FindReplaceDialog.js +139 -0
  55. package/src/charting/FormDialog.js +385 -0
  56. package/src/charting/Gauge.js +58 -0
  57. package/src/charting/Hierarchy.js +175 -0
  58. package/src/charting/HintPanel.js +86 -0
  59. package/src/charting/ImageSelector.js +148 -0
  60. package/src/charting/InteractionManager.js +725 -0
  61. package/src/charting/Legend.js +58 -0
  62. package/src/charting/MenuBar.js +62 -0
  63. package/src/charting/ModelFileFormat.js +115 -0
  64. package/src/charting/OrbitControls.js +77 -0
  65. package/src/charting/Palette.js +119 -0
  66. package/src/charting/PopupMenu.js +117 -0
  67. package/src/charting/PropertiesPanel.js +155 -0
  68. package/src/charting/PropertyListEditor.js +96 -0
  69. package/src/charting/PropertyLog.js +92 -0
  70. package/src/charting/SettingsCascade.js +93 -0
  71. package/src/charting/SettingsDialog.js +53 -0
  72. package/src/charting/SettingsManager.js +179 -0
  73. package/src/charting/SettingsViewPropertiesDialog.js +58 -0
  74. package/src/charting/ShapePaths.js +27 -0
  75. package/src/charting/Statistics.js +134 -0
  76. package/src/charting/TemplateCatalog.js +59 -0
  77. package/src/charting/TemplateLibrary.js +103 -0
  78. package/src/charting/TextStyle.js +168 -0
  79. package/src/charting/ViewFit.js +55 -0
  80. package/src/charting/ViewMenu.js +70 -0
  81. package/src/charting/ViewPropertiesDialog.js +77 -0
  82. package/src/charting/ViewTabStrip.js +81 -0
  83. package/src/charting/archimate/ArchiFileFormat.js +32 -0
  84. package/src/charting/archimate/ArchimateCanvasEditor.js +815 -0
  85. package/src/charting/archimate/ArchimateCsvFileFormat.js +35 -0
  86. package/src/charting/archimate/ArchimateEdge.js +137 -0
  87. package/src/charting/archimate/ArchimateElementTemplate.js +195 -0
  88. package/src/charting/archimate/ArchimatePalette.js +102 -0
  89. package/src/charting/archimate/CsvImportDialog.js +105 -0
  90. package/src/charting/archimate/CustomViewpoints.js +74 -0
  91. package/src/charting/archimate/DerivedEdge.js +29 -0
  92. package/src/charting/archimate/DrawioFileFormat.js +24 -0
  93. package/src/charting/archimate/ElementFilterRule.js +21 -0
  94. package/src/charting/archimate/ExchangeFileFormat.js +28 -0
  95. package/src/charting/archimate/ViewGroupTemplate.js +137 -0
  96. package/src/charting/archimate/ViewLineEdge.js +84 -0
  97. package/src/charting/archimate/ViewpointRule.js +45 -0
  98. package/src/charting/archimate/archimateFileFormats.js +12 -0
  99. package/src/charting/archimate/archimateNames.js +5 -0
  100. package/src/charting/archimate/csvMapping.js +122 -0
  101. package/src/charting/archimate/elementMenuItems.js +32 -0
  102. package/src/charting/archimate/elementProperties.js +146 -0
  103. package/src/charting/archimate/elementTypeChoices.js +7 -0
  104. package/src/charting/archimate/elementTypeGroups.js +19 -0
  105. package/src/charting/archimate/index.js +17 -0
  106. package/src/charting/archimate/specializationCatalogDialog.js +64 -0
  107. package/src/charting/archimate/typeGlyph.js +29 -0
  108. package/src/charting/arrangement/Arrangement.js +112 -0
  109. package/src/charting/arrangement/ArrangementCommand.js +29 -0
  110. package/src/charting/arrangement/BackgroundCommand.js +41 -0
  111. package/src/charting/arrangement/BackgroundGroup.js +18 -0
  112. package/src/charting/arrangement/GroupCommand.js +46 -0
  113. package/src/charting/arrangement/ItemGroup.js +62 -0
  114. package/src/charting/arrangement/LockCommand.js +32 -0
  115. package/src/charting/arrangement/UngroupCommand.js +27 -0
  116. package/src/charting/arrangement/alignment.js +88 -0
  117. package/src/charting/arrangement/arrangeMenuItems.js +25 -0
  118. package/src/charting/arrangement/index.js +11 -0
  119. package/src/charting/arrangement/layouts.js +233 -0
  120. package/src/charting/canvas/ArchiHint.js +78 -0
  121. package/src/charting/canvas/CanvasBoxKind.js +39 -0
  122. package/src/charting/canvas/CanvasPalette.js +49 -0
  123. package/src/charting/canvas/CanvasTemplateLibrary.js +61 -0
  124. package/src/charting/canvas/CanvasTemplateMenu.js +151 -0
  125. package/src/charting/canvas/EditHintCommand.js +28 -0
  126. package/src/charting/canvas/canvasBoxKinds.js +27 -0
  127. package/src/charting/canvas/canvasBoxMenuItems.js +40 -0
  128. package/src/charting/canvas/defaultCanvasTemplates.js +186 -0
  129. package/src/charting/canvas/diagramBoxKinds.js +12 -0
  130. package/src/charting/canvas/hintMenuItems.js +49 -0
  131. package/src/charting/charts/ArcGauge.js +55 -0
  132. package/src/charting/charts/AreaChart.js +71 -0
  133. package/src/charting/charts/BarChart.js +80 -0
  134. package/src/charting/charts/BarChart3D.js +56 -0
  135. package/src/charting/charts/BarChart3DOrbit.js +53 -0
  136. package/src/charting/charts/BarChartBase.js +70 -0
  137. package/src/charting/charts/BarGauge.js +42 -0
  138. package/src/charting/charts/BoxPlotChart.js +41 -0
  139. package/src/charting/charts/BubbleChart.js +99 -0
  140. package/src/charting/charts/BubbleChart3D.js +78 -0
  141. package/src/charting/charts/BulletGauge.js +87 -0
  142. package/src/charting/charts/CalendarHeatmapChart.js +204 -0
  143. package/src/charting/charts/CandlestickChart.js +54 -0
  144. package/src/charting/charts/ChordDiagram.js +130 -0
  145. package/src/charting/charts/DensityChart.js +73 -0
  146. package/src/charting/charts/DialGauge.js +65 -0
  147. package/src/charting/charts/DonutChart.js +15 -0
  148. package/src/charting/charts/FunnelChart.js +47 -0
  149. package/src/charting/charts/GanttChart.js +201 -0
  150. package/src/charting/charts/GaugeChart.js +175 -0
  151. package/src/charting/charts/GeoMapChart.js +146 -0
  152. package/src/charting/charts/GroupedBarChart.js +88 -0
  153. package/src/charting/charts/GroupedDistributionChart.js +70 -0
  154. package/src/charting/charts/HeatmapChart.js +80 -0
  155. package/src/charting/charts/HierarchyChart.js +39 -0
  156. package/src/charting/charts/HistogramChart.js +45 -0
  157. package/src/charting/charts/KpiTile.js +72 -0
  158. package/src/charting/charts/LagPlotChart.js +41 -0
  159. package/src/charting/charts/LineChart.js +124 -0
  160. package/src/charting/charts/MultiRingGauge.js +54 -0
  161. package/src/charting/charts/OutlineChart.js +95 -0
  162. package/src/charting/charts/ParallelCoordinatesChart.js +130 -0
  163. package/src/charting/charts/PieChart.js +56 -0
  164. package/src/charting/charts/PipeChart.js +88 -0
  165. package/src/charting/charts/PopulationPyramidChart.js +106 -0
  166. package/src/charting/charts/QQPlotChart.js +64 -0
  167. package/src/charting/charts/RadarChart.js +76 -0
  168. package/src/charting/charts/RadialBarChart.js +96 -0
  169. package/src/charting/charts/RingGauge.js +23 -0
  170. package/src/charting/charts/SankeyDiagram.js +174 -0
  171. package/src/charting/charts/ScatterChart.js +104 -0
  172. package/src/charting/charts/StackedAreaChart.js +15 -0
  173. package/src/charting/charts/StackedBarChart.js +33 -0
  174. package/src/charting/charts/StackedBarChart3DOrbit.js +58 -0
  175. package/src/charting/charts/StreamGraphChart.js +131 -0
  176. package/src/charting/charts/SunburstChart.js +57 -0
  177. package/src/charting/charts/ThermometerGauge.js +43 -0
  178. package/src/charting/charts/TreemapChart.js +54 -0
  179. package/src/charting/charts/ViolinChart.js +37 -0
  180. package/src/charting/charts/WaterfallChart.js +66 -0
  181. package/src/charting/charts/WordCloudChart.js +104 -0
  182. package/src/charting/diagramModel/AddViewCommand.js +33 -0
  183. package/src/charting/diagramModel/DiagramModel.js +39 -0
  184. package/src/charting/diagramModel/DiagramModelSearch.js +22 -0
  185. package/src/charting/diagramModel/DiagramView.js +50 -0
  186. package/src/charting/diagramModel/ModelHistory.js +43 -0
  187. package/src/charting/diagramModel/ModelReport.js +153 -0
  188. package/src/charting/diagramModel/ModelSearch.js +223 -0
  189. package/src/charting/diagramModel/RemoveViewCommand.js +25 -0
  190. package/src/charting/diagramModel/RenameViewCommand.js +21 -0
  191. package/src/charting/diagramModel/ReplaceTextCommand.js +25 -0
  192. package/src/charting/diagramModel/ViewSetChecker.js +34 -0
  193. package/src/charting/diagramModel/ViewSetModel.js +243 -0
  194. package/src/charting/diagramModel/index.js +6 -0
  195. package/src/charting/diagramModel/nameTransforms.js +29 -0
  196. package/src/charting/diagrams/ArchimateCommands.js +141 -0
  197. package/src/charting/diagrams/ArchimateDiagram.js +263 -0
  198. package/src/charting/diagrams/ArchimateModel.js +1155 -0
  199. package/src/charting/diagrams/ArchimateModelChecker.js +125 -0
  200. package/src/charting/diagrams/ArchimateModelReport.js +128 -0
  201. package/src/charting/diagrams/ArchimateModelSearch.js +41 -0
  202. package/src/charting/diagrams/ArchimateValidator.js +357 -0
  203. package/src/charting/diagrams/CanvasView.js +112 -0
  204. package/src/charting/diagrams/ContextMenu.js +37 -0
  205. package/src/charting/diagrams/DataModelDiagram.js +86 -0
  206. package/src/charting/diagrams/DataModelRelationshipStrategy.js +38 -0
  207. package/src/charting/diagrams/DerivedRelationships.js +102 -0
  208. package/src/charting/diagrams/EbnfDiagram.js +39 -0
  209. package/src/charting/diagrams/EdgeGeometry.js +553 -0
  210. package/src/charting/diagrams/EditViewItemCommand.js +128 -0
  211. package/src/charting/diagrams/ElementInstance.js +157 -0
  212. package/src/charting/diagrams/GraphDiagram.js +1340 -0
  213. package/src/charting/diagrams/GraphDiagram3D.js +152 -0
  214. package/src/charting/diagrams/GraphMetrics.js +81 -0
  215. package/src/charting/diagrams/GridOverlay.js +137 -0
  216. package/src/charting/diagrams/ImportRowsCommand.js +62 -0
  217. package/src/charting/diagrams/LabelHelper.js +108 -0
  218. package/src/charting/diagrams/MergeElementsCommand.js +101 -0
  219. package/src/charting/diagrams/NestInstanceCommand.js +34 -0
  220. package/src/charting/diagrams/NodeGeometry.js +158 -0
  221. package/src/charting/diagrams/PlaceItemsCommand.js +77 -0
  222. package/src/charting/diagrams/RadialLayout.js +101 -0
  223. package/src/charting/diagrams/RelationshipInstance.js +93 -0
  224. package/src/charting/diagrams/RemoveGroupFromViewCommand.js +28 -0
  225. package/src/charting/diagrams/RemoveLineCommand.js +27 -0
  226. package/src/charting/diagrams/ShowElementCommand.js +43 -0
  227. package/src/charting/diagrams/SvgCoordinate.js +17 -0
  228. package/src/charting/diagrams/SvgZoom.js +127 -0
  229. package/src/charting/diagrams/Tooltip.js +62 -0
  230. package/src/charting/diagrams/ViewConnectionInstance.js +102 -0
  231. package/src/charting/diagrams/ViewObjectInstance.js +56 -0
  232. package/src/charting/diagrams/commands/AddEdgeCommand.js +34 -0
  233. package/src/charting/diagrams/commands/AddNodeCommand.js +28 -0
  234. package/src/charting/diagrams/commands/AddWaypointCommand.js +27 -0
  235. package/src/charting/diagrams/commands/CreateFolderCommand.js +27 -0
  236. package/src/charting/diagrams/commands/DeleteEdgeCommand.js +30 -0
  237. package/src/charting/diagrams/commands/DeleteFolderCommand.js +47 -0
  238. package/src/charting/diagrams/commands/DeleteNodeCommand.js +35 -0
  239. package/src/charting/diagrams/commands/DeleteWaypointCommand.js +24 -0
  240. package/src/charting/diagrams/commands/GraphCommand.js +65 -0
  241. package/src/charting/diagrams/commands/InvertEdgeCommand.js +24 -0
  242. package/src/charting/diagrams/commands/MoveNodeCommand.js +44 -0
  243. package/src/charting/diagrams/commands/MoveWaypointCommand.js +27 -0
  244. package/src/charting/diagrams/commands/RenameEdgeCommand.js +23 -0
  245. package/src/charting/diagrams/commands/RenameFolderCommand.js +31 -0
  246. package/src/charting/diagrams/commands/RenameNodeCommand.js +27 -0
  247. package/src/charting/diagrams/commands/ResizeNodeCommand.js +46 -0
  248. package/src/charting/diagrams/commands/UpdateEdgeSideCommand.js +40 -0
  249. package/src/charting/diagrams/commands/index.js +17 -0
  250. package/src/charting/diagrams/duplicates.js +49 -0
  251. package/src/charting/diagrams/nesting.js +30 -0
  252. package/src/charting/diagrams/roadmap.js +77 -0
  253. package/src/charting/edgeMarkers/ArrowMarker.js +15 -0
  254. package/src/charting/edgeMarkers/CircleMarker.js +13 -0
  255. package/src/charting/edgeMarkers/CrowsFootMarker.js +16 -0
  256. package/src/charting/edgeMarkers/DiamondMarker.js +15 -0
  257. package/src/charting/edgeMarkers/EdgeMarker.js +34 -0
  258. package/src/charting/edgeMarkers/HalfArrowMarker.js +8 -0
  259. package/src/charting/edgeMarkers/HollowDiamondMarker.js +18 -0
  260. package/src/charting/edgeMarkers/HollowTriangleMarker.js +18 -0
  261. package/src/charting/edgeMarkers/OpenArrowMarker.js +17 -0
  262. package/src/charting/edgeMarkers/index.js +27 -0
  263. package/src/charting/edgeStyle/EdgeStyleCascade.js +22 -0
  264. package/src/charting/edgeStyle/EdgeStyleDialog.js +51 -0
  265. package/src/charting/edgeStyle/EdgeStyleSchema.js +43 -0
  266. package/src/charting/edgeStyle/SetStyleCommand.js +12 -0
  267. package/src/charting/edgeStyle/index.js +4 -0
  268. package/src/charting/emphasis/EmphasisRule.js +42 -0
  269. package/src/charting/emphasis/HighlightRule.js +24 -0
  270. package/src/charting/gauges/ArcTrack.js +51 -0
  271. package/src/charting/gauges/GaugeAnimation.js +51 -0
  272. package/src/charting/gauges/GaugeBands.js +48 -0
  273. package/src/charting/gauges/GaugeScale.js +87 -0
  274. package/src/charting/gauges/GaugeTrack.js +44 -0
  275. package/src/charting/gauges/GaugeValue.js +61 -0
  276. package/src/charting/gauges/HorizontalTrack.js +14 -0
  277. package/src/charting/gauges/LinearTrack.js +29 -0
  278. package/src/charting/gauges/Sparkline.js +42 -0
  279. package/src/charting/gauges/VerticalTrack.js +17 -0
  280. package/src/charting/glyphs/ArrowGlyph.js +21 -0
  281. package/src/charting/glyphs/BatteryGlyph.js +18 -0
  282. package/src/charting/glyphs/ChevronGlyph.js +18 -0
  283. package/src/charting/glyphs/CircleGlyph.js +15 -0
  284. package/src/charting/glyphs/CloudGlyph.js +19 -0
  285. package/src/charting/glyphs/ComponentGlyph.js +18 -0
  286. package/src/charting/glyphs/ConstraintGlyph.js +24 -0
  287. package/src/charting/glyphs/ContractBoxGlyph.js +10 -0
  288. package/src/charting/glyphs/CubeGlyph.js +19 -0
  289. package/src/charting/glyphs/CylinderGlyph.js +19 -0
  290. package/src/charting/glyphs/DashedDoubleArrowGlyph.js +11 -0
  291. package/src/charting/glyphs/DeviceGlyph.js +17 -0
  292. package/src/charting/glyphs/DiamondGlyph.js +17 -0
  293. package/src/charting/glyphs/DocumentGlyph.js +17 -0
  294. package/src/charting/glyphs/DoubleArrowGlyph.js +23 -0
  295. package/src/charting/glyphs/DoubleCircleGlyph.js +24 -0
  296. package/src/charting/glyphs/EllipseGlyph.js +18 -0
  297. package/src/charting/glyphs/FactoryGlyph.js +20 -0
  298. package/src/charting/glyphs/FlagGlyph.js +16 -0
  299. package/src/charting/glyphs/GapCircleGlyph.js +17 -0
  300. package/src/charting/glyphs/GearGlyph.js +37 -0
  301. package/src/charting/glyphs/Glyph.js +98 -0
  302. package/src/charting/glyphs/GroupingBoxGlyph.js +13 -0
  303. package/src/charting/glyphs/HalfCircleGlyph.js +22 -0
  304. package/src/charting/glyphs/HexagonGlyph.js +28 -0
  305. package/src/charting/glyphs/IconGlyph.js +22 -0
  306. package/src/charting/glyphs/ImageGlyph.js +16 -0
  307. package/src/charting/glyphs/JunctionGlyph.js +17 -0
  308. package/src/charting/glyphs/LollipopGlyph.js +22 -0
  309. package/src/charting/glyphs/MagnifierGlyph.js +17 -0
  310. package/src/charting/glyphs/NoteGlyph.js +33 -0
  311. package/src/charting/glyphs/ObjectBoxGlyph.js +21 -0
  312. package/src/charting/glyphs/OrJunctionGlyph.js +17 -0
  313. package/src/charting/glyphs/ParallelogramGlyph.js +20 -0
  314. package/src/charting/glyphs/PersonGlyph.js +23 -0
  315. package/src/charting/glyphs/PillGlyph.js +23 -0
  316. package/src/charting/glyphs/PinGlyph.js +18 -0
  317. package/src/charting/glyphs/PrincipleGlyph.js +23 -0
  318. package/src/charting/glyphs/ProductBoxGlyph.js +16 -0
  319. package/src/charting/glyphs/RectGlyph.js +15 -0
  320. package/src/charting/glyphs/RoundedBoxGlyph.js +13 -0
  321. package/src/charting/glyphs/StackGlyph.js +14 -0
  322. package/src/charting/glyphs/StepsGlyph.js +20 -0
  323. package/src/charting/glyphs/StickFigureGlyph.js +32 -0
  324. package/src/charting/glyphs/SystemSoftwareBoxGlyph.js +16 -0
  325. package/src/charting/glyphs/TabbedBoxGlyph.js +37 -0
  326. package/src/charting/glyphs/TargetGlyph.js +23 -0
  327. package/src/charting/glyphs/WavyBoxGlyph.js +17 -0
  328. package/src/charting/glyphs/WheelGlyph.js +28 -0
  329. package/src/charting/glyphs/drawGlyph.js +28 -0
  330. package/src/charting/glyphs/glyphSvg.js +55 -0
  331. package/src/charting/glyphs/index.js +109 -0
  332. package/src/charting/modelTree/AnalysisPanel.js +159 -0
  333. package/src/charting/modelTree/DiagramTabs.js +217 -0
  334. package/src/charting/modelTree/ModelTree.js +164 -0
  335. package/src/charting/modelTree/ModelTreePanel.js +914 -0
  336. package/src/charting/modelTree/TreeBuilder.js +238 -0
  337. package/src/charting/modelTree/TreeModeRegistry.js +51 -0
  338. package/src/charting/modelTree/TreeViewMode.js +110 -0
  339. package/src/charting/modelTree/buildFilterTrees.js +138 -0
  340. package/src/charting/modelTree/modes/FlatTreeMode.js +46 -0
  341. package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +62 -0
  342. package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +60 -0
  343. package/src/charting/modelTree/treeLayers.js +11 -0
  344. package/src/charting/report/reportHtml.js +82 -0
  345. package/src/charting/report/reportViewer.js +118 -0
  346. package/src/charting/shapes/CircleShape.js +19 -0
  347. package/src/charting/shapes/PathShape.js +17 -0
  348. package/src/charting/shapes/RectShape.js +20 -0
  349. package/src/charting/shapes/Shape.js +20 -0
  350. package/src/charting/shapes/ShapeFactory.js +23 -0
  351. package/src/charting/storage/LocalJsonStore.js +43 -0
  352. package/src/charting/templates/ActorTemplate.js +36 -0
  353. package/src/charting/templates/BoxTemplate.js +27 -0
  354. package/src/charting/templates/CircleTemplate.js +18 -0
  355. package/src/charting/templates/ClassTemplate.js +20 -0
  356. package/src/charting/templates/CloudTemplate.js +43 -0
  357. package/src/charting/templates/ComponentTemplate.js +19 -0
  358. package/src/charting/templates/CylinderTemplate.js +30 -0
  359. package/src/charting/templates/DataStoreTemplate.js +16 -0
  360. package/src/charting/templates/DiamondTemplate.js +10 -0
  361. package/src/charting/templates/DocumentTemplate.js +32 -0
  362. package/src/charting/templates/EllipseTemplate.js +15 -0
  363. package/src/charting/templates/FinalStateTemplate.js +12 -0
  364. package/src/charting/templates/GlyphTemplate.js +47 -0
  365. package/src/charting/templates/HexagonTemplate.js +17 -0
  366. package/src/charting/templates/LifelineTemplate.js +20 -0
  367. package/src/charting/templates/ManualInputTemplate.js +12 -0
  368. package/src/charting/templates/NoteTemplate.js +23 -0
  369. package/src/charting/templates/OctagonTemplate.js +7 -0
  370. package/src/charting/templates/PackageTemplate.js +25 -0
  371. package/src/charting/templates/ParallelogramTemplate.js +11 -0
  372. package/src/charting/templates/PentagonTemplate.js +5 -0
  373. package/src/charting/templates/PolygonTemplate.js +18 -0
  374. package/src/charting/templates/PredefinedProcessTemplate.js +13 -0
  375. package/src/charting/templates/RectangleTemplate.js +28 -0
  376. package/src/charting/templates/RegularPolygonTemplate.js +21 -0
  377. package/src/charting/templates/RoundedRectangleTemplate.js +5 -0
  378. package/src/charting/templates/StadiumTemplate.js +8 -0
  379. package/src/charting/templates/StarTemplate.js +17 -0
  380. package/src/charting/templates/SwimlaneTemplate.js +18 -0
  381. package/src/charting/templates/Template.js +208 -0
  382. package/src/charting/templates/TrapezoidTemplate.js +11 -0
  383. package/src/charting/templates/TriangleTemplate.js +12 -0
  384. package/src/charting/templates/index.js +31 -0
  385. package/src/charting/templates/outline.js +59 -0
  386. package/src/charting/templates/svg.js +19 -0
  387. package/src/charting/textToShapes.js +61 -0
  388. package/src/charting/toolbar/ToolbarButton.js +38 -0
  389. package/src/charting/toolbar/ToolbarCheckbox.js +31 -0
  390. package/src/charting/toolbar/ToolbarItem.js +19 -0
  391. package/src/charting/toolbar/ToolbarMenu.js +36 -0
  392. package/src/charting/toolbar/ToolbarSelect.js +38 -0
  393. package/src/charting/toolbar/ToolbarSeparator.js +7 -0
  394. package/src/charting/toolbar/ToolbarText.js +22 -0
  395. package/src/charting/toolbar/index.js +8 -0
  396. package/src/charting/toolbar/pickFile.js +14 -0
  397. package/src/charting/viewDecorations.js +85 -0
  398. package/src/charting/zOrder.js +57 -0
  399. package/src/csvTable.js +61 -0
  400. package/src/datamodel.js +122 -0
  401. package/src/datawindow/BoundedWindow.js +36 -0
  402. package/src/datawindow/FlatDataWindow.js +34 -0
  403. package/src/datawindow/GraphDataWindow.js +40 -0
  404. package/src/datawindow/GroupedSampleDataWindow.js +16 -0
  405. package/src/datawindow/SeriesDataWindow.js +42 -0
  406. package/src/datawindow/index.js +31 -0
  407. package/src/diagramCatalog.js +30 -0
  408. package/src/ebnfDiagram.js +57 -0
  409. package/src/ebnfParser.js +129 -0
  410. package/src/exportImage.js +233 -0
  411. package/src/index.js +2636 -0
  412. package/src/itIcons.js +84 -0
  413. package/src/kernelExpr.js +243 -0
  414. package/src/propertiesDialog.js +463 -0
  415. package/src/railroadDiagram.js +571 -0
  416. package/src/treeModeCatalog.js +16 -0
  417. package/src/workspace/ContextBus.js +79 -0
  418. package/src/workspace/EditorShell.js +67 -0
  419. package/src/workspace/Part.js +163 -0
  420. package/src/workspace/PartFactory.js +49 -0
  421. package/src/workspace/PartRegistry.js +86 -0
  422. package/src/workspace/Workspace.js +321 -0
  423. package/src/workspace/archimateServices.js +33 -0
  424. package/src/workspace/dom.js +120 -0
  425. package/src/workspace/index.js +75 -0
  426. package/src/workspace/layout/GridNode.js +280 -0
  427. package/src/workspace/layout/LayoutNode.js +89 -0
  428. package/src/workspace/layout/PartNode.js +77 -0
  429. package/src/workspace/layout/SplitNode.js +114 -0
  430. package/src/workspace/layout/TabsNode.js +191 -0
  431. package/src/workspace/layout/index.js +24 -0
  432. package/src/workspace/parts/AdapterPart.js +33 -0
  433. package/src/workspace/parts/ArchimateCanvasPart.js +345 -0
  434. package/src/workspace/parts/ArchimateEditorPart.js +79 -0
  435. package/src/workspace/parts/ChartPart.js +115 -0
  436. package/src/workspace/parts/ContentPart.js +34 -0
  437. package/src/workspace/parts/DetailPart.js +46 -0
  438. package/src/workspace/parts/DiagramEditorPart.js +135 -0
  439. package/src/workspace/parts/EditorPart.js +388 -0
  440. package/src/workspace/parts/HtmlPart.js +25 -0
  441. package/src/workspace/parts/ListPart.js +57 -0
  442. package/src/workspace/parts/ModelFile.js +187 -0
  443. package/src/workspace/parts/ModelsPart.js +135 -0
  444. package/src/workspace/styles.js +258 -0
  445. package/src/workspace/themes.js +96 -0
  446. package/src/workspace/workArea.js +413 -0
  447. package/src/workspace/workAreaModel.js +197 -0
  448. package/src/workspace.js +16 -0
  449. package/src/zip/ZipArchive.js +160 -0
  450. package/src/zip/crc32.js +25 -0
  451. package/src/zip/inflate.js +159 -0
@@ -0,0 +1,187 @@
1
+ import { pickFile } from '../../charting/toolbar/pickFile.js';
2
+ import { downloadBlob } from '../../exportImage.js';
3
+
4
+ /** Each page's own title, as it was before any model's file name went in front of it (several models share one page). */
5
+ const PAGE_TITLES = new WeakMap();
6
+
7
+ /**
8
+ * ModelFile — the file an EditorPart's model is open from and saved to: its
9
+ * name, its format (one of the part's ModelFileFormats) and, where the
10
+ * browser lets a page write a file back (the File System Access API, in
11
+ * Chrome and Edge), its handle. Open… and Save As… choose one; Save writes
12
+ * back to it, or (no handle, or no such browser) asks where (Save As). After
13
+ * opening or saving, the model is marked saved; its edits since make the part
14
+ * "dirty", which `label` and the page title show.
15
+ */
16
+ export class ModelFile {
17
+ /** @param {EditorPart} part */
18
+ constructor(part) {
19
+ this.part = part;
20
+ this.name = null;
21
+ this.format = null;
22
+ this.handle = null;
23
+ }
24
+
25
+ get doc() { return this.part.document; }
26
+ get win() { return this.doc?.defaultView ?? globalThis; }
27
+
28
+ /** The format a new file is saved in: the part's `saveFormat()`, else its first. */
29
+ get defaultFormat() {
30
+ return this.part.saveFormat?.() ?? this.part.fileFormats()[0] ?? null;
31
+ }
32
+
33
+ /**
34
+ * What the model is called: the file's name, else (not from a file) the
35
+ * model's own name, else Untitled; and • when it has changed since it was
36
+ * opened or saved.
37
+ */
38
+ get label() {
39
+ return `${this.name ?? (this.part.model.name || 'Untitled')}${this.part.model.isDirty?.() ? ' •' : ''}`;
40
+ }
41
+
42
+ /** Open…, Save, Save As… for the File menu. */
43
+ menuItems() {
44
+ return [
45
+ { label: 'Open…', action: () => this.open() },
46
+ { label: `Save${this.name ? ` (${this.name})` : ''}`, action: () => this.save() },
47
+ { label: 'Save As…', action: () => this.saveAs() },
48
+ ];
49
+ }
50
+
51
+ /** Ctrl+O, Ctrl+S and Ctrl+Shift+S, while the part is on the page. */
52
+ onKey(e) {
53
+ // Only the part on screen: another in a hidden tab has its own file.
54
+ if (!(e.ctrlKey || e.metaKey) || e.altKey || !this.part.isShown()) return;
55
+ const key = e.key.toLowerCase();
56
+ if (key === 's') { e.preventDefault(); e.shiftKey ? this.saveAs() : this.save(); }
57
+ else if (key === 'o' && !e.shiftKey) { e.preventDefault(); this.open(); }
58
+ }
59
+
60
+ /**
61
+ * Ask for a file and open it, replacing the model: its format is the first
62
+ * of the part's whose extension and contents fit. Keeps its handle, so Save
63
+ * writes back to it. Returns the new model, or null.
64
+ */
65
+ async open() {
66
+ const chosen = await this.choose();
67
+ return chosen ? this.adopt(chosen) : null;
68
+ }
69
+
70
+ /**
71
+ * Ask for a file and read it as a model, without opening it anywhere yet:
72
+ * `{ model, name, format, handle }`, or null (cancelled, or not a model).
73
+ * `adopt()` opens it, in this part or another of its kind.
74
+ */
75
+ async choose() {
76
+ const formats = this.part.fileFormats().filter(f => f.imports !== false);
77
+ const accept = [...new Set(formats.flatMap(f => f.accept.split(',').map(e => e.trim()).filter(Boolean)))];
78
+ let file = null, handle = null;
79
+ if (typeof this.win.showOpenFilePicker === 'function') {
80
+ try {
81
+ [handle] = await this.win.showOpenFilePicker({ types: [{ description: 'Models', accept: { 'application/octet-stream': accept } }] });
82
+ file = await handle.getFile();
83
+ } catch (err) {
84
+ if (err?.name === 'AbortError') return null;
85
+ throw err;
86
+ }
87
+ } else {
88
+ file = await pickFile(accept.join(','), this.doc);
89
+ }
90
+ if (!file) return null;
91
+ const bytes = new Uint8Array(await file.arrayBuffer());
92
+ const text = () => new TextDecoder().decode(bytes);
93
+ const format = formats.find(f => f.acceptsName(file.name) && f.recognizes(f.readsBytes ? bytes : text()))
94
+ ?? formats.find(f => f.acceptsName(file.name));
95
+ if (!format) { this.tell(`Not a file this editor opens: ${file.name}`); return null; }
96
+ try {
97
+ return { model: format.import(format.readsBytes ? bytes : text()), name: file.name, format, handle };
98
+ } catch (err) {
99
+ this.tell(`Open failed: ${err.message}`);
100
+ return null;
101
+ }
102
+ }
103
+
104
+ /** Open what `choose()` read: the part edits its model, from that file. Returns the model. */
105
+ adopt({ model, name, format, handle = null }) {
106
+ this.part.replaceModel(model);
107
+ Object.assign(this, { name, format, handle });
108
+ this.showState();
109
+ return model;
110
+ }
111
+
112
+ /** Save to the open file (where the browser can write it back), else Save As. */
113
+ async save() {
114
+ if (!this.handle?.createWritable || !this.format) return this.saveAs();
115
+ return this._write(this.handle, this.format, this.name);
116
+ }
117
+
118
+ /**
119
+ * Ask where to save (the browser's save dialog where it has one, else a
120
+ * download), in the open file's format or the default one, and keep it.
121
+ */
122
+ async saveAs() {
123
+ const format = this.format ?? this.defaultFormat;
124
+ if (!format) return false;
125
+ const suggested = this.name ?? format.fileName;
126
+ if (typeof this.win.showSaveFilePicker === 'function') {
127
+ let handle;
128
+ try {
129
+ const ext = format.accept.split(',')[0].trim();
130
+ handle = await this.win.showSaveFilePicker({ suggestedName: suggested, types: [{ description: format.label, accept: { 'application/octet-stream': [ext] } }] });
131
+ } catch (err) {
132
+ if (err?.name === 'AbortError') return false;
133
+ throw err;
134
+ }
135
+ return this._write(handle, format, handle.name ?? suggested);
136
+ }
137
+ // No way to write a file: download it (the page cannot write it back later).
138
+ const { data, mimeType } = format.export(this.part.model);
139
+ downloadBlob(new this.win.Blob([data], { type: mimeType }), suggested);
140
+ Object.assign(this, { name: suggested, format, handle: null });
141
+ this._saved();
142
+ return true;
143
+ }
144
+
145
+ /** @private */
146
+ async _write(handle, format, name) {
147
+ const { data } = format.export(this.part.model);
148
+ const writable = await handle.createWritable();
149
+ await writable.write(data);
150
+ await writable.close();
151
+ Object.assign(this, { name, format, handle });
152
+ this._saved();
153
+ return true;
154
+ }
155
+
156
+ /** @private */
157
+ _saved() {
158
+ this.part.model.markSaved?.();
159
+ this.showState();
160
+ }
161
+
162
+ /** The model now is not from a file (an import, a new model). */
163
+ forget() {
164
+ Object.assign(this, { name: null, format: null, handle: null });
165
+ this.showState();
166
+ }
167
+
168
+ /** Show the saved state: the page title, and anything listening (the part's toolbar). */
169
+ showState() {
170
+ const doc = this.doc;
171
+ if (doc && this.part.isShown()) {
172
+ if (!PAGE_TITLES.has(doc)) PAGE_TITLES.set(doc, doc.title);
173
+ doc.title = `${this.label} — ${PAGE_TITLES.get(doc)}`;
174
+ }
175
+ this.part.onFileState?.(this);
176
+ }
177
+
178
+ /** Put the page title back (the part is going). */
179
+ restoreTitle() {
180
+ if (this.doc && PAGE_TITLES.has(this.doc)) this.doc.title = PAGE_TITLES.get(this.doc);
181
+ }
182
+
183
+ /** @private */
184
+ tell(message) {
185
+ (this.win.alert ?? (() => {}))(message);
186
+ }
187
+ }
@@ -0,0 +1,135 @@
1
+ import { Part } from '../Part.js';
2
+ import { WorkArea } from '../workArea.js';
3
+ import { el } from '../dom.js';
4
+
5
+ /**
6
+ * ModelsPart — several models open at once (as Archi's model tree holds
7
+ * several): one editor part per model (any EditorPart type, `editorType`),
8
+ * each a tab in a work area, so each keeps its own file, unsaved state and
9
+ * undo history, and two can sit side by side. Copy and paste go between
10
+ * them as between any two editors.
11
+ *
12
+ * The editor parts it hosts find it as `ctx.models` and offer, in their File
13
+ * menu, New model, Open… in a new tab and Close model. A tab shows its file's
14
+ * name and • while it has unsaved changes; closing one with unsaved changes
15
+ * asks first; the page title follows the model in front. The last model
16
+ * closed leaves a new, empty one.
17
+ *
18
+ * Spec: `{ id, type: 'models', editorType, models?: [editor part spec], newModel?: editor part spec }`:
19
+ * `models` are opened at the start (one empty one without), `newModel` is what New model makes.
20
+ */
21
+ export class ModelsPart extends Part {
22
+ static type = 'models';
23
+
24
+ constructor(spec = {}) {
25
+ super(spec);
26
+ if (!spec.editorType) throw new TypeError('ModelsPart needs an editorType (the editor part type, e.g. "archimate-canvas")');
27
+ this.editorType = spec.editorType;
28
+ /** The ids of the editor parts open here, in the order opened. */
29
+ this.modelIds = [];
30
+ this.work = null;
31
+ this._next = 1;
32
+ }
33
+
34
+ get registry() {
35
+ return this.ctx?.registry ?? null;
36
+ }
37
+
38
+ render() {
39
+ Object.assign(this.container.style, { display: 'flex', flexDirection: 'column', height: '100%' });
40
+ const host = this.container.appendChild(el({ style: { flex: '1 1 auto', minHeight: '0' } }));
41
+ this.work = new WorkArea({
42
+ placeholder: { cls: 'ws-workarea-empty', text: 'No model open' },
43
+ // A tab's × asks first when its model has unsaved changes (closeModel closes it).
44
+ beforeClose: (id) => { this.closeModel(id); return false; },
45
+ onChange: () => this.activeModel()?.file?.showState?.(),
46
+ });
47
+ this.work.render(host, { ...this.ctx, models: this });
48
+ const specs = this.spec.models?.length ? this.spec.models : [this.spec.newModel ?? {}];
49
+ const parts = specs.map(spec => this.newModel(spec));
50
+ if (parts[0]) this.work.focus(parts[0].id);
51
+ }
52
+
53
+ /** The editor parts open here, in order. */
54
+ models() {
55
+ return this.modelIds.map(id => this.registry?.get(id)).filter(Boolean);
56
+ }
57
+
58
+ /** The editor part of the model in front (the selected tab of the active group). */
59
+ activeModel() {
60
+ const id = this.work?.activePart();
61
+ return id ? this.registry?.get(id) ?? null : null;
62
+ }
63
+
64
+ /**
65
+ * Open a new model in a tab: an editor part of `editorType` made from `spec`
66
+ * (default the spec's `newModel`, an empty model). Returns the part.
67
+ */
68
+ newModel(spec = this.spec.newModel ?? {}) {
69
+ const id = spec.id && !this.registry.has(spec.id) ? spec.id : this._freshId();
70
+ const part = this.registry.add({ ...spec, id, type: this.editorType });
71
+ this.modelIds.push(id);
72
+ this.work.open(id);
73
+ this.fileStateChanged(part);
74
+ return part;
75
+ }
76
+
77
+ /**
78
+ * Ask for a file (as `from`'s Open… does) and open it in a new tab,
79
+ * leaving `from`'s model as it is. Returns the new part, or null.
80
+ */
81
+ async openInNewTab(from) {
82
+ const chosen = await from.file.choose();
83
+ if (!chosen) return null;
84
+ const part = this.newModel();
85
+ part.file.adopt(chosen);
86
+ return part;
87
+ }
88
+
89
+ /**
90
+ * Close a model's tab; with unsaved changes, only once confirmed. The last
91
+ * one closed leaves a new, empty model. Returns whether it closed.
92
+ */
93
+ closeModel(id) {
94
+ const part = this.registry?.get(id);
95
+ if (!part || !this.modelIds.includes(id)) return false;
96
+ if (part.model?.isDirty?.() && !this.confirm(`"${this.labelOf(part)}" has unsaved changes. Close it anyway?`)) return false;
97
+ this.work.close(id);
98
+ this.modelIds = this.modelIds.filter(m => m !== id);
99
+ this.registry.remove(id);
100
+ if (!this.modelIds.length) this.newModel();
101
+ else this.activeModel()?.file?.showState?.();
102
+ return true;
103
+ }
104
+
105
+ /** A model's tab label: what its toolbar and the page title call it (ModelFile#label). */
106
+ labelOf(part) {
107
+ return part.fileLabel;
108
+ }
109
+
110
+ /** An editor part's file or saved state changed: its tab says so. */
111
+ fileStateChanged(part) {
112
+ part.title = this.labelOf(part);
113
+ this.work?.refreshLabels();
114
+ }
115
+
116
+ /** Ask the user (the page's confirm). @protected */
117
+ confirm(message) {
118
+ const win = this.container?.ownerDocument?.defaultView ?? globalThis;
119
+ return typeof win.confirm === 'function' ? win.confirm(message) : true;
120
+ }
121
+
122
+ /** @private */
123
+ _freshId() {
124
+ let id;
125
+ do { id = `${this.id}-model-${this._next++}`; } while (this.registry.has(id));
126
+ return id;
127
+ }
128
+
129
+ dispose() {
130
+ this.work?.dispose();
131
+ for (const id of this.modelIds) this.registry?.remove(id);
132
+ this.modelIds = [];
133
+ super.dispose();
134
+ }
135
+ }
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Shell CSS, shipped as a string and injected once into document.head.
3
+ *
4
+ * Light DOM by design: a mashup shell hosts parts that bring their own CSS, and
5
+ * a consumer stylesheet (workbench.css, say) cannot cross a shadow boundary —
6
+ * every adapted part would render unstyled. Encapsulation for genuinely
7
+ * untrusted parts is an iframe's job, not the shell's. Everything here is
8
+ * therefore prefixed `ws-`, and every colour is a custom property so a consumer
9
+ * can retheme without overriding rules.
10
+ *
11
+ * Grid geometry constants here MUST match GridNode.js's ROW_UNIT_PX/GRID_GAP_PX.
12
+ *
13
+ * CSS stays a string. The "build it from JS and JSON" guardrail is about
14
+ * markup — a stylesheet is not a DOM tree, and shredding it into style objects
15
+ * would cost readability for nothing.
16
+ */
17
+ import { el } from './dom.js';
18
+
19
+ export const WORKSPACE_STYLE_ID = 'ws-workspace-styles';
20
+
21
+ export const WORKSPACE_CSS = `
22
+ .ws-workspace {
23
+ --ws-bg: #ffffff;
24
+ --ws-fg: #1a1a1a;
25
+ --ws-panel-bg: #f3f3f3;
26
+ --ws-accent: #4a90e2;
27
+ --ws-border: #cccccc;
28
+ --ws-toolbar-bg: #222222;
29
+ --ws-toolbar-fg: #ffffff;
30
+ --ws-tabbar-bg: #ebebeb;
31
+ --ws-tab-bg: transparent;
32
+ --ws-tab-fg: #333333;
33
+ --ws-muted: #6b6b6b;
34
+
35
+ display: flex;
36
+ flex-direction: column;
37
+ height: 100%;
38
+ min-height: 0;
39
+ font-family: system-ui, -apple-system, Segoe UI, sans-serif;
40
+ font-size: 13px;
41
+ background: var(--ws-bg);
42
+ color: var(--ws-fg);
43
+ box-sizing: border-box;
44
+ }
45
+ .ws-workspace *, .ws-workspace *::before, .ws-workspace *::after { box-sizing: inherit; }
46
+
47
+ /* The values above are the light theme, repeated here only as the pre-JS
48
+ default so the shell never flashes unstyled. Themes themselves live in
49
+ themes.js as data and are applied as inline custom properties — see the
50
+ note there on why there is no [data-theme="dark"] block to go with this. */
51
+
52
+ /* ── Chrome ─────────────────────────────────────────────────────────────── */
53
+ .ws-toolbar {
54
+ display: flex; align-items: center; gap: 8px;
55
+ padding: 6px 10px; flex: 0 0 auto;
56
+ background: var(--ws-toolbar-bg); color: var(--ws-toolbar-fg);
57
+ }
58
+ .ws-toolbar-title { font-weight: 600; }
59
+ .ws-toolbar-spacer { flex: 1; }
60
+ .ws-perspectives { display: flex; gap: 2px; }
61
+ .ws-perspective-btn {
62
+ padding: 4px 12px; font: inherit; font-size: 12px; cursor: pointer;
63
+ color: var(--ws-toolbar-fg); background: rgba(127,127,127,.12);
64
+ border: 1px solid rgba(127,127,127,.25); border-radius: 4px 4px 0 0;
65
+ }
66
+ .ws-perspective-btn:hover { background: rgba(127,127,127,.25); }
67
+ .ws-perspective-btn.ws-active {
68
+ background: var(--ws-accent); color: #000;
69
+ border-bottom-color: var(--ws-accent);
70
+ }
71
+
72
+ .ws-theme-picker { display: flex; align-items: center; gap: 5px; }
73
+ .ws-theme-picker label { font-size: 11px; opacity: .7; }
74
+ .ws-theme-select {
75
+ font: inherit; font-size: 12px; padding: 3px 6px; cursor: pointer;
76
+ color: var(--ws-toolbar-fg); background: rgba(127,127,127,.25);
77
+ border: 1px solid rgba(127,127,127,.4); border-radius: 3px;
78
+ }
79
+ /* The dropdown list itself is painted by the OS against the page, not the
80
+ toolbar, so its own colours have to come from the panel vars or the options
81
+ render as light-on-light in a dark theme. */
82
+ .ws-theme-select option { background: var(--ws-panel-bg); color: var(--ws-fg); }
83
+
84
+ .ws-root { flex: 1 1 auto; min-height: 0; display: flex; }
85
+ .ws-root > .ws-node { flex: 1 1 auto; min-width: 0; min-height: 0; }
86
+
87
+ /* ── Layout nodes ───────────────────────────────────────────────────────── */
88
+ .ws-node { min-width: 0; min-height: 0; }
89
+
90
+ .ws-split-row, .ws-split-col { display: flex; height: 100%; width: 100%; }
91
+ .ws-split-row { flex-direction: row; }
92
+ .ws-split-col { flex-direction: column; }
93
+ .ws-split-pane { display: flex; min-width: 0; min-height: 0; overflow: hidden; }
94
+ .ws-split-pane > .ws-node { flex: 1 1 auto; min-width: 0; min-height: 0; }
95
+
96
+ .ws-splitter { background: var(--ws-border); flex: 0 0 5px; }
97
+ .ws-splitter-row { cursor: col-resize; }
98
+ .ws-splitter-col { cursor: row-resize; }
99
+ .ws-splitter:hover, .ws-splitting .ws-splitter { background: var(--ws-accent); }
100
+ .ws-splitting { user-select: none; }
101
+
102
+ .ws-tabs { display: flex; flex-direction: column; height: 100%; width: 100%; }
103
+ .ws-tabstrip {
104
+ display: flex; gap: 2px; flex: 0 0 auto; overflow-x: auto;
105
+ background: var(--ws-tabbar-bg); border-bottom: 1px solid var(--ws-border);
106
+ }
107
+ .ws-tab {
108
+ display: inline-flex; align-items: center; gap: 6px;
109
+ padding: 6px 10px 6px 14px; font: inherit; font-size: 12px; cursor: pointer;
110
+ background: var(--ws-tab-bg); color: var(--ws-tab-fg);
111
+ border: none; border-bottom: 2px solid transparent; white-space: nowrap;
112
+ user-select: none;
113
+ }
114
+ .ws-tab:hover { background: rgba(127,127,127,.15); }
115
+ .ws-tab:focus-visible { outline: 2px solid var(--ws-accent); outline-offset: -2px; }
116
+ .ws-tab-active { border-bottom-color: var(--ws-accent); font-weight: 600; }
117
+ .ws-tab-label { overflow: hidden; text-overflow: ellipsis; max-width: 22ch; }
118
+ .ws-tabclose {
119
+ flex: 0 0 auto; width: 16px; height: 16px; padding: 0; border: none; border-radius: 3px;
120
+ background: transparent; color: inherit; font: inherit; font-size: 14px; line-height: 14px;
121
+ cursor: pointer; opacity: 0;
122
+ }
123
+ /* Revealed on hover or while active, so a strip of tabs is not a row of
124
+ crosses — but always reachable, never display:none, or it could not be hit. */
125
+ .ws-tab:hover .ws-tabclose, .ws-tab-active .ws-tabclose, .ws-tabclose:focus { opacity: .7; }
126
+ .ws-tabclose:hover { opacity: 1; background: rgba(127,127,127,.3); }
127
+ .ws-tabbody { flex: 1 1 auto; min-height: 0; position: relative; }
128
+ .ws-tabpane { position: absolute; inset: 0; overflow: auto; }
129
+
130
+ /* Which group the next view opens into. WorkArea only applies this once there
131
+ is more than one group — with one, it is not a question anyone is asking. */
132
+ .ws-group-active > .ws-tabstrip { box-shadow: inset 0 2px 0 var(--ws-accent); }
133
+ .ws-workarea-empty {
134
+ display: flex; align-items: center; justify-content: center; height: 100%;
135
+ color: var(--ws-muted); font-size: 13px; background: var(--ws-panel-bg);
136
+ }
137
+
138
+ /* Action bar — filled by WorkArea from the focused view's own actions. */
139
+ .ws-actionbar {
140
+ display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
141
+ padding: 4px 8px; min-height: 0;
142
+ }
143
+ .ws-actionbar-empty { padding: 0; }
144
+ .ws-action {
145
+ display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
146
+ padding: 4px 10px; font: inherit; font-size: 12px; cursor: pointer;
147
+ color: var(--ws-fg); background: var(--ws-panel-bg);
148
+ border: 1px solid var(--ws-border); border-radius: 4px;
149
+ }
150
+ .ws-action:hover:not(:disabled) { border-color: var(--ws-accent); }
151
+ .ws-action:disabled { opacity: .45; cursor: default; }
152
+ .ws-action-sep { width: 1px; align-self: stretch; margin: 2px 4px; background: var(--ws-border); }
153
+
154
+ /* Outline rail — the focused view's own tree, mounted as a pooled part. */
155
+ .ws-outline { height: 100%; overflow: auto; background: var(--ws-panel-bg); }
156
+ .ws-outline-empty { display: flex; align-items: center; justify-content: center; }
157
+ .ws-outline-none { color: var(--ws-muted); font-size: 12px; padding: 12px; text-align: center; }
158
+
159
+ .ws-grid {
160
+ display: grid; gap: 14px; grid-auto-rows: 20px;
161
+ padding: 14px; overflow: auto; height: 100%; width: 100%;
162
+ align-content: start; background: var(--ws-panel-bg);
163
+ }
164
+ .ws-pane {
165
+ display: flex; flex-direction: column; min-width: 0; min-height: 0;
166
+ position: relative; overflow: hidden;
167
+ background: var(--ws-bg); border: 1px solid var(--ws-border); border-radius: 6px;
168
+ }
169
+ .ws-pane-header {
170
+ flex: 0 0 auto; padding: 6px 10px; font-size: 12px; font-weight: 600;
171
+ background: var(--ws-panel-bg); border-bottom: 1px solid var(--ws-border);
172
+ cursor: move; user-select: none;
173
+ display: flex; align-items: center; gap: 8px;
174
+ }
175
+ .ws-pane-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
176
+ /* Buttons live here so _attachDragMove's closest('.ws-pane-controls') check
177
+ keeps a click from starting a pane drag. */
178
+ .ws-pane-controls { flex: 0 0 auto; display: flex; gap: 2px; cursor: default; }
179
+ .ws-pane-btn {
180
+ font: inherit; font-size: 12px; font-weight: normal; line-height: 1;
181
+ padding: 2px 6px; cursor: pointer; border-radius: 3px;
182
+ color: var(--ws-fg); background: transparent; border: 1px solid transparent;
183
+ }
184
+ .ws-pane-btn:hover { background: rgba(127,127,127,.25); border-color: var(--ws-border); }
185
+ .ws-pane-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
186
+ .ws-pane-dragging { opacity: .75; z-index: 10; box-shadow: 0 6px 20px rgba(0,0,0,.3); }
187
+ .ws-resize-handle {
188
+ position: absolute; right: 0; bottom: 0; width: 16px; height: 16px;
189
+ display: flex; align-items: center; justify-content: center;
190
+ font-size: 10px; color: var(--ws-muted); cursor: nwse-resize; user-select: none;
191
+ }
192
+
193
+ /* ── Parts ──────────────────────────────────────────────────────────────── */
194
+ .ws-part-host { height: 100%; width: 100%; min-width: 0; min-height: 0; display: flex; }
195
+ .ws-part { flex: 1 1 auto; min-width: 0; min-height: 0; overflow: auto; padding: 10px; }
196
+ /* A chart sizes itself to its host, so padding would shrink it every re-render. */
197
+ .ws-part[data-part-type="chart"] { padding: 0; overflow: hidden; }
198
+ .ws-part[data-part-type="diagram-editor"] { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
199
+ .ws-part-missing { padding: 10px; color: #c0392b; font-size: 12px; }
200
+ .ws-muted { color: var(--ws-muted); }
201
+
202
+ .ws-list { list-style: none; margin: 0; padding: 0; }
203
+ .ws-list-item {
204
+ display: block; width: 100%; text-align: left; padding: 5px 8px;
205
+ font: inherit; cursor: pointer; color: inherit;
206
+ background: transparent; border: none; border-radius: 3px;
207
+ }
208
+ .ws-list-item:hover { background: rgba(127,127,127,.15); }
209
+ .ws-list-item-active { background: var(--ws-accent); color: #000; }
210
+
211
+ .ws-proplist { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0; }
212
+ .ws-proplist dt { color: var(--ws-muted); font-size: 12px; }
213
+ .ws-proplist dd { margin: 0; word-break: break-word; }
214
+
215
+ .ws-chart { width: 100%; height: 100%; min-height: 120px; }
216
+
217
+ /* Make chart chrome follow the theme.
218
+ *
219
+ * RenderEngine hard-codes its axis/label colours for a light background
220
+ * (#333 titles, #666 ticks, black category labels and axis line, #999 tick
221
+ * marks, #eee gridlines) and exposes no option to change them, so on a dark
222
+ * theme the title and labels render nearly invisible against --ws-bg.
223
+ *
224
+ * These are emitted as SVG *presentation attributes*, which sit below author
225
+ * CSS in the cascade — so a stylesheet rule overrides them with no change to
226
+ * the engine. Matching on the exact literal keeps the override surgical:
227
+ * anything deliberately coloured (bars, series palettes, white node initials
228
+ * in a graph) is left alone, because only the engine's own default greys are
229
+ * selected.
230
+ *
231
+ * The trade-off is that these selectors are coupled to those literals — if the
232
+ * engine's defaults change, the override silently stops matching. test/
233
+ * workspace.test.js pins the literal set for exactly that reason.
234
+ *
235
+ * Scoped to the workspace, NOT to .ws-chart: a chart is just as often rendered
236
+ * into a plain adopted container (AdapterPart wrapping an existing panel, as
237
+ * csv-chart-builder does) as into a ChartPart, and scoping to ChartPart's own
238
+ * class silently left every one of those unthemed.
239
+ *
240
+ * Each has its own var so a consumer can retheme chart chrome independently
241
+ * of the shell; all default to the shell's own colours. */
242
+ .ws-workspace svg text[fill="#333"],
243
+ .ws-workspace svg text[fill="black"] { fill: var(--ws-chart-fg, var(--ws-fg)); }
244
+ .ws-workspace svg text[fill="#666"] { fill: var(--ws-chart-muted, var(--ws-muted)); }
245
+ .ws-workspace svg path[stroke="black"] { stroke: var(--ws-chart-axis, var(--ws-fg)); }
246
+ .ws-workspace svg path[stroke="#999"] { stroke: var(--ws-chart-tick, var(--ws-muted)); }
247
+ .ws-workspace svg path[stroke="#eee"] { stroke: var(--ws-chart-grid, var(--ws-border)); }
248
+ `;
249
+
250
+ /** Inject the shell stylesheet once per document. */
251
+ export function ensureStyles(doc = document) {
252
+ if (doc.getElementById(WORKSPACE_STYLE_ID)) return;
253
+ doc.head.appendChild(el({
254
+ tag: 'style',
255
+ attrs: { id: WORKSPACE_STYLE_ID },
256
+ text: WORKSPACE_CSS,
257
+ }, doc));
258
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * themes.js — built-in theme variable sets, as data.
3
+ *
4
+ * A theme is a plain map of CSS custom properties. Keeping them here as JS
5
+ * objects rather than as `[data-theme=…]` blocks in the stylesheet is what lets
6
+ * the shell enumerate them: the toolbar's theme picker is built from whatever
7
+ * is registered, so a consumer's own theme appears in it automatically with no
8
+ * CSS change. It also keeps one source of truth — a CSS block plus a JS map
9
+ * would be two.
10
+ *
11
+ * `styles.js` still carries the light values as plain defaults on
12
+ * `.ws-workspace`, so the shell looks right in the moment before a theme is
13
+ * applied rather than flashing unstyled.
14
+ *
15
+ * Any subset of these keys is valid in a custom theme; unset ones fall back to
16
+ * the stylesheet defaults, because `applyTheme` clears the previous theme's
17
+ * properties before writing the new one's.
18
+ */
19
+
20
+ export const THEME_VARS = [
21
+ '--ws-bg', '--ws-fg', '--ws-panel-bg', '--ws-accent', '--ws-border',
22
+ '--ws-toolbar-bg', '--ws-toolbar-fg', '--ws-tabbar-bg', '--ws-tab-bg',
23
+ '--ws-tab-fg', '--ws-muted',
24
+ ];
25
+
26
+ export const LIGHT_THEME = {
27
+ '--ws-bg': '#ffffff',
28
+ '--ws-fg': '#1a1a1a',
29
+ '--ws-panel-bg': '#f3f3f3',
30
+ '--ws-accent': '#4a90e2',
31
+ '--ws-border': '#cccccc',
32
+ '--ws-toolbar-bg': '#222222',
33
+ '--ws-toolbar-fg': '#ffffff',
34
+ '--ws-tabbar-bg': '#ebebeb',
35
+ '--ws-tab-bg': 'transparent',
36
+ '--ws-tab-fg': '#333333',
37
+ '--ws-muted': '#6b6b6b',
38
+ };
39
+
40
+ export const DARK_THEME = {
41
+ '--ws-bg': '#1e1e1e',
42
+ '--ws-fg': '#f0f0f0',
43
+ '--ws-panel-bg': '#252526',
44
+ '--ws-accent': '#ffcc00',
45
+ '--ws-border': '#3a3a3a',
46
+ '--ws-toolbar-bg': '#141414',
47
+ '--ws-toolbar-fg': '#f0f0f0',
48
+ '--ws-tabbar-bg': '#2a2a2a',
49
+ '--ws-tab-bg': 'transparent',
50
+ '--ws-tab-fg': '#d0d0d0',
51
+ '--ws-muted': '#9a9a9a',
52
+ };
53
+
54
+ /** Higher contrast than `dark`, for low-light or accessibility needs. */
55
+ export const MIDNIGHT_THEME = {
56
+ '--ws-bg': '#0b0e14',
57
+ '--ws-fg': '#e6e6e6',
58
+ '--ws-panel-bg': '#111722',
59
+ '--ws-accent': '#59c2ff',
60
+ '--ws-border': '#1f2733',
61
+ '--ws-toolbar-bg': '#060911',
62
+ '--ws-toolbar-fg': '#e6e6e6',
63
+ '--ws-tabbar-bg': '#0e131c',
64
+ '--ws-tab-bg': 'transparent',
65
+ '--ws-tab-fg': '#b9c2cf',
66
+ '--ws-muted': '#8b97a8',
67
+ };
68
+
69
+ /** Warm, low-blue paper tone — easier than pure white for long sessions. */
70
+ export const SEPIA_THEME = {
71
+ '--ws-bg': '#fbf3e4',
72
+ '--ws-fg': '#3b3228',
73
+ '--ws-panel-bg': '#f2e7d2',
74
+ '--ws-accent': '#b58900',
75
+ '--ws-border': '#ded0b4',
76
+ '--ws-toolbar-bg': '#4a4033',
77
+ '--ws-toolbar-fg': '#fbf3e4',
78
+ '--ws-tabbar-bg': '#eee0c6',
79
+ '--ws-tab-bg': 'transparent',
80
+ '--ws-tab-fg': '#5b5040',
81
+ '--ws-muted': '#8a7c65',
82
+ };
83
+
84
+ export const BUILTIN_THEMES = {
85
+ light: LIGHT_THEME,
86
+ dark: DARK_THEME,
87
+ midnight: MIDNIGHT_THEME,
88
+ sepia: SEPIA_THEME,
89
+ };
90
+
91
+ /**
92
+ * The picker's "follow the OS" option. Not a theme itself — it resolves to
93
+ * `light` or `dark` at apply time and re-resolves when the OS setting changes,
94
+ * which is why it is a reserved name rather than an entry in BUILTIN_THEMES.
95
+ */
96
+ export const SYSTEM_THEME = 'system';