ea 0.3.1 → 0.5.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 (544) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -0
  3. data/TODO.complete/01-t-xref-parsing.md +91 -0
  4. data/TODO.complete/02-per-label-geometry.md +50 -0
  5. data/TODO.complete/03-object-properties-constraints.md +57 -0
  6. data/TODO.complete/04-operation-params.md +37 -0
  7. data/TODO.complete/05-pdata-flag-matrix.md +52 -0
  8. data/TODO.complete/06-emf-image-rendering.md +34 -0
  9. data/TODO.complete/07-auxiliary-tables.md +47 -0
  10. data/TODO.complete/10-mdg-stereotype-registry.md +40 -0
  11. data/TODO.complete/11-gml-xsd-generation.md +42 -0
  12. data/TODO.complete/13-shapescript-interpreter.md +28 -0
  13. data/TODO.complete/20-cli-diff.md +46 -0
  14. data/TODO.complete/21-cli-render.md +26 -0
  15. data/TODO.complete/22-cli-export.md +29 -0
  16. data/TODO.complete/23-cli-mdg.md +23 -0
  17. data/TODO.complete/30-headerlines-ocp-refactor.md +72 -0
  18. data/TODO.complete/31-public-send-cleanup.md +61 -0
  19. data/TODO.complete/32-spec-coverage.md +33 -0
  20. data/TODO.complete/33-blocked-parity-gaps.md +41 -0
  21. data/TODO.complete/36-stereotype-icon-wiring.md +32 -0
  22. data/TODO.complete/37-cli-lint.md +32 -0
  23. data/TODO.complete/38-cli-query.md +26 -0
  24. data/TODO.complete/39-cli-info.md +23 -0
  25. data/TODO.complete/40-ocl-evaluator.md +31 -0
  26. data/TODO.complete/41-round-trip-spec.md +18 -0
  27. data/TODO.complete/42-html-diff-report.md +18 -0
  28. data/TODO.complete/43-json-schema-export.md +20 -0
  29. data/TODO.complete/44-remaining-qea-tables.md +40 -0
  30. data/TODO.complete/45-shapescript-extensions.md +25 -0
  31. data/TODO.complete/46-xsd-consolidation.md +20 -0
  32. data/TODO.complete/47-headerlines-legacy-removal.md +20 -0
  33. data/TODO.complete/STATUS.md +109 -0
  34. data/TODO.diagrams/01-svg-measurement-harness.md +31 -0
  35. data/TODO.diagrams/01-xmi-extension-elements-parsing.md +67 -0
  36. data/TODO.diagrams/02-diagram-element-rich-model.md +61 -0
  37. data/TODO.diagrams/02-polygon-over-rendering.md +29 -0
  38. data/TODO.diagrams/03-ea-style-svg-emitter.md +70 -0
  39. data/TODO.diagrams/03-text-over-rendering.md +30 -0
  40. data/TODO.diagrams/04-connector-routing-from-soid-eoid.md +55 -0
  41. data/TODO.diagrams/04-rect-under-rendering.md +33 -0
  42. data/TODO.diagrams/05-canvas-dimension-parity.md +51 -0
  43. data/TODO.diagrams/05-marker-rendering-per-relationship-type.md +49 -0
  44. data/TODO.diagrams/06-connector-labels.md +49 -0
  45. data/TODO.diagrams/06-group-layering-parity.md +39 -0
  46. data/TODO.diagrams/07-canvas-size-and-viewbox.md +39 -0
  47. data/TODO.diagrams/07-text-content-fidelity.md +65 -0
  48. data/TODO.diagrams/08-qea-direct-pipeline.md +46 -0
  49. data/TODO.diagrams/08-visual-regression-harness.md +34 -0
  50. data/TODO.diagrams/09-cli-render-all-diagrams.md +25 -0
  51. data/TODO.diagrams/10-stereotype-color-config.md +29 -0
  52. data/TODO.diagrams/11-elkrb-auto-layout-integration.md +53 -0
  53. data/TODO.diagrams/12-connector-labels.md +40 -0
  54. data/TODO.diagrams/12-per-entity-svg-layer-ordering.md +24 -0
  55. data/TODO.diagrams/13-marker-polygon-vs-path-dispatch.md +20 -0
  56. data/TODO.diagrams/13-per-text-type-font-sizes.md +33 -0
  57. data/TODO.diagrams/14-center-header-text.md +33 -0
  58. data/TODO.diagrams/14-filter-diagram-frame-elements.md +18 -0
  59. data/TODO.diagrams/15-deep-dead-code-audit.md +47 -0
  60. data/TODO.diagrams/15-per-element-font-from-style.md +24 -0
  61. data/TODO.diagrams/16-canvas-marker-extent.md +30 -0
  62. data/TODO.diagrams/16-document-remaining-parity-gaps.md +91 -0
  63. data/TODO.diagrams/17-italic-abstract-classes.md +28 -0
  64. data/TODO.diagrams/17-remaining-parity-gaps.md +90 -0
  65. data/TODO.diagrams/18-canvas-from-image-bounds.md +20 -0
  66. data/TODO.diagrams/18-property-lookup-index.md +42 -0
  67. data/TODO.diagrams/19-connector-sx-sy-routing.md +27 -0
  68. data/TODO.diagrams/19-replace-respond-to-with-is-a.md +31 -0
  69. data/TODO.diagrams/20-split-labels-emitter.md +56 -0
  70. data/TODO.diagrams/20-visibility-glyph-font-encoding.md +27 -0
  71. data/TODO.diagrams/21-aggregation-navigability-arrow.md +21 -0
  72. data/TODO.diagrams/21-auto-generated-legend-block.md +65 -0
  73. data/TODO.diagrams/22-ghost-element-discriminator.md +57 -0
  74. data/TODO.diagrams/22-style-based-path-grouping.md +28 -0
  75. data/TODO.diagrams/23-marker-polygon-deduplication.md +47 -0
  76. data/TODO.diagrams/23-multiplicity-label-positioning.md +29 -0
  77. data/TODO.diagrams/24-marker-anchor-structural.md +35 -0
  78. data/TODO.diagrams/24-track-marker-anchors-structurally.md +66 -0
  79. data/TODO.diagrams/24-truncate-properties-to-fit-box.md +24 -0
  80. data/TODO.diagrams/26-phantom-general-parent-rendering.md +59 -0
  81. data/TODO.diagrams/27-path-grouping-mode-detection.md +43 -0
  82. data/TODO.diagrams/28-architecture-cleanup-batch.md +47 -0
  83. data/TODO.diagrams/30-decompose-elements-groups-for.md +52 -0
  84. data/TODO.diagrams/32-examples-coverage-batch.md +78 -0
  85. data/TODO.diagrams/36-instance-specification-model.md +42 -0
  86. data/TODO.diagrams/37-element-icon-decorations.md +41 -0
  87. data/TODO.diagrams/38-html-note-and-receptions.md +32 -0
  88. data/TODO.diagrams/39-property-stereotype-discriminator.md +40 -0
  89. data/TODO.diagrams/40-standalone-1-discriminator.md +38 -0
  90. data/TODO.diagrams/41-xmi-to-svg-pipeline.md +113 -0
  91. data/TODO.diagrams/42-close-all-parity-deltas.md +69 -0
  92. data/TODO.diagrams/43-marker-deduplication-strategy.md +54 -0
  93. data/TODO.diagrams/44-element-icon-decorations.md +34 -0
  94. data/TODO.diagrams/45-phantom-parent-class-boxes.md +40 -0
  95. data/TODO.diagrams/46-user-drawn-legend-swatches.md +44 -0
  96. data/TODO.diagrams/47-attribute-line-fidelity.md +72 -0
  97. data/TODO.diagrams/48-spec-coverage-critical-emitter-components.md +45 -0
  98. data/TODO.diagrams/49-spec-coverage-orchestrators.md +25 -0
  99. data/TODO.diagrams/50-examples-parity.md +85 -0
  100. data/TODO.diagrams/51-property-oy-gap-and-remaining-gaps.md +48 -0
  101. data/TODO.diagrams/52-marker-registration-architecture.md +89 -0
  102. data/TODO.diagrams/53-remaining-example-gaps.md +86 -0
  103. data/TODO.diagrams/54-display-name-nested-classes.md +40 -0
  104. data/TODO.diagrams/55-visibility-icon-discriminator.md +58 -0
  105. data/TODO.diagrams/56-package-contents-rendering.md +148 -0
  106. data/TODO.diagrams/57-instance-specification-model.md +100 -0
  107. data/TODO.diagrams/58-domain-model-note-text.md +67 -0
  108. data/TODO.diagrams/59-classes-arrow-discriminator.md +57 -0
  109. data/TODO.diagrams/60-testschema-association-marker.md +40 -0
  110. data/TODO.diagrams/61-legend-block-rendering.md +55 -0
  111. data/TODO.diagrams/61-plateau-parity-gaps.md +59 -0
  112. data/TODO.diagrams/62-ghost-element-rendering.md +56 -0
  113. data/TODO.diagrams/63-qualified-name-wrap.md +36 -0
  114. data/TODO.diagrams/64-property-stereotype-labels.md +22 -0
  115. data/TODO.diagrams/65-path-coordinate-frame.md +62 -0
  116. data/TODO.diagrams/67-path-coordinate-frame.md +62 -0
  117. data/TODO.diagrams/68-inherited-attributes.md +65 -0
  118. data/TODO.diagrams/69-package-anchor-conditional.md +29 -0
  119. data/TODO.diagrams/70-mdg-technology-support.md +68 -0
  120. data/TODO.diagrams/71-off-canvas-parent-ghost.md +45 -0
  121. data/TODO.diagrams/72-basic-attr-divider-paths.md +39 -0
  122. data/TODO.diagrams/73-plateau-polygon-gap.md +69 -0
  123. data/TODO.diagrams/74-plateau-rect-gap.md +22 -0
  124. data/TODO.diagrams/75-plateau-text-gap.md +39 -0
  125. data/TODO.diagrams/76-basic-poly-path-gaps.md +41 -0
  126. data/TODO.diagrams/77-basic-text-overrender.md +40 -0
  127. data/TODO.diagrams/78-headerlines-ocp-refactor.md +65 -0
  128. data/TODO.diagrams/79-architecture-backlog.md +65 -0
  129. data/TODO.diagrams/80-basic-triangle-polygons.md +51 -0
  130. data/TODO.diagrams/81-plateau-path-overrender.md +53 -0
  131. data/TODO.diagrams/82-appearance-canvas-offset.md +54 -0
  132. data/TODO.diagrams/83-3d-diagram-subtitle.md +58 -0
  133. data/TODO.diagrams/84-canvas-offset-mismatches.md +61 -0
  134. data/TODO.diagrams/85-phantom-property-overrender.md +95 -0
  135. data/TODO.diagrams/86-foreign-package-rule.md +62 -0
  136. data/TODO.diagrams/87-internal-tech-encryption.md +80 -0
  137. data/TODO.diagrams/EXAMPLES_STATUS.md +88 -0
  138. data/TODO.diagrams/README.md +69 -0
  139. data/TODO.diagrams/STATUS.md +73 -0
  140. data/TODO.fixup/01-default-grouped-paths.md +34 -0
  141. data/TODO.fixup/02-marker-consolidation-per-connector.md +20 -0
  142. data/TODO.fixup/03-diagram-font-inference.md +28 -0
  143. data/TODO.fixup/04-extract-bounds-calculator.md +25 -0
  144. data/TODO.fixup/05-marker-registry-ocp.md +32 -0
  145. data/TODO.fixup/06-connector-path-bend-routing.md +28 -0
  146. data/TODO.fixup/07-edge-attachment-formula.md +22 -0
  147. data/TODO.fixup/08-visual-diff-harness.md +28 -0
  148. data/TODO.fixup/09-extract-element-compartments.md +34 -0
  149. data/TODO.fixup/10-canvas-width-overshoot-fix.md +20 -0
  150. data/TODO.fixup/11-layer-sequencer-extraction.md +18 -0
  151. data/TODO.fixup/12-path-style-harmony.md +23 -0
  152. data/TODO.fixup/13-datatype-stereotype-fallback.md +28 -0
  153. data/TODO.fixup/14-ea-exe-reverse-engineering-notes.md +56 -0
  154. data/TODO.fixup/15-enumeration-literal-rendering.md +30 -0
  155. data/TODO.fixup/16-operation-compartment-rendering.md +42 -0
  156. data/TODO.fixup/17-path-count-calibration.md +27 -0
  157. data/TODO.fixup/18-polygon-count-calibration.md +32 -0
  158. data/TODO.fixup/19-rect-count-undershoot-investigation.md +40 -0
  159. data/TODO.fixup/20-stereotype-color-from-classifier.md +18 -0
  160. data/TODO.fixup/21-visibility-filter-for-properties.md +24 -0
  161. data/TODO.fixup/22-multiplicity-display-rule-calibration.md +25 -0
  162. data/TODO.fixup/23-diagram-frame-title-element.md +31 -0
  163. data/TODO.fixup/24-note-element-rendering.md +23 -0
  164. data/TODO.fixup/25-ea-exe-disassembly-findings.md +177 -0
  165. data/TODO.fixup/26-svg-renderer-architecture.md +78 -0
  166. data/TODO.fixup/27-svg-element-emitters-disassembly.md +135 -0
  167. data/TODO.fixup/28-geometry-parser-identification.md +57 -0
  168. data/TODO.fixup/29-qea-svg-xmi-triple-comparison.md +185 -0
  169. data/TODO.fixup/30-theme-system-stub.md +46 -0
  170. data/TODO.fixup/31-theme-value-object-registry.md +17 -0
  171. data/TODO.fixup/32-styleex-on-diagram-model.md +22 -0
  172. data/TODO.fixup/33-text-encoding-decimals-rotation.md +29 -0
  173. data/TODO.fixup/34-per-type-fill-via-theme.md +18 -0
  174. data/TODO.fixup/35-stroke-width-per-theme.md +7 -0
  175. data/TODO.fixup/36-qea-rect-coord-normalization.md +24 -0
  176. data/TODO.fixup/37-package-shape-rendering.md +22 -0
  177. data/TODO.fixup/38-note-element-rendering.md +15 -0
  178. data/TODO.fixup/39-styleex-flag-honoring.md +25 -0
  179. data/TODO.fixup/40-connector-dashed-lines.md +15 -0
  180. data/TODO.fixup/41-diagram-frame-showborder-detection.md +23 -0
  181. data/TODO.fixup/42-textrenderer-centralization.md +10 -0
  182. data/TODO.fixup/43-colorresolver-unification.md +24 -0
  183. data/TODO.fixup/44-theme-aware-textrenderer.md +17 -0
  184. data/TODO.fixup/45-theme-aware-fontresolver.md +22 -0
  185. data/TODO.fixup/46-style-parameterized-by-theme.md +21 -0
  186. data/TODO.fixup/47-canvas-frame-inset.md +19 -0
  187. data/TODO.fixup/48-background-rect-format.md +15 -0
  188. data/TODO.fixup/49-all-samples-integration-test.md +17 -0
  189. data/TODO.fixup/50-svg-emitter-architecture-docs.md +33 -0
  190. data/TODO.fixup/51-promote-theme-to-ea-namespace.md +28 -0
  191. data/TODO.fixup/52-theme-definition-integrated-fills.md +26 -0
  192. data/TODO.fixup/53-theme-registry-yaml-loading.md +50 -0
  193. data/TODO.fixup/54-diagram-theme-api.md +50 -0
  194. data/TODO.fixup/55-update-eaemitter-to-ea-theme.md +23 -0
  195. data/TODO.fixup/56-theme-yaml-files.md +65 -0
  196. data/TODO.fixup/57-theme-specs-and-integration.md +27 -0
  197. data/TODO.fixup/58-ea-entry-point-theme-autoload.md +20 -0
  198. data/TODO.fixup/59-thread-theme-through-all-renderers.md +29 -0
  199. data/TODO.fixup/60-cli-theme-option.md +22 -0
  200. data/TODO.fixup/61-theme-validation.md +28 -0
  201. data/TODO.fixup/62-theme-builder-dsl.md +31 -0
  202. data/TODO.fixup/63-theme-integration-rendering-spec.md +24 -0
  203. data/TODO.fixup/64-theme-writeback-styleex.md +21 -0
  204. data/TODO.fixup/65-remove-dead-eaemitter-theme-files.md +30 -0
  205. data/TODO.fixup/66-styleex-writeback.md +22 -0
  206. data/TODO.fixup/67-delete-dead-code.md +28 -0
  207. data/TODO.fixup/68-figure-parity-status.md +82 -0
  208. data/TODO.fixup/69-package-polygon-rendering.md +54 -0
  209. data/TODO.fixup/70-tagged-values-compartment.md +39 -0
  210. data/TODO.fixup/71-auto-detect-theme-from-xmi.md +37 -0
  211. data/TODO.fixup/72-sample-exports-as-regression-specs.md +37 -0
  212. data/TODO.fixup/73-delete-dead-transformations.md +14 -0
  213. data/TODO.fixup/74-delete-dead-diagram-renderers.md +18 -0
  214. data/TODO.fixup/75-visibility-legend-icons.md +23 -0
  215. data/TODO.fixup/76-plateau-text-undershoot.md +27 -0
  216. data/TODO.fixup/77-canvas-frame-margins.md +28 -0
  217. data/TODO.fixup/78-note-element-rendering.md +30 -0
  218. data/TODO.fixup/79-operation-compartment-rendering.md +27 -0
  219. data/TODO.fixup/80-tagged-value-stereotype-visibility.md +37 -0
  220. data/TODO.fixup/81-figure-parity-current-state.md +63 -0
  221. data/config/qea_schema.yml +356 -0
  222. data/config/stereotype_colors.yml +15 -0
  223. data/config/themes/119.yml +98 -0
  224. data/config/themes/default.yml +14 -0
  225. data/examples/exports/20251010_current_plateau_v5/UML_EA.DTD +6856 -0
  226. data/examples/exports/20251010_current_plateau_v5/model.xml +96709 -0
  227. data/examples/exports/ArcGISWorkspace_template/UML_EA.DTD +6856 -0
  228. data/examples/exports/ArcGISWorkspace_template/model.xml +1427 -0
  229. data/examples/exports/UmlModel_template/UML_EA.DTD +6856 -0
  230. data/examples/exports/UmlModel_template/model.xml +23 -0
  231. data/examples/exports/basic/UML_EA.DTD +6856 -0
  232. data/examples/exports/basic/model.xml +8039 -0
  233. data/examples/exports/simple/UML_EA.DTD +6856 -0
  234. data/examples/exports/simple/model.xml +585 -0
  235. data/examples/exports/simple_example/UML_EA.DTD +6856 -0
  236. data/examples/exports/simple_example/model.xml +23 -0
  237. data/examples/exports/test/UML_EA.DTD +6856 -0
  238. data/examples/exports/test/model.xml +1638 -0
  239. data/examples/qea/basic.qea +0 -0
  240. data/frontend/README.md +51 -0
  241. data/frontend/dist/app.iife.js +24 -0
  242. data/frontend/dist/style.css +1 -0
  243. data/frontend/index.html +26 -0
  244. data/frontend/package-lock.json +2359 -0
  245. data/frontend/package.json +26 -0
  246. data/frontend/src/App.vue +59 -0
  247. data/frontend/src/app.ts +8 -0
  248. data/frontend/src/components/AppHeader.vue +127 -0
  249. data/frontend/src/components/AppSidebar.vue +119 -0
  250. data/frontend/src/components/ClassDetails.vue +247 -0
  251. data/frontend/src/components/DiagramView.vue +79 -0
  252. data/frontend/src/components/PackageDetails.vue +92 -0
  253. data/frontend/src/components/PackageTreeNode.vue +64 -0
  254. data/frontend/src/components/SearchResults.vue +48 -0
  255. data/frontend/src/components/WelcomeView.vue +87 -0
  256. data/frontend/src/shims-vue.d.ts +5 -0
  257. data/frontend/src/stores/dataStore.ts +79 -0
  258. data/frontend/src/stores/uiStore.ts +167 -0
  259. data/frontend/src/styles/main.css +1566 -0
  260. data/frontend/src/types.ts +221 -0
  261. data/frontend/tests/e2e/__screenshots__/new-dark-mode.png +0 -0
  262. data/frontend/tests/e2e/__screenshots__/new-package-details.png +0 -0
  263. data/frontend/tests/e2e/__screenshots__/new-search-modal.png +0 -0
  264. data/frontend/tests/e2e/__screenshots__/new-sidebar-collapsed.png +0 -0
  265. data/frontend/tests/e2e/__screenshots__/new-welcome.png +0 -0
  266. data/frontend/tests/e2e/render.spec.ts +188 -0
  267. data/frontend/tsconfig.json +20 -0
  268. data/frontend/vite.config.ts +26 -0
  269. data/frontend/vitest.config.ts +8 -0
  270. data/lib/ea/cli/app.rb +62 -1
  271. data/lib/ea/cli/command/diagrams.rb +37 -28
  272. data/lib/ea/cli/command/diff.rb +46 -0
  273. data/lib/ea/cli/command/export.rb +80 -0
  274. data/lib/ea/cli/command/info.rb +75 -0
  275. data/lib/ea/cli/command/lint.rb +48 -0
  276. data/lib/ea/cli/command/mdg.rb +98 -0
  277. data/lib/ea/cli/command/query.rb +34 -0
  278. data/lib/ea/cli/command/render.rb +135 -0
  279. data/lib/ea/cli/command/svg.rb +43 -6
  280. data/lib/ea/cli/command.rb +7 -0
  281. data/lib/ea/diagram/display_config.rb +184 -0
  282. data/lib/ea/diagram.rb +4 -41
  283. data/lib/ea/diff/change.rb +30 -0
  284. data/lib/ea/diff/comparator.rb +82 -0
  285. data/lib/ea/diff/html_reporter.rb +91 -0
  286. data/lib/ea/diff.rb +15 -0
  287. data/lib/ea/export/json/generator.rb +42 -0
  288. data/lib/ea/export/json.rb +12 -0
  289. data/lib/ea/export/json_schema/generator.rb +77 -0
  290. data/lib/ea/export/json_schema.rb +12 -0
  291. data/lib/ea/export/plantuml/generator.rb +73 -0
  292. data/lib/ea/export/plantuml.rb +12 -0
  293. data/lib/ea/export/xmi/generator.rb +77 -0
  294. data/lib/ea/export/xmi.rb +11 -0
  295. data/lib/ea/export/xsd/class_mapping.rb +65 -0
  296. data/lib/ea/export/xsd/generator.rb +142 -0
  297. data/lib/ea/export/xsd/namespace_registry.rb +82 -0
  298. data/lib/ea/export/xsd.rb +19 -0
  299. data/lib/ea/export.rb +14 -0
  300. data/lib/ea/image/emf_renderer.rb +42 -0
  301. data/lib/ea/image.rb +12 -0
  302. data/lib/ea/lint/engine.rb +30 -0
  303. data/lib/ea/lint/lint_rule.rb +38 -0
  304. data/lib/ea/lint/offense.rb +18 -0
  305. data/lib/ea/lint/rules/cyclic_generalization.rb +62 -0
  306. data/lib/ea/lint/rules/duplicate_name.rb +28 -0
  307. data/lib/ea/lint/rules/missing_stereotype.rb +35 -0
  308. data/lib/ea/lint/rules/naming_convention.rb +44 -0
  309. data/lib/ea/lint/rules/orphan_element.rb +28 -0
  310. data/lib/ea/lint/rules.rb +14 -0
  311. data/lib/ea/lint.rb +13 -0
  312. data/lib/ea/mdg/document.rb +120 -0
  313. data/lib/ea/mdg/loader.rb +118 -0
  314. data/lib/ea/mdg/registry.rb +98 -0
  315. data/lib/ea/mdg/stereotype_alias_registry.rb +77 -0
  316. data/lib/ea/mdg/xml/applies_to.rb +18 -0
  317. data/lib/ea/mdg/xml/apply.rb +18 -0
  318. data/lib/ea/mdg/xml/content.rb +18 -0
  319. data/lib/ea/mdg/xml/documentation.rb +24 -0
  320. data/lib/ea/mdg/xml/stereotype.rb +28 -0
  321. data/lib/ea/mdg/xml/stereotypes.rb +18 -0
  322. data/lib/ea/mdg/xml/tag.rb +28 -0
  323. data/lib/ea/mdg/xml/tagged_values.rb +18 -0
  324. data/lib/ea/mdg/xml/technology.rb +28 -0
  325. data/lib/ea/mdg/xml/uml_profile.rb +22 -0
  326. data/lib/ea/mdg/xml/uml_profiles.rb +18 -0
  327. data/lib/ea/mdg/xml.rb +24 -0
  328. data/lib/ea/mdg.rb +25 -0
  329. data/lib/ea/model/classifier.rb +4 -0
  330. data/lib/ea/model/constraint.rb +24 -0
  331. data/lib/ea/model/diagram.rb +85 -0
  332. data/lib/ea/model/diagram_connector.rb +53 -1
  333. data/lib/ea/model/diagram_element.rb +44 -0
  334. data/lib/ea/model/document.rb +47 -2
  335. data/lib/ea/model/ghost_label.rb +32 -0
  336. data/lib/ea/model/instance_specification.rb +34 -0
  337. data/lib/ea/model/legend.rb +43 -0
  338. data/lib/ea/model/legend_item.rb +26 -0
  339. data/lib/ea/model/note.rb +28 -0
  340. data/lib/ea/model/operation.rb +2 -0
  341. data/lib/ea/model/property.rb +2 -0
  342. data/lib/ea/model/relationship.rb +2 -0
  343. data/lib/ea/model/signal.rb +14 -0
  344. data/lib/ea/model/slot.rb +19 -0
  345. data/lib/ea/model.rb +8 -0
  346. data/lib/ea/ocl/evaluator.rb +94 -0
  347. data/lib/ea/ocl/nodes.rb +30 -0
  348. data/lib/ea/ocl/parser.rb +133 -0
  349. data/lib/ea/ocl/unsupported_error.rb +7 -0
  350. data/lib/ea/ocl.rb +13 -0
  351. data/lib/ea/qea/factory/document_builder.rb +24 -10
  352. data/lib/ea/qea/factory/generalization_builder.rb +9 -11
  353. data/lib/ea/qea/infrastructure/table_reader.rb +9 -0
  354. data/lib/ea/qea/models/ea_author.rb +35 -0
  355. data/lib/ea/qea/models/ea_glossary.rb +34 -0
  356. data/lib/ea/qea/models/ea_image.rb +53 -0
  357. data/lib/ea/qea/models/ea_implement.rb +32 -0
  358. data/lib/ea/qea/models/ea_list.rb +42 -0
  359. data/lib/ea/qea/models/ea_object_effort.rb +34 -0
  360. data/lib/ea/qea/models/ea_object_problem.rb +37 -0
  361. data/lib/ea/qea/models/ea_object_require.rb +34 -0
  362. data/lib/ea/qea/models/ea_object_resource.rb +34 -0
  363. data/lib/ea/qea/models/ea_object_risk.rb +34 -0
  364. data/lib/ea/qea/models/ea_object_scenario.rb +34 -0
  365. data/lib/ea/qea/models/ea_object_test.rb +35 -0
  366. data/lib/ea/qea/models/ea_object_trx.rb +34 -0
  367. data/lib/ea/qea/models/ea_operation.rb +7 -0
  368. data/lib/ea/qea/models/ea_palette.rb +30 -0
  369. data/lib/ea/qea/models/ea_palette_item.rb +36 -0
  370. data/lib/ea/qea/models/ea_phase.rb +40 -0
  371. data/lib/ea/qea/models/ea_role_constraint.rb +32 -0
  372. data/lib/ea/qea/models/ea_secrypt.rb +34 -0
  373. data/lib/ea/qea/models/ea_version.rb +39 -0
  374. data/lib/ea/qea/models/ea_xref.rb +11 -1
  375. data/lib/ea/qea/models.rb +19 -0
  376. data/lib/ea/qea/services/database_loader.rb +22 -1
  377. data/lib/ea/query/builder.rb +108 -0
  378. data/lib/ea/query.rb +9 -0
  379. data/lib/ea/render/image_converter.rb +101 -0
  380. data/lib/ea/render.rb +10 -0
  381. data/lib/ea/shapescript/parser.rb +208 -0
  382. data/lib/ea/shapescript/renderer.rb +74 -0
  383. data/lib/ea/shapescript/shape.rb +34 -0
  384. data/lib/ea/shapescript.rb +24 -0
  385. data/lib/ea/sources/qea/adapter.rb +22 -5
  386. data/lib/ea/sources/qea/classifier_builder.rb +184 -7
  387. data/lib/ea/sources/qea/diagram_builder.rb +352 -24
  388. data/lib/ea/sources/qea/id_normalizer.rb +16 -1
  389. data/lib/ea/sources/qea/instance_builder.rb +113 -0
  390. data/lib/ea/sources/qea/legend_builder.rb +137 -0
  391. data/lib/ea/sources/qea/note_builder.rb +58 -0
  392. data/lib/ea/sources/qea/object_classifier_map.rb +6 -1
  393. data/lib/ea/sources/qea/operation_builder.rb +1 -0
  394. data/lib/ea/sources/qea/package_builder.rb +16 -0
  395. data/lib/ea/sources/qea/relationship_builder.rb +21 -5
  396. data/lib/ea/sources/qea/tagged_value_builder.rb +28 -9
  397. data/lib/ea/sources/qea/xref/legend_definition.rb +35 -0
  398. data/lib/ea/sources/qea/xref/parser.rb +150 -0
  399. data/lib/ea/sources/qea/xref/property_definition.rb +29 -0
  400. data/lib/ea/sources/qea/xref/record.rb +41 -0
  401. data/lib/ea/sources/qea/xref/stereotype_application.rb +37 -0
  402. data/lib/ea/sources/qea/xref.rb +27 -0
  403. data/lib/ea/sources/qea.rb +4 -0
  404. data/lib/ea/sources/xmi/adapter.rb +80 -2
  405. data/lib/ea/sources/xmi/annotation_builder.rb +1 -1
  406. data/lib/ea/sources/xmi/classifier_builder.rb +10 -1
  407. data/lib/ea/sources/xmi/diagram_builder.rb +242 -45
  408. data/lib/ea/sources/xmi/extension_elements.rb +74 -0
  409. data/lib/ea/sources/xmi/extension_geometry_parser.rb +124 -0
  410. data/lib/ea/sources/xmi/extension_style_parser.rb +91 -0
  411. data/lib/ea/sources/xmi/note_builder.rb +46 -0
  412. data/lib/ea/sources/xmi/property_builder.rb +9 -0
  413. data/lib/ea/sources/xmi/stereotype_builder.rb +54 -0
  414. data/lib/ea/sources/xmi/tag_builder.rb +45 -0
  415. data/lib/ea/sources/xmi/umldi_keyword_extractor.rb +87 -0
  416. data/lib/ea/sources/xmi.rb +7 -0
  417. data/lib/ea/spa/output/sharded_multi_file_strategy.rb +18 -3
  418. data/lib/ea/spa/output/single_file_strategy.rb +8 -2
  419. data/lib/ea/spa/output/strategy.rb +34 -0
  420. data/lib/ea/svg/connector_router.rb +134 -0
  421. data/lib/ea/svg/ea_emitter/background.rb +15 -0
  422. data/lib/ea/svg/ea_emitter/bounds_calculator.rb +142 -0
  423. data/lib/ea/svg/ea_emitter/canvas.rb +88 -0
  424. data/lib/ea/svg/ea_emitter/color_resolver.rb +56 -0
  425. data/lib/ea/svg/ea_emitter/compartment/attributes.rb +28 -0
  426. data/lib/ea/svg/ea_emitter/compartment/constraints.rb +30 -0
  427. data/lib/ea/svg/ea_emitter/compartment/enum_literals.rb +86 -0
  428. data/lib/ea/svg/ea_emitter/compartment/header.rb +32 -0
  429. data/lib/ea/svg/ea_emitter/compartment/header_divider.rb +57 -0
  430. data/lib/ea/svg/ea_emitter/compartment/instance_slots.rb +96 -0
  431. data/lib/ea/svg/ea_emitter/compartment/instance_underline.rb +67 -0
  432. data/lib/ea/svg/ea_emitter/compartment/note_body.rb +52 -0
  433. data/lib/ea/svg/ea_emitter/compartment/note_text.rb +102 -0
  434. data/lib/ea/svg/ea_emitter/compartment/operations.rb +38 -0
  435. data/lib/ea/svg/ea_emitter/compartment/package_contents.rb +72 -0
  436. data/lib/ea/svg/ea_emitter/compartment/package_from_parent.rb +136 -0
  437. data/lib/ea/svg/ea_emitter/compartment/shape.rb +82 -0
  438. data/lib/ea/svg/ea_emitter/compartment/tagged_values.rb +30 -0
  439. data/lib/ea/svg/ea_emitter/compartment.rb +58 -0
  440. data/lib/ea/svg/ea_emitter/connectors.rb +84 -0
  441. data/lib/ea/svg/ea_emitter/diagram_frame.rb +143 -0
  442. data/lib/ea/svg/ea_emitter/document.rb +35 -0
  443. data/lib/ea/svg/ea_emitter/element/attribute_line_builder.rb +117 -0
  444. data/lib/ea/svg/ea_emitter/element/attribute_renderer.rb +119 -0
  445. data/lib/ea/svg/ea_emitter/element/bcol_decoder.rb +29 -0
  446. data/lib/ea/svg/ea_emitter/element/compartment_geometry.rb +113 -0
  447. data/lib/ea/svg/ea_emitter/element/constraint_renderer.rb +53 -0
  448. data/lib/ea/svg/ea_emitter/element/divider_renderer.rb +17 -0
  449. data/lib/ea/svg/ea_emitter/element/enumeration_literal_renderer.rb +34 -0
  450. data/lib/ea/svg/ea_emitter/element/filter.rb +44 -0
  451. data/lib/ea/svg/ea_emitter/element/hand_draw_shape_renderer.rb +77 -0
  452. data/lib/ea/svg/ea_emitter/element/header_line_pipeline.rb +43 -0
  453. data/lib/ea/svg/ea_emitter/element/header_line_provider/instance_spec.rb +27 -0
  454. data/lib/ea/svg/ea_emitter/element/header_line_provider/name.rb +76 -0
  455. data/lib/ea/svg/ea_emitter/element/header_line_provider/parent_ghost.rb +25 -0
  456. data/lib/ea/svg/ea_emitter/element/header_line_provider/stereotype_label.rb +68 -0
  457. data/lib/ea/svg/ea_emitter/element/header_line_provider.rb +19 -0
  458. data/lib/ea/svg/ea_emitter/element/header_lines.rb +27 -0
  459. data/lib/ea/svg/ea_emitter/element/header_renderer.rb +48 -0
  460. data/lib/ea/svg/ea_emitter/element/icon_renderer.rb +109 -0
  461. data/lib/ea/svg/ea_emitter/element/legend_renderer.rb +177 -0
  462. data/lib/ea/svg/ea_emitter/element/note_shape_renderer.rb +112 -0
  463. data/lib/ea/svg/ea_emitter/element/operation_renderer.rb +100 -0
  464. data/lib/ea/svg/ea_emitter/element/package_shape_renderer.rb +181 -0
  465. data/lib/ea/svg/ea_emitter/element/row_icon_renderer.rb +156 -0
  466. data/lib/ea/svg/ea_emitter/element/shape_renderer.rb +17 -0
  467. data/lib/ea/svg/ea_emitter/element/stereotype_icon_renderer.rb +82 -0
  468. data/lib/ea/svg/ea_emitter/element/tagged_value_renderer.rb +50 -0
  469. data/lib/ea/svg/ea_emitter/element/text_escape.rb +20 -0
  470. data/lib/ea/svg/ea_emitter/element.rb +37 -0
  471. data/lib/ea/svg/ea_emitter/elements.rb +357 -0
  472. data/lib/ea/svg/ea_emitter/font_resolver.rb +111 -0
  473. data/lib/ea/svg/ea_emitter/ghost_labels.rb +66 -0
  474. data/lib/ea/svg/ea_emitter/label/end_label.rb +266 -0
  475. data/lib/ea/svg/ea_emitter/label/midpoint_label.rb +101 -0
  476. data/lib/ea/svg/ea_emitter/label/registry.rb +50 -0
  477. data/lib/ea/svg/ea_emitter/label.rb +23 -0
  478. data/lib/ea/svg/ea_emitter/labels.rb +130 -0
  479. data/lib/ea/svg/ea_emitter/layer.rb +20 -0
  480. data/lib/ea/svg/ea_emitter/layer_sequencer.rb +93 -0
  481. data/lib/ea/svg/ea_emitter/marker/arrow_path.rb +52 -0
  482. data/lib/ea/svg/ea_emitter/marker/diamond.rb +57 -0
  483. data/lib/ea/svg/ea_emitter/marker/kind.rb +35 -0
  484. data/lib/ea/svg/ea_emitter/marker/open_triangle.rb +27 -0
  485. data/lib/ea/svg/ea_emitter/marker/package_import.rb +39 -0
  486. data/lib/ea/svg/ea_emitter/marker/plus.rb +40 -0
  487. data/lib/ea/svg/ea_emitter/marker/registry.rb +42 -0
  488. data/lib/ea/svg/ea_emitter/marker.rb +37 -0
  489. data/lib/ea/svg/ea_emitter/markers.rb +404 -0
  490. data/lib/ea/svg/ea_emitter/render_context.rb +52 -0
  491. data/lib/ea/svg/ea_emitter/style.rb +15 -0
  492. data/lib/ea/svg/ea_emitter/text_renderer.rb +92 -0
  493. data/lib/ea/svg/ea_emitter.rb +51 -0
  494. data/lib/ea/svg/parity/checker.rb +105 -0
  495. data/lib/ea/svg/parity/source.rb +59 -0
  496. data/lib/ea/svg/parity/suite.rb +113 -0
  497. data/lib/ea/svg/parity.rb +14 -0
  498. data/lib/ea/svg/stereotype_color_resolver.rb +50 -0
  499. data/lib/ea/svg.rb +4 -15
  500. data/lib/ea/theme/definition.rb +176 -0
  501. data/lib/ea/theme/loader.rb +125 -0
  502. data/lib/ea/theme/registry.rb +96 -0
  503. data/lib/ea/theme.rb +37 -0
  504. data/lib/ea/transformations.rb +5 -88
  505. data/lib/ea/version.rb +4 -1
  506. data/lib/ea.rb +14 -4
  507. data/lib/tasks/svg_bench.rake +87 -0
  508. data/lutaml-uml-0.5.1.gem +0 -0
  509. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes-list.png +0 -0
  510. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes.png +0 -0
  511. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-2-gradients.png +0 -0
  512. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-3-colors.png +0 -0
  513. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance-fonts.png +0 -0
  514. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance.png +0 -0
  515. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-5-behavior.png +0 -0
  516. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-6-sequence.png +0 -0
  517. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram.png +0 -0
  518. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-2-objects.png +0 -0
  519. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-3-links.png +0 -0
  520. metadata +473 -26
  521. data/lib/ea/diagram/configuration.rb +0 -379
  522. data/lib/ea/diagram/element_renderers/base_renderer.rb +0 -77
  523. data/lib/ea/diagram/element_renderers/class_renderer.rb +0 -323
  524. data/lib/ea/diagram/element_renderers/connector_renderer.rb +0 -41
  525. data/lib/ea/diagram/element_renderers/package_renderer.rb +0 -61
  526. data/lib/ea/diagram/element_renderers.rb +0 -43
  527. data/lib/ea/diagram/extractor.rb +0 -566
  528. data/lib/ea/diagram/layout_engine.rb +0 -170
  529. data/lib/ea/diagram/path_builder.rb +0 -202
  530. data/lib/ea/diagram/style_parser.rb +0 -42
  531. data/lib/ea/diagram/style_resolver.rb +0 -291
  532. data/lib/ea/diagram/svg_renderer.rb +0 -274
  533. data/lib/ea/diagram/util.rb +0 -73
  534. data/lib/ea/svg/bounds_calculator.rb +0 -74
  535. data/lib/ea/svg/connector_path.rb +0 -138
  536. data/lib/ea/svg/element_box.rb +0 -256
  537. data/lib/ea/svg/renderer.rb +0 -77
  538. data/lib/ea/svg/style_resolver.rb +0 -72
  539. data/lib/ea/transformations/configuration.rb +0 -333
  540. data/lib/ea/transformations/format_registry.rb +0 -366
  541. data/lib/ea/transformations/parsers/base_parser.rb +0 -482
  542. data/lib/ea/transformations/parsers/qea_parser.rb +0 -401
  543. data/lib/ea/transformations/parsers/xmi_parser.rb +0 -243
  544. data/lib/ea/transformations/transformation_engine.rb +0 -390
