@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,546 @@
1
+ import {
2
+ parseXML, ARCHI_FOLDERS, archiFolderOf, archiVisualBoxes, archiBendpointLocations, relativizeArchiBendpoints,
3
+ parseArchiFont, archiFontString, typedArrayToProperties, toPascalType, escapeXml, escapeAttr,
4
+ } from './archimateArchiFormat.js';
5
+ import { ARCHI_TYPE_FEATURE } from './archimateArchiTypes.js';
6
+
7
+ /**
8
+ * The Open Group ArchiMate Model Exchange File Format (3.1): the standard
9
+ * route between ArchiMate tools (Archi, Sparx EA, BiZZdesign, ...).
10
+ *
11
+ * Both directions go through the shapes the Archi format uses, so everything
12
+ * downstream is shared: `parseExchangeModel` gives what `parseArchiModel`
13
+ * gives (hand it to `toArchimateModel`), and `toExchangeXML` takes what
14
+ * `toArchiXML` takes (an editor's model and its views as `fromArchimateView`
15
+ * trees). The differences are the format's own:
16
+ *
17
+ * - A node's x/y and a bendpoint are on the view (Archi: relative to the parent
18
+ * box, and offsets from the line's ends).
19
+ * - Colours are r/g/b with a 0-100 alpha; a font is a name, size and style.
20
+ * - Properties name a property definition.
21
+ * - Folders are organizations (an item per folder, holding item refs).
22
+ * - Only ArchiMate diagrams: the format has no canvases or sketches, which are
23
+ * not written. A box with no ArchiMate meaning (note, picture, view
24
+ * reference) is a Label; a group is a Container.
25
+ * - An element type Archi lacks is written as its nearest ArchiMate 3.2 type
26
+ * with its own kept in the property EXCHANGE_TYPE_PROPERTY, which import reads back.
27
+ */
28
+
29
+ export const EXCHANGE_NAMESPACE = 'http://www.opengroup.org/xsd/archimate/3.0/';
30
+ const EXCHANGE_SCHEMA = 'http://www.opengroup.org/xsd/archimate/3.1/archimate3_Diagram.xsd';
31
+ const XSI_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance';
32
+
33
+ /** The property that keeps an element's own type when it is written as another (as Archi's feature does). */
34
+ export const EXCHANGE_TYPE_PROPERTY = ARCHI_TYPE_FEATURE;
35
+
36
+ /** The format's viewpoint names; Archi's id for each is its name in lower case, without "and", joined by "_". */
37
+ export const EXCHANGE_VIEWPOINTS = Object.freeze([
38
+ 'Application Cooperation', 'Application Usage', 'Business Process Cooperation', 'Capability', 'Goal Realization',
39
+ 'Implementation and Deployment', 'Implementation and Migration', 'Information Structure', 'Layered', 'Migration',
40
+ 'Motivation', 'Organization', 'Outcome Realization', 'Physical', 'Product', 'Project', 'Requirements Realization',
41
+ 'Resource', 'Service Realization', 'Stakeholder', 'Strategy', 'Technology', 'Technology Usage', 'Value Stream',
42
+ ]);
43
+ const _viewpointId = (name) => name.toLowerCase().replace(/ and /g, ' ').replace(/ /g, '_');
44
+
45
+ /** An access relationship's access: the format's names by Archi's accessType (absent: write). */
46
+ const ACCESS_TYPES = Object.freeze({ 0: 'Write', 1: 'Read', 2: 'Access', 3: 'ReadWrite' });
47
+
48
+ /** The format's two junction types, by whether Archi's junction is an "or". */
49
+ const JUNCTION_TYPES = Object.freeze({ AndJunction: false, OrJunction: true });
50
+
51
+ /** Node types, by the Archi visual type each is read as. */
52
+ const NODE_VISUALS = Object.freeze({ Element: 'diagram-object', Container: 'diagram-model-group', Label: 'diagram-model-note' });
53
+
54
+ // --- reading ---
55
+
56
+ const _local = (el) => el.tagName.replace(/^.*:/, '');
57
+ const _kids = (el, name) => (el?.children ?? []).filter(c => _local(c) === name);
58
+ const _kid = (el, name) => _kids(el, name)[0];
59
+ /** The text of the first child `name` (the first language given). */
60
+ const _text = (el, name) => _kid(el, name)?.textContent ?? null;
61
+ const _xsiType = (el) => (el.getAttribute('xsi:type') ?? '').replace(/^.*:/, '');
62
+ const _number = (el, name) => Number(el.getAttribute(name) ?? 0);
63
+
64
+ /**
65
+ * Parse an Exchange Format file into the shapes `parseArchiModel` gives, ready
66
+ * for `toArchimateModel`.
67
+ * @param {string|ArchiXMLElement} xml
68
+ * @returns {Object} {id, name, documentation, properties, elements, relationships, views}
69
+ */
70
+ export function parseExchangeModel(xml) {
71
+ const root = typeof xml === 'string' ? parseXML(xml) : xml;
72
+ // Archi's own root is a <model> too: the namespace tells them apart (3.0 and 3.1 share it).
73
+ const inFormat = Object.entries(root.attributes ?? {}).some(([name, value]) => /^xmlns(:|$)/.test(name) && /opengroup\.org\/xsd\/archimate/.test(value));
74
+ if (_local(root) !== 'model' || !inFormat) throw new Error(`Not an ArchiMate Exchange Format model: the root is <${root.tagName}>`);
75
+
76
+ const definitions = new Map(_kids(_kid(root, 'propertyDefinitions'), 'propertyDefinition')
77
+ .map(d => [d.getAttribute('identifier'), _text(d, 'name') ?? d.getAttribute('name') ?? '']));
78
+ /** A concept's or view's properties as [{key, value}], in file order. */
79
+ const pairs = (el) => _kids(_kid(el, 'properties'), 'property').map(p => ({
80
+ key: definitions.get(p.getAttribute('propertyDefinitionRef') ?? p.getAttribute('identifierRef')) ?? '',
81
+ value: _text(p, 'value') ?? '',
82
+ }));
83
+ const folders = _organizationPaths(root);
84
+
85
+ const model = {
86
+ id: root.getAttribute('identifier'),
87
+ name: _text(root, 'name') ?? '',
88
+ documentation: _text(root, 'documentation'),
89
+ properties: pairs(root),
90
+ archi: null,
91
+ elements: [],
92
+ relationships: [],
93
+ views: [],
94
+ };
95
+ for (const el of _kids(_kid(root, 'elements'), 'element')) {
96
+ model.elements.push(_inFolder(_parseElement(el, pairs(el)), folders));
97
+ }
98
+ for (const el of _kids(_kid(root, 'relationships'), 'relationship')) {
99
+ model.relationships.push(_inFolder(_parseRelationship(el, pairs(el)), folders));
100
+ }
101
+ for (const el of _kids(_kid(_kid(root, 'views'), 'diagrams'), 'view')) {
102
+ if (_xsiType(el) !== 'Diagram') continue;
103
+ model.views.push(_inFolder(_parseView(el, pairs(el)), folders));
104
+ }
105
+ return model;
106
+ }
107
+
108
+ /** An item's folder path (`archiFolder`) from the organizations, when it has one. @private */
109
+ function _inFolder(item, folders) {
110
+ const path = folders.get(item.id);
111
+ if (path?.length) item.archiFolder = path;
112
+ return item;
113
+ }
114
+
115
+ /**
116
+ * The folder path of every item the organizations hold, by its id: each
117
+ * labelled item it is in, outermost first. An outermost item named as one of
118
+ * Archi's top-level folders is that folder, not a sub-folder (Archi exports
119
+ * its folders so); any other is a sub-folder.
120
+ * @private
121
+ */
122
+ function _organizationPaths(root) {
123
+ const topNames = new Set(ARCHI_FOLDERS.map(f => f.name));
124
+ const paths = new Map();
125
+ let made = 0;
126
+ const walk = (item, path, outermost) => {
127
+ for (const child of _kids(item, 'item')) {
128
+ const ref = child.getAttribute('identifierRef');
129
+ if (ref) { paths.set(ref, path); continue; }
130
+ const name = _text(child, 'label') ?? '';
131
+ if (outermost && topNames.has(name)) { walk(child, path, false); continue; }
132
+ const documentation = _text(child, 'documentation');
133
+ const step = { id: child.getAttribute('identifier') ?? `folder-${++made}`, name, ...(documentation && { documentation }) };
134
+ walk(child, [...path, step], false);
135
+ }
136
+ };
137
+ for (const organization of _kids(root, 'organizations')) walk(organization, [], true);
138
+ return paths;
139
+ }
140
+
141
+ /** An element as parseArchiModel gives it (type: Archi's class name). @private */
142
+ function _parseElement(el, propertyPairs) {
143
+ const xsiType = _xsiType(el);
144
+ const properties = Object.fromEntries(propertyPairs.map(({ key, value }) => [key, value]));
145
+ const ownType = properties[EXCHANGE_TYPE_PROPERTY];
146
+ delete properties[EXCHANGE_TYPE_PROPERTY];
147
+ const attributes = {};
148
+ const elements = [];
149
+ if (JUNCTION_TYPES[xsiType]) attributes.type = 'or';
150
+ // Its own type as Archi keeps it, so the model reads both files alike.
151
+ if (ownType) elements.push({ tag: 'feature', text: '', attributes: { name: ARCHI_TYPE_FEATURE, value: ownType } });
152
+ return {
153
+ id: el.getAttribute('identifier'),
154
+ name: _text(el, 'name') ?? '',
155
+ type: xsiType in JUNCTION_TYPES ? 'Junction' : xsiType,
156
+ documentation: _text(el, 'documentation'),
157
+ properties,
158
+ ...((Object.keys(attributes).length || elements.length) && { archi: { attributes, elements } }),
159
+ };
160
+ }
161
+
162
+ /** A relationship as parseArchiModel gives it (type: Archi's class name). @private */
163
+ function _parseRelationship(el, propertyPairs) {
164
+ const xsiType = _xsiType(el);
165
+ const attributes = {};
166
+ const access = Object.entries(ACCESS_TYPES).find(([, name]) => name === el.getAttribute('accessType'))?.[0];
167
+ if (access && access !== '0') attributes.accessType = access;
168
+ if (el.getAttribute('modifier')) attributes.strength = el.getAttribute('modifier');
169
+ return {
170
+ id: el.getAttribute('identifier'),
171
+ name: _text(el, 'name') ?? '',
172
+ type: `${xsiType}Relationship`,
173
+ source: el.getAttribute('source'),
174
+ target: el.getAttribute('target'),
175
+ ...(el.getAttribute('isDirected') === 'true' && { directed: true }),
176
+ documentation: _text(el, 'documentation'),
177
+ properties: Object.fromEntries(propertyPairs.map(({ key, value }) => [key, value])),
178
+ ...(Object.keys(attributes).length && { archi: { attributes, elements: [] } }),
179
+ };
180
+ }
181
+
182
+ /** A view as parseArchiModel gives it: a tree of Archi visuals, bounds relative to their parent. @private */
183
+ function _parseView(el, properties) {
184
+ const viewpoint = EXCHANGE_VIEWPOINTS.find(name => name === el.getAttribute('viewpoint'));
185
+ const view = {
186
+ id: el.getAttribute('identifier'),
187
+ name: _text(el, 'name') ?? '',
188
+ type: 'archimate-diagram-model',
189
+ documentation: _text(el, 'documentation'),
190
+ properties,
191
+ archi: viewpoint ? { attributes: { viewpoint: _viewpointId(viewpoint) }, elements: [] } : null,
192
+ children: [],
193
+ };
194
+ const byId = new Map();
195
+ const walk = (parent, origin, into) => {
196
+ for (const node of _kids(parent, 'node')) {
197
+ const box = { x: _number(node, 'x'), y: _number(node, 'y'), width: _number(node, 'w'), height: _number(node, 'h') };
198
+ const visual = _nodeVisual(node, { ...box, x: box.x - origin.x, y: box.y - origin.y });
199
+ byId.set(visual.id, visual);
200
+ into.push(visual);
201
+ walk(node, box, visual.children);
202
+ }
203
+ };
204
+ walk(el, { x: 0, y: 0 }, view.children);
205
+ for (const line of _kids(el, 'connection')) {
206
+ // On its source box, as Archi keeps it (a line from a line has no box, and is not kept).
207
+ const source = byId.get(line.getAttribute('source'));
208
+ if (!source || !byId.has(line.getAttribute('target'))) continue;
209
+ const style = _styleOf(line);
210
+ const bendpoints = _kids(line, 'bendpoint').map(bp => ({ x: _number(bp, 'x'), y: _number(bp, 'y') }));
211
+ source.sourceConnections.push({
212
+ id: line.getAttribute('identifier'),
213
+ source: source.id,
214
+ target: line.getAttribute('target'),
215
+ relationship: line.getAttribute('relationshipRef') || null,
216
+ type: '',
217
+ archiType: 'diagram-model-connection',
218
+ connectionType: 0,
219
+ archi: { attributes: {}, elements: [], style },
220
+ name: _text(line, 'label') ?? '',
221
+ style,
222
+ features: {},
223
+ ...(bendpoints.length && { bendpoints }),
224
+ });
225
+ }
226
+ // Bendpoints are on the view here; Archi keeps them as offsets from the line's ends.
227
+ relativizeArchiBendpoints(view);
228
+ return view;
229
+ }
230
+
231
+ /** One node as an Archi visual: an element's box, a group (Container) or a note (Label). @private */
232
+ function _nodeVisual(node, bounds) {
233
+ const kind = _xsiType(node);
234
+ const label = _text(node, 'label');
235
+ const style = _styleOf(node);
236
+ return {
237
+ id: node.getAttribute('identifier'),
238
+ type: NODE_VISUALS[kind] ?? NODE_VISUALS.Label,
239
+ archimateElement: node.getAttribute('elementRef') || null,
240
+ referencedModel: null,
241
+ imagePath: null,
242
+ name: kind === 'Container' ? label : null,
243
+ text: kind === 'Container' ? null : label,
244
+ notes: null,
245
+ bounds,
246
+ style,
247
+ archi: { attributes: {}, elements: [], style },
248
+ features: {},
249
+ properties: {},
250
+ sourceConnections: [],
251
+ children: [],
252
+ };
253
+ }
254
+
255
+ /** A colour element as Archi's "#rrggbb". @private */
256
+ const _hex = (color) => `#${['r', 'g', 'b'].map(c => Math.max(0, Math.min(255, _number(color, c))).toString(16).padStart(2, '0')).join('')}`;
257
+
258
+ /** A node's or line's <style> as Archi's style attributes (see archimateArchiFormat's STYLE_FIELDS). @private */
259
+ function _styleOf(el) {
260
+ const styleEl = _kid(el, 'style');
261
+ const style = {};
262
+ if (!styleEl) return style;
263
+ const fill = _kid(styleEl, 'fillColor');
264
+ if (fill) {
265
+ style.fillColor = _hex(fill);
266
+ const alpha = fill.getAttribute('a');
267
+ if (alpha !== null && alpha !== undefined && Number(alpha) < 100) style.alpha = String(Math.round(Number(alpha) * 2.55));
268
+ }
269
+ const line = _kid(styleEl, 'lineColor');
270
+ if (line) {
271
+ style.lineColor = _hex(line);
272
+ if (line.getAttribute('a') === '0') style.lineAlpha = '0';
273
+ }
274
+ const font = _kid(styleEl, 'font');
275
+ if (font) {
276
+ if (_kid(font, 'color')) style.fontColor = _hex(_kid(font, 'color'));
277
+ const name = font.getAttribute('name');
278
+ const size = font.getAttribute('size');
279
+ if (name || size) {
280
+ const words = String(font.getAttribute('style') ?? '').toLowerCase();
281
+ style.font = archiFontString({
282
+ ...(name && { fontFamily: name }),
283
+ ...(size && { fontSize: `${Number(size)}pt` }),
284
+ ...(words.includes('bold') && { fontWeight: 'bold' }),
285
+ ...(words.includes('italic') && { fontStyle: 'italic' }),
286
+ });
287
+ }
288
+ }
289
+ if (styleEl.getAttribute('lineWidth')) style.lineWidth = styleEl.getAttribute('lineWidth');
290
+ return style;
291
+ }
292
+
293
+ // --- writing ---
294
+
295
+ /** An xs:ID: a letter or underscore, then letters, digits, '.', '-', '_'. */
296
+ const NCNAME = /^[A-Za-z_][\w.-]*$/;
297
+
298
+ /**
299
+ * Identifiers for the file: every one unique, and each a valid xs:ID. An id
300
+ * that already is one is kept (so a round trip keeps them); others are made
301
+ * one. The same id asked for again by `ref` gets the same identifier.
302
+ * @private
303
+ */
304
+ class ExchangeIds {
305
+ constructor() {
306
+ this.byId = new Map();
307
+ this.used = new Set();
308
+ }
309
+
310
+ /** The identifier for a concept or view id (the same each time). */
311
+ ref(id) {
312
+ if (!this.byId.has(id)) this.byId.set(id, this.fresh(id));
313
+ return this.byId.get(id);
314
+ }
315
+
316
+ /** A new identifier, made from `id`. */
317
+ fresh(id) {
318
+ let candidate = NCNAME.test(String(id)) ? String(id) : `id-${String(id).replace(/[^\w.-]/g, '_')}`;
319
+ while (this.used.has(candidate)) candidate += '_';
320
+ this.used.add(candidate);
321
+ return candidate;
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Write a model as an Exchange Format file. Takes what `toArchiXML` takes.
327
+ * @param {Object} model - {id, name, documentation, properties, elements, relationships}
328
+ * @param {Array<Object>} views - Archi view trees (an editor's views via fromArchimateView); only
329
+ * ArchiMate diagrams are written
330
+ * @returns {string}
331
+ */
332
+ export function toExchangeXML(model, views = []) {
333
+ const ids = new ExchangeIds();
334
+ const definitions = new Map(); // property key -> its definition's identifier
335
+ const define = (key) => {
336
+ if (!definitions.has(key)) definitions.set(key, `propid-${definitions.size + 1}`);
337
+ return definitions.get(key);
338
+ };
339
+ const propertyLines = (pairs, indent) => pairs.length ? [
340
+ `${indent}<properties>`,
341
+ ...pairs.flatMap(({ key, value }) => [
342
+ `${indent} <property propertyDefinitionRef="${define(key)}">`,
343
+ `${indent} <value>${escapeXml(value ?? '')}</value>`,
344
+ `${indent} </property>`,
345
+ ]),
346
+ `${indent}</properties>`,
347
+ ] : [];
348
+ const textLines = (tag, text, indent) => text ? [`${indent}<${tag}>${escapeXml(text)}</${tag}>`] : [];
349
+ const conceptPairs = (concept, extra = []) => [
350
+ ...Object.entries(typedArrayToProperties(concept.properties)).map(([key, value]) => ({ key, value })),
351
+ ...extra,
352
+ ];
353
+
354
+ const elements = model.elements ?? [];
355
+ const relationships = model.relationships ?? [];
356
+ const diagrams = (views ?? []).filter(v => !v.type || v.type === 'archimate-diagram-model');
357
+
358
+ const elementLines = elements.flatMap(el => {
359
+ const { type, original } = archiFolderOf(el);
360
+ let xsiType = toPascalType(type);
361
+ if (xsiType === 'Junction') xsiType = el.archi?.attributes?.type === 'or' ? 'OrJunction' : 'AndJunction';
362
+ return [
363
+ ` <element identifier="${ids.ref(el.id)}" xsi:type="${xsiType}">`,
364
+ ` <name>${escapeXml(el.name ?? '')}</name>`,
365
+ ...textLines('documentation', el.documentation, ' '),
366
+ ...propertyLines(conceptPairs(el, original ? [{ key: EXCHANGE_TYPE_PROPERTY, value: original }] : []), ' '),
367
+ ' </element>',
368
+ ];
369
+ });
370
+
371
+ const known = new Set(elements.map(e => e.id));
372
+ const relationshipLines = relationships.flatMap(rel => {
373
+ const directed = rel.kind === 'association-directed';
374
+ const kind = directed ? 'association' : (rel.kind || 'association');
375
+ const attrs = [`identifier="${ids.ref(rel.id)}"`, `source="${ids.ref(rel.source)}"`, `target="${ids.ref(rel.target)}"`, `xsi:type="${toPascalType(kind)}"`];
376
+ if (directed) attrs.push('isDirected="true"');
377
+ const access = ACCESS_TYPES[rel.archi?.attributes?.accessType ?? 0];
378
+ if (kind === 'access' && access && access !== 'Write') attrs.push(`accessType="${access}"`);
379
+ if (kind === 'influence' && rel.archi?.attributes?.strength) attrs.push(`modifier="${escapeAttr(rel.archi.attributes.strength)}"`);
380
+ const name = rel.label ?? rel.name;
381
+ const body = [
382
+ ...textLines('name', name, ' '),
383
+ ...textLines('documentation', rel.documentation, ' '),
384
+ ...propertyLines(conceptPairs(rel), ' '),
385
+ ];
386
+ known.add(rel.id);
387
+ return body.length
388
+ ? [` <relationship ${attrs.join(' ')}>`, ...body, ' </relationship>']
389
+ : [` <relationship ${attrs.join(' ')}/>`];
390
+ });
391
+
392
+ const viewLines = diagrams.flatMap(view => _viewLines(view, { ids, known, propertyLines, textLines }));
393
+ const organizationLines = _organizationLines({ elements, relationships, views: diagrams, ids });
394
+
395
+ // Read once every property is defined: the model's, the concepts' and the views'.
396
+ const modelLines = [
397
+ ` <name>${escapeXml(model.name || 'Untitled')}</name>`,
398
+ ...textLines('documentation', model.documentation, ' '),
399
+ ...propertyLines(Array.isArray(model.properties) ? model.properties : [], ' '),
400
+ ];
401
+ const section = (tag, lines) => lines.length ? [` <${tag}>`, ...lines, ` </${tag}>`] : [];
402
+ return [
403
+ '<?xml version="1.0" encoding="UTF-8"?>',
404
+ `<model xmlns="${EXCHANGE_NAMESPACE}" xmlns:xsi="${XSI_NAMESPACE}" xsi:schemaLocation="${EXCHANGE_NAMESPACE} ${EXCHANGE_SCHEMA}" identifier="${ids.ref(model.id || 'model')}">`,
405
+ ...modelLines,
406
+ ...section('elements', elementLines),
407
+ ...section('relationships', relationshipLines),
408
+ ...section('organizations', organizationLines),
409
+ ...section('propertyDefinitions', [...definitions].flatMap(([key, id]) => [
410
+ ` <propertyDefinition identifier="${id}" type="string">`,
411
+ ` <name>${escapeXml(key)}</name>`,
412
+ ' </propertyDefinition>',
413
+ ])),
414
+ ...(viewLines.length ? [' <views>', ' <diagrams>', ...viewLines, ' </diagrams>', ' </views>'] : []),
415
+ '</model>',
416
+ ].join('\n');
417
+ }
418
+
419
+ /** One view: its nodes on the view (x/y absolute), then its lines with their bendpoints on the view. @private */
420
+ function _viewLines(view, { ids, known, propertyLines, textLines }) {
421
+ const boxes = archiVisualBoxes({ children: view.children ?? [] });
422
+ const nodeIds = new Map(); // visual id -> its identifier in this file
423
+ const visuals = [];
424
+ const collect = (visual) => { visuals.push(visual); (visual.children ?? []).forEach(collect); };
425
+ (view.children ?? []).forEach(collect);
426
+ for (const visual of visuals) if (boxes.has(visual.id)) nodeIds.set(visual.id, ids.fresh(visual.id));
427
+ // The format allows no negative x or y: the view moves right and down by its most negative (as Archi exports).
428
+ const pointsOf = new Map(visuals.flatMap(v => (v.sourceConnections ?? []).map(sc => [sc, sc.bendpoints?.length ? archiBendpointLocations(sc, boxes) : []])));
429
+ const all = [...boxes.values(), ...[...pointsOf.values()].flat()];
430
+ const shift = { x: Math.max(0, -Math.min(0, ...all.map(p => Math.round(p.x)))), y: Math.max(0, -Math.min(0, ...all.map(p => Math.round(p.y)))) };
431
+
432
+ const nodeLines = (visual, indent) => {
433
+ const box = boxes.get(visual.id);
434
+ if (!box) return [];
435
+ const attrs = [`identifier="${nodeIds.get(visual.id)}"`];
436
+ let label = null;
437
+ if (visual.archimateElement && known.has(visual.archimateElement)) {
438
+ attrs.push(`elementRef="${ids.ref(visual.archimateElement)}"`, 'xsi:type="Element"');
439
+ } else if (visual.type === 'diagram-model-group') {
440
+ attrs.push('xsi:type="Container"');
441
+ label = visual.name;
442
+ } else {
443
+ attrs.push('xsi:type="Label"');
444
+ label = visual.text ?? visual.name;
445
+ }
446
+ attrs.push(`x="${Math.round(box.x) + shift.x}"`, `y="${Math.round(box.y) + shift.y}"`, `w="${Math.round(box.width)}"`, `h="${Math.round(box.height)}"`);
447
+ const body = [
448
+ ...textLines('label', label, `${indent} `),
449
+ ..._styleLines(visual.style, `${indent} `),
450
+ ...(visual.children ?? []).flatMap(child => nodeLines(child, `${indent} `)),
451
+ ];
452
+ return body.length ? [`${indent}<node ${attrs.join(' ')}>`, ...body, `${indent}</node>`] : [`${indent}<node ${attrs.join(' ')}/>`];
453
+ };
454
+
455
+ const lines = visuals.flatMap(visual => (visual.sourceConnections ?? []).flatMap(sc => {
456
+ if (!nodeIds.has(sc.source) || !nodeIds.has(sc.target)) return [];
457
+ if (sc.relationship && !known.has(sc.relationship)) return [];
458
+ const attrs = [`identifier="${ids.fresh(sc.id)}"`];
459
+ attrs.push(sc.relationship ? `relationshipRef="${ids.ref(sc.relationship)}" xsi:type="Relationship"` : 'xsi:type="Line"');
460
+ attrs.push(`source="${nodeIds.get(sc.source)}"`, `target="${nodeIds.get(sc.target)}"`);
461
+ const points = pointsOf.get(sc);
462
+ const body = [
463
+ ...(sc.relationship ? [] : textLines('label', sc.name, ' ')),
464
+ ..._styleLines(sc.style, ' '),
465
+ ...points.map(p => ` <bendpoint x="${Math.round(p.x) + shift.x}" y="${Math.round(p.y) + shift.y}"/>`),
466
+ ];
467
+ return body.length ? [` <connection ${attrs.join(' ')}>`, ...body, ' </connection>'] : [` <connection ${attrs.join(' ')}/>`];
468
+ }));
469
+
470
+ const viewpoint = EXCHANGE_VIEWPOINTS.find(name => _viewpointId(name) === view.archi?.attributes?.viewpoint);
471
+ return [
472
+ ` <view identifier="${ids.ref(view.id)}" xsi:type="Diagram"${viewpoint ? ` viewpoint="${viewpoint}"` : ''}>`,
473
+ ` <name>${escapeXml(view.name || 'View')}</name>`,
474
+ ...textLines('documentation', view.documentation, ' '),
475
+ ...propertyLines(Array.isArray(view.properties) ? view.properties : [], ' '),
476
+ ...(view.children ?? []).flatMap(visual => nodeLines(visual, ' ')),
477
+ ...lines,
478
+ ' </view>',
479
+ ];
480
+ }
481
+
482
+ /** Archi's "#rrggbb" as the format's r/g/b attributes. @private */
483
+ function _rgb(hex) {
484
+ const m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(String(hex ?? ''));
485
+ return m && `r="${parseInt(m[1], 16)}" g="${parseInt(m[2], 16)}" b="${parseInt(m[3], 16)}"`;
486
+ }
487
+
488
+ /** Archi's style attributes as a <style> element (nothing when there is no style). @private */
489
+ function _styleLines(style = {}, indent) {
490
+ const inner = [];
491
+ const fill = _rgb(style.fillColor);
492
+ const alpha = style.alpha !== undefined ? Math.round(Number(style.alpha) / 2.55) : null;
493
+ if (fill) inner.push(`${indent} <fillColor ${fill}${alpha !== null ? ` a="${alpha}"` : ''}/>`);
494
+ else if (alpha === 0) inner.push(`${indent} <fillColor r="255" g="255" b="255" a="0"/>`);
495
+ const line = _rgb(style.lineColor ?? style.borderColor);
496
+ if (line) inner.push(`${indent} <lineColor ${line}${style.lineAlpha === '0' ? ' a="0"' : ''}/>`);
497
+ const font = parseArchiFont(style.font);
498
+ const color = _rgb(style.fontColor);
499
+ if (style.font || color) {
500
+ const attrs = [];
501
+ if (font.fontFamily) attrs.push(`name="${escapeAttr(font.fontFamily)}"`);
502
+ if (font.fontSize) attrs.push(`size="${parseFloat(font.fontSize)}"`);
503
+ const words = [font.fontWeight === 'bold' && 'bold', font.fontStyle === 'italic' && 'italic'].filter(Boolean);
504
+ if (words.length) attrs.push(`style="${words.join(' ')}"`);
505
+ const open = `${indent} <font${attrs.length ? ` ${attrs.join(' ')}` : ''}`;
506
+ inner.push(...(color ? [`${open}>`, `${indent} <color ${color}/>`, `${indent} </font>`] : [`${open}/>`]));
507
+ }
508
+ const width = style.lineWidth ? ` lineWidth="${Number(style.lineWidth)}"` : '';
509
+ if (!inner.length && !width) return [];
510
+ return inner.length ? [`${indent}<style${width}>`, ...inner, `${indent}</style>`] : [`${indent}<style${width}/>`];
511
+ }
512
+
513
+ /**
514
+ * The organizations: one item per Archi top-level folder that holds anything,
515
+ * each item's concepts or views in the sub-folders its `archiFolder` names.
516
+ * @private
517
+ */
518
+ function _organizationLines({ elements, relationships, views, ids }) {
519
+ const inFolder = new Map(ARCHI_FOLDERS.map(f => [f.type, []]));
520
+ for (const el of elements) inFolder.get(archiFolderOf(el).folder.type).push(el);
521
+ inFolder.get('relations').push(...relationships);
522
+ inFolder.get('diagrams').push(...views);
523
+
524
+ const write = (items, indent) => {
525
+ const lines = [];
526
+ const groups = new Map();
527
+ for (const item of items.filter(i => i.archiFolder?.length)) {
528
+ const [step, ...rest] = item.archiFolder;
529
+ if (!groups.has(step.id)) groups.set(step.id, { step, items: [] });
530
+ groups.get(step.id).items.push({ ...item, archiFolder: rest });
531
+ }
532
+ for (const { step, items: inner } of groups.values()) {
533
+ lines.push(`${indent}<item identifier="${ids.fresh(step.id)}">`, `${indent} <label>${escapeXml(step.name ?? '')}</label>`);
534
+ if (step.documentation) lines.push(`${indent} <documentation>${escapeXml(step.documentation)}</documentation>`);
535
+ lines.push(...write(inner, `${indent} `), `${indent}</item>`);
536
+ }
537
+ for (const item of items.filter(i => !i.archiFolder?.length)) lines.push(`${indent}<item identifierRef="${ids.ref(item.id)}"/>`);
538
+ return lines;
539
+ };
540
+ return ARCHI_FOLDERS.filter(f => inFolder.get(f.type).length).flatMap(folder => [
541
+ ' <item>',
542
+ ` <label>${escapeXml(folder.name)}</label>`,
543
+ ...write(inFolder.get(folder.type), ' '),
544
+ ' </item>',
545
+ ]);
546
+ }