@aranzatech/diagrams-bpmn 0.2.12 → 0.2.14

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 (47) hide show
  1. package/dist/{catalog-BKdtbOQT.d.ts → catalog-CK3_4cOb.d.ts} +1 -1
  2. package/dist/{catalog-DUfPajtM.d.cts → catalog-xOMF2ifW.d.cts} +1 -1
  3. package/dist/chunk-FBTGIYZS.js +218 -0
  4. package/dist/chunk-FBTGIYZS.js.map +1 -0
  5. package/dist/{chunk-O3NWJ5H7.js → chunk-QSMP34CT.js} +38 -5
  6. package/dist/chunk-QSMP34CT.js.map +1 -0
  7. package/dist/{chunk-MZVDC6FU.js → chunk-YUE5EM3W.js} +76 -10
  8. package/dist/chunk-YUE5EM3W.js.map +1 -0
  9. package/dist/edges/index.cjs +35 -2
  10. package/dist/edges/index.cjs.map +1 -1
  11. package/dist/edges/index.js +1 -1
  12. package/dist/elements/index.cjs +217 -0
  13. package/dist/elements/index.cjs.map +1 -1
  14. package/dist/elements/index.d.cts +15 -16
  15. package/dist/elements/index.d.ts +15 -16
  16. package/dist/elements/index.js +1 -1
  17. package/dist/guards-C70uIY_O.d.cts +16 -0
  18. package/dist/guards-foB6XIfZ.d.ts +16 -0
  19. package/dist/index.cjs +109 -10
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +4 -4
  22. package/dist/index.d.ts +4 -4
  23. package/dist/index.js +3 -3
  24. package/dist/layout/index.cjs +55 -19
  25. package/dist/layout/index.cjs.map +1 -1
  26. package/dist/layout/index.d.cts +17 -11
  27. package/dist/layout/index.d.ts +17 -11
  28. package/dist/layout/index.js +55 -19
  29. package/dist/layout/index.js.map +1 -1
  30. package/dist/modeling/index.d.cts +3 -3
  31. package/dist/modeling/index.d.ts +3 -3
  32. package/dist/{types-kI1SiQB4.d.ts → types-DG5yPKld.d.ts} +1 -1
  33. package/dist/{types-44yNtMtO.d.cts → types-jIDz306Y.d.cts} +1 -1
  34. package/dist/{types-hgmLfRA9.d.cts → types-y-ZbX-ff.d.cts} +32 -1
  35. package/dist/{types-hgmLfRA9.d.ts → types-y-ZbX-ff.d.ts} +32 -1
  36. package/dist/validation/index.d.cts +2 -2
  37. package/dist/validation/index.d.ts +2 -2
  38. package/dist/xml/index.cjs +74 -8
  39. package/dist/xml/index.cjs.map +1 -1
  40. package/dist/xml/index.d.cts +3 -3
  41. package/dist/xml/index.d.ts +3 -3
  42. package/dist/xml/index.js +1 -1
  43. package/package.json +2 -2
  44. package/dist/chunk-MZVDC6FU.js.map +0 -1
  45. package/dist/chunk-O3NWJ5H7.js.map +0 -1
  46. package/dist/chunk-OZKTOILD.js +0 -3
  47. package/dist/chunk-OZKTOILD.js.map +0 -1
@@ -1,25 +1,31 @@
1
1
  import { LayoutResult, LayoutOptions } from '@aranzatech/diagrams-core/types';
2
2
  export { applyLayoutResultToDiagram } from '@aranzatech/diagrams-core/layout';
3
- import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-kI1SiQB4.js';
3
+ import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-DG5yPKld.js';
4
4
  import { BpmnDiagramState } from '../modeling/index.js';
5
5
  import '@xyflow/react';
6
- import '../types-hgmLfRA9.js';
6
+ import '../types-y-ZbX-ff.js';
7
7
  import '@aranzatech/diagrams-core';
8
8
  import '@aranzatech/diagrams-core/serialization';
9
- import '../catalog-BKdtbOQT.js';
9
+ import '../catalog-CK3_4cOb.js';
10
10
 
11
11
  /**
12
12
  * ELK-based auto-layout for BPMN diagrams.
13
13
  *
14
- * Direction policy always LEFT-TO-RIGHT to match screen anatomy:
14
+ * Spacing philosophy: fixed, generous values that scale consistently
15
+ * regardless of diagram size. "Air" between elements is not waste —
16
+ * it is what makes the flow readable to the human eye.
17
+ *
18
+ * Direction policy:
15
19
  * - Root: RIGHT — free nodes and pools flow LR on the canvas.
16
- * - Pool that contains Lanes: DOWN internally so lanes stack top-to-bottom
17
- * (standard horizontal-pool anatomy); the pool itself is still placed LR.
18
- * - Pool without lanes, Lane, SubProcess, Transaction, AdHoc: RIGHT — content
19
- * flows left-to-right inside the container.
20
- * - All edges get ORTHOGONAL routing in a single INCLUDE_CHILDREN pass so
21
- * cross-pool and cross-lane edges are routed correctly.
22
- * - Containers auto-resize to fit their children.
20
+ * - Pool with Lanes: DOWN internally so lanes stack top-to-bottom;
21
+ * the pool itself is placed LR on the canvas.
22
+ * - Lane / SubProcess / Pool-without-lanes: RIGHT — content flows LR.
23
+ * - Each container runs its own INCLUDE_CHILDREN pass (per-container
24
+ * hierarchyHandling) so cross-lane edges are routed correctly without
25
+ * the global RIGHT direction forcing Lane containers sideways.
26
+ * - Root uses INHERIT so each pool is laid out independently.
27
+ * - Post-processing equalises Lane widths within each Pool so all Lanes
28
+ * span the full Pool width.
23
29
  */
