@aranzatech/diagrams-bpmn 0.2.14 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +34 -4
  2. package/dist/{catalog-xOMF2ifW.d.cts → catalog-DAGDhO-D.d.cts} +1 -1
  3. package/dist/{catalog-CK3_4cOb.d.ts → catalog-Q1QmKLDD.d.ts} +1 -1
  4. package/dist/{chunk-YUE5EM3W.js → chunk-334WN4JZ.js} +276 -107
  5. package/dist/chunk-334WN4JZ.js.map +1 -0
  6. package/dist/chunk-77L6O76M.js +3 -0
  7. package/dist/chunk-77L6O76M.js.map +1 -0
  8. package/dist/{chunk-QSMP34CT.js → chunk-CPFUQM6H.js} +80 -44
  9. package/dist/chunk-CPFUQM6H.js.map +1 -0
  10. package/dist/chunk-FFWJA5BV.js +163 -0
  11. package/dist/chunk-FFWJA5BV.js.map +1 -0
  12. package/dist/{chunk-FBTGIYZS.js → chunk-JEGYVEJO.js} +80 -3
  13. package/dist/{chunk-FBTGIYZS.js.map → chunk-JEGYVEJO.js.map} +1 -1
  14. package/dist/chunk-TB6V4S5N.js +104 -0
  15. package/dist/chunk-TB6V4S5N.js.map +1 -0
  16. package/dist/{chunk-IMW6RG6F.js → chunk-X54NHLBA.js} +43 -190
  17. package/dist/chunk-X54NHLBA.js.map +1 -0
  18. package/dist/{chunk-UAWLUDKC.js → chunk-YAYZW45I.js} +481 -26
  19. package/dist/chunk-YAYZW45I.js.map +1 -0
  20. package/dist/edges/index.cjs +78 -42
  21. package/dist/edges/index.cjs.map +1 -1
  22. package/dist/edges/index.js +1 -1
  23. package/dist/elements/index.cjs +78 -0
  24. package/dist/elements/index.cjs.map +1 -1
  25. package/dist/elements/index.d.cts +24 -5
  26. package/dist/elements/index.d.ts +24 -5
  27. package/dist/elements/index.js +1 -1
  28. package/dist/elk-QT7H4252.js +6 -0
  29. package/dist/elk-QT7H4252.js.map +1 -0
  30. package/dist/extensions/index.cjs +108 -0
  31. package/dist/extensions/index.cjs.map +1 -0
  32. package/dist/extensions/index.d.cts +145 -0
  33. package/dist/extensions/index.d.ts +145 -0
  34. package/dist/extensions/index.js +4 -0
  35. package/dist/extensions/index.js.map +1 -0
  36. package/dist/index.cjs +1067 -358
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +7 -5
  39. package/dist/index.d.ts +7 -5
  40. package/dist/index.js +7 -5
  41. package/dist/index.js.map +1 -1
  42. package/dist/layout/index.cjs +1396 -749
  43. package/dist/layout/index.cjs.map +1 -1
  44. package/dist/layout/index.d.cts +10 -4
  45. package/dist/layout/index.d.ts +10 -4
  46. package/dist/layout/index.js +543 -104
  47. package/dist/layout/index.js.map +1 -1
  48. package/dist/modeling/index.cjs +490 -23
  49. package/dist/modeling/index.cjs.map +1 -1
  50. package/dist/modeling/index.d.cts +81 -6
  51. package/dist/modeling/index.d.ts +81 -6
  52. package/dist/modeling/index.js +1 -1
  53. package/dist/nodes/index.cjs +42 -188
  54. package/dist/nodes/index.cjs.map +1 -1
  55. package/dist/nodes/index.d.cts +1 -1
  56. package/dist/nodes/index.d.ts +1 -1
  57. package/dist/nodes/index.js +1 -1
  58. package/dist/types-BX_o95GC.d.cts +40 -0
  59. package/dist/{types-y-ZbX-ff.d.cts → types-BYN4Zuee.d.cts} +15 -1
  60. package/dist/{types-y-ZbX-ff.d.ts → types-BYN4Zuee.d.ts} +15 -1
  61. package/dist/{types-jIDz306Y.d.cts → types-CggktCqr.d.cts} +4 -1
  62. package/dist/types-D7zel9dq.d.ts +40 -0
  63. package/dist/{types-DG5yPKld.d.ts → types-DmDODKlh.d.ts} +4 -1
  64. package/dist/validation/index.cjs +81 -125
  65. package/dist/validation/index.cjs.map +1 -1
  66. package/dist/validation/index.d.cts +22 -5
  67. package/dist/validation/index.d.ts +22 -5
  68. package/dist/validation/index.js +82 -126
  69. package/dist/validation/index.js.map +1 -1
  70. package/dist/xml/index.cjs +319 -49
  71. package/dist/xml/index.cjs.map +1 -1
  72. package/dist/xml/index.d.cts +5 -3
  73. package/dist/xml/index.d.ts +5 -3
  74. package/dist/xml/index.js +2 -1
  75. package/package.json +6 -1
  76. package/dist/chunk-IMW6RG6F.js.map +0 -1
  77. package/dist/chunk-QSMP34CT.js.map +0 -1
  78. package/dist/chunk-UAWLUDKC.js.map +0 -1
  79. package/dist/chunk-YUE5EM3W.js.map +0 -1
  80. package/dist/guards-C70uIY_O.d.cts +0 -16
  81. package/dist/guards-foB6XIfZ.d.ts +0 -16