@@ -0,0 +1,28 @@
1
+ # frozen_string: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Ea
6
+ module Mdg
7
+ module Xml
8
+ class Technology < Lutaml::Model::Serializable
9
+ attribute :version, :string
10
+ attribute :documentation, Documentation
11
+ attribute :uml_profiles, UmlProfiles
12
+ # Some MDG files place additional <UMLProfile> elements
13
+ # as direct children of <MDG.Technology> alongside
14
+ # <UMLProfiles>, not inside it.
15
+ attribute :standalone_profiles, UmlProfile, collection: true,
16
+ initialize_empty: true
17
+
18
+ xml do
19
+ root "MDG.Technology"
20
+ map_attribute "version", to: :version
21
+ map_element "Documentation", to: :documentation
22
+ map_element "UMLProfiles", to: :uml_profiles
23
+ map_element "UMLProfile", to: :standalone_profiles
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Ea
6
+ module Mdg
7
+ module Xml
8
+ class UmlProfile < Lutaml::Model::Serializable
9
+ attribute :profiletype, :string
10
+ attribute :documentation, Documentation
11
+ attribute :content, Content
12
+
13
+ xml do
14
+ root "UMLProfile"
15
+ map_attribute "profiletype", to: :profiletype
16
+ map_element "Documentation", to: :documentation
17
+ map_element "Content", to: :content
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Ea
6
+ module Mdg
7
+ module Xml
8
+ class UmlProfiles < Lutaml::Model::Serializable
9
+ attribute :profiles, UmlProfile, collection: true, initialize_empty: true
10
+
11
+ xml do
12
+ root "UMLProfiles"
13
+ map_element "UMLProfile", to: :profiles
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/ea/mdg/xml.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Ea
6
+ module Mdg
7
+ # lutaml-model classes for the EA MDG.Technology XML format.
8
+ # These are the deserialization models — use `from_xml` on
9
+ # MdgTechnology to parse an MDG.Technology file.
10
+ module Xml
11
+ autoload :Technology, "ea/mdg/xml/technology"
12
+ autoload :Documentation, "ea/mdg/xml/documentation"
13
+ autoload :UmlProfiles, "ea/mdg/xml/uml_profiles"
14
+ autoload :UmlProfile, "ea/mdg/xml/uml_profile"
15
+ autoload :Content, "ea/mdg/xml/content"
16
+ autoload :Stereotypes, "ea/mdg/xml/stereotypes"
17
+ autoload :Stereotype, "ea/mdg/xml/stereotype"
18
+ autoload :TaggedValues, "ea/mdg/xml/tagged_values"
19
+ autoload :Tag, "ea/mdg/xml/tag"
20
+ autoload :AppliesTo, "ea/mdg/xml/applies_to"
21
+ autoload :Apply, "ea/mdg/xml/apply"
22
+ end
23
+ end
24
+ end
data/lib/ea/mdg.rb ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Ea
6
+ # MDG (Model Driven Generation) Technology support.
7
+ #
8
+ # EA's MDG technologies bundle UML profiles, reference models,
9
+ # and toolbox definitions in a single XMI file. When EA loads
10
+ # an MDG, the MDG's classes/attributes/stereotypes become
11
+ # available to all models — including inherited attribute
12
+ # rendering when a classifier's stereotype maps to an MDG-
13
+ # defined metaclass.
14
+ #
15
+ # This namespace is standalone: it does not depend on QEA or
16
+ # XMI source adapters. Source adapters OPTIONALLY consume an
17
+ # Mdg::Registry to merge MDG-defined inherited attributes.
18
+ module Mdg
19
+ autoload :Document, "ea/mdg/document"
20
+ autoload :Loader, "ea/mdg/loader"
21
+ autoload :Registry, "ea/mdg/registry"
22
+ autoload :StereotypeAliasRegistry, "ea/mdg/stereotype_alias_registry"
23
+ autoload :Xml, "ea/mdg/xml"
24
+ end
25
+ end
@@ -13,6 +13,7 @@ module Ea
13
13
  class Classifier < Base
