yet-another-bpmn-auto-layout 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +85 -0
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../lib/di/DiUtil.js","../lib/utils/elementUtils.js","../lib/utils/layoutUtils.js","../lib/di/DiFactory.js","../lib/handler/index.js","../lib/handler/elementHandler.js","../lib/handler/outgoingHandler.js","../lib/handler/attachersHandler.js","../lib/Grid.js","../lib/Edge.js","../lib/GridWithEdges.js","../lib/newHandlers/outgoingHandler.js","../lib/Layouter.js","../lib/index.js"],"sourcesContent":["export function getDefaultSize(element) {\n if (is(element, 'bpmn:SubProcess')) {\n return { width: 100, height: 80 };\n }\n\n if (is(element, 'bpmn:Task')) {\n return { width: 100, height: 80 };\n }\n\n if (is(element, 'bpmn:Gateway')) {\n return { width: 50, height: 50 };\n }\n\n if (is(element, 'bpmn:Event')) {\n return { width: 36, height: 36 };\n }\n\n if (is(element, 'bpmn:Participant')) {\n return { width: 400, height: 100 };\n }\n\n if (is(element, 'bpmn:Lane')) {\n return { width: 400, height: 100 };\n }\n\n if (is(element, 'bpmn:DataObjectReference')) {\n return { width: 36, height: 50 };\n }\n\n if (is(element, 'bpmn:DataStoreReference')) {\n return { width: 50, height: 50 };\n }\n\n if (is(element, 'bpmn:TextAnnotation')) {\n return { width: 100, height: 30 };\n }\n\n return { width: 100, height: 80 };\n}\n\nexport function is(element, type) {\n return element.$instanceOf(type);\n}\n","import { is } from '../di/DiUtil.js';\n\nexport function isConnection(element) {\n return !!element.sourceRef;\n}\n\nexport function isBoundaryEvent(element) {\n return !!element.attachedToRef;\n}\n\nexport function getOutgoingElements(element) {\n let outgoing = new Set();\n if (element) {\n const selfOutgoing = (element.outgoing || [])\n .map(out => out.targetRef)\n .filter(el => el);\n selfOutgoing.forEach(out => outgoing.add(out));\n }\n return [ ...outgoing ];\n}\n\nexport function getIncomingElements(element) {\n let incoming = [];\n\n if (element) {\n incoming = (element.incoming || [])\n .map(out => out.sourceRef)\n .filter(el => el)\n .map(item => {\n if (item.attachedToRef) {\n return item.attachedToRef;\n } else {\n return item;\n }\n });\n }\n\n // there is no time to check, so here it is\n const unique = new Set(incoming);\n\n return [ ...unique ];\n}\n\n/**\n * Только входящие из хоста\n * @param element\n * @returns {any[]}\n */\nexport function getHostIncoming(element) {\n return (element.incoming || [])\n .map(out => {\n if (!out.sourceRef) throw new Error(`${out.id} has no sourceRef`);\n return out.sourceRef;\n })\n .filter(el => !isBoundaryEvent(el));\n}\n\nexport function getBoundaryIncomingHosts(element) {\n let boundaryIncoming = (element.incoming || [])\n .map(out => out.sourceRef)\n .filter(el => isBoundaryEvent(el))\n .map(item => item.attachedToRef);\n boundaryIncoming = new Set(boundaryIncoming);\n\n return [ ...boundaryIncoming ];\n}\n\nexport function getAttachedOutgoingElements(element) {\n const outgoing = new Set();\n if (element) {\n const attachedOutgoing = (element.attachers || [])\n .sort((a,b) => {\n const bOutCount = b.outgoing ? b.outgoing.length : 0;\n const aOutCount = a.outgoing ? a.outgoing.length : 0;\n return bOutCount - aOutCount;\n })\n .map(attacher => (attacher.outgoing || []).reverse())\n .flat()\n .map(out => out.targetRef)\n .filter((item, index, self) => self.indexOf(item) === index);\n for (const out of attachedOutgoing) {\n outgoing.add(out);\n }\n }\n\n return [ ...outgoing ];\n}\n\nexport function isStartIntermediate(element) {\n return (is(element, 'bpmn:IntermediateThrowEvent') || is(element, 'bpmn:IntermediateCatchEvent'))\n && (element.incoming === undefined || element.incoming.length === 0);\n}\n\nexport function bindBoundaryEventsWithHosts(elements) {\n const boundaryEvents = elements.filter(element => isBoundaryEvent(element));\n boundaryEvents.forEach(boundaryEvent => {\n const attachedTask = boundaryEvent.attachedToRef;\n const attachers = attachedTask.attachers || [];\n attachers.push(boundaryEvent);\n attachedTask.attachers = attachers;\n });\n}\n\nexport function getAllProcesses(bpmnModel) {\n const allElements = bpmnModel.elementsById;\n if (!allElements) return [];\n return Object.values(allElements).filter(element => element.$type === 'bpmn:Process' || element.$type === 'bpmn:SubProcess');\n}\n\n/**\n * Set expanded property to element from its diagram\n * @param bpmnModel\n */\nexport function setExpandedProcesses(bpmnModel) {\n const allElements = bpmnModel.elementsById;\n if (allElements) {\n for (const element of Object.values(allElements)) {\n if (element.$type === 'bpmndi:BPMNShape' && element.isExpanded === true) element.bpmnElement.isExpanded = true;\n }\n }\n}\n","import { getDefaultSize, is } from '../di/DiUtil.js';\n\nimport {\n getAttachedOutgoingElements,\n getIncomingElements as utilsGetIncomingElements,\n getOutgoingElements as utilsGetOutgoingElements,\n} from './elementUtils.js';\n\nexport const DEFAULT_CELL_WIDTH = 150;\nexport const DEFAULT_CELL_HEIGHT = 140;\nexport const DEFAULT_POOL_MARGIN = DEFAULT_CELL_HEIGHT / 2;\n\nexport function getOutgoingElements(element, isFlipped) {\n return !isFlipped ? new Set (utilsGetOutgoingElements(element).concat(getAttachedOutgoingElements(element))) : new Set (utilsGetIncomingElements(element));\n}\n\nexport function sortColsLeftRightRowsBottomTop(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n if (aPos && !bPos) return -1;\n if (!aPos && bPos) return 1;\n if (!aPos && !bPos) return 0;\n\n return aPos[1] - bPos[1] || bPos[0] - aPos[0];\n };\n}\n\n/**\n * Modified Manhattan layout: Uses space between grid columns to route connections\n * if direct connection is not possible.\n * @param {*} source\n * @param {*} target\n * @returns waypoints\n */\nexport function connectElements(source, target, layoutGrid, isBoundary = false, shift) {\n\n // TODO: Use Edges for Drawing\n const sourceDi = source.di;\n const targetDi = target.di;\n\n const sourceBounds = sourceDi.get('bounds');\n const targetBounds = targetDi.get('bounds');\n\n const sourceMid = getMid(sourceBounds);\n const targetMid = getMid(targetBounds);\n\n const dX = target.gridPosition.col - source.gridPosition.col;\n const dY = target.gridPosition.row - source.gridPosition.row;\n\n const dockingSource = `${(dY > 0 ? 'bottom' : 'top')}-${dX > 0 ? 'right' : 'left'}`;\n const dockingTarget = `${(dY > 0 ? 'top' : 'bottom')}-${dX > 0 ? 'left' : 'right'}`;\n\n const { x: sourceX, y: sourceY } = coordinatesToPosition(source, shift);\n const { x: targetX } = coordinatesToPosition(target, shift);\n\n const forBoundary = source.$type === 'bpmn:BoundaryEvent';\n\n if (forBoundary) {\n\n // self loop\n if (dX === 0 && dY === 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n }\n\n // 12\n if (dX === 0 && dY < 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n }\n\n // 1\n if (dX > 0 && dY < 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n }\n\n // 3\n if (dX > 0 && dY === 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n }\n\n // 4\n if (dX > 0 && dY > 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l')\n ];\n }\n\n // 6\n if (dX === 0 && dY > 0) {\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource);\n const lastPoint = getDockingPoint(targetMid, targetBounds, 't', dockingTarget);\n\n if (source.attachedToRef.isExpanded) {\n return [\n firstPoint,\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n lastPoint\n ];\n }\n\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n // 7\n if (dX < 0 && dY > 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'r')\n ];\n }\n\n // 9\n if (dX < 0 && dY === 0) {\n const maxExpanded = getMaxExpandedBetween(source, target, layoutGrid);\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT + maxExpanded * DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT + maxExpanded * DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n }\n\n // 10\n if (dX < 0 && dY < 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n }\n\n\n } else {\n\n // Source === Target ==> Build loop\n if (dX === 0 && dY === 0) {\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n }\n\n // 12 часов\n if (dX === 0 && dY < 0) {\n\n // проверяем есть ли в гриде элементы между, если есть, то пускаем в обход\n const elementsInMiddle = [];\n for (let row = source.gridPosition.row - 1; row > target.gridPosition.row; row--) {\n const candidate = layoutGrid.get(row, source.gridPosition.col);\n if (candidate) elementsInMiddle.push(candidate);\n }\n\n // пока так по колхозному\n const hasReversEdge = [ ...getOutgoingElements(target) ].includes(source);\n\n if (elementsInMiddle.length > 0 || hasReversEdge) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'l', dockingSource),\n { x: sourceX, y: sourceMid.y },\n { x: targetX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n } else {\n return [\n getDockingPoint(sourceMid, sourceBounds, 't', dockingSource),\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n }\n }\n\n // 1 час\n if (dX > 0 && dY < 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'r'),\n { x: targetMid.x, y: sourceMid.y },\n getDockingPoint(targetMid, targetBounds, 'b')\n ];\n }\n\n // 3\n if (dX > 0 && dY === 0) {\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'r', dockingSource);\n if (source.isExpanded) {\n firstPoint.y = sourceBounds.y + getDefaultSize(source).height / 2;\n }\n const lastPoint = getDockingPoint(targetMid, targetBounds, 'l', dockingTarget);\n if (target.isExpanded) {\n lastPoint.y = targetBounds.y + getDefaultSize(target).height / 2;\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n // 4 час\n if (dX > 0 && dY > 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l')\n ];\n }\n\n // 6\n if (dX === 0 && dY > 0) {\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource);\n const lastPoint = getDockingPoint(targetMid, targetBounds, 't', dockingTarget);\n\n if (source.isExpanded || target.isExpanded) {\n return [\n firstPoint,\n { x: sourceMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n lastPoint\n ];\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n // 7 часов\n if (dX < 0 && dY > 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'r')\n ];\n }\n\n // 9 часов\n if (dX < 0 && dY === 0) {\n\n // здесь аналогично вертикали\n // проверяем есть ли в гриде элементы между, если есть, то пускаем в обход - уже не актуально\n const elementsInMiddle = [];\n for (let col = source.gridPosition.col - 1; col > target.gridPosition.col; col--) {\n const candidate = layoutGrid ? layoutGrid.get(source.gridPosition.row, col) : null;\n if (candidate) elementsInMiddle.push(candidate);\n }\n\n // пока так по колхозному\n const hasReversEdge = utilsGetOutgoingElements(target).includes(source);\n\n // TODO: Remove by new edge drawing logic\n let hasSW_NEOut = layoutGrid ? layoutGrid.outgoing.get(target) : [];\n hasSW_NEOut = hasSW_NEOut.some(item => item.direction === 'SW_NE');\n\n if (elementsInMiddle.length > 0 || hasReversEdge || hasSW_NEOut) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: sourceY + (!source.isExpanded ? DEFAULT_CELL_HEIGHT : DEFAULT_CELL_HEIGHT * (source.grid.colCount + 1.5)) },\n { x: targetMid.x, y: sourceY + (!source.isExpanded ? DEFAULT_CELL_HEIGHT : DEFAULT_CELL_HEIGHT * (source.grid.colCount + 1.5)) },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n } else {\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'l', dockingSource);\n if (source.isExpanded) {\n firstPoint.y = sourceBounds.y + getDefaultSize(source).height / 2;\n }\n const lastPoint = getDockingPoint(targetMid, targetBounds, 'r', dockingTarget);\n if (target.isExpanded) {\n lastPoint.y = targetBounds.y + getDefaultSize(target).height / 2;\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n }\n\n // negative dX indicates connection from future to past\n // 10 часов\n if (dX < 0 && dY < 0) {\n\n // колхоз\n const elementsInHorizontal = [];\n for (let col = source.gridPosition.col - 1; col >= target.gridPosition.col; col--) {\n const candidate = layoutGrid ? layoutGrid.get(source.gridPosition.row, col) : null;\n if (candidate) elementsInHorizontal.push(candidate);\n }\n\n if (elementsInHorizontal.length > 0) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n } else {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'l'),\n { x: targetMid.x, y: sourceMid.y },\n getDockingPoint(targetMid, targetBounds, 'b')\n ];\n }\n }\n }\n\n // на будущее если не сработает что-то сверху\n const directManhattan = directManhattanConnect(source, target, layoutGrid);\n\n if (directManhattan) {\n const startPoint = getDockingPoint(sourceMid, sourceBounds, directManhattan[0], dockingSource);\n const endPoint = getDockingPoint(targetMid, targetBounds, directManhattan[1], dockingTarget);\n\n const midPoint = directManhattan[0] === 'h' ? { x: endPoint.x, y: startPoint.y } : { x: startPoint.x, y: endPoint.y };\n\n return [\n startPoint,\n midPoint,\n endPoint\n ];\n }\n const yOffset = -Math.sign(dY) * DEFAULT_CELL_HEIGHT / 2;\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'r', dockingSource),\n { x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y }, // out right\n { x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: targetMid.y + yOffset }, // to target row\n { x: targetMid.x - DEFAULT_CELL_WIDTH / 2, y: targetMid.y + yOffset }, // to target column\n { x: targetMid.x - DEFAULT_CELL_WIDTH / 2, y: targetMid.y }, // to mid\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n}\n\nexport function getMid(bounds) {\n return {\n x: bounds.x + bounds.width / 2,\n y: bounds.y + bounds.height / 2\n };\n}\n\nexport function getDockingPoint(point, rectangle, dockingDirection = 'r', targetOrientation = 'top-left') {\n\n // ensure we end up with a specific docking direction\n // based on the targetOrientation, if <h|v> is being passed\n if (dockingDirection === 'h') {\n dockingDirection = /left/.test(targetOrientation) ? 'l' : 'r';\n }\n\n if (dockingDirection === 'v') {\n dockingDirection = /top/.test(targetOrientation) ? 't' : 'b';\n }\n\n if (dockingDirection === 't') {\n return { original: point, x: point.x, y: rectangle.y };\n }\n\n if (dockingDirection === 'r') {\n return { original: point, x: rectangle.x + rectangle.width, y: point.y };\n }\n\n if (dockingDirection === 'b') {\n return { original: point, x: point.x, y: rectangle.y + rectangle.height };\n }\n\n if (dockingDirection === 'l') {\n return { original: point, x: rectangle.x, y: point.y };\n }\n\n throw new Error('unexpected dockingDirection: <' + dockingDirection + '>');\n}\n\n// helpers /////\nexport function coordinatesToPosition(element, shift = { x: 0, y:0 }) {\n const row = element.gridPosition.row;\n const col = element.gridPosition.col;\n\n return {\n width: DEFAULT_CELL_WIDTH,\n height: DEFAULT_CELL_HEIGHT,\n x: col * DEFAULT_CELL_WIDTH + shift.x,\n y: row * DEFAULT_CELL_HEIGHT + shift.y\n };\n}\n\nexport function getBounds(element, row, col, shift, attachedTo) {\n const { width, height } = getDefaultSize(element);\n const { x, y } = shift;\n\n // Center in cell\n if (!attachedTo) {\n return {\n width, height,\n x: (col * DEFAULT_CELL_WIDTH) + (DEFAULT_CELL_WIDTH - width) / 2 + x,\n y: row * DEFAULT_CELL_HEIGHT + (DEFAULT_CELL_HEIGHT - height) / 2 + y\n };\n }\n\n const hostBounds = attachedTo.di.bounds;\n\n return {\n width, height,\n x: Math.round(hostBounds.x + hostBounds.width / 2 - width / 2),\n y: Math.round(hostBounds.y + hostBounds.height - height / 2)\n };\n}\n\n// TODO: for future\n// eslint-disable-next-line no-unused-vars\nfunction isDirectPathBlocked(source, target, layoutGrid) {\n const { row: sourceRow, col: sourceCol } = source.gridPosition;\n const { row: targetRow, col: targetCol } = target.gridPosition;\n\n const dX = targetCol - sourceCol;\n const dY = targetRow - sourceRow;\n\n let totalElements = 0;\n\n if (dX) {\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, { row: sourceRow, col: targetCol }).length;\n }\n\n if (dY) {\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: targetCol }, { row: targetRow, col: targetCol }).length;\n }\n\n return totalElements > 2;\n}\n\nfunction directManhattanConnect(source, target, layoutGrid) {\n const { row: sourceRow, col: sourceCol } = source.gridPosition;\n const { row: targetRow, col: targetCol } = target.gridPosition;\n\n const dX = targetCol - sourceCol;\n const dY = targetRow - sourceRow;\n\n // Only directly connect left-to-right flow\n if (!(dX > 0 && dY !== 0)) {\n return;\n }\n\n // If below, go down then horizontal\n if (dY > 0) {\n let totalElements = 0;\n const bendPoint = { row: targetRow, col: sourceCol };\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, bendPoint).length;\n totalElements += layoutGrid.getElementsInRange(bendPoint, { row: targetRow, col: targetCol }).length;\n\n return totalElements > 2 ? false : [ 'v', 'h' ];\n } else {\n\n // If above, go horizontal than vertical\n let totalElements = 0;\n const bendPoint = { row: sourceRow, col: targetCol };\n\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, bendPoint).length;\n totalElements += layoutGrid.getElementsInRange(bendPoint, { row: targetRow, col: targetCol }).length;\n\n return totalElements > 2 ? false : [ 'h', 'v' ];\n }\n}\n\nexport function sortElementsTopLeftBottomRight(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n if (aPos && !bPos) return -1;\n if (!aPos && bPos) return 1;\n if (!aPos && !bPos) return 0;\n\n return aPos[0] - bPos[0] || aPos[1] - bPos[1];\n };\n}\n\nexport function sortElementsTopRightBottomLeft(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n if (aPos && !bPos) return -1;\n if (!aPos && bPos) return 1;\n if (!aPos && !bPos) return 0;\n\n return aPos[0] - bPos[0] || bPos[1] - aPos[1];\n };\n}\n\n\nexport function sortElementsTopLeftBottomRightColumn(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n if (aPos && !bPos) return -1;\n if (!aPos && bPos) return 1;\n if (!aPos && !bPos) return 0;\n\n return aPos[1] - bPos[1] || aPos[0] - bPos[0];\n };\n}\n\nexport function sortByType(arr, type) {\n const nonMatching = arr.filter(item => !is(item, type));\n const matching = arr.filter(item => is(item, type));\n\n return [ ...matching, ...nonMatching ];\n}\n\n/**\n *\n * @param {*[]} arr array of elements\n * @param {string[]} types array of types\n * @returns {*[]}\n */\nexport function newSortByType(arr, types) {\n if (types.length === 0) return arr;\n\n let result = [];\n types.forEach((type,index) => {\n const matching = arr.filter(item => is(item, type));\n result = result.concat(matching);\n if (index === types.length - 1 && result.length !== arr.length) {\n for (const item of arr) {\n if (!result.includes(item)) result.push(item);\n }\n };\n });\n\n return result;\n}\n\nfunction getMaxExpandedBetween(source, target, layoutGrid) {\n\n const hostSource = source.attachedToRef ? source.attachedToRef : source;\n const hostTarget = target.attachedToRef ? target.attachedToRef : target;\n\n\n const [ sourceRow, sourceCol ] = layoutGrid.find(hostSource);\n const [ , targetCol ] = layoutGrid.find(hostTarget);\n\n const firstCol = sourceCol < targetCol ? sourceCol : targetCol;\n const lastCol = sourceCol < targetCol ? targetCol : sourceCol;\n\n const elementsInRange = [ ...layoutGrid.elements ]\n .map(item => {\n if (item.size !== undefined) return [ ...item ];\n return item;\n }).flat()\n .filter(element => element.gridPosition.row === sourceRow && element.gridPosition.col > firstCol && element.gridPosition.col < lastCol);\n\n return elementsInRange.reduce((acc, cur) => {\n if (cur.grid?.getGridDimensions()[0] > acc) return cur.grid?.getGridDimensions()[0];\n return acc;\n }, 0);\n}\n","import { assign, map, pick } from 'min-dash';\n\n\nexport class DiFactory {\n constructor(moddle) {\n this.moddle = moddle;\n }\n\n create(type, attrs) {\n return this.moddle.create(type, attrs || {});\n }\n\n createDiBounds(bounds) {\n return this.create('dc:Bounds', bounds);\n }\n\n createDiLabel() {\n return this.create('bpmndi:BPMNLabel', {\n bounds: this.createDiBounds()\n });\n }\n\n createDiShape(semantic, bounds, attrs) {\n return this.create('bpmndi:BPMNShape', assign({\n bpmnElement: semantic,\n bounds: this.createDiBounds(bounds)\n }, attrs));\n }\n\n createDiWaypoints(waypoints) {\n var self = this;\n\n return map(waypoints, function(pos) {\n return self.createDiWaypoint(pos);\n });\n }\n\n createDiWaypoint(point) {\n return this.create('dc:Point', pick(point, [ 'x', 'y' ]));\n }\n\n createDiEdge(semantic, waypoints, attrs) {\n return this.create('bpmndi:BPMNEdge', assign({\n bpmnElement: semantic,\n waypoint: this.createDiWaypoints(waypoints)\n }, attrs));\n }\n\n createDiPlane(attrs) {\n return this.create('bpmndi:BPMNPlane', attrs);\n }\n\n createDiDiagram(attrs) {\n return this.create('bpmndi:BPMNDiagram', attrs);\n }\n}\n","import { default as attacherHandler } from './attachersHandler.js';\nimport { default as elementHandler } from './elementHandler.js';\nimport { default as outgoingHandler } from './outgoingHandler.js';\n\nexport const handlers = [ elementHandler, outgoingHandler, attacherHandler ];","import { is, getDefaultSize } from '../di/DiUtil.js';\nimport { DEFAULT_CELL_HEIGHT, DEFAULT_CELL_WIDTH, getBounds } from '../utils/layoutUtils.js';\n\nexport default {\n 'createElementDi': ({ element, row, col, diFactory, shift }) => {\n if (element.di) return;\n\n if (element.$type === 'bpmn:BoundaryEvent') {\n return createBEl({ element, row, col, diFactory, shift });\n }\n\n const bounds = getBounds(element, row, col, shift);\n\n // Todo: костыль для проверки работоспособности\n if (element.isExpanded && element.grid) {\n const { width, height } = getDefaultSize(element);\n const { rowCount, colCount } = element.grid;\n bounds.width = colCount * DEFAULT_CELL_WIDTH + width;\n bounds.height = rowCount * DEFAULT_CELL_HEIGHT + height;\n }\n\n const options = {\n id: element.id + '_di'\n };\n\n if (element.isExpanded) {\n options.isExpanded = true;\n }\n\n if (is(element, 'bpmn:ExclusiveGateway')) {\n options.isMarkerVisible = true;\n }\n\n const shapeDi = diFactory.createDiShape(element, bounds, options);\n element.di = shapeDi;\n element.gridPosition = { row, col };\n return shapeDi;\n }\n};\n\nfunction createBEl({ element, row, col, diFactory, shift }) {\n const hostBounds = element.attachedToRef.di.bounds;\n if (!hostBounds) throw new Error(`Create DI for ${element.id}. Nо hostBounds`);\n const DIs = [];\n\n // получаем соседние boundary\n const executedElements = element.$parent.flowElements.filter(item => item.attachedToRef === element.attachedToRef);\n\n executedElements.sort((a, b) => {\n const aOutCount = a.outgoing ? a.outgoing.length : 0;\n const bOutCount = b.outgoing ? b.outgoing.length : 0;\n return aOutCount - bOutCount;\n }).forEach((att, i, arr) => {\n att.gridPosition = { row, col };\n const bounds = getBounds(att, row, col, shift, element.attachedToRef);\n\n // distribute along lower edge\n bounds.x = hostBounds.x + (i + 1) * (hostBounds.width / (arr.length + 1)) - bounds.width / 2;\n\n const attacherDi = diFactory.createDiShape(att, bounds, {\n id: att.id + '_di'\n });\n att.di = attacherDi;\n att.gridPosition = { row, col };\n\n DIs.push(attacherDi);\n });\n return DIs;\n}","import {\n connectElements,\n} from '../utils/layoutUtils.js';\n\nexport default {\n 'createConnectionDi': ({ element, row, col, layoutGrid, diFactory, shift }) => {\n const outgoing = (element.outgoing || [])\n .filter(item => layoutGrid.elements.has(item.targetRef));\n\n return outgoing.map(out => {\n const target = out.targetRef;\n const waypoints = connectElements(element, target, layoutGrid, false, shift);\n\n return diFactory.createDiEdge(out, waypoints, {\n id: out.id + '_di'\n });\n });\n }\n};\n\n/**\n *\n * @param {PathSegment} pathSegments\n * @param grid\n * @param {boolean} hasVerticalCross\n * @returns {*[]} Array of Moddle elements\n */\n// TODO: for future\n// eslint-disable-next-line no-unused-vars\nfunction getCrossedElementsByPath(pathSegments, grid, hasVerticalCross) {\n const crossedElements = [];\n for (const segment of pathSegments) {\n const { position: [ row, col ], vCross, hCross } = segment;\n const crossCandidate = grid.get(row, col);\n if (!crossCandidate) continue;\n if ((hasVerticalCross && vCross) || (!hasVerticalCross && hCross)) {\n crossedElements.push(crossCandidate);\n }\n }\n return crossedElements;\n}\n","import {\n DEFAULT_CELL_HEIGHT,\n DEFAULT_CELL_WIDTH,\n connectElements,\n getMid,\n getDockingPoint,\n} from '../utils/layoutUtils.js';\n\n\nexport default {\n 'createConnectionDi': ({ element, row, col, layoutGrid, diFactory, shift }) => {\n const attachers = (element.attachers || []).sort((a, b) => {\n const aOutCount = a.outgoing ? a.outgoing.length : 0;\n const bOutCount = b.outgoing ? b.outgoing.length : 0;\n return aOutCount - bOutCount;\n });\n\n return attachers.flatMap(att => {\n const outgoing = (att.outgoing || [])\n .filter(item => layoutGrid.elements.has(item.targetRef));\n\n return outgoing.map(out => {\n const target = out.targetRef;\n const waypoints = connectElements(att, target, layoutGrid, true, shift);\n\n // Correct waypoints if they don't automatically attach to the bottom\n ensureExitBottom(att, waypoints, [ row, col ]);\n\n return diFactory.createDiEdge(out, waypoints, {\n id: out.id + '_di'\n });\n });\n });\n }\n};\n\nfunction ensureExitBottom(source, waypoints, [ row, col ]) {\n const sourceDi = source.di;\n const sourceBounds = sourceDi.get('bounds');\n const sourceMid = getMid(sourceBounds);\n const dockingPoint = getDockingPoint(sourceMid, sourceBounds, 'b');\n if (waypoints[0].x === dockingPoint.x && waypoints[0].y === dockingPoint.y) {\n return;\n }\n\n const baseSourceGrid = source.grid || source.attachedToRef?.grid;\n\n if (waypoints.length === 2) {\n const newStart = [\n dockingPoint,\n { x: dockingPoint.x, y: !baseSourceGrid ? (row + 1) * DEFAULT_CELL_HEIGHT : (row + baseSourceGrid.getGridDimensions()[0] + 1) * DEFAULT_CELL_HEIGHT },\n { x: !baseSourceGrid ? (col + 1) * DEFAULT_CELL_WIDTH : (col + baseSourceGrid.getGridDimensions()[1] + 1) * DEFAULT_CELL_WIDTH, y: !baseSourceGrid ? (row + 1) * DEFAULT_CELL_HEIGHT : (row + baseSourceGrid.getGridDimensions()[0] + 1) * DEFAULT_CELL_HEIGHT },\n { x: !baseSourceGrid ? (col + 1) * DEFAULT_CELL_WIDTH : (col + baseSourceGrid.getGridDimensions()[1] + 1) * DEFAULT_CELL_WIDTH, y: !baseSourceGrid ? (row + 0.5) * DEFAULT_CELL_HEIGHT : row * DEFAULT_CELL_HEIGHT + DEFAULT_CELL_HEIGHT / 2 },\n ];\n\n waypoints.splice(0, 1, ...newStart);\n return;\n }\n\n // add waypoints to exit bottom and connect to existing path\n const newStart = [\n dockingPoint,\n { x: dockingPoint.x, y: !baseSourceGrid ? (row + 1) * DEFAULT_CELL_HEIGHT : (row + baseSourceGrid.getGridDimensions()[0] + 1) * DEFAULT_CELL_HEIGHT },\n { x: waypoints[1].x, y: !baseSourceGrid ? (row + 1) * DEFAULT_CELL_HEIGHT : (row + baseSourceGrid.getGridDimensions()[0] + 1) * DEFAULT_CELL_HEIGHT },\n ];\n\n waypoints.splice(0, 1, ...newStart);\n}\n","export class Grid {\n constructor() {\n this._grid = [];\n this.isFlipped = false;\n this._elements = new Set();\n }\n\n get rowCount() {\n return this._grid.length;\n }\n\n get elementsCount() {\n return this._elements.size;\n }\n\n get elements() {\n return this._elements;\n }\n\n get colCount() {\n\n // так как грид теперь всегда прямоугольный, то можно позволить\n const firstRow = this._grid[0];\n return firstRow && firstRow.length;\n }\n\n /**\n *\n * @param element\n * @param {[number, number]} position - numbers are integer\n */\n add(element, position) {\n if (!this.isValidPosition(position)) {\n this._addStart(element);\n return;\n }\n\n const [ row, col ] = position;\n\n if (!this._grid[row]) {\n this._grid[row] = [];\n }\n\n // todo: remove to new logic\n if (this._grid[row][col]) {\n\n // throw new Error('Grid is occupied please ensure the place you insert at is not occupied');\n this._grid[row][col].add(element);\n } else {\n this._grid[row][col] = new Set([ element ]);\n }\n\n // this._grid[row][col] = element;\n this.elements.add(element);\n this.toRectangle();\n }\n\n move(element, toPosition) {\n if (!this.elements.has(element)) return;\n if (!this.isValidPosition(toPosition)) return;\n const position = this.find(element);\n if (!this.isValidPosition(position)) return;\n this.removeElementAt(position);\n this.add(element, toPosition);\n }\n\n removeElement(element) {\n if (!element) return;\n if (!this.elements.has(element)) return;\n const position = this.find(element);\n\n // todo: удалять один элемент\n this.removeElementAt(position);\n }\n\n /**\n *\n * @param {number} afterIndex - number is integer\n */\n createRow(afterIndex) {\n if (!afterIndex && !Number.isInteger(afterIndex)) {\n this._grid.push(Array(this.colCount));\n } else {\n this._grid.splice(afterIndex + 1, 0, Array(this.colCount));\n }\n }\n\n /**\n *\n * @param {number} afterIndex - number is integer\n * @param {number=} colCount - number is positive integer\n */\n createCol(afterIndex, colCount) {\n this._grid.forEach((row, rowIndex) => {\n this.expandRow(rowIndex, afterIndex, colCount);\n });\n }\n\n /**\n * @param {number} rowIndex - is positive integer\n * @param {number} afterIndex - is integer\n * @param {number=} colCount - is positive integer\n */\n expandRow(rowIndex, afterIndex, colCount) {\n if (!Number.isInteger(rowIndex) || rowIndex < 0 || rowIndex > this.rowCount - 1) return;\n\n const placeholder = Number.isInteger(colCount) && colCount > 0 ? Array(colCount) : Array(1);\n\n const row = this._grid[rowIndex];\n\n if (!afterIndex && !Number.isInteger(afterIndex)) {\n row.splice(row.length, 0, ...placeholder);\n } else {\n row.splice(afterIndex + 1, 0, ...placeholder);\n }\n }\n\n _addStart(element) {\n this._grid.push([ new Set([ element ]) ]);\n this.elements.add(element);\n }\n\n /**\n * return position of element:\n * - [row: integer, col: integer] if element exist\n * - else undefined\n * @param element\n * @returns {number[] | undefined}\n */\n find(element) {\n let row, col;\n row = this._grid.findIndex(row => {\n col = row.findIndex(el => {\n return el?.has(element);\n });\n\n return col !== -1;\n });\n\n if (this.isValidPosition([ row, col ])) {\n return [ row, col ];\n }\n }\n\n get(row, col) {\n return (this._grid[row] || [])[col];\n }\n\n getElementsInRange({ row: startRow, col: startCol }, { row: endRow, col: endCol }) {\n const elements = [];\n\n if (startRow > endRow) {\n [ startRow, endRow ] = [ endRow, startRow ];\n }\n\n if (startCol > endCol) {\n [ startCol, endCol ] = [ endCol, startCol ];\n }\n\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n const element = this.get(row, col);\n\n if (element) {\n elements.push(element);\n }\n }\n }\n\n return elements;\n }\n\n getGridDimensions() {\n const numRows = this._grid.length;\n let maxCols = 0;\n\n for (let i = 0; i < numRows; i++) {\n const currentRowLength = this._grid[i].length;\n if (currentRowLength > maxCols) {\n maxCols = currentRowLength;\n }\n }\n\n return [ numRows , maxCols ];\n }\n\n // TODO: REMOVE AFTER REFACTORING EDGE DRAWING\n elementsByPosition() {\n const elements = [];\n\n this._grid.forEach((row, rowIndex) => {\n row.forEach((element, colIndex) => {\n if (!element) return;\n for (const el of [ ...element ]) {\n elements.push({\n element:el,\n row: rowIndex,\n col: colIndex\n });\n }\n\n });\n });\n\n return elements;\n }\n\n shrinkCols() {\n\n for (let colIndex = this.colCount - 1 ; colIndex >= 0; colIndex--) {\n const shrinkRequired = this._grid.every(row => row[colIndex] == null);\n if (!shrinkRequired) continue;\n\n for (const row of this._grid) {\n row.splice(colIndex, 1);\n }\n }\n }\n\n shrinkRows() {\n this._grid = this._grid.filter(row => !row.every(col => col == null));\n }\n\n /**\n *\n * @param {[number, number]} position - numbers are integer\n */\n removeElementAt(position) {\n const [ row, col ] = position;\n const element = this.get(row, col);\n if (element) {\n this._grid[row][col] = null;\n this.elements.delete(element);\n }\n }\n\n toRectangle() {\n const [ , colCount ] = this.getGridDimensions();\n this._grid.forEach((row) => {\n if (row.length < colCount) {\n const difference = colCount - row.length;\n for (let i = 0; i < difference; i++) {\n row.splice(row.length, 0, null);\n }\n }\n });\n }\n\n flipHorizontally() {\n for (const row of this._grid) {\n row.reverse();\n }\n this.isFlipped = !this.isFlipped;\n }\n\n hasElement(element) {\n return this.elements.has(element);\n }\n\n isValidPosition(position) {\n if (!position || !Array.isArray(position) || position.length !== 2) return false;\n const [ row, col ] = position;\n return Number.isInteger(row) && Number.isInteger(col) && row >= 0 && col >= 0;\n }\n\n hasIntermediateElements(firstPosition, lastPosition, onVertical) {\n if (!this.isValidPosition(firstPosition) || !this.isValidPosition(lastPosition)) return false;\n if (!onVertical) {\n\n // работаем по горизонтали\n const [ start, end ] = firstPosition[1] <= lastPosition[1] ? [ firstPosition[1] , lastPosition[1] ] : [ lastPosition[1], firstPosition[1] ];\n for (let col = start + 1; col < end; col++) {\n if (!this.hasElementAt([ firstPosition[0], col ])) ;\n return true;\n }\n return false;\n } else {\n\n // работаем по вертикали\n const [ start, end ] = firstPosition[0] <= lastPosition[0] ? [ firstPosition[0] , lastPosition[0] ] : [ lastPosition[0], firstPosition[0] ];\n for (let row = start + 1; row < end; row++) {\n if (!this.hasElementAt([ row, firstPosition[1] ])) continue;\n return true;\n }\n return false;\n }\n }\n\n hasElementAt(position) {\n if (!this.isValidPosition(position)) return false;\n const [ row, col ] = position;\n const element = this.get(row, col);\n return !!element;\n }\n}","export class Edge {\n constructor(originalSource, originalTarget, grid, originalSourceIsBoundary) {\n\n // TODO: упасть с ошибкой если их нет в гриде?\n this._originalSource = originalSource;\n this._originalTarget = originalTarget;\n this._grid = grid;\n this._originalSourceIsBoundary = originalSourceIsBoundary;\n }\n\n get source() {\n return !this._grid.isFlipped ? this._originalSource : this._originalTarget;\n }\n\n get target() {\n return !this._grid.isFlipped ? this._originalTarget : this._originalSource;\n }\n\n get sourcePosition() {\n const source = this.source;\n return this._grid.find(source);\n }\n\n get targetPosition() {\n const target = this.target;\n return this._grid.find(target);\n }\n\n /**\n * Здесь уже НЕ надо использовать реверс, так как работаем с геттерами, которые уже делают расчет по флипу\n * @returns {Direction}\n */\n get direction() {\n return this.getDirection(this.sourcePosition, this.targetPosition);\n }\n\n /**\n * @returns {Array<PathSegment>}\n */\n get path() {\n const direction = this.direction;\n\n if (direction === 'NO_DIRECTION') return this._pathForNoDirection();\n if (direction === 'S_N') return this._pathForSouthToNorth();\n if (direction === 'SW_NE') return this._pathForSouthWestToNorthEast();\n if (direction === 'W_E') return this._pathForWestToEast();\n if (direction === 'NW_SE') return this._pathForNorthWestToSouthEast();\n if (direction === 'N_S') return this._pathForNorthToSouth();\n if (direction === 'NE_SW') return this._pathForNorthEastToSouthWest();\n if (direction === 'E_W') return this._pathForEastToWest();\n if (direction === 'SE_NW') return this._pathForSouthEastToNorthWest();\n return [];\n }\n\n /**\n *\n * @param {Array<PathSegment>} pathSegments\n * @returns {Array<PathSegment>}\n * @private\n */\n _normalizePathCols(pathSegments) {\n if (!this._grid.isFlipped) return pathSegments;\n\n const maxColIndex = this._grid.colCount - 1;\n\n for (const segment of pathSegments) {\n segment.position[1] = maxColIndex - segment.position[1];\n }\n\n return pathSegments;\n }\n\n _pathForNoDirection() {\n return [];\n }\n\n _pathForSouthToNorth() {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ targetRow ] = this.targetPosition;\n\n // если sourceIsBoundary, то сразу идем в обход, так же для реверса\n if (this._originalSourceIsBoundary) return pathSegments;\n\n // TODO: при реверсе флипать сегменты перед отдачей? Need tests!\n // проверяем есть ли элементы между sourcePosition, targetPosition\n // если есть, то ребро пойдет в обход\n // так же оно пойдет в обход если элементы на соседних клетках и есть обратное ребро targetPosition-sourcePosition\n let hasIntermediateElements = this._grid.hasIntermediateElements(this.sourcePosition, this.targetPosition, true);\n\n // идем между ячейками грида\n if (hasIntermediateElements) return pathSegments;\n\n // проверяем петлю source -> target -> source\n const targetElementOutgoingEdges = this._grid.getExistingOutgoingEdgesFor(this.target);\n const targetElementOutgoing = [ ...targetElementOutgoingEdges ].map(edge => edge.target);\n\n // идем в обход если есть ребро в противоположном направлении\n if (targetElementOutgoing.includes(this.source)) return pathSegments;\n\n // в остальных случаях идем прямо\n // TODO: вопрос что с реверсом ПОКА ТАК\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForSouthWestToNorthEast() {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ targetRow, targetCol ] = this.targetPosition;\n\n // если sourceIsBoundary, то пропускаем горизонтальную часть\n if (!this._originalSourceIsBoundary) {\n\n // move right then up\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n }\n\n pathSegments.push({ position: [ sourceRow, targetCol ], hCross: true, vCross: true });\n\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, targetCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForWestToEast() {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ , targetCol ] = this.targetPosition;\n\n // TODO: ПРОБУЕМ ИДТИ ВСЕГДА\n // всегда идем вперед\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthWestToSouthEast() {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ targetRow, targetCol ] = this.targetPosition;\n\n // идем сначала вниз, потом вправо так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n pathSegments.push({ position: [ targetRow, sourceCol ], vCross: true, hCross: true });\n\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ targetRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthToSouth() {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ targetRow ] = this.targetPosition;\n\n // всегда идем вниз так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthEastToSouthWest() {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ targetRow, targetCol ] = this.targetPosition;\n\n // идем вниз потом налево так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n pathSegments.push({ position: [ targetRow, sourceCol ], vCross: true, hCross: true });\n\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ targetRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForEastToWest() {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ , targetCol ] = this.targetPosition;\n\n // TODO: ПРОБУЕМ ИДТИ ВСЕГДА\n // здесь аналогично движению вверх\n // проверяем есть ли элементы между sourcePosition, targetPosition\n // если есть, то ребро пойдет в обход\n // так же оно пойдет в обход если элементы на соседних клетках и есть обратное ребро targetPosition-sourcePosition\n // идем между ячейками грида\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForSouthEastToNorthWest() {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ targetRow, targetCol ] = this.targetPosition;\n\n // для sourceIsBoundary пропускаем горизонталь,\n if (!this._originalSourceIsBoundary) {\n\n // пробуем новую схему для хост-хост без обхода\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n }\n\n // угловой сегмент\n if (!this._originalSourceIsBoundary) {\n pathSegments.push({ position: [ sourceRow, targetCol ], hCross: true, vCross: true });\n } else {\n pathSegments.push({ position: [ sourceRow, targetCol ], vCross: true });\n }\n\n // идем наверх\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, targetCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n /**\n *\n * @param {boolean} byVertical\n */\n crossedElements(byVertical) {\n const crossedElements = [];\n for (const segment of this.path) {\n const [ row, col ] = segment.position;\n const element = this._grid.get(row, col);\n if (element && ((byVertical && segment.vCross) || (!byVertical && segment.hCross))) crossedElements.push(element);\n }\n return crossedElements;\n }\n\n /**\n *\n * @param {boolean} byVertical\n */\n crossedElementsPositions(byVertical) {\n const crossedPositions = [];\n for (const segment of this.path) {\n const [ row, col ] = segment.position;\n const element = this._grid.get(row, col);\n if (element && ((byVertical && segment.vCross) || (!byVertical && segment.hCross))) crossedPositions.push([ row, col ]);\n }\n return crossedPositions;\n }\n\n /**\n * @typedef {('S_N' | 'SW_NE' | 'W_E' | 'NW_SE' | 'N_S' | 'NE_SW' | 'E_W' | 'SE_NW' | 'NO_DIRECTION')} Direction\n * - **S_N** - south to north\n * - **SW_NE** - south-west to north-east\n * - **W_E** - west to east\n * - **NW_SE** - north-west to south-east\n * - **N_S** - north to south\n * - **NE_SW** - north-east to south-west\n * - **E_W** - east to west\n * - **SE_NW** - south-east to north-west\n * - **NO_DIRECTION** - if it's not a vector but a point\n */\n\n /**\n * Return 1 of 8 directions for 'vector' or 'POINT'\n * @param {Position} sourcePosition\n * @param {Position} targetPosition\n * @returns {Direction}\n */\n getDirection(sourcePosition, targetPosition) {\n if (!this._grid.isValidPosition(sourcePosition) || !this._grid.isValidPosition(targetPosition)) return 'NO_DIRECTION';\n\n const [ sourceRow, sourceCol ] = sourcePosition;\n const [ targetRow, targetCol ] = targetPosition;\n\n const vDifference = sourceRow - targetRow;\n const hDifference = sourceCol - targetCol;\n\n // south to north\n if (vDifference > 0 && hDifference === 0) return 'S_N';\n\n // south-west to north-east\n if (vDifference > 0 && hDifference < 0) return 'SW_NE';\n\n // west to east\n if (vDifference === 0 && hDifference < 0) return 'W_E';\n\n // north-west to south-east\n if (vDifference < 0 && hDifference < 0) return 'NW_SE';\n\n // north to south\n if (vDifference < 0 && hDifference === 0) return 'N_S';\n\n // north-east to south-west\n if (sourceRow < targetRow && sourceCol > targetCol) return 'NE_SW';\n\n // east to west\n if (sourceRow === targetRow && sourceCol > targetCol) return 'E_W';\n\n // south-east to north-west\n if (sourceRow > targetRow && sourceCol > targetCol) return 'SE_NW';\n }\n\n isIntersect(position, byVertical) {\n\n // быстрый расчет по направлениям\n const [ row, col ] = position;\n const [ sourceRow, sourceCol ] = this.sourcePosition;\n const [ targetRow, targetCol ] = this.targetPosition;\n const direction = this.direction;\n\n if (direction === 'S_N') {\n if (byVertical && col === sourceCol && row < sourceRow && row > targetRow) return true;\n return false;\n }\n\n if (direction === 'SW_NE') {\n if (byVertical && col === targetCol && row <= sourceRow && row > targetRow) return true;\n if (!byVertical && col > sourceCol && col <= targetCol && row === sourceRow) return true;\n return false;\n }\n\n if (direction === 'W_E') {\n if (!byVertical && col > sourceCol && col < targetCol && row === sourceRow) return true;\n return false;\n }\n\n if (direction === 'NW_SE') {\n if (byVertical && col === sourceCol && row > sourceRow && row <= targetRow) return true;\n if (!byVertical && col >= sourceCol && col < targetCol && row === targetRow) return true;\n return false;\n }\n\n if (direction === 'N_S') {\n if (byVertical && col === sourceCol && row > sourceRow && row < targetRow) return true;\n return false;\n }\n\n if (direction === 'NE_SW') {\n if (byVertical && col === sourceCol && row > sourceRow && row <= targetRow) return true;\n if (!byVertical && col > targetCol && col <= sourceCol && row === targetRow) return true;\n return false;\n }\n\n if (direction === 'E_W') {\n if (!byVertical && col > targetCol && col < sourceCol && row === sourceRow) return true;\n return false;\n }\n\n if (direction === 'SE_NW') {\n\n // todo: все это надо собрать в одном месте\n // а так же если есть входящие в source с направлением NW_SE\n if (byVertical && col === targetCol && row > targetRow && row <= sourceRow) return true;\n if (!byVertical && col >= targetCol && col < sourceCol && row === sourceRow && !this._grid.getExistingIncomingEdgesFor(this.source).some(edge => edge.direction === 'NW_SE')) return true;\n return false;\n }\n\n return false;\n }\n}","import { Grid } from './Grid.js';\nimport { Edge } from './Edge.js';\nimport {\n getOutgoingElements,\n getHostIncoming,\n getAttachedOutgoingElements,\n getBoundaryIncomingHosts,\n} from './utils/elementUtils.js';\n\nimport {\n sortColsLeftRightRowsBottomTop,\n} from './utils/layoutUtils.js';\n\n\n/**\n * @typedef {[number, number]} Position\n * numbers must be integer\n */\n\n/**\n * @typedef {{position: Position, vCross: boolean, hCross: boolean}} PathSegment\n */\n\nexport class GridWithEdges extends Grid {\n constructor() {\n super();\n this._originalOutgoing = new Map();\n this._originalIncoming = new Map();\n }\n\n get incoming() {\n return !this.isFlipped ? this._originalIncoming : this._originalOutgoing;\n }\n\n get outgoing() {\n return !this.isFlipped ? this._originalOutgoing : this._originalIncoming;\n }\n\n /**\n *\n * @param element\n * @param {[number, number]} position - numbers are integer\n */\n add(element, position) {\n super.add(element, position);\n this._createNewEdgesFor(element);\n }\n\n removeElement(element) {\n this._removeEdgesFor(element);\n super.removeElement(element);\n }\n\n move(element, toPosition) {\n this.removeElement(element);\n this.add(element, toPosition);\n }\n\n _removeEdgesFor(element) {\n\n // при удалении элемента надо удалить его ребра, а так же ребра из других вершин где есть эта\n if (!this.hasElement(element)) return;\n\n // удаляем свои ребра\n this._originalOutgoing.delete(element);\n this._originalIncoming.delete(element);\n\n // удаляем из списка исходящих других вершин\n for (const [ keyElement, edges ] of this._originalOutgoing) {\n\n const hasAsTarget = edges.some(edge => edge.target === element);\n if (!hasAsTarget) continue;\n const newEdges = edges.filter(edge => edge.target !== element);\n\n // для оптимизации чтобы не шарашило по всем\n if (newEdges.length === edges.length) continue;\n this._originalOutgoing.set(keyElement, newEdges);\n }\n\n // удаляем из списка входящих других вершин\n for (const [ keyElement, edges ] of this._originalIncoming) {\n const hasAsSource = edges.some(edge => edge.source === element);\n if (!hasAsSource) continue;\n\n const newEdges = edges.filter(edge => edge.source !== element);\n\n // для оптимизации чтобы не шарашило по всем\n if (newEdges.length === edges.length) continue;\n this._originalIncoming.set(keyElement, newEdges);\n }\n }\n\n /**\n * Проверка существования для НОВЫХ ребер\n * Со старыми только через мапу\n * @param edge\n * @returns {*}\n * @private\n */\n _edgeIsExist(edge) {\n const { source, sourcePosition, target, targetPosition } = edge;\n return source && sourcePosition && target && targetPosition;\n }\n\n _addEdgeToGrid(edge) {\n if (!this._edgeIsExist(edge)) return;\n\n if ([ ...this._allEdges ].some(existingEdge => existingEdge.target === edge.target && existingEdge.source === edge.source)) return;\n\n const { _originalSource: source, _originalTarget: target } = edge;\n\n // добавляем в outgoing\n // TODO: Need tests for reverse\n const existingSource = this._originalOutgoing.get(source);\n if (existingSource) {\n existingSource.push(edge);\n } else {\n this._originalOutgoing.set(source, [ edge ]);\n }\n\n // добавляем в incoming\n const existingTarget = this._originalIncoming.get(target);\n if (existingTarget) {\n existingTarget.push(edge);\n } else {\n this._originalIncoming.set(target, [ edge ]);\n }\n }\n\n /**\n *\n * @param element\n * @private\n */\n _createNewEdgesFor(element) {\n\n // получаем исходящие из хоста\n // TODO: сделать сортировку?\n // Работать только по original при вставке\n const outgoingFromHost = getOutgoingElements(element)\n .filter(item => this.hasElement(item));\n for (const outgoing of outgoingFromHost) {\n\n // Ребро должно инициализироваться оригинальными сорс и target\n const edge = new Edge(element, outgoing, this);\n this._addEdgeToGrid(edge);\n }\n\n // получаем исходящие из boundary\n const outgoingFromBoundary = getAttachedOutgoingElements(element)\n .filter(item => this.hasElement(item));\n for (const outgoing of outgoingFromBoundary) {\n const edge = new Edge(element, outgoing, this, true);\n this._addEdgeToGrid(edge);\n }\n\n // входящие из host\n const incomingFromHost = getHostIncoming (element)\n .filter(item => this.hasElement(item));\n for (const incoming of incomingFromHost) {\n const edge = new Edge(incoming, element, this);\n this._addEdgeToGrid(edge);\n }\n\n // входящие из boundary\n const incomingFromBoundaryHost = getBoundaryIncomingHosts (element)\n .filter(item => this.hasElement(item));\n for (const incoming of incomingFromBoundaryHost) {\n const edge = new Edge(incoming,element, this, true);\n this._addEdgeToGrid(edge);\n }\n }\n\n // Возвращает исходящие только из элемента\n getOutgoingFromHost(element) {\n return !this.isFlipped ? new Set(getOutgoingElements(element)) : new Set(getHostIncoming (element));\n }\n\n // Возвращает исходящие только из boundary элемента\n getOutgoingFromBoundary(element) {\n return !this.isFlipped ? new Set (getAttachedOutgoingElements(element)) : new Set();\n }\n\n // Возвращает входящие только в элемент\n getIncomingFromHost(element) {\n return !this.isFlipped ? new Set(getHostIncoming (element)) : new Set(getOutgoingElements(element));\n }\n\n // Возвращает входящие только в boundary\n getIncomingFromBoundaryHost(element) {\n return !this.isFlipped ? new Set (getBoundaryIncomingHosts (element)) : new Set ();\n }\n\n getOutgoingElementsFor(element) {\n if (!element) return [];\n const outgoingFromHost = this.getOutgoingFromHost (element);\n const outgoingFromBoundary = this.getOutgoingFromBoundary (element);\n\n return new Set ([ ...outgoingFromHost, ...outgoingFromBoundary ]);\n }\n\n getIncomingElementsFor(element) {\n if (!element) return [];\n const incomingFromHost = this.getIncomingFromHost (element);\n const incomingFromBoundaryHost = this.getIncomingFromBoundaryHost (element);\n\n return new Set ([ ...incomingFromHost, ...incomingFromBoundaryHost ]);\n }\n\n /** @typedef {[number, number]} Position*/\n\n /**\n * @param {Position} position\n * @param {boolean} byVertical\n * @returns {boolean}\n */\n isCrossed(position, byVertical) {\n\n for (const edge of this._allEdges) {\n\n // быстрый вариант\n if (edge.isIntersect(position, byVertical)) return true;\n }\n }\n\n get _allEdges() {\n return new Set ([ ...this._originalOutgoing.values() ].flat());\n }\n\n /**\n * Экспериментальная функция с херовой производительностью\n * @param grid\n */\n shakeItHorizontal() {\n\n // todo: будет перерабатываться пока отключаем\n const sortedElements = [ ...this.elements ].sort(sortColsLeftRightRowsBottomTop (this)).reverse();\n\n while (sortedElements.length > 0) {\n\n // работаем по первому элементу\n const element = sortedElements.pop();\n\n // получаем вертикальную цепочку\n // удаляем из стека sortedElements все элементы из цепочки\n const verticalChain = this.getVerticalChain(element);\n for (const chainElement of verticalChain) {\n const deleteIndex = sortedElements.indexOf(chainElement);\n if (deleteIndex >= 0) {\n sortedElements.splice(sortedElements.indexOf(chainElement), 1);\n }\n }\n\n // проверяем можно ли двинуть цепочку влево\n // не одна из позиций не должна быть занята или иметь вертикального пересечения\n // - цепочка не должна удлиниться\n const [ , baseCol ] = this.find([ ...verticalChain ][0]);\n const rows = [ ...verticalChain ].map(item => {\n const itemPosition = this.find(item);\n return itemPosition[0];\n });\n\n // двигаться назад не вариант если в цепочка в первой колонке\n if (baseCol <= 0) continue;\n\n for (let col = baseCol - 1; col >= 0; col--) {\n const allPositionsAreFine = rows.every(row => {\n return !this.isCrossed([ row, col ],true) && !this.get(row, col);\n });\n\n if (!allPositionsAreFine) break;\n\n // пробно перемещаем все элементы из цепочки на новые места\n for (const chainElement of verticalChain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, [ chainElementPosition[0], col ]);\n }\n\n // проверяем не образовалось ли новых пересечений пока по старинке\n // TODO: ПРОБУЕМ ПРОВЕРЯТЬ ТОЛЬКО РЕБРА СДВИНУТЫХ\n const hasNewCrosses = this.hasAnyCross();\n const newVerticalChain = this.getVerticalChain(element);\n if (hasNewCrosses || newVerticalChain.size > verticalChain.size) {\n\n // вертаем все элементы взад\n for (const chainElement of verticalChain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, [ chainElementPosition[0], col + 1 ]);\n }\n break;\n }\n }\n\n // в конце каждого прохода шринкаем чтобы не ходить по пустым местам\n this.shrinkCols();\n }\n }\n\n /**\n * Экспериментальная функция с херовой производительностью\n * @param grid\n */\n shakeItVertical() {\n\n // todo: будет перерабатываться пока отключаем\n // const sortedElements = [ ...this.elements ].sort(sortElementsTopRightBottomLeft(this)).reverse();\n //\n // while (sortedElements.length > 0) {\n //\n // // работаем по первому элементу\n // const element = sortedElements.pop();\n //\n // // получаем вертикальную цепочку\n // // удаляем из стека sortedElements все элементы из цепочки\n // const horizontalChain = this.getHorizontalChain(element);\n // for (const chainElement of horizontalChain) {\n // const deleteIndex = sortedElements.indexOf(chainElement);\n // if (deleteIndex >= 0) {\n // sortedElements.splice(deleteIndex, 1);\n // }\n // }\n //\n // // проверяем можно ли двинуть цепочку вверх\n // // не одна из позиций не должна быть занята или иметь вертикального пересечения\n // // - цепочка не должна удлиниться\n // const [ baseRow ] = this.find([ ...horizontalChain ][0]);\n // const cols = [ ...horizontalChain ].map(item => {\n // const itemPosition = this.find(item);\n // return itemPosition[1];\n // });\n //\n // // двигаться вверх не вариант если цепочка в первой строке\n // if (baseRow <= 0) continue;\n //\n // for (let row = baseRow - 1; row >= 0; row--) {\n // const allPositionsAreFine = cols.every(col => {\n // return !this.isCrossed([ [ row, col ] ]) && !this.get(row, col);\n // });\n //\n // if (!allPositionsAreFine) break;\n //\n // // пробно перемещаем все элементы из цепочки на новые места\n // for (const chainElement of horizontalChain) {\n // const chainElementPosition = this.find(chainElement);\n // this.move(chainElement, [ row, chainElementPosition[1] ]);\n // }\n //\n // // проверяем не образовалось ли новых пересечений пока по старинке\n // // и не удлинилась ли цепочка\n // const hasNewCrosses = this.hasAnyCross();\n //\n // const newHorizontalChain = this.getHorizontalChain(element);\n // if (hasNewCrosses || newHorizontalChain.size > horizontalChain.size) {\n //\n // // вертаем все элементы взад\n // for (const chainElement of horizontalChain) {\n // const chainElementPosition = this.find(chainElement);\n // this.move(chainElement, [ row + 1 , chainElementPosition[1] ]);\n // }\n // break;\n // }\n // }\n //\n // // после каждого прохода шринкаем строки чтобы не ходить по пустым местам\n // this.shrinkRows();\n // }\n }\n\n /**\n * Пока так наличие пересечений определим\n * @param {Edge[]=} edges\n * @returns {boolean}\n */\n hasAnyCross(edges) {\n const executedEdges = edges ? edges : this._allEdges;\n\n // перебираем все исходящие ребра\n for (const edge of executedEdges) {\n for (const segment of edge.path) {\n const { position: [ segmentRow, segmentCol ], hCross, vCross } = segment;\n if ((hCross || vCross) && this.get(segmentRow, segmentCol)) return [ segmentRow, segmentCol, edge ];\n }\n }\n\n return false;\n }\n\n getVerticalChain(element, oldChain) {\n\n const chain = !oldChain ? new Set() : oldChain;\n if (!element) return chain;\n\n const elementPosition = this.find(element);\n if (!elementPosition) return chain;\n\n chain.add(element);\n\n const edges = [ ...this.getAllExistingEdgesFor(element) ]\n .filter(edge => edge.direction === 'N_S' || edge.direction === 'S_N');\n\n for (const edge of edges) {\n const nextElement = edge.source === element ? edge.target : edge.source;\n if (!chain.has(nextElement)) {\n const nextChain = this.getVerticalChain(nextElement, chain);\n for (const nextChainEl of nextChain) {\n chain.add(nextChainEl);\n }\n }\n }\n\n return chain;\n }\n\n getHorizontalChain(element, oldChain) {\n const chain = !oldChain ? new Set() : oldChain;\n if (!element) return chain;\n\n const elementPosition = this.find(element);\n if (!elementPosition) return chain;\n\n chain.add(element);\n\n const edges = [ ...this.getAllExistingEdgesFor(element) ]\n .filter(edge => edge.direction === 'W_E' || edge.direction === 'E_W');\n\n for (const edge of edges) {\n const nextElement = edge.source === element ? edge.target : edge.source;\n if (!chain.has(nextElement)) {\n const nextChain = this.getHorizontalChain(nextElement, chain);\n for (const nextChainEl of nextChain) {\n chain.add(nextChainEl);\n }\n }\n }\n return chain;\n }\n\n getExistingOutgoingEdgesFor(element) {\n return this.outgoing.get(element) || [];\n }\n\n getExistingIncomingEdgesFor(element) {\n return this.incoming.get(element) || [];\n }\n\n getAllExistingEdgesFor(element) {\n const outgoingEdges = this.getExistingOutgoingEdgesFor(element);\n const incomingEdges = this.getExistingIncomingEdgesFor(element);\n return new Set([ ...outgoingEdges, ...incomingEdges ]);\n }\n\n getElementsInRow(rowIndex) {\n return new Set (this._grid[rowIndex].filter(element => element != null));\n }\n\n _separateGrid() {\n\n // todo: временно глушим, так как будет другая логика\n // const grids = [];\n //\n // let maxRow = 0;\n // let nextGrid = this._createGridWith(this.rowCount, this.colCount);\n // let nextElements = new Set ();\n //\n // const visited = new Set();\n //\n // if (this.rowCount > maxRow) {\n //\n // const firstElements = this.getElementsInRow(maxRow);\n // nextElements = new Set ([ ...nextElements, ...firstElements ]);\n // }\n //\n //\n //\n // while (nextElements.size > 0) {\n // const nextElement = [ ...nextElements ].pop();\n // const nextElementPosition = this.find(nextElement);\n // if (nextElementPosition[0] > maxRow) maxRow = nextElementPosition[0];\n // nextGrid.add(nextElement, nextElementPosition);\n //\n // visited.add(nextElement);\n // nextElements.delete(nextElement);\n //\n // const allEdges = this.getAllExistingEdgesFor(nextElement);\n //\n // if (allEdges.size === 0 && maxRow < nextElementPosition[0]) {\n // maxRow = nextElementPosition[0];\n // }\n //\n // for (const edge of allEdges) {\n // const { source, target, sourcePosition, targetPosition } = edge;\n // const oppositeElement = source === nextElement ? target : source;\n // const oppositePosition = source === nextElement ? targetPosition : sourcePosition;\n //\n // // do not add self-loop\n // if (oppositeElement !== nextElement && !visited.has(oppositeElement)) {\n //\n // nextElements.add(oppositeElement);\n // if (oppositePosition[0] !== maxRow) {\n //\n // const elementsInRow = this.getElementsInRow(oppositePosition[0]);\n //\n // for (const elementInRow of elementsInRow) {\n // if (!visited.has(elementInRow)) nextElements.add(elementInRow);\n // }\n // }\n //\n // if (oppositePosition[0] > maxRow) maxRow = oppositePosition[0];\n // }\n // }\n //\n // // дошли до конца графа\n // if (nextElements.size === 0) {\n // grids.push(nextGrid);\n // nextGrid = this._createGridWith(this.rowCount, this.colCount);\n //\n // // добавить первый элемент нового графа\n // if (this.rowCount - 1 >= maxRow + 1) {\n // const firstElements = [ ...this.getElementsInRow(maxRow + 1) ].filter(el => !visited.has(el));\n //\n // nextElements = new Set ([ ...nextElements, ...firstElements ]);\n // }\n // }\n // }\n //\n // return grids;\n }\n\n _mergeGrids(grids) {\n const newGrid = new GridWithEdges();\n\n for (const grid of grids) {\n newGrid._grid = newGrid._grid.concat(grid._grid);\n newGrid._elements = new Set([ ...newGrid._elements, ...grid._elements ]);\n newGrid._originalIncoming = new Map ([ ...newGrid._originalIncoming, ...grid._originalIncoming ]);\n newGrid._originalOutgoing = new Map ([ ...newGrid._originalOutgoing, ...grid._originalOutgoing ]);\n }\n\n return newGrid;\n }\n\n getResultGrid() {\n const separated = this._separateGrid();\n\n for (const grid of separated) {\n grid.shrinkCols();\n grid.shrinkRows();\n\n // grid.shakeItHorizontal();\n // grid.shakeItVertical();\n }\n\n const mergedGrid = this._mergeGrids(separated);\n mergedGrid.toRectangle();\n return mergedGrid;\n }\n\n\n _createCrossGrid() {\n\n // создаем заготовку\n const crossGrid = [];\n for (let i = 0 ; i < this.rowCount; i++) {\n crossGrid.push(Array(this.colCount));\n }\n\n // проходим по всем элементам основного грида и записываем в текущий\n for (const element of this._elements) {\n\n // элемент\n const [ elementRow, elementCol ] = this.find(element);\n\n // ребра\n const incoming = this.incoming.get(element) || [];\n const outgoing = this.outgoing.get(element) || [];\n const hasToSouth = [ ...outgoing, ...incoming ].some(edge => {\n const { source, direction } = edge;\n if (source === element && (direction === 'N_S' || direction === 'NW_SE' || direction === 'NE_SW')) return true;\n if (source !== element && (direction === 'S_N' || direction === 'SW_NE' || direction === 'SE_SW')) return true;\n });\n\n for (const edge of outgoing) {\n for (const segment of edge.path) {\n const { position: [ segmentRow, segmentCol ], vCross, hCross } = segment;\n const crossGridElement = crossGrid[segmentRow][segmentCol] || {};\n if (vCross) crossGridElement.vCross = vCross;\n if (hCross) crossGridElement.hCross = hCross;\n crossGrid[segmentRow][segmentCol] = crossGridElement;\n }\n }\n\n // размещаем основную инфу\n crossGrid[elementRow][elementCol] = { ...(crossGrid[elementRow][elementCol] || {}), ...{ element, incoming, outgoing, hasToSouth } };\n }\n\n return crossGrid;\n }\n\n _createGridWith(rowCount, colCount) {\n const crossGrid = new GridWithEdges();\n for (let i = 0 ; i < rowCount; i++) {\n crossGrid._grid.push(Array(colCount));\n }\n return crossGrid;\n }\n}\n","import {\n sortElementsTopLeftBottomRight,\n} from '../utils/layoutUtils.js';\nimport { Graph } from 'graph-by-ivan-tulaev';\n\n\nexport function elementExecution(node, grid, executionSequence, visited, graph) {\n\n // Todo: это условие-костыль убрать его позже (см. добавление в stack)\n if (!node.notMoveForvard) {\n\n // выворачиваем\n // Верхние левые сдвигаем вперед и проверяем пересечения начиная с левого.\n // В идеале сдвигать только если у сдвигаемого элемента и сорса есть общий предок на его линии, чтобы не получился разрыв!\n // Вопрос по поводу переходов на другие линии выше для сорса...\n moveTopLeftOutgoingForward(node, grid, executionSequence, graph, visited);\n }\n node.notMoveForvard = false;\n\n // получаем новые которых нет в гриде\n const newOutgoing = getNewOutgoing(node, graph, visited, grid.isFlipped);\n\n // получаем вершины из стека с удалением их из грида\n // грохнем для теста так как их уже вытянули вперед\n const outgoingFromStack = getOutgoingFromStack(node, grid, executionSequence, newOutgoing && newOutgoing.length > 0, graph, visited);\n\n // Handle outgoing paths without boundaryEvents\n // Maybe later it will merge (Добавить сортировку по типу исходящих?)\n // Todo: поменял местами - boost - норм - надо звезды смотреть\n let outgoing = [ ...newOutgoing, ...outgoingFromStack ];\n\n let nextElements = [];\n let previousElement = null;\n\n outgoing.forEach(nextElement => {\n\n // подготавливаем место\n const nextPosition = getInsertPosition (node, previousElement, grid, nextElement, graph, visited, node.$type === 'bpmn:BoundaryEvent');\n\n // вставляем элемент\n grid.add(nextElement, nextPosition);\n visited.add(nextElement);\n\n fixNewCrosses(nextElement, grid, graph, visited, executionSequence, nextElements, true);\n\n // обновляем previous\n // TODO: Это тоже под удаление. так как будем по ребрам\n previousElement = nextElement;\n\n nextElements.unshift(nextElement);\n });\n\n // TODO: sort by priority\n const nextBoundaries = [];\n const nextOther = [];\n for (const item of nextElements) {\n if (item.$type === 'bpmn:BoundaryEvent') {\n nextBoundaries.push(item);\n } else {\n nextOther.push(item);\n }\n }\n\n nextBoundaries.sort((a, b) => {\n const aOutCount = a.outgoing ? a.outgoing.length : 0;\n const bOutCount = b.outgoing ? b.outgoing.length : 0;\n return aOutCount - bOutCount;\n });\n\n nextElements = [ ...nextBoundaries, ...nextOther ];\n return nextElements;\n}\n\nfunction moveTopLeftOutgoingForward(node, grid, executionSequence, graph, visited) {\n\n // получаем ребра ведущие назад из элемента\n const existingEdges = getExistingOutgoingEdgesFor(node, graph, visited, grid.isFlipped);\n if (!existingEdges || existingEdges.length === 0) return;\n\n const processingElements = existingEdges.filter(edge => {\n const target = !grid.isFlipped ? edge.target : edge.source;\n const source = !grid.isFlipped ? edge.source : edge.target;\n const targetPosition = grid.find(target);\n const sourcePosition = grid.find(source);\n\n if (source === target) return false; // self loop\n if (targetPosition[0] >= sourcePosition[0]) return false; // ниже или на той же строке, что элемент\n if (targetPosition[1] > sourcePosition[1]) return false; // правее чем элемент\n if (inStackWithoutOutgoing(target, graph, executionSequence, visited)) return false;// не двигаем крайние на ветках\n if (isTracingForTopLeftMove(target, source, graph, edge, visited, true)) return false;// не двигаем если таргет трейсится по обратному пути\n return true;\n }).map(item => item.target)\n .sort(sortElementsTopLeftBottomRight(grid));\n\n if (processingElements.length === 0) return;\n\n while (processingElements.length > 0) {\n\n // TODO: подумать над удалением из стека... скорее всего не надо\n const nextElement = processingElements.shift();\n const [ nextElementRow, nextElementCol ] = grid.find(nextElement);\n\n const elementsToDelete = processingElements.filter(item => {\n const [ itemRow ] = grid.find(item);\n return itemRow === nextElementRow;\n });\n\n for (const elementToDelete of elementsToDelete) {\n const deleteIndex = elementsToDelete.indexOf(elementToDelete);\n if (deleteIndex < 0) continue;\n processingElements.splice(deleteIndex, 1);\n }\n\n // сдвигаем строку, а точнее ее и все что выше, чтобы сохранить диагональный рост графа?\n const [ elementRow, elementCol ] = grid.find(node);\n\n const shiftCount = elementCol - nextElementCol + 1;\n\n for (let rowIndex = grid.rowCount - 1; rowIndex >= 0; rowIndex--) {\n if (rowIndex >= elementRow) {\n grid.expandRow(rowIndex, elementCol, shiftCount);\n continue;\n }\n grid.expandRow(rowIndex, nextElementCol - 1, shiftCount);\n }\n\n // устраняем пересечения\n // Проверяем пересечения для всех сдвинутых элементов\n // строки от 0 до nextElementRow включительно\n // колонки от elementCol + 1 включительно до конца строки\n const topLeftPosition = [ 0, elementCol + 1 ];\n const bottomRightPosition = [ grid.rowCount - 1, grid.colCount - 1 ];\n fixCrossesInGridPart (grid, graph, visited, topLeftPosition, bottomRightPosition);\n }\n}\n\nfunction inStackWithoutOutgoing(node, graph, executionSequence, visited, isFlipped) {\n const inStack = executionSequence.includes(node);\n const outgoing = getExistingOutgoingEdgesFor(node, graph, visited, isFlipped);\n\n return inStack && (!outgoing || outgoing.length === 0);\n}\n\nfunction getExistingOutgoingEdgesFor(node, graph, visited, isFlipped) {\n return [ ...(!isFlipped ? graph.getOutgoingEdgesFor(node) : graph.getIncomingEdgesFor(node)) ]\n .filter(edge => visited.has(!isFlipped ? edge.target : edge.source) && visited.has(node));\n}\n\nfunction getExistingIncomingEdgesFor(node, graph, visited, isFlipped) {\n return [ ...(!isFlipped ? graph.getIncomingEdgesFor(node) : graph.getOutgoingEdgesFor(node)) ]\n .filter(edge => visited.has(!isFlipped ? edge.target : edge.source) && visited.has(node));\n}\n\n/**\n * Пробуем делать укороченный проход чтобы не грузить проц - посмотрим как будет рисоваться\n * @param {Element} element\n * @param {Element} fromElement\n * @param {boolean} backward\n */\nfunction isTracingForTopLeftMove(toElement, fromElement, graph, unwantedEdge, visited, backward) {\n\n // не двигаем если таргет трейсится по обратному пути\n // получаем существующий граф\n const existGraph = new Graph();\n for (const node of graph.nodes) {\n if (visited.has(node)) existGraph.addNode(node);\n }\n for (const edge of graph.edges) {\n if (visited.has(edge.target) && visited.has(edge.source)) existGraph.addEdge(edge);\n }\n\n // удаляем ненужное ребро\n existGraph.deleteEdge(unwantedEdge);\n\n return existGraph.isNodeTraced(fromElement, toElement, backward);\n}\n\n/**\n * @param grid\n * @param {[number, number]} topLeftPosition\n * @param {[number, number]} bottomRightPosition\n */\nfunction fixCrossesInGridPart(grid, graph, visited, topLeftPosition, bottomRightPosition) {\n if (!grid.isValidPosition(topLeftPosition) || !grid.isValidPosition(bottomRightPosition)) throw new Error('fixCrossesInGridPart: invalid position');\n\n const [ topLeftRow, topLeftCol ] = topLeftPosition;\n const [ bottomRightRow, bottomRightCol ] = bottomRightPosition;\n\n for (let rowIndex = topLeftRow; rowIndex <= bottomRightRow; rowIndex++) {\n for (let colIndex = topLeftCol; colIndex <= bottomRightCol; colIndex++) {\n const element = grid.get(rowIndex, colIndex);\n if (!element) continue;\n fixNewCrosses(element, grid, graph, visited);\n }\n }\n}\n\n// TODO: Не стек, а крайние\nfunction getNewOutgoing(node, graph, visited, isFlipped) {\n\n // элементы\n // добавить сортировку по кол-ву исходящих?\n if (isFlipped) {\n\n const outgoing = [ ...graph.getOutgoingEdgesFor(node) ].filter(edge =>!visited.has(edge.target) && edge.target.$type === 'bpmn:BoundaryEvent');\n if (outgoing.length > 0) {\n return [ ...graph.getIncomingEdgesFor(node) ]\n .filter(edge => !visited.has(edge.source)).concat(outgoing).map(edge => {\n if (edge.target !== node) return edge.target;\n return edge.source;\n });\n }\n\n return [ ...graph.getIncomingEdgesFor(node) ]\n .filter(edge => !visited.has(edge.source))\n .map(edge => {\n if (edge.source.$type === 'bpmn:BoundaryEvent') return edge.source.attachedToRef;\n return edge.source;\n });\n }\n\n // todo: возможно добавить сортировку как изначально\n return [ ...graph.getOutgoingEdgesFor(node) ]\n .filter(edge => !visited.has(edge.target))\n .map(edge => edge.target);\n}\n\n\n/**\n * - Выдергивает исходящие элементы из стека обработки\n * - Так же удаляет их из графа\n * - Для дальнейшей обработки воспринимаем их как абсолютно новые вершины\n * @param element - элемент для которого ищем исходящие\n * @param grid\n * @param {Array<Element>}stack\n * @returns {any[]} - массив элементов\n */\nfunction getOutgoingFromStack(node, grid, executionSequence, hasNewOutgoings, graph, visited) {\n\n // получаем все исходящие базового элемента\n // const outgoing = grid.getExistingOutgoingEdgesFor(node);\n const outgoing = getExistingOutgoingEdgesFor(node, graph, visited, grid.isFlipped);\n const incoming = getExistingIncomingEdgesFor(node, graph, visited, grid.isFlipped).map(edge => edge.source);\n\n const [ , elementCol ] = grid.find(node);\n const processingElements = [ ...outgoing ].filter(edge => {\n\n // оставляем только те, что идут в стек и не имеют исходящих\n const target = !grid.isFlipped ? edge.target : edge.source;\n const targetCol = grid.find(target)[1];\n\n if (!inStackWithoutOutgoing(target, graph, executionSequence, visited, grid.isFlipped)) return false;\n\n\n // исключаем если общий родитель, так как уже расставили их правильно\n // пробуем нет входящих кроме element\n // если есть общий родитель и есть новые исходящие то выкидываем\n const targetIncoming = getExistingIncomingEdgesFor(target, graph, visited, grid.isFlipped)\n .map(targetEdge => targetEdge.source);\n\n const commonParent = targetIncoming.find(targetParent => incoming.includes(targetParent));\n if (commonParent && hasNewOutgoings) return false;\n\n // пробуем оставлять только те, что слева\n return targetCol <= elementCol;\n }).map(item => !grid.isFlipped ? item.target : item.source).sort(sortElementsTopLeftBottomRight (grid));\n\n // Обрабатываем элементы.\n // Удаляем их из стека и из грида\n for (const processingElement of processingElements) {\n executionSequence.splice(executionSequence.indexOf(processingElement), 1);\n visited.delete(processingElement);\n grid.removeElement(processingElement);\n }\n\n // после удаления из грида удаляем лишние колонки\n grid.shrinkRows();\n grid.shrinkCols();\n\n // обрабатываем их как новые исходящие\n return processingElements;\n}\n\nfunction getInsertPosition(element, previousElement, grid, nextEl, graph, visited, isBoundarySource) {\n\n if (nextEl.$type === 'bpmn:BoundaryEvent') return grid.find(element);\n\n const sourcePosition = grid.find(element);\n if (!sourcePosition) return;\n\n // по умолчанию располагаем справа от element или по диагонали\n const position = !isBoundarySource ? [ sourcePosition[0],sourcePosition[1] + 1 ] : [ sourcePosition[0] + 1,sourcePosition[1] + 1 ];\n\n // ищем первую дырку между ребрами источника\n const elPos = grid.find(element);\n const allItemsInElementPosition = [ ...grid.get(elPos[0], elPos[1]) ];\n const elementPositionEdges = [];\n for (const item of allItemsInElementPosition) {\n [ ...grid.getExistingOutgoingEdgesFor(item) ]\n .filter(edge => edge.target !== edge.source && visited.has(edge.source) && visited.has(edge.target))\n .forEach(edge => elementPositionEdges.push(edge));\n }\n\n // проверяем вертикаль вниз от позиции\n for (let i = position[0]; i <= grid.rowCount; i++) {\n const point = [ i, position[1] ];\n const crossedOrOccupied = elementPositionEdges.some(edge => {\n return (edge.targetPosition[0] === i && edge.targetPosition[1] === position[1]) || edge.isIntersect(point);\n });\n\n if (crossedOrOccupied && i === grid.colCount - 1) {\n position[0] = i + 1;\n continue;\n }\n\n if (crossedOrOccupied) continue;\n position[0] = i;\n break;\n }\n\n // обрабатываем занятость и вертикальные пересечения\n if (grid.get(position[0], position[1]) || grid.isCrossed(position, true)) {\n grid.createCol(position[1] - 1);\n }\n\n if (grid.isCrossed([ position[0], position[1] ])) {\n\n // todo: возможно стоит посмотреть по направлениям\n grid.createRow(position[0] - 1);\n }\n return position;\n}\n\n// только для тех что впереди\n/**\n * @param element\n * @param grid\n * @param {[Element]=} stack\n * @param {[Element]=} nextElements\n * @param {boolean} skipTopLeftOutgoing\n * @param {boolean} forwardOnlyOutgoing\n */\nfunction fixNewCrosses(element, grid, graph, visited, stack, nextElements, skipTopLeftOutgoing, forwardOnlyOutgoing) {\n\n // реверс логики переноса вперед для исходящих\n // исправляем пересечения образованные исходящими и входящими ребрами новой вершины\n // получаем исходящие\n const outgoingEdges = [ ...grid.getExistingOutgoingEdgesFor(element) ]\n .sort((a, b) => {\n const [ aRow, aCol ] = a.targetPosition;\n const [ bRow, bCol ] = b.targetPosition;\n return aRow - bRow || aCol - bCol;\n });\n const incomingEdges = [ ...grid.getExistingIncomingEdgesFor(element) ]\n .sort((a, b) => {\n const [ aRow, aCol ] = a.sourcePosition;\n const [ bRow, bCol ] = b.sourcePosition;\n return aRow - bRow || aCol - bCol;\n });\n\n const edges = [ ...outgoingEdges, ...incomingEdges ]\n .filter(edge => {\n const { target, source, direction } = edge;\n\n // не обрабатываем следующие случаи\n // если self loop\n if (target === source) return false;\n\n // если в обработке текущей очереди исходящих\n if (nextElements && nextElements.includes(target)) return false;\n\n // если таргет в стеке и у него нет существующих исходящих если передали стек\n if (stack) {\n\n if (inStackWithoutOutgoing(target, graph, stack, visited)) return false;\n }\n if (skipTopLeftOutgoing) {\n\n // TODO: Пока непонятно надо ли как то обрабатывать стек?\n if (source === element && (direction === 'SE_NW' || direction === 'S_N')) return false;\n }\n\n return true;\n });\n\n for (const edge of edges) {\n\n // исправляем вертикали\n fixNewVerticalCrosses(edge, grid);\n\n // не исправляем гризонтали если E_W из boundary\n if (edge.direction === 'E_W' && edge._originalSourceIsBoundary) continue;\n fixNewHorizontalCrosses(edge, grid);\n }\n}\n\n// TODO: Add tests for boundary edges\nfunction fixNewVerticalCrosses(edge, grid) {\n\n // заготовка по направлениям\n // S_N - нет, так как не предполагается схемой\n // SW_NE\n // W_E - нет вертикали\n // NW_SE\n // N_S\n // NE_SW\n // E_W - нет вертикали\n // SE_NW\n\n const { direction } = edge;\n\n if (direction === 'W_E' || direction === 'E_W') return;\n\n const vCrossed = edge.crossedElements(true);\n\n if (vCrossed.length <= 0) return;\n\n if (direction === 'S_N') {\n moveElementsRighterCrossLine(vCrossed, grid);\n return;\n }\n\n if (direction === 'SW_NE') {\n\n // требуется дополнительное условие?\n // пока сдвигаем вертикаль\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'NW_SE') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'N_S') {\n moveElementsRighterCrossLine(vCrossed, grid);\n return;\n }\n\n if (direction === 'NE_SW') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'SE_NW') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n}\n\n// TODO: Add tests for boundary edges\n// возможно добавить потом наличие ребер\nfunction fixNewHorizontalCrosses(edge, grid) {\n\n // заготовка по направлениям\n const { direction } = edge;\n\n // по этим направлениям не предполагается горизонтальных пересечений\n if (direction === 'S_N' || direction === 'N_S') return;\n\n const hCrossed = edge.crossedElements(false);\n\n if (hCrossed.length === 0) return;\n\n if (direction === 'SW_NE') {\n\n // поднимаем элементы выше пересечения\n const maxDown = getMaxDown(edge);\n const [ baseSourceRow ] = edge.sourcePosition;\n\n for (let i = maxDown; i > 0; i--) {\n grid.createRow(baseSourceRow - 1);\n }\n\n const elements = edge._grid.getElementsInRange({ row: edge.sourcePosition[0], col: edge.sourcePosition[1] + 1 }, { row: edge._grid.rowCount - 1, col: edge._grid.colCount - 1 });\n\n for (const element of elements) {\n const [ row, col ] = edge._grid.find([ ...element ][0]);\n for (const innerElement of [ ...element ]) {\n edge._grid.move(innerElement, [ row - maxDown, col ]);\n }\n }\n return;\n }\n\n if (direction === 'W_E') {\n\n // опускаем элементы\n moveElementsUnderCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'NW_SE') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'NE_SW') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'E_W') {\n\n // опускаем элементы\n moveElementsUnderCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'SE_NW') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n}\n\nfunction moveElementsUpperCrossLine(elements, grid) {\n\n // пробуем поднимать элементы выше пересечения\n const [ row ] = grid.find([ ...elements[0] ][0]);\n grid.createRow(row - 1);\n for (const element of elements) {\n const [ , col ] = grid.find([ ...element ][0]);\n for (const innerElement of [ ...element ]) {\n grid.move(innerElement, [ row , col ]);\n }\n }\n}\n\nfunction moveElementsUnderCrossLine(elements, grid) {\n\n // пробуем опускать элементы ниже пересечения\n const [ row ] = grid.find([ ...elements[0] ][0]);\n grid.createRow(row);\n for (const element of elements) {\n const [ , col ] = grid.find([ ...element ][0]);\n for (const innerItem of [ ...element ]) {\n grid.move(innerItem, [ row + 1 , col ]);\n }\n }\n}\n\n// TODO: проверить\nfunction moveElementsRighterCrossLine(elements, grid) {\n\n // TODO: костыльчик чтобы запустилось\n const [ , col ] = grid.find([ ...elements[0] ][0]);\n grid.createCol(col);\n\n for (const element of elements) {\n const [ row ] = grid.find([ ...element ][0]);\n for (const innerItem of [ ...element ]) {\n grid.move(innerItem, [ row, col + 1 ]);\n }\n }\n}\n\n/**\n * All crossed on one column\n * @param elements\n * @param grid\n */\nfunction pushVerticalEdgeBy(elements, grid) {\n const [ , col ] = grid.find([ ...elements[0] ][0]);\n grid.createCol(col - 1);\n\n for (const element of elements) {\n const [ row ] = grid.find([ ...element ][0]);\n for (const innerItem of [ ...element ]) {\n grid.move(innerItem, [ row, col ]);\n }\n }\n}\n\n// Todo: сделать для всех направлений, а не только для SW_NE и сделать методы в гриде\nfunction getMaxDown(edge) {\n const sourcePosition = edge.sourcePosition;\n const targetPosition = edge.targetPosition;\n\n let maxDown = sourcePosition[0];\n\n for (let rowIndex = sourcePosition[0]; rowIndex < edge._grid.rowCount; rowIndex++) {\n if (edge._grid.getElementsInRange({ row: rowIndex, col: sourcePosition[1] + 1 }, { row: rowIndex, col: targetPosition[1] }).length > 0) {\n maxDown++;\n } else {\n break;\n }\n }\n\n return maxDown - sourcePosition[0];\n}\n","import BPMNModdle from 'bpmn-moddle';\nimport {\n isStartIntermediate,\n setExpandedProcesses, getAllProcesses,\n} from './utils/elementUtils.js';\n\nimport {\n DEFAULT_CELL_HEIGHT,\n DEFAULT_CELL_WIDTH,\n DEFAULT_POOL_MARGIN,\n sortByType,\n} from './utils/layoutUtils.js';\nimport { DiFactory } from './di/DiFactory.js';\nimport { is, getDefaultSize } from './di/DiUtil.js';\nimport { handlers } from './handler/index.js';\nimport { isFunction } from 'min-dash';\nimport { GridWithEdges } from './GridWithEdges.js';\nimport { addToEnd, getLast, Graph } from 'graph-by-ivan-tulaev';\nimport { elementExecution } from './newHandlers/outgoingHandler';\n\n\n/**\n * @typedef {Object} BPMNElement\n * @property {boolean} isExpanded - is expanded or collapsed\n * @property {Array<BPMNElement>} attachers - prop for host element\n */\n\n\nexport class Layouter {\n constructor(debuggerCounter) {\n this.moddle = new BPMNModdle();\n this.diFactory = new DiFactory(this.moddle);\n this._handlers = handlers;\n this.maxDebugStep = debuggerCounter;\n this.currentDebugStep = 0;\n\n }\n\n async layoutProcess(xml) {\n const moddleObj = await this.moddle.fromXML(xml);\n\n const { rootElement } = moddleObj;\n\n // init important properties\n this.diagram = rootElement;\n\n setExpandedProcesses(moddleObj);\n\n // init process trees as nested sets\n // add nested set properties to process (left, right, level)\n this.processTrees = this.createNestedSets(moddleObj);\n\n // create and add grids for each process\n // root processes should be processed last for element expanding\n this.createGridsForProcesses();\n\n // get all process from root\n const rootProcesses = this.getRootProcesses();\n const collaboration = this.getCollaboration();\n\n if (rootProcesses.length > 0) {\n this.cleanDi();\n this.createRootDi(rootProcesses, collaboration);\n this.drawParticipants();\n this.drawProcesses();\n this.drawCollaborationMessageFlows(collaboration);\n }\n\n return (await this.moddle.toXML(this.diagram, { format: true })).xml;\n }\n\n handle(operation, options) {\n return this._handlers\n .filter(handler => isFunction(handler[operation]))\n .map(handler => handler[operation](options));\n }\n\n createGridsForProcesses() {\n\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => b.level - a.level);\n\n // create and add grids for each process\n // root processes should be processed last for element expanding\n for (const process of processes) {\n\n // add base grid with collapsed elements\n process.grid = this.createGridLayout(process);\n\n // separate base grid to independent grids\n const tempGridCollection = process.grid._separateGrid() || [ process.grid ];\n\n // for each independent grid:\n // - remove empty rows and cols\n // - shake elements by vertical and horizontal\n for (const grid of tempGridCollection) {\n grid.shrinkRows();\n grid.shrinkCols();\n\n // todo: будет перерабатываться пока отключаем\n // grid.shakeItVertical();\n // grid.shakeItHorizontal();\n grid.shrinkRows();\n grid.shrinkCols();\n grid.toRectangle();\n\n expandGridHorizontally(grid);\n expandGridVertically(grid);\n }\n\n // merge separated grids and set new grid to the process\n process.grid = process.grid._mergeGrids(tempGridCollection);\n process.grid.toRectangle();\n\n if (process.isExpanded) {\n const { colCount, rowCount } = process.grid;\n if (rowCount === 0) process.grid.createRow();\n if (colCount == 0) process.grid.createCol();\n }\n }\n }\n\n /**\n * draw participants pools at root\n */\n drawParticipants() {\n const collaboration = this.getCollaboration();\n\n if (!collaboration || !collaboration[0]) return;\n const participants = collaboration[0].participants;\n\n const x = 0;\n let y = 0;\n\n for (const participant of participants) {\n y = this.createParticipantDi(participant, { x, y }) + DEFAULT_POOL_MARGIN;\n }\n }\n\n /**\n * Draw processes.\n * Root processes should be processed first for element expanding\n */\n drawProcesses() {\n\n for (const procTree of this.processTrees) {\n const sortedProcesses = procTree.nodes.sort((a, b) => a.level - b.level);\n\n for (const process of sortedProcesses) {\n\n // draw root processes in participants\n const participant = this.getParticipantForProcess(process);\n\n if (participant) {\n const participantDi = this.getElementDi(participant);\n const diagram = this.getProcDi(participantDi);\n\n let { x, y } = participantDi.bounds;\n x += DEFAULT_CELL_WIDTH / 2;\n y += DEFAULT_CELL_HEIGHT / 2;\n this.generateDi(process.grid, { x, y }, diagram);\n continue;\n }\n\n // draw processes in expanded elements\n if (process.isExpanded) {\n const baseProcDi = this.getElementDi(process);\n const diagram = this.getProcDi(baseProcDi);\n let { x, y } = baseProcDi.bounds;\n const { width, height } = getDefaultSize(process);\n x += DEFAULT_CELL_WIDTH / 2 - width / 4;\n y += DEFAULT_CELL_HEIGHT - height - height / 4;\n this.generateDi(process.grid, { x, y }, diagram);\n continue;\n }\n\n // draw other processes\n const diagram = this.diagram.diagrams.find(diagram => diagram.plane.bpmnElement === process);\n this.generateDi(process.grid, { x: 0, y: 0 }, diagram);\n }\n }\n }\n\n drawCollaborationMessageFlows(collaboration) {\n const messageFlows = collaboration[0] ? collaboration[0].messageFlows : null;\n if (messageFlows) {\n for (const message of messageFlows) {\n const { sourceRef, targetRef } = message;\n const sourceBounds = sourceRef.di.bounds;\n const targetBounds = targetRef.di.bounds;\n const dY = targetBounds.y - sourceBounds.y;\n const waypoints = [\n { x: sourceBounds.x + sourceBounds.width / 2 },\n { x: targetBounds.x + targetBounds.width / 2 }\n ];\n\n if (dY > 0) {\n waypoints[0].y = sourceBounds.y + sourceBounds.height;\n waypoints[1].y = targetBounds.y;\n } else {\n waypoints[0].y = sourceBounds.y;\n waypoints[1].y = targetBounds.y + targetBounds.height;\n }\n\n const edge = this.diFactory.createDiEdge(message, waypoints);\n this.diagram.diagrams[0].plane.get('planeElement').push(edge);\n }\n }\n }\n\n getParticipantForProcess(process) {\n const collaboration = this.getCollaboration();\n if (!collaboration || !collaboration[0]) return;\n const participants = this.getCollaboration()[0].participants;\n\n if (!participants) return;\n\n return participants.find(participant => participant.processRef === process);\n }\n\n getElementDi(element) {\n return this.diagram.diagrams\n .map(diagram => diagram.plane.planeElement).flat()\n .find(item => item.bpmnElement === element);\n }\n\n getProcDi(element) {\n return this.diagram.diagrams.find(diagram => diagram.plane.planeElement.includes(element));\n }\n\n createNestedSets(bpmnModel) {\n const processGraph = new Graph();\n const allProcesses = getAllProcesses(bpmnModel);\n\n // add nodes to graph\n for (const process of allProcesses) {\n processGraph.addNode(process);\n }\n\n // add edges\n for (const process of allProcesses) {\n const children = this.getSubProcesses(process);\n for (const child of children) {\n processGraph.addEdge({ source: process, target: child });\n }\n }\n\n const separatedGraphs = processGraph.getSeparatedGraphs();\n\n // set root process to tree\n for (const graph of separatedGraphs) {\n const rootProcesses = graph.nodes.filter(node => graph.getIncomingEdgesFor(node).size === 0);\n\n // must have 1 root process\n if (rootProcesses.length > 1) throw new Error('Process tree has more than 1 root elements');\n if (rootProcesses.length === 0) throw new Error('Process tree has more than 0 root elements');\n\n graph.rootProcess = rootProcesses[0];\n }\n\n // set nested sets attributes\n for (const graph of separatedGraphs) {\n\n // callback that get start node from process tree\n // it's root process\n const getStartElement = (visited, initialGraph) => {\n const root = initialGraph.rootProcess;\n\n root.left = 0;\n root.level = 0;\n\n return root;\n };\n\n // callback that get next executed nodes\n // it's first node without left prop if we go from root,\n // or without right prop if we go to root\n const getNextNodes = (node, graph, visited) => {\n\n const { left, level } = node;\n\n // get first node without left prop\n const outgoingNode = [ ...graph.getOutgoingEdgesFor(node) ]\n .map(edge => edge.target)\n .find(node => node.left === undefined);\n\n if (outgoingNode) {\n outgoingNode.level = level + 1;\n outgoingNode.left = left + 1;\n return [ outgoingNode ];\n }\n\n // if no outgoingNode get max right\n const maxRight = [ ...graph.getOutgoingEdgesFor(node) ]\n .map(edge => edge.target)\n .reduce((prev, cur) => {\n if (prev === undefined || cur.right > prev.right) return cur.right;\n } , undefined);\n\n if (maxRight) {\n node.right = maxRight + 1;\n } else {\n node.right = node.left + 1;\n }\n\n // get incoming\n const incoming = [ ...graph.getIncomingEdgesFor(node) ]\n .map(edge => edge.source)\n .find(node => node.right === undefined);\n\n if (incoming) return [ incoming ];\n };\n graph.genericTraversing(getStartElement, getLast, getNextNodes, addToEnd);\n }\n\n return separatedGraphs;\n }\n\n getSubProcesses(processes) {\n return processes.flowElements ? processes.flowElements.filter(process => process.$type === 'bpmn:SubProcess') : [];\n }\n\n createRootDi(processes, collaboration) {\n\n const mainElement = collaboration && collaboration.length > 0 ? collaboration[0] : processes[0];\n this.createProcessDi(mainElement);\n }\n\n createProcessDi(element) {\n const diFactory = this.diFactory;\n\n const planeDi = diFactory.createDiPlane({\n id: 'BPMNPlane_' + element.id,\n bpmnElement: element\n });\n const diagramDi = diFactory.createDiDiagram({\n id: 'BPMNDiagram_' + element.id,\n plane: planeDi\n });\n\n const diagram = this.diagram;\n\n diagram.diagrams.push(diagramDi);\n\n return diagramDi;\n }\n\n /**\n * Create participant diagram\n * @param participant\n * @param {{x: number, y: number}} origin\n * @returns {number} bottom Y coordinate of created shape\n */\n createParticipantDi(participant, origin) {\n\n // get size of child process element\n const { colCount, rowCount } = participant.processRef.grid;\n\n const { width: defaultWidth, height: defaultHeight } = getDefaultSize(participant);\n\n // Result size is children grid size + paddings ( 1/2 of width or height)\n const width = colCount > 0 ? colCount * DEFAULT_CELL_WIDTH + DEFAULT_CELL_WIDTH : defaultWidth;\n const height = rowCount > 0 ? rowCount * DEFAULT_CELL_HEIGHT + DEFAULT_CELL_HEIGHT : defaultHeight;\n\n const participantDi = this.diFactory.createDiShape(participant, { width, height, ...origin }, { id: participant.id + '_di' });\n\n const planeDi = this.diagram.diagrams[0].plane.get('planeElement');\n\n planeDi.push(...[ participantDi ]);\n\n return participantDi.bounds.y + participantDi.bounds.height;\n }\n\n cleanDi() {\n this.diagram.diagrams = [];\n }\n\n createGridLayout(process) {\n const grid = new GridWithEdges();\n\n // create graph from elements\n const processGraph = new Graph();\n\n // add nodes\n for (const flowElement of process.flowElements || []) {\n\n if (!is(flowElement,'bpmn:SequenceFlow') && !is(flowElement,'bpmn:DataObject')) {\n processGraph.addNode(flowElement);\n }\n }\n\n // add edges\n for (const node of processGraph.nodes) {\n\n // sequenceFlow\n for (const outgoingItem of node.outgoing || []) {\n processGraph.addEdge({ source:outgoingItem.sourceRef, target:outgoingItem.targetRef });\n }\n\n // attachers\n const attachedToRef = node.attachedToRef;\n if (attachedToRef) {\n processGraph.addEdge({ source:attachedToRef, target:node });\n }\n\n // data associations\n const dataInputAssociations = node.dataInputAssociations;\n for (const dataInputAssociationsItem of dataInputAssociations || []) {\n const source = dataInputAssociationsItem.sourceRef[0];\n const target = dataInputAssociationsItem.$parent;\n processGraph.addEdge({ source, target });\n }\n\n const dataOutputAssociations = node.dataOutputAssociations;\n for (const dataOutputAssociationsItem of dataOutputAssociations || []) {\n const source = dataOutputAssociationsItem.$parent;\n const target = dataOutputAssociationsItem.targetRef;\n processGraph.addEdge({ source, target });\n }\n }\n\n // export type GetStartElementFunction<N> = (visited: Set<N>, initialGraph: Graph<N>)\n const dfsGetStartElement = (visited, initialGraph) => {\n if (this.maxDebugStep !== undefined && this.maxDebugStep <= this.currentDebugStep) return;\n\n // get elements in the grid that have incoming that are not in grid\n // const targetElementsInGrid = getTargetElementInGridSourceNotExist (grid);\n const targetElementInGridSourceNotExist = [ ...visited ].find(node => {\n if (grid.isFlipped) {\n return [ ...initialGraph.getOutgoingEdgesFor(node) ].filter(edge => !visited.has(edge.target)).length > 0;\n }\n return [ ...initialGraph.getIncomingEdgesFor(node) ].filter(edge => !visited.has(edge.source)).length > 0;\n });\n if (targetElementInGridSourceNotExist) {\n\n // todo: !!! добавить grid.flipHorizontally();\n grid.flipHorizontally();\n return targetElementInGridSourceNotExist;\n }\n\n // maybe need boundaryEvents processing here\n // const primaryStartElements = getPrimaryStartElements(hostElements, grid);\n const primaryStartElements = initialGraph.nodes.filter(node => {\n if (grid.isFlipped) {\n return !visited.has(node) && initialGraph.getOutgoingEdgesFor(node).size === 0 && !isStartIntermediate(node);\n }\n return !visited.has(node) && initialGraph.getIncomingEdgesFor(node).size === 0 && !isStartIntermediate(node);\n });\n if (primaryStartElements.length > 0) return sortByType(primaryStartElements, 'bpmn:StartEvent')[0];\n\n // const sourceElementsInGrid = getSourceElementInGridTargetNotExist(grid);\n const sourceElementInGridTargetNotExist = [ ...visited ].find(node => {\n const outgoing = !grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ].filter(edge => !visited.has(edge.target))\n : [ ...initialGraph.getIncomingEdgesFor(node) ].filter(edge => !visited.has(edge.source));\n\n // todo: !!! добавить сортировку sortElementsTopLeftBottomRight и костыль topLeftElement.notMoveForvard = true\n return outgoing.length > 0;\n });\n if (sourceElementInGridTargetNotExist) return sourceElementInGridTargetNotExist;\n\n // All elements without incoming from other elements\n // this case as the very last one\n // const otherStartingElements = getOtherStartElements (hostElements, grid);\n const otherStartingElement = initialGraph.nodes.find(node => {\n if (visited.has(node)) return false;\n\n // incoming without Loops\n const incoming = !grid.isFlipped ? [ ...initialGraph.getIncomingEdgesFor(node) ].filter(edge => edge.source !== node) : [ ...initialGraph.getOutgoingEdgesFor(node) ].filter(edge => edge.target !== node);\n return incoming.length === 0;\n });\n if (otherStartingElement) return otherStartingElement;\n\n // const flippedStartElements = getFlippedStartElements(hostElements, grid);\n const flippedStartElement = initialGraph.nodes.find(node => {\n\n if (visited.has(node)) return false;\n\n //\n // if ((!grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ]).some(edge => !grid.isFlipped ? edge.target === node : edge.source === node)) return false;\n //\n // if ((!grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ])\n // .some(edge => (!grid.isFlipped ? edge.target.attachedToRef === node : edge.source.attachedToRef === node) && ((!grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(edge.target) ] : [ ...initialGraph.getIncomingEdgesFor(edge.source) ]).some(edge => !grid.isFlipped ? edge.target === node : edge.source === node)))) return false;\n let outgoingEdges = !grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ].filter(edge => edge.target !== edge.source);\n\n // let incomingEdges = !grid.isFlipped ? [ ...initialGraph.getIncomingEdgesFor(node) ] : [ ...initialGraph.getOutgoingEdgesFor(node) ].filter(edge => edge.target !== edge.source);\n\n return outgoingEdges.length === 0;\n\n });\n\n // todo: !!!! add flip\n if (flippedStartElement) {\n grid.flipHorizontally();\n return flippedStartElement;\n }\n this.currentDebugStep += 1;\n\n // not traversed elements (restElements)\n return initialGraph.nodes.find(node => !visited.has(node));\n };\n\n // GetNextFromExecutionSequence<N> = (executionSequence: Array<N>) => N\n const dfsGetNextFromExecutionSequence = (executionSequence) => {\n return executionSequence.pop();\n };\n\n // GetNextNodesFunction<N> = (node: N, graph: Graph<N>, visited: Set<N>) => Array<N> | undefined\n const dfsGetNextNodes = (node, graph, visited, executionSequence) => {\n if (this.maxDebugStep !== undefined && this.maxDebugStep <= this.currentDebugStep) return;\n\n // основная обработка\n const nextElements = elementExecution(node, grid, executionSequence, visited, graph);\n\n // for (const item of nextElements) visited.add(item);\n\n this.currentDebugStep += 1;\n return nextElements;\n };\n\n // AddNextNodesToExecutionSequence<N> = (nodes: Array<N>, executionSequence: Array<N>) => void;\n const dfsAddNextNodesToExecutionSequence = (nodes, executionSequence) => {\n\n // todo: add sort for type\n for (const node of nodes) {\n executionSequence.push(node);\n }\n };\n\n const dfsExecuteCurrent = (node) => {\n\n // если грид пустой. то добавляем в него элемент\n // todo: возможно надо проверить что элемента нету\n if (!grid.hasElement(node)) {\n grid.add(node);\n }\n };\n\n\n processGraph.genericTraversing(\n dfsGetStartElement,\n dfsGetNextFromExecutionSequence,\n dfsGetNextNodes,\n dfsAddNextNodesToExecutionSequence,\n dfsExecuteCurrent\n );\n\n // flip grid on end\n if (grid.isFlipped) {\n grid.flipHorizontally();\n }\n\n return grid;\n }\n\n generateDi(layoutGrid , shift, procDi) {\n\n const diFactory = this.diFactory;\n\n const prePlaneElement = procDi ? procDi : this.diagram.diagrams[0];\n\n const planeElement = prePlaneElement.plane.get('planeElement');\n\n // Step 1: Create DI for all elements\n layoutGrid.elementsByPosition().forEach(({ element, row, col }) => {\n const dis = this\n .handle('createElementDi', { element, row, col, layoutGrid, diFactory, shift })\n .filter(item => item != undefined)\n .flat();\n\n planeElement.push(...dis);\n });\n\n // todo: заменить на ребра?\n // Step 2: Create DI for all connections\n layoutGrid.elementsByPosition().forEach(({ element, row, col }) => {\n const dis = this\n .handle('createConnectionDi', { element, row, col, layoutGrid, diFactory, shift })\n .flat();\n\n planeElement.push(...dis);\n });\n }\n\n handleGrid(grid, stack) {\n while (stack.length > 0 && (this.maxDebugStep === undefined || (this.maxDebugStep > 0 && this.currentDebugStep < this.maxDebugStep))) {\n\n const currentElement = stack.pop();\n const nextElements = this.handle('addToGrid', { element: currentElement, grid, stack });\n\n nextElements.flat().forEach(el => {\n stack.push(el);\n });\n\n this.currentDebugStep += 1;\n }\n }\n\n getRootProcesses() {\n return this.diagram.get('rootElements').filter(el => el.$type === 'bpmn:Process');\n }\n\n getCollaboration() {\n return this.diagram.get('rootElements').filter(el => el.$type === 'bpmn:Collaboration');\n }\n}\n\n/**\n * Check grid by columns.\n * If column has elements with isExpanded === true,\n * find the maximum size of elements grids and expand the parent grid horizontally.\n * @param grid\n */\nfunction expandGridHorizontally(grid) {\n for (let i = grid.colCount - 1 ; i >= 0; i--) {\n const elementsInCol = [];\n for (let j = 0; j < grid.rowCount; j++) {\n const candidate = [ ...(grid.get(j, i) || []) ].find(item => item.isExpanded);\n if (candidate) elementsInCol.push(candidate);\n }\n\n if (elementsInCol.length === 0) continue;\n\n const maxColCount = elementsInCol.reduce((acc,cur) => {\n if (acc === undefined || cur.grid.colCount > acc) return cur.grid.colCount;\n }, undefined);\n\n const shift = !maxColCount ? 2 : maxColCount;\n grid.createCol(i, shift);\n }\n}\n\n/**\n * Check grid by rows.\n * If row has elements with isExpanded === true,\n * find the maximum size of elements grids and expand the parent grid vertically.\n * @param grid\n */\nfunction expandGridVertically(grid) {\n\n for (let i = grid.rowCount - 1 ; i >= 0; i--) {\n const elementsInRow = [];\n for (let j = 0; j < grid.colCount; j++) {\n\n // [ ...(grid.get(j, i) || []) ].find(item => item.isExpanded);\n const candidate = [ ...(grid.get(i, j) || []) ].find(item => item.isExpanded);\n if (candidate) elementsInRow.push(candidate);\n }\n\n if (elementsInRow.length === 0) continue;\n\n const maxRowCount = elementsInRow.reduce((acc,cur) => {\n if (acc === undefined || cur.grid.rowCount > acc) return cur.grid.rowCount;\n }, undefined);\n\n const shift = !maxRowCount ? 1 : maxRowCount;\n\n // expand the parent grid vertically\n for (let index = 0; index < shift; index++) {\n grid.createRow(i);\n }\n }\n}\n","import { Layouter } from './Layouter.js';\n\nexport function layoutProcess(xml, debuggerCounter) {\n return new Layouter(debuggerCounter).layoutProcess(xml);\n}\n"],"names":["getDefaultSize","element","is","width","height","type","$instanceOf","isBoundaryEvent","attachedToRef","getOutgoingElements","outgoing","Set","map","out","targetRef","filter","el","forEach","add","getHostIncoming","incoming","sourceRef","Error","id","getBoundaryIncomingHosts","boundaryIncoming","item","getAttachedOutgoingElements","attachedOutgoing","attachers","sort","a","b","length","attacher","reverse","flat","index","self","indexOf","isStartIntermediate","undefined","DEFAULT_CELL_WIDTH","DEFAULT_CELL_HEIGHT","isFlipped","utilsGetOutgoingElements","concat","connectElements","source","target","layoutGrid","isBoundary","shift","sourceDi","di","targetDi","sourceBounds","get","targetBounds","sourceMid","getMid","targetMid","dX","gridPosition","col","dY","row","dockingSource","dockingTarget","x","sourceX","y","sourceY","coordinatesToPosition","targetX","$type","getDockingPoint","isExpanded","grid","rowCount","firstPoint","lastPoint","maxExpanded","hostSource","hostTarget","sourceRow","sourceCol","find","targetCol","firstCol","lastCol","elementsInRange","elements","size","reduce","acc","cur","getGridDimensions","getMaxExpandedBetween","elementsInMiddle","candidate","push","hasReversEdge","includes","hasSW_NEOut","some","direction","colCount","elementsInHorizontal","directManhattan","targetRow","totalElements","bendPoint","getElementsInRange","directManhattanConnect","startPoint","endPoint","yOffset","Math","sign","bounds","point","rectangle","dockingDirection","targetOrientation","test","original","getBounds","attachedTo","hostBounds","round","sortElementsTopLeftBottomRight","aPos","bPos","DiFactory","constructor","moddle","this","create","attrs","createDiBounds","createDiLabel","createDiShape","semantic","assign","bpmnElement","createDiWaypoints","waypoints","pos","createDiWaypoint","pick","createDiEdge","waypoint","createDiPlane","createDiDiagram","handlers","createElementDi","diFactory","DIs","executedElements","$parent","flowElements","att","i","arr","attacherDi","createBEl","options","isMarkerVisible","shapeDi","createConnectionDi","has","flatMap","dockingPoint","baseSourceGrid","newStart","splice","ensureExitBottom","Grid","_grid","_elements","elementsCount","firstRow","position","isValidPosition","_addStart","toRectangle","move","toPosition","removeElementAt","removeElement","createRow","afterIndex","Number","isInteger","Array","createCol","rowIndex","expandRow","placeholder","findIndex","startRow","startCol","endRow","endCol","numRows","maxCols","currentRowLength","elementsByPosition","colIndex","shrinkCols","every","shrinkRows","delete","difference","flipHorizontally","hasElement","isArray","hasIntermediateElements","firstPosition","lastPosition","onVertical","start","end","hasElementAt","Edge","originalSource","originalTarget","originalSourceIsBoundary","_originalSource","_originalTarget","_originalSourceIsBoundary","sourcePosition","targetPosition","getDirection","path","_pathForNoDirection","_pathForSouthToNorth","_pathForSouthWestToNorthEast","_pathForWestToEast","_pathForNorthWestToSouthEast","_pathForNorthToSouth","_pathForNorthEastToSouthWest","_pathForEastToWest","_pathForSouthEastToNorthWest","_normalizePathCols","pathSegments","maxColIndex","segment","getExistingOutgoingEdgesFor","edge","vCross","hCross","crossedElements","byVertical","crossedElementsPositions","crossedPositions","vDifference","hDifference","isIntersect","getExistingIncomingEdgesFor","GridWithEdges","super","_originalOutgoing","Map","_originalIncoming","_createNewEdgesFor","_removeEdgesFor","keyElement","edges","newEdges","set","_edgeIsExist","_addEdgeToGrid","_allEdges","existingEdge","existingSource","existingTarget","outgoingFromHost","outgoingFromBoundary","incomingFromHost","incomingFromBoundaryHost","getOutgoingFromHost","getOutgoingFromBoundary","getIncomingFromHost","getIncomingFromBoundaryHost","getOutgoingElementsFor","getIncomingElementsFor","isCrossed","values","shakeItHorizontal","sortedElements","pop","verticalChain","getVerticalChain","chainElement","baseCol","rows","chainElementPosition","hasNewCrosses","hasAnyCross","newVerticalChain","shakeItVertical","executedEdges","segmentRow","segmentCol","oldChain","chain","getAllExistingEdgesFor","nextElement","nextChain","nextChainEl","getHorizontalChain","outgoingEdges","incomingEdges","getElementsInRow","_separateGrid","_mergeGrids","grids","newGrid","getResultGrid","separated","mergedGrid","_createCrossGrid","crossGrid","elementRow","elementCol","hasToSouth","crossGridElement","_createGridWith","elementExecution","node","executionSequence","visited","graph","notMoveForvard","existingEdges","processingElements","inStackWithoutOutgoing","toElement","fromElement","unwantedEdge","backward","existGraph","Graph","nodes","addNode","addEdge","deleteEdge","isNodeTraced","isTracingForTopLeftMove","nextElementRow","nextElementCol","elementsToDelete","itemRow","elementToDelete","deleteIndex","shiftCount","topLeftPosition","bottomRightPosition","fixCrossesInGridPart","moveTopLeftOutgoingForward","newOutgoing","getOutgoingEdgesFor","getIncomingEdgesFor","getNewOutgoing","outgoingFromStack","hasNewOutgoings","targetEdge","targetParent","processingElement","getOutgoingFromStack","nextElements","previousElement","nextPosition","nextEl","isBoundarySource","elPos","allItemsInElementPosition","elementPositionEdges","crossedOrOccupied","getInsertPosition","fixNewCrosses","unshift","nextBoundaries","nextOther","inStack","topLeftRow","topLeftCol","bottomRightRow","bottomRightCol","stack","skipTopLeftOutgoing","forwardOnlyOutgoing","aRow","aCol","bRow","bCol","fixNewVerticalCrosses","fixNewHorizontalCrosses","vCrossed","pushVerticalEdgeBy","moveElementsRighterCrossLine","hCrossed","moveElementsUpperCrossLine","moveElementsUnderCrossLine","maxDown","getMaxDown","baseSourceRow","innerElement","innerItem","Layouter","debuggerCounter","BPMNModdle","_handlers","maxDebugStep","currentDebugStep","layoutProcess","xml","moddleObj","fromXML","rootElement","diagram","bpmnModel","allElements","elementsById","Object","setExpandedProcesses","processTrees","createNestedSets","createGridsForProcesses","rootProcesses","getRootProcesses","collaboration","getCollaboration","cleanDi","createRootDi","drawParticipants","drawProcesses","drawCollaborationMessageFlows","toXML","format","handle","operation","handler","isFunction","processes","level","process","createGridLayout","tempGridCollection","expandGridHorizontally","expandGridVertically","participants","participant","createParticipantDi","procTree","sortedProcesses","getParticipantForProcess","participantDi","getElementDi","getProcDi","generateDi","baseProcDi","diagrams","plane","messageFlows","message","processRef","planeElement","processGraph","allProcesses","getAllProcesses","children","getSubProcesses","child","separatedGraphs","getSeparatedGraphs","rootProcess","getStartElement","initialGraph","root","left","getNextNodes","outgoingNode","maxRight","prev","right","genericTraversing","getLast","addToEnd","mainElement","createProcessDi","planeDi","diagramDi","origin","defaultWidth","defaultHeight","flowElement","outgoingItem","dataInputAssociations","dataInputAssociationsItem","dataOutputAssociations","dataOutputAssociationsItem","targetElementInGridSourceNotExist","primaryStartElements","nonMatching","sortByType","sourceElementInGridTargetNotExist","otherStartingElement","flippedStartElement","procDi","dis","handleGrid","currentElement","elementsInCol","j","maxColCount","elementsInRow","maxRowCount","exports"],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import t from"bpmn-moddle";import{assign as e,map as o,pick as i,isFunction as n}from"min-dash";import{Graph as r,getLast as s,addToEnd as a}from"graph-by-ivan-tulaev";function c(t){return g(t,"bpmn:SubProcess")||g(t,"bpmn:Task")?{width:100,height:80}:g(t,"bpmn:Gateway")?{width:50,height:50}:g(t,"bpmn:Event")?{width:36,height:36}:g(t,"bpmn:Participant")||g(t,"bpmn:Lane")?{width:400,height:100}:g(t,"bpmn:DataObjectReference")?{width:36,height:50}:g(t,"bpmn:DataStoreReference")?{width:50,height:50}:g(t,"bpmn:TextAnnotation")?{width:100,height:30}:{width:100,height:80}}function g(t,e){return t.$instanceOf(e)}function d(t){return!!t.attachedToRef}function h(t){let e=new Set;if(t){(t.outgoing||[]).map((t=>t.targetRef)).filter((t=>t)).forEach((t=>e.add(t)))}return[...e]}function u(t){return(t.incoming||[]).map((t=>{if(!t.sourceRef)throw new Error(`${t.id} has no sourceRef`);return t.sourceRef})).filter((t=>!d(t)))}function l(t){let e=(t.incoming||[]).map((t=>t.sourceRef)).filter((t=>d(t))).map((t=>t.attachedToRef));return e=new Set(e),[...e]}function f(t){const e=new Set;if(t){const o=(t.attachers||[]).sort(((t,e)=>(e.outgoing?e.outgoing.length:0)-(t.outgoing?t.outgoing.length:0))).map((t=>(t.outgoing||[]).reverse())).flat().map((t=>t.targetRef)).filter(((t,e,o)=>o.indexOf(t)===e));for(const t of o)e.add(t)}return[...e]}function p(t){return(g(t,"bpmn:IntermediateThrowEvent")||g(t,"bpmn:IntermediateCatchEvent"))&&(void 0===t.incoming||0===t.incoming.length)}const m=150,E=140;function _(t,e){return new Set(h(t).concat(f(t)))}function x(t,e,o,i=!1,n){const r=t.di,s=e.di,a=r.get("bounds"),g=s.get("bounds"),d=y(a),u=y(g),l=e.gridPosition.col-t.gridPosition.col,f=e.gridPosition.row-t.gridPosition.row,p=`${f>0?"bottom":"top"}-${l>0?"right":"left"}`,m=`${f>0?"top":"bottom"}-${l>0?"left":"right"}`,{x:x,y:C}=b(t,n),{x:P}=b(e,n);if("bpmn:BoundaryEvent"===t.$type){if(0===l&&0===f)return[w(d,a,"b",p),{x:d.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},{x:P,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},{x:x,y:u.y},w(u,g,"l",m)];if(0===l&&f<0)return[w(d,a,"b",p),{x:d.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},{x:x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},{x:P,y:u.y},w(u,g,"l",m)];if(l>0&&f<0)return[w(d,a,"b",p),{x:d.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},{x:u.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},w(u,g,"b",m)];if(l>0&&0===f)return[w(d,a,"b",p),{x:d.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},{x:u.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},w(u,g,"b",m)];if(l>0&&f>0)return[w(d,a,"b"),{x:d.x,y:u.y},w(u,g,"l")];if(0===l&&f>0){const e=w(d,a,"b",p),o=w(u,g,"t",m);return t.attachedToRef.isExpanded?[e,{x:d.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},{x:u.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},o]:[e,o]}if(l<0&&f>0)return[w(d,a,"b"),{x:d.x,y:u.y},w(u,g,"r")];if(l<0&&0===f){const i=function(t,e,o){const i=t.attachedToRef?t.attachedToRef:t,n=e.attachedToRef?e.attachedToRef:e,[r,s]=o.find(i),[,a]=o.find(n),c=s<a?s:a,g=s<a?a:s,d=[...o.elements].map((t=>void 0!==t.size?[...t]:t)).flat().filter((t=>t.gridPosition.row===r&&t.gridPosition.col>c&&t.gridPosition.col<g));return d.reduce(((t,e)=>e.grid?.getGridDimensions()[0]>t?e.grid?.getGridDimensions()[0]:t),0)}(t,e,o);return[w(d,a,"b",p),{x:d.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E+i*E},{x:u.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E+i*E},w(u,g,"b",m)]}if(l<0&&f<0)return[w(d,a,"b",p),{x:d.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},{x:u.x,y:t.attachedToRef.isExpanded?C+(t.attachedToRef.grid.rowCount+1)*E:C+E},w(u,g,"b",m)]}else{if(0===l&&0===f)return[w(d,a,"b",p),{x:d.x,y:t.isExpanded?C+(t.grid.rowCount+1)*E:C+E},{x:P,y:t.isExpanded?C+(t.grid.rowCount+1)*E:C+E},{x:x,y:u.y},w(u,g,"l",m)];if(0===l&&f<0){const i=[];for(let n=t.gridPosition.row-1;n>e.gridPosition.row;n--){const e=o.get(n,t.gridPosition.col);e&&i.push(e)}const n=[..._(e)].includes(t);return i.length>0||n?[w(d,a,"l",p),{x:x,y:d.y},{x:P,y:u.y},w(u,g,"l",m)]:[w(d,a,"t",p),w(u,g,"b",m)]}if(l>0&&f<0)return[w(d,a,"r"),{x:u.x,y:d.y},w(u,g,"b")];if(l>0&&0===f){const o=w(d,a,"r",p);t.isExpanded&&(o.y=a.y+c(t).height/2);const i=w(u,g,"l",m);return e.isExpanded&&(i.y=g.y+c(e).height/2),[o,i]}if(l>0&&f>0)return[w(d,a,"b"),{x:d.x,y:u.y},w(u,g,"l")];if(0===l&&f>0){const o=w(d,a,"b",p),i=w(u,g,"t",m);return t.isExpanded||e.isExpanded?[o,{x:d.x,y:t.isExpanded?C+(t.grid.rowCount+1)*E:C+E},{x:u.x,y:t.isExpanded?C+(t.grid.rowCount+1)*E:C+E},i]:[o,i]}if(l<0&&f>0)return[w(d,a,"b"),{x:d.x,y:u.y},w(u,g,"r")];if(l<0&&0===f){const i=[];for(let n=t.gridPosition.col-1;n>e.gridPosition.col;n--){const e=o?o.get(t.gridPosition.row,n):null;e&&i.push(e)}const n=h(e).includes(t);let r=o?o.outgoing.get(e):[];if(r=r.some((t=>"SW_NE"===t.direction)),i.length>0||n||r)return[w(d,a,"b",p),{x:d.x,y:C+(t.isExpanded?E*(t.grid.colCount+1.5):E)},{x:u.x,y:C+(t.isExpanded?E*(t.grid.colCount+1.5):E)},w(u,g,"b",m)];{const o=w(d,a,"l",p);t.isExpanded&&(o.y=a.y+c(t).height/2);const i=w(u,g,"r",m);return e.isExpanded&&(i.y=g.y+c(e).height/2),[o,i]}}if(l<0&&f<0){const i=[];for(let n=t.gridPosition.col-1;n>=e.gridPosition.col;n--){const e=o?o.get(t.gridPosition.row,n):null;e&&i.push(e)}return i.length>0?[w(d,a,"b",p),{x:d.x,y:t.isExpanded?C+(t.grid.rowCount+1)*E:C+E},{x:u.x,y:t.isExpanded?C+(t.grid.rowCount+1)*E:C+E},w(u,g,"b",m)]:[w(d,a,"l"),{x:u.x,y:d.y},w(u,g,"b")]}}const S=function(t,e,o){const{row:i,col:n}=t.gridPosition,{row:r,col:s}=e.gridPosition,a=s-n,c=r-i;if(!(a>0&&0!==c))return;if(c>0){let t=0;const e={row:r,col:n};return t+=o.getElementsInRange({row:i,col:n},e).length,t+=o.getElementsInRange(e,{row:r,col:s}).length,!(t>2)&&["v","h"]}{let t=0;const e={row:i,col:s};return t+=o.getElementsInRange({row:i,col:n},e).length,t+=o.getElementsInRange(e,{row:r,col:s}).length,!(t>2)&&["h","v"]}}(t,e,o);if(S){const t=w(d,a,S[0],p),e=w(u,g,S[1],m);return[t,"h"===S[0]?{x:e.x,y:t.y}:{x:t.x,y:e.y},e]}const F=-Math.sign(f)*E/2;return[w(d,a,"r",p),{x:d.x+75,y:d.y},{x:d.x+75,y:u.y+F},{x:u.x-75,y:u.y+F},{x:u.x-75,y:u.y},w(u,g,"l",m)]}function y(t){return{x:t.x+t.width/2,y:t.y+t.height/2}}function w(t,e,o="r",i="top-left"){if("h"===o&&(o=/left/.test(i)?"l":"r"),"v"===o&&(o=/top/.test(i)?"t":"b"),"t"===o)return{original:t,x:t.x,y:e.y};if("r"===o)return{original:t,x:e.x+e.width,y:t.y};if("b"===o)return{original:t,x:t.x,y:e.y+e.height};if("l"===o)return{original:t,x:e.x,y:t.y};throw new Error("unexpected dockingDirection: <"+o+">")}function b(t,e={x:0,y:0}){const o=t.gridPosition.row,i=t.gridPosition.col;return{width:m,height:E,x:i*m+e.x,y:o*E+e.y}}function C(t,e,o,i,n){const{width:r,height:s}=c(t),{x:a,y:g}=i;if(!n)return{width:r,height:s,x:o*m+(m-r)/2+a,y:e*E+(E-s)/2+g};const d=n.di.bounds;return{width:r,height:s,x:Math.round(d.x+d.width/2-r/2),y:Math.round(d.y+d.height-s/2)}}function P(t){return function(e,o){const i=t.find(e),n=t.find(o);return i&&!n?-1:!i&&n?1:i||n?i[0]-n[0]||i[1]-n[1]:0}}class S{constructor(t){this.moddle=t}create(t,e){return this.moddle.create(t,e||{})}createDiBounds(t){return this.create("dc:Bounds",t)}createDiLabel(){return this.create("bpmndi:BPMNLabel",{bounds:this.createDiBounds()})}createDiShape(t,o,i){return this.create("bpmndi:BPMNShape",e({bpmnElement:t,bounds:this.createDiBounds(o)},i))}createDiWaypoints(t){var e=this;return o(t,(function(t){return e.createDiWaypoint(t)}))}createDiWaypoint(t){return this.create("dc:Point",i(t,["x","y"]))}createDiEdge(t,o,i){return this.create("bpmndi:BPMNEdge",e({bpmnElement:t,waypoint:this.createDiWaypoints(o)},i))}createDiPlane(t){return this.create("bpmndi:BPMNPlane",t)}createDiDiagram(t){return this.create("bpmndi:BPMNDiagram",t)}}const F=[{createElementDi:({element:t,row:e,col:o,diFactory:i,shift:n})=>{if(t.di)return;if("bpmn:BoundaryEvent"===t.$type)return function({element:t,row:e,col:o,diFactory:i,shift:n}){const r=t.attachedToRef.di.bounds;if(!r)throw new Error(`Create DI for ${t.id}. Nо hostBounds`);const s=[],a=t.$parent.flowElements.filter((e=>e.attachedToRef===t.attachedToRef));return a.sort(((t,e)=>(t.outgoing?t.outgoing.length:0)-(e.outgoing?e.outgoing.length:0))).forEach(((a,c,g)=>{a.gridPosition={row:e,col:o};const d=C(a,e,o,n,t.attachedToRef);d.x=r.x+(c+1)*(r.width/(g.length+1))-d.width/2;const h=i.createDiShape(a,d,{id:a.id+"_di"});a.di=h,a.gridPosition={row:e,col:o},s.push(h)})),s}({element:t,row:e,col:o,diFactory:i,shift:n});const r=C(t,e,o,n);if(t.isExpanded&&t.grid){const{width:e,height:o}=c(t),{rowCount:i,colCount:n}=t.grid;r.width=n*m+e,r.height=i*E+o}const s={id:t.id+"_di"};t.isExpanded&&(s.isExpanded=!0),g(t,"bpmn:ExclusiveGateway")&&(s.isMarkerVisible=!0);const a=i.createDiShape(t,r,s);return t.di=a,t.gridPosition={row:e,col:o},a}},{createConnectionDi:({element:t,row:e,col:o,layoutGrid:i,diFactory:n,shift:r})=>(t.outgoing||[]).filter((t=>i.elements.has(t.targetRef))).map((e=>{const o=e.targetRef,s=x(t,o,i,!1,r);return n.createDiEdge(e,s,{id:e.id+"_di"})}))},{createConnectionDi:({element:t,row:e,col:o,layoutGrid:i,diFactory:n,shift:r})=>(t.attachers||[]).sort(((t,e)=>(t.outgoing?t.outgoing.length:0)-(e.outgoing?e.outgoing.length:0))).flatMap((t=>(t.outgoing||[]).filter((t=>i.elements.has(t.targetRef))).map((s=>{const a=s.targetRef,c=x(t,a,i,!0,r);return function(t,e,[o,i]){const n=t.di.get("bounds"),r=w(y(n),n,"b");if(e[0].x===r.x&&e[0].y===r.y)return;const s=t.grid||t.attachedToRef?.grid;if(2===e.length){const t=[r,{x:r.x,y:s?(o+s.getGridDimensions()[0]+1)*E:(o+1)*E},{x:s?(i+s.getGridDimensions()[1]+1)*m:(i+1)*m,y:s?(o+s.getGridDimensions()[0]+1)*E:(o+1)*E},{x:s?(i+s.getGridDimensions()[1]+1)*m:(i+1)*m,y:s?o*E+70:(o+.5)*E}];return void e.splice(0,1,...t)}const a=[r,{x:r.x,y:s?(o+s.getGridDimensions()[0]+1)*E:(o+1)*E},{x:e[1].x,y:s?(o+s.getGridDimensions()[0]+1)*E:(o+1)*E}];e.splice(0,1,...a)}(t,c,[e,o]),n.createDiEdge(s,c,{id:s.id+"_di"})}))))}];class R{constructor(){this._grid=[],this.isFlipped=!1,this._elements=new Set}get rowCount(){return this._grid.length}get elementsCount(){return this._elements.size}get elements(){return this._elements}get colCount(){const t=this._grid[0];return t&&t.length}add(t,e){if(!this.isValidPosition(e))return void this._addStart(t);const[o,i]=e;this._grid[o]||(this._grid[o]=[]),this._grid[o][i]?this._grid[o][i].add(t):this._grid[o][i]=new Set([t]),this.elements.add(t),this.toRectangle()}move(t,e){if(!this.elements.has(t))return;if(!this.isValidPosition(e))return;const o=this.find(t);this.isValidPosition(o)&&(this.removeElementAt(o),this.add(t,e))}removeElement(t){if(!t)return;if(!this.elements.has(t))return;const e=this.find(t);this.removeElementAt(e)}createRow(t){t||Number.isInteger(t)?this._grid.splice(t+1,0,Array(this.colCount)):this._grid.push(Array(this.colCount))}createCol(t,e){this._grid.forEach(((o,i)=>{this.expandRow(i,t,e)}))}expandRow(t,e,o){if(!Number.isInteger(t)||t<0||t>this.rowCount-1)return;const i=Number.isInteger(o)&&o>0?Array(o):Array(1),n=this._grid[t];e||Number.isInteger(e)?n.splice(e+1,0,...i):n.splice(n.length,0,...i)}_addStart(t){this._grid.push([new Set([t])]),this.elements.add(t)}find(t){let e,o;if(e=this._grid.findIndex((e=>(o=e.findIndex((e=>e?.has(t))),-1!==o))),this.isValidPosition([e,o]))return[e,o]}get(t,e){return(this._grid[t]||[])[e]}getElementsInRange({row:t,col:e},{row:o,col:i}){const n=[];t>o&&([t,o]=[o,t]),e>i&&([e,i]=[i,e]);for(let r=t;r<=o;r++)for(let t=e;t<=i;t++){const e=this.get(r,t);e&&n.push(e)}return n}getGridDimensions(){const t=this._grid.length;let e=0;for(let o=0;o<t;o++){const t=this._grid[o].length;t>e&&(e=t)}return[t,e]}elementsByPosition(){const t=[];return this._grid.forEach(((e,o)=>{e.forEach(((e,i)=>{if(e)for(const n of[...e])t.push({element:n,row:o,col:i})}))})),t}shrinkCols(){for(let t=this.colCount-1;t>=0;t--){if(this._grid.every((e=>null==e[t])))for(const e of this._grid)e.splice(t,1)}}shrinkRows(){this._grid=this._grid.filter((t=>!t.every((t=>null==t))))}removeElementAt(t){const[e,o]=t,i=this.get(e,o);i&&(this._grid[e][o]=null,this.elements.delete(i))}toRectangle(){const[,t]=this.getGridDimensions();this._grid.forEach((e=>{if(e.length<t){const o=t-e.length;for(let t=0;t<o;t++)e.splice(e.length,0,null)}}))}flipHorizontally(){for(const t of this._grid)t.reverse();this.isFlipped=!this.isFlipped}hasElement(t){return this.elements.has(t)}isValidPosition(t){if(!t||!Array.isArray(t)||2!==t.length)return!1;const[e,o]=t;return Number.isInteger(e)&&Number.isInteger(o)&&e>=0&&o>=0}hasIntermediateElements(t,e,o){if(!this.isValidPosition(t)||!this.isValidPosition(e))return!1;if(o){const[o,i]=t[0]<=e[0]?[t[0],e[0]]:[e[0],t[0]];for(let e=o+1;e<i;e++)if(this.hasElementAt([e,t[1]]))return!0;return!1}{const[o,i]=t[1]<=e[1]?[t[1],e[1]]:[e[1],t[1]];for(let e=o+1;e<i;e++)return this.hasElementAt([t[0],e]),!0;return!1}}hasElementAt(t){if(!this.isValidPosition(t))return!1;const[e,o]=t;return!!this.get(e,o)}}class v{constructor(t,e,o,i){this._originalSource=t,this._originalTarget=e,this._grid=o,this._originalSourceIsBoundary=i}get source(){return this._grid.isFlipped?this._originalTarget:this._originalSource}get target(){return this._grid.isFlipped?this._originalSource:this._originalTarget}get sourcePosition(){const t=this.source;return this._grid.find(t)}get targetPosition(){const t=this.target;return this._grid.find(t)}get direction(){return this.getDirection(this.sourcePosition,this.targetPosition)}get path(){const t=this.direction;return"NO_DIRECTION"===t?this._pathForNoDirection():"S_N"===t?this._pathForSouthToNorth():"SW_NE"===t?this._pathForSouthWestToNorthEast():"W_E"===t?this._pathForWestToEast():"NW_SE"===t?this._pathForNorthWestToSouthEast():"N_S"===t?this._pathForNorthToSouth():"NE_SW"===t?this._pathForNorthEastToSouthWest():"E_W"===t?this._pathForEastToWest():"SE_NW"===t?this._pathForSouthEastToNorthWest():[]}_normalizePathCols(t){if(!this._grid.isFlipped)return t;const e=this._grid.colCount-1;for(const o of t)o.position[1]=e-o.position[1];return t}_pathForNoDirection(){return[]}_pathForSouthToNorth(){const t=[],[e,o]=this.sourcePosition,[i]=this.targetPosition;if(this._originalSourceIsBoundary)return t;if(this._grid.hasIntermediateElements(this.sourcePosition,this.targetPosition,!0))return t;if([...this._grid.getExistingOutgoingEdgesFor(this.target)].map((t=>t.target)).includes(this.source))return t;for(let n=e-1;n>i;n--)t.push({position:[n,o],vCross:!0});return t}_pathForSouthWestToNorthEast(){const t=[],[e,o]=this.sourcePosition,[i,n]=this.targetPosition;if(!this._originalSourceIsBoundary)for(let i=o+1;i<n;i++)t.push({position:[e,i],hCross:!0});t.push({position:[e,n],hCross:!0,vCross:!0});for(let o=e-1;o>i;o--)t.push({position:[o,n],vCross:!0});return t}_pathForWestToEast(){const t=[],[e,o]=this.sourcePosition,[,i]=this.targetPosition;for(let n=o+1;n<i;n++)t.push({position:[e,n],hCross:!0});return t}_pathForNorthWestToSouthEast(){const t=[],[e,o]=this.sourcePosition,[i,n]=this.targetPosition;for(let n=e+1;n<i;n++)t.push({position:[n,o],vCross:!0});t.push({position:[i,o],vCross:!0,hCross:!0});for(let e=o+1;e<n;e++)t.push({position:[i,e],hCross:!0});return t}_pathForNorthToSouth(){const t=[],[e,o]=this.sourcePosition,[i]=this.targetPosition;for(let n=e+1;n<i;n++)t.push({position:[n,o],vCross:!0});return t}_pathForNorthEastToSouthWest(){const t=[],[e,o]=this.sourcePosition,[i,n]=this.targetPosition;for(let n=e+1;n<i;n++)t.push({position:[n,o],vCross:!0});t.push({position:[i,o],vCross:!0,hCross:!0});for(let e=o-1;e>n;e--)t.push({position:[i,e],hCross:!0});return t}_pathForEastToWest(){const t=[],[e,o]=this.sourcePosition,[,i]=this.targetPosition;for(let n=o-1;n>i;n--)t.push({position:[e,n],hCross:!0});return t}_pathForSouthEastToNorthWest(){const t=[],[e,o]=this.sourcePosition,[i,n]=this.targetPosition;if(!this._originalSourceIsBoundary)for(let i=o-1;i>n;i--)t.push({position:[e,i],hCross:!0});this._originalSourceIsBoundary?t.push({position:[e,n],vCross:!0}):t.push({position:[e,n],hCross:!0,vCross:!0});for(let o=e-1;o>i;o--)t.push({position:[o,n],vCross:!0});return t}crossedElements(t){const e=[];for(const o of this.path){const[i,n]=o.position,r=this._grid.get(i,n);r&&(t&&o.vCross||!t&&o.hCross)&&e.push(r)}return e}crossedElementsPositions(t){const e=[];for(const o of this.path){const[i,n]=o.position;this._grid.get(i,n)&&(t&&o.vCross||!t&&o.hCross)&&e.push([i,n])}return e}getDirection(t,e){if(!this._grid.isValidPosition(t)||!this._grid.isValidPosition(e))return"NO_DIRECTION";const[o,i]=t,[n,r]=e,s=o-n,a=i-r;return s>0&&0===a?"S_N":s>0&&a<0?"SW_NE":0===s&&a<0?"W_E":s<0&&a<0?"NW_SE":s<0&&0===a?"N_S":o<n&&i>r?"NE_SW":o===n&&i>r?"E_W":o>n&&i>r?"SE_NW":void 0}isIntersect(t,e){const[o,i]=t,[n,r]=this.sourcePosition,[s,a]=this.targetPosition,c=this.direction;return"S_N"===c?!!(e&&i===r&&o<n&&o>s):"SW_NE"===c?!!(e&&i===a&&o<=n&&o>s)||!e&&i>r&&i<=a&&o===n:"W_E"===c?!e&&i>r&&i<a&&o===n:"NW_SE"===c?!!(e&&i===r&&o>n&&o<=s)||!e&&i>=r&&i<a&&o===s:"N_S"===c?!!(e&&i===r&&o>n&&o<s):"NE_SW"===c?!!(e&&i===r&&o>n&&o<=s)||!e&&i>a&&i<=r&&o===s:"E_W"===c?!e&&i>a&&i<r&&o===n:"SE_NW"===c&&(!!(e&&i===a&&o>s&&o<=n)||!e&&i>=a&&i<r&&o===n&&!this._grid.getExistingIncomingEdgesFor(this.source).some((t=>"NW_SE"===t.direction)))}}class D extends R{constructor(){super(),this._originalOutgoing=new Map,this._originalIncoming=new Map}get incoming(){return this.isFlipped?this._originalOutgoing:this._originalIncoming}get outgoing(){return this.isFlipped?this._originalIncoming:this._originalOutgoing}add(t,e){super.add(t,e),this._createNewEdgesFor(t)}removeElement(t){this._removeEdgesFor(t),super.removeElement(t)}move(t,e){this.removeElement(t),this.add(t,e)}_removeEdgesFor(t){if(this.hasElement(t)){this._originalOutgoing.delete(t),this._originalIncoming.delete(t);for(const[e,o]of this._originalOutgoing){if(!o.some((e=>e.target===t)))continue;const i=o.filter((e=>e.target!==t));i.length!==o.length&&this._originalOutgoing.set(e,i)}for(const[e,o]of this._originalIncoming){if(!o.some((e=>e.source===t)))continue;const i=o.filter((e=>e.source!==t));i.length!==o.length&&this._originalIncoming.set(e,i)}}}_edgeIsExist(t){const{source:e,sourcePosition:o,target:i,targetPosition:n}=t;return e&&o&&i&&n}_addEdgeToGrid(t){if(!this._edgeIsExist(t))return;if([...this._allEdges].some((e=>e.target===t.target&&e.source===t.source)))return;const{_originalSource:e,_originalTarget:o}=t,i=this._originalOutgoing.get(e);i?i.push(t):this._originalOutgoing.set(e,[t]);const n=this._originalIncoming.get(o);n?n.push(t):this._originalIncoming.set(o,[t])}_createNewEdgesFor(t){const e=h(t).filter((t=>this.hasElement(t)));for(const o of e){const e=new v(t,o,this);this._addEdgeToGrid(e)}const o=f(t).filter((t=>this.hasElement(t)));for(const e of o){const o=new v(t,e,this,!0);this._addEdgeToGrid(o)}const i=u(t).filter((t=>this.hasElement(t)));for(const e of i){const o=new v(e,t,this);this._addEdgeToGrid(o)}const n=l(t).filter((t=>this.hasElement(t)));for(const e of n){const o=new v(e,t,this,!0);this._addEdgeToGrid(o)}}getOutgoingFromHost(t){return this.isFlipped?new Set(u(t)):new Set(h(t))}getOutgoingFromBoundary(t){return this.isFlipped?new Set:new Set(f(t))}getIncomingFromHost(t){return this.isFlipped?new Set(h(t)):new Set(u(t))}getIncomingFromBoundaryHost(t){return this.isFlipped?new Set:new Set(l(t))}getOutgoingElementsFor(t){if(!t)return[];const e=this.getOutgoingFromHost(t),o=this.getOutgoingFromBoundary(t);return new Set([...e,...o])}getIncomingElementsFor(t){if(!t)return[];const e=this.getIncomingFromHost(t),o=this.getIncomingFromBoundaryHost(t);return new Set([...e,...o])}isCrossed(t,e){for(const o of this._allEdges)if(o.isIntersect(t,e))return!0}get _allEdges(){return new Set([...this._originalOutgoing.values()].flat())}shakeItHorizontal(){const t=[...this.elements].sort((e=this,function(t,o){const i=e.find(t),n=e.find(o);return i&&!n?-1:!i&&n?1:i||n?i[1]-n[1]||n[0]-i[0]:0})).reverse();for(var e;t.length>0;){const e=t.pop(),o=this.getVerticalChain(e);for(const e of o){t.indexOf(e)>=0&&t.splice(t.indexOf(e),1)}const[,i]=this.find([...o][0]),n=[...o].map((t=>this.find(t)[0]));if(!(i<=0)){for(let t=i-1;t>=0;t--){if(!n.every((e=>!this.isCrossed([e,t],!0)&&!this.get(e,t))))break;for(const e of o){const o=this.find(e);this.move(e,[o[0],t])}const i=this.hasAnyCross(),r=this.getVerticalChain(e);if(i||r.size>o.size){for(const e of o){const o=this.find(e);this.move(e,[o[0],t+1])}break}}this.shrinkCols()}}}shakeItVertical(){}hasAnyCross(t){const e=t||this._allEdges;for(const t of e)for(const e of t.path){const{position:[o,i],hCross:n,vCross:r}=e;if((n||r)&&this.get(o,i))return[o,i,t]}return!1}getVerticalChain(t,e){const o=e||new Set;if(!t)return o;if(!this.find(t))return o;o.add(t);const i=[...this.getAllExistingEdgesFor(t)].filter((t=>"N_S"===t.direction||"S_N"===t.direction));for(const e of i){const i=e.source===t?e.target:e.source;if(!o.has(i)){const t=this.getVerticalChain(i,o);for(const e of t)o.add(e)}}return o}getHorizontalChain(t,e){const o=e||new Set;if(!t)return o;if(!this.find(t))return o;o.add(t);const i=[...this.getAllExistingEdgesFor(t)].filter((t=>"W_E"===t.direction||"E_W"===t.direction));for(const e of i){const i=e.source===t?e.target:e.source;if(!o.has(i)){const t=this.getHorizontalChain(i,o);for(const e of t)o.add(e)}}return o}getExistingOutgoingEdgesFor(t){return this.outgoing.get(t)||[]}getExistingIncomingEdgesFor(t){return this.incoming.get(t)||[]}getAllExistingEdgesFor(t){const e=this.getExistingOutgoingEdgesFor(t),o=this.getExistingIncomingEdgesFor(t);return new Set([...e,...o])}getElementsInRow(t){return new Set(this._grid[t].filter((t=>null!=t)))}_separateGrid(){}_mergeGrids(t){const e=new D;for(const o of t)e._grid=e._grid.concat(o._grid),e._elements=new Set([...e._elements,...o._elements]),e._originalIncoming=new Map([...e._originalIncoming,...o._originalIncoming]),e._originalOutgoing=new Map([...e._originalOutgoing,...o._originalOutgoing]);return e}getResultGrid(){const t=this._separateGrid();for(const e of t)e.shrinkCols(),e.shrinkRows();const e=this._mergeGrids(t);return e.toRectangle(),e}_createCrossGrid(){const t=[];for(let e=0;e<this.rowCount;e++)t.push(Array(this.colCount));for(const e of this._elements){const[o,i]=this.find(e),n=this.incoming.get(e)||[],r=this.outgoing.get(e)||[],s=[...r,...n].some((t=>{const{source:o,direction:i}=t;return o===e&&("N_S"===i||"NW_SE"===i||"NE_SW"===i)||(o!==e&&("S_N"===i||"SW_NE"===i||"SE_SW"===i)||void 0)}));for(const e of r)for(const o of e.path){const{position:[e,i],vCross:n,hCross:r}=o,s=t[e][i]||{};n&&(s.vCross=n),r&&(s.hCross=r),t[e][i]=s}t[o][i]={...t[o][i]||{},element:e,incoming:n,outgoing:r,hasToSouth:s}}return t}_createGridWith(t,e){const o=new D;for(let i=0;i<t;i++)o._grid.push(Array(e));return o}}function N(t,e,o,i,n){t.notMoveForvard||function(t,e,o,i,n){const s=I(t,i,n,e.isFlipped);if(!s||0===s.length)return;const a=s.filter((t=>{const s=e.isFlipped?t.source:t.target,a=e.isFlipped?t.target:t.source,c=e.find(s),g=e.find(a);return a!==s&&(!(c[0]>=g[0])&&(!(c[1]>g[1])&&(!T(s,i,o,n)&&!function(t,e,o,i,n,s){const a=new r;for(const t of o.nodes)n.has(t)&&a.addNode(t);for(const t of o.edges)n.has(t.target)&&n.has(t.source)&&a.addEdge(t);return a.deleteEdge(i),a.isNodeTraced(e,t,s)}(s,a,i,t,n,!0))))})).map((t=>t.target)).sort(P(e));if(0===a.length)return;for(;a.length>0;){const o=a.shift(),[r,s]=e.find(o),c=a.filter((t=>{const[o]=e.find(t);return o===r}));for(const t of c){const e=c.indexOf(t);e<0||a.splice(e,1)}const[g,d]=e.find(t),h=d-s+1;for(let t=e.rowCount-1;t>=0;t--)t>=g?e.expandRow(t,d,h):e.expandRow(t,s-1,h);const u=[0,d+1],l=[e.rowCount-1,e.colCount-1];O(e,i,n,u,l)}}(t,e,o,n,i),t.notMoveForvard=!1;const s=function(t,e,o,i){if(i){const i=[...e.getOutgoingEdgesFor(t)].filter((t=>!o.has(t.target)&&"bpmn:BoundaryEvent"===t.target.$type));return i.length>0?[...e.getIncomingEdgesFor(t)].filter((t=>!o.has(t.source))).concat(i).map((e=>e.target!==t?e.target:e.source)):[...e.getIncomingEdgesFor(t)].filter((t=>!o.has(t.source))).map((t=>"bpmn:BoundaryEvent"===t.source.$type?t.source.attachedToRef:t.source))}return[...e.getOutgoingEdgesFor(t)].filter((t=>!o.has(t.target))).map((t=>t.target))}(t,n,i,e.isFlipped),a=function(t,e,o,i,n,r){const s=I(t,n,r,e.isFlipped),a=W(t,n,r,e.isFlipped).map((t=>t.source)),[,c]=e.find(t),g=[...s].filter((t=>{const s=e.isFlipped?t.source:t.target,g=e.find(s)[1];if(!T(s,n,o,r,e.isFlipped))return!1;return(!W(s,n,r,e.isFlipped).map((t=>t.source)).find((t=>a.includes(t)))||!i)&&g<=c})).map((t=>e.isFlipped?t.source:t.target)).sort(P(e));for(const t of g)o.splice(o.indexOf(t),1),r.delete(t),e.removeElement(t);return e.shrinkRows(),e.shrinkCols(),g}(t,e,o,s&&s.length>0,n,i);let c=[...s,...a],g=[],d=null;c.forEach((r=>{const s=function(t,e,o,i,n,r,s){if("bpmn:BoundaryEvent"===i.$type)return o.find(t);const a=o.find(t);if(!a)return;const c=s?[a[0]+1,a[1]+1]:[a[0],a[1]+1],g=o.find(t),d=[...o.get(g[0],g[1])],h=[];for(const t of d)[...o.getExistingOutgoingEdgesFor(t)].filter((t=>t.target!==t.source&&r.has(t.source)&&r.has(t.target))).forEach((t=>h.push(t)));for(let t=c[0];t<=o.rowCount;t++){const e=[t,c[1]],i=h.some((o=>o.targetPosition[0]===t&&o.targetPosition[1]===c[1]||o.isIntersect(e)));if(i&&t===o.colCount-1)c[0]=t+1;else if(!i){c[0]=t;break}}(o.get(c[0],c[1])||o.isCrossed(c,!0))&&o.createCol(c[1]-1);o.isCrossed([c[0],c[1]])&&o.createRow(c[0]-1);return c}(t,0,e,r,0,i,"bpmn:BoundaryEvent"===t.$type);e.add(r,s),i.add(r),G(r,e,n,i,o,g,!0),d=r,g.unshift(r)}));const h=[],u=[];for(const t of g)"bpmn:BoundaryEvent"===t.$type?h.push(t):u.push(t);return h.sort(((t,e)=>(t.outgoing?t.outgoing.length:0)-(e.outgoing?e.outgoing.length:0))),g=[...h,...u],g}function T(t,e,o,i,n){const r=o.includes(t),s=I(t,e,i,n);return r&&(!s||0===s.length)}function I(t,e,o,i){return[...i?e.getIncomingEdgesFor(t):e.getOutgoingEdgesFor(t)].filter((e=>o.has(i?e.source:e.target)&&o.has(t)))}function W(t,e,o,i){return[...i?e.getOutgoingEdgesFor(t):e.getIncomingEdgesFor(t)].filter((e=>o.has(i?e.source:e.target)&&o.has(t)))}function O(t,e,o,i,n){if(!t.isValidPosition(i)||!t.isValidPosition(n))throw new Error("fixCrossesInGridPart: invalid position");const[r,s]=i,[a,c]=n;for(let i=r;i<=a;i++)for(let n=s;n<=c;n++){const r=t.get(i,n);r&&G(r,t,e,o)}}function G(t,e,o,i,n,r,s,a){const c=[...[...e.getExistingOutgoingEdgesFor(t)].sort(((t,e)=>{const[o,i]=t.targetPosition,[n,r]=e.targetPosition;return o-n||i-r})),...[...e.getExistingIncomingEdgesFor(t)].sort(((t,e)=>{const[o,i]=t.sourcePosition,[n,r]=e.sourcePosition;return o-n||i-r}))].filter((e=>{const{target:a,source:c,direction:g}=e;return a!==c&&((!r||!r.includes(a))&&((!n||!T(a,o,n,i))&&(!s||c!==t||"SE_NW"!==g&&"S_N"!==g)))}));for(const t of c)B(t,e),"E_W"===t.direction&&t._originalSourceIsBoundary||M(t,e)}function B(t,e){const{direction:o}=t;if("W_E"===o||"E_W"===o)return;const i=t.crossedElements(!0);i.length<=0||("S_N"!==o?"SW_NE"!==o&&"NW_SE"!==o?"N_S"!==o?"NE_SW"!==o&&"SE_NW"!==o||V(i,e):k(i,e):V(i,e):k(i,e))}function M(t,e){const{direction:o}=t;if("S_N"===o||"N_S"===o)return;const i=t.crossedElements(!1);if(0!==i.length)if("SW_NE"!==o)"W_E"!==o?"NW_SE"!==o&&"NE_SW"!==o?"E_W"!==o?"SE_NW"!==o||$(i,e):A(i,e):$(i,e):A(i,e);else{const o=function(t){const e=t.sourcePosition,o=t.targetPosition;let i=e[0];for(let n=e[0];n<t._grid.rowCount&&t._grid.getElementsInRange({row:n,col:e[1]+1},{row:n,col:o[1]}).length>0;n++)i++;return i-e[0]}(t),[i]=t.sourcePosition;for(let t=o;t>0;t--)e.createRow(i-1);const n=t._grid.getElementsInRange({row:t.sourcePosition[0],col:t.sourcePosition[1]+1},{row:t._grid.rowCount-1,col:t._grid.colCount-1});for(const e of n){const[i,n]=t._grid.find([...e][0]);for(const r of[...e])t._grid.move(r,[i-o,n])}}}function $(t,e){const[o]=e.find([...t[0]][0]);e.createRow(o-1);for(const i of t){const[,t]=e.find([...i][0]);for(const n of[...i])e.move(n,[o,t])}}function A(t,e){const[o]=e.find([...t[0]][0]);e.createRow(o);for(const i of t){const[,t]=e.find([...i][0]);for(const n of[...i])e.move(n,[o+1,t])}}function k(t,e){const[,o]=e.find([...t[0]][0]);e.createCol(o);for(const i of t){const[t]=e.find([...i][0]);for(const n of[...i])e.move(n,[t,o+1])}}function V(t,e){const[,o]=e.find([...t[0]][0]);e.createCol(o-1);for(const i of t){const[t]=e.find([...i][0]);for(const n of[...i])e.move(n,[t,o])}}class z{constructor(e){this.moddle=new t,this.diFactory=new S(this.moddle),this._handlers=F,this.maxDebugStep=e,this.currentDebugStep=0}async layoutProcess(t){const e=await this.moddle.fromXML(t),{rootElement:o}=e;this.diagram=o,function(t){const e=t.elementsById;if(e)for(const t of Object.values(e))"bpmndi:BPMNShape"===t.$type&&!0===t.isExpanded&&(t.bpmnElement.isExpanded=!0)}(e),this.processTrees=this.createNestedSets(e),this.createGridsForProcesses();const i=this.getRootProcesses(),n=this.getCollaboration();return i.length>0&&(this.cleanDi(),this.createRootDi(i,n),this.drawParticipants(),this.drawProcesses(),this.drawCollaborationMessageFlows(n)),(await this.moddle.toXML(this.diagram,{format:!0})).xml}handle(t,e){return this._handlers.filter((e=>n(e[t]))).map((o=>o[t](e)))}createGridsForProcesses(){const t=this.processTrees.map((t=>[...t.nodes])).flat();t.sort(((t,e)=>e.level-t.level));for(const e of t){e.grid=this.createGridLayout(e);const t=e.grid._separateGrid()||[e.grid];for(const e of t)e.shrinkRows(),e.shrinkCols(),e.shrinkRows(),e.shrinkCols(),e.toRectangle(),H(e),L(e);if(e.grid=e.grid._mergeGrids(t),e.grid.toRectangle(),e.isExpanded){const{colCount:t,rowCount:o}=e.grid;0===o&&e.grid.createRow(),0==t&&e.grid.createCol()}}}drawParticipants(){const t=this.getCollaboration();if(!t||!t[0])return;const e=t[0].participants;let o=0;for(const t of e)o=this.createParticipantDi(t,{x:0,y:o})+70}drawProcesses(){for(const t of this.processTrees){const e=t.nodes.sort(((t,e)=>t.level-e.level));for(const t of e){const e=this.getParticipantForProcess(t);if(e){const o=this.getElementDi(e),i=this.getProcDi(o);let{x:n,y:r}=o.bounds;n+=75,r+=70,this.generateDi(t.grid,{x:n,y:r},i);continue}if(t.isExpanded){const e=this.getElementDi(t),o=this.getProcDi(e);let{x:i,y:n}=e.bounds;const{width:r,height:s}=c(t);i+=75-r/4,n+=E-s-s/4,this.generateDi(t.grid,{x:i,y:n},o);continue}const o=this.diagram.diagrams.find((e=>e.plane.bpmnElement===t));this.generateDi(t.grid,{x:0,y:0},o)}}}drawCollaborationMessageFlows(t){const e=t[0]?t[0].messageFlows:null;if(e)for(const t of e){const{sourceRef:e,targetRef:o}=t,i=e.di.bounds,n=o.di.bounds,r=n.y-i.y,s=[{x:i.x+i.width/2},{x:n.x+n.width/2}];r>0?(s[0].y=i.y+i.height,s[1].y=n.y):(s[0].y=i.y,s[1].y=n.y+n.height);const a=this.diFactory.createDiEdge(t,s);this.diagram.diagrams[0].plane.get("planeElement").push(a)}}getParticipantForProcess(t){const e=this.getCollaboration();if(!e||!e[0])return;const o=this.getCollaboration()[0].participants;return o?o.find((e=>e.processRef===t)):void 0}getElementDi(t){return this.diagram.diagrams.map((t=>t.plane.planeElement)).flat().find((e=>e.bpmnElement===t))}getProcDi(t){return this.diagram.diagrams.find((e=>e.plane.planeElement.includes(t)))}createNestedSets(t){const e=new r,o=function(t){const e=t.elementsById;return e?Object.values(e).filter((t=>"bpmn:Process"===t.$type||"bpmn:SubProcess"===t.$type)):[]}(t);for(const t of o)e.addNode(t);for(const t of o){const o=this.getSubProcesses(t);for(const i of o)e.addEdge({source:t,target:i})}const i=e.getSeparatedGraphs();for(const t of i){const e=t.nodes.filter((e=>0===t.getIncomingEdgesFor(e).size));if(e.length>1)throw new Error("Process tree has more than 1 root elements");if(0===e.length)throw new Error("Process tree has more than 0 root elements");t.rootProcess=e[0]}for(const t of i){const e=(t,e)=>{const o=e.rootProcess;return o.left=0,o.level=0,o},o=(t,e,o)=>{const{left:i,level:n}=t,r=[...e.getOutgoingEdgesFor(t)].map((t=>t.target)).find((t=>void 0===t.left));if(r)return r.level=n+1,r.left=i+1,[r];const s=[...e.getOutgoingEdgesFor(t)].map((t=>t.target)).reduce(((t,e)=>{if(void 0===t||e.right>t.right)return e.right}),void 0);t.right=s?s+1:t.left+1;const a=[...e.getIncomingEdgesFor(t)].map((t=>t.source)).find((t=>void 0===t.right));return a?[a]:void 0};t.genericTraversing(e,s,o,a)}return i}getSubProcesses(t){return t.flowElements?t.flowElements.filter((t=>"bpmn:SubProcess"===t.$type)):[]}createRootDi(t,e){const o=e&&e.length>0?e[0]:t[0];this.createProcessDi(o)}createProcessDi(t){const e=this.diFactory,o=e.createDiPlane({id:"BPMNPlane_"+t.id,bpmnElement:t}),i=e.createDiDiagram({id:"BPMNDiagram_"+t.id,plane:o});return this.diagram.diagrams.push(i),i}createParticipantDi(t,e){const{colCount:o,rowCount:i}=t.processRef.grid,{width:n,height:r}=c(t),s=o>0?o*m+m:n,a=i>0?i*E+E:r,g=this.diFactory.createDiShape(t,{width:s,height:a,...e},{id:t.id+"_di"});return this.diagram.diagrams[0].plane.get("planeElement").push(g),g.bounds.y+g.bounds.height}cleanDi(){this.diagram.diagrams=[]}createGridLayout(t){const e=new D,o=new r;for(const e of t.flowElements||[])g(e,"bpmn:SequenceFlow")||g(e,"bpmn:DataObject")||o.addNode(e);for(const t of o.nodes){for(const e of t.outgoing||[])o.addEdge({source:e.sourceRef,target:e.targetRef});const e=t.attachedToRef;e&&o.addEdge({source:e,target:t});const i=t.dataInputAssociations;for(const t of i||[]){const e=t.sourceRef[0],i=t.$parent;o.addEdge({source:e,target:i})}const n=t.dataOutputAssociations;for(const t of n||[]){const e=t.$parent,i=t.targetRef;o.addEdge({source:e,target:i})}}return o.genericTraversing(((t,o)=>{if(void 0!==this.maxDebugStep&&this.maxDebugStep<=this.currentDebugStep)return;const i=[...t].find((i=>e.isFlipped?[...o.getOutgoingEdgesFor(i)].filter((e=>!t.has(e.target))).length>0:[...o.getIncomingEdgesFor(i)].filter((e=>!t.has(e.source))).length>0));if(i)return e.flipHorizontally(),i;const n=o.nodes.filter((i=>e.isFlipped?!t.has(i)&&0===o.getOutgoingEdgesFor(i).size&&!p(i):!t.has(i)&&0===o.getIncomingEdgesFor(i).size&&!p(i)));if(n.length>0)return function(t,e){const o=t.filter((t=>!g(t,e)));return[...t.filter((t=>g(t,e))),...o]}(n,"bpmn:StartEvent")[0];const r=[...t].find((i=>(e.isFlipped?[...o.getIncomingEdgesFor(i)].filter((e=>!t.has(e.source))):[...o.getOutgoingEdgesFor(i)].filter((e=>!t.has(e.target)))).length>0));if(r)return r;const s=o.nodes.find((i=>{if(t.has(i))return!1;return 0===(e.isFlipped?[...o.getOutgoingEdgesFor(i)].filter((t=>t.target!==i)):[...o.getIncomingEdgesFor(i)].filter((t=>t.source!==i))).length}));if(s)return s;const a=o.nodes.find((i=>{if(t.has(i))return!1;return 0===(e.isFlipped?[...o.getIncomingEdgesFor(i)].filter((t=>t.target!==t.source)):[...o.getOutgoingEdgesFor(i)]).length}));return a?(e.flipHorizontally(),a):(this.currentDebugStep+=1,o.nodes.find((e=>!t.has(e))))}),(t=>t.pop()),((t,o,i,n)=>{if(void 0!==this.maxDebugStep&&this.maxDebugStep<=this.currentDebugStep)return;const r=N(t,e,n,i,o);return this.currentDebugStep+=1,r}),((t,e)=>{for(const o of t)e.push(o)}),(t=>{e.hasElement(t)||e.add(t)})),e.isFlipped&&e.flipHorizontally(),e}generateDi(t,e,o){const i=this.diFactory,n=(o||this.diagram.diagrams[0]).plane.get("planeElement");t.elementsByPosition().forEach((({element:o,row:r,col:s})=>{const a=this.handle("createElementDi",{element:o,row:r,col:s,layoutGrid:t,diFactory:i,shift:e}).filter((t=>null!=t)).flat();n.push(...a)})),t.elementsByPosition().forEach((({element:o,row:r,col:s})=>{const a=this.handle("createConnectionDi",{element:o,row:r,col:s,layoutGrid:t,diFactory:i,shift:e}).flat();n.push(...a)}))}handleGrid(t,e){for(;e.length>0&&(void 0===this.maxDebugStep||this.maxDebugStep>0&&this.currentDebugStep<this.maxDebugStep);){const o=e.pop();this.handle("addToGrid",{element:o,grid:t,stack:e}).flat().forEach((t=>{e.push(t)})),this.currentDebugStep+=1}}getRootProcesses(){return this.diagram.get("rootElements").filter((t=>"bpmn:Process"===t.$type))}getCollaboration(){return this.diagram.get("rootElements").filter((t=>"bpmn:Collaboration"===t.$type))}}function H(t){for(let e=t.colCount-1;e>=0;e--){const o=[];for(let i=0;i<t.rowCount;i++){const n=[...t.get(i,e)||[]].find((t=>t.isExpanded));n&&o.push(n)}if(0===o.length)continue;const i=o.reduce(((t,e)=>{if(void 0===t||e.grid.colCount>t)return e.grid.colCount}),void 0),n=i||2;t.createCol(e,n)}}function L(t){for(let e=t.rowCount-1;e>=0;e--){const o=[];for(let i=0;i<t.colCount;i++){const n=[...t.get(e,i)||[]].find((t=>t.isExpanded));n&&o.push(n)}if(0===o.length)continue;const i=o.reduce(((t,e)=>{if(void 0===t||e.grid.rowCount>t)return e.grid.rowCount}),void 0),n=i||1;for(let o=0;o<n;o++)t.createRow(e)}}function j(t,e){return new z(e).layoutProcess(t)}export{j as layoutProcess};//# sourceMappingURL=index.js.map
|