package/dist/index.cjs CHANGED
@@ -717,6 +717,186 @@ function supportsCollapse(type) {
717
717
  function supportsMarkers(type) {
718
718
  return BPMN_ELEMENT_CATALOG[type].supportsMarkers ?? false;
719
719
  }
720
+
721
+ // src/elements/event-subtypes.ts
722
+ var EVENT_TRIGGER_ORDER = [
723
+ "none",
724
+ "message",
725
+ "timer",
726
+ "signal",
727
+ "error",
728
+ "escalation",
729
+ "conditional",
730
+ "link",
731
+ "compensation",
732
+ "cancel",
733
+ "terminate",
734
+ "multiple",
735
+ "parallelMultiple"
736
+ ];
737
+ var BASE_ALLOWED_EVENT_TRIGGERS = {
738
+ StartEvent: /* @__PURE__ */ new Set(["none", "message", "timer", "conditional", "signal", "multiple", "parallelMultiple"]),
739
+ EndEvent: /* @__PURE__ */ new Set(["none", "message", "signal", "error", "escalation", "terminate", "compensation", "cancel", "multiple"]),
740
+ IntermediateCatchEvent: /* @__PURE__ */ new Set(["none", "message", "timer", "conditional", "signal", "link", "multiple", "parallelMultiple"]),
741
+ IntermediateThrowEvent: /* @__PURE__ */ new Set(["none", "message", "signal", "link", "escalation", "compensation", "multiple"]),
742
+ BoundaryEvent: /* @__PURE__ */ new Set(["message", "timer", "conditional", "signal", "error", "escalation", "cancel", "compensation"])
743
+ };
744
+ var EVENT_SUBPROCESS_ALLOWED_START_TRIGGERS = /* @__PURE__ */ new Set([
745
+ "message",
746
+ "timer",
747
+ "escalation",
748
+ "conditional",
749
+ "error",
750
+ "compensation",
751
+ "signal",
752
+ "multiple",
753
+ "parallelMultiple"
754
+ ]);
755
+ var NON_INTERRUPTING_EVENT_SUBPROCESS_START_TRIGGERS = /* @__PURE__ */ new Set([
756
+ "message",
757
+ "timer",
758
+ "escalation",
759
+ "conditional",
760
+ "signal",
761
+ "multiple",
762
+ "parallelMultiple"
763
+ ]);
764
+ var NON_INTERRUPTING_BOUNDARY_TRIGGERS = /* @__PURE__ */ new Set([
765
+ "message",
766
+ "timer",
767
+ "conditional",
768
+ "signal",
769
+ "escalation"
770
+ ]);
771
+ function isEventSubProcessParent(parentType, parentSubProcessVariant) {
772
+ return parentType === "EventSubProcess" || parentSubProcessVariant === "event";
773
+ }
774
+ function getAllowedEventTriggers(options) {
775
+ const allowed = new Set(BASE_ALLOWED_EVENT_TRIGGERS[options.baseType]);
776
+ if (options.baseType === "StartEvent" && isEventSubProcessParent(options.parentType, options.parentSubProcessVariant)) {
777
+ for (const trigger of Array.from(allowed)) {
778
+ if (!EVENT_SUBPROCESS_ALLOWED_START_TRIGGERS.has(trigger)) {
779
+ allowed.delete(trigger);
780
+ }
781
+ }
782
+ }
783
+ if (options.baseType === "StartEvent" && options.isNonInterrupting) {
784
+ for (const trigger of Array.from(allowed)) {
785
+ if (!NON_INTERRUPTING_EVENT_SUBPROCESS_START_TRIGGERS.has(trigger)) {
786
+ allowed.delete(trigger);
787
+ }
788
+ }
789
+ }
790
+ if (options.baseType === "BoundaryEvent" && options.isNonInterrupting) {
791
+ for (const trigger of Array.from(allowed)) {
792
+ if (!NON_INTERRUPTING_BOUNDARY_TRIGGERS.has(trigger)) {
793
+ allowed.delete(trigger);
794
+ }
795
+ }
796
+ }
797
+ return EVENT_TRIGGER_ORDER.filter((trigger) => allowed.has(trigger));
798
+ }
799
+
800
+ // src/xml/aranza-descriptor.ts
801
+ var ARANZA_DESCRIPTOR = {
802
+ name: "Aranza",
803
+ uri: "http://aranzatech.io/schema/bpmn-extension/1.0",
804
+ prefix: "aranza",
805
+ xml: { tagAlias: "lowerCase" },
806
+ types: [
807
+ {
808
+ name: "TaskConfig",
809
+ superClass: ["Element"],
810
+ properties: [
811
+ { name: "priority", isAttr: true, type: "String" },
812
+ { name: "owner", isAttr: true, type: "String" },
813
+ { name: "sla", isAttr: true, type: "String" },
814
+ // Aranza connector execution config (resolved at runtime by the Flowable delegate)
815
+ { name: "implementation", isAttr: true, type: "String" },
816
+ { name: "connectorInstanceId", isAttr: true, type: "String" },
817
+ { name: "connectorId", isAttr: true, type: "String" },
818
+ { name: "connectorAction", isAttr: true, type: "String" },
819
+ { name: "connectorParamsJson", isAttr: true, type: "String" },
820
+ { name: "httpMethod", isAttr: true, type: "String" },
821
+ { name: "endpoint", isAttr: true, type: "String" },
822
+ { name: "operationRef", isAttr: true, type: "String" },
823
+ { name: "connector", isAttr: true, type: "String" },
824
+ { name: "action", isAttr: true, type: "String" },
825
+ // Flowable implementation hints stored for round-trip fidelity
826
+ { name: "flowableType", isAttr: true, type: "String" },
827
+ { name: "flowableDelegateExpression", isAttr: true, type: "String" },
828
+ // BusinessRuleTask: reference to a DMN decision table id
829
+ { name: "decisionRef", isAttr: true, type: "String" },
830
+ // UserTask: form key resolved to a FormDefinition name at runtime
831
+ { name: "formKey", isAttr: true, type: "String" },
832
+ // UserTask: Flowable task assignment — comma-separated ids
833
+ { name: "candidateUsers", isAttr: true, type: "String" },
834
+ { name: "candidateGroups", isAttr: true, type: "String" },
835
+ // UserTask: scheduling + skip expression
836
+ { name: "dueDate", isAttr: true, type: "String" },
837
+ { name: "skipExpression", isAttr: true, type: "String" },
838
+ { name: "businessCalendarName", isAttr: true, type: "String" }
839
+ ]
840
+ },
841
+ {
842
+ // BusinessRuleTask: simplified inline decision table (JSON-serialized)
843
+ name: "InlineDecision",
844
+ superClass: ["Element"],
845
+ properties: [
846
+ { name: "hitPolicy", isAttr: true, type: "String" },
847
+ { name: "tableJson", isAttr: true, type: "String" }
848
+ ]
849
+ },
850
+ {
851
+ // MessageFlow: payload schema + correlation key for executable BPMN
852
+ name: "MessageFlowConfig",
853
+ superClass: ["Element"],
854
+ properties: [
855
+ { name: "payloadSchema", isAttr: true, type: "String" },
856
+ { name: "correlationKey", isAttr: true, type: "String" }
857
+ ]
858
+ }
859
+ ],
860
+ enumerations: [],
861
+ associations: []
862
+ };
863
+
864
+ // src/extensions/types.ts
865
+ function hasText(value) {
866
+ return typeof value === "string" && value.trim().length > 0;
867
+ }
868
+ function getBpmnTaskExecutionExtensions(data) {
869
+ const result = {};
870
+ if (data.priority) result.priority = data.priority;
871
+ if (hasText(data.owner)) result.owner = data.owner;
872
+ if (hasText(data.sla)) result.sla = data.sla;
873
+ if (hasText(data.connector)) result.connector = data.connector;
874
+ if (hasText(data.action)) result.action = data.action;
875
+ if (hasText(data.flowableType)) result.flowableType = data.flowableType;
876
+ if (hasText(data.flowableDelegateExpression)) {
877
+ result.flowableDelegateExpression = data.flowableDelegateExpression;
878
+ }
879
+ if (data.serviceConfig && Object.keys(data.serviceConfig).length > 0) {
880
+ result.serviceConfig = data.serviceConfig;
881
+ }
882
+ if (hasText(data.decisionRef)) result.decisionRef = data.decisionRef;
883
+ if (data.inlineDecisionTable) result.inlineDecisionTable = data.inlineDecisionTable;
884
+ if (hasText(data.formKey)) result.formKey = data.formKey;
885
+ if (hasText(data.candidateUsers)) result.candidateUsers = data.candidateUsers;
886
+ if (hasText(data.candidateGroups)) result.candidateGroups = data.candidateGroups;
887
+ if (hasText(data.dueDate)) result.dueDate = data.dueDate;
888
+ if (hasText(data.skipExpression)) result.skipExpression = data.skipExpression;
889
+ if (hasText(data.businessCalendarName)) {
890
+ result.businessCalendarName = data.businessCalendarName;
891
+ }
892
+ return Object.keys(result).length > 0 ? result : void 0;
893
+ }
894
+ function getBpmnMessageFlowExecutionExtensions(data) {
895
+ const result = {};
896
+ if (hasText(data.payloadSchema)) result.payloadSchema = data.payloadSchema;
897
+ if (hasText(data.correlationKey)) result.correlationKey = data.correlationKey;
898
+ return Object.keys(result).length > 0 ? result : void 0;
899
+ }
720
900
  var ALL_POSITIONS = [
721
901
  react.Position.Top,
722
902
  react.Position.Right,
@@ -762,6 +942,7 @@ var BPMN_THEME = {
762
942
  fillSoft: "#f8fbff",
763
943
  fillSubtle: "#eef6ff",
764
944
  stroke: "#334155",
945
+ strokeMuted: "#64748b",
765
946
  strokeSelected: "#2563eb",
766
947
  strokeWidth: 1.5,
767
948
  strokeWidthSelected: 2.5,
@@ -1401,71 +1582,33 @@ function SubProcessNode({ data, selected }) {
1401
1582
  }
1402
1583
  );
1403
1584
  }
1404
- var HEADER_WIDTH = 30;
1405
- var HEADER_HEIGHT = 28;
1406
- function PoolNode({ data, selected }) {
1407
- const d = data;
1408
- const stroke = resolveStroke(selected, d.color?.stroke);
1409
- const sw = resolveStrokeWidth(selected);
1410
- const orientation = d.orientation ?? "horizontal";
1411
- const fill = d.color?.fill ?? "#f8fbff";
1412
- const headerFill = d.color?.fill ?? "#eaf2ff";
1413
- if (orientation === "vertical") {
1414
- return /* @__PURE__ */ jsxRuntime.jsxs(
1415
- "div",
1416
- {
1417
- style: {
1418
- width: "100%",
1419
- height: "100%",
1420
- display: "flex",
1421
- flexDirection: "column",
1422
- border: `${sw}px solid ${stroke}`,
1423
- borderRadius: 4,
1424
- boxSizing: "border-box",
1425
- background: fill,
1426
- boxShadow: resolveNodeShadow(selected),
1427
- overflow: "hidden",
1428
- fontFamily: BPMN_THEME.fontFamily,
1429
- transition: BPMN_THEME.transition
1430
- },
1431
- children: [
1432
- /* @__PURE__ */ jsxRuntime.jsx(
1433
- "div",
1434
- {
1435
- "aria-label": "pool-header",
1436
- className: "pool-drag-handle",
1437
- style: {
1438
- height: HEADER_HEIGHT,
1439
- minHeight: HEADER_HEIGHT,
1440
- borderBottom: `${sw}px solid ${stroke}`,
1441
- display: "flex",
1442
- alignItems: "center",
1443
- justifyContent: "center",
1444
- background: headerFill,
1445
- padding: "0 8px",
1446
- cursor: "grab"
1447
- },
1448
- children: /* @__PURE__ */ jsxRuntime.jsx(
1449
- "span",
1450
- {
1451
- style: {
1452
- fontSize: BPMN_THEME.fontSize,
1453
- fontWeight: 600,
1454
- color: BPMN_THEME.labelColor,
1455
- whiteSpace: "nowrap",
1456
- overflow: "hidden",
1457
- textOverflow: "ellipsis"
1458
- },
1459
- children: d.label
1460
- }
1461
- )
1462
- }
1463
- ),
1464
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, position: "relative" } })
1465
- ]
1585
+ function PoolNode({ selected }) {
1586
+ const sw = selected ? 2.5 : 2;
1587
+ const borderColor = selected ? "var(--color-accent)" : "color-mix(in srgb, var(--color-accent) 40%, transparent)";
1588
+ const bg = "color-mix(in srgb, var(--color-accent) 3%, white)";
1589
+ return /* @__PURE__ */ jsxRuntime.jsx(
1590
+ "div",
1591
+ {
1592
+ style: {
1593
+ width: "100%",
1594
+ height: "100%",
1595
+ border: `${sw}px solid ${borderColor}`,
1596
+ borderRadius: 6,
1597
+ boxSizing: "border-box",
1598
+ background: bg,
1599
+ fontFamily: BPMN_THEME.fontFamily,
1600
+ transition: "border-color 140ms ease",
1601
+ overflow: "visible"
1466
1602
  }
1467
- );
1468
- }
1603
+ }
1604
+ );
1605
+ }
1606
+ var LABEL_W = 28;
1607
+ function LaneNode({ data, selected }) {
1608
+ const d = data;
1609
+ const stroke = selected ? BPMN_THEME.strokeSelected : d.color?.stroke ?? BPMN_THEME.strokeMuted;
1610
+ const bodyFill = "#fbfdff";
1611
+ const labelFill = d.color?.fill ?? "#eef6ff";
1469
1612
  return /* @__PURE__ */ jsxRuntime.jsxs(
1470
1613
  "div",
1471
1614
  {
@@ -1473,11 +1616,11 @@ function PoolNode({ data, selected }) {
1473
1616
  width: "100%",
1474
1617
  height: "100%",
1475
1618
  display: "flex",
1476
- border: `${sw}px solid ${stroke}`,
1477
- borderRadius: 4,
1619
+ flexDirection: "row",
1620
+ border: `1px solid ${stroke}`,
1621
+ borderRadius: 3,
1478
1622
  boxSizing: "border-box",
1479
- background: fill,
1480
- boxShadow: resolveNodeShadow(selected),
1623
+ background: bodyFill,
1481
1624
  overflow: "hidden",
1482
1625
  fontFamily: BPMN_THEME.fontFamily,
1483
1626
  transition: BPMN_THEME.transition
@@ -1486,17 +1629,19 @@ function PoolNode({ data, selected }) {
1486
1629
  /* @__PURE__ */ jsxRuntime.jsx(
1487
1630
  "div",
1488
1631
  {
1489
- "aria-label": "pool-header",
1490
- className: "pool-drag-handle",
1632
+ "aria-label": "lane-header",
1633
+ className: "lane-drag-handle",
1491
1634
  style: {
1492
- width: HEADER_WIDTH,
1493
- minWidth: HEADER_WIDTH,
1494
- borderRight: `${sw}px solid ${stroke}`,
1635
+ width: LABEL_W,
1636
+ minWidth: LABEL_W,
1637
+ borderRight: `1px solid ${stroke}`,
1495
1638
  display: "flex",
1496
1639
  alignItems: "center",
1497
1640
  justifyContent: "center",
1498
- background: headerFill,
1499
- cursor: "grab"
1641
+ background: labelFill,
1642
+ cursor: "grab",
1643
+ userSelect: "none",
1644
+ flexShrink: 0
1500
1645
  },
1501
1646
  children: /* @__PURE__ */ jsxRuntime.jsx(
1502
1647
  "span",
@@ -1505,7 +1650,7 @@ function PoolNode({ data, selected }) {
1505
1650
  writingMode: "vertical-rl",
1506
1651
  transform: "rotate(180deg)",
1507
1652
  fontSize: BPMN_THEME.fontSize,
1508
- fontWeight: 600,
1653
+ fontWeight: 500,
1509
1654
  color: BPMN_THEME.labelColor,
1510
1655
  whiteSpace: "nowrap",
1511
1656
  overflow: "hidden",
@@ -1517,118 +1662,7 @@ function PoolNode({ data, selected }) {
1517
1662
  )
1518
1663
  }
1519
1664
  ),
1520
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, position: "relative" } })
1521
- ]
1522
- }
1523
- );
1524
- }
1525
- var HEADER_HEIGHT2 = 24;
1526
- var HEADER_WIDTH2 = 28;
1527
- function LaneNode({ data, selected }) {
1528
- const d = data;
1529
- const stroke = resolveStroke(selected, d.color?.stroke);
1530
- const sw = resolveStrokeWidth(selected);
1531
- const orientation = d.orientation ?? "horizontal";
1532
- const fill = d.color?.fill ?? "#fbfdff";
1533
- const headerFill = d.color?.fill ?? "#eef6ff";
1534
- if (orientation === "vertical") {
1535
- return /* @__PURE__ */ jsxRuntime.jsxs(
1536
- "div",
1537
- {
1538
- style: {
1539
- width: "100%",
1540
- height: "100%",
1541
- display: "flex",
1542
- border: `${sw}px solid ${stroke}`,
1543
- borderRadius: 2,
1544
- boxSizing: "border-box",
1545
- background: fill,
1546
- boxShadow: resolveNodeShadow(selected),
1547
- overflow: "hidden",
1548
- fontFamily: BPMN_THEME.fontFamily,
1549
- transition: BPMN_THEME.transition
1550
- },
1551
- children: [
1552
- /* @__PURE__ */ jsxRuntime.jsx(
1553
- "div",
1554
- {
1555
- "aria-label": "lane-header",
1556
- className: "lane-drag-handle",
1557
- style: {
1558
- width: HEADER_WIDTH2,
1559
- minWidth: HEADER_WIDTH2,
1560
- borderRight: `1px solid ${stroke}`,
1561
- display: "flex",
1562
- alignItems: "center",
1563
- justifyContent: "center",
1564
- background: headerFill,
1565
- padding: "6px 0",
1566
- cursor: "grab"
1567
- },
1568
- children: /* @__PURE__ */ jsxRuntime.jsx(
1569
- "span",
1570
- {
1571
- style: {
1572
- writingMode: "vertical-rl",
1573
- transform: "rotate(180deg)",
1574
- fontSize: BPMN_THEME.fontSize,
1575
- fontWeight: 500,
1576
- color: BPMN_THEME.labelColor,
1577
- whiteSpace: "nowrap",
1578
- overflow: "hidden",
1579
- textOverflow: "ellipsis",
1580
- maxHeight: "90%"
1581
- },
1582
- children: d.label
1583
- }
1584
- )
1585
- }
1586
- ),
1587
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, position: "relative" } })
1588
- ]
1589
- }
1590
- );
1591
- }
1592
- return /* @__PURE__ */ jsxRuntime.jsxs(
1593
- "div",
1594
- {
1595
- style: {
1596
- width: "100%",
1597
- height: "100%",
1598
- display: "flex",
1599
- flexDirection: "column",
1600
- border: `${sw}px solid ${stroke}`,
1601
- borderRadius: 2,
1602
- boxSizing: "border-box",
1603
- background: fill,
1604
- boxShadow: resolveNodeShadow(selected),
1605
- overflow: "hidden",
1606
- fontFamily: BPMN_THEME.fontFamily,
1607
- transition: BPMN_THEME.transition
1608
- },
1609
- children: [
1610
- /* @__PURE__ */ jsxRuntime.jsx(
1611
- "div",
1612
- {
1613
- "aria-label": "lane-header",
1614
- className: "lane-drag-handle",
1615
- style: {
1616
- height: HEADER_HEIGHT2,
1617
- minHeight: HEADER_HEIGHT2,
1618
- borderBottom: `1px solid ${stroke}`,
1619
- display: "flex",
1620
- alignItems: "center",
1621
- paddingLeft: 8,
1622
- background: headerFill,
1623
- fontSize: BPMN_THEME.fontSize,
1624
- fontWeight: 500,
1625
- color: BPMN_THEME.labelColor,
1626
- cursor: "grab"
1627
- },
1628
- children: d.label
1629
- }
1630
- ),
1631
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, position: "relative" } })
1665
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nodrag", style: { flex: 1, position: "relative" } })
1632
1666
  ]
1633
1667
  }
1634
1668
  );
@@ -2225,32 +2259,32 @@ var BPMN_NODE_TYPES = {
2225
2259
  };
2226
2260
 
2227
2261
  // src/edges/path.ts