14
14
  attribute :qualified_name, :string
15
15
  attribute :package_id, :string # containing package
16
+ attribute :package_name, :string # containing package name
16
17
  attribute :is_abstract, :boolean, default: false
17
18
  attribute :visibility, :string
18
19
  attribute :model_kind, :string, default: -> { "classifier" }
@@ -20,6 +21,7 @@ module Ea
20
21
  attribute :operations, Operation, collection: true, initialize_empty: true
21
22
  attribute :stereotype_refs, :string, collection: true, initialize_empty: true
22
23
  attribute :tagged_values, TaggedValue, collection: true, initialize_empty: true
24
+ attribute :constraints, Constraint, collection: true, initialize_empty: true
23
25
  attribute :annotations, Annotation, collection: true, initialize_empty: true
24
26
 
25
27
  json do
@@ -27,6 +29,7 @@ module Ea
27
29
  map "name", to: :name
28
30
  map "qualifiedName", to: :qualified_name
29
31
  map "packageId", to: :package_id
32
+ map "packageName", to: :package_name
30
33
  map "isAbstract", to: :is_abstract, render_default: true
31
34
  map "visibility", to: :visibility
32
35
  map "modelKind", to: :model_kind, render_default: true
@@ -34,6 +37,7 @@ module Ea
34
37
  map "operations", to: :operations, render_empty: true