24
30
  declare function bpmnElkLayout(nodes: BpmnRFNode[], edges: BpmnRFEdge[]): Promise<{
25
31
  nodes: BpmnRFNode[];
@@ -13,20 +13,20 @@ var BPMN_CONTAINER_TYPES = /* @__PURE__ */ new Set([
13
13
  "AdHocSubProcess"
14
14
  ]);
15
15
  var CONTAINER_MIN_SIZE = {
16
- Pool: { w: 560, h: 160 },
17
- Lane: { w: 480, h: 100 },
18
- SubProcess: { w: 200, h: 120 },
19
- Transaction: { w: 200, h: 120 },
20
- EventSubProcess: { w: 200, h: 120 },
21
- AdHocSubProcess: { w: 200, h: 120 }
16
+ Pool: { w: 720, h: 200 },
17
+ Lane: { w: 600, h: 160 },
18
+ SubProcess: { w: 240, h: 140 },
19
+ Transaction: { w: 240, h: 140 },
20
+ EventSubProcess: { w: 240, h: 140 },
21
+ AdHocSubProcess: { w: 240, h: 140 }
22
22
  };
23
23
  var CONTAINER_PADDING = {
24
- Pool: "[top=20,left=30,bottom=20,right=20]",
25
- Lane: "[top=20,left=50,bottom=20,right=50]",
26
- SubProcess: "[top=20,left=30,bottom=20,right=30]",
27
- Transaction: "[top=20,left=30,bottom=20,right=30]",
28
- EventSubProcess: "[top=20,left=30,bottom=20,right=30]",
29
- AdHocSubProcess: "[top=20,left=30,bottom=20,right=30]"
24
+ Pool: "[top=30,left=60,bottom=30,right=50]",
25
+ Lane: "[top=40,left=70,bottom=40,right=50]",
26
+ SubProcess: "[top=30,left=40,bottom=30,right=40]",
27
+ Transaction: "[top=30,left=40,bottom=30,right=40]",
28
+ EventSubProcess: "[top=30,left=40,bottom=30,right=40]",
29
+ AdHocSubProcess: "[top=30,left=40,bottom=30,right=40]"
30
30
  };
31
31
  async function bpmnElkLayout(nodes, edges) {
32
32
  const poolsWithLanes = /* @__PURE__ */ new Set();
@@ -47,13 +47,26 @@ async function bpmnElkLayout(nodes, edges) {
47
47
  },
48
48
  isContainerNode: (node) => BPMN_CONTAINER_TYPES.has(node.data.elementType),
49
49
  getNodeLayoutOptions: (node) => {
50
- const type = node.data.elementType;
50
+ const bNode = node;
51
+ const type = bNode.data.elementType;
51
52
  if (!BPMN_CONTAINER_TYPES.has(type)) return void 0;
52
53
  const min = CONTAINER_MIN_SIZE[type];
53
- const dir = type === "Pool" && poolsWithLanes.has(node.id) ? "DOWN" : "RIGHT";
54
+ const isPoolWithLanes = type === "Pool" && poolsWithLanes.has(node.id);
55
+ const dir = isPoolWithLanes ? "DOWN" : "RIGHT";
54
56
  return {
55
57
  "elk.direction": dir,
56
58
  "elk.nodeSize.constraints": "MINIMUM_SIZE",
59
+ // Each container handles its own layout pass so cross-lane edges
60
+ // participate in the internal layout without the global direction
61
+ // forcing Lane containers to align sideways.
62
+ "elk.hierarchyHandling": "INCLUDE_CHILDREN",
63
+ // Lanes within a Pool share a border — zero gap between them.
64
+ // Other containers keep the tighter inner spacing.
65
+ ...isPoolWithLanes ? { "elk.spacing.nodeNode": "0", "elk.spacing.componentComponent": "0" } : {
66
+ "elk.layered.spacing.nodeNodeBetweenLayers": "100",
67
+ "elk.layered.spacing.edgeNodeBetweenLayers": "45",
68
+ "elk.spacing.nodeNode": "50"
69
+ },
57
70
  ...min ? { "elk.nodeSize.minimum": `[w=${min.w},h=${min.h}]` } : {},
58
71
  ...CONTAINER_PADDING[type] ? { "elk.padding": CONTAINER_PADDING[type] } : {}
59
72
  };
@@ -61,12 +74,15 @@ async function bpmnElkLayout(nodes, edges) {
61
74
  elk: {
62
75
  "elk.algorithm": "layered",
63
76
  "elk.direction": "RIGHT",
64
- "elk.hierarchyHandling": "INCLUDE_CHILDREN",
77
+ // INHERIT: each container handles its own INCLUDE_CHILDREN pass so
78
+ // the global RIGHT direction does not force Lane containers sideways.
79
+ "elk.hierarchyHandling": "INHERIT",
65
80
  "elk.edgeRouting": "ORTHOGONAL",
66
- "elk.layered.spacing.nodeNodeBetweenLayers": "80",
67
- "elk.layered.spacing.edgeNodeBetweenLayers": "20",
68
- "elk.spacing.nodeNode": "40",
69
- "elk.spacing.componentComponent": "60"
81
+ // Global spacing — generous values for visual breathing room.
82
+ "elk.layered.spacing.nodeNodeBetweenLayers": "120",
83
+ "elk.layered.spacing.edgeNodeBetweenLayers": "50",
84
+ "elk.spacing.nodeNode": "70",
85
+ "elk.spacing.componentComponent": "100"
70
86
  }
71
87
  }
72
88
  );
@@ -77,6 +93,26 @@ async function bpmnElkLayout(nodes, edges) {
77
93
  if (!laid) return node;
78
94
  return { ...node, position: laid.position, width: laid.width, height: laid.height };
79
95
  });
96
+ const lanesByPool = /* @__PURE__ */ new Map();
97
+ for (const node of updatedNodes) {
98
+ if (node.data.elementType === "Lane" && node.parentId) {
99
+ const arr = lanesByPool.get(node.parentId) ?? [];
100
+ arr.push(node.id);
101
+ lanesByPool.set(node.parentId, arr);
102
+ }
103
+ }
104
+ const nodeIndex = new Map(updatedNodes.map((n, i) => [n.id, i]));
105
+ for (const laneIds of lanesByPool.values()) {
106
+ const widths = laneIds.map((id) => updatedNodes[nodeIndex.get(id)]?.width ?? 0);
107
+ const maxWidth = Math.max(...widths);
108
+ if (maxWidth <= 0) continue;
109
+ for (const id of laneIds) {
110
+ const idx = nodeIndex.get(id);
111
+ if (idx !== void 0) {
112
+ updatedNodes[idx] = { ...updatedNodes[idx], width: maxWidth };
113
+ }
114
+ }
115
+ }
80
116
  const updatedEdges = edges.map((edge) => {
81
117
  const laid = edgeMap.get(edge.id);
82
118
  if (!laid) return edge;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/layout/elk.ts","../../src/layout/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { elkLayout } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode, DiagramEdge } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport type { BpmnElementType } from \"../elements/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\n\n// Container types that ELK auto-sizes based on their children.\nconst BPMN_CONTAINER_TYPES = new Set<BpmnElementType>([\n \"Pool\",\n \"Lane\",\n \"SubProcess\",\n \"Transaction\",\n \"EventSubProcess\",\n \"AdHocSubProcess\",\n]);\n\nconst CONTAINER_MIN_SIZE: Partial<Record<BpmnElementType, { w: number; h: number }>> = {\n Pool: { w: 560, h: 160 },\n Lane: { w: 480, h: 100 },\n SubProcess: { w: 200, h: 120 },\n Transaction: { w: 200, h: 120 },\n EventSubProcess: { w: 200, h: 120 },\n AdHocSubProcess: { w: 200, h: 120 },\n};\n\n// Left padding includes the pool label strip (≈30 px).\nconst CONTAINER_PADDING: Partial<Record<BpmnElementType, string>> = {\n Pool: \"[top=20,left=30,bottom=20,right=20]\",\n Lane: \"[top=20,left=50,bottom=20,right=50]\",\n SubProcess: \"[top=20,left=30,bottom=20,right=30]\",\n Transaction: \"[top=20,left=30,bottom=20,right=30]\",\n EventSubProcess: \"[top=20,left=30,bottom=20,right=30]\",\n AdHocSubProcess: \"[top=20,left=30,bottom=20,right=30]\",\n};\n\n/**\n * ELK-based auto-layout for BPMN diagrams.\n *\n * Direction policy — always LEFT-TO-RIGHT to match screen anatomy:\n * - Root: RIGHT — free nodes and pools flow LR on the canvas.\n * - Pool that contains Lanes: DOWN internally so lanes stack top-to-bottom\n * (standard horizontal-pool anatomy); the pool itself is still placed LR.\n * - Pool without lanes, Lane, SubProcess, Transaction, AdHoc: RIGHT — content\n * flows left-to-right inside the container.\n * - All edges get ORTHOGONAL routing in a single INCLUDE_CHILDREN pass so\n * cross-pool and cross-lane edges are routed correctly.\n * - Containers auto-resize to fit their children.\n */\nexport async function bpmnElkLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n): Promise<{ nodes: BpmnRFNode[]; edges: BpmnRFEdge[] }> {\n // Pools that contain at least one Lane child need DOWN internal direction so\n // the lanes stack vertically (standard horizontal BPMN pool).\n const poolsWithLanes = new Set<string>();\n for (const node of nodes) {\n if (node.data.elementType === \"Lane\" && node.parentId) {\n poolsWithLanes.add(node.parentId);\n }\n }\n\n const result = await elkLayout(\n nodes as unknown as DiagramNode[],\n edges as unknown as DiagramEdge[],\n {\n direction: \"LR\",\n getNodeSize: (node) => {\n const bNode = node as unknown as BpmnRFNode;\n if (BPMN_CONTAINER_TYPES.has(bNode.data.elementType)) return undefined;\n return getBpmnNodeSize(bNode);\n },\n isContainerNode: (node) =>\n BPMN_CONTAINER_TYPES.has((node as unknown as BpmnRFNode).data.elementType),\n getNodeLayoutOptions: (node) => {\n const type = (node as unknown as BpmnRFNode).data.elementType;\n if (!BPMN_CONTAINER_TYPES.has(type)) return undefined;\n const min = CONTAINER_MIN_SIZE[type];\n // Pool with Lanes: DOWN so lanes stack top-to-bottom inside the pool.\n // Everything else (Lane content, SubProcess, free tasks): RIGHT (LR).\n const dir = type === \"Pool\" && poolsWithLanes.has(node.id) ? \"DOWN\" : \"RIGHT\";\n return {\n \"elk.direction\": dir,\n \"elk.nodeSize.constraints\": \"MINIMUM_SIZE\",\n ...(min ? { \"elk.nodeSize.minimum\": `[w=${min.w},h=${min.h}]` } : {}),\n ...(CONTAINER_PADDING[type] ? { \"elk.padding\": CONTAINER_PADDING[type] } : {}),\n };\n },\n elk: {\n \"elk.algorithm\": \"layered\",\n \"elk.direction\": \"RIGHT\",\n \"elk.hierarchyHandling\": \"INCLUDE_CHILDREN\",\n \"elk.edgeRouting\": \"ORTHOGONAL\",\n \"elk.layered.spacing.nodeNodeBetweenLayers\": \"80\",\n \"elk.layered.spacing.edgeNodeBetweenLayers\": \"20\",\n \"elk.spacing.nodeNode\": \"40\",\n \"elk.spacing.componentComponent\": \"60\",\n },\n },\n );\n\n const nodeMap = new Map(result.nodes.map((n) => [n.id, n]));\n const edgeMap = new Map(result.edges.map((e) => [e.id, e]));\n\n const updatedNodes = nodes.map((node) => {\n const laid = nodeMap.get(node.id);\n if (!laid) return node;\n return { ...node, position: laid.position, width: laid.width, height: laid.height };\n });\n\n const updatedEdges = edges.map((edge) => {\n const laid = edgeMap.get(edge.id);\n if (!laid) return edge;\n const nextData = { ...edge.data };\n if (laid.points && laid.points.length > 0) {\n nextData.routingPoints = laid.points;\n } else {\n delete nextData.routingPoints;\n }\n return { ...edge, data: nextData };\n });\n\n return { nodes: updatedNodes, edges: updatedEdges as BpmnRFEdge[] };\n}\n","import type { DiagramEdge, LayoutOptions, LayoutResult } from \"@aranzatech/diagrams-core/types\";\nimport { dagreLayout, applyLayoutResultToDiagram } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\nimport type { BpmnDiagramState } from \"../modeling\";\n\nexport { applyLayoutResultToDiagram };\nexport { bpmnElkLayout } from \"./elk\";\n\n/**\n * Dagre layout pre-configured for BPMN diagrams.\n * Uses BPMN-specific node sizes (events 52×52, gateways 64×64, tasks 192×64, etc.)\n * instead of the generic fallback, which prevents overlaps and poor spacing.\n */\nexport async function bpmnDagreLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n options: LayoutOptions = {},\n): Promise<LayoutResult> {\n return dagreLayout(nodes as DiagramNode[], edges as DiagramEdge[], {\n ...options,\n getNodeSize: (node) => getBpmnNodeSize(node as BpmnRFNode),\n });\n}\n\n/**\n * Applies a bpmn dagre layout result back to the diagram state.\n * Convenience wrapper so callers only need one import.\n */\nexport function applyBpmnLayoutResult(\n state: BpmnDiagramState,\n result: LayoutResult,\n): BpmnDiagramState {\n return applyLayoutResultToDiagram(state, result) as BpmnDiagramState;\n}\n"]}
