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,65 @@
1
+ # TODO-D 79: Architecture improvements backlog
2
+
3
+ ## Status: open (rolling)
4
+
5
+ A list of architecture / code-quality improvements surfaced while
6
+ closing parity gaps. Each is shippable independently.
7
+
8
+ ## 1. Elements#build_context decomposition
9
+
10
+ `Elements#build_context` (lib/ea/svg/ea_emitter/elements.rb) is
11
+ ~50 lines and growing. It now also resolves the off-canvas parent
12
+ name, adding a new concern. Extract collaborators:
13
+
14
+ - `HeaderInputResolver` — gathers inputs for HeaderLines
15
+ (visually_nested, parent_name, umldi_keyword, bounds_width).
16
+ - `CompartmentInputResolver` — gathers attr_lines/op_lines/etc.
17
+
18
+ Each returns a small Struct; `build_context` just assembles them
19
+ into the RenderContext.
20
+
21
+ ## 2. RenderContext struct field count
22
+
23
+ RenderContext carries 23 keyword fields. Some are mutually relevant
24
+ (e.g., `attr_lines` and `geometry.attr_lines_count`). Consider
25
+ grouping:
26
+
27
+ - `HeaderInput` struct (header_lines, off_canvas_parent_name)
28
+ - `CompartmentInput` struct (attr_lines, op_lines, enum_literals,
29
+ tagged_values, constraints, package_content_lines)
30
+
31
+ Fewer top-level fields, clearer purpose per group.
32
+
33
+ ## 3. Phantom connector label boxes
34
+
35
+ `DiagramBuilder::DEFAULT_LABEL_BOXES` is a constant in the builder.
36
+ The geometry belongs on the synthesized DiagramConnector model
37
+ field (e.g., `default_label_offsets: true`). Currently the
38
+ `has_geometry_offsets` flag conveys this for one case; generalize.
39
+
40
+ ## 4. LayerSequencer dependency threading
41
+
42
+ LayerSequencer takes `document:` and threads it to multiple
43
+ collaborators (Labels, Elements). The collaborators individually
44
+ re-fetch relationships from the document. A precomputed per-diagram
45
+ "parent_index" (child_id → parent_id) built once at DiagramBuilder
46
+ time would remove the per-render relationship scan.
47
+
48
+ ## 5. public_send in Qea::Repositories::BaseRepository
49
+
50
+ `BaseRepository` uses `public_send(attr)` for dynamic attribute
51
+ dispatch. This is intentional metaprogramming (the attribute name
52
+ is data), not type-checking. But it's worth documenting with a
53
+ comment so future readers don't mistake it for the forbidden
54
+ private-send pattern.
55
+
56
+ ## 6. Spec coverage for new code
57
+
58
+ New code added in TODO-D 71 (off-canvas parent ghost line):
59
+ - `Elements#off_canvas_parent_name_for` — no spec
60
+ - `Elements#parent_generalization_for` — no spec
61
+ - `Elements#parent_package_represented_on_diagram?` — no spec
62
+ - `HeaderLines` italic prepend — covered indirectly via existing
63
+ header_lines_spec.
64
+
65
+ Add specs for the three Elements methods.
@@ -0,0 +1,51 @@
1
+ # TODO-D 80: Basic.qea Generalization triangle markers as polygons
2
+
3
+ ## Status: open (initial hypothesis disproven)
4
+
5
+ On 4 basic.qea diagrams ("Basic Class Diagram with Attributes",
6
+ "Operations", "Receptions", "Attributes and Operations"), ref
7
+ shows 2 extra triangle `<polygon>` markers per diagram that we
8
+ emit as `<path>` arrows instead.
9
+
10
+ ## Per-diagram delta
11
+
12
+ - Attributes: -2 polygons (and +2 paths)
13
+ - Operations: -2 polygons (and +2 paths)
14
+ - Receptions: -2 polygons (and +2 paths)
15
+ - Attributes+Operations: -2 polygons (and +2 paths)
16
+ - Multiplicities: -1 polygon
17
+ - Roles: -1 polygon
18
+ - Package Dependencies: +3 polygons (over-render — likely
19
+ package_import marker issue)
20
+ - Domain Model: +1 polygon
21
+
22
+ Net basic polygon delta: -6.
23
+
24
+ ## Initial hypothesis (DISPROVEN)
25
+
26
+ Tried: emit `:triangle` instead of `:arrow` for Association with
27
+ direction="Unspecified".
28
+
29
+ Result: Over-corrected. basic polygons went from -6 to +15 because
30
+ many basic.qea "Unspecified" Associations DO want arrow markers,
31
+ not triangles. The discriminator must be narrower.
32
+
33
+ ## Next investigation
34
+
35
+ The 4 failing diagrams share: 2 Association connectors, both
36
+ "Unspecified", connecting Class A → Class B.
37
+
38
+ Inspect what distinguishes these from other "Unspecified"
39
+ Associations on basic.qea that DO render arrows correctly.
40
+ Possibilities:
41
+ - The connector's sourcecard/destcard (multiplicity)
42
+ - The connector's sourceaccess/destaccess
43
+ - The presence of a Name vs anonymous
44
+ - The t_diagramlinks geometry (Path=, SX/SY/EX/EY)
45
+
46
+ ## Related
47
+
48
+ basic.qea path over-render (+6) is the mirror image — same 6
49
+ markers counted as paths instead of polygons. Closing one closes
50
+ the other.
51
+
@@ -0,0 +1,53 @@
1
+ # TODO-D 81: Plateau path over-render on ifc_3 (+3) and similar diagrams
2
+
3
+ ## Status: open
4
+
5
+ Several plateau diagrams render extra short horizontal `<path>`
6
+ elements (110-300px wide) that don't appear in EA's reference
7
+ SVG. The paths look like compartment dividers but appear at
8
+ positions where ref doesn't emit them.
9
+
10
+ ## Per-diagram delta
11
+
12
+ - ifc_3: +3 paths
13
+ - utility network: -4 paths (different issue — missing phantom
14
+ connector paths)
15
+ - GenericObject: -5 paths (same as utility network)
16
+ - cons_1: +2 paths
17
+ - bldg:Buildingの拡張属性(LOD4): +2 paths
18
+ - bldg:Roomの拡張属性(LOD4): +2 paths
19
+ - udx: +2 paths
20
+ - Urban Planning ADE2: +1 path
21
+ - CityObjectGroupの拡張属性: +1
22
+ - その他の構造物: +1
23
+ - 位置図_C09_2: +1
24
+
25
+ ## Pattern analysis (ifc_3)
26
+
27
+ Our extra paths at the same x range (218-438), varying y:
28
+ - M 218 394 L 438 394
29
+ - M 218 438 L 438 438
30
+ - M 218 463 L 438 463
31
+ - M 218 507 L 438 507
32
+
33
+ These look like 4 dividers in 4 different elements stacked
34
+ vertically. Ref's element layout differs (different y values),
35
+ suggesting our canvas/element y-offsets diverge from EA's.
36
+
37
+ ## Hypothesis
38
+
39
+ Either:
40
+ 1. Our divider emission logic fires for elements that EA treats
41
+ as header-only (no divider).
42
+ 2. Our canvas y-offset is off for some diagrams, causing dividers
43
+ to land at "wrong" y values that don't match ref.
44
+
45
+ ## Next step
46
+
47
+ For each affected diagram:
48
+ 1. Compare element bounds (our placement vs ref's).
49
+ 2. Compare divider_y values.
50
+ 3. Identify whether it's a positioning issue or a divider-logic
51
+ issue.
52
+
53
+ This is the largest remaining path-delta contributor.
@@ -0,0 +1,54 @@
1
+ # TODO-D 82: Plateau Appearance diagram — canvas offset mismatch
2
+
3
+ ## Status: open
4
+
5
+ The "Appearance" diagram (BC1F7E00 / C31C1314 — there are 2
6
+ versions) has 2 extra `<rect>` elements at positions that don't
7
+ match EA's reference.
8
+
9
+ ## Symptom
10
+
11
+ Our rects: Ref rects:
12
+ (35, 379) w=214 h=70 (35, 680) w=214 h=70
13
+ (45, 479) w=208 h=70 (45, 580) w=208 h=70
14
+
15
+ Both elements (TransformationMatrix3x4 and TransformationMatrix2x2)
16
+ are placed on the diagram (stereotype="dataType", 16 placed
17
+ elements total). Ref renders them at y=580/680, we render at
18
+ y=379/479 — a delta of ~200 px.
19
+
20
+ ## Root cause hypothesis
21
+
22
+ My `BoundsCalculator` computes canvas min_y = -1169 (lowest
23
+ element y -1154 minus MARKER_EXTENT 15). Reference's implied
24
+ min_y = -1470 (calculated from element model y -830 + render y 680
25
+ + inset 40).
26
+
27
+ The 301-px difference suggests EA includes additional geometry
28
+ (extended labels, image-bounds padding, or some other source) in
29
+ its canvas bound computation that we don't.
30
+
31
+ ## Why fixing this is hard
32
+
33
+ The BoundsCalculator is shared across all diagrams. A change here
34
+ affects every diagram's canvas. If the missing bound source is
35
+ diagram-specific (e.g., only DataType elements with certain
36
+ styles trigger it), the fix would need conditional logic.
37
+
38
+ ## Likely related
39
+
40
+ - Polygon positions on Appearance also differ — triangles at
41
+ different anchors (might be connector endpoint mismatch
42
+ due to wrong canvas translate).
43
+ - Other diagrams with rect_delta > 0 may share the same offset
44
+ issue.
45
+
46
+ ## Next step
47
+
48
+ 1. Identify what additional geometry EA's bounds include for
49
+ Appearance. Candidates:
50
+ - Connector label box extents (LLB/LRT geometry)
51
+ - Element image_bounds vs logical bounds handling
52
+ - Phantom connector waypoint contributions
53
+ 2. Test by adding the candidate source to BoundsCalculator and
54
+ verifying the canvas min_y matches.
@@ -0,0 +1,58 @@
1
+ # TODO-D 83: 3D diagram subtitle over-render (3 phantom subtitles)
2
+
3
+ ## Status: open
4
+
5
+ The "3D都市モデル応用スキーマと他のスキーマとの関係" diagram
6
+ shows 4 placed packages:
7
+
8
+ - Inner "3D都市モデル" (parent: outer "3D都市モデル")
9
+ - i-UR (parent: Conceptual Models)
10
+ - CityGML2.0 (parent: Conceptual Models)
11
+ - gml (parent: Conceptual Models)
12
+
13
+ EA reference renders 0 "(from X)" subtitles. Our code renders
14
+ 3 (the inner 3D都市モデル was suppressed by the name-match rule
15
+ in commit cf3dcf2; the other 3 still over-render).
16
+
17
+ ## Compared to udx
18
+
19
+ udx diagram shows 3 placed packages:
20
+
21
+ - 都市計画データ (parent: 3D都市モデル)
22
+ - i-UR (parent: Conceptual Models)
23
+ - CityGML2.0 (parent: Conceptual Models)
24
+
25
+ EA reference renders 3 subtitles. So udx and 3D have similar
26
+ structure but opposite subtitle behavior.
27
+
28
+ ## What differs
29
+
30
+ The diagrams have similar PDATA/StyleEx (both Package type,
31
+ HideParents=0). The ONLY visible difference: 3D includes a
32
+ placed element (inner 3D都市モデル) whose parent shares its name
33
+ with itself.
34
+
35
+ ## Hypothesis (untested)
36
+
37
+ When ANY placed package has a parent whose name collides with
38
+ another package's name in the diagram, EA suppresses all
39
+ subtitle rendering for that diagram. The reasoning: name
40
+ collisions confuse subtitle interpretation, so safer to omit.
41
+
42
+ Alternatively: a flag in t_diagram or t_diagramobjects that
43
+ we're not yet parsing.
44
+
45
+ ## Investigation block
46
+
47
+ This rule cannot be safely derived from one example. Closing
48
+ this gap requires either:
49
+ 1. Finding the rule from additional EA reference outputs (with
50
+ different package-name configurations).
51
+ 2. Reverse-engineering EA's source code for the subtitle logic.
52
+ 3. Per-diagram manual tuning (not scalable).
53
+
54
+ ## Related
55
+
56
+ - TODO-D 75: plateau text under-render (-36 / -37 after this
57
+ fix). The 3D diagram contributes +3 (or +4 pre-fix) to the
58
+ text count discrepancy.
@@ -0,0 +1,61 @@
1
+ # TODO-D 84: Per-diagram canvas-offset / positioning mismatches
2
+
3
+ ## Status: open (rolling)
4
+
5
+ Multiple plateau diagrams have small per-shape deltas (1-5 shapes
6
+ each) where my rendered positions differ from EA's reference.
7
+ The shape COUNTS are correct, but specific shapes are at the wrong
8
+ coordinates.
9
+
10
+ ## Affected diagrams (sample)
11
+
12
+ - utility network: -4 paths (canvas height off: ours 1156 vs ref 1156)
13
+ - GenericObject: -5 paths (canvas width off: ours 872 vs ref 772)
14
+ - ifc_3: +3 paths (frame dimensions match but divider y-positions off)
15
+ - Appearance: +2 rects (canvas height off by 36px)
16
+ - cons_1: +2 paths
17
+ - bldg:Buildingの拡張属性(LOD4): +2 paths
18
+ - bldg:Roomの拡張属性(LOD4): +2 paths
19
+
20
+ ## Common pattern
21
+
22
+ Canvas dimensions or coordinate offsets differ by a small amount
23
+ (10-300 px). Once the canvas offset differs, every shape's
24
+ position shifts, producing both "extra" and "missing" paths at
25
+ slightly different coordinates.
26
+
27
+ ## Likely root cause areas
28
+
29
+ 1. `BoundsCalculator` includes element + connector + marker +
30
+ package_tab points. EA may include ADDITIONAL geometry (label
31
+ boxes, image bounds extensions, etc.) that we miss.
32
+
33
+ 2. The MARKER_EXTENT padding (15 px) may differ from EA's actual
34
+ padding for certain connector/marker combinations.
35
+
36
+ 3. Element `image_bounds` handling: when an element has image
37
+ bounds below its logical bounds, my code includes those points.
38
+ EA may handle this conditionally.
39
+
40
+ ## Why this is hard to fix incrementally
41
+
42
+ A change to BoundsCalculator affects EVERY diagram's canvas. A
43
+ fix that improves one diagram may regress others. Requires
44
+ identifying the precise missing bound source and applying
45
+ conditionally.
46
+
47
+ ## Strategy
48
+
49
+ 1. Pick one diagram (e.g. Appearance).
50
+ 2. Reverse-engineer its canvas height from the reference.
51
+ 3. Identify what geometry would produce that canvas height.
52
+ 4. Add the missing bound source to BoundsCalculator.
53
+ 5. Verify no regression on other diagrams.
54
+
55
+ Repeat for each affected diagram pattern.
56
+
57
+ ## Related
58
+
59
+ - TODO-D 82: Appearance-specific investigation
60
+ - TODO-D 81: path over-render investigation
61
+ - TODO-D 73: polygon under-render
@@ -0,0 +1,95 @@
1
+ # TODO-D 85: Phantom connector «property» over-render on selected diagrams
2
+
3
+ ## Status: open
4
+
5
+ Several plateau diagrams over-render the «property» stereotype
6
+ text (and associated role + multiplicity labels) for PHANTOM
7
+ Aggregation connectors — synthesized when both endpoints are
8
+ placed but no t_diagramlinks entry exists.
9
+
10
+ ## Per-diagram «property» delta
11
+
12
+ | Diagram | Ours | Ref | Diff |
13
+ |---|---|---|---|
14
+ | indoor | 10 | 10 | 0 ✓ |
15
+ | brid_1 | 12 | 11 | +1 |
16
+ | CityGMLCore | 4 | 2 | +2 |
17
+ | veg | 16 | 11 | +5 |
18
+
19
+ ## What's known
20
+
21
+ - Phantom Aggregation connectors get `DEFAULT_LABEL_BOXES`
22
+ (LLT/LLB geometry) in `DiagramBuilder#build_phantom_connector`.
23
+ - This geometry triggers `EndLabel#texts` to emit role +
24
+ «property» + multiplicity labels.
25
+ - The `property_label?` check gates on direction
26
+ ("Source -> Destination" or "Destination -> Source" → render;
27
+ "Unspecified" / "Bi-Directional" → suppress).
28
+ - On indoor, all 9 phantom Aggregations with non-empty
29
+ SourceRole correctly render «property» in ref.
30
+ - On brid_1, 3 phantom Aggregations have non-empty SourceRole
31
+ but ref renders «property» for only 2 of them.
32
+
33
+ ## Discriminator candidates (untested)
34
+
35
+ 1. Source class stereotype — maybe «dataType» sources render
36
+ «property» but other stereotypes don't.
37
+ 2. Source class's attribute compartment visibility — maybe
38
+ sources with hidden attribute compartments don't render
39
+ «property» labels.
40
+ 3. Destination class's attribute compartment — similar.
41
+ 4. A specific t_connector flag (SourceAccess, DestAccess,
42
+ Pursposes, etc.) that we don't yet parse.
43
+ 5. Connector has a Style flag indicating label visibility.
44
+
45
+ ## Investigation update (2026-08-02)
46
+
47
+ brid_1's over-render is NOT from phantom connectors — brid_1
48
+ has 11 EXPLICIT t_diagramlinks for Aggregations. The over-render
49
+ is from the role-fallback logic in `EndLabel#texts`:
50
+
51
+ Connector 424 (DataQualityAttribute -> _AbstractBridge):
52
+ - Geometry has LLT/LLB (source end) AND LRT (target end)
53
+ - SourceRole = "bridDataQualityAttribute"
54
+ - DestRole = empty
55
+
56
+ My code:
57
+ - Source end: LLT present + role present → renders role + «property»
58
+ - Target end: LRT present + role empty → FALLBACK to source role
59
+ → renders role + «property» AGAIN at LRT position
60
+
61
+ Ref:
62
+ - Source end: renders role + «property» (matches my code)
63
+ - Target end: NOTHING (despite LRT geometry present)
64
+
65
+ ## Tested fix (REVERTED)
66
+
67
+ Tried restricting role fallback to only fire when text_box is
68
+ also missing. Result: text delta went from -40 to -154 — the
69
+ fallback is needed for many OTHER cases (114 valid labels rely
70
+ on it).
71
+
72
+ ## The actual discriminator (needed)
73
+
74
+ EA likely considers LRT geometry "stale" when:
75
+ - The geometry has unusual offset (e.g., OY=315 for connector
76
+ 424, vs typical ±50)
77
+ - OR the connector's direction makes the target end non-navigable
78
+
79
+ The "unusual offset" rule is fragile. A more principled rule
80
+ would require parsing additional t_diagramlinks fields or
81
+ comparing against EA's internal "dirty" flag.
82
+
83
+ ## Strategy
84
+
85
+ For each affected diagram, identify which connectors have LRT
86
+ geometry but no target role, and trace the LRT offset. If a
87
+ threshold rule (e.g., |OY| > 100) cleanly separates valid from
88
+ invalid, apply it.
89
+
90
+ ## Related
91
+
92
+ - TODO-D 75: plateau text under-render (current -40)
93
+ - TODO-D 81: plateau path over-render
94
+ - lib/ea/svg/ea_emitter/label/end_label.rb (property_label?)
95
+ - lib/ea/sources/qea/diagram_builder.rb (DEFAULT_LABEL_BOXES)
@@ -0,0 +1,62 @@
1
+ # TODO-D 86: Foreign-package rule over-suppression (parent-ghost)
2
+
3
+ ## Status: open (rolling)
4
+
5
+ The current `parent_package_represented_on_diagram?` check in
6
+ `lib/ea/svg/ea_emitter/elements.rb` suppresses the off-canvas
7
+ parent-class italic ghost line when ANY placed element shares
8
+ the parent's package. This rule was added to fix the Building
9
+ diagram's spurious _Feature/_AbstractGeometricAggregate ghosts.
10
+
11
+ ## Trade-off
12
+
13
+ | Rule state | Text delta | Effect |
14
+ |---|---|---|
15
+ | Rule ENABLED (current) | -40 | Some valid ghosts suppressed |
16
+ | Rule DISABLED | +60 | Some invalid ghosts rendered |
17
+
18
+ Net: rule removes 100 ghosts total (60 invalid + 40 valid).
19
+
20
+ ## Hypotheses tested (all DISPROVEN)
21
+
22
+ 1. **Package match** (current rule) — over-suppresses
23
+ 2. **Parent name in diagram name** — too narrow
24
+ 3. **Parent stereotype vs child stereotype** — all cases have
25
+ identical stereotypes, no discriminator
26
+ 4. **Parent abstract flag** — both abstract and non-abstract
27
+ parents render on indoor; both don't on Building
28
+ 5. **Parent's package_id is top-level** — all parents are
29
+ top-level; no discriminator
30
+
31
+ ## Valid vs invalid samples
32
+
33
+ | Diagram | Child | Parent | Parent pkg | Renders in ref? |
34
+ |---|---|---|---|---|
35
+ | indoor | Room | _CityObject | core | YES |
36
+ | indoor | _AbstractBuilding | _Site | core | YES |
37
+ | tran_2 | TrafficVolumeAttribute | RoadAttribute | uro | YES |
38
+ | bldg_1 | BuildingDetailAttribute | BuildingAttribute | uro | YES |
39
+ | Building | Address | _Feature | gml | NO |
40
+ | Building | _CityObject | _Feature | gml | NO |
41
+ | Building | _Solid | _GeometricPrimitive | gml | NO |
42
+
43
+ The discriminator between YES (render) and NO (suppress) cases
44
+ is NOT in t_object, t_connector, or any field we currently parse.
45
+
46
+ ## Remaining candidates (untested)
47
+
48
+ 1. A per-element flag in t_diagramlinks or t_diagramobjects
49
+ (e.g., a per-element "show parent" flag).
50
+ 2. A diagram-level StyleEx flag we haven't decoded.
51
+ 3. The depth of the inheritance chain (immediate parent vs
52
+ grandparent).
53
+ 4. A Package-level attribute (e.g., "abstract package" vs
54
+ "concrete package").
55
+
56
+ ## Strategic block
57
+
58
+ The discriminator requires either EA source access or
59
+ significant reference-SVG triangulation. Each additional rule
60
+ attempted in this conversation has either over-suppressed
61
+ valid cases or under-suppressed invalid ones. The current rule
62
+ is the best trade-off found.
@@ -0,0 +1,80 @@
1
+ # TODO-D 87: Reverse-engineer EA's InternalTechnologies encryption
2
+
3
+ ## Status: open (encryption scheme unidentified)
4
+
5
+ EA's `InternalTechnologies/*.xml` files (66 files including
6
+ `GML_Tech.xml`) are stored in an encrypted/compressed format.
7
+ These contain stereotype icon definitions for built-in technologies
8
+ (GML, UML, SysML, BPMN, etc.) — including the FeatureType icon
9
+ needed for the polygon -4 parity gap.
10
+
11
+ ## File format analysis
12
+
13
+ - File: GML_Tech.xml, 3076 bytes
14
+ - First bytes: 30 c6 3c f8 e4 d6 4b fd e0 dd 36 f5 57 84 8d 7b
15
+ - NOT standard compression (zip/gzip/zlib headers absent)
16
+ - NOT valid XML
17
+
18
+ ## Hypotheses tested (all FAILED)
19
+
20
+ | Approach | Result |
21
+ |---|---|
22
+ | Single-byte XOR (256 keys) | No valid `<?xml` start |
23
+ | Multi-byte XOR assuming `<?xml version=` start | Key derives but doesn't repeat |
24
+ | zlib inflate at offsets 0-63 with wbits -15/-14/15/31/47 | No valid output |
25
+ | Byte rotation then zlib | No valid output |
26
+ | Byte subtraction (delta 1-255) then zlib | No valid output |
27
+ | XOR with position index | No valid output |
28
+ | Position-reversed XOR | No valid output |
29
+ | Add position modulo 256 | No valid output |
30
+
31
+ ## Byte frequency analysis
32
+
33
+ Byte distribution at position mod 4 is fairly uniform (each byte
34
+ value appears 7-9 times per position). This is consistent with
35
+ **strong encryption** (AES, RC4, etc.) rather than simple XOR.
36
+
37
+ ## EA.exe binary analysis
38
+
39
+ Located `MDGTechnology.cpp` debug tag at offset 0x4584684 in
40
+ EA.exe. Found references to `CryptEncrypt`/`CryptDecrypt` Windows
41
+ APIs and `aes_encrypt`/`aes_decrypt` SQL functions.
42
+
43
+ Searched EA.exe (70MB binary) for plaintext GML technology
44
+ content (`<MDG.Technology`, `ApplicationSchema`, `GML::FeatureType`,
45
+ `FeatureType`) — **zero matches**. The plaintext is NOT embedded
46
+ in the binary.
47
+
48
+ Extracted 19MB `.rsrc` section via `wrestool`. Contains many
49
+ `BSTRING` resources (UI strings, etc.) but none contain MDG
50
+ technology XML.
51
+
52
+ ## Decryption options (none trivial)
53
+
54
+ 1. **Run EA via Wine** to call the COM API:
55
+ `Repository.GetTechnologyByClassID(...)` then export. Requires
56
+ CrossOver/Wine GUI session — non-trivial setup.
57
+
58
+ 2. **Ghidra/IDA disassembly** of MDGTechnology.cpp routine:
59
+ locate the decryption function, identify the algorithm and
60
+ hardcoded key. Requires reverse-engineering expertise and
61
+ 10+ hours of analysis.
62
+
63
+ 3. **Debugger capture**: run EA under `winedbg`, set breakpoint
64
+ at file-read for GML_Tech.xml, trace until plaintext appears
65
+ in memory, dump it. Requires Wine debugging setup.
66
+
67
+ 4. **Side-channel acquisition**: ask Sparx Systems support for
68
+ the technology definition (they may provide it).
69
+
70
+ ## Recommendation
71
+
72
+ The polygon -4 parity gap is small (4 missing stereotype
73
+ decorator icons across 188 diagrams). The effort to reverse-
74
+ engineer EA's encryption significantly exceeds the value of
75
+ closing this gap.
76
+
77
+ Recommend: DEFER this work until either:
78
+ - A user provides plaintext MDG exports from EA
79
+ - The `ea` gem adds Wine-based extraction as an optional feature
80
+ - A security researcher publishes the EA encryption scheme
@@ -0,0 +1,88 @@
1
+ # Examples parity report (2026-07-28)
2
+
3
+ `rake svg:examples` benches every QEA in `examples/qea/` against
4
+ its matching exports/Images directory.
5
+
6
+ ## Headline
7
+
8
+ | Example | Matched | Perfect | Notes |
9
+ |---------|---------|---------|-------|
10
+ | simple | 2/2 | **2** | 100% parity |
11
+ | ArcGISWorkspace_template | 5/6 | 5 | Workspace diagram has decorative icons |
12
+ | basic | 19/22 | 8 | Visibility icons + Object instance format missing |
13
+ | test | 1/2 | 1 | Test Model diagram needs visibility icons |
14
+
15
+ **15 of 27 renderable example diagrams are at 100% parity.**
16
+
17
+ ## Per-example breakdown
18
+
19
+ ### simple.qea — 100% ✓
20
+
21
+ ```
22
+ simple 2/2 matched
23
+ rect ours=8 ref=8 delta=0
24
+ path ours=3 ref=3 delta=0
25
+ polygon ours=12 ref=12 delta=0
26
+ text ours=22 ref=22 delta=0
27
+ ```
28
+
29
+ Both diagrams (`Simple Package Diagram`, `Simple Class Diagram`)
30
+ render byte-identical element counts.
31
+
32
+ ### ArcGISWorkspace_template — 5/6 perfect
33
+
34
+ Only `ArcGIS Workspace` diagram has deltas (-2 rect, -7 path).
35
+ The 7 missing paths are decorative "data icon" paths (small
36
+ horizontal lines + dots) inside one element's attribute
37
+ compartment. Canvas height calc is also slightly off (641 vs 600).
38
+
39
+ ### basic.qea — 8/22 perfect, 19/22 within tolerance
40
+
41
+ **Perfect diagrams:**
42
+ - Package Contents
43
+ - Package Dependencies
44
+ - Package B
45
+ - Basic Class Diagram with Multiplicities
46
+ - Signals
47
+ - Two Level Class Type Hierarchy with Attributes
48
+ - Two Level Class Composition Hierarchy with Attributes
49
+ - Composition with Substitution
50
+
51
+ **Remaining gaps (concentrated in 3 areas):**
52
+
53
+ 1. **Visibility icons** (Test Model diagram in test.qea +
54
+ Package Imports + Object with Value Specifications in basic):
55
+ EA renders 3 elements per attribute row (outer rect 11x14 +
56
+ inner rect 11x4 + horizontal divider path). Implementing this
57
+ would close ~25 rects and ~15 paths across examples.
58
+
59
+ 2. **Object instance format** (Objects as Instances of Classes +
60
+ Object with Value Specifications): EA renders
61
+ `Object 01 / roleOne: Class A` and `attribute = value` slot
62
+ format. We render the qualified class name only.
63
+
64
+ 3. **Decorative data icons** (ArcGIS Workspace): "Hamburger menu"
65
+ icons (3 horizontal lines + dots). Specific to ArcGIS template.
66
+
67
+ ### test.qea — 1/2 perfect
68
+
69
+ - `TestSchema` diagram: 100%
70
+ - `Test Model` diagram: needs visibility icons + Package element
71
+ attribute rendering
72
+
73
+ ## How to run
74
+
75
+ ```
76
+ bundle exec rake svg:examples
77
+ ```
78
+
79
+ Outputs per-example bench in a single table. Run after every
80
+ renderer change to catch regressions in any example.
81
+
82
+ ## Architecture
83
+
84
+ The `rake svg:examples` task auto-discovers QEA files in
85
+ `examples/qea/` and matches them with ref directories in
86
+ `examples/exports/<name>/{images,Images}/`. Uses the existing
87
+ `Ea::Svg::Parity::Suite` with `Ea::Sources::Qea::IdNormalizer`
88
+ for diagram-id → SVG-filename resolution.