35
38
  map "stereotypeRefs", to: :stereotype_refs, render_empty: true
36
39
  map "taggedValues", to: :tagged_values, render_empty: true
40
+ map "constraints", to: :constraints, render_empty: true
37
41
  map "annotations", to: :annotations, render_empty: true
38
42
  end
39
43
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ea
4
+ module Model
5
+ # A UML/OCL constraint attached to a classifier or other model
6
+ # element. EA stores these in t_objectconstraint; the `name` is
7
+ # the constraint label (rendered as "{name}" in the constraints
8
+ # compartment), and the body holds the OCL expression.
9
+ class Constraint < Base
10
+ attribute :name, :string
11
+ attribute :kind, :string # "OCL", "Invariant", "Postcondition", etc.
12
+ attribute :body, :string
13
+ attribute :status, :string
14
+
15
+ json do
16
+ map "id", to: :id
17
+ map "name", to: :name
18
+ map "kind", to: :kind
19
+ map "body", to: :body
20
+ map "status", to: :status
21
+ end
22
+ end
23
+ end
24
+ end
@@ -9,6 +9,13 @@ module Ea
9
9
  attribute :package_id, :string
10
10
  attribute :diagram_type, :string # logical|class|sequence|use_case|...
11
11
  attribute :bounds, Bounds # canvas size
