@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,125 @@
1
+ import { ViewSetChecker } from '../diagramModel/ViewSetChecker.js';
2
+ import { ArchimateValidator } from './ArchimateValidator.js';
3
+ import { viewNestings, nestingRelationships } from './nesting.js';
4
+ import { duplicateGroups, UNPRINTABLE } from './duplicates.js';
5
+
6
+ /**
7
+ * ArchimateModelChecker — the checks Archi's validator makes over a model,
8
+ * on top of the view-set ones (empty views): relationships the specification
9
+ * does not allow, elements that look like the same thing twice, and elements
10
+ * and relationships no view shows (a relationship a nesting stands for counts
11
+ * as shown), and elements nested in another with no relationship for it.
12
+ * Findings name elements, relationships or views (`kind`).
13
+ */
14
+ export class ArchimateModelChecker extends ViewSetChecker {
15
+ /**
16
+ * @param {ArchimateModel} model
17
+ * @param {Object} [options]
18
+ * @param {string} [options.version] - ArchiMate version for the relationship check ('3.2' | '4')
19
+ */
20
+ constructor(model, { version = '4' } = {}) {
21
+ super(model);
22
+ this.version = version;
23
+ }
24
+
25
+ checks() {
26
+ return [this.invalidRelationships, this.possibleDuplicates, this.unusedElements, this.unusedRelationships, this.nestedWithoutRelationship, this.unprintableText, ...super.checks()];
27
+ }
28
+
29
+ /** Elements drawn on no view. */
30
+ unusedElements() {
31
+ const drawn = new Set(this.model.views().flatMap(v => [...v.elementInstances.values()].map(i => i.elementId)));
32
+ return this.model.elements()
33
+ .filter(e => !drawn.has(e.id))
34
+ .map(e => ({ code: 'unused-element', severity: 'info', kind: 'element', ids: [e.id], message: `"${this._name(e)}" is in no view` }));
35
+ }
36
+
37
+ /** Relationships drawn on no view, nor shown by a nesting (an element drawn inside another). */
38
+ unusedRelationships() {
39
+ const drawn = new Set(this.model.views().flatMap(v => [...v.relationshipInstances.values()].map(i => i.relationshipId)));
40
+ for (const n of this.model.views().flatMap(v => viewNestings(v))) {
41
+ for (const r of nestingRelationships(this.model, n.parentElementId, n.childElementId)) drawn.add(r.id);
42
+ }
43
+ return this.model.relationships()
44
+ .filter(r => !drawn.has(r.id))
45
+ .map(r => ({ code: 'unused-relationship', severity: 'info', kind: 'relationship', ids: [r.id], message: `${this._relationshipText(r)} is in no view` }));
46
+ }
47
+
48
+ /**
49
+ * Elements drawn inside another on a view with no relationship from the
50
+ * parent to it that a nesting stands for (NESTING_KINDS): the drawing says
51
+ * more than the model does. One finding per view and pair.
52
+ */
53
+ nestedWithoutRelationship() {
54
+ const seen = new Set();
55
+ return this.model.views().flatMap(v => viewNestings(v))
56
+ .filter(n => !nestingRelationships(this.model, n.parentElementId, n.childElementId).length)
57
+ .filter(n => { const key = `${n.view.id}\u0000${n.parentElementId}\u0000${n.childElementId}`; return !seen.has(key) && seen.add(key); })
58
+ .map(n => {
59
+ const [parent, child] = [n.parentElementId, n.childElementId].map(id => this.model.getElement(id));
60
+ return {
61
+ code: 'nested-without-relationship', severity: 'warning', kind: 'element', ids: [n.childElementId], viewId: n.view.id,
62
+ message: `"${this._name(child)}" is drawn inside "${this._name(parent)}" on "${n.view.name || n.view.id}" with no relationship between them`,
63
+ };
64
+ });
65
+ }
66
+
67
+ /**
68
+ * Elements of the same type whose names have the same words (ignoring
69
+ * case, punctuation, word order and filler words: duplicates.js): likely
70
+ * one thing twice. The finding names them all, so they can be merged.
71
+ */
72
+ possibleDuplicates() {
73
+ return duplicateGroups(this.model.elements()).map(g => {
74
+ // Names that differ only in case and spacing are one name to the reader.
75
+ const byLook = new Map();
76
+ for (const e of g) {
77
+ const look = this._name(e).trim().replace(/\s+/g, ' ').toLowerCase();
78
+ if (!byLook.has(look)) byLook.set(look, this._name(e).trim());
79
+ }
80
+ const names = [...byLook.values()];
81
+ return {
82
+ code: 'possible-duplicate', severity: 'warning', kind: 'element', ids: g.map(e => e.id),
83
+ message: names.length === 1
84
+ ? `${g.length} ${g[0].type} elements are named "${names[0]}"`
85
+ : `${g.length} ${g[0].type} elements look the same: ${names.map(n => `"${n}"`).join(', ')}`,
86
+ };
87
+ });
88
+ }
89
+
90
+ /** Names and documentation of elements and relationships with characters that should not be there (control characters, zero-width spaces). */
91
+ unprintableText() {
92
+ const found = [];
93
+ const look = (kind, item) => {
94
+ const fields = [['name', UNPRINTABLE.name], ['documentation', UNPRINTABLE.documentation]].filter(([f, re]) => re.test(String(item[f] ?? '')));
95
+ if (fields.length) {
96
+ found.push({
97
+ code: 'unprintable-text', severity: 'warning', kind, ids: [item.id],
98
+ message: `${kind === 'element' ? `"${this._name(item).replace(UNPRINTABLE.name, '?')}"` : this._relationshipText(item)} has unprintable characters in its ${fields.map(([f]) => f).join(' and ')}`,
99
+ });
100
+ }
101
+ };
102
+ this.model.elements().forEach(e => look('element', e));
103
+ this.model.relationships().forEach(r => look('relationship', r));
104
+ return found;
105
+ }
106
+
107
+ /** Relationships the ArchiMate specification does not allow between their ends. */
108
+ invalidRelationships() {
109
+ const warnings = ArchimateValidator.validateModel(this.model.elements(), this.model.relationships(), this.version);
110
+ return warnings
111
+ .filter(w => w.type === 'relationship' && w.relationship)
112
+ .map(w => ({ code: w.code ?? 'invalid-relationship', severity: 'warning', kind: 'relationship', ids: [w.relationship.id], message: `${this._relationshipText(w.relationship)}: ${w.message}` }));
113
+ }
114
+
115
+ /** @private */
116
+ _name(element) {
117
+ return element?.name || element?.id || '?';
118
+ }
119
+
120
+ /** @private */
121
+ _relationshipText(r) {
122
+ const end = (id) => { const e = this.model.getElement(id); return e ? this._name(e) : id; };
123
+ return `${r.kind || 'association'} from "${end(r.source)}" to "${end(r.target)}"`;
124
+ }
125
+ }
@@ -0,0 +1,128 @@
1
+ import { ModelReport } from '../diagramModel/ModelReport.js';
2
+ import { ArchimateDiagram } from './ArchimateDiagram.js';
3
+ import { TREE_LAYERS, treeLayerOf } from '../modelTree/treeLayers.js';
4
+ import { typeTitle } from '../archimate/archimateNames.js';
5
+
6
+ /**
7
+ * ArchimateModelReport — the report of an ArchiMate model (as Archi's HTML
8
+ * report): on top of the views, a page per element (its type and layer
9
+ * colour, documentation, properties, its relationships with the element at
10
+ * the other end, the views it is on) and per relationship (its source and
11
+ * target, the views it is on); a view's page lists its elements and
12
+ * relationships. The tree has Elements by layer, as the model tree has them,
13
+ * and Relationships by kind.
14
+ */
15
+ export class ArchimateModelReport extends ModelReport {
16
+ modelFacts() {
17
+ return [
18
+ { label: 'Elements', text: String(this.model.elements().length) },
19
+ { label: 'Relationships', text: String(this.model.relationships().length) },
20
+ ...super.modelFacts(),
21
+ ];
22
+ }
23
+
24
+ viewType(view) {
25
+ return view.constructor.kind === 'canvas' ? 'Canvas' : 'View';
26
+ }
27
+
28
+ viewFacts(view) {
29
+ return view.viewpoint ? [{ label: 'Viewpoint', text: typeTitle(String(view.viewpoint)) }] : [];
30
+ }
31
+
32
+ /** A view's elements and relationships, each once, in the order they were placed. */
33
+ viewLists(view) {
34
+ const once = (ids) => [...new Set(ids)];
35
+ const elementIds = once([...(view.elementInstances?.values() ?? [])].map(i => i.elementId))
36
+ .filter(id => id && this.model.getElement(id));
37
+ const relationshipIds = once([...(view.relationshipInstances?.values() ?? [])].map(i => i.relationshipId))
38
+ .filter(id => id && this.model.getRelationship(id));
39
+ return [
40
+ { title: 'Elements', rows: elementIds.map(id => ({ key: this.key('element', id), note: typeTitle(this.model.getElement(id).type ?? '') })) },
41
+ // A named relationship's row says which elements it joins; an unnamed one's name already does.
42
+ { title: 'Relationships', rows: relationshipIds.map(id => { const rel = this.model.getRelationship(id); return { key: this.key('relationship', id), ...(rel.name && { note: this.ends(rel) }) }; }) },
43
+ ];
44
+ }
45
+
46
+ conceptItems() {
47
+ return [...this.model.elements().map(e => this.elementItem(e)), ...this.model.relationships().map(r => this.relationshipItem(r))];
48
+ }
49
+
50
+ /** An element's page. */
51
+ elementItem(element) {
52
+ const { incoming, outgoing } = this.model.relationshipsFor(element.id);
53
+ // An unnamed relationship's name already says which elements it joins; a named one's row says the other end.
54
+ const row = (rel, other, arrow) => ({ key: this.key('relationship', rel.id), ...(rel.name && { note: `${arrow} ${this.nameOf(other)}` }) });
55
+ return this.item('element', element.id, {
56
+ name: element.name,
57
+ type: typeTitle(element.type ?? 'element'),
58
+ color: this.colorOf(element),
59
+ documentation: element.documentation,
60
+ properties: element.properties,
61
+ facts: [{ label: 'Layer', text: typeTitle(treeLayerOf(element)) }],
62
+ lists: [
63
+ { title: 'Relationships', rows: [...outgoing.map(r => row(r, r.target, '→')), ...incoming.map(r => row(r, r.source, '←'))] },
64
+ { title: 'Views', rows: this.model.views().filter(v => v.elementInstancesFor?.(element.id).length).map(v => ({ key: this.key('view', v.id) })) },
65
+ ],
66
+ });
67
+ }
68
+
69
+ /** A relationship's page. */
70
+ relationshipItem(rel) {
71
+ const end = (label, id) => (this.model.getElement(id) ? { label, key: this.key('element', id) } : { label, text: String(id ?? '') });
72
+ return this.item('relationship', rel.id, {
73
+ name: this.relationshipName(rel),
74
+ type: `${typeTitle(this.kindOf(rel))} relationship`,
75
+ documentation: rel.documentation,
76
+ properties: rel.properties,
77
+ facts: [end('Source', rel.source), end('Target', rel.target)],
78
+ lists: [{ title: 'Views', rows: this.model.views().filter(v => v.relationshipInstancesFor?.(rel.id).length).map(v => ({ key: this.key('view', v.id) })) }],
79
+ });
80
+ }
81
+
82
+ /** A relationship's name, or (most have none) its kind and ends. */
83
+ relationshipName(rel) {
84
+ return rel.name || `${typeTitle(this.kindOf(rel))}: ${this.ends(rel)}`;
85
+ }
86
+
87
+ /** Elements by layer (in the model tree's order), then relationships by kind. */
88
+ conceptSections() {
89
+ const elements = this.model.elements();
90
+ const relationships = this.model.relationships();
91
+ const byLayer = TREE_LAYERS.map(layer => ({
92
+ title: typeTitle(layer),
93
+ keys: this.sorted(elements.filter(e => treeLayerOf(e) === layer)).map(e => this.key('element', e.id)),
94
+ }));
95
+ const kinds = [...new Set(relationships.map(r => this.kindOf(r)))].sort();
96
+ const byKind = kinds.map(kind => ({
97
+ title: typeTitle(kind),
98
+ keys: this.sorted(relationships.filter(r => this.kindOf(r) === kind), r => this.relationshipName(r))
99
+ .map(r => this.key('relationship', r.id)),
100
+ }));
101
+ return [{ title: 'Elements', groups: byLayer }, { title: 'Relationships', groups: byKind }];
102
+ }
103
+
104
+ /** A relationship's kind ('serving', ...): `kind`, or `type` as some sources write it. */
105
+ kindOf(rel) {
106
+ return rel.kind ?? rel.type ?? 'relationship';
107
+ }
108
+
109
+ /** "Source → Target" by name. */
110
+ ends(rel) {
111
+ return `${this.nameOf(rel.source)} → ${this.nameOf(rel.target)}`;
112
+ }
113
+
114
+ /** @private */
115
+ nameOf(elementId) {
116
+ return this.model.getElement(elementId)?.name || elementId || '?';
117
+ }
118
+
119
+ /** @private */
120
+ colorOf(element) {
121
+ return element.fillColor || ArchimateDiagram.layerColor(ArchimateDiagram.elementLayer(element));
122
+ }
123
+
124
+ /** @private */
125
+ sorted(items, name = (i) => i.name ?? '') {
126
+ return [...items].sort((a, b) => String(name(a)).localeCompare(String(name(b))));
127
+ }
128
+ }
@@ -0,0 +1,41 @@
1
+ import { ModelSearch } from '../diagramModel/ModelSearch.js';
2
+ import { ViewObjectInstance } from './ViewObjectInstance.js';
3
+
4
+ /**
5
+ * ArchimateModelSearch — find and replace in an ArchiMate model (as Archi's
6
+ * Find/Replace): on top of the model and views (ModelSearch), every element's
7
+ * and relationship's name, documentation and properties, and the text of the
8
+ * notes on each view.
9
+ */
10
+ export class ArchimateModelSearch extends ModelSearch {
11
+ conceptTargets() {
12
+ const concept = (kind, c) => {
13
+ const owner = { kind, id: c.id, owner: c.name || c.id };
14
+ return [this.text(owner, 'name', c), this.text(owner, 'documentation', c), ...this.propertyTargets(owner, c.properties)];
15
+ };
16
+ return [
17
+ ...this.model.elements().flatMap(e => concept('element', e)),
18
+ ...this.model.relationships().flatMap(r => concept('relationship', r)),
19
+ ];
20
+ }
21
+
22
+ /** Elements and relationships hold properties too. */
23
+ propertyHolders() {
24
+ return [
25
+ ...super.propertyHolders(),
26
+ ...this.model.elements().map(e => ({ owner: `element ${e.id}`, object: e })),
27
+ ...this.model.relationships().map(r => ({ owner: `relationship ${r.id}`, object: r })),
28
+ ];
29
+ }
30
+
31
+ /** A note's text (its `label`, and the `name` it is listed by), which belongs to its view. */
32
+ viewItemTargets(view) {
33
+ return [...(view.elementInstances?.values() ?? [])]
34
+ .filter(inst => inst instanceof ViewObjectInstance && inst.content.shape === 'note')
35
+ .map(inst => ({
36
+ kind: 'note', id: inst.id, viewId: view.id, owner: 'Note', field: 'name', fieldLabel: 'Text',
37
+ read: () => inst.content.label ?? '',
38
+ write: (text) => { inst.content.label = text; inst.content.name = text; },
39
+ }));
40
+ }
41
+ }
@@ -0,0 +1,357 @@
1
+ import { ArchimateNotation, ArchimateViewpoints, archimate32Type } from '../../archimate.js';
2
+ import { ITIconNotation } from '../../itIcons.js';
3
+ import { RELATIONSHIP_LETTERS, RELATIONSHIP_TABLE_CONCEPTS, RELATIONSHIP_TABLE_ROWS, RELATIONSHIP_TABLE_VERSION } from '../../archimateRelationshipTable.js';
4
+
5
+ /** source type -> target type -> Set of allowed kinds, from the specification's table (built on first use). */
6
+ let SPEC_TABLE = null;
7
+ function specTable() {
8
+ if (SPEC_TABLE) return SPEC_TABLE;
9
+ SPEC_TABLE = new Map();
10
+ for (const [source, row] of Object.entries(RELATIONSHIP_TABLE_ROWS)) {
11
+ const targets = new Map();
12
+ row.split(',').forEach((letters, i) => {
13
+ targets.set(RELATIONSHIP_TABLE_CONCEPTS[i], new Set([...letters].map(c => RELATIONSHIP_LETTERS[c]).filter(Boolean)));
14
+ });
15
+ SPEC_TABLE.set(source, targets);
16
+ }
17
+ return SPEC_TABLE;
18
+ }
19
+
20
+ /**
21
+ * ArchimateValidator — DOM-free ArchiMate standard-alignment checks.
22
+ *
23
+ * The validator is advisory: it returns warnings, it never blocks rendering.
24
+ * Rules are encoded as data so they can be tuned as the standard interpretation
25
+ * evolves. Custom/unofficial element types are allowed through without warnings
26
+ * unless the relationship kind is clearly nonsensical for the resolved aspects.
27
+ *
28
+ * Coverage:
29
+ * - Relationship validity by source/target aspect and layer.
30
+ * - v4 Common Domain elements (process/function/service/interaction/event)
31
+ * must carry an explicit `layer` field (their type no longer implies one).
32
+ * - v3.2 types used under v4 are flagged as migrated/retired.
33
+ */
34
+ export class ArchimateValidator {
35
+ /** The 11 official relationship kinds (plus the directed-association alias). */
36
+ static RELATIONSHIP_KINDS = [
37
+ 'composition', 'aggregation', 'assignment', 'realization',
38
+ 'specialization', 'access', 'serving', 'influence', 'triggering', 'flow',
39
+ 'association', 'association-directed',
40
+ ];
41
+
42
+ /**
43
+ * Allow-rule matrix, for element types the specification's table does not
44
+ * cover (custom and IT types; see specificationKinds). Each rule describes
45
+ * when a given set of relationship kinds is valid between a source and target. The first matching rule wins;
46
+ * if no rule matches, the relationship is flagged as a warning.
47
+ * Association is the final, permissive fallback. A rule may also name the
48
+ * element types it applies to (`fromTypes`, `toTypes`) when the standard
49
+ * allows a pairing for those types only.
50
+ */
51
+ static RULES = [
52
+ // Structural: whole-part, same-aspect, same-layer preferred.
53
+ {
54
+ kinds: ['composition', 'aggregation'],
55
+ sameAspect: true,
56
+ sameLayer: true,
57
+ message: 'Composition and aggregation are normally used between elements of the same aspect and layer',
58
+ },
59
+ // Assignment between named active-structure types: "a business actor may
60
+ // be assigned to one or more business roles" (ArchiMate 3.2, 8.2.1; also 4).
61
+ {
62
+ kinds: ['assignment'],
63
+ fromTypes: ['business-actor'],
64
+ toTypes: ['business-role'],
65
+ message: 'A business actor is assigned to the business roles it fulfils',
66
+ },
67
+ // Assignment: active structure performs/responsible for behavior or passive structure.
68
+ {
69
+ kinds: ['assignment'],
70
+ fromAspect: 'active-structure',
71
+ toAspects: ['behavior', 'passive-structure'],
72
+ message: 'Assignment usually goes from an active-structure element to a behavior or passive-structure element',
73
+ },
74
+ // Realization: behavior (or active structure) realizes a passive structure.
75
+ {
76
+ kinds: ['realization'],
77
+ fromAspects: ['behavior', 'active-structure'],
78
+ toAspect: 'passive-structure',
79
+ message: 'Realization usually goes from a behavior or active-structure element to a passive-structure element',
80
+ },
81
+ // Specialization: same aspect/layer.
82
+ {
83
+ kinds: ['specialization'],
84
+ sameAspect: true,
85
+ sameLayer: true,
86
+ message: 'Specialization is normally between elements of the same aspect and layer',
87
+ },
88
+ // Access: behavior reads/writes passive structure.
89
+ {
90
+ kinds: ['access'],
91
+ fromAspect: 'behavior',
92
+ toAspect: 'passive-structure',
93
+ message: 'Access usually goes from a behavior element to a passive-structure element',
94
+ },
95
+ // Serving: behavior serves behavior, may cross layers.
96
+ {
97
+ kinds: ['serving'],
98
+ fromAspect: 'behavior',
99
+ toAspect: 'behavior',
100
+ crossLayer: true,
101
+ message: 'Serving usually goes from one behavior element to another',
102
+ },
103
+ // Triggering: behavior triggers behavior.
104
+ {
105
+ kinds: ['triggering'],
106
+ fromAspects: ['behavior', 'motivation'],
107
+ toAspects: ['behavior', 'motivation'],
108
+ message: 'Triggering usually goes from one behavior or event element to another',
109
+ },
110
+ // Flow: behavior to behavior or passive structure to passive structure.
111
+ {
112
+ kinds: ['flow'],
113
+ sameAspect: true,
114
+ aspects: ['behavior', 'passive-structure'],
115
+ message: 'Flow is normally between behavior elements, or between passive-structure elements',
116
+ },
117
+ // Influence: very broad, but motivation elements are the natural source.
118
+ {
119
+ kinds: ['influence'],
120
+ message: 'Influence is broadly allowed; ensure the direction matches your intent',
121
+ severity: 'info',
122
+ },
123
+ // Association: permissive fallback.
124
+ {
125
+ kinds: ['association', 'association-directed'],
126
+ message: 'Association is the permissive fallback relationship',
127
+ severity: 'info',
128
+ },
129
+ ];
130
+
131
+ /**
132
+ * Validate a single relationship.
133
+ * @param {object} sourceElement
134
+ * @param {object} targetElement
135
+ * @param {string} kind
136
+ * @param {'3.2'|'4'} [version='4']
137
+ * @returns {{valid: boolean, code?: string, message?: string, severity?: string, suggestedKinds?: string[]}}
138
+ */
139
+ static validateRelationship(sourceElement, targetElement, kind, version = '4') {
140
+ const source = this._resolve(sourceElement, version);
141
+ const target = this._resolve(targetElement, version);
142
+ const normalizedKind = kind || 'association';
143
+
144
+ // Unknown kind is itself a warning (fall back to association notation).
145
+ if (!this.RELATIONSHIP_KINDS.includes(normalizedKind)) {
146
+ return {
147
+ valid: false,
148
+ code: 'unknown-kind',
149
+ message: `Unknown relationship kind "${normalizedKind}"; falling back to association`,
150
+ severity: 'warning',
151
+ suggestedKinds: ['association'],
152
+ };
153
+ }
154
+
155
+ // Custom/unofficial types on both ends are allowed any relationship so
156
+ // validation stays helpful without punishing informal extensions.
157
+ if (source.isCustom && target.isCustom) {
158
+ return { valid: true };
159
+ }
160
+
161
+ // Two ArchiMate types: the specification's own table decides.
162
+ const allowed = this.specificationKinds(sourceElement, targetElement);
163
+ if (allowed) {
164
+ if (allowed.has(normalizedKind)) return { valid: true };
165
+ const suggested = this.RELATIONSHIP_KINDS.filter(k => allowed.has(k));
166
+ return {
167
+ valid: false,
168
+ code: 'not-in-specification',
169
+ message: `ArchiMate ${RELATIONSHIP_TABLE_VERSION} does not allow ${normalizedKind} from ${archimate32Type(sourceElement)} to ${archimate32Type(targetElement)}`,
170
+ severity: 'warning',
171
+ suggestedKinds: suggested.length ? suggested : ['association'],
172
+ };
173
+ }
174
+
175
+ const rule = this._matchingRule(normalizedKind, source, target);
176
+ if (rule) {
177
+ return { valid: true };
178
+ }
179
+
180
+ const suggested = this.allowedKinds(sourceElement, targetElement, version)
181
+ .filter(k => k !== normalizedKind);
182
+ return {
183
+ valid: false,
184
+ code: 'aspect-or-layer-mismatch',
185
+ message: `Relationship "${normalizedKind}" is unusual between a ${source.aspect} element and a ${target.aspect} element`,
186
+ severity: 'warning',
187
+ suggestedKinds: suggested.length ? suggested : ['association'],
188
+ };
189
+ }
190
+
191
+ /**
192
+ * Validate an entire model.
193
+ * @param {Array<object>} elements
194
+ * @param {Array<object>} relationships
195
+ * @param {'3.2'|'4'} [version='4']
196
+ * @returns {Array<object>} warnings, each with {type, code, message, severity, element?, relationship?, source?, target?}
197
+ */
198
+ static validateModel(elements, relationships, version = '4', viewpoint = null, customViewpoints = []) {
199
+ const warnings = [];
200
+ const byId = new Map((elements || []).map(e => [e.id, e]));
201
+
202
+ for (const element of elements || []) {
203
+ // Diagram annotations are not ArchiMate model elements; skip them.
204
+ if (element?.shape === 'note' || element?.annotation === true) continue;
205
+ const elementWarnings = this._validateElement(element, version);
206
+ for (const w of elementWarnings) {
207
+ warnings.push({ ...w, type: 'element', element });
208
+ }
209
+ if (viewpoint && viewpoint !== 'All') {
210
+ const vpWarning = ArchimateViewpoints.validateElement(element, viewpoint, version, customViewpoints);
211
+ if (vpWarning) {
212
+ warnings.push({ type: 'element', code: 'viewpoint-mismatch', severity: 'warning', message: vpWarning, element });
213
+ }
214
+ }
215
+ }
216
+
217
+ for (const relationship of relationships || []) {
218
+ const source = byId.get(relationship.source);
219
+ const target = byId.get(relationship.target);
220
+ if (!source) {
221
+ warnings.push({ type: 'relationship', code: 'missing-source', relationship, severity: 'warning', message: `Relationship references missing source "${relationship.source}"` });
222
+ continue;
223
+ }
224
+ if (!target) {
225
+ warnings.push({ type: 'relationship', code: 'missing-target', relationship, severity: 'warning', message: `Relationship references missing target "${relationship.target}"` });
226
+ continue;
227
+ }
228
+ const result = this.validateRelationship(source, target, relationship.kind, version);
229
+ if (!result.valid) {
230
+ warnings.push({
231
+ type: 'relationship',
232
+ code: result.code,
233
+ severity: result.severity,
234
+ message: result.message,
235
+ suggestedKinds: result.suggestedKinds,
236
+ relationship,
237
+ source,
238
+ target,
239
+ });
240
+ }
241
+ }
242
+
243
+ return warnings;
244
+ }
245
+
246
+ /**
247
+ * Return the relationship kinds permitted between two elements.
248
+ * @param {object} sourceElement
249
+ * @param {object} targetElement
250
+ * @param {'3.2'|'4'} [version='4']
251
+ * @returns {string[]}
252
+ */
253
+ static allowedKinds(sourceElement, targetElement, version = '4') {
254
+ const source = this._resolve(sourceElement, version);
255
+ const target = this._resolve(targetElement, version);
256
+ if (source.isCustom && target.isCustom) {
257
+ return [...this.RELATIONSHIP_KINDS];
258
+ }
259
+ const allowed = this.specificationKinds(sourceElement, targetElement);
260
+ if (allowed) return this.RELATIONSHIP_KINDS.filter(kind => allowed.has(kind));
261
+ return this.RELATIONSHIP_KINDS.filter(kind => this._matchingRule(kind, source, target));
262
+ }
263
+
264
+ /**
265
+ * The relationship kinds the ArchiMate specification's relationship table
266
+ * (Appendix B) allows from one element to another, or null when either is
267
+ * not an ArchiMate type (a custom or IT type: RULES apply instead). An
268
+ * ArchiMate 4 type is looked up as its 3.2 type (archimate32Type). A
269
+ * directed association is an association.
270
+ * @param {object} sourceElement
271
+ * @param {object} targetElement
272
+ * @returns {Set<string>|null}
273
+ */
274
+ static specificationKinds(sourceElement, targetElement) {
275
+ const row = specTable().get(archimate32Type(sourceElement ?? {}));
276
+ const kinds = row?.get(archimate32Type(targetElement ?? {}));
277
+ if (!kinds) return null;
278
+ return kinds.has('association') ? new Set([...kinds, 'association-directed']) : kinds;
279
+ }
280
+
281
+ static _resolve(element, version) {
282
+ const typeName = element?.type;
283
+ // A 3.2 type retired in 4 keeps its 3.2 layer and aspect, so its relationships
284
+ // are still checked; _validateElement flags the retirement itself.
285
+ const type = typeof typeName === 'string'
286
+ ? (ArchimateNotation.elementType(typeName, version)
287
+ || ArchimateNotation.elementType(typeName, '3.2')
288
+ || ITIconNotation.elementType(typeName))
289
+ : undefined;
290
+ const layerName = element?.layer
291
+ ? element.layer
292
+ : (type?.layer?.name || ArchimateNotation.elementLayer(element, version));
293
+ const aspect = type?.aspect || element?.aspect || 'other';
294
+ return {
295
+ type: typeName,
296
+ resolvedType: type,
297
+ layer: layerName,
298
+ aspect,
299
+ isCustom: !type,
300
+ isCommonDomain: type && type.layer === null && !element?.layer,
301
+ };
302
+ }
303
+
304
+ static _validateElement(element, version) {
305
+ const warnings = [];
306
+ const type = typeof element?.type === 'string' ? ArchimateNotation.elementType(element.type, version) : undefined;
307
+
308
+ if (!type && element?.type && !ArchimateNotation.elementType(element.type, '3.2')) {
309
+ // Custom types are allowed; no warning. (A 3.2 type under 4 is retired, not custom.)
310
+ return warnings;
311
+ }
312
+
313
+ if (version === '4' && type?.layer === null && !element?.layer) {
314
+ warnings.push({
315
+ code: 'common-domain-missing-layer',
316
+ severity: 'warning',
317
+ message: `Element "${element.name || element.id}" is a Common Domain type (${element.type}) and needs an explicit layer in ArchiMate 4`,
318
+ });
319
+ }
320
+
321
+ if (version === '4' && ArchimateNotation.elementType(element?.type, '3.2') && !ArchimateNotation.elementType(element?.type, '4')) {
322
+ warnings.push({
323
+ code: 'retired-type-in-v4',
324
+ severity: 'warning',
325
+ message: `Element type "${element.type}" is retired in ArchiMate 4; use migrateElementToV4() or switch to archimateVersion:"3.2"`,
326
+ });
327
+ }
328
+
329
+ return warnings;
330
+ }
331
+
332
+ static _matchingRule(kind, source, target) {
333
+ for (const rule of this.RULES) {
334
+ if (!rule.kinds.includes(kind)) continue;
335
+
336
+ const sourceAspects = rule.fromAspects || (rule.fromAspect ? [rule.fromAspect] : undefined);
337
+ const targetAspects = rule.toAspects || (rule.toAspect ? [rule.toAspect] : undefined);
338
+ const allAspects = rule.aspects;
339
+
340
+ if (rule.fromTypes && !rule.fromTypes.includes(source.type)) continue;
341
+ if (rule.toTypes && !rule.toTypes.includes(target.type)) continue;
342
+ if (sourceAspects && !sourceAspects.includes(source.aspect)) continue;
343
+ if (targetAspects && !targetAspects.includes(target.aspect)) continue;
344
+ if (allAspects && (!allAspects.includes(source.aspect) || !allAspects.includes(target.aspect))) continue;
345
+
346
+ if (rule.sameAspect && source.aspect !== target.aspect) continue;
347
+ if (rule.sameLayer && source.layer !== target.layer) continue;
348
+ if (rule.crossLayer === false && source.layer !== target.layer) continue;
349
+
350
+ if (rule.fromLayer && rule.fromLayer !== source.layer) continue;
351
+ if (rule.toLayer && rule.toLayer !== target.layer) continue;
352
+
353
+ return rule;
354
+ }
355
+ return null;
356
+ }
357
+ }