@miragon/context-maps-renderer 0.0.1

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 (95) hide show
  1. package/README.md +148 -0
  2. package/dist/CmBaseViewer.d.ts +49 -0
  3. package/dist/CmBaseViewer.d.ts.map +1 -0
  4. package/dist/Modeler.d.ts +14 -0
  5. package/dist/Modeler.d.ts.map +1 -0
  6. package/dist/NavigatedViewer.d.ts +7 -0
  7. package/dist/NavigatedViewer.d.ts.map +1 -0
  8. package/dist/Viewer.d.ts +7 -0
  9. package/dist/Viewer.d.ts.map +1 -0
  10. package/dist/behaviors/CmClickSelectionBehavior.d.ts +7 -0
  11. package/dist/behaviors/CmClickSelectionBehavior.d.ts.map +1 -0
  12. package/dist/behaviors/CmDragBehavior.d.ts +7 -0
  13. package/dist/behaviors/CmDragBehavior.d.ts.map +1 -0
  14. package/dist/behaviors/CmFlatModelBehavior.d.ts +9 -0
  15. package/dist/behaviors/CmFlatModelBehavior.d.ts.map +1 -0
  16. package/dist/behaviors/index.d.ts +7 -0
  17. package/dist/behaviors/index.d.ts.map +1 -0
  18. package/dist/connect-handles/CmConnectHandles.d.ts +15 -0
  19. package/dist/connect-handles/CmConnectHandles.d.ts.map +1 -0
  20. package/dist/connect-handles/index.d.ts +5 -0
  21. package/dist/connect-handles/index.d.ts.map +1 -0
  22. package/dist/context-maps.css +2 -0
  23. package/dist/draw/ContextMapsRenderer.d.ts +26 -0
  24. package/dist/draw/ContextMapsRenderer.d.ts.map +1 -0
  25. package/dist/draw/endRoleChips.d.ts +17 -0
  26. package/dist/draw/endRoleChips.d.ts.map +1 -0
  27. package/dist/draw/icons.d.ts +10 -0
  28. package/dist/draw/icons.d.ts.map +1 -0
  29. package/dist/draw/index.d.ts +5 -0
  30. package/dist/draw/index.d.ts.map +1 -0
  31. package/dist/draw/palette-icons.d.ts +4 -0
  32. package/dist/draw/palette-icons.d.ts.map +1 -0
  33. package/dist/draw/styles.d.ts +25 -0
  34. package/dist/draw/styles.d.ts.map +1 -0
  35. package/dist/index.d.ts +22 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +1279 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/io/CmExporter.d.ts +11 -0
  40. package/dist/io/CmExporter.d.ts.map +1 -0
  41. package/dist/io/CmImporter.d.ts +20 -0
  42. package/dist/io/CmImporter.d.ts.map +1 -0
  43. package/dist/io/index.d.ts +9 -0
  44. package/dist/io/index.d.ts.map +1 -0
  45. package/dist/io/saveSvg.d.ts +6 -0
  46. package/dist/io/saveSvg.d.ts.map +1 -0
  47. package/dist/io/types.d.ts +11 -0
  48. package/dist/io/types.d.ts.map +1 -0
  49. package/dist/keyboard/CmKeyboard.d.ts +9 -0
  50. package/dist/keyboard/CmKeyboard.d.ts.map +1 -0
  51. package/dist/keyboard/index.d.ts +5 -0
  52. package/dist/keyboard/index.d.ts.map +1 -0
  53. package/dist/label-editing/CmLabelEditing.d.ts +14 -0
  54. package/dist/label-editing/CmLabelEditing.d.ts.map +1 -0
  55. package/dist/label-editing/index.d.ts +5 -0
  56. package/dist/label-editing/index.d.ts.map +1 -0
  57. package/dist/model/CmDiagramElementFactory.d.ts +9 -0
  58. package/dist/model/CmDiagramElementFactory.d.ts.map +1 -0
  59. package/dist/model/CmElementFactory.d.ts +13 -0
  60. package/dist/model/CmElementFactory.d.ts.map +1 -0
  61. package/dist/model/CmLayouter.d.ts +21 -0
  62. package/dist/model/CmLayouter.d.ts.map +1 -0
  63. package/dist/model/di-types.d.ts +27 -0
  64. package/dist/model/di-types.d.ts.map +1 -0
  65. package/dist/model/index.d.ts +15 -0
  66. package/dist/model/index.d.ts.map +1 -0
  67. package/dist/modeling/CmModeling.d.ts +39 -0
  68. package/dist/modeling/CmModeling.d.ts.map +1 -0
  69. package/dist/modeling/cmd/SwapEndsHandler.d.ts +15 -0
  70. package/dist/modeling/cmd/SwapEndsHandler.d.ts.map +1 -0
  71. package/dist/modeling/cmd/UpdatePropertiesHandler.d.ts +13 -0
  72. package/dist/modeling/cmd/UpdatePropertiesHandler.d.ts.map +1 -0
  73. package/dist/modeling/index.d.ts +10 -0
  74. package/dist/modeling/index.d.ts.map +1 -0
  75. package/dist/palette/CmPaletteProvider.d.ts +12 -0
  76. package/dist/palette/CmPaletteProvider.d.ts.map +1 -0
  77. package/dist/palette/index.d.ts +5 -0
  78. package/dist/palette/index.d.ts.map +1 -0
  79. package/dist/rules/CmRules.d.ts +8 -0
  80. package/dist/rules/CmRules.d.ts.map +1 -0
  81. package/dist/rules/index.d.ts +5 -0
  82. package/dist/rules/index.d.ts.map +1 -0
  83. package/dist/theme/index.d.ts +2 -0
  84. package/dist/theme/index.d.ts.map +1 -0
  85. package/dist/theme/palette.d.ts +47 -0
  86. package/dist/theme/palette.d.ts.map +1 -0
  87. package/dist/validation/CmValidationMarkers.d.ts +13 -0
  88. package/dist/validation/CmValidationMarkers.d.ts.map +1 -0
  89. package/dist/validation/index.d.ts +5 -0
  90. package/dist/validation/index.d.ts.map +1 -0
  91. package/dist/zorder/CmZOrder.d.ts +13 -0
  92. package/dist/zorder/CmZOrder.d.ts.map +1 -0
  93. package/dist/zorder/index.d.ts +5 -0
  94. package/dist/zorder/index.d.ts.map +1 -0
  95. package/package.json +48 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/model/di-types.ts","../src/io/saveSvg.ts","../src/io/types.ts","../src/CmBaseViewer.ts","../src/model/CmElementFactory.ts","../src/model/CmDiagramElementFactory.ts","../src/model/CmLayouter.ts","../src/model/index.ts","../src/theme/palette.ts","../src/draw/styles.ts","../src/draw/endRoleChips.ts","../src/draw/ContextMapsRenderer.ts","../src/draw/index.ts","../src/io/CmImporter.ts","../src/io/CmExporter.ts","../src/io/index.ts","../src/Viewer.ts","../src/NavigatedViewer.ts","../src/modeling/cmd/UpdatePropertiesHandler.ts","../src/modeling/cmd/SwapEndsHandler.ts","../src/modeling/CmModeling.ts","../src/modeling/index.ts","../src/rules/CmRules.ts","../src/rules/index.ts","../src/behaviors/CmFlatModelBehavior.ts","../src/behaviors/CmDragBehavior.ts","../src/behaviors/CmClickSelectionBehavior.ts","../src/behaviors/index.ts","../src/draw/palette-icons.ts","../src/palette/CmPaletteProvider.ts","../src/palette/index.ts","../src/draw/icons.ts","../src/connect-handles/CmConnectHandles.ts","../src/connect-handles/index.ts","../src/label-editing/CmLabelEditing.ts","../src/label-editing/index.ts","../src/keyboard/CmKeyboard.ts","../src/keyboard/index.ts","../src/validation/CmValidationMarkers.ts","../src/validation/index.ts","../src/zorder/CmZOrder.ts","../src/zorder/index.ts","../src/Modeler.ts"],"sourcesContent":["/**\n * diagram-js runtime model for the Context Maps notation.\n *\n * - `context` — a bounded context: a placed, resizable SHAPE (box) with a\n * label, optional owning team and subdomain classification.\n * - `relationship` — a context-mapping pattern: a CONNECTION (edge) between two\n * contexts, carrying a pattern plus upstream/downstream roles.\n *\n * These runtime properties are the source of truth while editing; the exporter\n * rebuilds the canonical `CmDocument` from them.\n */\n\nimport type { Connection, Shape } from \"diagram-js/lib/model/Types\";\nimport type {\n DownstreamRole,\n RelationshipPattern,\n SubdomainType,\n UpstreamRole,\n} from \"@miragon/context-maps-schema-model\";\n\nexport type CmKind = \"context\" | \"relationship\";\n\nexport interface CmContext extends Shape {\n cmKind: \"context\";\n subdomainType?: SubdomainType;\n /** Display name (separate from diagram-js `label`). */\n cmLabel?: string;\n team?: string;\n description?: string;\n fill?: string;\n stroke?: string;\n}\n\nexport interface CmRelationship extends Connection {\n cmKind: \"relationship\";\n pattern: RelationshipPattern;\n upstreamRoles?: UpstreamRole[];\n downstreamRoles?: DownstreamRole[];\n cmLabel?: string;\n description?: string;\n implementationTechnology?: string;\n}\n\nexport type CmElement = CmContext | CmRelationship;\n\nfunction kindOf(el: unknown): string | undefined {\n return typeof el === \"object\" && el !== null\n ? ((el as { cmKind?: unknown }).cmKind as string | undefined)\n : undefined;\n}\n\nexport function isCmElement(el: unknown): el is CmElement {\n return typeof kindOf(el) === \"string\";\n}\n\nexport function isCmContext(el: unknown): el is CmContext {\n return kindOf(el) === \"context\";\n}\n\nexport function isCmRelationship(el: unknown): el is CmRelationship {\n return kindOf(el) === \"relationship\";\n}\n","/**\n * Serialises the current canvas into a standalone SVG (snapshot / export),\n * fitted to the content bounds and independent of the current zoom / scroll.\n */\n\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\nimport type ElementRegistry from \"diagram-js/lib/core/ElementRegistry\";\nimport { isCmContext } from \"../model/di-types.js\";\n\nconst MARGIN = 40;\n\nexport function saveSVG(canvas: Canvas, elementRegistry: ElementRegistry): { svg: string } {\n const container = canvas.getContainer();\n const source = container.querySelector(\"svg\");\n if (!source) throw new Error(\"No SVG found in the canvas container.\");\n\n // Content bounds from the context boxes (relationship lines stay within them).\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const el of elementRegistry.getAll()) {\n if (!isCmContext(el)) continue;\n const s = el as unknown as { x: number; y: number; width: number; height: number };\n minX = Math.min(minX, s.x);\n minY = Math.min(minY, s.y);\n maxX = Math.max(maxX, s.x + s.width);\n maxY = Math.max(maxY, s.y + s.height);\n }\n if (!Number.isFinite(minX)) {\n minX = 0;\n minY = 0;\n maxX = 100;\n maxY = 100;\n }\n\n const x = minX - MARGIN;\n const y = minY - MARGIN;\n const width = maxX - minX + MARGIN * 2;\n const height = maxY - minY + MARGIN * 2;\n\n const clone = source.cloneNode(true) as SVGSVGElement;\n clone.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\");\n clone.setAttribute(\"viewBox\", `${x} ${y} ${width} ${height}`);\n clone.setAttribute(\"width\", String(Math.round(width)));\n clone.setAttribute(\"height\", String(Math.round(height)));\n\n // Neutralise pan/zoom: let the viewBox (above) drive the geometry.\n const viewport = clone.querySelector<SVGGElement>(\".viewport\");\n if (viewport) viewport.removeAttribute(\"transform\");\n\n const svg = new XMLSerializer().serializeToString(clone);\n return { svg: '<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n' + svg };\n}\n","/** ID of the diagram-js root element holding the Context Maps diagram. */\nexport const ROOT_ID = \"cm-root\";\n\nexport interface ImportWarning {\n readonly message: string;\n readonly elementId?: string;\n}\n\n/** Diagram-level metadata stashed on the root element. */\nexport interface RootBusinessObject {\n title: string;\n}\n","/**\n * Shared lifecycle & DI bootstrap for every Context Maps viewer. Subclasses\n * only override `_getModules()`. The renderer\n * is framework-agnostic — mount it into any element (e.g. a VS Code webview).\n */\n\nimport Diagram from \"diagram-js/lib/Diagram\";\nimport type { ModuleDeclaration } from \"didi\";\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\nimport type ElementRegistry from \"diagram-js/lib/core/ElementRegistry\";\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type { Root } from \"diagram-js/lib/model/Types\";\nimport type { CmDocument } from \"@miragon/context-maps-schema-model\";\nimport { saveSVG } from \"./io/saveSvg.js\";\nimport type CmImporter from \"./io/CmImporter.js\";\nimport type CmExporter from \"./io/CmExporter.js\";\nimport { ROOT_ID, type ImportWarning, type RootBusinessObject } from \"./io/types.js\";\n\nexport interface CmViewerOptions {\n /** Host element. When absent, a detached <div> is created (attach later). */\n container?: HTMLElement;\n width?: number | string;\n height?: number | string;\n /** Appended to the module list (extension point). */\n additionalModules?: ModuleDeclaration[];\n}\n\nexport type EventCallback<T = unknown> = (event: T) => void;\n\ntype RootWithMeta = Root & { businessObject?: RootBusinessObject };\n\nfunction sizeToCss(value: number | string): string {\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\nexport abstract class CmBaseViewer {\n protected abstract _getModules(): ModuleDeclaration[];\n\n private _diagram: Diagram | undefined;\n private readonly _container: HTMLElement;\n private readonly _options: CmViewerOptions;\n\n constructor(options: CmViewerOptions = {}) {\n this._options = options;\n this._container = this._createContainer(options);\n }\n\n private _createContainer(options: CmViewerOptions): HTMLElement {\n const container = options.container ?? document.createElement(\"div\");\n container.classList.add(\"cm-djs-container\");\n container.style.width = sizeToCss(options.width ?? \"100%\");\n container.style.height = sizeToCss(options.height ?? (options.container ? \"100%\" : \"600px\"));\n return container;\n }\n\n private _ensureDiagram(): Diagram {\n if (!this._diagram) {\n const modules = [...this._getModules(), ...(this._options.additionalModules ?? [])];\n this._diagram = new Diagram({ canvas: { container: this._container }, modules });\n }\n return this._diagram;\n }\n\n /** Resolve a diagram-js service from the didi injector. */\n get<T>(name: string): T {\n return this._ensureDiagram().get<T>(name);\n }\n\n on<T = unknown>(event: string, callback: EventCallback<T>, priority = 1000): void {\n this.get<EventBus>(\"eventBus\").on(event, priority, callback as EventCallback);\n }\n\n off(event: string, callback: EventCallback): void {\n this.get<EventBus>(\"eventBus\").off(event, callback);\n }\n\n /** Load a document into the canvas (replaces existing content). */\n importDocument(doc: CmDocument): { warnings: ImportWarning[] } {\n const diagram = this._ensureDiagram();\n const eventBus = diagram.get<EventBus>(\"eventBus\");\n const importer = diagram.get<CmImporter>(\"cmImporter\");\n importer.clear();\n const warnings = importer.import(doc);\n this._fit();\n eventBus.fire(\"import.done\", { warnings });\n return { warnings };\n }\n\n /** Current canvas state as a canonical document. */\n exportDocument(): CmDocument {\n return this.get<CmExporter>(\"cmExporter\").export();\n }\n\n /** Update diagram-level metadata (title / flow-of-change) on the root. */\n setMeta(partial: Partial<RootBusinessObject>): void {\n const canvas = this.get<Canvas>(\"canvas\");\n let root: RootWithMeta | undefined;\n try {\n root = canvas.getRootElement() as RootWithMeta;\n } catch {\n return;\n }\n if (!root || root.id !== ROOT_ID) return;\n const current = root.businessObject ?? { title: \"Untitled context map\" };\n root.businessObject = { ...current, ...partial };\n }\n\n /** Read diagram-level metadata (title / flow-of-change) from the root. */\n getMeta(): RootBusinessObject | undefined {\n try {\n const root = this.get<Canvas>(\"canvas\").getRootElement() as RootWithMeta;\n return root.businessObject;\n } catch {\n return undefined;\n }\n }\n\n /** Standalone, self-contained SVG snapshot. */\n saveSVG(): { svg: string } {\n return saveSVG(this.get<Canvas>(\"canvas\"), this.get<ElementRegistry>(\"elementRegistry\"));\n }\n\n /** Fit the content into the viewport, leaving room at the top for the palette. */\n private _fit(topInset = 84, pad = 56): void {\n const canvas = this.get<Canvas>(\"canvas\");\n const registry = this.get<ElementRegistry>(\"elementRegistry\");\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const el of registry.getAll()) {\n const e = el as { x?: number; y?: number; width?: number; height?: number };\n if (\n typeof e.x !== \"number\" ||\n typeof e.y !== \"number\" ||\n typeof e.width !== \"number\" ||\n typeof e.height !== \"number\"\n ) {\n continue;\n }\n minX = Math.min(minX, e.x);\n minY = Math.min(minY, e.y);\n maxX = Math.max(maxX, e.x + e.width);\n maxY = Math.max(maxY, e.y + e.height);\n }\n if (!Number.isFinite(minX)) return;\n\n const rect = this._container.getBoundingClientRect();\n const W = rect.width;\n const H = rect.height;\n const cw = Math.max(maxX - minX, 1);\n const ch = Math.max(maxY - minY, 1);\n if (!W || !H) {\n canvas.zoom(\"fit-viewport\");\n return;\n }\n const s = Math.min((W - 2 * pad) / cw, (H - topInset - pad) / ch, 1.25);\n canvas.viewbox({\n x: minX + cw / 2 - W / 2 / s,\n y: minY - topInset / s,\n width: W / s,\n height: H / s,\n });\n }\n\n /** Attach the container into `target`. */\n attachTo(target: HTMLElement): void {\n target.appendChild(this._container);\n this.get<Canvas>(\"canvas\").resized();\n }\n\n /** Detach the container from the DOM, preserving state. */\n detach(): void {\n this._container.remove();\n }\n\n clear(): void {\n this._ensureDiagram().clear();\n }\n\n destroy(): void {\n if (this._diagram) {\n this._diagram.destroy();\n this._diagram = undefined;\n }\n this._container.remove();\n }\n\n get container(): HTMLElement {\n return this._container;\n }\n}\n","/**\n * Creates diagram-js runtime elements carrying Context Maps markers: bounded\n * contexts (shapes) and relationships (connections), from canonical document\n * elements (import) or from scratch (palette / context-pad create).\n */\n\nimport type ElementFactory from \"diagram-js/lib/core/ElementFactory\";\nimport type { Point } from \"diagram-js/lib/util/Types\";\nimport { SUBDOMAIN_TYPE_SPECS } from \"@miragon/context-maps-schema-model\";\nimport type {\n BoundedContext,\n Relationship,\n SubdomainType,\n} from \"@miragon/context-maps-schema-model\";\nimport type { CmContext, CmRelationship } from \"./di-types.js\";\n\nexport default class CmElementFactory {\n static $inject = [\"elementFactory\"];\n\n constructor(private readonly elementFactory: ElementFactory) {}\n\n // --- from canonical document elements (import) -------------------------\n\n createContext(ctx: BoundedContext): CmContext {\n return this.elementFactory.createShape({\n id: ctx.id,\n x: ctx.position.x,\n y: ctx.position.y,\n width: ctx.size.width,\n height: ctx.size.height,\n cmKind: \"context\",\n cmLabel: ctx.label,\n ...(ctx.subdomainType ? { subdomainType: ctx.subdomainType } : {}),\n ...(ctx.team ? { team: ctx.team } : {}),\n ...(ctx.description ? { description: ctx.description } : {}),\n ...(ctx.fill ? { fill: ctx.fill } : {}),\n ...(ctx.stroke ? { stroke: ctx.stroke } : {}),\n } as Partial<CmContext>) as unknown as CmContext;\n }\n\n createRelationship(\n rel: Relationship,\n source: CmContext,\n target: CmContext,\n waypoints: Point[],\n ): CmRelationship {\n return this.elementFactory.createConnection({\n id: rel.id,\n source,\n target,\n waypoints,\n cmKind: \"relationship\",\n pattern: rel.pattern,\n ...(rel.upstreamRoles?.length ? { upstreamRoles: [...rel.upstreamRoles] } : {}),\n ...(rel.downstreamRoles?.length ? { downstreamRoles: [...rel.downstreamRoles] } : {}),\n ...(rel.label ? { cmLabel: rel.label } : {}),\n ...(rel.description ? { description: rel.description } : {}),\n ...(rel.implementationTechnology\n ? { implementationTechnology: rel.implementationTechnology }\n : {}),\n } as unknown as Partial<CmRelationship>) as unknown as CmRelationship;\n }\n\n // --- fresh, not-yet-placed elements (palette / context-pad create) -----\n //\n // No explicit id: the element factory (CmDiagramElementFactory) assigns a\n // collision-free model-style id (`ctx_…`).\n\n createNewContext(subdomainType: SubdomainType, label?: string): CmContext {\n const spec = SUBDOMAIN_TYPE_SPECS[subdomainType];\n return this.elementFactory.createShape({\n width: spec.defaultSize.width,\n height: spec.defaultSize.height,\n cmKind: \"context\",\n subdomainType,\n cmLabel: label ?? \"New Context\",\n } as Partial<CmContext>) as unknown as CmContext;\n }\n}\n","/**\n * Element factory that assigns model-style random ids (`ctx_…`, `rel_…`) when\n * none is provided. diagram-js' stock factory numbers elements with a session\n * counter that restarts on every page load and is never advanced past ids\n * arriving via import — after a reload, drawing a connection would re-generate\n * an id already taken by an imported relationship (e.g. `connection_13`) and\n * the create command would die with \"element already exists\", silently\n * dropping the just-drawn line.\n */\n\nimport ElementFactory from \"diagram-js/lib/core/ElementFactory\";\nimport type { Connection, Label, Root, Shape } from \"diagram-js/lib/model/Types\";\nimport { newId } from \"@miragon/context-maps-schema-model\";\n\nexport default class CmDiagramElementFactory extends ElementFactory {\n override create(type: \"root\", attrs?: Partial<Root>): Root;\n override create(type: \"shape\", attrs?: Partial<Shape>): Shape;\n override create(type: \"connection\", attrs?: Partial<Connection>): Connection;\n override create(type: \"label\", attrs?: Partial<Label>): Label;\n override create(\n type: \"root\" | \"shape\" | \"connection\" | \"label\",\n attrs?: Partial<Root | Shape | Connection | Label>,\n ): Root | Shape | Connection | Label {\n if (!attrs?.id && (type === \"shape\" || type === \"connection\")) {\n attrs = { ...attrs, id: newId(type === \"shape\" ? \"ctx\" : \"rel\") };\n }\n return super.create(type as \"shape\", attrs as Partial<Shape>);\n }\n}\n","/**\n * Straight-line connection layouter that crops the waypoints to the context box\n * borders via the cropping docking. diagram-js' stock BaseLayouter only returns\n * mid(source)→mid(target), so without this the relationship line would run from\n * box centre to box centre (visibly starting inside the boxes).\n */\n\nimport { getMid } from \"diagram-js/lib/layout/LayoutUtil\";\nimport type CroppingConnectionDocking from \"diagram-js/lib/layout/CroppingConnectionDocking\";\nimport type { ConnectionLike, ShapeLike } from \"diagram-js/lib/model/Types\";\nimport type { Point } from \"diagram-js/lib/util/Types\";\n\ninterface LayoutHints {\n /**\n * diagram-js may pass a Point (drag anchor) or `false` (end did not move,\n * e.g. MoveHelper's `connectionStart: sourceMoved && anchor`) here.\n */\n connectionStart?: Point | false;\n connectionEnd?: Point | false;\n source?: ShapeLike;\n target?: ShapeLike;\n}\n\nexport default class CmLayouter {\n static $inject = [\"connectionDocking\"];\n\n constructor(private readonly docking: CroppingConnectionDocking) {}\n\n layoutConnection(connection: ConnectionLike, hints: LayoutHints = {}): Point[] {\n const source = hints.source ?? connection.source;\n const target = hints.target ?? connection.target;\n // A relationship line always aims at the CENTRE of its contexts (then gets\n // cropped to the borders below). Anchor hints are deliberately ignored when\n // the shape is known: diagram-js' move helpers pass stale/shifted anchors\n // (the box may already have been relaid out), which would detach the line.\n // Hints only matter while an end has no shape yet (connect rubber band).\n const start = source ? getMid(source) : hints.connectionStart || undefined;\n const end = target ? getMid(target) : hints.connectionEnd || undefined;\n\n const provisional: Point[] = [start, end].filter(Boolean) as Point[];\n // Give the connection a straight line so the docking can crop it to the\n // shape borders. Falls back to the raw line if either end is missing.\n connection.waypoints = provisional;\n if (source && target && provisional.length === 2) {\n return this.docking.getCroppedWaypoints(connection, source, target);\n }\n return provisional;\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport CroppingConnectionDocking from \"diagram-js/lib/layout/CroppingConnectionDocking\";\nimport CmElementFactory from \"./CmElementFactory.js\";\nimport CmDiagramElementFactory from \"./CmDiagramElementFactory.js\";\n\n/**\n * Element factory with Context Maps defaults, plus the cropping docking so\n * relationship lines dock to the context box borders. The layouter itself is\n * bound in the modeling module (see there) because diagram-js' ModelingModule\n * binds a default `layouter` and loads after this one. The stock\n * `elementFactory` is replaced so every element gets a collision-free id\n * (see CmDiagramElementFactory).\n */\nexport const cmModelModule: ModuleDeclaration = {\n elementFactory: [\"type\", CmDiagramElementFactory],\n cmElementFactory: [\"type\", CmElementFactory],\n connectionDocking: [\"type\", CroppingConnectionDocking],\n};\n\nexport { default as CmElementFactory } from \"./CmElementFactory.js\";\nexport { default as CmDiagramElementFactory } from \"./CmDiagramElementFactory.js\";\nexport { default as CmLayouter } from \"./CmLayouter.js\";\nexport * from \"./di-types.js\";\n","/**\n * Miragon design tokens — the single source of truth for every non-notation colour in the renderer.\n *\n * Values mirror the Miragon corporate identity: the `miragon-brand:corporate-design` skill in\n * `Miragon/corporate-identity`, whose vendored `cd-tokens.generated.css` (next to this file) defines\n * the `--cd-*` custom properties, generated from the brand's `tokens.json`. Re-copy that CSS from the\n * corporate-identity repo to update; never fork the hex values by hand. `theme.sync.test.ts` fails if\n * this mirror drifts from the vendored CSS.\n *\n * Pure data — no DOM, no imports — so it can be consumed by the SVG-drawing constants in\n * `draw/styles.ts`.\n *\n * Brand rule: blue leads (`blau` — surfaces, buttons, links, selection), green accents (`gruen` — key\n * visual, highlights; a fill, never body text on white). The subdomain-type fills and\n * relationship-pattern strokes are the official Context Maps notation and live in\n * `schema-model/notation.ts` — they are NOT part of this brand ramp.\n */\n\n/** Raw Miragon brand ramp + functional layer — exact `--cd-*` values. */\nexport const MIRAGON = {\n /** Primary: surfaces, buttons, links, selection, backgrounds. */\n blau: \"#335DE5\",\n /** Deeper blue for links / accent text on white (WCAG AA, ~5.5:1). */\n blauLink: \"#2B50D4\",\n /** Lightened blue for accents on dark surfaces (unused here — the canvas is light-only). */\n blauHell: \"#6B8AFF\",\n /** Accent: key visual, highlights, the brand gradient. Bright — a fill, never text on white. */\n gruen: \"#00E676\",\n /** Calm neutral surface (warm off-white) — the paper surround. */\n grau: \"#F9F7F7\",\n /** Text on light; not pure black. */\n schwarz: \"#1D1D1D\",\n weiss: \"#FFFFFF\",\n /** Functional / status layer (own layer beside the brand palette; AA as text on white). */\n success: \"#0B7A55\",\n warning: \"#92610A\",\n danger: \"#C92A2A\",\n info: \"#2B50D4\",\n /** Signature brand gradient — brand moments only. Use verbatim. */\n gradientBrand: \"linear-gradient(120deg, #335DE5 30%, #00E676)\",\n} as const;\n\n/**\n * Every `--cd-*` token this repo depends on, mapped to the value it MUST hold. The drift test parses\n * `cd-tokens.generated.css` and asserts each entry matches, so re-copying the vendored CSS with a\n * changed value fails CI until this mirror (and `MIRAGON`) is updated too.\n */\nexport const CD_TOKENS: Record<string, string> = {\n \"--cd-blau\": MIRAGON.blau,\n \"--cd-gruen\": MIRAGON.gruen,\n \"--cd-grau\": MIRAGON.grau,\n \"--cd-schwarz\": MIRAGON.schwarz,\n \"--cd-weiss\": MIRAGON.weiss,\n \"--cd-blau-link\": MIRAGON.blauLink,\n \"--cd-blau-hell\": MIRAGON.blauHell,\n \"--cd-success\": MIRAGON.success,\n \"--cd-success-soft\": \"rgba(11, 122, 85, 0.12)\",\n \"--cd-warning\": MIRAGON.warning,\n \"--cd-warning-soft\": \"rgba(146, 97, 10, 0.12)\",\n \"--cd-danger\": MIRAGON.danger,\n \"--cd-danger-soft\": \"rgba(201, 42, 42, 0.12)\",\n \"--cd-info\": MIRAGON.info,\n \"--cd-info-soft\": \"rgba(43, 80, 212, 0.12)\",\n \"--cd-gradient-brand\": MIRAGON.gradientBrand,\n};\n","/** Shared rendering constants (typography, accent, priorities) — Miragon corporate identity.\n * Colours are derived from the single source of truth in `theme/palette.ts` (`MIRAGON`), which\n * mirrors the vendored `--cd-*` brand tokens. */\n\nimport { MIRAGON } from \"../theme/index.js\";\n\n/** BaseRenderer default priority is 1000; 1500 wins the render.shape/connection event. */\nexport const TT_RENDER_PRIORITY = 1500;\n\n/** Selection / hover accent (Miragon blue — kept in sync with the app theme via the shared palette). */\nexport const ACCENT = MIRAGON.blau;\n\nexport const INK = MIRAGON.schwarz;\nexport const INK_SOFT = \"#5B5B5B\";\n\nexport const FONT = {\n /**\n * Set directly as the `font-family` attribute on every SVG <text> (canvas\n * labels and therefore the SVG export too) — not inherited from a CSS\n * container. Prefers the self-hosted Miragon typeface Geist (registered as\n * 'Geist Variable' by @fontsource-variable/geist, with 'Geist' as a fallback\n * name), and falls back to a system sans when the host hasn't loaded it (e.g.\n * an exported SVG opened standalone).\n */\n family:\n \"'Geist Variable', 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif\",\n label: 13.5,\n small: 11,\n} as const;\n\n/** Paper colour used for the label halo so text stays legible over lines. */\nexport const PAPER = MIRAGON.weiss;\n","/**\n * Geometry of the role-chip group at a relationship end (the OHS/PL/ACL/CF\n * badges next to the direction letter). Kept in one place so the renderer\n * (which draws the chips) and the validation markers (which anchor to the\n * chips' bottom-right corner) can never drift apart.\n */\n\nimport type { Point } from \"diagram-js/lib/util/Types\";\nimport { FONT } from \"./styles.js\";\n\nexport interface EndRoleChipLayout {\n /** The parent box around all chips of this end. */\n box: { x: number; y: number; width: number; height: number };\n center: Point;\n chipWidths: number[];\n chipHeight: number;\n innerWidth: number;\n gap: number;\n}\n\nexport function endRoleChipLayout(\n endpoint: Point,\n toward: Point,\n direction: string,\n roles: string[],\n): EndRoleChipLayout | null {\n if (roles.length === 0) return null;\n\n const dx = toward.x - endpoint.x;\n const dy = toward.y - endpoint.y;\n const length = Math.hypot(dx, dy) || 1;\n const ux = dx / length;\n const uy = dy / length;\n const charW = FONT.small * 0.64;\n const letterDist = 11;\n\n const chipHeight = FONT.small + 6;\n const gap = 3;\n const pad = 4;\n const chipWidths = roles.map((role) => role.length * charW + 12);\n const innerWidth = chipWidths.reduce((a, b) => a + b, 0) + gap * (roles.length - 1);\n const width = innerWidth + pad * 2;\n const height = chipHeight + pad * 2;\n\n const dist = letterDist + (direction.length * charW) / 2 + 8 + width / 2;\n const center = { x: endpoint.x + ux * dist, y: endpoint.y + uy * dist };\n\n return {\n box: { x: center.x - width / 2, y: center.y - height / 2, width, height },\n center,\n chipWidths,\n chipHeight,\n innerWidth,\n gap,\n };\n}\n","/**\n * SVG rendering of the Context Maps notation (BaseRenderer subclass).\n *\n * - bounded contexts: solid resizable boxes, coloured by subdomain type, with a\n * wrapped name and an optional owning-team caption;\n * - relationships: lines between contexts carrying the pattern abbreviation\n * (e.g. \"SK\", \"C/S\"), U/D end markers for asymmetric patterns, and the\n * integration roles (OHS/PL upstream, ACL/CF downstream).\n *\n * Colours/labels come from the single notation source (`@miragon/context-maps-schema-model`).\n */\n\nimport BaseRenderer from \"diagram-js/lib/draw/BaseRenderer\";\nimport {\n append as svgAppend,\n create as svgCreate,\n attr as svgAttr,\n clear as svgClear,\n} from \"tiny-svg\";\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type { ConnectionLike, ElementLike, ShapeLike } from \"diagram-js/lib/model/Types\";\nimport type { Point } from \"diagram-js/lib/util/Types\";\nimport {\n MARK_COLORS,\n MARK_TEXT_COLOR,\n RELATIONSHIP_PATTERN_SPECS,\n SUBDOMAIN_TYPE_SPECS,\n} from \"@miragon/context-maps-schema-model\";\nimport type { SubdomainType } from \"@miragon/context-maps-schema-model\";\nimport { FONT, INK, INK_SOFT, PAPER, TT_RENDER_PRIORITY } from \"./styles.js\";\nimport { endRoleChipLayout } from \"./endRoleChips.js\";\nimport {\n isCmContext,\n isCmElement,\n isCmRelationship,\n type CmContext,\n type CmRelationship,\n} from \"../model/di-types.js\";\n\ntype Attrs = Record<string, string | number>;\n\nconst NEUTRAL_FILL = \"#F1F1EE\";\nconst NEUTRAL_STROKE = \"#8A8577\";\n\nexport default class ContextMapsRenderer extends BaseRenderer {\n static $inject = [\"eventBus\"];\n\n constructor(eventBus: EventBus) {\n super(eventBus, TT_RENDER_PRIORITY);\n }\n\n override canRender(element: ElementLike): boolean {\n return isCmElement(element);\n }\n\n override drawShape(visuals: SVGElement, element: ShapeLike): SVGElement {\n // diagram-js does not always clear our visual group before re-rendering on\n // update; clear it ourselves so re-draws never leave stale duplicates behind.\n svgClear(visuals);\n if (isCmContext(element)) return this.drawContext(visuals, element);\n const rect = svgAttr(svgCreate(\"rect\"), {\n width: element.width,\n height: element.height,\n fill: \"#eee\",\n });\n svgAppend(visuals, rect);\n return rect;\n }\n\n override drawConnection(visuals: SVGElement, connection: ConnectionLike): SVGElement {\n svgClear(visuals);\n if (isCmRelationship(connection)) return this.drawRelationship(visuals, connection);\n const line = svgAttr(svgCreate(\"polyline\"), {\n points: (connection.waypoints ?? []).map((p) => `${p.x},${p.y}`).join(\" \"),\n fill: \"none\",\n stroke: INK,\n });\n svgAppend(visuals, line);\n return line;\n }\n\n override getShapePath(shape: ShapeLike): string {\n const { x, y, width, height } = shape;\n return `M${x},${y}l${width},0l0,${height}l${-width},0z`;\n }\n\n override getConnectionPath(connection: ConnectionLike): string {\n const wp = (connection.waypoints ?? []) as Point[];\n if (wp.length === 0) return \"\";\n return wp.map((p, idx) => `${idx === 0 ? \"M\" : \"L\"}${p.x},${p.y}`).join(\"\");\n }\n\n // --- bounded context -----------------------------------------------------\n\n private drawContext(visuals: SVGElement, ctx: CmContext): SVGElement {\n const spec = ctx.subdomainType ? SUBDOMAIN_TYPE_SPECS[ctx.subdomainType] : undefined;\n const w = Math.max(ctx.width, 1);\n const h = Math.max(ctx.height, 1);\n const sw = 2;\n const i = sw / 2;\n const box = svgAttr(svgCreate(\"rect\"), {\n x: i,\n y: i,\n width: w - sw,\n height: h - sw,\n rx: 8,\n ry: 8,\n fill: ctx.fill ?? spec?.fill ?? NEUTRAL_FILL,\n stroke: ctx.stroke ?? spec?.stroke ?? NEUTRAL_STROKE,\n \"stroke-width\": sw,\n \"stroke-linejoin\": \"round\",\n });\n svgAppend(visuals, box);\n\n const hasTeam = Boolean(ctx.team);\n this.appendLabel(visuals, ctx.cmLabel ?? \"\", w, hasTeam ? h - 18 : h, {\n \"font-weight\": \"650\",\n });\n if (ctx.subdomainType && spec) {\n // Kaiser subdomain icon at the top-left corner (star / open hand / dotted\n // circle) plus the domain-type label next to it.\n svgAppend(visuals, subdomainIcon(ctx.subdomainType, 15, 15, 18, spec.stroke));\n const badge = svgAttr(svgCreate(\"text\"), {\n x: 28,\n y: 15,\n \"font-family\": FONT.family,\n \"font-size\": FONT.small,\n \"font-weight\": \"700\",\n fill: spec.stroke,\n \"text-anchor\": \"start\",\n \"dominant-baseline\": \"central\",\n \"letter-spacing\": \"0.03em\",\n });\n badge.textContent = spec.label;\n svgAppend(visuals, badge);\n }\n if (ctx.team) {\n // People icon + team name, centred as a unit at the bottom of the box.\n const textWidth = ctx.team.length * FONT.small * 0.55;\n const iconSize = 14;\n const gap = 5;\n const totalWidth = iconSize + gap + textWidth;\n const startX = w / 2 - totalWidth / 2;\n const cy = h - 12;\n\n svgAppend(visuals, peopleIcon(startX + iconSize / 2, cy, iconSize, INK_SOFT));\n\n const team = svgAttr(svgCreate(\"text\"), {\n x: startX + iconSize + gap,\n y: cy,\n \"font-family\": FONT.family,\n \"font-size\": FONT.small,\n fill: INK_SOFT,\n \"text-anchor\": \"start\",\n \"dominant-baseline\": \"central\",\n });\n team.textContent = ctx.team;\n svgAppend(visuals, team);\n }\n return box;\n }\n\n // --- relationship --------------------------------------------------------\n\n private drawRelationship(visuals: SVGElement, rel: CmRelationship): SVGElement {\n const spec =\n RELATIONSHIP_PATTERN_SPECS[rel.pattern] ?? RELATIONSHIP_PATTERN_SPECS[\"upstream-downstream\"];\n const wp = (rel.waypoints ?? []) as Point[];\n const dash = spec.dash;\n const line = svgAttr(svgCreate(\"polyline\"), {\n points: wp.map((p) => `${p.x},${p.y}`).join(\" \"),\n fill: \"none\",\n stroke: spec.stroke,\n \"stroke-width\": spec.strokeWidth,\n \"stroke-linejoin\": \"round\",\n \"stroke-linecap\": \"round\",\n ...(dash ? { \"stroke-dasharray\": dash } : {}),\n });\n svgAppend(visuals, line);\n\n if (wp.length >= 2) {\n const src = wp[0];\n const tgt = wp[wp.length - 1];\n const upRoles = rel.upstreamRoles ?? [];\n const downRoles = rel.downstreamRoles ?? [];\n\n if (spec.symmetric) {\n // No direction (SK / P / SW): a single neutral pattern chip in the MIDDLE.\n const mx = (src.x + tgt.x) / 2;\n const my = (src.y + tgt.y) / 2;\n this.chip(visuals, mx, my, spec.abbreviation, PAPER, spec.stroke, spec.stroke);\n } else {\n // Direction letter sits AT the domain as a plain letter (no box); the\n // integration roles follow as their own coloured boxes. Customer-supplier\n // uses S (supplier, upstream) and C (customer, downstream) instead of U/D.\n const cs = rel.pattern === \"customer-supplier\";\n this.endMarkers(visuals, src, tgt, cs ? \"S\" : \"U\", upRoles);\n this.endMarkers(visuals, tgt, src, cs ? \"C\" : \"D\", downRoles);\n }\n }\n return line;\n }\n\n /**\n * Draws the markers at one relationship end: the direction letter (U/D/S/C) as\n * a plain letter right at the domain (no box), then the integration roles side\n * by side inside a single axis-aligned parent box.\n */\n private endMarkers(\n visuals: SVGElement,\n endpoint: Point,\n toward: Point,\n direction: string,\n roles: string[],\n ): void {\n const dx = toward.x - endpoint.x;\n const dy = toward.y - endpoint.y;\n const len = Math.hypot(dx, dy) || 1;\n const ux = dx / len;\n const uy = dy / len;\n\n // Direction letter: plain bold letter at the domain, white halo for legibility.\n const letterDist = 11;\n const dirColor = MARK_COLORS[direction] ?? INK;\n const letter = svgAttr(svgCreate(\"text\"), {\n x: endpoint.x + ux * letterDist,\n y: endpoint.y + uy * letterDist,\n \"font-family\": FONT.family,\n \"font-size\": FONT.small + 1,\n \"font-weight\": \"800\",\n fill: dirColor,\n stroke: PAPER,\n \"stroke-width\": 3,\n \"paint-order\": \"stroke\",\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n });\n letter.textContent = direction;\n svgAppend(visuals, letter);\n\n // Integration roles: horizontal chips inside one axis-aligned parent box\n // (geometry shared with the validation markers via endRoleChipLayout).\n const layout = endRoleChipLayout(endpoint, toward, direction, roles);\n if (!layout) return;\n const { box, center, chipWidths: widths, chipHeight: chipH, innerWidth: innerW, gap } = layout;\n const cy = center.y;\n\n const parent = svgAttr(svgCreate(\"rect\"), {\n x: box.x,\n y: box.y,\n width: box.width,\n height: box.height,\n rx: 6,\n ry: 6,\n fill: PAPER,\n \"fill-opacity\": 0.96,\n stroke: \"#d9d5cc\",\n \"stroke-width\": 1,\n });\n svgAppend(visuals, parent);\n\n let x = center.x - innerW / 2;\n roles.forEach((role, i) => {\n const w = widths[i];\n const fill = MARK_COLORS[role] ?? NEUTRAL_STROKE;\n this.miniChip(visuals, x + w / 2, cy, w, chipH, role, fill);\n x += w + gap;\n });\n }\n\n /** A fixed-size coloured sub-label (own colour + border) inside a parent box. */\n private miniChip(\n visuals: SVGElement,\n cx: number,\n cy: number,\n w: number,\n h: number,\n text: string,\n fill: string,\n ): void {\n const bg = svgAttr(svgCreate(\"rect\"), {\n x: cx - w / 2,\n y: cy - h / 2,\n width: w,\n height: h,\n rx: 3,\n ry: 3,\n fill,\n stroke: darken(fill),\n \"stroke-width\": 1,\n });\n svgAppend(visuals, bg);\n const t = svgAttr(svgCreate(\"text\"), {\n x: cx,\n y: cy,\n \"font-family\": FONT.family,\n \"font-size\": FONT.small,\n \"font-weight\": \"700\",\n fill: MARK_TEXT_COLOR,\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n });\n t.textContent = text;\n svgAppend(visuals, t);\n }\n\n /** A single small filled, bordered box (background, text colour, border colour). */\n private chip(\n visuals: SVGElement,\n cx: number,\n cy: number,\n text: string,\n bgFill: string,\n textFill: string,\n border: string,\n ): void {\n if (!text) return;\n const padX = 6;\n const charW = FONT.small * 0.64;\n const w = text.length * charW + padX * 2;\n const h = FONT.small + 8;\n const bg = svgAttr(svgCreate(\"rect\"), {\n x: cx - w / 2,\n y: cy - h / 2,\n width: w,\n height: h,\n rx: 4,\n ry: 4,\n fill: bgFill,\n stroke: border,\n \"stroke-width\": 1,\n ...(bgFill === PAPER ? { \"fill-opacity\": 0.95 } : {}),\n });\n svgAppend(visuals, bg);\n const t = svgAttr(svgCreate(\"text\"), {\n x: cx,\n y: cy,\n \"font-family\": FONT.family,\n \"font-size\": FONT.small,\n \"font-weight\": \"700\",\n fill: textFill,\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n });\n t.textContent = text;\n svgAppend(visuals, t);\n }\n\n // --- shared label rendering (wrapped, centred) ---------------------------\n\n private appendLabel(visuals: SVGElement, text: string, w: number, h: number, attrs: Attrs): void {\n const fontSize =\n typeof attrs[\"font-size\"] === \"number\" ? (attrs[\"font-size\"] as number) : FONT.label;\n const lines = wrapLabel(text, w - 20, fontSize);\n const lineHeight = fontSize * 1.2;\n const startY = h / 2 - ((lines.length - 1) * lineHeight) / 2;\n lines.forEach((ln, idx) => {\n const t = svgAttr(svgCreate(\"text\"), {\n x: w / 2,\n y: startY + idx * lineHeight,\n \"font-family\": FONT.family,\n \"font-size\": fontSize,\n fill: INK,\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n ...attrs,\n });\n t.textContent = ln;\n svgAppend(visuals, t);\n });\n }\n}\n\n// --- helpers ---------------------------------------------------------------\n\n/** Darkens a #rrggbb colour toward black by factor `f` (0..1) for chip borders. */\nfunction darken(hex: string, f = 0.7): string {\n const m = /^#([0-9a-f]{6})$/i.exec(hex);\n if (!m) return hex;\n const n = parseInt(m[1], 16);\n const r = Math.round(((n >> 16) & 255) * f);\n const g = Math.round(((n >> 8) & 255) * f);\n const b = Math.round((n & 255) * f);\n return `rgb(${r},${g},${b})`;\n}\n\n// Material star + pan_tool (open hand) paths (Apache-2.0), 24×24 viewBox.\nconst STAR_PATH =\n \"M12 2l2.9 6.26L22 9.27l-5 4.87L18.18 22 12 18.56 5.82 22 7 14.14l-5-4.87 7.1-1.01z\";\nconst HAND_PATH =\n \"M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z\";\n\n/**\n * Kaiser subdomain icon centred on (cx, cy) at `size` px: a filled star for a\n * core domain, an open hand for a supporting subdomain, a dotted circle for a\n * generic subdomain.\n */\nfunction subdomainIcon(\n type: SubdomainType,\n cx: number,\n cy: number,\n size: number,\n color: string,\n): SVGElement {\n if (type === \"generic\") {\n const g = svgCreate(\"g\");\n const c = svgAttr(svgCreate(\"circle\"), {\n cx,\n cy,\n r: size / 2 - 1,\n fill: \"none\",\n stroke: color,\n \"stroke-width\": 1.6,\n \"stroke-dasharray\": \"2.2 2.2\",\n });\n svgAppend(g, c);\n return g;\n }\n const scale = size / 24;\n // The open hand is drawn upright by Material; rotate it to lie sideways.\n const rot = type === \"supporting\" ? \" rotate(90 12 12)\" : \"\";\n const g = svgCreate(\"g\");\n svgAttr(g, {\n transform: `translate(${cx - 12 * scale} ${cy - 12 * scale}) scale(${scale})${rot}`,\n });\n const path = svgAttr(svgCreate(\"path\"), {\n d: type === \"core\" ? STAR_PATH : HAND_PATH,\n fill: color,\n });\n svgAppend(g, path);\n return g;\n}\n\n// Material \"people\" icon (Apache-2.0), 24×24 viewBox.\nconst PEOPLE_PATH =\n \"M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z\";\n\n/** A people glyph centred on (cx, cy), rendered at `size` px in the given colour. */\nfunction peopleIcon(cx: number, cy: number, size: number, color: string): SVGElement {\n const scale = size / 24;\n const g = svgCreate(\"g\");\n svgAttr(g, { transform: `translate(${cx - 12 * scale} ${cy - 12 * scale}) scale(${scale})` });\n const path = svgAttr(svgCreate(\"path\"), { d: PEOPLE_PATH, fill: color });\n svgAppend(g, path);\n return g;\n}\n\n/** Greedy word-wrap into lines that roughly fit `maxWidth` at the font size. */\nfunction wrapLabel(text: string, maxWidth: number, fontSize: number): string[] {\n const maxChars = Math.max(4, Math.floor(maxWidth / (fontSize * 0.58)));\n const words = text.split(/\\s+/).filter(Boolean);\n if (words.length === 0) return [];\n const lines: string[] = [];\n let cur = \"\";\n for (const word of words) {\n const candidate = cur ? `${cur} ${word}` : word;\n if (candidate.length > maxChars && cur) {\n lines.push(cur);\n cur = word;\n } else {\n cur = candidate;\n }\n }\n if (cur) lines.push(cur);\n return lines;\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport ContextMapsRenderer from \"./ContextMapsRenderer.js\";\n\n/** SVG rendering of all Context Maps element types (BaseRenderer, priority 1500). */\nexport const cmDrawModule: ModuleDeclaration = {\n __init__: [\"cmRenderer\"],\n cmRenderer: [\"type\", ContextMapsRenderer],\n};\n\nexport { default as ContextMapsRenderer } from \"./ContextMapsRenderer.js\";\n","/**\n * Bridges the canonical `CmDocument` into the diagram-js canvas. Contexts become\n * shapes; relationships become connections whose waypoints are cropped to the\n * context box borders. Connections are added first so they sit behind the boxes.\n */\n\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\nimport type ElementFactory from \"diagram-js/lib/core/ElementFactory\";\nimport type ElementRegistry from \"diagram-js/lib/core/ElementRegistry\";\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type { Root } from \"diagram-js/lib/model/Types\";\nimport type { Point } from \"diagram-js/lib/util/Types\";\nimport type { CmDocument } from \"@miragon/context-maps-schema-model\";\nimport type CmElementFactory from \"../model/CmElementFactory.js\";\nimport type { CmContext } from \"../model/di-types.js\";\nimport { ROOT_ID, type ImportWarning, type RootBusinessObject } from \"./types.js\";\n\ntype RootWithMeta = Root & { businessObject?: RootBusinessObject };\n\ninterface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** The point where the ray from a rect's centre toward `toward` crosses its border. */\nfunction borderPoint(rect: Rect, toward: Point): Point {\n const cx = rect.x + rect.width / 2;\n const cy = rect.y + rect.height / 2;\n const dx = toward.x - cx;\n const dy = toward.y - cy;\n if (dx === 0 && dy === 0) return { x: cx, y: cy };\n const sx = dx !== 0 ? rect.width / 2 / Math.abs(dx) : Infinity;\n const sy = dy !== 0 ? rect.height / 2 / Math.abs(dy) : Infinity;\n const s = Math.min(sx, sy);\n return { x: cx + dx * s, y: cy + dy * s };\n}\n\nfunction centre(rect: Rect): Point {\n return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };\n}\n\nexport default class CmImporter {\n static $inject = [\"canvas\", \"elementFactory\", \"cmElementFactory\", \"eventBus\", \"elementRegistry\"];\n\n constructor(\n private readonly canvas: Canvas,\n private readonly elementFactory: ElementFactory,\n private readonly factory: CmElementFactory,\n private readonly eventBus: EventBus,\n private readonly elementRegistry: ElementRegistry,\n ) {}\n\n import(doc: CmDocument): ImportWarning[] {\n const warnings: ImportWarning[] = [];\n this.eventBus.fire(\"import.render.start\", { document: doc });\n\n let existing: RootWithMeta | undefined;\n try {\n existing = this.canvas.getRootElement() as RootWithMeta;\n } catch {\n existing = undefined;\n }\n let root: RootWithMeta;\n if (existing && existing.id === ROOT_ID) {\n root = existing;\n } else {\n root = this.elementFactory.createRoot({ id: ROOT_ID }) as RootWithMeta;\n this.canvas.setRootElement(root);\n }\n root.businessObject = { title: doc.title };\n\n const byId = new Map<string, CmContext>();\n for (const ctx of doc.contexts) {\n const shape = this.factory.createContext(ctx);\n byId.set(ctx.id, shape);\n }\n\n // Connections first (back), then contexts (front).\n for (const rel of doc.relationships) {\n const source = byId.get(rel.from);\n const target = byId.get(rel.to);\n if (!source || !target) {\n warnings.push({\n message: `Relationship \"${rel.id}\" references a missing context; skipped.`,\n elementId: rel.id,\n });\n continue;\n }\n const waypoints: Point[] = [\n borderPoint(source as unknown as Rect, centre(target as unknown as Rect)),\n borderPoint(target as unknown as Rect, centre(source as unknown as Rect)),\n ];\n const connection = this.factory.createRelationship(rel, source, target, waypoints);\n this.canvas.addConnection(connection, root);\n }\n for (const shape of byId.values()) {\n this.canvas.addShape(shape, root);\n }\n\n this.eventBus.fire(\"import.render.done\", { warnings });\n return warnings;\n }\n\n /** Removes every element (for re-import). */\n clear(): void {\n for (const el of [...this.elementRegistry.getAll()]) {\n if (el.id === ROOT_ID) continue;\n try {\n if (\"waypoints\" in el) this.canvas.removeConnection(el.id);\n else this.canvas.removeShape(el.id);\n } catch {\n // already removed — ignore\n }\n }\n }\n}\n","/**\n * Rebuilds a canonical `CmDocument` from the diagram-js runtime model. Position\n * and size truth are the live `x/y/width/height`; editable fields (label,\n * subdomain, team, pattern, roles, colours) are read from runtime properties.\n */\n\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\nimport type ElementRegistry from \"diagram-js/lib/core/ElementRegistry\";\nimport type { Root } from \"diagram-js/lib/model/Types\";\nimport { DOCUMENT_VERSION } from \"@miragon/context-maps-schema-model\";\nimport type { BoundedContext, Relationship, CmDocument } from \"@miragon/context-maps-schema-model\";\nimport { isCmContext, isCmRelationship } from \"../model/di-types.js\";\nimport { ROOT_ID, type RootBusinessObject } from \"./types.js\";\n\nexport default class CmExporter {\n static $inject = [\"elementRegistry\", \"canvas\"];\n\n constructor(\n private readonly elementRegistry: ElementRegistry,\n private readonly canvas: Canvas,\n ) {}\n\n export(): CmDocument {\n let meta: RootBusinessObject | undefined;\n try {\n const root = this.canvas.getRootElement() as Root & {\n businessObject?: RootBusinessObject;\n };\n meta = root.businessObject;\n } catch {\n meta = undefined;\n }\n\n const contexts: BoundedContext[] = [];\n const relationships: Relationship[] = [];\n\n for (const el of this.elementRegistry.getAll()) {\n if (el.id === ROOT_ID) continue;\n\n if (isCmContext(el)) {\n const geom = el as unknown as { x: number; y: number; width: number; height: number };\n contexts.push({\n id: el.id,\n label: el.cmLabel ?? \"\",\n position: { x: geom.x, y: geom.y },\n size: { width: geom.width, height: geom.height },\n ...(el.subdomainType ? { subdomainType: el.subdomainType } : {}),\n ...(el.team ? { team: el.team } : {}),\n ...(el.description ? { description: el.description } : {}),\n ...(el.fill ? { fill: el.fill } : {}),\n ...(el.stroke ? { stroke: el.stroke } : {}),\n });\n } else if (isCmRelationship(el)) {\n const source = el.source as { id?: string } | undefined;\n const target = el.target as { id?: string } | undefined;\n if (!source?.id || !target?.id) continue;\n relationships.push({\n id: el.id,\n from: source.id,\n to: target.id,\n pattern: el.pattern,\n ...(el.upstreamRoles?.length ? { upstreamRoles: [...el.upstreamRoles] } : {}),\n ...(el.downstreamRoles?.length ? { downstreamRoles: [...el.downstreamRoles] } : {}),\n ...(el.cmLabel ? { label: el.cmLabel } : {}),\n ...(el.description ? { description: el.description } : {}),\n ...(el.implementationTechnology\n ? { implementationTechnology: el.implementationTechnology }\n : {}),\n });\n }\n }\n\n return {\n version: DOCUMENT_VERSION,\n title: meta?.title ?? \"Untitled context map\",\n contexts,\n relationships,\n };\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport CmImporter from \"./CmImporter.js\";\nimport CmExporter from \"./CmExporter.js\";\n\n/** Document <-> diagram-js bridge (import / export). */\nexport const ioModule: ModuleDeclaration = {\n cmImporter: [\"type\", CmImporter],\n cmExporter: [\"type\", CmExporter],\n};\n\nexport { default as CmImporter } from \"./CmImporter.js\";\nexport { default as CmExporter } from \"./CmExporter.js\";\nexport { saveSVG } from \"./saveSvg.js\";\nexport { ROOT_ID } from \"./types.js\";\nexport type { ImportWarning, RootBusinessObject } from \"./types.js\";\n","import type { ModuleDeclaration } from \"didi\";\nimport { CmBaseViewer } from \"./CmBaseViewer.js\";\nimport { cmModelModule } from \"./model/index.js\";\nimport { cmDrawModule } from \"./draw/index.js\";\nimport { ioModule } from \"./io/index.js\";\n\n/** Read-only renderer: draws a Context Maps diagram with no interaction. */\nexport class Viewer extends CmBaseViewer {\n protected _getModules(): ModuleDeclaration[] {\n return [cmModelModule, cmDrawModule, ioModule];\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport SelectionModule from \"diagram-js/lib/features/selection\";\nimport ZoomScrollModule from \"diagram-js/lib/navigation/zoomscroll\";\nimport MoveCanvasModule from \"diagram-js/lib/navigation/movecanvas\";\nimport { Viewer } from \"./Viewer.js\";\n\n/** Read-only + navigation: zoom (scroll), pan (drag), selection. */\nexport class NavigatedViewer extends Viewer {\n protected override _getModules(): ModuleDeclaration[] {\n return [...super._getModules(), SelectionModule, ZoomScrollModule, MoveCanvasModule];\n }\n}\n","/**\n * Generic, undo-able command that sets arbitrary Context Maps properties\n * (cmLabel, teamType, mode, fill, stroke, description). Returns the changed\n * element so the CommandStack fires `elements.changed` → re-render.\n */\n\nimport type { ElementLike } from \"diagram-js/lib/core/Types\";\nimport type CommandHandler from \"diagram-js/lib/command/CommandHandler\";\n\nexport interface UpdatePropertiesContext {\n element: ElementLike & Record<string, unknown>;\n properties: Record<string, unknown>;\n /** set internally by the handler (for revert). */\n oldProperties?: Record<string, unknown>;\n}\n\nfunction setOrDelete(obj: Record<string, unknown>, key: string, value: unknown): void {\n if (value === undefined) delete obj[key];\n else obj[key] = value;\n}\n\nexport default class UpdatePropertiesHandler implements CommandHandler {\n execute(context: UpdatePropertiesContext): ElementLike[] {\n const { element, properties } = context;\n const target = element as unknown as Record<string, unknown>;\n const old: Record<string, unknown> = {};\n for (const key of Object.keys(properties)) {\n old[key] = target[key];\n setOrDelete(target, key, properties[key]);\n }\n context.oldProperties = old;\n return [element];\n }\n\n revert(context: UpdatePropertiesContext): ElementLike[] {\n const { element, oldProperties } = context;\n const target = element as unknown as Record<string, unknown>;\n if (oldProperties) {\n for (const key of Object.keys(oldProperties)) setOrDelete(target, key, oldProperties[key]);\n }\n return [element];\n }\n}\n","/**\n * Swaps a relationship's two ends: source ⇄ target (and reverses the waypoints).\n * This flips the direction — what was upstream/supplier becomes downstream/\n * customer and vice versa. The integration roles stay bound to their SIDE, not\n * to a context: upstreamRoles (OHS/PL) always describe whichever context is\n * upstream after the swap, downstreamRoles (ACL/CF) the downstream one — the\n * role types are side-specific, so they cannot travel with a context.\n * Undoable (revert simply swaps back).\n */\n\nimport type CommandHandler from \"diagram-js/lib/command/CommandHandler\";\nimport type { Connection, Element } from \"diagram-js/lib/model/Types\";\nimport type { Point } from \"diagram-js/lib/util/Types\";\n\nexport interface SwapEndsContext {\n connection: Connection & { source: Element; target: Element; waypoints: Point[] };\n}\n\nfunction swap(connection: SwapEndsContext[\"connection\"]): Element[] {\n const oldSource = connection.source;\n connection.source = connection.target;\n connection.target = oldSource;\n if (Array.isArray(connection.waypoints)) {\n connection.waypoints = [...connection.waypoints].reverse();\n }\n return [connection];\n}\n\nexport default class SwapEndsHandler implements CommandHandler {\n execute(context: SwapEndsContext): Element[] {\n return swap(context.connection);\n }\n\n revert(context: SwapEndsContext): Element[] {\n return swap(context.connection);\n }\n}\n","/**\n * High-level Context Maps mutations that go through the command stack\n * (undo/redo). Registers the generic property command handler.\n */\n\nimport type CommandStack from \"diagram-js/lib/command/CommandStack\";\nimport type ElementRegistry from \"diagram-js/lib/core/ElementRegistry\";\nimport type GraphicsFactory from \"diagram-js/lib/core/GraphicsFactory\";\nimport {\n isSymmetricPattern,\n type DownstreamRole,\n type RelationshipPattern,\n type SubdomainType,\n type UpstreamRole,\n} from \"@miragon/context-maps-schema-model\";\nimport type { CmContext, CmElement, CmRelationship } from \"../model/di-types.js\";\nimport { isCmRelationship } from \"../model/di-types.js\";\nimport UpdatePropertiesHandler from \"./cmd/UpdatePropertiesHandler.js\";\nimport SwapEndsHandler, { type SwapEndsContext } from \"./cmd/SwapEndsHandler.js\";\n\nconst UPDATE_PROPERTIES = \"element.updateProperties\";\nconst SWAP_ENDS = \"relationship.swapEnds\";\n\nexport default class CmModeling {\n static $inject = [\"commandStack\", \"elementRegistry\", \"graphicsFactory\"];\n\n constructor(\n private readonly commandStack: CommandStack,\n private readonly elementRegistry: ElementRegistry,\n private readonly graphicsFactory: GraphicsFactory,\n ) {\n commandStack.registerHandler(UPDATE_PROPERTIES, UpdatePropertiesHandler);\n commandStack.registerHandler(SWAP_ENDS, SwapEndsHandler);\n }\n\n /**\n * Force an immediate re-render of an element's graphics. diagram-js'\n * ChangeSupport only redraws on `elements.changed` when `element.parent` is\n * set; this guarantees the visual reflects a property/swap change regardless\n * (a redundant redraw is harmless — the visual layer is cleared first).\n */\n private redraw(element: CmElement): void {\n const gfx = this.elementRegistry.getGraphics(element);\n if (!gfx) return;\n this.graphicsFactory.update(isCmRelationship(element) ? \"connection\" : \"shape\", element, gfx);\n }\n\n /** Swap the two ends of a relationship (reverse upstream/downstream). */\n swapEnds(relationship: CmRelationship): void {\n this.commandStack.execute(SWAP_ENDS, {\n connection: relationship,\n } as unknown as SwapEndsContext);\n this.redraw(relationship);\n }\n\n updateProperties(element: CmElement, properties: Record<string, unknown>): void {\n this.commandStack.execute(UPDATE_PROPERTIES, { element, properties });\n this.redraw(element);\n }\n\n /** Rename / relabel any element. */\n updateLabel(element: CmElement, label: string): void {\n this.updateProperties(element, { cmLabel: label || undefined });\n }\n\n // --- context ------------------------------------------------------------\n\n setSubdomainType(context: CmContext, subdomainType: SubdomainType | undefined): void {\n this.updateProperties(context, { subdomainType });\n }\n\n setTeam(context: CmContext, team: string | undefined): void {\n this.updateProperties(context, { team: team || undefined });\n }\n\n setDescription(element: CmElement, description: string | undefined): void {\n this.updateProperties(element, { description: description || undefined });\n }\n\n /** Set or clear per-element colour overrides (`undefined` reverts to default). */\n setColors(context: CmContext, fill: string | undefined, stroke: string | undefined): void {\n this.updateProperties(context, { fill, stroke });\n }\n\n // --- relationship -------------------------------------------------------\n\n /**\n * Switch the pattern and sanitise the roles so the result is always valid:\n * symmetric patterns carry no roles; customer-supplier drops the inapplicable\n * OHS (upstream) and CF (downstream).\n */\n setPattern(relationship: CmRelationship, pattern: RelationshipPattern): void {\n const props: Record<string, unknown> = { pattern };\n if (isSymmetricPattern(pattern)) {\n props.upstreamRoles = undefined;\n props.downstreamRoles = undefined;\n } else if (pattern === \"customer-supplier\") {\n const up = (relationship.upstreamRoles ?? []).filter((r) => r !== \"OHS\");\n const down = (relationship.downstreamRoles ?? []).filter((r) => r !== \"CF\");\n props.upstreamRoles = up.length ? up : undefined;\n props.downstreamRoles = down.length ? down : undefined;\n }\n this.updateProperties(relationship, props);\n }\n\n setUpstreamRoles(relationship: CmRelationship, roles: UpstreamRole[]): void {\n this.updateProperties(relationship, { upstreamRoles: roles.length ? roles : undefined });\n }\n\n setDownstreamRoles(relationship: CmRelationship, roles: DownstreamRole[]): void {\n this.updateProperties(relationship, { downstreamRoles: roles.length ? roles : undefined });\n }\n\n setImplementationTechnology(relationship: CmRelationship, tech: string | undefined): void {\n this.updateProperties(relationship, { implementationTechnology: tech || undefined });\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport CmModeling from \"./CmModeling.js\";\nimport CmLayouter from \"../model/CmLayouter.js\";\n\n/**\n * High-level Context Maps mutations + command handlers. Also (re)binds the\n * cropping `layouter`: diagram-js' ModelingModule binds a default BaseLayouter,\n * and this module loads after it, so binding here wins and relationship lines\n * dock to the context box borders.\n */\nexport const cmModelingModule: ModuleDeclaration = {\n __init__: [\"cmModeling\"],\n cmModeling: [\"type\", CmModeling],\n layouter: [\"type\", CmLayouter],\n};\n\nexport { default as CmModeling } from \"./CmModeling.js\";\n","/**\n * Allowed editing operations.\n *\n * - Contexts are free, placed, resizable shapes that overlap but never nest.\n * - Relationships are connections between two distinct contexts (no\n * self-loops), at most ONE per pair of contexts — a second, overlapping\n * line between the same two contexts is impossible to tell apart visually.\n */\n\nimport RuleProvider from \"diagram-js/lib/features/rules/RuleProvider\";\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport { isCmContext } from \"../model/di-types.js\";\n\ninterface MoveContext {\n target?: { parent?: unknown } | null;\n}\n\ninterface ConnectContext {\n source?: unknown;\n target?: unknown;\n}\n\ninterface ReconnectContext {\n source?: unknown;\n target?: unknown;\n connection?: unknown;\n}\n\nexport default class CmRules extends RuleProvider {\n static override $inject = [\"eventBus\"];\n\n constructor(eventBus: EventBus) {\n super(eventBus);\n }\n\n override init(): void {\n // Don't re-parent a dragged shape into whatever it is dropped on: contexts\n // are independent and only overlap. Dropping on the root (no parent) is fine.\n this.addRule([\"shape.move\", \"elements.move\"], (context: MoveContext) =>\n context.target && context.target.parent ? null : true,\n );\n this.addRule(\"shape.create\", () => true);\n this.addRule(\"shape.resize\", () => true);\n\n // A relationship connects two distinct contexts. Returning an attributes\n // object (not just `true`) makes diagram-js stamp the new connection as a\n // relationship with a default pattern, so it renders correctly.\n this.addRule(\"connection.create\", (context: ConnectContext) =>\n canConnect(context.source, context.target),\n );\n this.addRule(\"connection.reconnect\", (context: ReconnectContext) =>\n canConnect(context.source, context.target, context.connection) ? true : false,\n );\n this.addRule(\"connection.updateWaypoints\", () => true);\n }\n}\n\ninterface ConnectedElement {\n incoming?: Array<{ source?: unknown; target?: unknown }>;\n outgoing?: Array<{ source?: unknown; target?: unknown }>;\n}\n\n/** True if any relationship (other than `ignore`) already links the two contexts, either way. */\nfunction alreadyConnected(source: unknown, target: unknown, ignore?: unknown): boolean {\n const { incoming = [], outgoing = [] } = source as ConnectedElement;\n return [...incoming, ...outgoing].some(\n (connection) =>\n connection !== ignore &&\n ((connection.source === source && connection.target === target) ||\n (connection.source === target && connection.target === source)),\n );\n}\n\n/** Returns default relationship attributes if the connection is allowed, else false. */\nfunction canConnect(\n source: unknown,\n target: unknown,\n ignore?: unknown,\n): false | { cmKind: \"relationship\"; pattern: \"upstream-downstream\" } {\n if (!isCmContext(source) || !isCmContext(target)) return false;\n if (source === target) return false;\n if (alreadyConnected(source, target, ignore)) return false;\n return { cmKind: \"relationship\", pattern: \"upstream-downstream\" };\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport RulesModule from \"diagram-js/lib/features/rules\";\nimport CmRules from \"./CmRules.js\";\n\n/** Context Maps editing rules (connect, move, create, resize). */\nexport const cmRulesModule: ModuleDeclaration = {\n __depends__: [RulesModule],\n __init__: [\"cmRules\"],\n cmRules: [\"type\", CmRules],\n};\n\nexport { default as CmRules } from \"./CmRules.js\";\n","/**\n * Two model-keeping behaviours:\n *\n * 1. Flat model — diagram-js parents a newly created shape to whatever element\n * it is dropped on, which would nest overlapping contexts and glue them\n * together. Force every created shape onto the diagram root instead.\n * (Re-parenting on *move* is prevented separately in CmRules.)\n *\n * 2. Connection relayout — when a context moves or resizes, re-crop the\n * waypoints of its attached relationships to the new box borders, so lines\n * stay docked to the edges.\n */\n\nimport CommandInterceptor from \"diagram-js/lib/command/CommandInterceptor\";\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\nimport type Modeling from \"diagram-js/lib/features/modeling/Modeling\";\nimport type { Connection, Shape } from \"diagram-js/lib/model/Types\";\n\ninterface MovedContext {\n shape?: Shape;\n shapes?: Shape[];\n}\n\nexport default class CmFlatModelBehavior extends CommandInterceptor {\n static override $inject = [\"eventBus\", \"canvas\", \"modeling\"];\n\n constructor(eventBus: EventBus, canvas: Canvas, modeling: Modeling) {\n super(eventBus);\n\n this.preExecute(\n [\"shape.create\", \"elements.create\"],\n (context: { parent?: unknown }) => {\n context.parent = canvas.getRootElement();\n },\n true,\n );\n\n const relayout = (context: MovedContext): void => {\n const shapes = context.shapes ?? (context.shape ? [context.shape] : []);\n const seen = new Set<string>();\n for (const shape of shapes) {\n const attached: Connection[] = [\n ...((shape.incoming as Connection[]) ?? []),\n ...((shape.outgoing as Connection[]) ?? []),\n ];\n for (const connection of attached) {\n if (seen.has(connection.id)) continue;\n seen.add(connection.id);\n modeling.layoutConnection(connection);\n }\n }\n };\n\n this.postExecute([\"shape.move\", \"elements.move\", \"shape.resize\"], relayout, true);\n }\n}\n","/**\n * Marks the canvas container with `cm-dragging` while any drag operation\n * (connect, move, create) is in flight. The CSS keyed on it makes the HTML\n * overlays (connect handles, validation markers, tooltips) click-transparent,\n * so releasing a drag on top of one still reaches the element underneath —\n * otherwise a connect drag dropped on a warning triangle would silently die.\n */\n\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\n\nconst DRAGGING_CLS = \"cm-dragging\";\n\nexport default class CmDragBehavior {\n static $inject = [\"eventBus\", \"canvas\"];\n\n constructor(eventBus: EventBus, canvas: Canvas) {\n eventBus.on(\"drag.init\", () => {\n canvas.getContainer().classList.add(DRAGGING_CLS);\n });\n eventBus.on(\"drag.cleanup\", () => {\n canvas.getContainer().classList.remove(DRAGGING_CLS);\n });\n }\n}\n","/**\n * Clicking an already-selected element KEEPS it selected. diagram-js' stock\n * SelectionBehavior toggles instead (click on selected = deselect), which\n * reads as \"the editor lost my selection\" — especially since the connect\n * handles and the inspector vanish with it. Deselecting is done by clicking\n * the empty canvas. Ctrl/Cmd-click still toggles for multi-select workflows.\n */\n\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type Selection from \"diagram-js/lib/features/selection/Selection\";\nimport { hasPrimaryModifier } from \"diagram-js/lib/util/Mouse\";\nimport { isCmElement } from \"../model/di-types.js\";\n\n/** Above SelectionBehavior's element.click listener (default priority 500). */\nconst BEFORE_SELECTION_BEHAVIOR = 2000;\n\nexport default class CmClickSelectionBehavior {\n static $inject = [\"eventBus\", \"selection\"];\n\n constructor(eventBus: EventBus, selection: Selection) {\n eventBus.on(\n \"element.click\",\n BEFORE_SELECTION_BEHAVIOR,\n (event: { element?: unknown } & Parameters<typeof hasPrimaryModifier>[0]) => {\n const element = event.element;\n if (!isCmElement(element)) return;\n if (hasPrimaryModifier(event)) return;\n if (selection.isSelected(element)) return false;\n },\n );\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport CmFlatModelBehavior from \"./CmFlatModelBehavior.js\";\nimport CmDragBehavior from \"./CmDragBehavior.js\";\nimport CmClickSelectionBehavior from \"./CmClickSelectionBehavior.js\";\n\n/** Editing behaviors: keep the model flat (no nesting), drag-state CSS marker. */\nexport const cmBehaviorsModule: ModuleDeclaration = {\n __init__: [\"cmFlatModelBehavior\", \"cmDragBehavior\", \"cmClickSelectionBehavior\"],\n cmFlatModelBehavior: [\"type\", CmFlatModelBehavior],\n cmDragBehavior: [\"type\", CmDragBehavior],\n cmClickSelectionBehavior: [\"type\", CmClickSelectionBehavior],\n};\n\nexport { default as CmFlatModelBehavior } from \"./CmFlatModelBehavior.js\";\nexport { default as CmDragBehavior } from \"./CmDragBehavior.js\";\nexport { default as CmClickSelectionBehavior } from \"./CmClickSelectionBehavior.js\";\n","/**\n * Tiny inline-SVG glyphs for the palette / legend — the same shapes the canvas\n * draws (contexts coloured by subdomain, plus a relationship line). Returned as\n * HTML strings for diagram-js palette `html`.\n */\n\nimport {\n RELATIONSHIP_PATTERN_SPECS,\n SUBDOMAIN_TYPE_SPECS,\n} from \"@miragon/context-maps-schema-model\";\nimport type { RelationshipPattern, SubdomainType } from \"@miragon/context-maps-schema-model\";\n\nfunction svg(inner: string): string {\n return `<svg class=\"cm-palette-svg\" width=\"24\" height=\"24\" viewBox=\"0 0 26 26\" aria-hidden=\"true\">${inner}</svg>`;\n}\n\n// Kaiser subdomain glyphs (Material star / pan_tool), 24×24 viewBox.\nconst STAR = \"M12 2l2.9 6.26L22 9.27l-5 4.87L18.18 22 12 18.56 5.82 22 7 14.14l-5-4.87 7.1-1.01z\";\nconst HAND =\n \"M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z\";\n\n/** The subdomain glyph centred at (cx, cy) at `size` px: star / hand / dotted circle. */\nfunction subdomainGlyph(\n type: SubdomainType,\n cx: number,\n cy: number,\n size: number,\n color: string,\n): string {\n if (type === \"generic\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${size / 2 - 0.5}\" fill=\"none\" stroke=\"${color}\" stroke-width=\"1.4\" stroke-dasharray=\"1.8 1.8\"/>`;\n }\n const scale = size / 24;\n const rot = type === \"supporting\" ? ` rotate(90 12 12)` : \"\";\n const t = `translate(${cx - 12 * scale} ${cy - 12 * scale}) scale(${scale})${rot}`;\n return `<path d=\"${type === \"core\" ? STAR : HAND}\" fill=\"${color}\" transform=\"${t}\"/>`;\n}\n\nexport function contextIconSvg(type: SubdomainType): string {\n const s = SUBDOMAIN_TYPE_SPECS[type];\n return svg(\n `<rect x=\"2\" y=\"4\" width=\"22\" height=\"18\" rx=\"3.5\" fill=\"${s.fill}\" stroke=\"${s.stroke}\" stroke-width=\"1.5\"/>` +\n subdomainGlyph(type, 13, 13, 12, s.stroke),\n );\n}\n\nexport function relationshipIconSvg(pattern: RelationshipPattern = \"upstream-downstream\"): string {\n const s = RELATIONSHIP_PATTERN_SPECS[pattern];\n const dash = s.dash ? ` stroke-dasharray=\"${s.dash}\"` : \"\";\n const w = Math.min(s.strokeWidth, 2.6);\n return svg(\n `<g stroke=\"${s.stroke}\" stroke-width=\"${w}\" stroke-linecap=\"round\">` +\n `<circle cx=\"5\" cy=\"13\" r=\"2.5\" fill=\"${s.stroke}\" stroke=\"none\"/>` +\n `<line x1=\"7\" y1=\"13\" x2=\"19\" y2=\"13\"${dash}/>` +\n `<circle cx=\"21\" cy=\"13\" r=\"2.5\" fill=\"${s.stroke}\" stroke=\"none\"/></g>`,\n );\n}\n","/**\n * The floating tool palette (styled top-centre, Excalidraw style):\n * drag-to-create the three subdomain types of bounded context. Relationships\n * are drawn via the context pad's connect arrow, not from the palette.\n */\n\nimport type Palette from \"diagram-js/lib/features/palette/Palette\";\nimport type Create from \"diagram-js/lib/features/create/Create\";\nimport type {\n PaletteEntries,\n default as PaletteProvider,\n} from \"diagram-js/lib/features/palette/PaletteProvider\";\nimport type { Element } from \"diagram-js/lib/model/Types\";\nimport { ALL_SUBDOMAIN_SPECS } from \"@miragon/context-maps-schema-model\";\nimport { contextIconSvg } from \"../draw/palette-icons.js\";\nimport type CmElementFactory from \"../model/CmElementFactory.js\";\n\nconst GROUP_CONTEXTS = \"cm-1-contexts\";\n\nfunction entryHtml(icon: string, title: string): string {\n return `<div class=\"entry cm-palette-entry\" draggable=\"true\" title=\"${title}\">${icon}</div>`;\n}\n\nexport default class CmPaletteProvider implements PaletteProvider {\n static $inject = [\"palette\", \"create\", \"cmElementFactory\"];\n\n constructor(\n palette: Palette,\n private readonly create: Create,\n private readonly factory: CmElementFactory,\n ) {\n palette.registerProvider(this);\n }\n\n getPaletteEntries(): PaletteEntries {\n const entries: PaletteEntries = {};\n\n for (const spec of ALL_SUBDOMAIN_SPECS) {\n const start = (event: Event) =>\n this.create.start(\n event as MouseEvent,\n this.factory.createNewContext(spec.type, spec.label) as unknown as Element,\n );\n entries[`context.${spec.type}`] = {\n group: GROUP_CONTEXTS,\n title: `${spec.label} — ${spec.description}`,\n html: entryHtml(contextIconSvg(spec.type), `${spec.label} — ${spec.description}`),\n action: { dragstart: start, click: start },\n };\n }\n\n return entries;\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport PaletteModule from \"diagram-js/lib/features/palette\";\nimport CreateModule from \"diagram-js/lib/features/create\";\nimport ConnectModule from \"diagram-js/lib/features/connect\";\nimport CmPaletteProvider from \"./CmPaletteProvider.js\";\n\n/** Tool palette: drag-to-create contexts. */\nexport const cmPaletteModule: ModuleDeclaration = {\n __depends__: [PaletteModule, CreateModule, ConnectModule],\n __init__: [\"cmPaletteProvider\"],\n cmPaletteProvider: [\"type\", CmPaletteProvider],\n};\n\nexport { default as CmPaletteProvider } from \"./CmPaletteProvider.js\";\n","/**\n * A handful of Material-style icon paths (Apache-2.0) used by the context pad,\n * exposed as HTML markup. Reusable by host chrome too.\n */\n\nexport const ICON_ARROW_FORWARD = \"M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z\";\nexport const ICON_EDIT =\n \"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\";\nexport const ICON_DELETE =\n \"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\";\nexport const ICON_SWAP = \"M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z\";\n\nexport function iconMarkup(path: string, size = 18): string {\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"${path}\"/></svg>`;\n}\n","/**\n * Four connect handles around a selected bounded context — one arrow at the\n * middle of each side (top, right, bottom, left), each pointing outward.\n * Press a handle, drag, release over another context to draw the relationship\n * (press-drag-release ONLY: a click listener would restart the tool after the\n * mouseup and leave the preview line chasing the cursor). Implemented as\n * diagram-js overlays so the handles float outside the shape, follow it, and\n * never collide with the resize handles on the selection outline.\n */\n\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type Overlays from \"diagram-js/lib/features/overlays/Overlays\";\nimport type Selection from \"diagram-js/lib/features/selection/Selection\";\nimport type Connect from \"diagram-js/lib/features/connect/Connect\";\nimport type Dragging from \"diagram-js/lib/features/dragging/Dragging\";\nimport type { Element } from \"diagram-js/lib/model/Types\";\nimport { getMid } from \"diagram-js/lib/layout/LayoutUtil\";\nimport { isCmContext } from \"../model/di-types.js\";\nimport { ICON_ARROW_FORWARD, iconMarkup } from \"../draw/icons.js\";\n\nconst OVERLAY_TYPE = \"cm-connect-handle\";\nconst HANDLE_SIZE = 28;\n/** Clear of the selection outline and its mid-side resize handles. */\nconst HANDLE_GAP = 12;\n\nconst SIDES = [\n { side: \"top\", rotationDeg: -90 },\n { side: \"right\", rotationDeg: 0 },\n { side: \"bottom\", rotationDeg: 90 },\n { side: \"left\", rotationDeg: 180 },\n] as const;\n\ntype Side = (typeof SIDES)[number][\"side\"];\n\nfunction handlePosition(\n side: Side,\n shape: { width: number; height: number },\n): { top: number; left: number } {\n const centeredLeft = shape.width / 2 - HANDLE_SIZE / 2;\n const centeredTop = shape.height / 2 - HANDLE_SIZE / 2;\n const outside = HANDLE_SIZE + HANDLE_GAP;\n switch (side) {\n case \"top\":\n return { top: -outside, left: centeredLeft };\n case \"bottom\":\n return { top: shape.height + HANDLE_GAP, left: centeredLeft };\n case \"left\":\n return { top: centeredTop, left: -outside };\n case \"right\":\n return { top: centeredTop, left: shape.width + HANDLE_GAP };\n }\n}\n\nexport default class CmConnectHandles {\n static $inject = [\"eventBus\", \"selection\", \"overlays\", \"connect\", \"dragging\"];\n\n constructor(\n private readonly eventBus: EventBus,\n private readonly selection: Selection,\n private readonly overlays: Overlays,\n connect: Connect,\n private readonly dragging: Dragging,\n ) {\n // Not used to start the drag, but injecting Connect instantiates it so its\n // connect.* event handlers (hover/end → modeling.connect) are registered —\n // the connect module does not eagerly initialize it.\n void connect;\n const refresh = (): void => this.refresh();\n eventBus.on(\"selection.changed\", refresh);\n // Re-anchor after resize/undo/redo (handle offsets depend on width/height).\n eventBus.on(\"commandStack.changed\", refresh);\n }\n\n private refresh(): void {\n this.overlays.remove({ type: OVERLAY_TYPE });\n\n const selected = this.selection.get() as Element[];\n if (selected.length !== 1) return;\n const element = selected[0];\n if (!isCmContext(element)) return;\n const shape = element as unknown as { width: number; height: number };\n\n for (const { side, rotationDeg } of SIDES) {\n const handle = document.createElement(\"div\");\n handle.className = \"cm-connect-handle\";\n handle.dataset.side = side;\n handle.title = \"Connect to another context\";\n handle.innerHTML = `<span style=\"display:flex;transform:rotate(${rotationDeg}deg)\">${iconMarkup(ICON_ARROW_FORWARD)}</span>`;\n handle.addEventListener(\"mousedown\", (event: MouseEvent) => {\n if (event.button !== 0) return;\n event.preventDefault();\n event.stopPropagation();\n // Same payload as Connect#start, but with trapClick OFF: the ghost-\n // click trap Dragging arms after a drag is only consumed by a click\n // that reaches the canvas — a drag started on this HTML handle never\n // produces one, so the trap would instead swallow the user's NEXT\n // click on a context (no selection, seemingly broken editor).\n this.dragging.init(event, \"connect\", {\n autoActivate: false,\n trapClick: false,\n data: {\n shape: element,\n context: { start: element, connectionStart: getMid(element) },\n },\n });\n // Keep the source context marked after the drag: the drag lifecycle\n // clears the selection, but the user is still \"at\" this context. Low\n // priority so this runs after the stock cleanup listeners.\n this.eventBus.once(\"connect.cleanup\", 250, () => {\n if (this.selection.get().length === 0) this.selection.select(element);\n });\n });\n\n this.overlays.add(element, OVERLAY_TYPE, {\n position: handlePosition(side, shape),\n html: handle,\n });\n }\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport ConnectModule from \"diagram-js/lib/features/connect\";\nimport OverlaysModule from \"diagram-js/lib/features/overlays\";\nimport SelectionModule from \"diagram-js/lib/features/selection\";\nimport CmConnectHandles from \"./CmConnectHandles.js\";\n\n/** Four outward connect arrows around a selected context (top/right/bottom/left). */\nexport const cmConnectHandlesModule: ModuleDeclaration = {\n __depends__: [ConnectModule, OverlaysModule, SelectionModule],\n __init__: [\"cmConnectHandles\"],\n cmConnectHandles: [\"type\", CmConnectHandles],\n};\n\nexport { default as CmConnectHandles } from \"./CmConnectHandles.js\";\n","/**\n * Inline label editing as an HTML overlay (an <input> centred over the element).\n * Commit goes through `cmModeling.updateLabel` → command stack (undoable).\n * Double-click any element (context or relationship) to (re)label it.\n */\n\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type { Point } from \"diagram-js/lib/util/Types\";\nimport { isCmElement, isCmRelationship, type CmElement } from \"../model/di-types.js\";\nimport type CmModeling from \"../modeling/CmModeling.js\";\n\ninterface ActiveEdit {\n commit: () => void;\n cleanup: () => void;\n}\n\nexport default class CmLabelEditing {\n static $inject = [\"eventBus\", \"canvas\", \"cmModeling\"];\n\n private active: ActiveEdit | null = null;\n\n constructor(\n eventBus: EventBus,\n private readonly canvas: Canvas,\n private readonly modeling: CmModeling,\n ) {\n eventBus.on(\"element.dblclick\", (event: { element?: unknown }) => {\n if (isCmElement(event.element)) this.activate(event.element);\n });\n // Any click/drag/pan outside the input commits (only Escape discards).\n eventBus.on([\"element.mousedown\", \"drag.init\", \"canvas.viewbox.changing\"], () =>\n this.active?.commit(),\n );\n }\n\n activate(element: CmElement): void {\n this.active?.commit();\n\n const container = this.canvas.getContainer();\n const scale = this.canvas.zoom();\n const vb = this.canvas.viewbox();\n const { x: cx, y: cy } = centreOf(element);\n const width = 170;\n const left = (cx - vb.x) * scale - width / 2;\n const top = (cy - vb.y) * scale - 14;\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.className = \"cm-label-input\";\n input.value = element.cmLabel ?? \"\";\n input.style.position = \"absolute\";\n input.style.left = `${left}px`;\n input.style.top = `${top}px`;\n input.style.width = `${width}px`;\n container.appendChild(input);\n input.focus();\n input.select();\n\n let done = false;\n const cleanup = () => {\n if (done) return;\n done = true;\n input.removeEventListener(\"keydown\", onKey);\n input.removeEventListener(\"blur\", onBlur);\n input.remove();\n this.active = null;\n };\n const commit = () => {\n if (done) return;\n const value = input.value.trim();\n const changed = value !== (element.cmLabel ?? \"\");\n cleanup();\n if (changed) this.modeling.updateLabel(element, value);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commit();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n cleanup();\n }\n };\n const onBlur = () => commit();\n input.addEventListener(\"keydown\", onKey);\n input.addEventListener(\"blur\", onBlur);\n\n this.active = { commit, cleanup };\n }\n\n cancel(): void {\n this.active?.cleanup();\n }\n}\n\n/** The canvas-space centre of a context (box centre) or relationship (mid-waypoint). */\nfunction centreOf(element: CmElement): Point {\n if (isCmRelationship(element)) {\n const wp = (element.waypoints ?? []) as Point[];\n if (wp.length >= 2) {\n const a = wp[0];\n const b = wp[wp.length - 1];\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n }\n if (wp.length === 1) return { x: wp[0].x, y: wp[0].y };\n return { x: 0, y: 0 };\n }\n const shape = element as unknown as { x: number; y: number; width: number; height: number };\n return { x: shape.x + shape.width / 2, y: shape.y + shape.height / 2 };\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport CmLabelEditing from \"./CmLabelEditing.js\";\n\n/** Inline label editing (double-click a team to rename). */\nexport const cmLabelEditingModule: ModuleDeclaration = {\n __init__: [\"cmLabelEditing\"],\n cmLabelEditing: [\"type\", CmLabelEditing],\n};\n\nexport { default as CmLabelEditing } from \"./CmLabelEditing.js\";\n","/**\n * Keyboard shortcuts: undo / redo / delete-selection. Bound to the document so\n * they work without first clicking (focusing) the canvas — typing inside form\n * fields is left untouched. No container `tabindex`, so the canvas never shows a\n * focus ring.\n */\n\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\nimport type CommandStack from \"diagram-js/lib/command/CommandStack\";\nimport type Selection from \"diagram-js/lib/features/selection/Selection\";\nimport type Modeling from \"diagram-js/lib/features/modeling/Modeling\";\nimport type { Element } from \"diagram-js/lib/model/Types\";\n\nfunction isTypingTarget(target: EventTarget | null): boolean {\n const el = target as HTMLElement | null;\n if (!el) return false;\n return (\n el.tagName === \"INPUT\" ||\n el.tagName === \"TEXTAREA\" ||\n el.tagName === \"SELECT\" ||\n el.isContentEditable\n );\n}\n\nexport default class CmKeyboard {\n static $inject = [\"canvas\", \"commandStack\", \"selection\", \"modeling\"];\n\n constructor(\n canvas: Canvas,\n commandStack: CommandStack,\n selection: Selection,\n modeling: Modeling,\n ) {\n const doc = canvas.getContainer().ownerDocument ?? document;\n\n doc.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (isTypingTarget(e.target)) return;\n const cmd = e.ctrlKey || e.metaKey;\n const key = e.key.toLowerCase();\n\n if (cmd && key === \"z\" && !e.shiftKey) {\n e.preventDefault();\n if (commandStack.canUndo()) commandStack.undo();\n } else if ((cmd && key === \"z\" && e.shiftKey) || (cmd && key === \"y\")) {\n e.preventDefault();\n if (commandStack.canRedo()) commandStack.redo();\n } else if (key === \"delete\" || key === \"backspace\") {\n const sel = selection.get() as Element[];\n if (sel.length) {\n e.preventDefault();\n modeling.removeElements([...sel]);\n }\n }\n });\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport CmKeyboard from \"./CmKeyboard.js\";\n\n/** Undo/redo + delete-selection on the canvas container. */\nexport const cmKeyboardModule: ModuleDeclaration = {\n __init__: [\"cmKeyboard\"],\n cmKeyboard: [\"type\", CmKeyboard],\n};\n\nexport { default as CmKeyboard } from \"./CmKeyboard.js\";\n","/**\n * Live semantic-rule markers on the canvas: a relationship with validation\n * findings gets a small warning triangle next to the issue — amber for\n * warnings, red if any finding is an error. Sided findings (e.g. an ACL issue\n * is a downstream concern) anchor at the BOTTOM-RIGHT corner of that end's\n * role-chip box (geometry shared with the renderer via endRoleChipLayout);\n * findings about the relationship as a whole sit at the middle of the line.\n * Hovering shows the message(s) instantly via a CSS tooltip (a native `title`\n * would only appear after the OS hover delay). Implemented as diagram-js\n * overlays (HTML above the SVG), so hover is not swallowed by the connection\n * hit layer and the marker follows its element. Recomputed on every change.\n */\n\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport type ElementRegistry from \"diagram-js/lib/core/ElementRegistry\";\nimport type Overlays from \"diagram-js/lib/features/overlays/Overlays\";\nimport type { Point } from \"diagram-js/lib/util/Types\";\nimport { validateDocument, type SemanticFinding } from \"@miragon/context-maps-schema-model\";\nimport type CmExporter from \"../io/CmExporter.js\";\nimport { isCmRelationship, type CmRelationship } from \"../model/di-types.js\";\nimport { endRoleChipLayout } from \"../draw/endRoleChips.js\";\n\nconst OVERLAY_TYPE = \"cm-validation\";\nconst MARKER_SIZE = 20;\nconst LINE_OFFSET = 16;\n/** Fallback distance from the endpoint when the end has no role chips. */\nconst END_DISTANCE = 44;\n\ntype MarkerSide = \"upstream\" | \"downstream\" | \"middle\";\n\nconst AMBER = \"#d97706\";\nconst RED = \"#dc2626\";\n\ninterface RankedFinding extends SemanticFinding {\n kind: \"error\" | \"warning\";\n}\n\nfunction markerHtml(findings: RankedFinding[]): HTMLElement {\n const hasError = findings.some((finding) => finding.kind === \"error\");\n const fill = hasError ? RED : AMBER;\n const marker = document.createElement(\"div\");\n marker.className = \"cm-validation-marker\";\n marker.innerHTML =\n `<svg width=\"${MARKER_SIZE}\" height=\"${MARKER_SIZE}\" viewBox=\"0 0 24 24\">` +\n `<path d=\"M12 2.5 23 21.5H1Z\" fill=\"${fill}\" stroke=\"#fff\" stroke-width=\"1.6\" stroke-linejoin=\"round\"/>` +\n `<text x=\"12\" y=\"18.5\" text-anchor=\"middle\" font-size=\"12\" font-weight=\"800\" fill=\"#fff\" font-family=\"system-ui, sans-serif\">!</text>` +\n `</svg>`;\n\n const tooltip = document.createElement(\"div\");\n tooltip.className = \"cm-validation-tooltip\";\n for (const finding of findings) {\n const message = document.createElement(\"div\");\n message.className = \"cm-validation-tooltip__message\";\n message.textContent = finding.message;\n tooltip.appendChild(message);\n }\n marker.appendChild(tooltip);\n return marker;\n}\n\n/**\n * Where the marker sits. Sided findings anchor at the bottom-right corner of\n * the role-chip box of that end (that is where the offending OHS/PL/ACL/CF\n * badge is drawn); without chips they fall back to a point near the endpoint.\n * Whole-relationship findings sit at the middle of the line, nudged off it.\n */\nfunction anchorPoint(relationship: CmRelationship, waypoints: Point[], side: MarkerSide): Point {\n const start = waypoints[0];\n const end = waypoints[waypoints.length - 1];\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const length = Math.hypot(dx, dy) || 1;\n const ux = dx / length;\n const uy = dy / length;\n\n if (side === \"middle\") {\n return {\n x: (start.x + end.x) / 2 + -uy * LINE_OFFSET,\n y: (start.y + end.y) / 2 + ux * LINE_OFFSET,\n };\n }\n\n const customerSupplier = relationship.pattern === \"customer-supplier\";\n const layout =\n side === \"upstream\"\n ? endRoleChipLayout(\n start,\n end,\n customerSupplier ? \"S\" : \"U\",\n relationship.upstreamRoles ?? [],\n )\n : endRoleChipLayout(\n end,\n start,\n customerSupplier ? \"C\" : \"D\",\n relationship.downstreamRoles ?? [],\n );\n if (layout) {\n // Centred (almost) on the chip box corner: the triangle's visible body is\n // bottom-heavy, so half the marker overlapping the corner reads as sitting\n // right AT the corner instead of floating next to it.\n const corner = { x: layout.box.x + layout.box.width, y: layout.box.y + layout.box.height };\n return { x: corner.x + 1, y: corner.y + 1 };\n }\n\n const along = Math.min(END_DISTANCE, length * 0.35);\n const baseX = side === \"upstream\" ? start.x + ux * along : end.x - ux * along;\n const baseY = side === \"upstream\" ? start.y + uy * along : end.y - uy * along;\n return { x: baseX + -uy * LINE_OFFSET, y: baseY + ux * LINE_OFFSET };\n}\n\nexport default class CmValidationMarkers {\n static $inject = [\"eventBus\", \"elementRegistry\", \"overlays\", \"cmExporter\"];\n\n constructor(\n eventBus: EventBus,\n private readonly elementRegistry: ElementRegistry,\n private readonly overlays: Overlays,\n private readonly exporter: CmExporter,\n ) {\n const refresh = (): void => this.refresh();\n eventBus.on(\"import.render.done\", refresh);\n eventBus.on(\"commandStack.changed\", refresh);\n }\n\n private refresh(): void {\n this.overlays.remove({ type: OVERLAY_TYPE });\n\n const report = validateDocument(this.exporter.export());\n // One marker per relationship END the findings point at (or the middle for\n // whole-relationship findings), so the triangle sits next to the issue.\n const byAnchor = new Map<string, { relationshipId: string; findings: RankedFinding[] }>();\n const collect = (findings: SemanticFinding[], kind: RankedFinding[\"kind\"]): void => {\n for (const finding of findings) {\n if (!finding.relationshipId) continue;\n const key = `${finding.relationshipId} ${finding.side ?? \"middle\"}`;\n const group = byAnchor.get(key) ?? { relationshipId: finding.relationshipId, findings: [] };\n group.findings.push({ ...finding, kind });\n byAnchor.set(key, group);\n }\n };\n collect(report.errors, \"error\");\n collect(report.warnings, \"warning\");\n\n for (const [key, group] of byAnchor) {\n const element = this.elementRegistry.get(group.relationshipId);\n if (!isCmRelationship(element)) continue;\n const waypoints = (element.waypoints ?? []) as Point[];\n if (waypoints.length < 2) continue;\n const side = key.split(\" \")[1] as MarkerSide;\n const { x: markerX, y: markerY } = anchorPoint(element, waypoints, side);\n\n // Overlay positions on a connection are relative to its waypoint bbox.\n const bboxX = Math.min(...waypoints.map((p) => p.x));\n const bboxY = Math.min(...waypoints.map((p) => p.y));\n this.overlays.add(element, OVERLAY_TYPE, {\n position: {\n left: markerX - bboxX - MARKER_SIZE / 2,\n top: markerY - bboxY - MARKER_SIZE / 2,\n },\n html: markerHtml(group.findings),\n });\n }\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport OverlaysModule from \"diagram-js/lib/features/overlays\";\nimport CmValidationMarkers from \"./CmValidationMarkers.js\";\n\n/** Live semantic-rule markers (warning triangles with tooltips) on the canvas. */\nexport const cmValidationModule: ModuleDeclaration = {\n __depends__: [OverlaysModule],\n __init__: [\"cmValidationMarkers\"],\n cmValidationMarkers: [\"type\", CmValidationMarkers],\n};\n\nexport { default as CmValidationMarkers } from \"./CmValidationMarkers.js\";\n","/**\n * Enforces a fixed stacking order regardless of creation order, by reordering\n * the element graphics within the canvas layer. Back → front:\n *\n * relationships < contexts\n *\n * So the relationship lines always read behind the context boxes and appear to\n * dock to the box borders (the segment inside a box is covered by the box).\n */\n\nimport type Canvas from \"diagram-js/lib/core/Canvas\";\nimport type ElementRegistry from \"diagram-js/lib/core/ElementRegistry\";\nimport type EventBus from \"diagram-js/lib/core/EventBus\";\nimport { isCmElement, isCmRelationship, type CmElement } from \"../model/di-types.js\";\n\n/** Lower = further back. */\nfunction tier(el: CmElement): number {\n return isCmRelationship(el) ? 0 : 1;\n}\n\nexport default class CmZOrder {\n static $inject = [\"eventBus\", \"canvas\", \"elementRegistry\"];\n\n private importing = false;\n\n constructor(\n eventBus: EventBus,\n private readonly canvas: Canvas,\n private readonly elementRegistry: ElementRegistry,\n ) {\n eventBus.on(\"import.render.start\", () => {\n this.importing = true;\n });\n eventBus.on(\"import.render.done\", () => {\n this.importing = false;\n this.reorder();\n });\n eventBus.on(\"commandStack.changed\", () => {\n if (!this.importing) this.reorder();\n });\n }\n\n /** Re-append each element's graphics group in ascending tier order (back → front). */\n reorder(): void {\n const ordered = (this.elementRegistry.getAll().filter(isCmElement) as CmElement[]).sort(\n (a, b) => tier(a) - tier(b),\n );\n for (const el of ordered) {\n const gfx = this.canvas.getGraphics(el) as SVGElement | undefined;\n const wrapper = gfx?.parentNode as (Node & ChildNode) | null;\n const layer = wrapper?.parentNode as (Node & { appendChild(n: Node): Node }) | null;\n if (wrapper && layer) layer.appendChild(wrapper);\n }\n }\n}\n","import type { ModuleDeclaration } from \"didi\";\nimport CmZOrder from \"./CmZOrder.js\";\n\n/** Keeps the fixed stacking order (interactions on top, base teams at the back). */\nexport const cmZOrderModule: ModuleDeclaration = {\n __init__: [\"cmZOrder\"],\n cmZOrder: [\"type\", CmZOrder],\n};\n\nexport { default as CmZOrder } from \"./CmZOrder.js\";\n","import type { ModuleDeclaration } from \"didi\";\nimport type CommandStack from \"diagram-js/lib/command/CommandStack\";\n\nimport ConnectionPreviewModule from \"diagram-js/lib/features/connection-preview\";\nimport ModelingModule from \"diagram-js/lib/features/modeling\";\nimport MoveModule from \"diagram-js/lib/features/move\";\nimport OutlineModule from \"diagram-js/lib/features/outline\";\nimport ResizeModule from \"diagram-js/lib/features/resize\";\n\nimport { NavigatedViewer } from \"./NavigatedViewer.js\";\nimport { cmModelingModule } from \"./modeling/index.js\";\nimport { cmRulesModule } from \"./rules/index.js\";\nimport { cmBehaviorsModule } from \"./behaviors/index.js\";\nimport { cmPaletteModule } from \"./palette/index.js\";\nimport { cmConnectHandlesModule } from \"./connect-handles/index.js\";\nimport { cmLabelEditingModule } from \"./label-editing/index.js\";\nimport { cmKeyboardModule } from \"./keyboard/index.js\";\nimport { cmValidationModule } from \"./validation/index.js\";\nimport { cmZOrderModule } from \"./zorder/index.js\";\n\n/**\n * Full Context Maps editor: palette/create, move, resize, connect with\n * rules, context pad, inline label editing, undo/redo.\n */\nexport class Modeler extends NavigatedViewer {\n protected override _getModules(): ModuleDeclaration[] {\n return [\n ...super._getModules(),\n // diagram-js stock\n ConnectionPreviewModule,\n ModelingModule,\n MoveModule,\n OutlineModule,\n ResizeModule,\n // Context Maps editor\n cmModelingModule,\n cmRulesModule,\n cmBehaviorsModule,\n cmPaletteModule,\n cmConnectHandlesModule,\n cmLabelEditingModule,\n cmKeyboardModule,\n cmValidationModule,\n cmZOrderModule,\n ];\n }\n\n undo(): void {\n this.get<CommandStack>(\"commandStack\").undo();\n }\n\n redo(): void {\n this.get<CommandStack>(\"commandStack\").redo();\n }\n\n canUndo(): boolean {\n return this.get<CommandStack>(\"commandStack\").canUndo();\n }\n\n canRedo(): boolean {\n return this.get<CommandStack>(\"commandStack\").canRedo();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { default as Canvas } from 'diagram-js/lib/core/Canvas';