12
+ attribute :style, :string # raw t_diagram.Style (HideAtts=1;HideOps=0;...)
13
+ attribute :style_ex, :string # raw t_diagram.StyleEx (Theme=:NNN;SuppressFOC=1;...)
14
+ attribute :theme_override_id, :string # set by theme= when given an ID
15
+ attribute :show_package_contents, :boolean, default: false
16
+ attribute :hand_draw, :boolean, default: false
17
+ attribute :show_notes, :boolean, default: false
18
+ attribute :show_parents, :boolean, default: true
12
19
  attribute :elements, DiagramElement, collection: true, initialize_empty: true
13
20
  attribute :connectors, DiagramConnector, collection: true, initialize_empty: true
14
21
  attribute :annotations, Annotation, collection: true, initialize_empty: true
@@ -19,10 +26,88 @@ module Ea
19
26
  map "packageId", to: :package_id
20
27
  map "diagramType", to: :diagram_type
21
28
  map "bounds", to: :bounds
29
+ map "style", to: :style
30
+ map "styleEx", to: :style_ex
31
+ map "themeOverrideId", to: :theme_override_id
32
+ map "showPackageContents", to: :show_package_contents
33
+ map "handDraw", to: :hand_draw
34
+ map "showNotes", to: :show_notes
35
+ map "showParents", to: :show_parents
22
36
  map "elements", to: :elements, render_empty: true
