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.
- checksums.yaml +4 -4
- data/Rakefile +3 -0
- data/TODO.complete/01-t-xref-parsing.md +91 -0
- data/TODO.complete/02-per-label-geometry.md +50 -0
- data/TODO.complete/03-object-properties-constraints.md +57 -0
- data/TODO.complete/04-operation-params.md +37 -0
- data/TODO.complete/05-pdata-flag-matrix.md +52 -0
- data/TODO.complete/06-emf-image-rendering.md +34 -0
- data/TODO.complete/07-auxiliary-tables.md +47 -0
- data/TODO.complete/10-mdg-stereotype-registry.md +40 -0
- data/TODO.complete/11-gml-xsd-generation.md +42 -0
- data/TODO.complete/13-shapescript-interpreter.md +28 -0
- data/TODO.complete/20-cli-diff.md +46 -0
- data/TODO.complete/21-cli-render.md +26 -0
- data/TODO.complete/22-cli-export.md +29 -0
- data/TODO.complete/23-cli-mdg.md +23 -0
- data/TODO.complete/30-headerlines-ocp-refactor.md +72 -0
- data/TODO.complete/31-public-send-cleanup.md +61 -0
- data/TODO.complete/32-spec-coverage.md +33 -0
- data/TODO.complete/33-blocked-parity-gaps.md +41 -0
- data/TODO.complete/36-stereotype-icon-wiring.md +32 -0
- data/TODO.complete/37-cli-lint.md +32 -0
- data/TODO.complete/38-cli-query.md +26 -0
- data/TODO.complete/39-cli-info.md +23 -0
- data/TODO.complete/40-ocl-evaluator.md +31 -0
- data/TODO.complete/41-round-trip-spec.md +18 -0
- data/TODO.complete/42-html-diff-report.md +18 -0
- data/TODO.complete/43-json-schema-export.md +20 -0
- data/TODO.complete/44-remaining-qea-tables.md +40 -0
- data/TODO.complete/45-shapescript-extensions.md +25 -0
- data/TODO.complete/46-xsd-consolidation.md +20 -0
- data/TODO.complete/47-headerlines-legacy-removal.md +20 -0
- data/TODO.complete/STATUS.md +109 -0
- data/TODO.diagrams/01-svg-measurement-harness.md +31 -0
- data/TODO.diagrams/01-xmi-extension-elements-parsing.md +67 -0
- data/TODO.diagrams/02-diagram-element-rich-model.md +61 -0
- data/TODO.diagrams/02-polygon-over-rendering.md +29 -0
- data/TODO.diagrams/03-ea-style-svg-emitter.md +70 -0
- data/TODO.diagrams/03-text-over-rendering.md +30 -0
- data/TODO.diagrams/04-connector-routing-from-soid-eoid.md +55 -0
- data/TODO.diagrams/04-rect-under-rendering.md +33 -0
- data/TODO.diagrams/05-canvas-dimension-parity.md +51 -0
- data/TODO.diagrams/05-marker-rendering-per-relationship-type.md +49 -0
- data/TODO.diagrams/06-connector-labels.md +49 -0
- data/TODO.diagrams/06-group-layering-parity.md +39 -0
- data/TODO.diagrams/07-canvas-size-and-viewbox.md +39 -0
- data/TODO.diagrams/07-text-content-fidelity.md +65 -0
- data/TODO.diagrams/08-qea-direct-pipeline.md +46 -0
- data/TODO.diagrams/08-visual-regression-harness.md +34 -0
- data/TODO.diagrams/09-cli-render-all-diagrams.md +25 -0
- data/TODO.diagrams/10-stereotype-color-config.md +29 -0
- data/TODO.diagrams/11-elkrb-auto-layout-integration.md +53 -0
- data/TODO.diagrams/12-connector-labels.md +40 -0
- data/TODO.diagrams/12-per-entity-svg-layer-ordering.md +24 -0
- data/TODO.diagrams/13-marker-polygon-vs-path-dispatch.md +20 -0
- data/TODO.diagrams/13-per-text-type-font-sizes.md +33 -0
- data/TODO.diagrams/14-center-header-text.md +33 -0
- data/TODO.diagrams/14-filter-diagram-frame-elements.md +18 -0
- data/TODO.diagrams/15-deep-dead-code-audit.md +47 -0
- data/TODO.diagrams/15-per-element-font-from-style.md +24 -0
- data/TODO.diagrams/16-canvas-marker-extent.md +30 -0
- data/TODO.diagrams/16-document-remaining-parity-gaps.md +91 -0
- data/TODO.diagrams/17-italic-abstract-classes.md +28 -0
- data/TODO.diagrams/17-remaining-parity-gaps.md +90 -0
- data/TODO.diagrams/18-canvas-from-image-bounds.md +20 -0
- data/TODO.diagrams/18-property-lookup-index.md +42 -0
- data/TODO.diagrams/19-connector-sx-sy-routing.md +27 -0
- data/TODO.diagrams/19-replace-respond-to-with-is-a.md +31 -0
- data/TODO.diagrams/20-split-labels-emitter.md +56 -0
- data/TODO.diagrams/20-visibility-glyph-font-encoding.md +27 -0
- data/TODO.diagrams/21-aggregation-navigability-arrow.md +21 -0
- data/TODO.diagrams/21-auto-generated-legend-block.md +65 -0
- data/TODO.diagrams/22-ghost-element-discriminator.md +57 -0
- data/TODO.diagrams/22-style-based-path-grouping.md +28 -0
- data/TODO.diagrams/23-marker-polygon-deduplication.md +47 -0
- data/TODO.diagrams/23-multiplicity-label-positioning.md +29 -0
- data/TODO.diagrams/24-marker-anchor-structural.md +35 -0
- data/TODO.diagrams/24-track-marker-anchors-structurally.md +66 -0
- data/TODO.diagrams/24-truncate-properties-to-fit-box.md +24 -0
- data/TODO.diagrams/26-phantom-general-parent-rendering.md +59 -0
- data/TODO.diagrams/27-path-grouping-mode-detection.md +43 -0
- data/TODO.diagrams/28-architecture-cleanup-batch.md +47 -0
- data/TODO.diagrams/30-decompose-elements-groups-for.md +52 -0
- data/TODO.diagrams/32-examples-coverage-batch.md +78 -0
- data/TODO.diagrams/36-instance-specification-model.md +42 -0
- data/TODO.diagrams/37-element-icon-decorations.md +41 -0
- data/TODO.diagrams/38-html-note-and-receptions.md +32 -0
- data/TODO.diagrams/39-property-stereotype-discriminator.md +40 -0
- data/TODO.diagrams/40-standalone-1-discriminator.md +38 -0
- data/TODO.diagrams/41-xmi-to-svg-pipeline.md +113 -0
- data/TODO.diagrams/42-close-all-parity-deltas.md +69 -0
- data/TODO.diagrams/43-marker-deduplication-strategy.md +54 -0
- data/TODO.diagrams/44-element-icon-decorations.md +34 -0
- data/TODO.diagrams/45-phantom-parent-class-boxes.md +40 -0
- data/TODO.diagrams/46-user-drawn-legend-swatches.md +44 -0
- data/TODO.diagrams/47-attribute-line-fidelity.md +72 -0
- data/TODO.diagrams/48-spec-coverage-critical-emitter-components.md +45 -0
- data/TODO.diagrams/49-spec-coverage-orchestrators.md +25 -0
- data/TODO.diagrams/50-examples-parity.md +85 -0
- data/TODO.diagrams/51-property-oy-gap-and-remaining-gaps.md +48 -0
- data/TODO.diagrams/52-marker-registration-architecture.md +89 -0
- data/TODO.diagrams/53-remaining-example-gaps.md +86 -0
- data/TODO.diagrams/54-display-name-nested-classes.md +40 -0
- data/TODO.diagrams/55-visibility-icon-discriminator.md +58 -0
- data/TODO.diagrams/56-package-contents-rendering.md +148 -0
- data/TODO.diagrams/57-instance-specification-model.md +100 -0
- data/TODO.diagrams/58-domain-model-note-text.md +67 -0
- data/TODO.diagrams/59-classes-arrow-discriminator.md +57 -0
- data/TODO.diagrams/60-testschema-association-marker.md +40 -0
- data/TODO.diagrams/61-legend-block-rendering.md +55 -0
- data/TODO.diagrams/61-plateau-parity-gaps.md +59 -0
- data/TODO.diagrams/62-ghost-element-rendering.md +56 -0
- data/TODO.diagrams/63-qualified-name-wrap.md +36 -0
- data/TODO.diagrams/64-property-stereotype-labels.md +22 -0
- data/TODO.diagrams/65-path-coordinate-frame.md +62 -0
- data/TODO.diagrams/67-path-coordinate-frame.md +62 -0
- data/TODO.diagrams/68-inherited-attributes.md +65 -0
- data/TODO.diagrams/69-package-anchor-conditional.md +29 -0
- data/TODO.diagrams/70-mdg-technology-support.md +68 -0
- data/TODO.diagrams/71-off-canvas-parent-ghost.md +45 -0
- data/TODO.diagrams/72-basic-attr-divider-paths.md +39 -0
- data/TODO.diagrams/73-plateau-polygon-gap.md +69 -0
- data/TODO.diagrams/74-plateau-rect-gap.md +22 -0
- data/TODO.diagrams/75-plateau-text-gap.md +39 -0
- data/TODO.diagrams/76-basic-poly-path-gaps.md +41 -0
- data/TODO.diagrams/77-basic-text-overrender.md +40 -0
- data/TODO.diagrams/78-headerlines-ocp-refactor.md +65 -0
- data/TODO.diagrams/79-architecture-backlog.md +65 -0
- data/TODO.diagrams/80-basic-triangle-polygons.md +51 -0
- data/TODO.diagrams/81-plateau-path-overrender.md +53 -0
- data/TODO.diagrams/82-appearance-canvas-offset.md +54 -0
- data/TODO.diagrams/83-3d-diagram-subtitle.md +58 -0
- data/TODO.diagrams/84-canvas-offset-mismatches.md +61 -0
- data/TODO.diagrams/85-phantom-property-overrender.md +95 -0
- data/TODO.diagrams/86-foreign-package-rule.md +62 -0
- data/TODO.diagrams/87-internal-tech-encryption.md +80 -0
- data/TODO.diagrams/EXAMPLES_STATUS.md +88 -0
- data/TODO.diagrams/README.md +69 -0
- data/TODO.diagrams/STATUS.md +73 -0
- data/TODO.fixup/01-default-grouped-paths.md +34 -0
- data/TODO.fixup/02-marker-consolidation-per-connector.md +20 -0
- data/TODO.fixup/03-diagram-font-inference.md +28 -0
- data/TODO.fixup/04-extract-bounds-calculator.md +25 -0
- data/TODO.fixup/05-marker-registry-ocp.md +32 -0
- data/TODO.fixup/06-connector-path-bend-routing.md +28 -0
- data/TODO.fixup/07-edge-attachment-formula.md +22 -0
- data/TODO.fixup/08-visual-diff-harness.md +28 -0
- data/TODO.fixup/09-extract-element-compartments.md +34 -0
- data/TODO.fixup/10-canvas-width-overshoot-fix.md +20 -0
- data/TODO.fixup/11-layer-sequencer-extraction.md +18 -0
- data/TODO.fixup/12-path-style-harmony.md +23 -0
- data/TODO.fixup/13-datatype-stereotype-fallback.md +28 -0
- data/TODO.fixup/14-ea-exe-reverse-engineering-notes.md +56 -0
- data/TODO.fixup/15-enumeration-literal-rendering.md +30 -0
- data/TODO.fixup/16-operation-compartment-rendering.md +42 -0
- data/TODO.fixup/17-path-count-calibration.md +27 -0
- data/TODO.fixup/18-polygon-count-calibration.md +32 -0
- data/TODO.fixup/19-rect-count-undershoot-investigation.md +40 -0
- data/TODO.fixup/20-stereotype-color-from-classifier.md +18 -0
- data/TODO.fixup/21-visibility-filter-for-properties.md +24 -0
- data/TODO.fixup/22-multiplicity-display-rule-calibration.md +25 -0
- data/TODO.fixup/23-diagram-frame-title-element.md +31 -0
- data/TODO.fixup/24-note-element-rendering.md +23 -0
- data/TODO.fixup/25-ea-exe-disassembly-findings.md +177 -0
- data/TODO.fixup/26-svg-renderer-architecture.md +78 -0
- data/TODO.fixup/27-svg-element-emitters-disassembly.md +135 -0
- data/TODO.fixup/28-geometry-parser-identification.md +57 -0
- data/TODO.fixup/29-qea-svg-xmi-triple-comparison.md +185 -0
- data/TODO.fixup/30-theme-system-stub.md +46 -0
- data/TODO.fixup/31-theme-value-object-registry.md +17 -0
- data/TODO.fixup/32-styleex-on-diagram-model.md +22 -0
- data/TODO.fixup/33-text-encoding-decimals-rotation.md +29 -0
- data/TODO.fixup/34-per-type-fill-via-theme.md +18 -0
- data/TODO.fixup/35-stroke-width-per-theme.md +7 -0
- data/TODO.fixup/36-qea-rect-coord-normalization.md +24 -0
- data/TODO.fixup/37-package-shape-rendering.md +22 -0
- data/TODO.fixup/38-note-element-rendering.md +15 -0
- data/TODO.fixup/39-styleex-flag-honoring.md +25 -0
- data/TODO.fixup/40-connector-dashed-lines.md +15 -0
- data/TODO.fixup/41-diagram-frame-showborder-detection.md +23 -0
- data/TODO.fixup/42-textrenderer-centralization.md +10 -0
- data/TODO.fixup/43-colorresolver-unification.md +24 -0
- data/TODO.fixup/44-theme-aware-textrenderer.md +17 -0
- data/TODO.fixup/45-theme-aware-fontresolver.md +22 -0
- data/TODO.fixup/46-style-parameterized-by-theme.md +21 -0
- data/TODO.fixup/47-canvas-frame-inset.md +19 -0
- data/TODO.fixup/48-background-rect-format.md +15 -0
- data/TODO.fixup/49-all-samples-integration-test.md +17 -0
- data/TODO.fixup/50-svg-emitter-architecture-docs.md +33 -0
- data/TODO.fixup/51-promote-theme-to-ea-namespace.md +28 -0
- data/TODO.fixup/52-theme-definition-integrated-fills.md +26 -0
- data/TODO.fixup/53-theme-registry-yaml-loading.md +50 -0
- data/TODO.fixup/54-diagram-theme-api.md +50 -0
- data/TODO.fixup/55-update-eaemitter-to-ea-theme.md +23 -0
- data/TODO.fixup/56-theme-yaml-files.md +65 -0
- data/TODO.fixup/57-theme-specs-and-integration.md +27 -0
- data/TODO.fixup/58-ea-entry-point-theme-autoload.md +20 -0
- data/TODO.fixup/59-thread-theme-through-all-renderers.md +29 -0
- data/TODO.fixup/60-cli-theme-option.md +22 -0
- data/TODO.fixup/61-theme-validation.md +28 -0
- data/TODO.fixup/62-theme-builder-dsl.md +31 -0
- data/TODO.fixup/63-theme-integration-rendering-spec.md +24 -0
- data/TODO.fixup/64-theme-writeback-styleex.md +21 -0
- data/TODO.fixup/65-remove-dead-eaemitter-theme-files.md +30 -0
- data/TODO.fixup/66-styleex-writeback.md +22 -0
- data/TODO.fixup/67-delete-dead-code.md +28 -0
- data/TODO.fixup/68-figure-parity-status.md +82 -0
- data/TODO.fixup/69-package-polygon-rendering.md +54 -0
- data/TODO.fixup/70-tagged-values-compartment.md +39 -0
- data/TODO.fixup/71-auto-detect-theme-from-xmi.md +37 -0
- data/TODO.fixup/72-sample-exports-as-regression-specs.md +37 -0
- data/TODO.fixup/73-delete-dead-transformations.md +14 -0
- data/TODO.fixup/74-delete-dead-diagram-renderers.md +18 -0
- data/TODO.fixup/75-visibility-legend-icons.md +23 -0
- data/TODO.fixup/76-plateau-text-undershoot.md +27 -0
- data/TODO.fixup/77-canvas-frame-margins.md +28 -0
- data/TODO.fixup/78-note-element-rendering.md +30 -0
- data/TODO.fixup/79-operation-compartment-rendering.md +27 -0
- data/TODO.fixup/80-tagged-value-stereotype-visibility.md +37 -0
- data/TODO.fixup/81-figure-parity-current-state.md +63 -0
- data/config/qea_schema.yml +356 -0
- data/config/stereotype_colors.yml +15 -0
- data/config/themes/119.yml +98 -0
- data/config/themes/default.yml +14 -0
- data/examples/exports/20251010_current_plateau_v5/UML_EA.DTD +6856 -0
- data/examples/exports/20251010_current_plateau_v5/model.xml +96709 -0
- data/examples/exports/ArcGISWorkspace_template/UML_EA.DTD +6856 -0
- data/examples/exports/ArcGISWorkspace_template/model.xml +1427 -0
- data/examples/exports/UmlModel_template/UML_EA.DTD +6856 -0
- data/examples/exports/UmlModel_template/model.xml +23 -0
- data/examples/exports/basic/UML_EA.DTD +6856 -0
- data/examples/exports/basic/model.xml +8039 -0
- data/examples/exports/simple/UML_EA.DTD +6856 -0
- data/examples/exports/simple/model.xml +585 -0
- data/examples/exports/simple_example/UML_EA.DTD +6856 -0
- data/examples/exports/simple_example/model.xml +23 -0
- data/examples/exports/test/UML_EA.DTD +6856 -0
- data/examples/exports/test/model.xml +1638 -0
- data/examples/qea/basic.qea +0 -0
- data/frontend/README.md +51 -0
- data/frontend/dist/app.iife.js +24 -0
- data/frontend/dist/style.css +1 -0
- data/frontend/index.html +26 -0
- data/frontend/package-lock.json +2359 -0
- data/frontend/package.json +26 -0
- data/frontend/src/App.vue +59 -0
- data/frontend/src/app.ts +8 -0
- data/frontend/src/components/AppHeader.vue +127 -0
- data/frontend/src/components/AppSidebar.vue +119 -0
- data/frontend/src/components/ClassDetails.vue +247 -0
- data/frontend/src/components/DiagramView.vue +79 -0
- data/frontend/src/components/PackageDetails.vue +92 -0
- data/frontend/src/components/PackageTreeNode.vue +64 -0
- data/frontend/src/components/SearchResults.vue +48 -0
- data/frontend/src/components/WelcomeView.vue +87 -0
- data/frontend/src/shims-vue.d.ts +5 -0
- data/frontend/src/stores/dataStore.ts +79 -0
- data/frontend/src/stores/uiStore.ts +167 -0
- data/frontend/src/styles/main.css +1566 -0
- data/frontend/src/types.ts +221 -0
- data/frontend/tests/e2e/__screenshots__/new-dark-mode.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-package-details.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-search-modal.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-sidebar-collapsed.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-welcome.png +0 -0
- data/frontend/tests/e2e/render.spec.ts +188 -0
- data/frontend/tsconfig.json +20 -0
- data/frontend/vite.config.ts +26 -0
- data/frontend/vitest.config.ts +8 -0
- data/lib/ea/cli/app.rb +62 -1
- data/lib/ea/cli/command/diagrams.rb +37 -28
- data/lib/ea/cli/command/diff.rb +46 -0
- data/lib/ea/cli/command/export.rb +80 -0
- data/lib/ea/cli/command/info.rb +75 -0
- data/lib/ea/cli/command/lint.rb +48 -0
- data/lib/ea/cli/command/mdg.rb +98 -0
- data/lib/ea/cli/command/query.rb +34 -0
- data/lib/ea/cli/command/render.rb +135 -0
- data/lib/ea/cli/command/svg.rb +43 -6
- data/lib/ea/cli/command.rb +7 -0
- data/lib/ea/diagram/display_config.rb +184 -0
- data/lib/ea/diagram.rb +4 -41
- data/lib/ea/diff/change.rb +30 -0
- data/lib/ea/diff/comparator.rb +82 -0
- data/lib/ea/diff/html_reporter.rb +91 -0
- data/lib/ea/diff.rb +15 -0
- data/lib/ea/export/json/generator.rb +42 -0
- data/lib/ea/export/json.rb +12 -0
- data/lib/ea/export/json_schema/generator.rb +77 -0
- data/lib/ea/export/json_schema.rb +12 -0
- data/lib/ea/export/plantuml/generator.rb +73 -0
- data/lib/ea/export/plantuml.rb +12 -0
- data/lib/ea/export/xmi/generator.rb +77 -0
- data/lib/ea/export/xmi.rb +11 -0
- data/lib/ea/export/xsd/class_mapping.rb +65 -0
- data/lib/ea/export/xsd/generator.rb +142 -0
- data/lib/ea/export/xsd/namespace_registry.rb +82 -0
- data/lib/ea/export/xsd.rb +19 -0
- data/lib/ea/export.rb +14 -0
- data/lib/ea/image/emf_renderer.rb +42 -0
- data/lib/ea/image.rb +12 -0
- data/lib/ea/lint/engine.rb +30 -0
- data/lib/ea/lint/lint_rule.rb +38 -0
- data/lib/ea/lint/offense.rb +18 -0
- data/lib/ea/lint/rules/cyclic_generalization.rb +62 -0
- data/lib/ea/lint/rules/duplicate_name.rb +28 -0
- data/lib/ea/lint/rules/missing_stereotype.rb +35 -0
- data/lib/ea/lint/rules/naming_convention.rb +44 -0
- data/lib/ea/lint/rules/orphan_element.rb +28 -0
- data/lib/ea/lint/rules.rb +14 -0
- data/lib/ea/lint.rb +13 -0
- data/lib/ea/mdg/document.rb +120 -0
- data/lib/ea/mdg/loader.rb +118 -0
- data/lib/ea/mdg/registry.rb +98 -0
- data/lib/ea/mdg/stereotype_alias_registry.rb +77 -0
- data/lib/ea/mdg/xml/applies_to.rb +18 -0
- data/lib/ea/mdg/xml/apply.rb +18 -0
- data/lib/ea/mdg/xml/content.rb +18 -0
- data/lib/ea/mdg/xml/documentation.rb +24 -0
- data/lib/ea/mdg/xml/stereotype.rb +28 -0
- data/lib/ea/mdg/xml/stereotypes.rb +18 -0
- data/lib/ea/mdg/xml/tag.rb +28 -0
- data/lib/ea/mdg/xml/tagged_values.rb +18 -0
- data/lib/ea/mdg/xml/technology.rb +28 -0
- data/lib/ea/mdg/xml/uml_profile.rb +22 -0
- data/lib/ea/mdg/xml/uml_profiles.rb +18 -0
- data/lib/ea/mdg/xml.rb +24 -0
- data/lib/ea/mdg.rb +25 -0
- data/lib/ea/model/classifier.rb +4 -0
- data/lib/ea/model/constraint.rb +24 -0
- data/lib/ea/model/diagram.rb +85 -0
- data/lib/ea/model/diagram_connector.rb +53 -1
- data/lib/ea/model/diagram_element.rb +44 -0
- data/lib/ea/model/document.rb +47 -2
- data/lib/ea/model/ghost_label.rb +32 -0
- data/lib/ea/model/instance_specification.rb +34 -0
- data/lib/ea/model/legend.rb +43 -0
- data/lib/ea/model/legend_item.rb +26 -0
- data/lib/ea/model/note.rb +28 -0
- data/lib/ea/model/operation.rb +2 -0
- data/lib/ea/model/property.rb +2 -0
- data/lib/ea/model/relationship.rb +2 -0
- data/lib/ea/model/signal.rb +14 -0
- data/lib/ea/model/slot.rb +19 -0
- data/lib/ea/model.rb +8 -0
- data/lib/ea/ocl/evaluator.rb +94 -0
- data/lib/ea/ocl/nodes.rb +30 -0
- data/lib/ea/ocl/parser.rb +133 -0
- data/lib/ea/ocl/unsupported_error.rb +7 -0
- data/lib/ea/ocl.rb +13 -0
- data/lib/ea/qea/factory/document_builder.rb +24 -10
- data/lib/ea/qea/factory/generalization_builder.rb +9 -11
- data/lib/ea/qea/infrastructure/table_reader.rb +9 -0
- data/lib/ea/qea/models/ea_author.rb +35 -0
- data/lib/ea/qea/models/ea_glossary.rb +34 -0
- data/lib/ea/qea/models/ea_image.rb +53 -0
- data/lib/ea/qea/models/ea_implement.rb +32 -0
- data/lib/ea/qea/models/ea_list.rb +42 -0
- data/lib/ea/qea/models/ea_object_effort.rb +34 -0
- data/lib/ea/qea/models/ea_object_problem.rb +37 -0
- data/lib/ea/qea/models/ea_object_require.rb +34 -0
- data/lib/ea/qea/models/ea_object_resource.rb +34 -0
- data/lib/ea/qea/models/ea_object_risk.rb +34 -0
- data/lib/ea/qea/models/ea_object_scenario.rb +34 -0
- data/lib/ea/qea/models/ea_object_test.rb +35 -0
- data/lib/ea/qea/models/ea_object_trx.rb +34 -0
- data/lib/ea/qea/models/ea_operation.rb +7 -0
- data/lib/ea/qea/models/ea_palette.rb +30 -0
- data/lib/ea/qea/models/ea_palette_item.rb +36 -0
- data/lib/ea/qea/models/ea_phase.rb +40 -0
- data/lib/ea/qea/models/ea_role_constraint.rb +32 -0
- data/lib/ea/qea/models/ea_secrypt.rb +34 -0
- data/lib/ea/qea/models/ea_version.rb +39 -0
- data/lib/ea/qea/models/ea_xref.rb +11 -1
- data/lib/ea/qea/models.rb +19 -0
- data/lib/ea/qea/services/database_loader.rb +22 -1
- data/lib/ea/query/builder.rb +108 -0
- data/lib/ea/query.rb +9 -0
- data/lib/ea/render/image_converter.rb +101 -0
- data/lib/ea/render.rb +10 -0
- data/lib/ea/shapescript/parser.rb +208 -0
- data/lib/ea/shapescript/renderer.rb +74 -0
- data/lib/ea/shapescript/shape.rb +34 -0
- data/lib/ea/shapescript.rb +24 -0
- data/lib/ea/sources/qea/adapter.rb +22 -5
- data/lib/ea/sources/qea/classifier_builder.rb +184 -7
- data/lib/ea/sources/qea/diagram_builder.rb +352 -24
- data/lib/ea/sources/qea/id_normalizer.rb +16 -1
- data/lib/ea/sources/qea/instance_builder.rb +113 -0
- data/lib/ea/sources/qea/legend_builder.rb +137 -0
- data/lib/ea/sources/qea/note_builder.rb +58 -0
- data/lib/ea/sources/qea/object_classifier_map.rb +6 -1
- data/lib/ea/sources/qea/operation_builder.rb +1 -0
- data/lib/ea/sources/qea/package_builder.rb +16 -0
- data/lib/ea/sources/qea/relationship_builder.rb +21 -5
- data/lib/ea/sources/qea/tagged_value_builder.rb +28 -9
- data/lib/ea/sources/qea/xref/legend_definition.rb +35 -0
- data/lib/ea/sources/qea/xref/parser.rb +150 -0
- data/lib/ea/sources/qea/xref/property_definition.rb +29 -0
- data/lib/ea/sources/qea/xref/record.rb +41 -0
- data/lib/ea/sources/qea/xref/stereotype_application.rb +37 -0
- data/lib/ea/sources/qea/xref.rb +27 -0
- data/lib/ea/sources/qea.rb +4 -0
- data/lib/ea/sources/xmi/adapter.rb +80 -2
- data/lib/ea/sources/xmi/annotation_builder.rb +1 -1
- data/lib/ea/sources/xmi/classifier_builder.rb +10 -1
- data/lib/ea/sources/xmi/diagram_builder.rb +242 -45
- data/lib/ea/sources/xmi/extension_elements.rb +74 -0
- data/lib/ea/sources/xmi/extension_geometry_parser.rb +124 -0
- data/lib/ea/sources/xmi/extension_style_parser.rb +91 -0
- data/lib/ea/sources/xmi/note_builder.rb +46 -0
- data/lib/ea/sources/xmi/property_builder.rb +9 -0
- data/lib/ea/sources/xmi/stereotype_builder.rb +54 -0
- data/lib/ea/sources/xmi/tag_builder.rb +45 -0
- data/lib/ea/sources/xmi/umldi_keyword_extractor.rb +87 -0
- data/lib/ea/sources/xmi.rb +7 -0
- data/lib/ea/spa/output/sharded_multi_file_strategy.rb +18 -3
- data/lib/ea/spa/output/single_file_strategy.rb +8 -2
- data/lib/ea/spa/output/strategy.rb +34 -0
- data/lib/ea/svg/connector_router.rb +134 -0
- data/lib/ea/svg/ea_emitter/background.rb +15 -0
- data/lib/ea/svg/ea_emitter/bounds_calculator.rb +142 -0
- data/lib/ea/svg/ea_emitter/canvas.rb +88 -0
- data/lib/ea/svg/ea_emitter/color_resolver.rb +56 -0
- data/lib/ea/svg/ea_emitter/compartment/attributes.rb +28 -0
- data/lib/ea/svg/ea_emitter/compartment/constraints.rb +30 -0
- data/lib/ea/svg/ea_emitter/compartment/enum_literals.rb +86 -0
- data/lib/ea/svg/ea_emitter/compartment/header.rb +32 -0
- data/lib/ea/svg/ea_emitter/compartment/header_divider.rb +57 -0
- data/lib/ea/svg/ea_emitter/compartment/instance_slots.rb +96 -0
- data/lib/ea/svg/ea_emitter/compartment/instance_underline.rb +67 -0
- data/lib/ea/svg/ea_emitter/compartment/note_body.rb +52 -0
- data/lib/ea/svg/ea_emitter/compartment/note_text.rb +102 -0
- data/lib/ea/svg/ea_emitter/compartment/operations.rb +38 -0
- data/lib/ea/svg/ea_emitter/compartment/package_contents.rb +72 -0
- data/lib/ea/svg/ea_emitter/compartment/package_from_parent.rb +136 -0
- data/lib/ea/svg/ea_emitter/compartment/shape.rb +82 -0
- data/lib/ea/svg/ea_emitter/compartment/tagged_values.rb +30 -0
- data/lib/ea/svg/ea_emitter/compartment.rb +58 -0
- data/lib/ea/svg/ea_emitter/connectors.rb +84 -0
- data/lib/ea/svg/ea_emitter/diagram_frame.rb +143 -0
- data/lib/ea/svg/ea_emitter/document.rb +35 -0
- data/lib/ea/svg/ea_emitter/element/attribute_line_builder.rb +117 -0
- data/lib/ea/svg/ea_emitter/element/attribute_renderer.rb +119 -0
- data/lib/ea/svg/ea_emitter/element/bcol_decoder.rb +29 -0
- data/lib/ea/svg/ea_emitter/element/compartment_geometry.rb +113 -0
- data/lib/ea/svg/ea_emitter/element/constraint_renderer.rb +53 -0
- data/lib/ea/svg/ea_emitter/element/divider_renderer.rb +17 -0
- data/lib/ea/svg/ea_emitter/element/enumeration_literal_renderer.rb +34 -0
- data/lib/ea/svg/ea_emitter/element/filter.rb +44 -0
- data/lib/ea/svg/ea_emitter/element/hand_draw_shape_renderer.rb +77 -0
- data/lib/ea/svg/ea_emitter/element/header_line_pipeline.rb +43 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/instance_spec.rb +27 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/name.rb +76 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/parent_ghost.rb +25 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/stereotype_label.rb +68 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider.rb +19 -0
- data/lib/ea/svg/ea_emitter/element/header_lines.rb +27 -0
- data/lib/ea/svg/ea_emitter/element/header_renderer.rb +48 -0
- data/lib/ea/svg/ea_emitter/element/icon_renderer.rb +109 -0
- data/lib/ea/svg/ea_emitter/element/legend_renderer.rb +177 -0
- data/lib/ea/svg/ea_emitter/element/note_shape_renderer.rb +112 -0
- data/lib/ea/svg/ea_emitter/element/operation_renderer.rb +100 -0
- data/lib/ea/svg/ea_emitter/element/package_shape_renderer.rb +181 -0
- data/lib/ea/svg/ea_emitter/element/row_icon_renderer.rb +156 -0
- data/lib/ea/svg/ea_emitter/element/shape_renderer.rb +17 -0
- data/lib/ea/svg/ea_emitter/element/stereotype_icon_renderer.rb +82 -0
- data/lib/ea/svg/ea_emitter/element/tagged_value_renderer.rb +50 -0
- data/lib/ea/svg/ea_emitter/element/text_escape.rb +20 -0
- data/lib/ea/svg/ea_emitter/element.rb +37 -0
- data/lib/ea/svg/ea_emitter/elements.rb +357 -0
- data/lib/ea/svg/ea_emitter/font_resolver.rb +111 -0
- data/lib/ea/svg/ea_emitter/ghost_labels.rb +66 -0
- data/lib/ea/svg/ea_emitter/label/end_label.rb +266 -0
- data/lib/ea/svg/ea_emitter/label/midpoint_label.rb +101 -0
- data/lib/ea/svg/ea_emitter/label/registry.rb +50 -0
- data/lib/ea/svg/ea_emitter/label.rb +23 -0
- data/lib/ea/svg/ea_emitter/labels.rb +130 -0
- data/lib/ea/svg/ea_emitter/layer.rb +20 -0
- data/lib/ea/svg/ea_emitter/layer_sequencer.rb +93 -0
- data/lib/ea/svg/ea_emitter/marker/arrow_path.rb +52 -0
- data/lib/ea/svg/ea_emitter/marker/diamond.rb +57 -0
- data/lib/ea/svg/ea_emitter/marker/kind.rb +35 -0
- data/lib/ea/svg/ea_emitter/marker/open_triangle.rb +27 -0
- data/lib/ea/svg/ea_emitter/marker/package_import.rb +39 -0
- data/lib/ea/svg/ea_emitter/marker/plus.rb +40 -0
- data/lib/ea/svg/ea_emitter/marker/registry.rb +42 -0
- data/lib/ea/svg/ea_emitter/marker.rb +37 -0
- data/lib/ea/svg/ea_emitter/markers.rb +404 -0
- data/lib/ea/svg/ea_emitter/render_context.rb +52 -0
- data/lib/ea/svg/ea_emitter/style.rb +15 -0
- data/lib/ea/svg/ea_emitter/text_renderer.rb +92 -0
- data/lib/ea/svg/ea_emitter.rb +51 -0
- data/lib/ea/svg/parity/checker.rb +105 -0
- data/lib/ea/svg/parity/source.rb +59 -0
- data/lib/ea/svg/parity/suite.rb +113 -0
- data/lib/ea/svg/parity.rb +14 -0
- data/lib/ea/svg/stereotype_color_resolver.rb +50 -0
- data/lib/ea/svg.rb +4 -15
- data/lib/ea/theme/definition.rb +176 -0
- data/lib/ea/theme/loader.rb +125 -0
- data/lib/ea/theme/registry.rb +96 -0
- data/lib/ea/theme.rb +37 -0
- data/lib/ea/transformations.rb +5 -88
- data/lib/ea/version.rb +4 -1
- data/lib/ea.rb +14 -4
- data/lib/tasks/svg_bench.rake +87 -0
- data/lutaml-uml-0.5.1.gem +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes-list.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-2-gradients.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-3-colors.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance-fonts.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-5-behavior.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-6-sequence.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-2-objects.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-3-links.png +0 -0
- metadata +473 -26
- data/lib/ea/diagram/configuration.rb +0 -379
- data/lib/ea/diagram/element_renderers/base_renderer.rb +0 -77
- data/lib/ea/diagram/element_renderers/class_renderer.rb +0 -323
- data/lib/ea/diagram/element_renderers/connector_renderer.rb +0 -41
- data/lib/ea/diagram/element_renderers/package_renderer.rb +0 -61
- data/lib/ea/diagram/element_renderers.rb +0 -43
- data/lib/ea/diagram/extractor.rb +0 -566
- data/lib/ea/diagram/layout_engine.rb +0 -170
- data/lib/ea/diagram/path_builder.rb +0 -202
- data/lib/ea/diagram/style_parser.rb +0 -42
- data/lib/ea/diagram/style_resolver.rb +0 -291
- data/lib/ea/diagram/svg_renderer.rb +0 -274
- data/lib/ea/diagram/util.rb +0 -73
- data/lib/ea/svg/bounds_calculator.rb +0 -74
- data/lib/ea/svg/connector_path.rb +0 -138
- data/lib/ea/svg/element_box.rb +0 -256
- data/lib/ea/svg/renderer.rb +0 -77
- data/lib/ea/svg/style_resolver.rb +0 -72
- data/lib/ea/transformations/configuration.rb +0 -333
- data/lib/ea/transformations/format_registry.rb +0 -366
- data/lib/ea/transformations/parsers/base_parser.rb +0 -482
- data/lib/ea/transformations/parsers/qea_parser.rb +0 -401
- data/lib/ea/transformations/parsers/xmi_parser.rb +0 -243
- data/lib/ea/transformations/transformation_engine.rb +0 -390
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ea
|
|
4
|
+
module Svg
|
|
5
|
+
module EaEmitter
|
|
6
|
+
# Emits marker `<polygon>` and `<path>` elements per connector,
|
|
7
|
+
# matching EA's encoding rules. Returns an Array of `Layer`
|
|
8
|
+
# structs bucketed by marker style.
|
|
9
|
+
#
|
|
10
|
+
# Layer style keys:
|
|
11
|
+
# - :diamond_filled → 4-pt <polygon>, black fill
|
|
12
|
+
# - :triangle_open → 3-pt <polygon>, white fill
|
|
13
|
+
# - :arrow → 3-pt <path>, no fill (shares style with
|
|
14
|
+
# connector lines — same stroke, no fill)
|
|
15
|
+
#
|
|
16
|
+
# Default mode (`grouped: true`) consolidates all markers of
|
|
17
|
+
# the same style into ONE `<g>`. Pass `grouped: false` for
|
|
18
|
+
# per-connector grouping.
|
|
19
|
+
class Markers
|
|
20
|
+
DIAMOND_HALF_W = 5
|
|
21
|
+
DIAMOND_HALF_H = 10
|
|
22
|
+
TRI_HALF_BASE = 6
|
|
23
|
+
TRI_HEIGHT = 11
|
|
24
|
+
ARROW_HALF_BASE = 6
|
|
25
|
+
ARROW_HEIGHT = 11
|
|
26
|
+
|
|
27
|
+
attr_reader :diagram, :model_index, :canvas, :grouped, :stroke_width
|
|
28
|
+
|
|
29
|
+
def initialize(diagram, model_index:, canvas: nil, grouped: true, stroke_width: 2)
|
|
30
|
+
@diagram = diagram
|
|
31
|
+
@model_index = model_index
|
|
32
|
+
@canvas = canvas
|
|
33
|
+
@grouped = grouped
|
|
34
|
+
@stroke_width = stroke_width
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def layers
|
|
38
|
+
entries = visible_connectors.flat_map { |c| entries_for(c) }
|
|
39
|
+
return [] if entries.empty?
|
|
40
|
+
|
|
41
|
+
if grouped
|
|
42
|
+
entries.group_by(&:style_key).map do |key, grouped_entries|
|
|
43
|
+
# EA emits ONE marker per connector regardless of
|
|
44
|
+
# anchor overlap. Verified against plateau Bridge
|
|
45
|
+
# diagram: 9 generalizations fanning from the same
|
|
46
|
+
# parent anchor produce 9 distinct triangle polygons
|
|
47
|
+
# at the same coordinates. The earlier "dedup by
|
|
48
|
+
# anchor" hypothesis is disproven by reference SVGs.
|
|
49
|
+
Layer.new(style_key: key,
|
|
50
|
+
style: style_for(key),
|
|
51
|
+
body: grouped_entries.map(&:body).join("\n "))
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
entries.map { |e| Layer.new(style_key: e.style_key, style: style_for(e.style_key), body: e.body) }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def render
|
|
59
|
+
layers.map(&:to_svg).join("\n")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Backwards-compatible API: count of marker bodies emitted.
|
|
63
|
+
def count_for(connector)
|
|
64
|
+
return 0 if connector.hidden
|
|
65
|
+
return 0 unless connector.waypoints&.any? { |w| w.position }
|
|
66
|
+
|
|
67
|
+
entries_for(connector).size
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# Entry pairs the rendered SVG body with the structural
|
|
73
|
+
# anchor (rounded integer [x, y] pair). Anchor is retained
|
|
74
|
+
# for future use (e.g. overlap diagnostics) but no longer
|
|
75
|
+
# drives dedup — EA emits one marker per connector.
|
|
76
|
+
Entry = Struct.new(:style_key, :body, :anchor,
|
|
77
|
+
:connector_waypoint_count,
|
|
78
|
+
keyword_init: true) do
|
|
79
|
+
def hash
|
|
80
|
+
anchor.hash
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def eql?(other)
|
|
84
|
+
other.is_a?(Entry) && anchor == other.anchor
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def style_for(key)
|
|
89
|
+
case key
|
|
90
|
+
when :diamond_filled
|
|
91
|
+
"stroke-width:#{stroke_width};stroke-linecap:round;stroke-linejoin:bevel; fill:#000000;fill-opacity:1.00; stroke:#000000; stroke-opacity:1.00"
|
|
92
|
+
when :triangle_open
|
|
93
|
+
"stroke-width:#{stroke_width};stroke-linecap:round;stroke-linejoin:bevel; fill:#FFFFFF;fill-opacity:1.00; stroke:#000000; stroke-opacity:1.00"
|
|
94
|
+
when :connector_line
|
|
95
|
+
"stroke-width:#{stroke_width};stroke-linecap:round;stroke-linejoin:bevel; fill:#000000;fill-opacity:0.00; stroke:#000000; stroke-opacity:1.00"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def visible_connectors
|
|
100
|
+
(diagram.connectors || []).select(&:renderable?)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def entries_for(connector)
|
|
104
|
+
specs = specs_for(connector)
|
|
105
|
+
waypoint_count = waypoint_pairs(connector).size
|
|
106
|
+
specs.filter_map do |spec|
|
|
107
|
+
next nil if suppress_arrow?(spec, connector)
|
|
108
|
+
|
|
109
|
+
body = render_shape(spec)
|
|
110
|
+
next nil unless body
|
|
111
|
+
|
|
112
|
+
Entry.new(style_key: style_key_for(spec),
|
|
113
|
+
body: body,
|
|
114
|
+
anchor: anchor_for(spec),
|
|
115
|
+
connector_waypoint_count: waypoint_count)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Suppress arrow markers when:
|
|
120
|
+
# 1. The diagram is an Object diagram (instance links).
|
|
121
|
+
# 2. The connector is an unidirectional Association with
|
|
122
|
+
# significant waypoint deviation from a straight line
|
|
123
|
+
# (> 3px). EA treats connectors with small deviations as
|
|
124
|
+
# straight (WITH arrow); large deviations are orthogonal/
|
|
125
|
+
# tree-routed (NO arrow). Bidirectional associations always
|
|
126
|
+
# show arrows at both ends regardless of routing.
|
|
127
|
+
BEND_DEVIATION_THRESHOLD = 3
|
|
128
|
+
|
|
129
|
+
def suppress_arrow?(spec, connector)
|
|
130
|
+
return false unless spec.shape == :arrow
|
|
131
|
+
return true if object_diagram? && association?(connector)
|
|
132
|
+
return false if connector.direction == "Bi-Directional"
|
|
133
|
+
return true if horizontal_tree_routed?(connector)
|
|
134
|
+
|
|
135
|
+
false
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# A "horizontal tree-routed" connector has its source and
|
|
139
|
+
# target endpoints at the SAME y-coordinate with interior
|
|
140
|
+
# waypoints deviating above and below — the classic EA tree
|
|
141
|
+
# routing pattern where multiple connectors fan out from a
|
|
142
|
+
# shared parent at the same height. These don't render arrow
|
|
143
|
+
# markers in basic.qea Classes diagrams. This check is
|
|
144
|
+
# deliberately narrow to avoid suppressing arrows on plateau
|
|
145
|
+
# connectors where source and target are at different heights.
|
|
146
|
+
def horizontal_tree_routed?(connector)
|
|
147
|
+
return false unless association?(connector)
|
|
148
|
+
return false if object_diagram?
|
|
149
|
+
|
|
150
|
+
points = waypoint_pairs(connector)
|
|
151
|
+
return false if points.size < 4
|
|
152
|
+
|
|
153
|
+
source = points.first
|
|
154
|
+
target = points.last
|
|
155
|
+
return false unless source[1] == target[1]
|
|
156
|
+
|
|
157
|
+
max_bend_deviation(connector) > BEND_DEVIATION_THRESHOLD
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def tree_routed_association?(connector)
|
|
161
|
+
return false unless association?(connector)
|
|
162
|
+
return false if object_diagram?
|
|
163
|
+
return false if connector.direction == "Bi-Directional"
|
|
164
|
+
|
|
165
|
+
# Only apply the tree-routed heuristic to connectors with
|
|
166
|
+
# 4+ waypoints AND significant bend deviation. 3-waypoint
|
|
167
|
+
# connectors with a single bend are too common on plateau
|
|
168
|
+
# to suppress reliably.
|
|
169
|
+
points = waypoint_pairs(connector)
|
|
170
|
+
return false if points.size < 4
|
|
171
|
+
|
|
172
|
+
max_bend_deviation(connector) > BEND_DEVIATION_THRESHOLD
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def max_bend_deviation(connector)
|
|
176
|
+
points = waypoint_pairs(connector)
|
|
177
|
+
return 0 if points.size < 3
|
|
178
|
+
|
|
179
|
+
source = points.first
|
|
180
|
+
target = points.last
|
|
181
|
+
interior = points[1..-2]
|
|
182
|
+
interior.map { |p| perpendicular_distance(p, source, target) }.max || 0
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def perpendicular_distance(point, line_start, line_end)
|
|
186
|
+
px, py = point
|
|
187
|
+
x1, y1 = line_start
|
|
188
|
+
x2, y2 = line_end
|
|
189
|
+
dx = x2 - x1
|
|
190
|
+
dy = y2 - y1
|
|
191
|
+
length_sq = dx * dx + dy * dy
|
|
192
|
+
return 0 if length_sq.zero?
|
|
193
|
+
|
|
194
|
+
((dy * px - dx * py + x2 * y1 - y2 * x1).abs / Math.sqrt(length_sq)).round
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def association?(connector)
|
|
198
|
+
effective_type(connector) == "Association"
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def object_diagram?
|
|
202
|
+
diagram.diagram_type == "Object"
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Rounded [x, y] of the marker's tip (anchor) in canvas
|
|
206
|
+
# coordinates. Used for deduplication.
|
|
207
|
+
def anchor_for(spec)
|
|
208
|
+
tx, ty = translate_point(spec.anchor)
|
|
209
|
+
[tx.round, ty.round]
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def style_key_for(spec)
|
|
213
|
+
case spec.shape
|
|
214
|
+
when :diamond then :diamond_filled
|
|
215
|
+
when :triangle then :triangle_open
|
|
216
|
+
when :plus then :connector_line # shares style with line <g>
|
|
217
|
+
when :arrow then :connector_line # share with line <g>
|
|
218
|
+
when :package_anchor then :connector_line
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Rounded [x, y] of the marker's tip (anchor) in canvas
|
|
223
|
+
# coordinates. Used for deduplication.
|
|
224
|
+
def anchor_for(spec)
|
|
225
|
+
tx, ty = translate_point(spec.anchor)
|
|
226
|
+
[tx.round, ty.round]
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def render_shape(spec)
|
|
230
|
+
case spec.shape
|
|
231
|
+
when :diamond then diamond_polygon(spec.anchor, spec.base)
|
|
232
|
+
when :triangle then triangle_polygon(spec.anchor, spec.base)
|
|
233
|
+
when :plus then plus_path(spec.anchor)
|
|
234
|
+
when :arrow then arrow_path(spec.anchor, spec.base)
|
|
235
|
+
when :package_anchor then package_anchor_path(spec.anchor, spec.base)
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Plus marker: two crossed line segments at the anchor.
|
|
240
|
+
# EA encodes as one <path> with two sub-paths:
|
|
241
|
+
# M cx cy-8 L cx cy+8 (vertical arm)
|
|
242
|
+
# M cx+8 cy L cx-8 cy (horizontal arm)
|
|
243
|
+
def plus_path(anchor)
|
|
244
|
+
cx, cy = translate_point(anchor)
|
|
245
|
+
cx_str = Canvas.coord(cx)
|
|
246
|
+
cy_str = Canvas.coord(cy)
|
|
247
|
+
up = Canvas.coord(cy - Marker::Plus::ARM_LENGTH)
|
|
248
|
+
down = Canvas.coord(cy + Marker::Plus::ARM_LENGTH)
|
|
249
|
+
left = Canvas.coord(cx - Marker::Plus::ARM_LENGTH)
|
|
250
|
+
right = Canvas.coord(cx + Marker::Plus::ARM_LENGTH)
|
|
251
|
+
d = "M #{cx_str} #{up} L #{cx_str} #{down} M #{right} #{cy_str} L #{left} #{cy_str}"
|
|
252
|
+
%(<path d="#{d}" shape-rendering="auto"/>)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def specs_for(connector)
|
|
256
|
+
points = waypoint_pairs(connector)
|
|
257
|
+
return [] if points.size < 2
|
|
258
|
+
|
|
259
|
+
source = points.first
|
|
260
|
+
target = points.last
|
|
261
|
+
before_target = points[-2] || source
|
|
262
|
+
after_source = points[1] || target
|
|
263
|
+
Marker::Registry.specs_for(connector,
|
|
264
|
+
effective_type(connector),
|
|
265
|
+
source, target,
|
|
266
|
+
before_target, after_source,
|
|
267
|
+
relationship: relationship_for(connector))
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def effective_type(connector)
|
|
271
|
+
return connector.connector_type if connector.connector_type
|
|
272
|
+
|
|
273
|
+
rel = relationship_for(connector)
|
|
274
|
+
return "Association" unless rel
|
|
275
|
+
|
|
276
|
+
# Use the polymorphic kind field rather than class-name
|
|
277
|
+
# inspection - subclasses set `relationship_kind` at the
|
|
278
|
+
# model level (e.g. Association → "association", which we
|
|
279
|
+
# then capitalize to match EA's Connector_Type).
|
|
280
|
+
kind = rel.relationship_kind || "association"
|
|
281
|
+
kind.capitalize
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def relationship_for(connector)
|
|
285
|
+
return nil unless connector.relationship_ref && model_index
|
|
286
|
+
|
|
287
|
+
model_index[connector.relationship_ref]
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def diamond_polygon(tip, base)
|
|
291
|
+
tx, ty = translate_point(tip)
|
|
292
|
+
bx, by = translate_point(base)
|
|
293
|
+
ux, uy = unit_vector(tx, ty, bx, by)
|
|
294
|
+
return nil unless ux
|
|
295
|
+
|
|
296
|
+
right_x = tx - ux * DIAMOND_HALF_H + (-uy) * DIAMOND_HALF_W
|
|
297
|
+
right_y = ty - uy * DIAMOND_HALF_H + ux * DIAMOND_HALF_W
|
|
298
|
+
back_x = tx - ux * (DIAMOND_HALF_H * 2)
|
|
299
|
+
back_y = ty - uy * (DIAMOND_HALF_H * 2)
|
|
300
|
+
left_x = tx - ux * DIAMOND_HALF_H - (-uy) * DIAMOND_HALF_W
|
|
301
|
+
left_y = ty - uy * DIAMOND_HALF_H - ux * DIAMOND_HALF_W
|
|
302
|
+
pts = [
|
|
303
|
+
Canvas.coord(tx), Canvas.coord(ty),
|
|
304
|
+
Canvas.coord(right_x), Canvas.coord(right_y),
|
|
305
|
+
Canvas.coord(back_x), Canvas.coord(back_y),
|
|
306
|
+
Canvas.coord(left_x), Canvas.coord(left_y)
|
|
307
|
+
].join(" ")
|
|
308
|
+
%(<polygon points="#{pts}" shape-rendering="auto" style="fill-rule:evenodd;"/>)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def triangle_polygon(tip, base)
|
|
312
|
+
tx, ty = translate_point(tip)
|
|
313
|
+
bx, by = translate_point(base)
|
|
314
|
+
ux, uy = unit_vector(tx, ty, bx, by)
|
|
315
|
+
return nil unless ux
|
|
316
|
+
|
|
317
|
+
back_x = tx - ux * TRI_HEIGHT
|
|
318
|
+
back_y = ty - uy * TRI_HEIGHT
|
|
319
|
+
w1_x = back_x + (-uy) * TRI_HALF_BASE
|
|
320
|
+
w1_y = back_y + ux * TRI_HALF_BASE
|
|
321
|
+
w2_x = back_x - (-uy) * TRI_HALF_BASE
|
|
322
|
+
w2_y = back_y - ux * TRI_HALF_BASE
|
|
323
|
+
pts = [
|
|
324
|
+
Canvas.coord(tx), Canvas.coord(ty),
|
|
325
|
+
Canvas.coord(w1_x), Canvas.coord(w1_y),
|
|
326
|
+
Canvas.coord(w2_x), Canvas.coord(w2_y)
|
|
327
|
+
].join(" ")
|
|
328
|
+
%(<polygon points="#{pts}" shape-rendering="auto" style="fill-rule:evenodd;"/>)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def arrow_path(tip, base)
|
|
332
|
+
tx, ty = translate_point(tip)
|
|
333
|
+
bx, by = translate_point(base)
|
|
334
|
+
ux, uy = unit_vector(tx, ty, bx, by)
|
|
335
|
+
return nil unless ux
|
|
336
|
+
|
|
337
|
+
back_x = tx - ux * ARROW_HEIGHT
|
|
338
|
+
back_y = ty - uy * ARROW_HEIGHT
|
|
339
|
+
w1_x = back_x + (-uy) * ARROW_HALF_BASE
|
|
340
|
+
w1_y = back_y + ux * ARROW_HALF_BASE
|
|
341
|
+
w2_x = back_x - (-uy) * ARROW_HALF_BASE
|
|
342
|
+
w2_y = back_y - ux * ARROW_HALF_BASE
|
|
343
|
+
d = "M #{Canvas.coord(w1_x)} #{Canvas.coord(w1_y)} L #{Canvas.coord(tx)} #{Canvas.coord(ty)} L #{Canvas.coord(w2_x)} #{Canvas.coord(w2_y)}"
|
|
344
|
+
%(<path d="#{d}" shape-rendering="auto"/>)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
# «import» source-end marker: a small closed trapezoid that
|
|
348
|
+
# visually represents the imported package. Shape is a 4-point
|
|
349
|
+
# polygon: top edge shorter than bottom edge, centered on the
|
|
350
|
+
# anchor point.
|
|
351
|
+
PACKAGE_ANCHOR_W = 5
|
|
352
|
+
PACKAGE_ANCHOR_H_TOP = 3
|
|
353
|
+
PACKAGE_ANCHOR_H_BOTTOM = 4
|
|
354
|
+
|
|
355
|
+
def package_anchor_path(tip, base)
|
|
356
|
+
tx, ty = translate_point(tip)
|
|
357
|
+
bx, by = translate_point(base)
|
|
358
|
+
ux, uy = unit_vector(tx, ty, bx, by)
|
|
359
|
+
return nil unless ux
|
|
360
|
+
|
|
361
|
+
back_x = tx - ux * PACKAGE_ANCHOR_H_BOTTOM
|
|
362
|
+
back_y = ty - uy * PACKAGE_ANCHOR_H_BOTTOM
|
|
363
|
+
tl_x = tx - ux * PACKAGE_ANCHOR_H_TOP + (-uy) * PACKAGE_ANCHOR_W
|
|
364
|
+
tl_y = ty - uy * PACKAGE_ANCHOR_H_TOP + ux * PACKAGE_ANCHOR_W
|
|
365
|
+
tr_x = tx - ux * PACKAGE_ANCHOR_H_TOP - (-uy) * PACKAGE_ANCHOR_W
|
|
366
|
+
tr_y = ty - uy * PACKAGE_ANCHOR_H_TOP - ux * PACKAGE_ANCHOR_W
|
|
367
|
+
bl_x = back_x + (-uy) * (PACKAGE_ANCHOR_W + 1)
|
|
368
|
+
bl_y = back_y + ux * (PACKAGE_ANCHOR_W + 1)
|
|
369
|
+
br_x = back_x - (-uy) * (PACKAGE_ANCHOR_W + 1)
|
|
370
|
+
br_y = back_y - ux * (PACKAGE_ANCHOR_W + 1)
|
|
371
|
+
d = "M #{Canvas.coord(tl_x)} #{Canvas.coord(tl_y)} " \
|
|
372
|
+
"L #{Canvas.coord(tr_x)} #{Canvas.coord(tr_y)} " \
|
|
373
|
+
"L #{Canvas.coord(br_x)} #{Canvas.coord(br_y)} " \
|
|
374
|
+
"L #{Canvas.coord(bl_x)} #{Canvas.coord(bl_y)} " \
|
|
375
|
+
"L #{Canvas.coord(tl_x)} #{Canvas.coord(tl_y)} Z"
|
|
376
|
+
%(<path d="#{d}" shape-rendering="auto"/>)
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def unit_vector(tx, ty, bx, by)
|
|
380
|
+
dx = tx - bx
|
|
381
|
+
dy = ty - by
|
|
382
|
+
len = Math.sqrt(dx * dx + dy * dy)
|
|
383
|
+
return nil if len.zero?
|
|
384
|
+
|
|
385
|
+
[dx / len, dy / len]
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def translate_point(p)
|
|
389
|
+
return p unless @canvas
|
|
390
|
+
|
|
391
|
+
[@canvas.translate_x(p[0]), @canvas.translate_y(p[1])]
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
def waypoint_pairs(connector)
|
|
395
|
+
(connector.waypoints || []).filter_map do |w|
|
|
396
|
+
next unless w.position
|
|
397
|
+
|
|
398
|
+
[w.position.x, w.position.y]
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ea
|
|
4
|
+
module Svg
|
|
5
|
+
module EaEmitter
|
|
6
|
+
# Per-element render context. Holds the immutable inputs each
|
|
7
|
+
# compartment renderer needs (bounds, classifier, fill/stroke,
|
|
8
|
+
# font, geometry, line data). Built once per element; passed
|
|
9
|
+
# to every compartment in the pipeline so they don't reach
|
|
10
|
+
# back into the parent Elements orchestrator.
|
|
11
|
+
#
|
|
12
|
+
# Value object: equality by structural attributes. Each
|
|
13
|
+
# instance is frozen after construction.
|
|
14
|
+
class RenderContext < Struct.new(
|
|
15
|
+
:element, :bounds, :model_element, :classifier,
|
|
16
|
+
:fill, :stroke, :stroke_width, :text_fill,
|
|
17
|
+
:family, :size, :size_unit,
|
|
18
|
+
:header_lines, :attr_lines, :op_lines,
|
|
19
|
+
:enum_literals, :tagged_values, :constraints,
|
|
20
|
+
:package_content_lines,
|
|
21
|
+
:geometry, :theme, :canvas, :diagram, :model_index,
|
|
22
|
+
:off_canvas_parent_name,
|
|
23
|
+
keyword_init: true
|
|
24
|
+
)
|
|
25
|
+
def note_body
|
|
26
|
+
return nil unless model_element.is_a?(Ea::Model::Note)
|
|
27
|
+
|
|
28
|
+
body = model_element.body
|
|
29
|
+
body.nil? || body.empty? ? nil : body
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Resolve a model element by id via the threaded model index.
|
|
33
|
+
# Returns nil when no index is wired in or the id is absent.
|
|
34
|
+
def model_index_for(id)
|
|
35
|
+
return nil unless model_index && id
|
|
36
|
+
|
|
37
|
+
model_index[id]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Compartments below the header that produce a divider when
|
|
41
|
+
# any of them has content. Returns true when at least one
|
|
42
|
+
# is non-empty.
|
|
43
|
+
def content_below_header?
|
|
44
|
+
!attr_lines.empty? || !op_lines.empty? ||
|
|
45
|
+
enum_literals.any? || tagged_values.any? ||
|
|
46
|
+
(constraints&.any?) ||
|
|
47
|
+
(!package_content_lines.nil? && !package_content_lines.empty?)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ea
|
|
4
|
+
module Svg
|
|
5
|
+
module EaEmitter
|
|
6
|
+
# Centralizes SVG style strings used across emitters.
|
|
7
|
+
# Connector and marker styles are now computed dynamically
|
|
8
|
+
# via stroke_width parameter — only TEXT_GROUP remains as
|
|
9
|
+
# a constant (shared across all text-emitting renderers).
|
|
10
|
+
module Style
|
|
11
|
+
TEXT_GROUP = "stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel; fill:#000000;fill-opacity:1.00; stroke:#000000; stroke-opacity:0.00"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ea
|
|
4
|
+
module Svg
|
|
5
|
+
module EaEmitter
|
|
6
|
+
# Single source of truth for emitting `<text>` SVG elements.
|
|
7
|
+
# Handles:
|
|
8
|
+
#
|
|
9
|
+
# - Decimal `x`/`y` formatting (`%.2f`): matches EA's
|
|
10
|
+
# `x="11.00" y="19.00"` encoding.
|
|
11
|
+
# - Always-present rotation transform: even when rotation is 0,
|
|
12
|
+
# EA emits `transform="rotate(-0.00 X Y)"`.
|
|
13
|
+
# - Proper XML escaping of content.
|
|
14
|
+
# - Optional `textLength` integer (computed by caller).
|
|
15
|
+
#
|
|
16
|
+
# Replaces the duplicated `build_text` helpers across
|
|
17
|
+
# HeaderRenderer, AttributeRenderer, OperationRenderer,
|
|
18
|
+
# EnumerationLiteralRenderer, Labels, and DiagramFrame.
|
|
19
|
+
class TextRenderer
|
|
20
|
+
DEFAULT_FILL = "#000000"
|
|
21
|
+
DEFAULT_ROTATION = -0.00
|
|
22
|
+
DEFAULT_STROKE_IN_TEXT = "#000000"
|
|
23
|
+
DEFAULT_WIDTH_FACTOR = 0.65
|
|
24
|
+
|
|
25
|
+
attr_reader :content, :x, :y, :family, :size, :weight, :style,
|
|
26
|
+
:fill, :text_length, :rotation, :size_unit,
|
|
27
|
+
:stroke_in_text, :width_factor
|
|
28
|
+
|
|
29
|
+
def initialize(content:, x:, y:, family:, size:, weight: 400,
|
|
30
|
+
style: "normal", fill: DEFAULT_FILL,
|
|
31
|
+
text_length: nil, rotation: DEFAULT_ROTATION,
|
|
32
|
+
size_unit: "px",
|
|
33
|
+
stroke_in_text: DEFAULT_STROKE_IN_TEXT,
|
|
34
|
+
width_factor: DEFAULT_WIDTH_FACTOR)
|
|
35
|
+
@content = content.to_s
|
|
36
|
+
@x = x
|
|
37
|
+
@y = y
|
|
38
|
+
@family = family
|
|
39
|
+
@size = size
|
|
40
|
+
@weight = weight
|
|
41
|
+
@style = style
|
|
42
|
+
@fill = fill
|
|
43
|
+
@text_length = text_length
|
|
44
|
+
@rotation = rotation
|
|
45
|
+
@size_unit = size_unit
|
|
46
|
+
@stroke_in_text = stroke_in_text
|
|
47
|
+
@width_factor = width_factor
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def to_svg
|
|
51
|
+
attrs = format_attrs
|
|
52
|
+
style = format_style
|
|
53
|
+
%(<text #{attrs} textLength="#{formatted_text_length}" style="#{style}" xml:space="preserve" transform="#{formatted_transform}">#{escaped_content}</text>)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def format_attrs
|
|
59
|
+
%(x="#{format('%.2f', x)}" y="#{format('%.2f', y)}")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def format_style
|
|
63
|
+
"font-family:#{family}; font-weight:#{weight}; font-style:#{style}; font-size:#{size}#{size_unit}; fill:#{fill};fill-opacity:1.00; stroke:#{stroke_in_text}; stroke-opacity:0.00 stroke-width:0; white-space: pre;"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.estimate_width(text, size, width_factor = 0.65)
|
|
67
|
+
content = text.to_s
|
|
68
|
+
space_count = content.count(" ")
|
|
69
|
+
letter_count = content.length - space_count
|
|
70
|
+
letter_count * size * width_factor + space_count * size * 0.3
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def formatted_text_length
|
|
74
|
+
return text_length.to_i.to_s if text_length
|
|
75
|
+
|
|
76
|
+
TextRenderer.estimate_width(content, size, width_factor).round.to_s
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def formatted_transform
|
|
80
|
+
"rotate(#{format('%<r>.2f', r: rotation)} #{format('%.2f', x)} #{format('%.2f', y)})"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def escaped_content
|
|
84
|
+
content.gsub("&", "&")
|
|
85
|
+
.gsub("<", "<")
|
|
86
|
+
.gsub(">", ">")
|
|
87
|
+
.gsub("\"", """)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ea
|
|
4
|
+
module Svg
|
|
5
|
+
# EaEmitter orchestrates SVG output that mirrors EA's layering
|
|
6
|
+
# and naming conventions.
|
|
7
|
+
#
|
|
8
|
+
# Architecture:
|
|
9
|
+
#
|
|
10
|
+
# Document (entry point)
|
|
11
|
+
# └─ LayerSequencer (frame?, theme via diagram.theme)
|
|
12
|
+
# ├─ Background
|
|
13
|
+
# ├─ DiagramFrame (opt-in)
|
|
14
|
+
# ├─ Elements → Element::* compartment renderers
|
|
15
|
+
# ├─ Connectors → Layer
|
|
16
|
+
# ├─ Markers → Marker::Registry (OCP) → Layer
|
|
17
|
+
# └─ Labels → TextRenderer
|
|
18
|
+
#
|
|
19
|
+
# Cross-cutting:
|
|
20
|
+
# Canvas, BoundsCalculator, ColorResolver, FontResolver
|
|
21
|
+
# Ea::Theme::Definition / Registry / Loader (domain-level)
|
|
22
|
+
# TextRenderer, Style
|
|
23
|
+
#
|
|
24
|
+
# Theme is a top-level domain concept at Ea::Theme::*.
|
|
25
|
+
# See lib/ea/theme.rb for the full API.
|
|
26
|
+
#
|
|
27
|
+
module EaEmitter
|
|
28
|
+
autoload :Canvas, "ea/svg/ea_emitter/canvas"
|
|
29
|
+
autoload :Background, "ea/svg/ea_emitter/background"
|
|
30
|
+
autoload :BoundsCalculator, "ea/svg/ea_emitter/bounds_calculator"
|
|
31
|
+
autoload :Style, "ea/svg/ea_emitter/style"
|
|
32
|
+
autoload :Elements, "ea/svg/ea_emitter/elements"
|
|
33
|
+
autoload :Connectors, "ea/svg/ea_emitter/connectors"
|
|
34
|
+
autoload :Markers, "ea/svg/ea_emitter/markers"
|
|
35
|
+
autoload :Labels, "ea/svg/ea_emitter/labels"
|
|
36
|
+
autoload :GhostLabels, "ea/svg/ea_emitter/ghost_labels"
|
|
37
|
+
autoload :Layer, "ea/svg/ea_emitter/layer"
|
|
38
|
+
autoload :LayerSequencer, "ea/svg/ea_emitter/layer_sequencer"
|
|
39
|
+
autoload :FontResolver, "ea/svg/ea_emitter/font_resolver"
|
|
40
|
+
autoload :Marker, "ea/svg/ea_emitter/marker"
|
|
41
|
+
autoload :Element, "ea/svg/ea_emitter/element"
|
|
42
|
+
autoload :DiagramFrame, "ea/svg/ea_emitter/diagram_frame"
|
|
43
|
+
autoload :TextRenderer, "ea/svg/ea_emitter/text_renderer"
|
|
44
|
+
autoload :ColorResolver, "ea/svg/ea_emitter/color_resolver"
|
|
45
|
+
autoload :Document, "ea/svg/ea_emitter/document"
|
|
46
|
+
autoload :Label, "ea/svg/ea_emitter/label"
|
|
47
|
+
autoload :Compartment, "ea/svg/ea_emitter/compartment"
|
|
48
|
+
autoload :RenderContext, "ea/svg/ea_emitter/render_context"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|