2
+ import { default as ElementRegistry } from 'diagram-js/lib/core/ElementRegistry';
3
+ import { CmDocument } from '@miragon/context-maps-schema-model';
4
+ export default class CmExporter {
5
+ private readonly elementRegistry;
6
+ private readonly canvas;
7
+ static $inject: string[];
8
+ constructor(elementRegistry: ElementRegistry, canvas: Canvas);
9
+ export(): CmDocument;
10
+ }
11
+ //# sourceMappingURL=CmExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CmExporter.d.ts","sourceRoot":"","sources":["../../src/io/CmExporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AAGvE,OAAO,KAAK,EAAgC,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAInG,MAAM,CAAC,OAAO,OAAO,UAAU;IAI3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,MAAM,CAAC,OAAO,WAAiC;gBAG5B,eAAe,EAAE,eAAe,EAChC,MAAM,EAAE,MAAM;IAGjC,MAAM,IAAI,UAAU;CAyDrB"}
@@ -0,0 +1,20 @@
1
+ import { default as Canvas } from 'diagram-js/lib/core/Canvas';
2
+ import { default as ElementFactory } from 'diagram-js/lib/core/ElementFactory';
3
+ import { default as ElementRegistry } from 'diagram-js/lib/core/ElementRegistry';
4
+ import { default as EventBus } from 'diagram-js/lib/core/EventBus';
5
+ import { CmDocument } from '@miragon/context-maps-schema-model';
6
+ import { default as CmElementFactory } from '../model/CmElementFactory.js';
7
+ import { ImportWarning } from './types.js';
8
+ export default class CmImporter {
9
+ private readonly canvas;
10
+ private readonly elementFactory;
11
+ private readonly factory;
12
+ private readonly eventBus;
13
+ private readonly elementRegistry;
14
+ static $inject: string[];
15
+ constructor(canvas: Canvas, elementFactory: ElementFactory, factory: CmElementFactory, eventBus: EventBus, elementRegistry: ElementRegistry);
16
+ import(doc: CmDocument): ImportWarning[];
17
+ /** Removes every element (for re-import). */
18
+ clear(): void;
19
+ }
20
+ //# sourceMappingURL=CmImporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CmImporter.d.ts","sourceRoot":"","sources":["../../src/io/CmImporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,cAAc,MAAM,oCAAoC,CAAC;AACrE,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AACvE,OAAO,KAAK,QAAQ,MAAM,8BAA8B,CAAC;AAGzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAW,KAAK,aAAa,EAA2B,MAAM,YAAY,CAAC;AA4BlF,MAAM,CAAC,OAAO,OAAO,UAAU;IAI3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAPlC,MAAM,CAAC,OAAO,WAAmF;gBAG9E,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe;IAGnD,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,aAAa,EAAE;IAmDxC,6CAA6C;IAC7C,KAAK,IAAI,IAAI;CAWd"}
@@ -0,0 +1,9 @@
1
+ import { ModuleDeclaration } from 'didi';
2
+ /** Document <-> diagram-js bridge (import / export). */
3
+ export declare const ioModule: ModuleDeclaration;
4
+ export { default as CmImporter } from './CmImporter.js';
5
+ export { default as CmExporter } from './CmExporter.js';
6
+ export { saveSVG } from './saveSvg.js';
7
+ export { ROOT_ID } from './types.js';
8
+ export type { ImportWarning, RootBusinessObject } from './types.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAI9C,wDAAwD;AACxD,eAAO,MAAM,QAAQ,EAAE,iBAGtB,CAAC;AAEF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { default as Canvas } from 'diagram-js/lib/core/Canvas';
2
+ import { default as ElementRegistry } from 'diagram-js/lib/core/ElementRegistry';
3
+ export declare function saveSVG(canvas: Canvas, elementRegistry: ElementRegistry): {
4
+ svg: string;
5
+ };
6
+ //# sourceMappingURL=saveSvg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saveSvg.d.ts","sourceRoot":"","sources":["../../src/io/saveSvg.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AAKvE,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CA0CzF"}
@@ -0,0 +1,11 @@
1
+ /** ID of the diagram-js root element holding the Context Maps diagram. */
2
+ export declare const ROOT_ID = "cm-root";
3
+ export interface ImportWarning {
4
+ readonly message: string;
5
+ readonly elementId?: string;
6
+ }
7
+ /** Diagram-level metadata stashed on the root element. */
8
+ export interface RootBusinessObject {
9
+ title: string;
10
+ }
11
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/io/types.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,eAAO,MAAM,OAAO,YAAY,CAAC;AAEjC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,9 @@
1
+ import { default as Canvas } from 'diagram-js/lib/core/Canvas';
2
+ import { default as CommandStack } from 'diagram-js/lib/command/CommandStack';
3
+ import { default as Selection } from 'diagram-js/lib/features/selection/Selection';
4
+ import { default as Modeling } from 'diagram-js/lib/features/modeling/Modeling';
5
+ export default class CmKeyboard {
6
+ static $inject: string[];
7
+ constructor(canvas: Canvas, commandStack: CommandStack, selection: Selection, modeling: Modeling);
8
+ }
9
+ //# sourceMappingURL=CmKeyboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CmKeyboard.d.ts","sourceRoot":"","sources":["../../src/keyboard/CmKeyboard.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,qCAAqC,CAAC;AACpE,OAAO,KAAK,SAAS,MAAM,6CAA6C,CAAC;AACzE,OAAO,KAAK,QAAQ,MAAM,2CAA2C,CAAC;AActE,MAAM,CAAC,OAAO,OAAO,UAAU;IAC7B,MAAM,CAAC,OAAO,WAAuD;gBAGnE,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ;CAwBrB"}
@@ -0,0 +1,5 @@
1
+ import { ModuleDeclaration } from 'didi';
2
+ /** Undo/redo + delete-selection on the canvas container. */
3
+ export declare const cmKeyboardModule: ModuleDeclaration;
4
+ export { default as CmKeyboard } from './CmKeyboard.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keyboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAG9C,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,EAAE,iBAG9B,CAAC;AAEF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { default as Canvas } from 'diagram-js/lib/core/Canvas';
2
+ import { default as EventBus } from 'diagram-js/lib/core/EventBus';
3
+ import { CmElement } from '../model/di-types.js';
4
+ import { default as CmModeling } from '../modeling/CmModeling.js';
5
+ export default class CmLabelEditing {
6
+ private readonly canvas;
7
+ private readonly modeling;
8
+ static $inject: string[];
9
+ private active;
10
+ constructor(eventBus: EventBus, canvas: Canvas, modeling: CmModeling);
11
+ activate(element: CmElement): void;
12
+ cancel(): void;
13
+ }
14
+ //# sourceMappingURL=CmLabelEditing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CmLabelEditing.d.ts","sourceRoot":"","sources":["../../src/label-editing/CmLabelEditing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,QAAQ,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACrF,OAAO,KAAK,UAAU,MAAM,2BAA2B,CAAC;AAOxD,MAAM,CAAC,OAAO,OAAO,cAAc;IAO/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP3B,MAAM,CAAC,OAAO,WAAwC;IAEtD,OAAO,CAAC,MAAM,CAA2B;gBAGvC,QAAQ,EAAE,QAAQ,EACD,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,UAAU;IAWvC,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI;IAuDlC,MAAM,IAAI,IAAI;CAGf"}
@@ -0,0 +1,5 @@
1
+ import { ModuleDeclaration } from 'didi';
2
+ /** Inline label editing (double-click a team to rename). */
3
+ export declare const cmLabelEditingModule: ModuleDeclaration;
4
+ export { default as CmLabelEditing } from './CmLabelEditing.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/label-editing/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAG9C,4DAA4D;AAC5D,eAAO,MAAM,oBAAoB,EAAE,iBAGlC,CAAC;AAEF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { default as ElementFactory } from 'diagram-js/lib/core/ElementFactory';
2
+ import { Connection, Label, Root, Shape } from 'diagram-js/lib/model/Types';
3
+ export default class CmDiagramElementFactory extends ElementFactory {
4
+ create(type: "root", attrs?: Partial<Root>): Root;
5
+ create(type: "shape", attrs?: Partial<Shape>): Shape;
6
+ create(type: "connection", attrs?: Partial<Connection>): Connection;
7
+ create(type: "label", attrs?: Partial<Label>): Label;
8
+ }
9
+ //# sourceMappingURL=CmDiagramElementFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CmDiagramElementFactory.d.ts","sourceRoot":"","sources":["../../src/model/CmDiagramElementFactory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,cAAc,MAAM,oCAAoC,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAGjF,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,cAAc;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IACjD,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK;IACpD,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU;IACnE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK;CAU9D"}
@@ -0,0 +1,13 @@
1
+ import { default as ElementFactory } from 'diagram-js/lib/core/ElementFactory';
2
+ import { Point } from 'diagram-js/lib/util/Types';
3
+ import { BoundedContext, Relationship, SubdomainType } from '@miragon/context-maps-schema-model';
4
+ import { CmContext, CmRelationship } from './di-types.js';
5
+ export default class CmElementFactory {
6
+ private readonly elementFactory;
7
+ static $inject: string[];
8
+ constructor(elementFactory: ElementFactory);
9
+ createContext(ctx: BoundedContext): CmContext;
10
+ createRelationship(rel: Relationship, source: CmContext, target: CmContext, waypoints: Point[]): CmRelationship;
11
+ createNewContext(subdomainType: SubdomainType, label?: string): CmContext;
12
+ }
13
+ //# sourceMappingURL=CmElementFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CmElementFactory.d.ts","sourceRoot":"","sources":["../../src/model/CmElementFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,cAAc,MAAM,oCAAoC,CAAC;AACrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAEvD,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,aAAa,EACd,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,gBAAgB;IAGvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAF3C,MAAM,CAAC,OAAO,WAAsB;gBAEP,cAAc,EAAE,cAAc;IAI3D,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS;IAiB7C,kBAAkB,CAChB,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,KAAK,EAAE,GACjB,cAAc;IAuBjB,gBAAgB,CAAC,aAAa,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS;CAU1E"}
@@ -0,0 +1,21 @@
1
+ import { default as CroppingConnectionDocking } from 'diagram-js/lib/layout/CroppingConnectionDocking';
2
+ import { ConnectionLike, ShapeLike } from 'diagram-js/lib/model/Types';
3
+ import { Point } from 'diagram-js/lib/util/Types';
4
+ interface LayoutHints {
5
+ /**
6
+ * diagram-js may pass a Point (drag anchor) or `false` (end did not move,
7
+ * e.g. MoveHelper's `connectionStart: sourceMoved && anchor`) here.
8
+ */
9
+ connectionStart?: Point | false;
10
+ connectionEnd?: Point | false;
11
+ source?: ShapeLike;
12
+ target?: ShapeLike;
13
+ }
14
+ export default class CmLayouter {
15
+ private readonly docking;
16
+ static $inject: string[];
17
+ constructor(docking: CroppingConnectionDocking);
18
+ layoutConnection(connection: ConnectionLike, hints?: LayoutHints): Point[];
19
+ }
20
+ export {};
21
+ //# sourceMappingURL=CmLayouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CmLayouter.d.ts","sourceRoot":"","sources":["../../src/model/CmLayouter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,yBAAyB,MAAM,iDAAiD,CAAC;AAC7F,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAEvD,UAAU,WAAW;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC9B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,CAAC,OAAO,OAAO,UAAU;IAGjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,MAAM,CAAC,OAAO,WAAyB;gBAEV,OAAO,EAAE,yBAAyB;IAE/D,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,KAAK,GAAE,WAAgB,GAAG,KAAK,EAAE;CAoB/E"}
@@ -0,0 +1,27 @@
1
+ import { Connection, Shape } from 'diagram-js/lib/model/Types';
2
+ import { DownstreamRole, RelationshipPattern, SubdomainType, UpstreamRole } from '@miragon/context-maps-schema-model';
3
+ export type CmKind = "context" | "relationship";
4
+ export interface CmContext extends Shape {
5
+ cmKind: "context";
6
+ subdomainType?: SubdomainType;
7
+ /** Display name (separate from diagram-js `label`). */
8
+ cmLabel?: string;
9
+ team?: string;
10
+ description?: string;
11
+ fill?: string;
12
+ stroke?: string;
13
+ }
14
+ export interface CmRelationship extends Connection {
15
+ cmKind: "relationship";
16
+ pattern: RelationshipPattern;
17
+ upstreamRoles?: UpstreamRole[];
18
+ downstreamRoles?: DownstreamRole[];
19
+ cmLabel?: string;
20
+ description?: string;
21
+ implementationTechnology?: string;
22
+ }
23
+ export type CmElement = CmContext | CmRelationship;
24
+ export declare function isCmElement(el: unknown): el is CmElement;
25
+ export declare function isCmContext(el: unknown): el is CmContext;
26
+ export declare function isCmRelationship(el: unknown): el is CmRelationship;
27
+ //# sourceMappingURL=di-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"di-types.d.ts","sourceRoot":"","sources":["../../src/model/di-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,YAAY,EACb,MAAM,oCAAoC,CAAC;AAE5C,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,cAAc,CAAC;AAEhD,MAAM,WAAW,SAAU,SAAQ,KAAK;IACtC,MAAM,EAAE,SAAS,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,cAAc,CAAC;AAQnD,wBAAgB,WAAW,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,SAAS,CAExD;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,SAAS,CAExD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,cAAc,CAElE"}
@@ -0,0 +1,15 @@
1
+ import { ModuleDeclaration } from 'didi';
2
+ /**
3
+ * Element factory with Context Maps defaults, plus the cropping docking so
4
+ * relationship lines dock to the context box borders. The layouter itself is
5
+ * bound in the modeling module (see there) because diagram-js' ModelingModule
6
+ * binds a default `layouter` and loads after this one. The stock
7
+ * `elementFactory` is replaced so every element gets a collision-free id
8
+ * (see CmDiagramElementFactory).
9
+ */
10
+ export declare const cmModelModule: ModuleDeclaration;
11
+ export { default as CmElementFactory } from './CmElementFactory.js';
12
+ export { default as CmDiagramElementFactory } from './CmDiagramElementFactory.js';
13
+ export { default as CmLayouter } from './CmLayouter.js';
14
+ export * from './di-types.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAK9C;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,iBAI3B,CAAC;AAEF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,cAAc,eAAe,CAAC"}