23
37
  map "connectors", to: :connectors, render_empty: true
24
38
  map "annotations", to: :annotations, render_empty: true
25
39
  end
40
+
41
+ # Parses style_ex into a Hash of flag => value. Returns empty
42
+ # Hash when style_ex is nil/empty.
43
+ #
44
+ # Example: "Theme=:119;SuppressFOC=1;AttPkg=1" →
45
+ # { "Theme" => ":119", "SuppressFOC" => "1", "AttPkg" => "1" }
46
+ def style_ex_flags
47
+ return {} if style_ex.nil? || style_ex.empty?
48
+
49
+ style_ex.split(";").filter_map do |pair|
50
+ next nil unless pair.include?("=")
51
+
52
+ key, value = pair.split("=", 2)
53
+ [key, value.to_s] if key && !key.empty?
54
+ end.to_h
55
+ end
56
+
57
+ # Returns the effective theme ID. Resolved from (in order):
58
+ # 1. theme_override_id (set by theme=)
59
+ # 2. style_ex_flags["Theme"]
60
+ #
61
+ # @return [String, nil]
62
+ def theme_id
63
+ theme_override_id || style_ex_flags["Theme"]
64
+ end
65
+
66
+ # Returns the resolved Theme Definition. Looks up from the
67
+ # Registry by theme_id, falling back to default.
68
+ #
69
+ # @return [Ea::Theme::Definition]
70
+ def theme
71
+ Ea::Theme::Registry.lookup(theme_id)
72
+ end
73
+
74
+ # Returns the DisplayConfig parsed from style + style_ex.
75
+ # Controls behavioral rendering flags (HideAtts, HideOps,
76
+ # SuppressFOC, AttPub, ShowNotes, etc.).
77
+ #
78
+ # @return [Ea::Diagram::DisplayConfig]
79
+ def display_config
80
+ Ea::Diagram::DisplayConfig.from_style(style:, style_ex:)
81
+ end
82
+
83
+ # Set the diagram's theme. Accepts:
84
+ #
85
+ # diagram.theme = :119 # by Symbol ID
86
+ # diagram.theme = ":119" # by String ID
87
+ # diagram.theme = "119" # by String ID (no colon)
88
+ # diagram.theme = definition # by Definition object
89
+ #
90
+ # When given an ID, sets theme_override_id. When given a
91
+ # Definition, registers it in the Registry and stores its ID.
92
+ #
93
+ # @param value [Symbol, String, Ea::Theme::Definition]
94
+ def theme=(value)
95
+ case value
96
+ when Ea::Theme::Definition
97
+ Ea::Theme::Registry.register(value)
98
+ @theme_override_id = value.id
99
+ else
100
+ @theme_override_id = normalize_theme_id(value)
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ def normalize_theme_id(value)
107
+ return nil if value.nil?
108
+
109
+ value.to_s.gsub(/^:/, "")
110
+ end
26
111
  end
