@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,304 @@
1
+ /**
2
+ * CheckboxTreeSelector — generic tree with checkboxes and tri-state cascading logic.
3
+ *
4
+ * Reusable across any domain: build a tree of { id, label, children? } nodes and get back a
5
+ * DOM container + methods to track checked/unchecked ids. Tri-state: checking a branch checks
6
+ * all descendants; parent shows indeterminate when some (but not all) children are checked.
7
+ *
8
+ * Usage:
9
+ * const selector = new CheckboxTreeSelector({ doc: document, nodes: [...], checkedIds: new Set(['id1']) });
10
+ * const container = selector.build();
11
+ * parent.appendChild(container);
12
+ * selector.onChange(ids => { ... }); // fires on any checkbox click
13
+ *
14
+ * Node shape:
15
+ * { id: string, label: string, children?: Node[] }
16
+ */
17
+
18
+ export class CheckboxTreeSelector {
19
+ constructor({ doc, nodes = [], checkedIds = null } = {}) {
20
+ this.doc = doc;
21
+ this.nodes = nodes;
22
+ this._checkedIds = checkedIds || new Set(); // null (default) = everything checked
23
+ this._listeners = [];
24
+ this._checkboxesByNodeId = new Map(); // nodeId -> input[type=checkbox]
25
+ }
26
+
27
+ build() {
28
+ const container = this.doc.createElement('div');
29
+ container.style.cssText = 'font-family: sans-serif; font-size: 13px; padding: 4px 0;';
30
+
31
+ for (const node of this.nodes) {
32
+ this._buildNode(node, container, 0);
33
+ }
34
+
35
+ return container;
36
+ }
37
+
38
+ /**
39
+ * Recursively build DOM for a node and its children.
40
+ * @private
41
+ */
42
+ _buildNode(node, parent, depth = 0) {
43
+ if (!node.children || node.children.length === 0) {
44
+ // Leaf: checkbox + label
45
+ this._buildLeaf(node, parent, depth);
46
+ } else {
47
+ // Branch: <details>/<summary> + checkbox
48
+ this._buildBranch(node, parent, depth);
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Build a leaf node (no children).
54
+ * @private
55
+ */
56
+ _buildLeaf(node, parent, depth) {
57
+ const row = this.doc.createElement('div');
58
+ row.style.cssText = `display: flex; align-items: center; gap: 6px; margin-bottom: 4px; padding-left: ${depth * 16}px;`;
59
+
60
+ const checkbox = this.doc.createElement('input');
61
+ checkbox.type = 'checkbox';
62
+ checkbox.id = `checkbox-${node.id}`;
63
+ checkbox.checked = this._checkedIds.size === 0 || this._checkedIds.has(node.id);
64
+ checkbox.style.cssText = 'flex-shrink: 0; cursor: pointer;';
65
+
66
+ checkbox.addEventListener('change', () => {
67
+ this._updateChecked(node.id, checkbox.checked, true);
68
+ });
69
+
70
+ this._checkboxesByNodeId.set(node.id, checkbox);
71
+
72
+ const label = this.doc.createElement('label');
73
+ label.htmlFor = checkbox.id;
74
+ label.textContent = node.label;
75
+ label.style.cssText = 'flex: 1; cursor: pointer; user-select: none;';
76
+
77
+ row.appendChild(checkbox);
78
+ row.appendChild(label);
79
+ parent.appendChild(row);
80
+ }
81
+
82
+ /**
83
+ * Build a branch node (has children, collapsible).
84
+ * @private
85
+ */
86
+ _buildBranch(node, parent, depth) {
87
+ const details = this.doc.createElement('details');
88
+ details.style.cssText = `margin-bottom: 4px; padding-left: ${depth * 16}px;`;
89
+ details.open = true;
90
+
91
+ const summary = this.doc.createElement('summary');
92
+ summary.style.cssText = 'display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; padding: 2px 0;';
93
+
94
+ const checkbox = this.doc.createElement('input');
95
+ checkbox.type = 'checkbox';
96
+ checkbox.id = `checkbox-${node.id}`;
97
+ const isChecked = this._checkedIds.size === 0 || this._checkedIds.has(node.id);
98
+ const allChildrenChecked = this._allChildrenChecked(node);
99
+ const someChildrenChecked = this._someChildrenChecked(node);
100
+
101
+ checkbox.checked = isChecked && allChildrenChecked;
102
+ checkbox.indeterminate = isChecked && someChildrenChecked && !allChildrenChecked;
103
+ checkbox.style.cssText = 'flex-shrink: 0; cursor: pointer;';
104
+
105
+ checkbox.addEventListener('change', () => {
106
+ this._updateBranch(node, checkbox.checked);
107
+ });
108
+
109
+ this._checkboxesByNodeId.set(node.id, checkbox);
110
+
111
+ const label = this.doc.createElement('span');
112
+ label.textContent = node.label;
113
+ label.style.cssText = 'flex: 1; cursor: pointer; font-weight: 500;';
114
+
115
+ summary.appendChild(checkbox);
116
+ summary.appendChild(label);
117
+ details.appendChild(summary);
118
+
119
+ const childrenContainer = this.doc.createElement('div');
120
+ for (const child of node.children) {
121
+ this._buildNode(child, childrenContainer, depth + 1);
122
+ }
123
+ details.appendChild(childrenContainer);
124
+
125
+ parent.appendChild(details);
126
+ }
127
+
128
+ /**
129
+ * Check/uncheck a single leaf node and notify.
130
+ * @private
131
+ */
132
+ _updateChecked(nodeId, checked, notify = true) {
133
+ if (checked) {
134
+ this._checkedIds.add(nodeId);
135
+ } else {
136
+ this._checkedIds.delete(nodeId);
137
+ }
138
+
139
+ // Update parent indeterminate state (walk up tree — not used for flat leaves, but cleaner)
140
+ this._updateBranchStates();
141
+
142
+ if (notify) {
143
+ this._notifyListeners();
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Check/uncheck a branch and all its descendants.
149
+ * @private
150
+ */
151
+ _updateBranch(node, checked) {
152
+ const allIds = this._getAllNodeIds(node);
153
+ if (checked) {
154
+ allIds.forEach(id => this._checkedIds.add(id));
155
+ } else {
156
+ allIds.forEach(id => this._checkedIds.delete(id));
157
+ }
158
+
159
+ // Update DOM state for all affected checkboxes
160
+ this._updateAllCheckboxes();
161
+ this._updateBranchStates();
162
+ this._notifyListeners();
163
+ }
164
+
165
+ /**
166
+ * Collect all descendant node ids (including the node itself).
167
+ * @private
168
+ */
169
+ _getAllNodeIds(node) {
170
+ const ids = [node.id];
171
+ if (node.children) {
172
+ for (const child of node.children) {
173
+ ids.push(...this._getAllNodeIds(child));
174
+ }
175
+ }
176
+ return ids;
177
+ }
178
+
179
+ /**
180
+ * Check if all children (direct and nested) are checked.
181
+ * @private
182
+ */
183
+ _allChildrenChecked(node) {
184
+ if (!node.children || node.children.length === 0) return true;
185
+ return node.children.every(child => {
186
+ const childId = child.id;
187
+ const hasDescendants = child.children && child.children.length > 0;
188
+ if (hasDescendants) {
189
+ return this._allChildrenChecked(child);
190
+ } else {
191
+ return this._checkedIds.size === 0 || this._checkedIds.has(childId);
192
+ }
193
+ });
194
+ }
195
+
196
+ /**
197
+ * Check if at least one child (direct or nested) is checked.
198
+ * @private
199
+ */
200
+ _someChildrenChecked(node) {
201
+ if (!node.children || node.children.length === 0) return false;
202
+ return node.children.some(child => {
203
+ const childId = child.id;
204
+ const hasDescendants = child.children && child.children.length > 0;
205
+ if (hasDescendants) {
206
+ return this._someChildrenChecked(child) || (this._checkedIds.size === 0 || this._checkedIds.has(childId));
207
+ } else {
208
+ return this._checkedIds.size === 0 || this._checkedIds.has(childId);
209
+ }
210
+ });
211
+ }
212
+
213
+ /**
214
+ * Update checkbox states (indeterminate flags) for all branches.
215
+ * @private
216
+ */
217
+ _updateBranchStates() {
218
+ for (const [nodeId, checkbox] of this._checkboxesByNodeId) {
219
+ const node = this._findNode(nodeId);
220
+ if (node && node.children && node.children.length > 0) {
221
+ const allChecked = this._allChildrenChecked(node);
222
+ const someChecked = this._someChildrenChecked(node);
223
+ checkbox.checked = allChecked;
224
+ checkbox.indeterminate = someChecked && !allChecked;
225
+ }
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Find a node by id in the tree.
231
+ * @private
232
+ */
233
+ _findNode(id, nodes = this.nodes) {
234
+ for (const node of nodes) {
235
+ if (node.id === id) return node;
236
+ if (node.children) {
237
+ const found = this._findNode(id, node.children);
238
+ if (found) return found;
239
+ }
240
+ }
241
+ return null;
242
+ }
243
+
244
+ /**
245
+ * Get the set of currently-checked node ids.
246
+ */
247
+ getCheckedIds() {
248
+ return new Set(this._checkedIds);
249
+ }
250
+
251
+ /**
252
+ * Set which nodes are checked (Set<string> | null = everything checked).
253
+ */
254
+ setCheckedIds(ids) {
255
+ this._checkedIds = ids ? new Set(ids) : new Set();
256
+ // Update all checkbox states (checked + indeterminate) to reflect new state
257
+ this._updateAllCheckboxes();
258
+ this._updateBranchStates();
259
+ }
260
+
261
+ /**
262
+ * Update all checkboxes to match current _checkedIds state.
263
+ * @private
264
+ */
265
+ _updateAllCheckboxes() {
266
+ for (const [nodeId, checkbox] of this._checkboxesByNodeId) {
267
+ const node = this._findNode(nodeId);
268
+ if (!node) continue;
269
+ if (node.children && node.children.length > 0) {
270
+ // Branch: set checked if all children checked, indeterminate if some checked
271
+ const allChecked = this._allChildrenChecked(node);
272
+ const someChecked = this._someChildrenChecked(node);
273
+ checkbox.checked = allChecked;
274
+ checkbox.indeterminate = someChecked && !allChecked;
275
+ } else {
276
+ // Leaf: set checked if in _checkedIds
277
+ checkbox.checked = this._checkedIds.size === 0 || this._checkedIds.has(nodeId);
278
+ checkbox.indeterminate = false;
279
+ }
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Register a change listener. Called with Set<string> of checked ids.
285
+ */
286
+ onChange(callback) {
287
+ this._listeners.push(callback);
288
+ }
289
+
290
+ /**
291
+ * Notify all listeners of the current checked state.
292
+ * @private
293
+ */
294
+ _notifyListeners() {
295
+ const ids = this.getCheckedIds();
296
+ for (const cb of this._listeners) {
297
+ try {
298
+ cb(ids);
299
+ } catch (err) {
300
+ console.warn('CheckboxTreeSelector listener error:', err);
301
+ }
302
+ }
303
+ }
304
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * ColorField — the control a FormDialog shows for a `color` field: the value
3
+ * as text (`#rrggbb`, or `none` for no colour, which a native colour input
4
+ * cannot hold), the browser's colour picker, and a row of preset swatches.
5
+ * The text box is the field's control (FormDialog `controls[key]`), so its
6
+ * `value` is what the field reads.
7
+ *
8
+ * Presets come from the field (`presets`) or ColorField.PRESETS; `allowNone:
9
+ * false` leaves out "No colour" (e.g. for text).
10
+ */
11
+ export class ColorField {
12
+ /** The value that means no colour (transparent). */
13
+ static NONE = 'none';
14
+
15
+ /** The swatches every colour field offers unless it names its own. */
16
+ static PRESETS = Object.freeze([
17
+ { value: 'none', name: 'No colour' },
18
+ { value: '#000000', name: 'Black' },
19
+ { value: '#ffffff', name: 'White' },
20
+ { value: '#ff0000', name: 'Red' },
21
+ { value: '#00b050', name: 'Green' },
22
+ { value: '#0070c0', name: 'Blue' },
23
+ { value: '#ffff00', name: 'Yellow' },
24
+ { value: '#ffa500', name: 'Orange' },
25
+ { value: '#7030a0', name: 'Purple' },
26
+ { value: '#808080', name: 'Grey' },
27
+ { value: '#d9d9d9', name: 'Light grey' },
28
+ ]);
29
+
30
+ /** Whether `value` is a colour the picker can show (#rrggbb). */
31
+ static isHex(value) {
32
+ return /^#[0-9a-f]{6}$/i.test(String(value ?? ''));
33
+ }
34
+
35
+ /**
36
+ * The presets a field offers.
37
+ * @param {{presets?: Array<{value, name}>, allowNone?: boolean}} field
38
+ */
39
+ static presetsFor({ presets = ColorField.PRESETS, allowNone = true } = {}) {
40
+ return presets.filter(p => allowNone || p.value !== ColorField.NONE);
41
+ }
42
+
43
+ /**
44
+ * The el() spec of the control.
45
+ * @param {Object} field - The FormDialog field (value, presets, allowNone, readOnly)
46
+ * @param {Object} options
47
+ * @param {string} options.id - The text box's id
48
+ * @param {(input) => void} options.ref - Receives the text box (the field's control)
49
+ * @param {Object} [options.style] - Extra style for the text box (read-only look)
50
+ */
51
+ static spec(field, { id, ref, style = {} }) {
52
+ let text, picker;
53
+ const disabled = () => !!field.readOnly || !!text?.disabled;
54
+ const notify = (node) => {
55
+ for (const type of ['input', 'change']) {
56
+ const EventClass = node.ownerDocument?.defaultView?.Event ?? globalThis.Event;
57
+ if (EventClass && node.dispatchEvent) node.dispatchEvent(new EventClass(type, { bubbles: true }));
58
+ }
59
+ };
60
+ const show = (value) => {
61
+ if (picker && ColorField.isHex(value)) picker.value = value.toLowerCase();
62
+ if (picker) picker.title = value === ColorField.NONE ? 'No colour' : 'Pick a colour';
63
+ };
64
+ const choose = (value) => {
65
+ if (disabled()) return;
66
+ text.value = value;
67
+ show(value);
68
+ notify(text);
69
+ };
70
+ const value = field.value == null ? '' : String(field.value);
71
+ return {
72
+ style: { display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'wrap' },
73
+ children: [
74
+ {
75
+ tag: 'input',
76
+ attrs: { id, type: 'text', value, placeholder: '#rrggbb', readonly: !!field.readOnly, 'aria-label': field.label ?? 'Colour' },
77
+ style: { width: '74px', fontFamily: 'monospace', ...style },
78
+ on: { input: (e) => show(e.target.value.trim()) },
79
+ ref: (n) => { text = n; ref(n); },
80
+ },
81
+ {
82
+ tag: 'input',
83
+ attrs: { type: 'color', value: ColorField.isHex(value) ? value.toLowerCase() : '#cccccc', disabled: !!field.readOnly, 'aria-label': 'Pick a colour' },
84
+ style: { width: '32px', height: '22px', padding: '0', border: '1px solid #bbb' },
85
+ on: { input: (e) => choose(e.target.value) },
86
+ ref: (n) => { picker = n; },
87
+ },
88
+ {
89
+ style: { display: 'flex', gap: '3px', flexWrap: 'wrap' },
90
+ attrs: { role: 'group', 'aria-label': 'Preset colours' },
91
+ children: ColorField.presetsFor(field).map(preset => ({
92
+ tag: 'button',
93
+ attrs: { type: 'button', title: preset.name, 'aria-label': preset.name, 'data-color': preset.value, disabled: !!field.readOnly },
94
+ style: {
95
+ width: '16px', height: '16px', padding: '0', border: '1px solid #999', borderRadius: '2px', cursor: 'pointer',
96
+ // No colour: white, struck through in red.
97
+ background: preset.value === ColorField.NONE
98
+ ? 'linear-gradient(to top right, #fff 45%, #d00 45%, #d00 55%, #fff 55%)'
99
+ : preset.value,
100
+ },
101
+ on: { click: () => choose(preset.value) },
102
+ })),
103
+ },
104
+ ],
105
+ };
106
+ }
107
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * ColorPalette — reusable palette rotation and color utilities for charts.
3
+ *
4
+ * Pure color math lives on static methods so it can be used without
5
+ * instantiating anything. Instance methods delegate to those static helpers
6
+ * and add the palette-index convenience used by most chart methods.
7
+ */
8
+ export class ColorPalette {
9
+ /** The default palette used by line/area/pipe and multiline legends. */
10
+ static DEFAULT = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452'];
11
+
12
+ constructor(colors = ColorPalette.DEFAULT) {
13
+ this.colors = colors;
14
+ }
15
+
16
+ /** Return the palette color at `index`, wrapping around. */
17
+ colorAt(index) {
18
+ return this.colors[index % this.colors.length];
19
+ }
20
+
21
+ /**
22
+ * Lighten or darken a hex color by `amount` in [-1, 1].
23
+ * Positive values lighten; negative values darken.
24
+ */
25
+ static lighten(color, amount) {
26
+ const hex = color.replace('#', '');
27
+ const num = parseInt(hex, 16);
28
+ const r = Math.max(0, Math.min(255, (num >> 16) + Math.round(255 * amount)));
29
+ const g = Math.max(0, Math.min(255, (num >> 8 & 0x00FF) + Math.round(255 * amount)));
30
+ const b = Math.max(0, Math.min(255, (num & 0x0000FF) + Math.round(255 * amount)));
31
+ return `#${(0x1000000 + r * 0x10000 + g * 0x100 + b).toString(16).slice(1)}`;
32
+ }
33
+
34
+ lighten(color, amount) {
35
+ return ColorPalette.lighten(color, amount);
36
+ }
37
+
38
+ /** Parse "#rrggbb" into {r, g, b}. */
39
+ static hexToRgb(hex) {
40
+ const num = parseInt(hex.replace('#', ''), 16);
41
+ return { r: (num >> 16) & 0xFF, g: (num >> 8) & 0xFF, b: num & 0xFF };
42
+ }
43
+
44
+ hexToRgb(hex) {
45
+ return ColorPalette.hexToRgb(hex);
46
+ }
47
+
48
+ /** Linearly interpolate between two hex colors at t in [0, 1]. */
49
+ static interpolate(c1, c2, t) {
50
+ const a = ColorPalette.hexToRgb(c1);
51
+ const b = ColorPalette.hexToRgb(c2);
52
+ const r = Math.round(a.r + (b.r - a.r) * t);
53
+ const g = Math.round(a.g + (b.g - a.g) * t);
54
+ const bl = Math.round(a.b + (b.b - a.b) * t);
55
+ return `#${((1 << 24) + (r << 16) + (g << 8) + bl).toString(16).slice(1)}`;
56
+ }
57
+
58
+ interpolate(c1, c2, t) {
59
+ return ColorPalette.interpolate(c1, c2, t);
60
+ }
61
+
62
+ /** Maps a value within [vMin, vMax] to a color along an N-stop scale
63
+ * (linear interpolation between adjacent stops). */
64
+ static scaleColor(stops, vMin, vMax, v) {
65
+ if (stops.length === 1) return stops[0];
66
+ const range = (vMax - vMin) || 1;
67
+ const t = Math.min(1, Math.max(0, (v - vMin) / range));
68
+ const segCount = stops.length - 1;
69
+ const segT = t * segCount;
70
+ const segIndex = Math.min(segCount - 1, Math.floor(segT));
71
+ const localT = segT - segIndex;
72
+ return ColorPalette.interpolate(stops[segIndex], stops[segIndex + 1], localT);
73
+ }
74
+
75
+ scaleColor(stops, vMin, vMax, v) {
76
+ return ColorPalette.scaleColor(stops, vMin, vMax, v);
77
+ }
78
+
79
+ /** Perceptual-ish luma check for choosing readable text on a color. */
80
+ static isDark(hex) {
81
+ const { r, g, b } = ColorPalette.hexToRgb(hex);
82
+ return (0.299 * r + 0.587 * g + 0.114 * b) < 140;
83
+ }
84
+
85
+ isDark(hex) {
86
+ return ColorPalette.isDark(hex);
87
+ }
88
+ }
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Command — abstract base class for one reversible edit.
3
+ *
4
+ * Subclasses implement `execute()` and `undo()` to mutate and restore some
5
+ * piece of state. They may also implement `merge(other)` so the history can
6
+ * coalesce a rapid sequence of edits (e.g. a drag) into a single undoable
7
+ * entry.
8
+ */
9
+ export class Command {
10
+ constructor(label = '') {
11
+ if (new.target === Command) {
12
+ throw new TypeError('Command is abstract — subclass it');
13
+ }
14
+ this.label = label;
15
+ }
16
+
17
+ /** Apply the edit. Called once when the command is executed. */
18
+ execute() {
19
+ throw new Error(`${this.constructor.name} must implement execute()`);
20
+ }
21
+
22
+ /** Reverse the edit. Called when the user presses undo. */
23
+ undo() {
24
+ throw new Error(`${this.constructor.name} must implement undo()`);
25
+ }
26
+
27
+ /**
28
+ * Optional: return a merged command if `other` should be coalesced with
29
+ * this one, or undefined/null to keep them separate. Used by
30
+ * CommandHistory for drag/resize coalescing.
31
+ * @param {Command} other
32
+ * @returns {Command|undefined}
33
+ */
34
+ merge(other) {
35
+ return undefined;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * CompositeCommand — groups several commands into one undoable unit.
41
+ */
42
+ export class CompositeCommand extends Command {
43
+ constructor(label = '', commands = []) {
44
+ super(label);
45
+ /** @type {Command[]} */
46
+ this.commands = commands.slice();
47
+ }
48
+
49
+ add(cmd) {
50
+ this.commands.push(cmd);
51
+ return this;
52
+ }
53
+
54
+ execute() {
55
+ for (const cmd of this.commands) cmd.execute();
56
+ }
57
+
58
+ undo() {
59
+ for (let i = this.commands.length - 1; i >= 0; i--) {
60
+ this.commands[i].undo();
61
+ }
62
+ }
63
+ }
64
+
65
+ /**
66
+ * CommandHistory — bounded undo/redo stack for reversible edits.
67
+ *
68
+ * Commands are executed as they are pushed. Undo pops the last executed
69
+ * command and calls its `undo()`; redo replays it with `execute()`.
70
+ */
71
+ export class CommandHistory {
72
+ constructor(options = {}) {
73
+ this._undoStack = [];
74
+ this._redoStack = [];
75
+ this._maxSize = options.maxSize ?? 200;
76
+ this._onChange = options.onChange ?? null;
77
+ this._listeners = [];
78
+ // A token per state: the undo stack's top one (0 at the start), so undoing back to a
79
+ // state gives its token again and a model can tell it is back where it was saved.
80
+ this._tokens = [];
81
+ this._redoTokens = [];
82
+ this._stamp = 0;
83
+ }
84
+
85
+ /** Which state the history is in: the same token whenever it is back in that state. */
86
+ get stateToken() {
87
+ return this._tokens[this._tokens.length - 1] ?? 0;
88
+ }
89
+
90
+ /** Call `fn()` after every execute, undo, redo or clear. Returns an unsubscribe function. */
91
+ onChange(fn) {
92
+ this._listeners.push(fn);
93
+ return () => { this._listeners = this._listeners.filter(l => l !== fn); };
94
+ }
95
+
96
+ get canUndo() { return this._undoStack.length > 0; }
97
+ get canRedo() { return this._redoStack.length > 0; }
98
+ get undoLabel() { return this._undoStack[this._undoStack.length - 1]?.label ?? ''; }
99
+ get redoLabel() { return this._redoStack[this._redoStack.length - 1]?.label ?? ''; }
100
+
101
+ /**
102
+ * Execute a command and push it onto the undo stack. Clears redo.
103
+ * Checked by shape (execute + undo), not instanceof: a page can load two
104
+ * copies of this library (the engine and workspace bundles each carry one),
105
+ * and a Command from either copy must work in either history.
106
+ */
107
+ execute(cmd) {
108
+ if (typeof cmd?.execute !== 'function' || typeof cmd.undo !== 'function') {
109
+ throw new TypeError('CommandHistory.execute expects a command with execute() and undo()');
110
+ }
111
+
112
+ // Try to merge with the most recent command of the same constructor.
113
+ const last = this._undoStack[this._undoStack.length - 1];
114
+ if (last && last.constructor === cmd.constructor && typeof last.merge === 'function') {
115
+ const merged = last.merge(cmd);
116
+ if (merged) {
117
+ merged.execute();
118
+ this._undoStack[this._undoStack.length - 1] = merged;
119
+ this._tokens[this._tokens.length - 1] = ++this._stamp;
120
+ this._notifyChange();
121
+ return merged;
122
+ }
123
+ }
124
+
125
+ cmd.execute();
126
+ this._undoStack.push(cmd);
127
+ this._tokens.push(++this._stamp);
128
+ this._redoStack = [];
129
+ this._redoTokens = [];
130
+ if (this._undoStack.length > this._maxSize) {
131
+ this._undoStack.shift();
132
+ this._tokens.shift();
133
+ }
134
+ this._notifyChange();
135
+ return cmd;
136
+ }
137
+
138
+ undo() {
139
+ if (!this.canUndo) return null;
140
+ const cmd = this._undoStack.pop();
141
+ console.log(`[CommandHistory] UNDO: ${cmd.label}`);
142
+ cmd.undo();
143
+ this._redoStack.push(cmd);
144
+ this._redoTokens.push(this._tokens.pop());
145
+ this._notifyChange();
146
+ return cmd;
147
+ }
148
+
149
+ redo() {
150
+ if (!this.canRedo) return null;
151
+ const cmd = this._redoStack.pop();
152
+ console.log(`[CommandHistory] REDO: ${cmd.label}`);
153
+ cmd.execute();
154
+ this._undoStack.push(cmd);
155
+ this._tokens.push(this._redoTokens.pop());
156
+ this._notifyChange();
157
+ return cmd;
158
+ }
159
+
160
+ clear() {
161
+ this._undoStack = [];
162
+ this._redoStack = [];
163
+ this._tokens = [];
164
+ this._redoTokens = [];
165
+ this._notifyChange();
166
+ }
167
+
168
+ _notifyChange() {
169
+ if (this._onChange) {
170
+ try { this._onChange(this.canUndo, this.canRedo); } catch (err) { console.error(err); }
171
+ }
172
+ for (const fn of this._listeners) {
173
+ try { fn(this); } catch (err) { console.error(err); }
174
+ }
175
+ }
176
+ }