2228
- function getPolylineMidpoint(points) {
2262
+ function getPreferredLabelAnchor(points) {
2229
2263
  if (points.length === 0) return { x: 0, y: 0 };
2230
2264
  if (points.length === 1) return points[0];
2231
- let total = 0;
2232
- const lengths = [];
2265
+ let bestIndex = 1;
2266
+ let bestLength = -1;
2233
2267
  for (let i = 1; i < points.length; i += 1) {
2234
- const dx = points[i].x - points[i - 1].x;
2235
- const dy = points[i].y - points[i - 1].y;
2236
- const length = Math.hypot(dx, dy);
2237
- lengths.push(length);
2238
- total += length;
2239
- }
2240
- const halfway = total / 2;
2241
- let traversed = 0;
2242
- for (let i = 1; i < points.length; i += 1) {
2243
- const length = lengths[i - 1];
2244
- if (traversed + length >= halfway) {
2245
- const ratio = length === 0 ? 0 : (halfway - traversed) / length;
2246
- return {
2247
- x: points[i - 1].x + (points[i].x - points[i - 1].x) * ratio,
2248
- y: points[i - 1].y + (points[i].y - points[i - 1].y) * ratio
2249
- };
2268
+ const dx2 = points[i].x - points[i - 1].x;
2269
+ const dy2 = points[i].y - points[i - 1].y;
2270
+ const length = Math.hypot(dx2, dy2);
2271
+ if (length > bestLength) {
2272
+ bestLength = length;
2273
+ bestIndex = i;
2250
2274
  }
2251
- traversed += length;
2252
2275
  }
2253
- return points[points.length - 1];
2276
+ const from = points[bestIndex - 1];
2277
+ const to = points[bestIndex];
2278
+ const midpoint = {
2279
+ x: from.x + (to.x - from.x) / 2,
2280
+ y: from.y + (to.y - from.y) / 2
2281
+ };
2282
+ const dx = to.x - from.x;
2283
+ const dy = to.y - from.y;
2284
+ if (Math.abs(dx) >= Math.abs(dy)) {
2285
+ return { x: midpoint.x, y: midpoint.y - 12 };
2286
+ }
2287
+ return { x: midpoint.x + 12, y: midpoint.y };
2254
2288
  }
2255
2289
  function getSegmentAngle(points) {
2256
2290
  if (points.length < 2) return 0;
@@ -2290,10 +2324,13 @@ function SequenceFlowEdge({
2290
2324
  const points = d?.routingPoints;
2291
2325
  const polyline = points && points.length >= 2 ? [{ x: sourceX, y: sourceY }, ...points.slice(1, -1), { x: targetX, y: targetY }] : [{ x: sourceX, y: sourceY }, { x: targetX, y: targetY }];
2292
2326
  const path = points && points.length >= 2 ? routing.pointsToSvgPath([{ x: sourceX, y: sourceY }, ...points.slice(1, -1), { x: targetX, y: targetY }]) : routing.getOrthogonalPath(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition);
2293
- const midpoint = getPolylineMidpoint(polyline);
2327
+ const labelAnchor = getPreferredLabelAnchor(polyline);
2294
2328
  const defaultMarkerPath = d?.isDefault ? getDefaultFlowMarkerPath(polyline) : null;
2295
- const labelX = midpoint.x + (d?.labelOffsetX ?? 0);
2296
- const labelY = midpoint.y + (d?.labelOffsetY ?? 0);
2329
+ const labelX = labelAnchor.x + (d?.labelOffsetX ?? 0);
2330
+ const labelY = labelAnchor.y + (d?.labelOffsetY ?? 0);
2331
+ const strokeColor = selected ? "#1a56db" : "#404040";
2332
+ const strokeWidth = selected ? 2.25 : 1.5;
2333
+ const haloWidth = selected ? 7 : 5;
2297
2334
  const { updateEdgeData, getViewport } = react.useReactFlow();
2298
2335
  const dragStartRef = react$1.useRef(null);
2299
2336
  const handleLabelPointerDown = react$1.useCallback((e) => {
@@ -2320,6 +2357,17 @@ function SequenceFlowEdge({
2320
2357
  dragStartRef.current = null;
2321
2358
  }, []);
2322
2359
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2360
+ /* @__PURE__ */ jsxRuntime.jsx(
2361
+ react.BaseEdge,
2362
+ {
2363
+ id: `${id}__halo`,
2364
+ path,
2365
+ style: {
2366
+ stroke: "rgba(255,255,255,0.92)",
2367
+ strokeWidth: haloWidth
2368
+ }
2369
+ }
2370
+ ),
2323
2371
  /* @__PURE__ */ jsxRuntime.jsx(
2324
2372
  react.BaseEdge,
2325
2373
  {
@@ -2328,8 +2376,8 @@ function SequenceFlowEdge({
2328
2376
  ...d?.conditionExpression ? { markerStart: "url(#bpmn-diamond-open)" } : {},
2329
2377
  markerEnd: markerEnd ?? "url(#bpmn-arrow)",
2330
2378
  style: {
2331
- stroke: selected ? "#1a56db" : "#404040",
2332
- strokeWidth: selected ? 2 : 1.5,
2379
+ stroke: strokeColor,
2380
+ strokeWidth,
2333
2381
  ...style ?? {}
2334
2382
  }
2335
2383
  }
@@ -2339,8 +2387,8 @@ function SequenceFlowEdge({
2339
2387
  {
2340
2388
  d: defaultMarkerPath,
2341
2389
  fill: "none",
2342
- stroke: selected ? "#1a56db" : "#404040",
2343
- strokeWidth: selected ? 2 : 1.5,
2390
+ stroke: strokeColor,
2391
+ strokeWidth,
2344
2392
  strokeLinecap: "round",
2345
2393
  "data-testid": "bpmn-default-flow-marker"
2346
2394
  }
@@ -2355,13 +2403,17 @@ function SequenceFlowEdge({
2355
2403
  position: "absolute",
2356
2404
  transform: `translate(-50%,-50%) translate(${labelX}px,${labelY}px)`,
2357
2405
  fontSize: 11,
2358
- fontFamily: "Inter, system-ui, sans-serif",
2359
- background: "rgba(255,255,255,0.85)",
2360
- padding: "1px 4px",
2361
- borderRadius: 2,
2406
+ fontFamily: '"IBM Plex Sans", Inter, system-ui, sans-serif',
2407
+ background: "rgba(255,255,255,0.96)",
2408
+ color: "#1f2937",
2409
+ padding: "2px 6px",
2410
+ borderRadius: 999,
2411
+ border: "1px solid rgba(148, 163, 184, 0.45)",
2412
+ boxShadow: "0 1px 2px rgba(15, 23, 42, 0.10)",
2362
2413
  pointerEvents: "all",
2363
2414
  cursor: "grab",
2364
- userSelect: "none"
2415
+ userSelect: "none",
2416
+ whiteSpace: "nowrap"
2365
2417
  },
2366
2418
  className: "nodrag nopan",
2367
2419
  children: label ?? d?.label
@@ -2387,8 +2439,22 @@ function MessageFlowEdge({
2387
2439
  const points = d?.routingPoints;
2388
2440
  const polyline = points && points.length >= 2 ? [{ x: sourceX, y: sourceY }, ...points.slice(1, -1), { x: targetX, y: targetY }] : [{ x: sourceX, y: sourceY }, { x: targetX, y: targetY }];
2389
2441
  const path = points && points.length >= 2 ? routing.pointsToSvgPath([{ x: sourceX, y: sourceY }, ...points.slice(1, -1), { x: targetX, y: targetY }]) : routing.getOrthogonalPath(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition);
2390
- const midpoint = getPolylineMidpoint(polyline);
2442
+ const labelAnchor = getPreferredLabelAnchor(polyline);
2443
+ const strokeColor = selected ? "#1a56db" : "#404040";
2444
+ const strokeWidth = selected ? 2.25 : 1.5;
2445
+ const haloWidth = selected ? 7 : 5;
2391
2446
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2447
+ /* @__PURE__ */ jsxRuntime.jsx(
2448
+ react.BaseEdge,
2449
+ {
2450
+ id: `${id}__halo`,
2451
+ path,
2452
+ style: {
2453
+ stroke: "rgba(255,255,255,0.92)",
2454
+ strokeWidth: haloWidth
2455
+ }
2456
+ }
2457
+ ),
2392
2458
  /* @__PURE__ */ jsxRuntime.jsx(
2393
2459
  react.BaseEdge,
2394
2460
  {
@@ -2397,8 +2463,8 @@ function MessageFlowEdge({
2397
2463
  markerStart: "url(#bpmn-circle-open)",
2398
2464
  markerEnd: markerEnd ?? "url(#bpmn-arrow-open)",
2399
2465
  style: {
2400
- stroke: selected ? "#1a56db" : "#404040",
2401
- strokeWidth: selected ? 2 : 1.5,
2466
+ stroke: strokeColor,
2467
+ strokeWidth,
2402
2468
  strokeDasharray: "6 3",
2403
2469
  ...style ?? {}
2404
2470
  }
@@ -2409,13 +2475,17 @@ function MessageFlowEdge({
2409
2475
  {
2410
2476
  style: {
2411
2477
  position: "absolute",
2412
- transform: `translate(-50%,-50%) translate(${midpoint.x}px,${midpoint.y}px)`,
2478
+ transform: `translate(-50%,-50%) translate(${labelAnchor.x}px,${labelAnchor.y}px)`,
2413
2479
  fontSize: 11,
2414
- fontFamily: "Inter, system-ui, sans-serif",
2415
- background: "rgba(255,255,255,0.85)",
2416
- padding: "1px 4px",
2417
- borderRadius: 2,
2418
- pointerEvents: "all"
2480
+ fontFamily: '"IBM Plex Sans", Inter, system-ui, sans-serif',
2481
+ background: "rgba(255,255,255,0.96)",
2482
+ color: "#1f2937",
2483
+ padding: "2px 6px",
2484
+ borderRadius: 999,
2485
+ border: "1px solid rgba(148, 163, 184, 0.45)",
2486
+ boxShadow: "0 1px 2px rgba(15, 23, 42, 0.10)",
2487
+ pointerEvents: "all",
2488
+ whiteSpace: "nowrap"
2419
2489
  },
2420
2490
  className: "nodrag nopan",
2421
2491
  children: label ?? d?.label
@@ -2525,62 +2595,6 @@ var BPMN_EDGE_TYPES = {
2525
2595
  conversationLink: ConversationLinkEdge
2526
2596
  };
2527
2597
 
2528
- // src/xml/aranza-descriptor.ts
2529
- var ARANZA_DESCRIPTOR = {
2530
- name: "Aranza",
2531
- uri: "http://aranzatech.io/schema/bpmn-extension/1.0",
2532
- prefix: "aranza",
2533
- xml: { tagAlias: "lowerCase" },
2534
- types: [
2535
- {
2536
- name: "TaskConfig",
2537
- superClass: ["Element"],
2538
- properties: [
2539
- { name: "priority", isAttr: true, type: "String" },
2540
- { name: "owner", isAttr: true, type: "String" },
2541
- { name: "sla", isAttr: true, type: "String" },
2542
- // Aranza connector execution config (resolved at runtime by the Flowable delegate)
2543
- { name: "connector", isAttr: true, type: "String" },
2544
- { name: "action", isAttr: true, type: "String" },
2545
- // Flowable implementation hints stored for round-trip fidelity
2546
- { name: "flowableType", isAttr: true, type: "String" },
2547
- { name: "flowableDelegateExpression", isAttr: true, type: "String" },
2548
- // BusinessRuleTask: reference to a DMN decision table id
2549
- { name: "decisionRef", isAttr: true, type: "String" },
2550
- // UserTask: form key resolved to a FormDefinition name at runtime
2551
- { name: "formKey", isAttr: true, type: "String" },
2552
- // UserTask: Flowable task assignment — comma-separated ids
2553
- { name: "candidateUsers", isAttr: true, type: "String" },
2554
- { name: "candidateGroups", isAttr: true, type: "String" },
2555
- // UserTask: scheduling + skip expression
2556
- { name: "dueDate", isAttr: true, type: "String" },
2557
- { name: "skipExpression", isAttr: true, type: "String" },
2558
- { name: "businessCalendarName", isAttr: true, type: "String" }
2559
- ]
2560
- },
2561
- {
2562
- // BusinessRuleTask: simplified inline decision table (JSON-serialized)
2563
- name: "InlineDecision",
2564
- superClass: ["Element"],
2565
- properties: [
2566
- { name: "hitPolicy", isAttr: true, type: "String" },
2567
- { name: "tableJson", isAttr: true, type: "String" }
2568
- ]
2569
- },
2570
- {
2571
- // MessageFlow: payload schema + correlation key for executable BPMN
2572
- name: "MessageFlowConfig",
2573
- superClass: ["Element"],
2574
- properties: [
2575
- { name: "payloadSchema", isAttr: true, type: "String" },
2576
- { name: "correlationKey", isAttr: true, type: "String" }
2577
- ]
2578
- }
2579
- ],
2580
- enumerations: [],
2581
- associations: []
2582
- };
2583
-
2584
2598
  // src/xml/mapper.ts
2585
2599
  var MODDLE_TO_ELEMENT_TYPE = {
2586
2600
  "bpmn:StartEvent": "StartEvent",
@@ -2709,6 +2723,11 @@ function asElements(v) {
2709
2723
  function asString(v) {
2710
2724
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
2711
2725
  }
2726
+ function asStringRecord(value) {
2727
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
2728
+ const entries = Object.entries(value).filter((entry) => typeof entry[1] === "string");
2729
+ return entries.length > 0 ? Object.fromEntries(entries) : void 0;
2730
+ }
2712
2731
  function extractDocumentation(el) {
2713
2732
  const [doc] = asElements(el.documentation);
2714
2733
  return asString(doc?.text);
@@ -2887,6 +2906,35 @@ function extractAranzaExtensions(el) {
2887
2906
  if (owner) result.owner = owner;
2888
2907
  const sla = asString(taskConfig.sla);
2889
2908
  if (sla) result.sla = sla;
2909
+ const serviceConfig = {};
2910
+ const implementation = asString(taskConfig.implementation);
2911
+ if (implementation === "none" || implementation === "connector" || implementation === "http" || implementation === "webService") {
2912
+ serviceConfig.implementation = implementation;
2913
+ }
2914
+ const connectorInstanceId = asString(taskConfig.connectorInstanceId);
2915
+ if (connectorInstanceId) serviceConfig.connectorInstanceId = connectorInstanceId;
2916
+ const connectorId = asString(taskConfig.connectorId);
2917
+ if (connectorId) serviceConfig.connectorId = connectorId;
2918
+ const connectorAction = asString(taskConfig.connectorAction);
2919
+ if (connectorAction) serviceConfig.connectorAction = connectorAction;
2920
+ const connectorParamsJson = asString(taskConfig.connectorParamsJson);
2921
+ if (connectorParamsJson) {
2922
+ try {
2923
+ const parsed = JSON.parse(connectorParamsJson);
2924
+ const connectorParams = asStringRecord(parsed);
2925
+ if (connectorParams) serviceConfig.connectorParams = connectorParams;
2926
+ } catch {
2927
+ }
2928
+ }
2929
+ const httpMethod = asString(taskConfig.httpMethod);
2930
+ if (httpMethod === "GET" || httpMethod === "POST" || httpMethod === "PUT" || httpMethod === "DELETE" || httpMethod === "PATCH") {
2931
+ serviceConfig.httpMethod = httpMethod;
2932
+ }
2933
+ const endpoint = asString(taskConfig.endpoint);
2934
+ if (endpoint) serviceConfig.endpoint = endpoint;
2935
+ const operationRef = asString(taskConfig.operationRef);
2936
+ if (operationRef) serviceConfig.operationRef = operationRef;
2937
+ if (Object.keys(serviceConfig).length > 0) result.serviceConfig = serviceConfig;
2890
2938
  const connector = asString(taskConfig.connector);
2891
2939
  if (connector) result.connector = connector;
2892
2940
  const action = asString(taskConfig.action);
@@ -2979,6 +3027,7 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
2979
3027
  const completionCondition = elementType === "AdHocSubProcess" ? extractCompletionCondition(el) : void 0;
2980
3028
  const loopChars = extractLoopCharacteristics(el);
2981
3029
  const dataObjectRef = elementType === "DataObjectReference" ? asString(el.dataObjectRef?.id) : void 0;
3030
+ const dataStoreRef = elementType === "DataStoreReference" ? asString(el.dataStoreRef?.id) : void 0;
2982
3031
  const data = {
2983
3032
  elementType,
2984
3033
  ...label ? { label } : {},
@@ -3000,6 +3049,7 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
3000
3049
  ...script ? { script } : {},
3001
3050
  ...completionCondition ? { completionCondition } : {},
3002
3051
  ...dataObjectRef ? { dataObjectRef } : {},
3052
+ ...dataStoreRef ? { dataStoreRef } : {},
3003
3053
  ...loopChars,
3004
3054
  ...aranzaExt
3005
3055
  };
@@ -3156,9 +3206,10 @@ async function parseBpmnXml(xml) {
3156
3206
  }
3157
3207
  }
3158
3208
  const defaultFlowById = /* @__PURE__ */ new Set();
3209
+ const defaultFlowBySourceId = /* @__PURE__ */ new Map();
3159
3210
  const nodeIds = new Set(nodes.map((node) => node.id));
3160
3211
  for (const rootEl of asElements(rootElement.rootElements)) {
3161
- collectDefaultFlows(rootEl, defaultFlowById);
3212
+ collectDefaultFlows(rootEl, defaultFlowById, defaultFlowBySourceId);
3162
3213
  }
3163
3214
  const normalizedEdges = edges.map((edge) => {
3164
3215
  if (!defaultFlowById.has(edge.id)) return edge;
@@ -3181,18 +3232,36 @@ async function parseBpmnXml(xml) {
3181
3232
  if (importedDefinitions) importedProcess.definitions = importedDefinitions;
3182
3233
  return importedProcess;
3183
3234
  })() : importedDefinitions ? { definitions: importedDefinitions } : void 0;
3235
+ const normalizedNodes = normalizeChildPositions(nodes, nodeIds).map((node) => {
3236
+ const defaultFlowId = defaultFlowBySourceId.get(node.id);
3237
+ if (!defaultFlowId) return node;
3238
+ return {
3239
+ ...node,
3240
+ data: {
3241
+ ...node.data,
3242
+ default: defaultFlowId
3243
+ }
3244
+ };
3245
+ });
3184
3246
  return {
3185
- nodes: normalizeChildPositions(nodes, nodeIds),
3247
+ nodes: normalizedNodes,
3186
3248
  edges: normalizedEdges,
3187
3249
  warnings,
3188
3250
  ...process ? { process } : {}
3189
3251
  };
3190
3252
  }
3191
- function collectDefaultFlows(el, defaultFlowById) {
3253
+ function collectDefaultFlows(el, defaultFlowById, defaultFlowBySourceId) {
3192
3254
  const defaultRef = el.default;
3193
- if (defaultRef?.id) defaultFlowById.add(defaultRef.id);
3194
- for (const child of asElements(el.rootElements)) collectDefaultFlows(child, defaultFlowById);
3195
- for (const child of asElements(el.flowElements)) collectDefaultFlows(child, defaultFlowById);
3255
+ if (defaultRef?.id) {
3256
+ defaultFlowById.add(defaultRef.id);
3257
+ if (el.id) defaultFlowBySourceId.set(el.id, defaultRef.id);
3258
+ }
3259
+ for (const child of asElements(el.rootElements)) {
3260
+ collectDefaultFlows(child, defaultFlowById, defaultFlowBySourceId);
3261
+ }
3262
+ for (const child of asElements(el.flowElements)) {
3263
+ collectDefaultFlows(child, defaultFlowById, defaultFlowBySourceId);
3264
+ }
3196
3265
  }
3197
3266
  function normalizeChildPositions(nodes, nodeIds) {
3198
3267
  const absoluteById = new Map(nodes.map((node) => [node.id, node.position]));
@@ -3253,6 +3322,12 @@ function parseVariableType2(type) {
3253
3322
  return "xsd:string";
3254
3323
  }
3255
3324
  }
3325
+ function escapeXml(text) {
3326
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
3327
+ }
3328
+ function escapeRegex(text) {
3329
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3330
+ }
3256
3331
  function buildGlobalDefinitions(moddle, definitionsSet) {
3257
3332
  if (!definitionsSet) return [];
3258
3333
  const rootElements = [];
@@ -3278,6 +3353,33 @@ function buildGlobalDefinitions(moddle, definitionsSet) {
3278
3353
  }
3279
3354
  return rootElements;
3280
3355
  }
3356
+ function collectReferencedDataStoreIds(nodes) {
3357
+ const ids = /* @__PURE__ */ new Set();
3358
+ for (const node of nodes) {
3359
+ if (node.data.elementType !== "DataStoreReference") continue;
3360
+ const explicitRef = typeof node.data.dataStoreRef === "string" ? node.data.dataStoreRef : `DataStore_${node.id}`;
3361
+ ids.add(explicitRef);
3362
+ }
3363
+ return ids;
3364
+ }
3365
+ function buildGlobalDataStores(moddle, nodes) {
3366
+ const referencedIds = collectReferencedDataStoreIds(nodes);
3367
+ if (referencedIds.size === 0) return [];
3368
+ const byId = new Map(nodes.map((node) => [node.id, node]));
3369
+ const rootElements = [];
3370
+ for (const id of referencedIds) {
3371
+ const existing = byId.get(id);
3372
+ if (existing?.data.elementType === "DataStore") {
3373
+ rootElements.push(moddle.create("bpmn:DataStore", {
3374
+ id,
3375
+ name: existing.data.label ?? ""
3376
+ }));
3377
+ continue;
3378
+ }
3379
+ rootElements.push(moddle.create("bpmn:DataStore", { id }));
3380
+ }
3381
+ return rootElements;
3382
+ }
3281
3383
  function buildItemDefinitions(moddle, variables) {
3282
3384
  return (variables ?? []).map(
3283
3385
  (variable) => moddle.create("bpmn:ItemDefinition", {
@@ -3311,38 +3413,41 @@ function buildEventDefinitions(moddle, node, eventDefinition) {
3311
3413
  return [moddle.create(defType, attrs)];
3312
3414
  }
3313
3415
  function buildAranzaExtensionElements(moddle, node) {
3314
- const { priority, owner, sla } = node.data;
3315
- const connector = typeof node.data.connector === "string" ? node.data.connector : void 0;
3316
- const action = typeof node.data.action === "string" ? node.data.action : void 0;
3317
- const flowableType = typeof node.data.flowableType === "string" ? node.data.flowableType : void 0;
3318
- const flowableDelegateExpression = typeof node.data.flowableDelegateExpression === "string" ? node.data.flowableDelegateExpression : void 0;
3319
- const decisionRef = typeof node.data.decisionRef === "string" ? node.data.decisionRef : void 0;
3320
- const formKey = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
3321
- const candidateUsers = typeof node.data.candidateUsers === "string" ? node.data.candidateUsers : void 0;
3322
- const candidateGroups = typeof node.data.candidateGroups === "string" ? node.data.candidateGroups : void 0;
3323
- const dueDate = typeof node.data.dueDate === "string" ? node.data.dueDate : void 0;
3324
- const skipExpression = typeof node.data.skipExpression === "string" ? node.data.skipExpression : void 0;
3325
- const businessCalendarName = typeof node.data.businessCalendarName === "string" ? node.data.businessCalendarName : void 0;
3326
- if (!priority && !owner && !sla && !connector && !action && !flowableType && !flowableDelegateExpression && !decisionRef && !formKey && !candidateUsers && !candidateGroups && !dueDate && !skipExpression && !businessCalendarName) {
3416
+ const ext = getBpmnTaskExecutionExtensions(node.data);
3417
+ if (!ext) {
3327
3418
  return null;
3328
3419
  }
3329
3420
  const configAttrs = {};
3330
- if (priority) configAttrs.priority = priority;
3331
- if (owner) configAttrs.owner = owner;
3332
- if (sla) configAttrs.sla = sla;
3333
- if (connector) configAttrs.connector = connector;
3334
- if (action) configAttrs.action = action;
3335
- if (flowableType) configAttrs.flowableType = flowableType;
3336
- if (flowableDelegateExpression) configAttrs.flowableDelegateExpression = flowableDelegateExpression;
3337
- if (decisionRef) configAttrs.decisionRef = decisionRef;
3338
- if (formKey) configAttrs.formKey = formKey;
3339
- if (candidateUsers) configAttrs.candidateUsers = candidateUsers;
3340
- if (candidateGroups) configAttrs.candidateGroups = candidateGroups;
3341
- if (dueDate) configAttrs.dueDate = dueDate;
3342
- if (skipExpression) configAttrs.skipExpression = skipExpression;
3343
- if (businessCalendarName) configAttrs.businessCalendarName = businessCalendarName;
3421
+ if (ext.priority) configAttrs.priority = ext.priority;
3422
+ if (ext.owner) configAttrs.owner = ext.owner;
3423
+ if (ext.sla) configAttrs.sla = ext.sla;
3424
+ if (ext.serviceConfig?.implementation) configAttrs.implementation = ext.serviceConfig.implementation;
3425
+ if (ext.serviceConfig?.connectorInstanceId) {
3426
+ configAttrs.connectorInstanceId = ext.serviceConfig.connectorInstanceId;
3427
+ }
3428
+ if (ext.serviceConfig?.connectorId) configAttrs.connectorId = ext.serviceConfig.connectorId;
3429
+ if (ext.serviceConfig?.connectorAction) {
3430
+ configAttrs.connectorAction = ext.serviceConfig.connectorAction;
3431
+ }
3432
+ if (ext.serviceConfig?.connectorParams && Object.keys(ext.serviceConfig.connectorParams).length > 0) {
3433
+ configAttrs.connectorParamsJson = JSON.stringify(ext.serviceConfig.connectorParams);
3434
+ }
3435
+ if (ext.serviceConfig?.httpMethod) configAttrs.httpMethod = ext.serviceConfig.httpMethod;
3436
+ if (ext.serviceConfig?.endpoint) configAttrs.endpoint = ext.serviceConfig.endpoint;
3437
+ if (ext.serviceConfig?.operationRef) configAttrs.operationRef = ext.serviceConfig.operationRef;
3438
+ if (ext.connector) configAttrs.connector = ext.connector;
3439
+ if (ext.action) configAttrs.action = ext.action;
3440
+ if (ext.flowableType) configAttrs.flowableType = ext.flowableType;
3441
+ if (ext.flowableDelegateExpression) configAttrs.flowableDelegateExpression = ext.flowableDelegateExpression;
3442
+ if (ext.decisionRef) configAttrs.decisionRef = ext.decisionRef;
3443
+ if (ext.formKey) configAttrs.formKey = ext.formKey;
3444
+ if (ext.candidateUsers) configAttrs.candidateUsers = ext.candidateUsers;
3445
+ if (ext.candidateGroups) configAttrs.candidateGroups = ext.candidateGroups;
3446
+ if (ext.dueDate) configAttrs.dueDate = ext.dueDate;
3447
+ if (ext.skipExpression) configAttrs.skipExpression = ext.skipExpression;
3448
+ if (ext.businessCalendarName) configAttrs.businessCalendarName = ext.businessCalendarName;
3344
3449
  const values = [moddle.create("aranza:TaskConfig", configAttrs)];
3345
- const inlineDecisionTable = node.data.inlineDecisionTable;
3450
+ const inlineDecisionTable = ext.inlineDecisionTable;
3346
3451
  if (inlineDecisionTable && typeof inlineDecisionTable === "object") {
3347
3452
  const tbl = inlineDecisionTable;
3348
3453
  const { hitPolicy, ...rest } = tbl;
@@ -3362,13 +3467,15 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3362
3467
  const poolNodes = asNodes(nodes, ["Pool"]);
3363
3468
  const laneNodes = asNodes(nodes, ["Lane"]);
3364
3469
  const isCollaboration = poolNodes.length > 0;
3470
+ const referencedDataStoreIds = collectReferencedDataStoreIds(nodes);
3365
3471
  const definitions = moddle.create("bpmn:Definitions", {
3366
3472
  id: defId,
3367
3473
  targetNamespace: "http://bpmn.io/schema/bpmn",
3368
3474
  ...defName ? { name: defName } : {}
3369
3475
  });
3370
3476
  const rootElements = [
3371
- ...buildGlobalDefinitions(moddle, opts.process?.definitions)
3477
+ ...buildGlobalDefinitions(moddle, opts.process?.definitions),
3478
+ ...buildGlobalDataStores(moddle, nodes)
3372
3479
  ];
3373
3480
  const itemDefinitions = buildItemDefinitions(moddle, opts.process?.definitions?.variables);
3374
3481
  if (itemDefinitions.length > 0) {
@@ -3379,7 +3486,7 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3379
3486
  const processes = [];
3380
3487
  for (const pool of poolNodes) {
3381
3488
  const processId = `Process_${pool.id}`;
3382
- const process = buildProcess(moddle, nodes, edges, pool.id, laneNodes, processId, opts);
3489
+ const process = buildProcess(moddle, nodes, edges, pool.id, laneNodes, processId, opts, referencedDataStoreIds);
3383
3490
  processes.push(process);
3384
3491
  const participant = moddle.create("bpmn:Participant", {
3385
3492
  id: pool.id,
@@ -3391,18 +3498,17 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3391
3498
  const messageFlowEdges = edges.filter((e) => e.data?.edgeType === "messageFlow");
3392
3499
  const conversationLinkEdges = edges.filter((e) => e.data?.edgeType === "conversationLink");
3393
3500
  const messageFlows = messageFlowEdges.map((e) => {
3394
- const ps = typeof e.data?.payloadSchema === "string" ? e.data.payloadSchema : void 0;
3395
- const ck = typeof e.data?.correlationKey === "string" ? e.data.correlationKey : void 0;
3501
+ const ext = e.data ? getBpmnMessageFlowExecutionExtensions(e.data) : void 0;
3396
3502
  const mfAttrs = {
3397
3503
  id: e.id,
3398
3504
  name: e.data?.label ?? "",
3399
3505
  sourceRef: { id: e.source },
3400
3506
  targetRef: { id: e.target }
3401
3507
  };
3402
- if (ps || ck) {
3508
+ if (ext?.payloadSchema || ext?.correlationKey) {
3403
3509
  const cfg = moddle.create("aranza:MessageFlowConfig", {
3404
- ...ps ? { payloadSchema: ps } : {},
3405
- ...ck ? { correlationKey: ck } : {}
3510
+ ...ext.payloadSchema ? { payloadSchema: ext.payloadSchema } : {},
3511
+ ...ext.correlationKey ? { correlationKey: ext.correlationKey } : {}
3406
3512
  });
3407
3513
  mfAttrs.extensionElements = moddle.create("bpmn:ExtensionElements", { values: [cfg] });
3408
3514
  }
@@ -3430,14 +3536,15 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3430
3536
  void 0,
3431
3537
  laneNodes,
3432
3538
  opts.process?.processId ?? "Process_1",
3433
- opts
3539
+ opts,
3540
+ referencedDataStoreIds
3434
3541
  );
3435
3542
  rootElements.push(process);
3436
3543
  }
3437
3544
  definitions.rootElements = rootElements;
3438
3545
  return definitions;
3439
3546
  }
3440
- function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId, opts) {
3547
+ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId, opts, referencedDataStoreIds) {
3441
3548
  const subProcessIds = new Set(
3442
3549
  allNodes.filter(
3443
3550
  (n) => n.data.elementType === "SubProcess" || n.data.elementType === "Transaction" || n.data.elementType === "EventSubProcess" || n.data.elementType === "AdHocSubProcess"
@@ -3459,7 +3566,7 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
3459
3566
  }
3460
3567
  return false;
3461
3568
  };
3462
- const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
3569
+ const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n)).filter((n) => !(n.data.elementType === "DataStore" && referencedDataStoreIds.has(n.id)));
3463
3570
  const myLanes = laneNodes.filter((l) => poolId ? l.parentId === poolId : true);
3464
3571
  const presentDataObjectIds = new Set(
3465
3572
  myNodes.filter((n) => n.data.elementType === "DataObject").map((n) => n.id)
@@ -3503,10 +3610,18 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
3503
3610
  const elementById = new Map(
3504
3611
  flowElements.filter((element) => typeof element.id === "string").map((element) => [element.id, element])
3505
3612
  );
3613
+ const defaultEdgeBySource = /* @__PURE__ */ new Map();
3614
+ for (const node of myNodes) {
3615
+ const defaultFlowId = typeof node.data.default === "string" ? node.data.default : void 0;
3616
+ if (defaultFlowId) defaultEdgeBySource.set(node.id, defaultFlowId);
3617
+ }
3506
3618
  for (const edge of myEdges) {
3507
- if (!edge.data?.isDefault) continue;
3508
- const sourceElement = elementById.get(edge.source);
3509
- const edgeElement = elementById.get(edge.id);
3619
+ if (!edge.data?.isDefault || defaultEdgeBySource.has(edge.source)) continue;
3620
+ defaultEdgeBySource.set(edge.source, edge.id);
3621
+ }
3622
+ for (const [sourceId, edgeId] of defaultEdgeBySource) {
3623
+ const sourceElement = elementById.get(sourceId);
3624
+ const edgeElement = elementById.get(edgeId);
3510
3625
  if (sourceElement && edgeElement) {
3511
3626
  sourceElement.default = edgeElement;
3512
3627
  }
@@ -3573,6 +3688,10 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3573
3688
  const refId = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : `DataObject_${node.id}`;
3574
3689
  attrs.dataObjectRef = { id: refId };
3575
3690
  }
3691
+ if (elementType === "DataStoreReference") {
3692
+ const refId = typeof node.data.dataStoreRef === "string" ? node.data.dataStoreRef : `DataStore_${node.id}`;
3693
+ attrs.dataStoreRef = { id: refId };
3694
+ }
3576
3695
  if (elementType === "ScriptTask") {
3577
3696
  const scriptFormat = typeof node.data.scriptFormat === "string" ? node.data.scriptFormat : void 0;
3578
3697
  const script = typeof node.data.script === "string" ? node.data.script : void 0;
@@ -3634,7 +3753,8 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3634
3753
  return element;
3635
3754
  }
3636
3755
  function buildNestedFlowElements(moddle, parent, allNodes, allEdges) {
3637
- const childNodes = allNodes.filter((node) => node.parentId === parent.id);
3756
+ const referencedDataStoreIds = collectReferencedDataStoreIds(allNodes);
3757
+ const childNodes = allNodes.filter((node) => node.parentId === parent.id).filter((node) => !(node.data.elementType === "DataStore" && referencedDataStoreIds.has(node.id)));
3638
3758
  const childNodeIds = new Set(childNodes.map((node) => node.id));
3639
3759
  const flowElements = [];
3640
3760
  const artifacts = [];
@@ -3788,6 +3908,124 @@ function buildAbsolutePositionMap(nodes) {
3788
3908
  for (const node of nodes) resolve(node);
3789
3909
  return absoluteById;
3790
3910
  }
3911
+ function getServiceTaskConfig(node, opts) {
3912
+ const override = opts.flowable?.serviceTaskConfigs?.[node.id];
3913
+ if (override) return override;
3914
+ const config = node.data.serviceConfig;
3915
+ return config && typeof config === "object" ? config : void 0;
3916
+ }
3917
+ function injectFlowableNamespace(xml) {
3918
+ if (xml.includes("xmlns:flowable=")) return xml;
3919
+ return xml.replace(
3920
+ "<bpmn:definitions",
3921
+ '<bpmn:definitions xmlns:flowable="http://flowable.org/bpmn"'
3922
+ );
3923
+ }
3924
+ function ensureOpeningTagAttribute(openTag, name, value) {
3925
+ if (new RegExp(`\\b${escapeRegex(name)}=`).test(openTag)) return openTag;
3926
+ return openTag.replace(/>$/, ` ${name}="${escapeXml(value)}">`);
3927
+ }
3928
+ function injectFlowableFieldsIntoElement(xml, elementTagName, nodeId, fieldsXml, flowableType) {
3929
+ const idPattern = escapeRegex(nodeId);
3930
+ const selfClosingPattern = new RegExp(
3931
+ `<bpmn:${elementTagName}\\b[^>]*?\\bid="${idPattern}"[^>]*/>`,
3932
+ "s"
3933
+ );
3934
+ const blockPattern = new RegExp(
3935
+ `<bpmn:${elementTagName}\\b[^>]*?\\bid="${idPattern}"[^>]*>[\\s\\S]*?<\\/bpmn:${elementTagName}>`,
3936
+ "s"
3937
+ );
3938
+ if (selfClosingPattern.test(xml)) {
3939
+ return xml.replace(selfClosingPattern, (match) => {
3940
+ const openTag = ensureOpeningTagAttribute(match.replace(/\/>$/, ">"), "flowable:type", flowableType);
3941
+ return `${openTag}
3942
+ <bpmn:extensionElements>
3943
+ ${fieldsXml}
3944
+ </bpmn:extensionElements>
3945
+ </bpmn:${elementTagName}>`;
3946
+ });
3947
+ }
3948
+ return xml.replace(blockPattern, (block) => {
3949
+ const openTagMatch = block.match(new RegExp(`^<bpmn:${elementTagName}\\b[^>]*>`, "s"));
3950
+ if (!openTagMatch) return block;
3951
+ const openTag = ensureOpeningTagAttribute(openTagMatch[0], "flowable:type", flowableType);
3952
+ let nextBlock = openTag + block.slice(openTagMatch[0].length);
3953
+ if (nextBlock.includes("<bpmn:extensionElements>")) {
3954
+ return nextBlock.replace(
3955
+ /<bpmn:extensionElements>([\s\S]*?)<\/bpmn:extensionElements>/,
3956
+ (_match, inner) => `<bpmn:extensionElements>${inner.trimEnd()}
3957
+ ${fieldsXml}
3958
+ </bpmn:extensionElements>`
3959
+ );
3960
+ }
3961
+ return nextBlock.replace(
3962
+ openTag,
3963
+ `${openTag}
3964
+ <bpmn:extensionElements>
3965
+ ${fieldsXml}
3966
+ </bpmn:extensionElements>`
3967
+ );
3968
+ });
3969
+ }
3970
+ function injectFlowableConnectorServiceTasks(xml, nodes, opts) {
3971
+ let result = xml;
3972
+ const backendUrlTemplate = opts.flowable?.backendUrlTemplate ?? "%%ARANZAFLOWS_BACKEND_URL%%";
3973
+ const responseVariableName = opts.flowable?.connectorResponseVariableName ?? "connectorResult";
3974
+ for (const node of nodes) {
3975
+ if (node.data.elementType !== "ServiceTask") continue;
3976
+ const cfg = getServiceTaskConfig(node, opts);
3977
+ if (cfg?.implementation !== "connector" || !cfg.connectorInstanceId || !cfg.connectorAction) {
3978
+ continue;
3979
+ }
3980
+ result = injectFlowableNamespace(result);
3981
+ const bodyObj = {
3982
+ action: cfg.connectorAction,
3983
+ params: cfg.connectorParams ?? {}
3984
+ };
3985
+ const url = `${backendUrlTemplate}/api/v1/integrations/${encodeURIComponent(cfg.connectorInstanceId)}/execute-internal`;
3986
+ const fieldsXml = [
3987
+ ' <flowable:field name="requestMethod"><flowable:string>POST</flowable:string></flowable:field>',
3988
+ ` <flowable:field name="requestUrl"><flowable:string>${escapeXml(url)}</flowable:string></flowable:field>`,
3989
+ ' <flowable:field name="requestHeaders"><flowable:string>Content-Type: application/json</flowable:string></flowable:field>',
3990
+ ` <flowable:field name="requestBody"><flowable:expression>${escapeXml(JSON.stringify(bodyObj))}</flowable:expression></flowable:field>`,
3991
+ ` <flowable:field name="responseVariableName"><flowable:string>${escapeXml(responseVariableName)}</flowable:string></flowable:field>`,
3992
+ ' <flowable:field name="saveResponseParameters"><flowable:string>false</flowable:string></flowable:field>'
3993
+ ].join("\n");
3994
+ result = injectFlowableFieldsIntoElement(result, "serviceTask", node.id, fieldsXml, "http");
3995
+ }
3996
+ return result;
3997
+ }
3998
+ function injectFlowableDecisionTasks(xml, nodes, opts) {
3999
+ let result = xml;
4000
+ const variables = opts.process?.definitions?.variables ?? [];
4001
+ const backendUrlTemplate = opts.flowable?.backendUrlTemplate ?? "%%ARANZAFLOWS_BACKEND_URL%%";
4002
+ const responseVariableName = opts.flowable?.decisionResponseVariableName ?? "decisionResult";
4003
+ for (const node of nodes) {
4004
+ if (node.data.elementType !== "BusinessRuleTask") continue;
4005
+ const decisionRef = typeof node.data.decisionRef === "string" ? node.data.decisionRef : void 0;
4006
+ if (!decisionRef) continue;
4007
+ result = injectFlowableNamespace(result);
4008
+ const url = `${backendUrlTemplate}/api/v1/decisions/${encodeURIComponent(decisionRef)}/evaluate-internal`;
4009
+ const bodyField = variables.length > 0 ? `<flowable:expression>${escapeXml(
4010
+ `{${variables.map((variable) => `"${variable.name}": \${${variable.name}}`).join(", ")}}`
4011
+ )}</flowable:expression>` : "<flowable:string>{}</flowable:string>";
4012
+ const fieldsXml = [
4013
+ ' <flowable:field name="requestMethod"><flowable:string>POST</flowable:string></flowable:field>',
4014
+ ` <flowable:field name="requestUrl"><flowable:string>${escapeXml(url)}</flowable:string></flowable:field>`,
4015
+ ' <flowable:field name="requestHeaders"><flowable:string>Content-Type: application/json</flowable:string></flowable:field>',
4016
+ ` <flowable:field name="requestBody">${bodyField}</flowable:field>`,
4017
+ ` <flowable:field name="responseVariableName"><flowable:string>${escapeXml(responseVariableName)}</flowable:string></flowable:field>`,
4018
+ ' <flowable:field name="saveResponseParameters"><flowable:string>false</flowable:string></flowable:field>'
4019
+ ].join("\n");
4020
+ result = injectFlowableFieldsIntoElement(result, "businessRuleTask", node.id, fieldsXml, "http");
4021
+ }
4022
+ return result;
4023
+ }
4024
+ function applyFlowableExportEnrichment(xml, nodes, opts) {
4025
+ if (!opts.flowable?.enabled) return xml;
4026
+ const withServiceTasks = injectFlowableConnectorServiceTasks(xml, nodes, opts);
4027
+ return injectFlowableDecisionTasks(withServiceTasks, nodes, opts);
4028
+ }
3791
4029
  async function serializeBpmnXml(nodes, edges, opts = {}) {
3792
4030
  const { BpmnModdle } = await import('bpmn-moddle');
3793
4031
  const moddle = new BpmnModdle({ aranza: ARANZA_DESCRIPTOR });
@@ -3796,7 +4034,7 @@ async function serializeBpmnXml(nodes, edges, opts = {}) {
3796
4034
  const { xml } = await moddle.toXML(definitions, {
3797
4035
  format: opts.format ?? true
3798
4036
  });
3799
- return xml;
4037
+ return applyFlowableExportEnrichment(xml, nodes, opts);
3800
4038
  }
3801
4039
 
3802
4040
  // src/simulation/evaluator.ts
@@ -4418,7 +4656,9 @@ function createBpmnNode(options) {
4418
4656
  height: options.height ?? size.height,
4419
4657
  zIndex: getBpmnNodeZIndex(options.elementType),
4420
4658
  ...options.parentId ? { parentId: options.parentId } : {},
4421
- ...options.elementType === "Lane" && options.parentId ? { extent: "parent" } : {},
4659
+ // extent:"parent" is intentionally omitted for Lane it blocks resize beyond
4660
+ // the Pool boundary before the Pool/Lane coupling can expand the Pool.
4661
+ // Lane containment during drag is handled programmatically in handleNodeDragStop.
4422
4662
  ...dragHandle ? { dragHandle } : {}
4423
4663
  };
4424
4664
  }
@@ -4435,12 +4675,24 @@ function withBpmnNodeZIndexes(nodes) {
4435
4675
  });
4436
4676
  }
4437
4677
  var BPMN_POOL_LANE_LAYOUT = {
4438
- poolHeaderSize: 30,
4439
- laneHeaderSize: 24,
4678
+ // Pool inner padding on all sides (no left label strip).
4679
+ // 8px = pool border (2px) + 6px visible gap.
4680
+ poolPad: 8,
4681
+ /** @deprecated use poolPad */
4682
+ poolHeaderSize: 8,
4683
+ // Lane left label strip (vertical text).
4684
+ laneHeaderSize: 28,
4440
4685
  laneGap: 0,
4441
4686
  verticalPoolHeaderSize: 28,
4442
4687
  minLaneSize: 96
4443
4688
  };
4689
+ var BPMN_POOL_LANE_STACK_LAYOUT = {
4690
+ poolInnerPad: 8,
4691
+ laneGap: 8,
4692
+ minLaneWidth: 240,
4693
+ minLaneHeight: 80,
4694
+ defaultLaneHeight: 120
4695
+ };
4444
4696
  function getBpmnDragHandleSelector(elementType) {
4445
4697
  if (elementType === "Pool") return ".pool-drag-handle";
4446
4698
  if (elementType === "Lane") return ".lane-drag-handle";
@@ -4511,7 +4763,9 @@ function inferBpmnEdgeType(state, sourceId, targetId) {
4511
4763
  if (source.data.elementType === "Conversation" || source.data.elementType === "SubConversation" || source.data.elementType === "CallConversation" || target.data.elementType === "Conversation" || target.data.elementType === "SubConversation" || target.data.elementType === "CallConversation") {
4512
4764
  return "conversationLink";
4513
4765
  }
4514
- if (source.parentId && target.parentId && source.parentId !== target.parentId) {
4766
+ const sourcePoolId = getAncestorContainerId(state, source, "Pool");
4767
+ const targetPoolId = getAncestorContainerId(state, target, "Pool");
4768
+ if (sourcePoolId && targetPoolId && sourcePoolId !== targetPoolId) {
4515
4769
  return "messageFlow";
4516
4770
  }
4517
4771
  return "sequenceFlow";
@@ -4560,6 +4814,67 @@ function getBpmnPoolLanes(state, poolId) {
4560
4814
  (node) => node.data.elementType === "Lane"
4561
4815
  );
4562
4816
  }
4817
+ function getBpmnNodeBounds(state, node) {
4818
+ const position = getBpmnNodeAbsolutePosition(state, node) ?? node.position;
4819
+ const size = getBpmnNodeSize(node);
4820
+ return {
4821
+ ...position,
4822
+ width: size.width,
4823
+ height: size.height
4824
+ };
4825
+ }
4826
+ var BPMN_BOUNDARY_ATTACH_MARGIN = 32;
4827
+ function clampBoundaryCoordinate(value, min, max) {
4828
+ return Math.min(max, Math.max(min, value));
4829
+ }
4830
+ function isPointInsideExpandedBounds(point, origin, size) {
4831
+ return point.x >= origin.x - BPMN_BOUNDARY_ATTACH_MARGIN && point.x <= origin.x + size.width + BPMN_BOUNDARY_ATTACH_MARGIN && point.y >= origin.y - BPMN_BOUNDARY_ATTACH_MARGIN && point.y <= origin.y + size.height + BPMN_BOUNDARY_ATTACH_MARGIN;
4832
+ }
4833
+ function snapBoundaryCenterToHostBorder(center, hostOrigin, hostSize) {
4834
+ const distances = [
4835
+ { side: "left", value: Math.abs(center.x - hostOrigin.x) },
4836
+ { side: "right", value: Math.abs(center.x - (hostOrigin.x + hostSize.width)) },
4837
+ { side: "top", value: Math.abs(center.y - hostOrigin.y) },
4838
+ { side: "bottom", value: Math.abs(center.y - (hostOrigin.y + hostSize.height)) }
4839
+ ].sort((a, b) => a.value - b.value);
4840
+ const side = distances[0]?.side;
4841
+ if (side === "left") {
4842
+ return { x: hostOrigin.x, y: clampBoundaryCoordinate(center.y, hostOrigin.y, hostOrigin.y + hostSize.height) };
4843
+ }
4844
+ if (side === "right") {
4845
+ return { x: hostOrigin.x + hostSize.width, y: clampBoundaryCoordinate(center.y, hostOrigin.y, hostOrigin.y + hostSize.height) };
4846
+ }
4847
+ if (side === "top") {
4848
+ return { x: clampBoundaryCoordinate(center.x, hostOrigin.x, hostOrigin.x + hostSize.width), y: hostOrigin.y };
4849
+ }
4850
+ return {
4851
+ x: clampBoundaryCoordinate(center.x, hostOrigin.x, hostOrigin.x + hostSize.width),
4852
+ y: hostOrigin.y + hostSize.height
4853
+ };
4854
+ }
4855
+ function findBpmnLaneAt(state, position) {
4856
+ return state.nodes.find((node) => {
4857
+ if (node.data.elementType !== "Lane") return false;
4858
+ const bounds = getBpmnNodeBounds(state, node);
4859
+ return position.x >= bounds.x && position.x <= bounds.x + bounds.width && position.y >= bounds.y && position.y <= bounds.y + bounds.height;
4860
+ });
4861
+ }
4862
+ function getAncestorLaneId(state, node) {
4863
+ let current = node;
4864
+ while (current) {
4865
+ if (current.data.elementType === "Lane") return current.id;
4866
+ current = current.parentId ? diagramsCore.getNode(state, current.parentId) : void 0;
4867
+ }
4868
+ return void 0;
4869
+ }
4870
+ function getAncestorContainerId(state, node, elementType) {
4871
+ let current = node;
4872
+ while (current) {
4873
+ if (current.data.elementType === elementType) return current.id;
4874
+ current = current.parentId ? diagramsCore.getNode(state, current.parentId) : void 0;
4875
+ }
4876
+ return void 0;
4877
+ }
4563
4878
  function getNodeDimension(node, axis) {
4564
4879
  return node[axis] ?? node.measured?.[axis] ?? getBpmnElementSize(node.data.elementType)[axis];
4565
4880
  }
@@ -4567,17 +4882,250 @@ function getBpmnLaneOrderPosition(lane, orientation) {
4567
4882
  const size = getBpmnNodeSize(lane);
4568
4883
  return orientation === "vertical" ? lane.position.x + size.width / 2 : lane.position.y + size.height / 2;
4569
4884
  }
4885
+ function getBpmnPoolOrientation(pool) {
4886
+ return pool.data.orientation === "vertical" ? "vertical" : "horizontal";
4887
+ }
4888
+ function getBpmnPoolLanesOrderedByStack(nodes, poolId, orientation) {
4889
+ return nodes.filter((node) => node.parentId === poolId && node.data.elementType === "Lane").sort((a, b) => {
4890
+ const aIndex = typeof a.data.laneIndex === "number" ? a.data.laneIndex : void 0;
4891
+ const bIndex = typeof b.data.laneIndex === "number" ? b.data.laneIndex : void 0;
4892
+ if (aIndex !== void 0 || bIndex !== void 0) return (aIndex ?? 0) - (bIndex ?? 0);
4893
+ return orientation === "vertical" ? (a.position?.x ?? 0) - (b.position?.x ?? 0) : (a.position?.y ?? 0) - (b.position?.y ?? 0);
4894
+ });
4895
+ }
4896
+ function layoutBpmnPoolLaneNodesPreservingHeights(nodes, poolId) {
4897
+ const pool = nodes.find((node) => node.id === poolId && node.data.elementType === "Pool");
4898
+ if (!pool) return nodes;
4899
+ const orientation = getBpmnPoolOrientation(pool);
4900
+ const lanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
4901
+ if (lanes.length === 0) return withBpmnNodeZIndexes(nodes);
4902
+ const poolW = pool.measured?.width ?? pool.width ?? 720;
4903
+ const poolH = pool.measured?.height ?? pool.height ?? 200;
4904
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
4905
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
4906
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
4907
+ const minLaneH = BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
4908
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
4909
+ if (orientation === "vertical") {
4910
+ const laneWidth2 = Math.max(
4911
+ minLaneW,
4912
+ Math.floor((poolW - pad * 2 - gap * Math.max(0, lanes.length - 1)) / Math.max(1, lanes.length))
4913
+ );
4914
+ const laneHeight = Math.max(minLaneH, poolH - pad * 2);
4915
+ let cumX = pad;
4916
+ const laneMap2 = new Map(
4917
+ lanes.map((lane, index) => {
4918
+ const nextLane = {
4919
+ ...lane,
4920
+ position: { x: cumX, y: pad },
4921
+ width: laneWidth2,
4922
+ height: laneHeight,
4923
+ parentId: pool.id,
4924
+ data: { ...lane.data, orientation: "vertical", laneIndex: index }
4925
+ };
4926
+ cumX += laneWidth2 + gap;
4927
+ return [lane.id, nextLane];
4928
+ })
4929
+ );
4930
+ const requiredPoolW = cumX - gap + pad;
4931
+ return withBpmnNodeZIndexes(
4932
+ nodes.map(
4933
+ (node) => laneMap2.get(node.id) ?? (node.id === pool.id ? { ...pool, width: Math.max(requiredPoolW, poolW) } : node)
4934
+ )
4935
+ );
4936
+ }
4937
+ const laneWidth = Math.max(minLaneW, poolW - pad * 2);
4938
+ let cumY = pad;
4939
+ const laneMap = new Map(
4940
+ lanes.map((lane, index) => {
4941
+ const laneHeight = Math.max(minLaneH, lane.measured?.height ?? lane.height ?? defaultLaneH);
4942
+ const nextLane = {
4943
+ ...lane,
4944
+ position: { x: pad, y: cumY },
4945
+ width: laneWidth,
4946
+ height: laneHeight,
4947
+ parentId: pool.id,
4948
+ data: { ...lane.data, orientation: "horizontal", laneIndex: index }
4949
+ };
4950
+ cumY += laneHeight + gap;
4951
+ return [lane.id, nextLane];
4952
+ })
4953
+ );
4954
+ const requiredPoolH = cumY - gap + pad;
4955
+ return withBpmnNodeZIndexes(
4956
+ nodes.map(
4957
+ (node) => laneMap.get(node.id) ?? (node.id === pool.id ? { ...pool, height: Math.max(requiredPoolH, poolH) } : node)
4958
+ )
4959
+ );
4960
+ }
4961
+ function reorderBpmnPoolLaneAfterDropPreservingHeights(nodes, laneId) {
4962
+ const lane = nodes.find((node) => node.id === laneId && node.data.elementType === "Lane");
4963
+ if (!lane?.parentId) return nodes;
4964
+ const pool = nodes.find((node) => node.id === lane.parentId && node.data.elementType === "Pool");
4965
+ if (!pool) return nodes;
4966
+ const orientation = getBpmnPoolOrientation(pool);
4967
+ const lanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
4968
+ const moved = lanes.find((candidate) => candidate.id === lane.id);
4969
+ if (!moved) return layoutBpmnPoolLaneNodesPreservingHeights(nodes, pool.id);
4970
+ const withoutMoved = lanes.filter((candidate) => candidate.id !== lane.id);
4971
+ const movedCenter = orientation === "vertical" ? (lane.position?.x ?? 0) + (lane.width ?? 0) / 2 : (lane.position?.y ?? 0) + (lane.height ?? 0) / 2;
4972
+ const insertIndex = withoutMoved.findIndex((candidate) => {
4973
+ const candidateCenter = orientation === "vertical" ? (candidate.position?.x ?? 0) + (candidate.width ?? 0) / 2 : (candidate.position?.y ?? 0) + (candidate.height ?? 0) / 2;
4974
+ return movedCenter < candidateCenter;
4975
+ });
4976
+ const ordered = [...withoutMoved];
4977
+ ordered.splice(insertIndex === -1 ? ordered.length : insertIndex, 0, moved);
4978
+ const orderedMap = new Map(ordered.map((candidate, index) => [candidate.id, index]));
4979
+ return layoutBpmnPoolLaneNodesPreservingHeights(
4980
+ nodes.map(
4981
+ (node) => node.parentId === pool.id && node.data.elementType === "Lane" ? { ...node, data: { ...node.data, laneIndex: orderedMap.get(node.id) ?? 0 } } : node
4982
+ ),
4983
+ pool.id
4984
+ );
4985
+ }
4986
+ function getAppendedBpmnLaneFrame(nodes, poolOrId) {
4987
+ const pool = typeof poolOrId === "string" ? nodes.find((node) => node.id === poolOrId && node.data.elementType === "Pool") : poolOrId;
4988
+ if (!pool || pool.data.elementType !== "Pool") return null;
4989
+ const orientation = getBpmnPoolOrientation(pool);
4990
+ const existingLanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
4991
+ const poolW = pool.measured?.width ?? pool.width ?? 600;
4992
+ const poolH = pool.measured?.height ?? pool.height ?? 400;
4993
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
4994
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
4995
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
4996
+ const minLaneH = BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
4997
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
4998
+ if (orientation === "horizontal") {
4999
+ const lastLane2 = existingLanes[existingLanes.length - 1];
5000
+ return {
5001
+ position: {
5002
+ x: pad,
5003
+ y: lastLane2 ? (lastLane2.position?.y ?? pad) + (lastLane2.height ?? defaultLaneH) + gap : pad
5004
+ },
5005
+ width: Math.max(minLaneW, poolW - pad * 2),
5006
+ height: existingLanes.length === 0 ? Math.max(minLaneH, poolH - pad * 2) : defaultLaneH,
5007
+ laneIndex: existingLanes.length,
5008
+ orientation
5009
+ };
5010
+ }
5011
+ const lastLane = existingLanes[existingLanes.length - 1];
5012
+ return {
5013
+ position: {
5014
+ x: lastLane ? (lastLane.position?.x ?? pad) + (lastLane.width ?? defaultLaneH) + gap : pad,
5015
+ y: pad
5016
+ },
5017
+ width: existingLanes.length === 0 ? Math.max(minLaneW, poolW - pad * 2) : defaultLaneH,
5018
+ height: Math.max(minLaneH, poolH - pad * 2),
5019
+ laneIndex: existingLanes.length,
5020
+ orientation
5021
+ };
5022
+ }
5023
+ function getBpmnPoolLaneNodeMaxSize(state, nodeId) {
5024
+ const n = diagramsCore.getNode(state, nodeId);
5025
+ if (n?.data.elementType === "Lane" && n.parentId) {
5026
+ const pool = diagramsCore.getNode(state, n.parentId);
5027
+ if (pool) {
5028
+ const siblings = state.nodes.filter(
5029
+ (x) => x.parentId === n.parentId && x.data.elementType === "Lane" && x.id !== n.id
5030
+ );
5031
+ const poolH = pool.measured?.height ?? pool.height ?? 500;
5032
+ const siblingsMinH = siblings.length * BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
5033
+ const siblingGaps = siblings.length * BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
5034
+ const maxH = Math.max(
5035
+ BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight,
5036
+ poolH - BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2 - siblingsMinH - siblingGaps
5037
+ );
5038
+ return {
5039
+ width: (pool.width ?? 720) - BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2,
5040
+ height: maxH
5041
+ };
5042
+ }
5043
+ }
5044
+ return void 0;
5045
+ }
5046
+ function getBpmnPoolLaneNodeMinSize(state, nodeId) {
5047
+ const n = diagramsCore.getNode(state, nodeId);
5048
+ if (n?.data.elementType === "Pool") {
5049
+ const lanes = state.nodes.filter((x) => x.parentId === nodeId && x.data.elementType === "Lane");
5050
+ if (lanes.length > 0) {
5051
+ const minW = Math.max(...lanes.map((l) => (l.width ?? 0) + BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2));
5052
+ const minH = lanes.reduce((s, l) => s + (l.height ?? BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight), 0) + BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2 + Math.max(0, lanes.length - 1) * BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
5053
+ return { width: minW, height: minH };
5054
+ }
5055
+ }
5056
+ return void 0;
5057
+ }
5058
+ function applyBpmnPoolLaneDimensionChange(nodes, previousNodes, nodeId, width, height) {
5059
+ const node = nodes.find((candidate) => candidate.id === nodeId);
5060
+ const previousNode = previousNodes.find((candidate) => candidate.id === nodeId);
5061
+ if (!node) return nodes;
5062
+ const curW = previousNode?.measured?.width ?? previousNode?.width ?? 0;
5063
+ const curH = previousNode?.measured?.height ?? previousNode?.height ?? 0;
5064
+ if (Math.abs(width - curW) < 1 && Math.abs(height - curH) < 1) return nodes;
5065
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
5066
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
5067
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
5068
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
5069
+ if (node.data.elementType === "Pool") {
5070
+ const targetLaneW = Math.max(minLaneW, width - pad * 2);
5071
+ return nodes.map(
5072
+ (candidate) => candidate.parentId === node.id && candidate.data.elementType === "Lane" ? {
5073
+ ...candidate,
5074
+ width: targetLaneW,
5075
+ measured: {
5076
+ width: targetLaneW,
5077
+ height: candidate.measured?.height ?? candidate.height ?? defaultLaneH
5078
+ },
5079
+ position: { x: pad, y: candidate.position?.y ?? pad }
5080
+ } : candidate
5081
+ );
5082
+ }
5083
+ if (node.data.elementType === "Lane" && node.parentId) {
5084
+ const pool = nodes.find((candidate) => candidate.id === node.parentId && candidate.data.elementType === "Pool");
5085
+ if (!pool) return nodes;
5086
+ const poolW = Math.max(width + pad * 2, pool.measured?.width ?? pool.width ?? 720);
5087
+ const sortedLanes = getBpmnPoolLanesOrderedByStack(nodes, node.parentId, "horizontal");
5088
+ let cumY = pad;
5089
+ const laneMap = /* @__PURE__ */ new Map();
5090
+ for (const lane of sortedLanes) {
5091
+ const laneH = lane.id === node.id ? height : lane.measured?.height ?? lane.height ?? defaultLaneH;
5092
+ laneMap.set(lane.id, {
5093
+ ...lane,
5094
+ width,
5095
+ height: laneH,
5096
+ measured: { width, height: laneH },
5097
+ position: { x: pad, y: cumY }
5098
+ });
5099
+ cumY += laneH + gap;
5100
+ }
5101
+ const newPoolH = cumY - gap + pad;
5102
+ return nodes.map((candidate) => {
5103
+ if (candidate.id === pool.id) {
5104
+ return {
5105
+ ...candidate,
5106
+ width: poolW,
5107
+ height: newPoolH,
5108
+ measured: { width: poolW, height: newPoolH }
5109
+ };
5110
+ }
5111
+ return laneMap.get(candidate.id) ?? candidate;
5112
+ });
5113
+ }
5114
+ return nodes;
5115
+ }
4570
5116
  function resizeHorizontalBpmnLanes(lanes, pool) {
5117
+ const pad = BPMN_POOL_LANE_LAYOUT.poolPad;
4571
5118
  const poolSize = getBpmnNodeSize(pool);
4572
- const laneWidth = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, poolSize.width - BPMN_POOL_LANE_LAYOUT.poolHeaderSize);
4573
- const laneHeight = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, poolSize.height / Math.max(1, lanes.length));
5119
+ const laneWidth = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, poolSize.width - pad * 2);
5120
+ const availH = Math.max(0, poolSize.height - pad * 2);
5121
+ const laneHeight = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, availH / Math.max(1, lanes.length));
4574
5122
  return lanes.map((lane, index) => ({
4575
5123
  ...lane,
4576
- position: { x: BPMN_POOL_LANE_LAYOUT.poolHeaderSize, y: index * laneHeight },
5124
+ position: { x: pad, y: pad + index * laneHeight },
4577
5125
  width: laneWidth,
4578
5126
  height: laneHeight,
4579
5127
  parentId: pool.id,
4580
- extent: "parent",
5128
+ // extent:"parent" intentionally omitted — blocks resize→Pool coupling.
4581
5129
  zIndex: getBpmnNodeZIndex("Lane"),
4582
5130
  data: { ...lane.data, orientation: "horizontal", laneIndex: index }
4583
5131
  }));
@@ -4608,10 +5156,22 @@ function layoutBpmnPoolLaneNodes(nodes, poolId) {
4608
5156
  return getBpmnLaneOrderPosition(a, orientation) - getBpmnLaneOrderPosition(b, orientation);
4609
5157
  });
4610
5158
  if (lanes.length === 0) return withBpmnNodeZIndexes(nodes);
4611
- const laneMap = new Map(
4612
- (orientation === "vertical" ? resizeVerticalBpmnLanes(lanes, pool) : resizeHorizontalBpmnLanes(lanes, pool)).map((lane) => [lane.id, lane])
5159
+ const resizedLanes = orientation === "vertical" ? resizeVerticalBpmnLanes(lanes, pool) : resizeHorizontalBpmnLanes(lanes, pool);
5160
+ const laneMap = new Map(resizedLanes.map((lane) => [lane.id, lane]));
5161
+ const pad = BPMN_POOL_LANE_LAYOUT.poolPad;
5162
+ const totalLaneH = resizedLanes.reduce((sum, l) => sum + (l.height ?? 0), 0);
5163
+ const requiredPoolH = totalLaneH + pad * 2;
5164
+ const poolMap = /* @__PURE__ */ new Map();
5165
+ if (orientation === "horizontal") {
5166
+ const currentH = getBpmnNodeSize(pool).height;
5167
+ poolMap.set(pool.id, {
5168
+ ...pool,
5169
+ height: Math.max(requiredPoolH, currentH)
5170
+ });
5171
+ }
5172
+ return withBpmnNodeZIndexes(
5173
+ nodes.map((node) => laneMap.get(node.id) ?? poolMap.get(node.id) ?? node)
4613
5174
  );
4614
- return withBpmnNodeZIndexes(nodes.map((node) => laneMap.get(node.id) ?? node));
4615
5175
  }
4616
5176
  function reorderBpmnLaneAfterDrop(nodes, laneId) {
4617
5177
  const lane = nodes.find((node) => node.id === laneId && node.data.elementType === "Lane");
@@ -4670,9 +5230,116 @@ function findBpmnContainerAt(state, options) {
4670
5230
  }
4671
5231
  });
4672
5232
  }
5233
+ function resolveBpmnDropTarget(state, options) {
5234
+ if (options.elementType === "Pool") {
5235
+ return { highlightedContainerId: null, invalidContainerId: null, isValid: true };
5236
+ }
5237
+ if (options.elementType === "Lane") {
5238
+ const pool = state.nodes.find((node) => {
5239
+ if (node.data.elementType !== "Pool") return false;
5240
+ const bounds = getBpmnNodeBounds(state, node);
5241
+ return options.position.x >= bounds.x && options.position.x <= bounds.x + bounds.width && options.position.y >= bounds.y && options.position.y <= bounds.y + bounds.height;
5242
+ });
5243
+ return {
5244
+ ...pool ? { container: pool } : {},
5245
+ highlightedContainerId: pool?.id ?? null,
5246
+ invalidContainerId: null,
5247
+ isValid: Boolean(pool)
5248
+ };
5249
+ }
5250
+ const lane = findBpmnLaneAt(state, options.position);
5251
+ if (lane) {
5252
+ return {
5253
+ container: lane,
5254
+ highlightedContainerId: lane.id,
5255
+ invalidContainerId: null,
5256
+ isValid: true
5257
+ };
5258
+ }
5259
+ const container = findBpmnContainerAt(state, {
5260
+ position: options.position,
5261
+ ...options.excludeId ? { excludeId: options.excludeId } : {}
5262
+ });
5263
+ if (container?.data.elementType === "Pool") {
5264
+ const hasLanes = getBpmnPoolLanes(state, container.id).length > 0;
5265
+ if (hasLanes) {
5266
+ return {
5267
+ highlightedContainerId: null,
5268
+ invalidContainerId: container.id,
5269
+ isValid: false
5270
+ };
5271
+ }
5272
+ }
5273
+ return {
5274
+ ...container ? { container } : {},
5275
+ highlightedContainerId: getAncestorLaneId(state, container) ?? container?.id ?? null,
5276
+ invalidContainerId: null,
5277
+ isValid: true
5278
+ };
5279
+ }
4673
5280
  function getBpmnNodeCenter(node, absolutePosition) {
4674
5281
  return diagramsCore.getNodeCenterPosition(absolutePosition, getBpmnNodeSize(node));
4675
5282
  }
5283
+ function getBoundaryEventAttachment(state, boundaryNode) {
5284
+ if (boundaryNode.data.elementType !== "BoundaryEvent") return null;
5285
+ const boundaryOrigin = getBpmnNodeAbsolutePosition(state, boundaryNode) ?? boundaryNode.position;
5286
+ const boundarySize = getBpmnNodeSize(boundaryNode);
5287
+ const boundaryCenter = {
5288
+ x: boundaryOrigin.x + boundarySize.width / 2,
5289
+ y: boundaryOrigin.y + boundarySize.height / 2
5290
+ };
5291
+ const candidates = state.nodes.filter((node) => node.id !== boundaryNode.id && acceptsBoundaryEvents(node.data.elementType)).map((node) => {
5292
+ const origin = getBpmnNodeAbsolutePosition(state, node) ?? node.position;
5293
+ const size = getBpmnNodeSize(node);
5294
+ const hostCenter = { x: origin.x + size.width / 2, y: origin.y + size.height / 2 };
5295
+ return {
5296
+ node,
5297
+ origin,
5298
+ size,
5299
+ distance: Math.hypot(boundaryCenter.x - hostCenter.x, boundaryCenter.y - hostCenter.y)
5300
+ };
5301
+ }).filter(({ origin, size }) => isPointInsideExpandedBounds(boundaryCenter, origin, size)).sort((a, b) => a.distance - b.distance);
5302
+ const host = candidates[0];
5303
+ if (!host) return null;
5304
+ const snappedCenter = snapBoundaryCenterToHostBorder(boundaryCenter, host.origin, host.size);
5305
+ return {
5306
+ hostId: host.node.id,
5307
+ position: {
5308
+ x: snappedCenter.x - host.origin.x - boundarySize.width / 2,
5309
+ y: snappedCenter.y - host.origin.y - boundarySize.height / 2
5310
+ }
5311
+ };
5312
+ }
5313
+ function getBpmnEdgeLaneContext(state, edgeOrId) {
5314
+ const edge = typeof edgeOrId === "string" ? state.edges.find((candidate) => candidate.id === edgeOrId) : edgeOrId;
5315
+ if (!edge) return void 0;
5316
+ const source = diagramsCore.getNode(state, edge.source);
5317
+ const target = diagramsCore.getNode(state, edge.target);
5318
+ if (!source || !target) return void 0;
5319
+ const sourceLaneId = getAncestorLaneId(state, source);
5320
+ const targetLaneId = getAncestorLaneId(state, target);
5321
+ const sourcePoolId = getAncestorContainerId(state, source, "Pool");
5322
+ const targetPoolId = getAncestorContainerId(state, target, "Pool");
5323
+ const sameLane = Boolean(sourceLaneId) && sourceLaneId === targetLaneId;
5324
+ const samePool = Boolean(sourcePoolId) && sourcePoolId === targetPoolId;
5325
+ const crossesLanesWithinPool = Boolean(
5326
+ sourceLaneId && targetLaneId && sourceLaneId !== targetLaneId && samePool
5327
+ );
5328
+ const crossesPools = Boolean(
5329
+ sourcePoolId && targetPoolId && sourcePoolId !== targetPoolId
5330
+ );
5331
+ return {
5332
+ edgeId: edge.id,
5333
+ ...sourceLaneId ? { sourceLaneId } : {},
5334
+ ...targetLaneId ? { targetLaneId } : {},
5335
+ ...sourcePoolId ? { sourcePoolId } : {},
5336
+ ...targetPoolId ? { targetPoolId } : {},
5337
+ sameLane,
5338
+ samePool,
5339
+ crossesLanesWithinPool,
5340
+ crossesPools
5341
+ };
5342
+ }
4676
5343
  function resolvePoolLaneDirection(pool) {
4677
5344
  return pool.data.orientation === "vertical" ? "horizontal" : "vertical";
4678
5345
  }
@@ -4762,6 +5429,14 @@ function validateBpmnConnectionForEdgeType(state, edgeType, source, target) {
4762
5429
  }
4763
5430
  return true;
4764
5431
  }
5432
+ function resolveBpmnConnection(state, sourceId, targetId, requestedType) {
5433
+ const source = diagramsCore.getNode(state, sourceId);
5434
+ const target = diagramsCore.getNode(state, targetId);
5435
+ if (!source || !target) return { ok: false, reason: "No se encontr\xF3 el origen o destino." };
5436
+ const validation = validateBpmnConnectionForEdgeType(state, requestedType, source, target);
5437
+ if (validation !== true) return { ok: false, reason: validation };
5438
+ return { ok: true, edgeType: requestedType };
5439
+ }
4765
5440
  function validateEdgeCardinality(state, edgeType, source, target) {
4766
5441
  if (edgeType !== "sequenceFlow") return true;
4767
5442
  const sourceMax = BPMN_ELEMENT_CATALOG[source.data.elementType].maxOutgoing;
@@ -4949,6 +5624,28 @@ function reparentBpmnNodeAtPosition(state, options) {
4949
5624
  });
4950
5625
  }
4951
5626
  var BE_HALF = 18;
5627
+ function getBoundarySpanRatio(value, size) {
5628
+ const min = BE_HALF;
5629
+ const max = size - BE_HALF;
5630
+ if (max <= min) return 0.5;
5631
+ return (clampBoundaryCoordinate(value, min, max) - min) / (max - min);
5632
+ }
5633
+ function fromBoundarySpanRatio(ratio, size) {
5634
+ const min = BE_HALF;
5635
+ const max = size - BE_HALF;
5636
+ if (max <= min) return size / 2;
5637
+ return min + (max - min) * ratio;
5638
+ }
5639
+ function detectBoundarySide(center, hostSize) {
5640
+ const distances = [
5641
+ { side: "left", value: Math.abs(center.x) },
5642
+ { side: "right", value: Math.abs(center.x - hostSize.width) },
5643
+ { side: "top", value: Math.abs(center.y) },
5644
+ { side: "bottom", value: Math.abs(center.y - hostSize.height) }
5645
+ ];
5646
+ distances.sort((a, b) => a.value - b.value);
5647
+ return distances[0]?.side ?? "bottom";
5648
+ }
4952
5649
  function clampBoundaryEventsAfterResize(state, hostId, oldW, oldH, newW, newH) {
4953
5650
  const boundaryEvents = state.nodes.filter(
4954
5651
  (n) => n.data.elementType === "BoundaryEvent" && n.parentId === hostId
@@ -4959,25 +5656,21 @@ function clampBoundaryEventsAfterResize(state, hostId, oldW, oldH, newW, newH) {
4959
5656
  const py = be.position?.y ?? 0;
4960
5657
  const cx = px + BE_HALF;
4961
5658
  const cy = py + BE_HALF;
4962
- const distLeft = Math.abs(cx);
4963
- const distRight = Math.abs(cx - oldW);
4964
- const distTop = Math.abs(cy);
4965
- const distBottom = Math.abs(cy - oldH);
4966
- const minDist = Math.min(distLeft, distRight, distTop, distBottom);
5659
+ const side = detectBoundarySide({ x: cx, y: cy }, { width: oldW, height: oldH });
4967
5660
  let newCx;
4968
5661
  let newCy;
4969
- if (minDist === distBottom) {
5662
+ if (side === "bottom") {
4970
5663
  newCy = newH;
4971
- newCx = Math.min(Math.max(cx, BE_HALF), newW - BE_HALF);
4972
- } else if (minDist === distRight) {
5664
+ newCx = fromBoundarySpanRatio(getBoundarySpanRatio(cx, oldW), newW);
5665
+ } else if (side === "right") {
4973
5666
  newCx = newW;
4974
- newCy = Math.min(Math.max(cy, BE_HALF), newH - BE_HALF);
4975
- } else if (minDist === distTop) {
5667
+ newCy = fromBoundarySpanRatio(getBoundarySpanRatio(cy, oldH), newH);
5668
+ } else if (side === "top") {
4976
5669
  newCy = 0;
4977
- newCx = Math.min(Math.max(cx, BE_HALF), newW - BE_HALF);
5670
+ newCx = fromBoundarySpanRatio(getBoundarySpanRatio(cx, oldW), newW);
4978
5671
  } else {
4979
5672
  newCx = 0;
4980
- newCy = Math.min(Math.max(cy, BE_HALF), newH - BE_HALF);
5673
+ newCy = fromBoundarySpanRatio(getBoundarySpanRatio(cy, oldH), newH);
4981
5674
  }
4982
5675
  next = diagramsCore.moveNode(next, be.id, { x: newCx - BE_HALF, y: newCy - BE_HALF });
4983
5676
  }
@@ -5241,6 +5934,7 @@ function withBpmnLayoutCache(layoutFn, cache) {
5241
5934
  return diagramsCore.withLayoutCache(layoutFn, cache ?? diagramsCore.createLayoutCache());
5242
5935
  }
5243
5936
 
5937
+ exports.ARANZA_DESCRIPTOR = ARANZA_DESCRIPTOR;
5244
5938
  exports.AnnotationNode = AnnotationNode;
5245
5939
  exports.AssociationEdge = AssociationEdge;
5246
5940
  exports.BPMN_EDGE_CONNECTION_RULES = BPMN_EDGE_CONNECTION_RULES;
@@ -5249,6 +5943,7 @@ exports.BPMN_ELEMENT_CATALOG = BPMN_ELEMENT_CATALOG;
5249
5943
  exports.BPMN_MODELING_RULES = BPMN_MODELING_RULES;
5250
5944
  exports.BPMN_NODE_TYPES = BPMN_NODE_TYPES;
5251
5945
  exports.BPMN_POOL_LANE_LAYOUT = BPMN_POOL_LANE_LAYOUT;
5946
+ exports.BPMN_POOL_LANE_STACK_LAYOUT = BPMN_POOL_LANE_STACK_LAYOUT;
5252
5947
  exports.BPMN_RESIZABLE_ELEMENT_TYPES = BPMN_RESIZABLE_ELEMENT_TYPES;
5253
5948
  exports.BPMN_ROUTABLE_EDGE_TYPES = BPMN_ROUTABLE_EDGE_TYPES;
5254
5949
  exports.BPMN_SELECTION_STYLE = BPMN_SELECTION_STYLE;
@@ -5280,6 +5975,7 @@ exports.SubConversationNode = SubConversationNode;
5280
5975
  exports.SubProcessNode = SubProcessNode;
5281
5976
  exports.TaskNode = TaskNode;
5282
5977
  exports.acceptsBoundaryEvents = acceptsBoundaryEvents;
5978
+ exports.applyBpmnPoolLaneDimensionChange = applyBpmnPoolLaneDimensionChange;
5283
5979
  exports.attachBoundaryEventCommand = attachBoundaryEventCommand;
5284
5980
  exports.bpmnConnectionValidators = bpmnConnectionValidators;
5285
5981
  exports.canContainBpmnElement = canContainBpmnElement;
@@ -5297,16 +5993,25 @@ exports.deserializeBpmnDiagram = deserializeBpmnDiagram;
5297
5993
  exports.deserializeBpmnDiagramSnapshot = deserializeBpmnDiagramSnapshot;
5298
5994
  exports.findBpmnContainerAt = findBpmnContainerAt;
5299
5995
  exports.fire = fire;
5996
+ exports.getAllowedEventTriggers = getAllowedEventTriggers;
5997
+ exports.getAppendedBpmnLaneFrame = getAppendedBpmnLaneFrame;
5998
+ exports.getBoundaryEventAttachment = getBoundaryEventAttachment;
5300
5999
  exports.getBpmnDragHandleSelector = getBpmnDragHandleSelector;
5301
6000
  exports.getBpmnEdgeLabelLayout = getBpmnEdgeLabelLayout;
6001
+ exports.getBpmnEdgeLaneContext = getBpmnEdgeLaneContext;
5302
6002
  exports.getBpmnElementSize = getBpmnElementSize;
5303
6003
  exports.getBpmnLaneIndexAtPosition = getBpmnLaneIndexAtPosition;
6004
+ exports.getBpmnMessageFlowExecutionExtensions = getBpmnMessageFlowExecutionExtensions;
5304
6005
  exports.getBpmnNodeAbsolutePosition = getBpmnNodeAbsolutePosition;
5305
6006
  exports.getBpmnNodeCenter = getBpmnNodeCenter;
5306
6007
  exports.getBpmnNodeSize = getBpmnNodeSize;
5307
6008
  exports.getBpmnNodeZIndex = getBpmnNodeZIndex;
6009
+ exports.getBpmnPoolLaneNodeMaxSize = getBpmnPoolLaneNodeMaxSize;
6010
+ exports.getBpmnPoolLaneNodeMinSize = getBpmnPoolLaneNodeMinSize;
5308
6011
  exports.getBpmnPoolLanes = getBpmnPoolLanes;
6012
+ exports.getBpmnPoolOrientation = getBpmnPoolOrientation;
5309
6013
  exports.getBpmnTabOrder = getBpmnTabOrder;
6014
+ exports.getBpmnTaskExecutionExtensions = getBpmnTaskExecutionExtensions;
5310
6015
  exports.getElementMeta = getElementMeta;
5311
6016
  exports.getFireable = getFireable;
5312
6017
  exports.getHandlePolicy = getHandlePolicy;
@@ -5326,6 +6031,7 @@ exports.isEventType = isEventType;
5326
6031
  exports.isGatewayType = isGatewayType;
5327
6032
  exports.isTaskType = isTaskType;
5328
6033
  exports.layoutBpmnPoolLaneNodes = layoutBpmnPoolLaneNodes;
6034
+ exports.layoutBpmnPoolLaneNodesPreservingHeights = layoutBpmnPoolLaneNodesPreservingHeights;
5329
6035
  exports.layoutBpmnPoolLanes = layoutBpmnPoolLanes;
5330
6036
  exports.moveBpmnLaneCommand = moveBpmnLaneCommand;
5331
6037
  exports.parseBpmnDiagramDocument = parseBpmnDiagramDocument;
@@ -5335,11 +6041,14 @@ exports.persistBpmnHistory = persistBpmnHistory;
5335
6041
  exports.reorderBpmnLane = reorderBpmnLane;
5336
6042
  exports.reorderBpmnLaneAfterDrop = reorderBpmnLaneAfterDrop;
5337
6043
  exports.reorderBpmnLaneCommand = reorderBpmnLaneCommand;
6044
+ exports.reorderBpmnPoolLaneAfterDropPreservingHeights = reorderBpmnPoolLaneAfterDropPreservingHeights;
5338
6045
  exports.reparentBpmnNodeAtPosition = reparentBpmnNodeAtPosition;
5339
6046
  exports.reparentBpmnNodeCommand = reparentBpmnNodeCommand;
5340
6047
  exports.replaceBpmnNodeCommand = replaceBpmnNodeCommand;
5341
6048
  exports.resizeBpmnNodeByHandleCommand = resizeBpmnNodeByHandleCommand;
5342
6049
  exports.resizeBpmnNodeCommand = resizeBpmnNodeCommand;
6050
+ exports.resolveBpmnConnection = resolveBpmnConnection;
6051
+ exports.resolveBpmnDropTarget = resolveBpmnDropTarget;
5343
6052
  exports.restoreBpmnHistory = restoreBpmnHistory;
5344
6053
  exports.routeBpmnEdgeCommand = routeBpmnEdgeCommand;
5345
6054
  exports.runBatchSimulation = runBatchSimulation;