27
112
  end
28
113
  end
@@ -5,15 +5,33 @@ module Ea
5
5
  # A connector drawn on a diagram between two DiagramElements.
6
6
  # References the underlying Relationship (by id) and the source
7
7
  # and target DiagramElements (by id). Carries ordered waypoints
8
- # for routing.
8
+ # for routing plus the EA EDGE codes (1=top, 2=right, 3=bottom,
9
+ # 4=left, 5..8=diagonal variants) which tell the renderer where
10
+ # to anchor the line on each end.
9
11
  class DiagramConnector < Base
10
12
  attribute :diagram_id, :string
11
13
  attribute :relationship_ref, :string
12
14
  attribute :source_element_ref, :string
13
15
  attribute :target_element_ref, :string
16
+ attribute :source_duid, :string
17
+ attribute :target_duid, :string
18
+ attribute :source_edge, :integer
19
+ attribute :target_edge, :integer
20
+ attribute :connector_type, :string
21
+ attribute :direction, :string
14
22
  attribute :waypoints, Waypoint, collection: true, initialize_empty: true
15
23
  attribute :label, :string
16
24
  attribute :style, :hash, default: -> { {} }
25
+ attribute :line_color, :integer
26
+ attribute :line_width, :integer
27
+ attribute :hidden, :boolean
28
+ attribute :label_boxes, :hash, default: -> { {} }
29
+ attribute :ghost_labels, GhostLabel, collection: true, initialize_empty: true
30
+ # True when the t_diagramlinks.Geometry string carries explicit
31
+ # SX/SY/EX/EY offset fields. EA renders the «import» package_anchor
32
+ # marker only for connectors with explicit offsets — auto-routed
33
+ # connectors (no SX/SY) get a plain solid line.
34
+ attribute :has_geometry_offsets, :boolean, default: false
17
35
 
18
36
  json do
19
37
  map "id", to: :id
@@ -21,9 +39,43 @@ module Ea
21
39
  map "relationshipRef", to: :relationship_ref
22
40
  map "sourceElementRef", to: :source_element_ref
23
41
  map "targetElementRef", to: :target_element_ref
42
+ map "sourceDuid", to: :source_duid
43
+ map "targetDuid", to: :target_duid
44
+ map "sourceEdge", to: :source_edge
45
+ map "targetEdge", to: :target_edge
46
+ map "connectorType", to: :connector_type
47
+ map "direction", to: :direction
24
48
  map "waypoints", to: :waypoints, render_empty: true
25
49
  map "label", to: :label
26
50
  map "style", to: :style
51
+ map "lineColor", to: :line_color
52
+ map "lineWidth", to: :line_width
53
+ map "hidden", to: :hidden, render_default: true
54
+ map "labelBoxes", to: :label_boxes
55
+ map "ghostLabels", to: :ghost_labels, render_empty: true
56
+ map "hasGeometryOffsets", to: :has_geometry_offsets, render_default: true
57
+ end
58
+
59
+ # EA encodes package nesting and other implicit relationships
60
+ # as connector rows in t_diagramlinks. These are typically
61
+ # not rendered as paths in the SVG output — the containment
62
+ # is implied by visual position. However, when a connector
63
+ # has the `tree` style attribute (e.g. "V" for vertical tree
64
+ # routing), EA renders it as a real visible connector with
65
+ # a "+" marker at the contained end.
66
+ IMPLICIT_TYPES = %w[Nesting].freeze
67
+
68
+ # True when this connector should appear in SVG output. False
69
+ # when hidden via the Hidden flag. Implicit-type connectors
70
+ # (e.g. Nesting) are filtered out UNLESS they carry a `tree`
71
+ # style attribute marking them as visible (basic.qea's
72
+ # "Package Contents" diagram has visible nesting; simple.qea's
73
+ # "Package Contents" diagram has invisible implicit nesting).
74
+ def renderable?
75
+ return false if hidden
76
+ return true unless IMPLICIT_TYPES.include?(connector_type.to_s)
77
+
78
+ (style || {}).key?(:tree) || (style || {}).key?("tree")
27
79
  end
28
80
  end
29
81
  end
@@ -5,18 +5,62 @@ module Ea
5
5
  # A single placed element on a diagram. References the model
6
6
  # element it visualizes (by id), carries pixel bounds and a
7
7
  # parsed style map (fill color, line color, font, etc.).
8
+ #
9
+ # Carries two distinct bounds:
10
+ # - `bounds` — logical rect (EA's Left/Top/Right/Bottom)
11
+ # - `image_bounds` — visual rect including padding (EA's
12
+ # imgL/imgT/imgR/imgB); used by EA's SVG renderer for the
13
+ # actual `<rect>` width/height
8
14
  class DiagramElement < Base
9
15
  attribute :diagram_id, :string
10
16
  attribute :model_element_ref, :string # id of Classifier/Package/etc.
11
17
  attribute :bounds, Bounds
18
+ attribute :image_bounds, Bounds
12
19
  attribute :style, :hash, default: -> { {} } # parsed style fields
20
+ attribute :background_color, :integer # EA BGR integer
21
+ attribute :line_color, :integer
22
+ attribute :line_width, :integer
23
+ attribute :font_family, :string
24
+ attribute :font_size, :integer
25
+ attribute :font_bold, :boolean
26
+ attribute :font_italic, :boolean
27
+ attribute :font_underline, :boolean
28
+ attribute :show_tagged_values, :boolean
29
+ # EA's per-element "HideIcon" flag — tri-state:
30
+ # "shown" → HideIcon=0, render the type icon
31
+ # "hidden" → HideIcon=1, suppress the type icon
32
+ # nil → not set in source; renderer applies the
33
+ # diagram default (typically hidden).
34
+ attribute :icon_visibility, :string
35
+ attribute :z_order, :integer # seqno
36
+ attribute :duid, :string # EA's per-placement DUID for connector resolution
37
+ # UMLDI keyword text EA emitted for this shape (e.g. "Type",
38
+ # "FeatureType"). When present, this is the authoritative
39
+ # label EA rendered in the SVG header — the source XMI is
40
+ # canonical. Falls back to the classifier's stereotype when
41
+ # absent (basic.qea has no UMLDI metadata).
42
+ attribute :umldi_keyword, :string
13
43
 
14
44
  json do
15
45
  map "id", to: :id
16
46
  map "diagramId", to: :diagram_id
17
47
  map "modelElementRef", to: :model_element_ref
18
48
  map "bounds", to: :bounds
49
+ map "imageBounds", to: :image_bounds
19
50
  map "style", to: :style
51
+ map "backgroundColor", to: :background_color
52
+ map "lineColor", to: :line_color
53
+ map "lineWidth", to: :line_width
54
+ map "fontFamily", to: :font_family
55
+ map "fontSize", to: :font_size
56
+ map "fontBold", to: :font_bold, render_default: true
57
+ map "fontItalic", to: :font_italic, render_default: true
58
+ map "fontUnderline", to: :font_underline, render_default: true
59
+ map "showTaggedValues", to: :show_tagged_values, render_default: true
60
+ map "iconVisibility", to: :icon_visibility
61
+ map "zOrder", to: :z_order
62
+ map "duid", to: :duid
63
+ map "umldiKeyword", to: :umldi_keyword
20
64
  end
21
65
  end
22
66
  end
@@ -13,7 +13,8 @@ module Ea
13
13
  "data_type" => "Ea::Model::DataType",
14
14
  "primitive_type" => "Ea::Model::PrimitiveType",
15
15
  "enumeration" => "Ea::Model::Enumeration",
16
- "interface" => "Ea::Model::Interface"
16
+ "interface" => "Ea::Model::Interface",
17
+ "signal" => "Ea::Model::Signal"
17
18
  }
18
19
  }.freeze
19
20
 
@@ -43,18 +44,31 @@ module Ea
43
44
  attribute :relationships, Relationship, collection: true, initialize_empty: true,
44
45
  polymorphic: RELATIONSHIP_POLYMORPHIC_MAP
45
46
  attribute :stereotypes, Stereotype, collection: true, initialize_empty: true