1
+ {"version":3,"sources":["../../src/layout/elk.ts","../../src/layout/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { elkLayout } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode, DiagramEdge } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport type { BpmnElementType } from \"../elements/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\n\n// Container types that ELK auto-sizes based on their children.\nconst BPMN_CONTAINER_TYPES = new Set<BpmnElementType>([\n \"Pool\",\n \"Lane\",\n \"SubProcess\",\n \"Transaction\",\n \"EventSubProcess\",\n \"AdHocSubProcess\",\n]);\n\nconst CONTAINER_MIN_SIZE: Partial<Record<BpmnElementType, { w: number; h: number }>> = {\n Pool: { w: 720, h: 200 },\n Lane: { w: 600, h: 160 },\n SubProcess: { w: 240, h: 140 },\n Transaction: { w: 240, h: 140 },\n EventSubProcess: { w: 240, h: 140 },\n AdHocSubProcess: { w: 240, h: 140 },\n};\n\n// Padding inside each container type.\n// Left padding for Pool/Lane accounts for the vertical label strip (~30px) + breathing room.\nconst CONTAINER_PADDING: Partial<Record<BpmnElementType, string>> = {\n Pool: \"[top=30,left=60,bottom=30,right=50]\",\n Lane: \"[top=40,left=70,bottom=40,right=50]\",\n SubProcess: \"[top=30,left=40,bottom=30,right=40]\",\n Transaction: \"[top=30,left=40,bottom=30,right=40]\",\n EventSubProcess: \"[top=30,left=40,bottom=30,right=40]\",\n AdHocSubProcess: \"[top=30,left=40,bottom=30,right=40]\",\n};\n\n/**\n * ELK-based auto-layout for BPMN diagrams.\n *\n * Spacing philosophy: fixed, generous values that scale consistently\n * regardless of diagram size. \"Air\" between elements is not waste —\n * it is what makes the flow readable to the human eye.\n *\n * Direction policy:\n * - Root: RIGHT — free nodes and pools flow LR on the canvas.\n * - Pool with Lanes: DOWN internally so lanes stack top-to-bottom;\n * the pool itself is placed LR on the canvas.\n * - Lane / SubProcess / Pool-without-lanes: RIGHT — content flows LR.\n * - Each container runs its own INCLUDE_CHILDREN pass (per-container\n * hierarchyHandling) so cross-lane edges are routed correctly without\n * the global RIGHT direction forcing Lane containers sideways.\n * - Root uses INHERIT so each pool is laid out independently.\n * - Post-processing equalises Lane widths within each Pool so all Lanes\n * span the full Pool width.\n */\nexport async function bpmnElkLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n): Promise<{ nodes: BpmnRFNode[]; edges: BpmnRFEdge[] }> {\n // Pools that directly contain at least one Lane.\n const poolsWithLanes = new Set<string>();\n for (const node of nodes) {\n if (node.data.elementType === \"Lane\" && node.parentId) {\n poolsWithLanes.add(node.parentId);\n }\n }\n\n const result = await elkLayout(\n nodes as unknown as DiagramNode[],\n edges as unknown as DiagramEdge[],\n {\n direction: \"LR\",\n getNodeSize: (node) => {\n const bNode = node as unknown as BpmnRFNode;\n if (BPMN_CONTAINER_TYPES.has(bNode.data.elementType)) return undefined;\n return getBpmnNodeSize(bNode);\n },\n isContainerNode: (node) =>\n BPMN_CONTAINER_TYPES.has((node as unknown as BpmnRFNode).data.elementType),\n getNodeLayoutOptions: (node) => {\n const bNode = node as unknown as BpmnRFNode;\n const type = bNode.data.elementType;\n if (!BPMN_CONTAINER_TYPES.has(type)) return undefined;\n\n const min = CONTAINER_MIN_SIZE[type];\n const isPoolWithLanes = type === \"Pool\" && poolsWithLanes.has(node.id);\n\n // Pool with Lanes stacks Lanes top-to-bottom (standard horizontal BPMN).\n // Everything else flows left-to-right.\n const dir = isPoolWithLanes ? \"DOWN\" : \"RIGHT\";\n\n return {\n \"elk.direction\": dir,\n \"elk.nodeSize.constraints\": \"MINIMUM_SIZE\",\n // Each container handles its own layout pass so cross-lane edges\n // participate in the internal layout without the global direction\n // forcing Lane containers to align sideways.\n \"elk.hierarchyHandling\": \"INCLUDE_CHILDREN\",\n // Lanes within a Pool share a border — zero gap between them.\n // Other containers keep the tighter inner spacing.\n ...(isPoolWithLanes\n ? { \"elk.spacing.nodeNode\": \"0\", \"elk.spacing.componentComponent\": \"0\" }\n : {\n \"elk.layered.spacing.nodeNodeBetweenLayers\": \"100\",\n \"elk.layered.spacing.edgeNodeBetweenLayers\": \"45\",\n \"elk.spacing.nodeNode\": \"50\",\n }),\n ...(min ? { \"elk.nodeSize.minimum\": `[w=${min.w},h=${min.h}]` } : {}),\n ...(CONTAINER_PADDING[type] ? { \"elk.padding\": CONTAINER_PADDING[type] } : {}),\n };\n },\n elk: {\n \"elk.algorithm\": \"layered\",\n \"elk.direction\": \"RIGHT\",\n // INHERIT: each container handles its own INCLUDE_CHILDREN pass so\n // the global RIGHT direction does not force Lane containers sideways.\n \"elk.hierarchyHandling\": \"INHERIT\",\n \"elk.edgeRouting\": \"ORTHOGONAL\",\n // Global spacing — generous values for visual breathing room.\n \"elk.layered.spacing.nodeNodeBetweenLayers\": \"120\",\n \"elk.layered.spacing.edgeNodeBetweenLayers\": \"50\",\n \"elk.spacing.nodeNode\": \"70\",\n \"elk.spacing.componentComponent\": \"100\",\n },\n },\n );\n\n const nodeMap = new Map(result.nodes.map((n) => [n.id, n]));\n const edgeMap = new Map(result.edges.map((e) => [e.id, e]));\n\n const updatedNodes = nodes.map((node) => {\n const laid = nodeMap.get(node.id);\n if (!laid) return node;\n return { ...node, position: laid.position, width: laid.width, height: laid.height };\n });\n\n // Post-processing: equalise Lane widths within each Pool so all Lanes\n // span the full Pool width regardless of their individual content width.\n const lanesByPool = new Map<string, string[]>();\n for (const node of updatedNodes) {\n if (node.data.elementType === \"Lane\" && node.parentId) {\n const arr = lanesByPool.get(node.parentId) ?? [];\n arr.push(node.id);\n lanesByPool.set(node.parentId, arr);\n }\n }\n const nodeIndex = new Map(updatedNodes.map((n, i) => [n.id, i]));\n for (const laneIds of lanesByPool.values()) {\n const widths = laneIds.map((id) => updatedNodes[nodeIndex.get(id)!]?.width ?? 0);\n const maxWidth = Math.max(...widths);\n if (maxWidth <= 0) continue;\n for (const id of laneIds) {\n const idx = nodeIndex.get(id);\n if (idx !== undefined) {\n updatedNodes[idx] = { ...updatedNodes[idx], width: maxWidth };\n }\n }\n }\n\n const updatedEdges = edges.map((edge) => {\n const laid = edgeMap.get(edge.id);\n if (!laid) return edge;\n const nextData = { ...edge.data };\n if (laid.points && laid.points.length > 0) {\n nextData.routingPoints = laid.points;\n } else {\n delete nextData.routingPoints;\n }\n return { ...edge, data: nextData };\n });\n\n return { nodes: updatedNodes, edges: updatedEdges as BpmnRFEdge[] };\n}\n","import type { DiagramEdge, LayoutOptions, LayoutResult } from \"@aranzatech/diagrams-core/types\";\nimport { dagreLayout, applyLayoutResultToDiagram } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\nimport type { BpmnDiagramState } from \"../modeling\";\n\nexport { applyLayoutResultToDiagram };\nexport { bpmnElkLayout } from \"./elk\";\n\n/**\n * Dagre layout pre-configured for BPMN diagrams.\n * Uses BPMN-specific node sizes (events 52×52, gateways 64×64, tasks 192×64, etc.)\n * instead of the generic fallback, which prevents overlaps and poor spacing.\n */\nexport async function bpmnDagreLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n options: LayoutOptions = {},\n): Promise<LayoutResult> {\n return dagreLayout(nodes as DiagramNode[], edges as DiagramEdge[], {\n ...options,\n getNodeSize: (node) => getBpmnNodeSize(node as BpmnRFNode),\n });\n}\n\n/**\n * Applies a bpmn dagre layout result back to the diagram state.\n * Convenience wrapper so callers only need one import.\n */\nexport function applyBpmnLayoutResult(\n state: BpmnDiagramState,\n result: LayoutResult,\n): BpmnDiagramState {\n return applyLayoutResultToDiagram(state, result) as BpmnDiagramState;\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import { ModelingRules, ClipboardState, DiagramSnapshot, DiagramState, DiagramEventBus, ResizeHandlePosition, DiagramCommand, ConnectionValidator, SmartGuideResult, SelectionState, LayoutCacheOptions, LayoutCache, EdgeLabelOffsetOptions, EdgeLabelLayout, CommandStackState, Viewport, LayoutFn } from '@aranzatech/diagrams-core';
2
2
  import { DiagramDocument, CreateDiagramDocumentOptions } from '@aranzatech/diagrams-core/serialization';
3
- import { c as BpmnEdgeType, b as BpmnEdgeData, f as BpmnElementType, m as BpmnNodeData } from '../types-hgmLfRA9.cjs';
4
- import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-44yNtMtO.cjs';
5
- export { g as getBpmnElementSize, i as isBpmnElementResizable } from '../catalog-DUfPajtM.cjs';
3
+ import { c as BpmnEdgeType, b as BpmnEdgeData, f as BpmnElementType, m as BpmnNodeData } from '../types-y-ZbX-ff.cjs';
4
+ import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-jIDz306Y.cjs';
5
+ export { g as getBpmnElementSize, i as isBpmnElementResizable } from '../catalog-xOMF2ifW.cjs';
6
6
  import '@xyflow/react';
7
7
 
8
8
  type BpmnDiagramState = DiagramState<BpmnRFNode, BpmnRFEdge>;
@@ -1,8 +1,8 @@
1
1
  import { ModelingRules, ClipboardState, DiagramSnapshot, DiagramState, DiagramEventBus, ResizeHandlePosition, DiagramCommand, ConnectionValidator, SmartGuideResult, SelectionState, LayoutCacheOptions, LayoutCache, EdgeLabelOffsetOptions, EdgeLabelLayout, CommandStackState, Viewport, LayoutFn } from '@aranzatech/diagrams-core';
2
2
  import { DiagramDocument, CreateDiagramDocumentOptions } from '@aranzatech/diagrams-core/serialization';
3
- import { c as BpmnEdgeType, b as BpmnEdgeData, f as BpmnElementType, m as BpmnNodeData } from '../types-hgmLfRA9.js';
4
- import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-kI1SiQB4.js';
5
- export { g as getBpmnElementSize, i as isBpmnElementResizable } from '../catalog-BKdtbOQT.js';
3
+ import { c as BpmnEdgeType, b as BpmnEdgeData, f as BpmnElementType, m as BpmnNodeData } from '../types-y-ZbX-ff.js';
4
+ import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-DG5yPKld.js';
5
+ export { g as getBpmnElementSize, i as isBpmnElementResizable } from '../catalog-CK3_4cOb.js';
6
6
  import '@xyflow/react';
7
7
 
8
8
  type BpmnDiagramState = DiagramState<BpmnRFNode, BpmnRFEdge>;
@@ -1,5 +1,5 @@
1
1
  import { Node, Edge } from '@xyflow/react';
2
- import { m as BpmnNodeData, b as BpmnEdgeData, a as BpmnDefinitionsSet } from './types-hgmLfRA9.js';
2
+ import { m as BpmnNodeData, b as BpmnEdgeData, a as BpmnDefinitionsSet } from './types-y-ZbX-ff.js';
3
3
 
4
4
  type BpmnRFNode = Node<BpmnNodeData>;
5
5
  type BpmnRFEdge = Edge<BpmnEdgeData>;
@@ -1,5 +1,5 @@
1
1
  import { Node, Edge } from '@xyflow/react';
2
- import { m as BpmnNodeData, b as BpmnEdgeData, a as BpmnDefinitionsSet } from './types-hgmLfRA9.cjs';
2
+ import { m as BpmnNodeData, b as BpmnEdgeData, a as BpmnDefinitionsSet } from './types-y-ZbX-ff.cjs';
3
3
 
4
4
  type BpmnRFNode = Node<BpmnNodeData>;
5
5
  type BpmnRFEdge = Edge<BpmnEdgeData>;
@@ -166,6 +166,8 @@ interface BpmnNodeData extends Record<string, unknown> {
166
166
  script?: string;
167
167
  /** BusinessRuleTask: id of the referenced DMN decision table. */
168
168
  decisionRef?: string;
169
+ /** BusinessRuleTask: simplified inline decision table (alternative to external decisionRef). */
170
+ inlineDecisionTable?: InlineDecisionTable;
169
171
  /** UserTask: form key resolved to a FormDefinition by name at runtime. */
170
172
  formKey?: string;
171
173
  /** UserTask: comma-separated Flowable user ids that can claim this task. */
@@ -191,6 +193,28 @@ interface BpmnNodeData extends Record<string, unknown> {
191
193
  /** MultiInstanceLoopCharacteristics: FEEL condition to stop before all instances finish. */
192
194
  loopCompletionCondition?: string;
193
195
  }
196
+ interface InlineDecisionInput {
197
+ id: string;
198
+ expression: string;
199
+ label: string;
200
+ }
201
+ interface InlineDecisionOutput {
202
+ id: string;
203
+ name: string;
204
+ label: string;
205
+ }
206
+ interface InlineDecisionRule {
207
+ id: string;
208
+ inputs: Record<string, string>;
209
+ outputs: Record<string, string>;
210
+ annotation?: string;
211
+ }
212
+ interface InlineDecisionTable {
213
+ hitPolicy: "FIRST" | "UNIQUE" | "COLLECT";
214
+ inputs: InlineDecisionInput[];
215
+ outputs: InlineDecisionOutput[];
216
+ rules: InlineDecisionRule[];
217
+ }
194
218
  interface BpmnEdgeData extends Record<string, unknown> {
195
219
  label?: string;
196
220
  edgeType: BpmnEdgeType;
@@ -206,6 +230,13 @@ interface BpmnEdgeData extends Record<string, unknown> {
206
230
  x: number;
207
231
  y: number;
208
232
  }>;
233
+ /** Manual label offset from the auto-computed midpoint (px). Set by dragging the label. */
234
+ labelOffsetX?: number;
235
+ labelOffsetY?: number;
236
+ /** MessageFlow: free-text description or JSON schema of the message payload. */
237
+ payloadSchema?: string;
238
+ /** MessageFlow: FEEL/JSONPath correlation key expression, e.g. $.orderId. */
239
+ correlationKey?: string;
209
240
  }
210
241
 
211
- export type { BpmnCategory as B, EventTrigger as E, SubProcessVariant as S, TaskMarker as T, BpmnDefinitionsSet as a, BpmnEdgeData as b, BpmnEdgeType as c, BpmnElementMeta as d, BpmnElementSize as e, BpmnElementType as f, BpmnErrorDefinition as g, BpmnEscalationDefinition as h, BpmnEventDefinition as i, BpmnEventSemantics as j, BpmnHandlePolicy as k, BpmnMessageDefinition as l, BpmnNodeData as m, BpmnOrientation as n, BpmnProcessVariable as o, BpmnSignalDefinition as p, BpmnTimerDefinition as q, BpmnTimerKind as r };
242
+ export type { BpmnCategory as B, EventTrigger as E, InlineDecisionInput as I, SubProcessVariant as S, TaskMarker as T, BpmnDefinitionsSet as a, BpmnEdgeData as b, BpmnEdgeType as c, BpmnElementMeta as d, BpmnElementSize as e, BpmnElementType as f, BpmnErrorDefinition as g, BpmnEscalationDefinition as h, BpmnEventDefinition as i, BpmnEventSemantics as j, BpmnHandlePolicy as k, BpmnMessageDefinition as l, BpmnNodeData as m, BpmnOrientation as n, BpmnProcessVariable as o, BpmnSignalDefinition as p, BpmnTimerDefinition as q, BpmnTimerKind as r, InlineDecisionOutput as s, InlineDecisionRule as t, InlineDecisionTable as u };
@@ -166,6 +166,8 @@ interface BpmnNodeData extends Record<string, unknown> {
166
166
  script?: string;
167
167
  /** BusinessRuleTask: id of the referenced DMN decision table. */
168
168
  decisionRef?: string;
169
+ /** BusinessRuleTask: simplified inline decision table (alternative to external decisionRef). */
170
+ inlineDecisionTable?: InlineDecisionTable;
169
171
  /** UserTask: form key resolved to a FormDefinition by name at runtime. */
170
172
  formKey?: string;
171
173
  /** UserTask: comma-separated Flowable user ids that can claim this task. */
@@ -191,6 +193,28 @@ interface BpmnNodeData extends Record<string, unknown> {
191
193
  /** MultiInstanceLoopCharacteristics: FEEL condition to stop before all instances finish. */
192
194
  loopCompletionCondition?: string;
193
195
  }
196
+ interface InlineDecisionInput {
197
+ id: string;
198
+ expression: string;
199
+ label: string;
200
+ }
201
+ interface InlineDecisionOutput {
202
+ id: string;
203
+ name: string;
204
+ label: string;
205
+ }
206
+ interface InlineDecisionRule {
207
+ id: string;
208
+ inputs: Record<string, string>;
209
+ outputs: Record<string, string>;
210
+ annotation?: string;
211
+ }
212
+ interface InlineDecisionTable {
213
+ hitPolicy: "FIRST" | "UNIQUE" | "COLLECT";
214
+ inputs: InlineDecisionInput[];
215
+ outputs: InlineDecisionOutput[];
216
+ rules: InlineDecisionRule[];
217
+ }
194
218
  interface BpmnEdgeData extends Record<string, unknown> {
195
219
  label?: string;
196
220
  edgeType: BpmnEdgeType;
@@ -206,6 +230,13 @@ interface BpmnEdgeData extends Record<string, unknown> {
206
230
  x: number;
207
231
  y: number;
208
232
  }>;
233
+ /** Manual label offset from the auto-computed midpoint (px). Set by dragging the label. */
234
+ labelOffsetX?: number;
235
+ labelOffsetY?: number;
236
+ /** MessageFlow: free-text description or JSON schema of the message payload. */
237
+ payloadSchema?: string;
238
+ /** MessageFlow: FEEL/JSONPath correlation key expression, e.g. $.orderId. */
239
+ correlationKey?: string;
209
240
  }
210
241
 
211
- export type { BpmnCategory as B, EventTrigger as E, SubProcessVariant as S, TaskMarker as T, BpmnDefinitionsSet as a, BpmnEdgeData as b, BpmnEdgeType as c, BpmnElementMeta as d, BpmnElementSize as e, BpmnElementType as f, BpmnErrorDefinition as g, BpmnEscalationDefinition as h, BpmnEventDefinition as i, BpmnEventSemantics as j, BpmnHandlePolicy as k, BpmnMessageDefinition as l, BpmnNodeData as m, BpmnOrientation as n, BpmnProcessVariable as o, BpmnSignalDefinition as p, BpmnTimerDefinition as q, BpmnTimerKind as r };
242
+ export type { BpmnCategory as B, EventTrigger as E, InlineDecisionInput as I, SubProcessVariant as S, TaskMarker as T, BpmnDefinitionsSet as a, BpmnEdgeData as b, BpmnEdgeType as c, BpmnElementMeta as d, BpmnElementSize as e, BpmnElementType as f, BpmnErrorDefinition as g, BpmnEscalationDefinition as h, BpmnEventDefinition as i, BpmnEventSemantics as j, BpmnHandlePolicy as k, BpmnMessageDefinition as l, BpmnNodeData as m, BpmnOrientation as n, BpmnProcessVariable as o, BpmnSignalDefinition as p, BpmnTimerDefinition as q, BpmnTimerKind as r, InlineDecisionOutput as s, InlineDecisionRule as t, InlineDecisionTable as u };
@@ -1,6 +1,6 @@
1
- import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-44yNtMtO.cjs';
1
+ import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-jIDz306Y.cjs';
2
2
  import '@xyflow/react';
3
- import '../types-hgmLfRA9.cjs';
3
+ import '../types-y-ZbX-ff.cjs';
4
4
 
5
5
  type BpmnValidationSeverity = "error" | "warning" | "info";
6
6
  interface BpmnValidationIssue {
@@ -1,6 +1,6 @@
1
- import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-kI1SiQB4.js';
1
+ import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-DG5yPKld.js';
2
2
  import '@xyflow/react';
3
- import '../types-hgmLfRA9.js';
3
+ import '../types-y-ZbX-ff.js';
4
4
 
5
5
  type BpmnValidationSeverity = "error" | "warning" | "info";
6
6
  interface BpmnValidationIssue {
@@ -32,6 +32,24 @@ var ARANZA_DESCRIPTOR = {
32
32
  { name: "skipExpression", isAttr: true, type: "String" },
33
33
  { name: "businessCalendarName", isAttr: true, type: "String" }
34
34
  ]
35
+ },
36
+ {
37
+ // BusinessRuleTask: simplified inline decision table (JSON-serialized)
38
+ name: "InlineDecision",
39
+ superClass: ["Element"],
40
+ properties: [
41
+ { name: "hitPolicy", isAttr: true, type: "String" },
42
+ { name: "tableJson", isAttr: true, type: "String" }
43
+ ]
44
+ },
45
+ {
46
+ // MessageFlow: payload schema + correlation key for executable BPMN
47
+ name: "MessageFlowConfig",
48
+ superClass: ["Element"],
49
+ properties: [
50
+ { name: "payloadSchema", isAttr: true, type: "String" },
51
+ { name: "correlationKey", isAttr: true, type: "String" }
52
+ ]
35
53
  }
36
54
  ],
37
55
  enumerations: [],
@@ -911,7 +929,20 @@ function extractAranzaExtensions(el) {
911
929
  }
912
930
  const ext = el.extensionElements;
913
931
  if (!ext) return result;
914
- const taskConfig = asElements(ext.values).find((v) => v.$type === "aranza:TaskConfig");
932
+ const extValues = asElements(ext.values);
933
+ const inlineDecision = extValues.find((v) => v.$type === "aranza:InlineDecision");
934
+ if (inlineDecision) {
935
+ const hitPolicy = asString(inlineDecision.hitPolicy) ?? "UNIQUE";
936
+ const tableJson = asString(inlineDecision.tableJson);
937
+ if (tableJson) {
938
+ try {
939
+ const parsed = JSON.parse(tableJson);
940
+ result.inlineDecisionTable = { hitPolicy, ...parsed };
941
+ } catch {
942
+ }
943
+ }
944
+ }
945
+ const taskConfig = extValues.find((v) => v.$type === "aranza:TaskConfig");
915
946
  if (!taskConfig) return result;
916
947
  const priority = asString(taskConfig.priority);
917
948
  if (priority === "critical" || priority === "high" || priority === "medium" || priority === "low") {
@@ -1069,12 +1100,26 @@ function buildEdge(el, edgeType, ctx, edges) {
1069
1100
  const condExpr = el.conditionExpression;
1070
1101
  const rawDir = asString(el.associationDirection);
1071
1102
  const associationDirection = edgeType === "association" && rawDir ? rawDir.toLowerCase() : void 0;
1103
+ let payloadSchema;
1104
+ let correlationKey;
1105
+ if (edgeType === "messageFlow") {
1106
+ const mfExt = el.extensionElements;
1107
+ if (mfExt) {
1108
+ const mfConfig = asElements(mfExt.values).find((v) => v.$type === "aranza:MessageFlowConfig");
1109
+ if (mfConfig) {
1110
+ payloadSchema = asString(mfConfig.payloadSchema) || void 0;
1111
+ correlationKey = asString(mfConfig.correlationKey) || void 0;
1112
+ }
1113
+ }
1114
+ }
1072
1115
  const data = {
1073
1116
  edgeType,
1074
1117
  ...label ? { label } : {},
1075
1118
  ...documentation ? { documentation } : {},
1076
1119
  ...condExpr?.body ? { conditionExpression: condExpr.body } : {},
1077
- ...associationDirection ? { associationDirection } : {}
1120
+ ...associationDirection ? { associationDirection } : {},
1121
+ ...payloadSchema ? { payloadSchema } : {},
1122
+ ...correlationKey ? { correlationKey } : {}
1078
1123
  };
1079
1124
  const waypoints = ctx.waypoints.get(id);
1080
1125
  if (waypoints?.length) data.routingPoints = waypoints;
@@ -1361,8 +1406,19 @@ function buildAranzaExtensionElements(moddle, node) {
1361
1406
  if (dueDate) configAttrs.dueDate = dueDate;
1362
1407
  if (skipExpression) configAttrs.skipExpression = skipExpression;
1363
1408
  if (businessCalendarName) configAttrs.businessCalendarName = businessCalendarName;
1364
- const taskConfig = moddle.create("aranza:TaskConfig", configAttrs);
1365
- return moddle.create("bpmn:ExtensionElements", { values: [taskConfig] });
1409
+ const values = [moddle.create("aranza:TaskConfig", configAttrs)];
1410
+ const inlineDecisionTable = node.data.inlineDecisionTable;
1411
+ if (inlineDecisionTable && typeof inlineDecisionTable === "object") {
1412
+ const tbl = inlineDecisionTable;
1413
+ const { hitPolicy, ...rest } = tbl;
1414
+ values.push(
1415
+ moddle.create("aranza:InlineDecision", {
1416
+ hitPolicy: hitPolicy ?? "UNIQUE",
1417
+ tableJson: JSON.stringify(rest)
1418
+ })
1419
+ );
1420
+ }
1421
+ return moddle.create("bpmn:ExtensionElements", { values });
1366
1422
  }
1367
1423
  var ARTIFACT_ELEMENT_TYPES = /* @__PURE__ */ new Set(["Annotation", "Group"]);
1368
1424
  function buildSemanticModel(moddle, nodes, edges, opts) {
@@ -1399,14 +1455,24 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
1399
1455
  }
1400
1456
  const messageFlowEdges = edges.filter((e) => e.data?.edgeType === "messageFlow");
1401
1457
  const conversationLinkEdges = edges.filter((e) => e.data?.edgeType === "conversationLink");
1402
- const messageFlows = messageFlowEdges.map(
1403
- (e) => moddle.create("bpmn:MessageFlow", {
1458
+ const messageFlows = messageFlowEdges.map((e) => {
1459
+ const ps = typeof e.data?.payloadSchema === "string" ? e.data.payloadSchema : void 0;
1460
+ const ck = typeof e.data?.correlationKey === "string" ? e.data.correlationKey : void 0;
1461
+ const mfAttrs = {
1404
1462
  id: e.id,
1405
1463
  name: e.data?.label ?? "",
1406
1464
  sourceRef: { id: e.source },
1407
1465
  targetRef: { id: e.target }
1408
- })
1409
- );
1466
+ };
1467
+ if (ps || ck) {
1468
+ const cfg = moddle.create("aranza:MessageFlowConfig", {
1469
+ ...ps ? { payloadSchema: ps } : {},
1470
+ ...ck ? { correlationKey: ck } : {}
1471
+ });
1472
+ mfAttrs.extensionElements = moddle.create("bpmn:ExtensionElements", { values: [cfg] });
1473
+ }
1474
+ return moddle.create("bpmn:MessageFlow", mfAttrs);
1475
+ });
1410
1476
  const conversationLinks = conversationLinkEdges.map(
1411
1477
  (e) => moddle.create("bpmn:ConversationLink", {
1412
1478
  id: e.id,