47
+ attribute :notes, Note, collection: true, initialize_empty: true
48
+ attribute :instance_specifications, InstanceSpecification, collection: true,
49
+ initialize_empty: true
46
50
  attribute :diagrams, Diagram, collection: true, initialize_empty: true
47
51
 
48
52
  # Flat lookup indexes, built lazily by consumers. Not
49
53
  # serialized — they're derived from the element collections.
54
+ #
55
+ # EA XMI stores packages with `EAPK_<guid>` ids inside the
56
+ # uml:Model hierarchy, but diagram element `subject=` refs use
57
+ # `EAID_<guid>`. We alias packages under both prefixes so
58
+ # `model_element_ref` lookups from diagram elements resolve.
50
59
  def index_by_id
51
60
  @index_by_id ||= begin
52
61
  idx = {}
53
- packages.each { |p| idx[p.id] = p }
62
+ packages.each do |p|
63
+ idx[p.id] = p
64
+ alias_eaid_for_package(idx, p)
65
+ end
54
66
  classifiers.each { |c| idx[c.id] = c }
55
67
  relationships.each { |r| idx[r.id] = r }
56
68
  stereotypes.each { |s| idx[s.id] = s }
69
+ instance_specifications.each { |i| idx[i.id] = i }
57
70
  diagrams.each { |d| idx[d.id] = d }
71
+ notes.each { |n| idx[n.id] = n }
58
72
  diagrams.each do |d|
59
73
  d.elements.each { |e| idx[e.id] = e }
60
74
  d.connectors.each { |c| idx[c.id] = c }
@@ -63,6 +77,33 @@ module Ea
63
77
  end
64
78
  end
65
79
 
80
+ # Flat lookup of Properties by id across all classifiers. Built
81
+ # lazily; not serialized. Used by connector label rendering to
82
+ # resolve association-end properties in O(1) rather than
83
+ # walking every classifier's property list per lookup.
84
+ def property_index
85
+ @property_index ||= begin
86
+ idx = {}
87
+ classifiers.each do |cls|
88
+ (cls.properties || []).each { |p| idx[p.id] = p }
89
+ end
90
+ idx
91
+ end
92
+ end
93
+
94
+ # O(1) Property lookup by id. Returns nil when not found.
95
+ def property_by_id(id)
96
+ return nil unless id
97
+
98
+ property_index[id]
99
+ end
100
+
101
+ def alias_eaid_for_package(idx, package)
102
+ return unless package.id&.start_with?("EAPK_")
103
+
104
+ idx["EAID_#{package.id[5..]}"] = package
105
+ end
106
+
66
107
  def root_packages
67
108
  packages.select { |p| p.parent_id.nil? }
68
109
  end
@@ -90,6 +131,7 @@ module Ea
90
131
 
91
132
  def reset_indexes
92
133
  @index_by_id = nil
134
+ @property_index = nil
93
135
  end
94
136
 
95
137
  json do
@@ -100,6 +142,9 @@ module Ea
100
142
  map "relationships", to: :relationships, render_empty: true,
101
143
  polymorphic: RELATIONSHIP_POLYMORPHIC_MAP
102
144
  map "stereotypes", to: :stereotypes, render_empty: true
145
+ map "notes", to: :notes, render_empty: true
146
+ map "instanceSpecifications", to: :instance_specifications,
147
+ render_empty: true
103
148
  map "diagrams", to: :diagrams, render_empty: true
104
149
  end
105
150
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string: true
2
+
3
+ module Ea
4
+ module Model
5
+ # A "ghost" classifier name rendered near a connector endpoint
6
+ # that references a classifier NOT placed on the current diagram.
7
+ # EA shows the name as italic text at the connector's off-canvas
8
+ # end so the reader knows what the connector attaches to.
9
+ #
10
+ # Carries:
11
+ # - name: the classifier's display name (simple or qualified)
12
+ # - end_kind: :source or :target (which end is ghost)
13
+ # - anchor: [x, y] canvas-space coordinates of the label
14
+ #
15
+ # Multiple connectors can reference the same ghost classifier;
16
+ # each produces its own GhostLabel at its own anchor.
17
+ class GhostLabel < Base
18
+ attribute :name, :string
19
+ attribute :end_kind, :string
20
+ attribute :anchor_x, :integer
21
+ attribute :anchor_y, :integer
22
+
23
+ json do
24
+ map "id", to: :id
25
+ map "name", to: :name
26
+ map "endKind", to: :end_kind
27
+ map "anchorX", to: :anchor_x
28
+ map "anchorY", to: :anchor_y
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ea
4
+ module Model
5
+ # A UML InstanceSpecification — an instance of a Classifier shown
6
+ # on an Object diagram. Carries a name, a reference to the
7
+ # classifier it instantiates, and a list of Slots (variable =
8
+ # value pairs parsed from EA's RunState field).
9
+ class InstanceSpecification < Base
10
+ attribute :name, :string
11
+ attribute :classifier_id, :string
12
+ attribute :classifier_name, :string
13
+ attribute :package_id, :string
14
+ attribute :package_name, :string
15
+ attribute :qualified_name, :string
16
+ attribute :slots, Slot, collection: true, initialize_empty: true
17
+ attribute :role_name, :string
18
+ attribute :annotations, Annotation, collection: true, initialize_empty: true
19
+
20
+ json do
21
+ map "id", to: :id
22
+ map "name", to: :name
23
+ map "classifierId", to: :classifier_id
24
+ map "classifierName", to: :classifier_name
25
+ map "packageId", to: :package_id
26
+ map "packageName", to: :package_name
27
+ map "qualifiedName", to: :qualified_name
28
+ map "slots", to: :slots, render_empty: true
29
+ map "roleName", to: :role_name
30
+ map "annotations", to: :annotations, render_empty: true
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ea
4
+ module Model
5
+ # An auto-generated legend block. EA emits these from a
6
+ # `t_object` row of Object_Type="Text" whose StyleEx carries
7
+ # `LegendOpts=...`. The visible block — title, colored icon
8
+ # rects, and per-item labels — is configured by a sibling
9
+ # `t_xref` row of name="CustomProperties" on the same GUID.
10
+ #
11
+ # Colors are stored as EA's BGR-packed integers (same encoding
12
+ # as t_object.BCol). Convert to "#RRGGBB" at render time via
13
+ # Ea::Svg::EaEmitter::Element::BColDecoder.
14
+ class Legend < Base
15
+ DEFAULT_TITLE = "凡例"
16
+ DEFAULT_HEADING_SIZE = 12
17
+ DEFAULT_ITEM_SIZE = 9
18
+ DEFAULT_FONT_COLOR = 0x603000 # BGR for #003060
19
+ DEFAULT_BACKGROUND_COLOR = 0xF0F0F0 # BGR for #F0F0F0
20
+ DEFAULT_BORDER_COLOR = 0xD7D7D7 # BGR for #D7D7D7
21
+
22
+ attribute :title, :string, default: -> { DEFAULT_TITLE }
23
+ attribute :heading_size, :integer
24
+ attribute :font_color, :integer, default: -> { DEFAULT_FONT_COLOR }
25
+ attribute :background_color, :integer, default: -> { DEFAULT_BACKGROUND_COLOR }
26
+ attribute :border_color, :integer, default: -> { DEFAULT_BORDER_COLOR }
27
+ attribute :background_is_default, :boolean, default: -> { true }
28
+ attribute :items, LegendItem, collection: true, initialize_empty: true
29
+
30
+ json do
31
+ map "id", to: :id
32
+ map "name", to: :name
33
+ map "title", to: :title
34
+ map "headingSize", to: :heading_size
35
+ map "fontColor", to: :font_color
36
+ map "backgroundColor", to: :background_color
37
+ map "borderColor", to: :border_color
38
+ map "backgroundIsDefault", to: :background_is_default
39
+ map "items", to: :items, render_empty: true
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ea
4
+ module Model
5
+ # One item in an auto-generated legend block: a colored icon
6
+ # paired with a label string. The background_color is the icon's
7
+ # fill, encoded as EA's BGR-packed integer (same encoding as
8
+ # t_object.BCol). sort_index is the 0-based display order.
9
+ class LegendItem < Base
10
+ attribute :name, :string
11
+ attribute :background_color, :integer
12
+ attribute :pen_color, :integer, default: -> { 0 }
13
+ attribute :pen_size, :integer, default: -> { 1 }
14
+ attribute :sort_index, :integer, default: -> { 0 }
15
+
16
+ json do
17
+ map "id", to: :id
18
+ map "name", to: :name
19
+ map "backgroundColor", to: :background_color
20
+ map "penColor", to: :pen_color
21
+ map "penSize", to: :pen_size
22
+ map "sortIndex", to: :sort_index
23
+ end
24
+ end
25
+ end
26
+ end