yet-another-bpmn-auto-layout 0.0.4 → 0.0.6
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/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../lib/di/DiUtil.js","../lib/utils/elementUtils.js","../lib/utils/layoutUtils.js","../lib/di/DiFactory.js","../lib/Grid.js","../lib/Edge.js","../lib/GridWithEdges.js","../lib/newHandlers/outgoingHandler.js","../lib/newHandlers/createElementDi.js","../lib/Layouter.js","../lib/newHandlers/createConnection.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 if (!element) throw new Error('Element is not defined in getOutgoingElements');\n const outgoingElements = (element.outgoing || []).map(out => out.targetRef);\n\n // возвращаем уникальные, так как BPMN может быть не валидным\n return [ ...new Set(outgoingElements) ];\n}\n\nexport function getIncomingElements(element) {\n if (!element) throw new Error('Element is not defined in getIncomingElements');\n let incomingElements = (element.incoming || []).map(out => out.sourceRef);\n\n // возвращаем уникальные, так как BPMN может быть не валидным\n return [ ...new Set(incomingElements) ];\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\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(edge, layoutGrid, isBoundary = false, shift) {\n\n const { source, target } = edge;\n\n // TODO: Use GridController 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 // todo: убрать dX ???\n const edgeDirection = layoutGrid.getEdgeDirection(edge);\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 sourceIsBoundary = source.$type === 'bpmn:BoundaryEvent';\n\n // Source === Target ==> Build loop\n if (edgeDirection === 'NO_DIRECTION') {\n\n if (sourceIsBoundary) 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 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 (edgeDirection === 'S_N') {\n\n if (sourceIsBoundary) 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 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 (edgeDirection === 'SW_NE') {\n if (sourceIsBoundary) 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 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 (edgeDirection === 'W_E') {\n\n if (sourceIsBoundary) 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 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 (edgeDirection === 'NW_SE') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l')\n ];\n\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 (edgeDirection === 'N_S') {\n\n if (sourceIsBoundary) {\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 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 (edgeDirection === 'NE_SW') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'r')\n ];\n\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 (edgeDirection === 'E_W') {\n\n if (sourceIsBoundary) {\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 // здесь аналогично вертикали\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.getExistingOutgoingEdgesFor(target) : [];\n hasSW_NEOut = hasSW_NEOut.some(item => layoutGrid.getEdgeDirection(item) === '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 (edgeDirection === 'SE_NW') {\n\n if (sourceIsBoundary) 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 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 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\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\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\n/**\n *\n * @param {*[]} arr array of BPMN elements\n * @param {string|string[]} types array of types\n * @returns {*[]} sorted array of BPMN elements\n */\nexport function sortByType(arr, types) {\n const typesArray = [ types ].flat();\n if (typesArray.length === 0) return arr;\n\n let result = [];\n typesArray.forEach((type,index) => {\n const matching = arr.filter(item => is(item, type));\n result = result.concat(matching);\n if (index === typesArray.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 const [ sourceRow, sourceCol ] = layoutGrid.find(source);\n const [ , targetCol ] = layoutGrid.find(target);\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","export class Grid {\n constructor(height = 0, width = 0) {\n\n const newGrid = Array(height);\n for (let i = 0; i < newGrid.length; i++) {\n newGrid[i] = Array(width);\n }\n\n this._grid = newGrid;\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._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 if (position) {\n const setPos = this.get(position[0], position[1]);\n setPos.delete(element);\n this.elements.delete(element);\n\n if (setPos.size === 0) this._grid[position[0]][position[1]] = null;\n\n }\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 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(source, target) {\n this.source = source;\n this.target = target;\n }\n}","import { Graph } from 'graph-by-ivan-tulaev';\n\nimport { Grid } from './Grid.js';\nimport { Edge } from './Edge.js';\n\nimport {\n sortByType,\n sortColsLeftRightRowsBottomTop, sortElementsTopRightBottomLeft,\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(initialGraph, height, width) {\n super(height, width);\n\n this.initialGraph = initialGraph;\n this.graph = new Graph();\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\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n }\n\n removeElement(element) {\n this.graph.deleteNode(element);\n\n super.removeElement(element);\n }\n\n move(element, toPosition) {\n const allEls = [ ...this.get(...this.find(element)) ];\n const edges = allEls.reduce((prev, cur) => {\n return [ ...prev, ...this.getAllExistingEdgesFor(cur) ];\n }, []);\n\n for (const el of allEls) {\n this.removeElement(el);\n this.add(el, toPosition);\n }\n\n for (const edge of edges) {\n\n // todo: пока костыль с пересозданием ребра - в какой-то момент теряется ссылка на нужный грид\n const newEdge = new Edge(edge.source, edge.target);\n newEdge.id = edge.id;\n this._addEdgeToGrid(newEdge);\n }\n }\n\n /**\n * Проверка существования для НОВЫХ ребер\n * Со старыми только через мапу\n * @param edge\n * @returns {*}\n * @private\n */\n _edgeIsExist(edge) {\n\n return [ ...this.graph.edges ]\n .some(existingEdge => existingEdge.id === edge.id && existingEdge.source === edge.source && existingEdge.target === edge.target);\n }\n\n _addEdgeToGrid(edge) {\n if (this._edgeIsExist(edge)) return;\n this.graph.addEdge(edge);\n }\n\n /**\n *\n * @param element element\n * @private\n */\n _createNewEdgesFor(element) {\n\n // todo: переписать под обертку\n const edges = [ ...this.initialGraph.edges ]\n .filter(edge => (edge.source === element || edge.target === element) && this.hasElement(edge.source) && this.hasElement(edge.target));\n for (const edge of edges) {\n\n const newEdge = new Edge(edge.source, edge.target);\n newEdge.id = edge.id;\n this._addEdgeToGrid(newEdge);\n }\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 return [ ...this._allEdges ].some(edge => this.isIntersect(edge, position, byVertical));\n }\n\n get _allEdges() {\n return this.graph.edges;\n }\n\n /**\n * Пока так наличие пересечений определим\n * @param {Edge[]=} edges\n * @returns {boolean}\n */\n hasAnyCross(edges) {\n const executedEdges = edges ? edges : this._allEdges;\n\n return [ ...executedEdges ].some(edge => this.getCrossedElementsFor(edge).length > 0 || this.getCrossedElementsFor(edge, true).length > 0);\n }\n\n /**\n * Уплотняет грид по горизонтали или по вертикали\n * @param {boolean} byVertical\n */\n shakeIt(byVertical) {\n\n const sortedElements = [ ...this.elements ].sort(byVertical ? sortElementsTopRightBottomLeft(this) : sortColsLeftRightRowsBottomTop (this)).reverse();\n\n while (sortedElements.length > 0) {\n\n // работаем по первому элементу\n const element = sortedElements.pop();\n\n // получаем цепочку противоположную направлению уплотнения\n // удаляем из стека sortedElements все элементы из цепочки\n const chain = this.getChain(element, !byVertical);\n\n for (const chainElement of chain) {\n const deleteIndex = sortedElements.indexOf(chainElement);\n if (deleteIndex >= 0) {\n sortedElements.splice(deleteIndex, 1);\n }\n }\n\n // проверяем можно ли двинуть цепочку вверх для уплотнения по вертикали и влево для уплотнения по горизонтали\n // не одна из позиций не должна быть занята или иметь пересечения\n // - цепочка не должна удлиниться\n // todo: пока под вопросом для ребра из boundary не должны закручиваться\n const [ baseRow, baseCol ] = this.find([ ...chain ][0]);\n\n // двигаться не вариант если цепочка у края грида\n if (byVertical ? baseRow <= 0 : baseCol <= 0) continue;\n\n for (let index = byVertical ? baseRow - 1 : baseCol - 1 ; index >= 0; index--) {\n\n // не двигаем если есть пересечения\n // todo: добавить оптимизации\n const allPositionsAreFine = [ ...chain ].every(element => {\n const curPos = this.find(element);\n\n return curPos && !this.isCrossed(curPos, true) && !this.isCrossed(curPos, false) ;\n });\n if (!allPositionsAreFine) break;\n\n // проверяем заняты ли новые позиции\n // todo: добавить оптимизации\n const newPositionsAreFine = [ ...chain ].every(element => {\n const curPos = this.find(element);\n const checkedRow = byVertical ? index : curPos[0];\n const checkedCol = byVertical ? curPos[1] : index;\n return !this.get(checkedRow, checkedCol);\n });\n if (!newPositionsAreFine) break;\n\n // пробно перемещаем все элементы из цепочки на новые места\n // пересечения позже всем скоупом проверим\n for (const chainElement of chain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, byVertical ? [ index, chainElementPosition[1] ] : [ chainElementPosition[0], index ]);\n }\n\n // проверяем не образовалось ли новых пересечений пока по старинке\n // и не удлинилась ли цепочка\n // todo: не пробегаться по всему гриду, а работать только по цепочке!!!\n const hasNewCrosses = this.hasAnyCross();\n const newChain = byVertical ? this.getChain(element, false) : this.getChain(element, true);\n if (hasNewCrosses || newChain.size > chain.size) {\n\n // вертаем все элементы взад\n for (const chainElement of chain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, byVertical ? [ index + 1 , chainElementPosition[1] ] : [ chainElementPosition[0], index + 1 ]);\n }\n break;\n }\n }\n\n // после каждого прохода удаляем пустые линии чтобы не ходить по пустым местам\n byVertical ? this.shrinkRows() : this.shrinkCols();\n }\n }\n\n /**\n * Возвращает горизонтальную или вертикальную последовательность элементов\n * @param {any} element BPMN Element\n * @param {boolean} byVertical\n * @param {Set<any>=}oldChain\n * @returns {Set<any>}\n */\n getChain(element, byVertical, 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 const edges = [];\n\n // получаем все элементы в позиции\n const elInPos = this.get(elementPosition[0], elementPosition[1]);\n for (const el of elInPos) {\n chain.add(el);\n\n // todo: возможно стоит добавить другие варианты ребер - в себя - убрать undefined\n [ ...this.getAllExistingEdgesFor(el) ]\n\n // .filter(edge => !byVertical ? (this.getEdgeDirection(edge) === 'W_E' || this.getEdgeDirection(edge) === 'E_W' || this.getEdgeDirection(edge) === 'NO_DIRECTION' || this.getEdgeDirection(edge) === undefined) : (this.getEdgeDirection(edge) === 'N_S' || this.getEdgeDirection(edge) === 'S_N' || this.getEdgeDirection(edge) === 'NO_DIRECTION' || this.getEdgeDirection(edge) === undefined))\n .filter(edge => !byVertical ? (this.getEdgeDirection(edge) === 'W_E' || this.getEdgeDirection(edge) === 'E_W') : (this.getEdgeDirection(edge) === 'N_S' || this.getEdgeDirection(edge) === 'S_N'))\n .forEach(edge => edges.push(edge));\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.getChain(nextElement, byVertical, 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.isFlipped ? [ ...this.graph.getOutgoingEdgesFor(element) ] : [ ...this.graph.getIncomingEdgesFor(element) ];\n }\n\n getExistingIncomingEdgesFor(element) {\n return !this.isFlipped ? [ ...this.graph.getIncomingEdgesFor(element) ] : [ ...this.graph.getOutgoingEdgesFor(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 _separateGrid() {\n\n // создаем копию графа\n const executedGraph = Graph.mergeGraphs(new Set([ this.graph ]));\n\n const separatedGraphs = executedGraph.getSeparatedGraphs();\n\n // todo: костыль для устранения проблемы после разделения пустого графа\n if (separatedGraphs.length === 0) return [ new GridWithEdges(this.initialGraph, this.colCount, this.rowCount) ];\n\n // todo: добавить проверку на не пересечение\n const grids = [];\n\n for (const graph of separatedGraphs) {\n const grid = new GridWithEdges(this.initialGraph, this.colCount, this.rowCount);\n\n let minRow = null;\n let maxRow = null;\n\n // todo: костыль до полного перехода на граф\n for (const node of sortByType(graph.nodes, 'bpmn:BoundaryEvent').reverse()) {\n const position = this.find(node);\n if (minRow === null || minRow > position[0]) minRow = position[0];\n if (maxRow === null || maxRow < position[0]) maxRow = position[0];\n grid._superAdd(node, position);\n grid.graph.addNode(node);\n }\n\n // todo: костыль для пролива ребер надо посмотреть почему не создаются - может в ручную делать а не при добавлении вершины\n graph.edges.forEach(edge => {\n grid._addEdgeToGrid(edge);\n });\n\n grids.push(grid);\n }\n\n return grids;\n }\n\n _superAdd(element, position) {\n super.add(element, position);\n }\n\n // todo: сделать нормальное копирование\n _mergeGrids(grids) {\n const height = grids.reduce((acc, cur) => acc + cur.rowCount, 0);\n const width = grids.reduce((acc, cur) => cur.colCount > acc ? cur.colCount : acc, 0);\n const newGrid = new GridWithEdges(grids[0].initialGraph, height, width);\n\n grids.forEach((grid, index) => {\n let rowShift = 0;\n for (let i = 0; i < index; i++) {\n rowShift = rowShift + grids[i].rowCount;\n }\n\n for (const element of grid.elements) {\n const [ row, col ] = grid.find(element);\n newGrid.add(element, [ row + rowShift, col ]);\n }\n\n // newGrid.graph = Graph.mergeGraphs(new Set([ newGrid.graph, grid.graph ]));\n });\n\n return newGrid;\n }\n\n getSourcePosition(edge) {\n const source = !this.isFlipped ? edge.source : edge.target;\n return this.find(source);\n }\n\n getTargetPosition(edge) {\n const target = !this.isFlipped ? edge.target : edge.source;\n return this.find(target);\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 * @param edge\n * @returns {Direction}\n */\n getEdgeDirection(edge) {\n const sourcePosition = this.getSourcePosition(edge);\n const targetPosition = this.getTargetPosition(edge);\n\n if (!this.isValidPosition(sourcePosition) || !this.isValidPosition(targetPosition)) throw new Error(`Invalid position of source or target in ${edge.source}-${edge.target} flipped:${this.isFlipped}`);\n\n const [ sourceRow, sourceCol ] = sourcePosition;\n const [ targetRow, targetCol ] = targetPosition;\n\n const vDifference = sourceRow - targetRow;\n const hDifference = sourceCol - targetCol;\n\n // self\n if (vDifference === 0 && hDifference === 0) return 'NO_DIRECTION';\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 /**\n * @param edge\n * @returns {Array<PathSegment>}\n */\n getPathFor(edge) {\n const direction = this.getEdgeDirection(edge);\n\n if (direction === 'NO_DIRECTION') return this._pathForNoDirection();\n if (direction === 'S_N') return this._pathForSouthToNorth(edge);\n if (direction === 'SW_NE') return this._pathForSouthWestToNorthEast(edge);\n if (direction === 'W_E') return this._pathForWestToEast(edge);\n if (direction === 'NW_SE') return this._pathForNorthWestToSouthEast(edge);\n if (direction === 'N_S') return this._pathForNorthToSouth(edge);\n if (direction === 'NE_SW') return this._pathForNorthEastToSouthWest(edge);\n if (direction === 'E_W') return this._pathForEastToWest(edge);\n if (direction === 'SE_NW') return this._pathForSouthEastToNorthWest(edge);\n return [];\n }\n\n _pathForNoDirection() {\n return [];\n }\n\n _pathForSouthToNorth(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow ] = this.getTargetPosition(edge);\n\n // если sourceIsBoundary, то сразу идем в обход, так же для реверса\n // todo: переписать под source\n if ((!this.isFlipped ? edge.source : edge.target).$type === 'bpmn:BoundaryEvent' && edge.id) return pathSegments;\n\n // TODO: при реверсе флипать сегменты перед отдачей? Need tests!\n // проверяем есть ли элементы между sourcePosition, targetPosition\n // если есть, то ребро пойдет в обход\n // так же оно пойдет в обход если элементы на соседних клетках и есть обратное ребро targetPosition-sourcePosition\n let hasIntermediateElements = this.hasIntermediateElements(this.getSourcePosition(edge), this.getTargetPosition(edge), true);\n\n // идем между ячейками грида\n if (hasIntermediateElements) return pathSegments;\n\n // проверяем петлю source -> target -> source\n const targetElementOutgoingEdges = this.getExistingOutgoingEdgesFor(!this.isFlipped ? edge.target : edge.source);\n const targetElementOutgoing = [ ...targetElementOutgoingEdges ].map(edge => !this.isFlipped ? edge.target : edge.source);\n\n // идем в обход если есть ребро в противоположном направлении\n if (targetElementOutgoing.includes(!this.isFlipped ? edge.source : edge.target)) 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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // если sourceIsBoundary, то пропускаем горизонтальную часть\n // todo: переписать под source без _originalSourceIsBoundary и без id\n if (!((!this.isFlipped ? edge.source : edge.target).$type === 'bpmn:BoundaryEvent' && edge.id)) {\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ , targetCol ] = this.getTargetPosition(edge);\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow ] = this.getTargetPosition(edge);\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ , targetCol ] = this.getTargetPosition(edge);\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // для sourceIsBoundary пропускаем горизонталь,\n // todo: переписать под source без _originalSourceIsBoundary\n if (!((!this.isFlipped ? edge.source : edge.target).$type === 'bpmn:BoundaryEvent' && edge.id)) {\n\n // пробуем новую схему для хост-хост без обхода\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n }\n\n // угловой сегмент\n // todo: переписать под source без _originalSourceIsBoundary\n if (!((!this.isFlipped ? edge.source : edge.target).$type === 'bpmn:BoundaryEvent' && edge.id)) {\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 getCrossedElementsFor(edge, byVertical = false) {\n const crossedElements = [];\n for (const segment of this.getPathFor(edge)) {\n const [ row, col ] = segment.position;\n const element = this.get(row, col);\n if (element && ((byVertical && segment.vCross) || (!byVertical && segment.hCross))) crossedElements.push(element);\n }\n return crossedElements;\n }\n\n isIntersect(edge, position, byVertical) {\n\n // быстрый расчет по направлениям\n const [ row, col ] = position;\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n const direction = this.getEdgeDirection(edge);\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.getExistingIncomingEdgesFor(!this.isFlipped ? edge.source : edge.target).some(edge => this.getEdgeDirection(edge) === 'NW_SE' || this.getEdgeDirection(edge) === 'W_E')) return true;\n return false;\n }\n\n return false;\n }\n\n /**\n * Получает ребра идущие назад и вверх\n * @param node\n * @returns {*}\n */\n getBackwardUpOutgoingEdgesFor(node) {\n return this.getExistingOutgoingEdgesFor(node).filter(edge => {\n const direction = this.getEdgeDirection(edge);\n return direction === 'S_N' || direction === 'SE_NW';\n });\n }\n\n /**\n * Создает копию грида\n * @returns {GridWithEdges}\n */\n getGridCopy() {\n return this._mergeGrids([ this ]);\n }\n\n /**\n * Удаляет ребро из грида\n * @param edge\n */\n removeEdge(edge) {\n this.graph.deleteEdge(edge);\n }\n\n getGraphSegmentFrom(node) {\n\n const segment = new Graph();\n\n // проходим только вперед\n // GetStartElementFunction<N> = (visited: Set<N>, initialGraph: Graph<N>) => N | undefined\n const getStartElement = (visited, initialGraph) => {\n if (!visited.has(node)) return node;\n };\n\n // GetNextFromExecutionSequence<N> = (executionSequence: Array<N>) => N | undefined\n const getNextFromExecutionSequence = (executionSequence) => {\n return executionSequence.pop();\n };\n\n // GetNextNodesFunction<N> = (node: N, graph: Graph<N>, visited: Set<N>, executionSequence: Array<N>) => Array<N> | undefined\n const getNextNodes = (node, graph, visited, executionSequence) => {\n const nextEdges = this.getExistingOutgoingEdgesFor(node).filter(edge => {\n const target = !this.isFlipped ? edge.target : edge.source;\n const source = !this.isFlipped ? edge.source : edge.target;\n return !visited.has(target) && target !== source;\n });\n\n segment.addNode(node);\n const nextNodes = nextEdges.map(edge => {\n return !this.isFlipped ? edge.target : edge.source;\n });\n\n for (const node of nextNodes) {\n segment.addNode(node);\n }\n\n for (const edge of nextEdges) {\n segment.addEdge(edge);\n }\n\n return nextNodes;\n };\n\n // AddNextNodesToExecutionSequence<N> = (nodes: Array<N>, executionSequence: Array<N>) => void;\n const addNextNodesToExecutionSequence = (nodes, executionSequence) => {\n for (const node of nodes) {\n executionSequence.push(node);\n }\n };\n\n\n this.graph.genericTraversing(getStartElement, getNextFromExecutionSequence, getNextNodes, addNextNodesToExecutionSequence);\n\n return segment;\n }\n\n getSegmentLeftCoordinates(segment) {\n\n const leftCoordinates = new Map();\n\n for (const node of segment.nodes) {\n const [ nodeRow, nodeCol ] = this.find(node);\n\n if (!leftCoordinates.has(nodeRow)) leftCoordinates.set(nodeRow, nodeCol);\n\n if (nodeCol < leftCoordinates.get(nodeRow)) leftCoordinates.set(nodeRow, nodeCol);\n\n // return leftCoordinates;\n\n }\n return leftCoordinates;\n }\n}\n","import {\n // eslint-disable-next-line no-unused-vars\n sortElementsTopLeftBottomRight, sortElementsTopLeftBottomRightColumn,\n} from '../utils/layoutUtils.js';\n// eslint-disable-next-line no-unused-vars\nimport { Graph } from 'graph-by-ivan-tulaev';\n\n\nexport function elementExecution(node, grid, executionSequence, visited, graph) {\n\n // получаем новые которых нет в гриде\n // todo: перенести код\n const newOutgoing = (!grid.isFlipped ? [ ...grid.initialGraph.getOutgoingEdgesFor(node) ] : [ ...grid.initialGraph.getIncomingEdgesFor(node) ]).filter(edge => !grid.hasElement(!grid.isFlipped ? edge.target : edge.source)).map(edge => !grid.isFlipped ? edge.target : edge.source);\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\n outgoing.forEach(nextElement => {\n\n // подготавливаем место\n const nextPosition = getInsertPosition (node, grid, nextElement);\n\n // вставляем элемент\n // todo: костыль вставляем attachedToRef\n if (grid.isFlipped && nextElement.$type === 'bpmn:BoundaryEvent' && nextElement.attachedToRef !== node) {\n const attachedToRef = nextElement.attachedToRef;\n if (!visited.has(attachedToRef)) {\n grid.add(attachedToRef, nextPosition);\n visited.add(attachedToRef);\n fixNewCrosses(attachedToRef, grid, graph, visited, executionSequence, nextElements, true);\n nextElements.unshift(nextElement);\n }\n }\n grid.add(nextElement, nextPosition);\n visited.add(nextElement);\n\n fixNewCrosses(nextElement, grid, graph, visited, executionSequence, nextElements, true);\n\n // выворачиваем\n // Верхние левые сдвигаем вперед и проверяем пересечения начиная с левого.\n // В идеале сдвигать только если у сдвигаемого элемента и сорса есть общий предок на его линии, чтобы не получился разрыв!\n // Вопрос по поводу переходов на другие линии выше для сорса...\n moveTopLeftOutgoingForward(nextElement, grid, executionSequence, graph, visited);\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 // todo: выбрать сегмент по всем идущим назад ребрами\n // двигать весь сегмент\n // нужны тестовые данные для этого кейса\n /*\n Алгоритм без выворачивания следующий.\n Вопрос по элементам ниже пока не двигаем - тоже их удаляем из копии.\n Делаем копию грида.\n Работаем по копии грида.\n Удаляем все элементы левее таргета.\n Удаляем все исходящие ребра из сорса. ---\n Строим сегмент графа из таргета.\n Если сорс в сегменте, то не двигаем.\n Находим крайние левые позиции сегмента.\n Двигаем в базовом гриде сегмент вправо таким образом, чтобы крайний левый элемент оказался правее сорса\n */\n // получаем ребра ведущие назад из элемента\n let existingEdges = grid.getBackwardUpOutgoingEdgesFor(node);\n\n // todo: пока без сортировки чтобы проверить концепцию сдвига\n while (existingEdges.length > 0) {\n\n const workingEdge = existingEdges.shift();\n\n // todo: оптимизировать\n const newTarget = !grid.isFlipped ? workingEdge.target : workingEdge.source;\n if (grid.find(newTarget)[1] > grid.find(node)[1]) continue;\n\n\n\n const gridCopy = grid.getGridCopy();\n\n // todo: костыль\n const realEdge = [ ...gridCopy._allEdges ].find(edge => edge.source === workingEdge.source && edge.target === workingEdge.target && edge.id === workingEdge.id);\n\n gridCopy.removeEdge(realEdge);\n\n const source = !grid.isFlipped ? realEdge.source : realEdge.target;\n const target = !grid.isFlipped ? realEdge.target : realEdge.source;\n\n const sourcePos = gridCopy.find(source);\n const targetPos = gridCopy.find(target);\n\n for (const element of gridCopy.elements) {\n const elementPos = gridCopy.find(element);\n\n // убираем только те, что левее target\n if (elementPos[1] < targetPos[1]) gridCopy.removeElement(element);\n }\n\n const graphSegment = gridCopy.getGraphSegmentFrom(target);\n\n if (graphSegment.nodes.includes(source)) continue;\n\n const segmentCords = Array.from(gridCopy.getSegmentLeftCoordinates(graphSegment));\n\n const minColPosition = segmentCords.reduce((acc, cur) => {\n if (acc === undefined) return cur;\n return cur[1] < acc[1] ? cur : acc;\n }, undefined);\n\n const minRowPosition = segmentCords.reduce((acc, cur) => {\n if (acc === undefined) return cur;\n return cur[0] < acc[0] ? cur : acc;\n }, undefined);\n\n const maxRowPosition = segmentCords.reduce((acc, cur) => {\n if (acc === undefined) return cur;\n return cur[0] > acc[0] ? cur : acc;\n }, undefined);\n\n\n\n const shift = sourcePos[1] - minColPosition[1] + 1;\n\n const newMap = new Map(segmentCords);\n\n let previousShiftPos = undefined; // [row, col]\n\n for (let rowIndex = 0; rowIndex < grid.rowCount; rowIndex++) {\n\n const getShiftPos = () => {\n\n // todo: погонять тесты\n // здесь надо смещать все что выше\n if (rowIndex < minRowPosition[0]) {\n previousShiftPos = minRowPosition[0];\n return minRowPosition[1] - 1; // выше сегмента\n }\n if (newMap.has(rowIndex)) {\n previousShiftPos = newMap.get(rowIndex);\n return newMap.get(rowIndex) - 1;\n }\n\n // посреди сегмента выше ноды\n if (rowIndex > minRowPosition[0] && rowIndex < maxRowPosition[0] && rowIndex < grid.find(node)[0]) {\n return previousShiftPos;\n }\n\n\n if (rowIndex === grid.find(node)[0] || rowIndex > minRowPosition[0]) {\n const curItemPos = grid.find(node);\n previousShiftPos = curItemPos;\n\n return curItemPos[1];\n }\n\n return previousShiftPos;\n };\n\n\n const shiftPos = getShiftPos() ;\n\n grid.expandRow(rowIndex, shiftPos, shift);\n }\n }\n grid.toRectangle();\n}\n\nfunction inStackWithoutOutgoing(node, executionSequence, grid) {\n const inStack = executionSequence.includes(node);\n const outgoing = grid.getExistingOutgoingEdgesFor(node);\n\n return inStack && (!outgoing || outgoing.length === 0);\n}\n\n/**\n * Пробуем делать укороченный проход чтобы не грузить проц - посмотрим как будет рисоваться\n * @param {Element} element\n * @param {Element} fromElement\n * @param {boolean} backward\n */\n\n// todo: где еще используется кроме move forward\n// eslint-disable-next-line no-unused-vars\nfunction isTracingForTopLeftMove(node, to, graph, unwantedEdge, visited, grid, backward) {\n\n // не двигаем если таргет трейсится по обратному пути\n // получаем существующий граф\n const gridCopy = grid.getGridCopy();\n\n // удаляем ненужное ребро\n gridCopy.removeEdge(unwantedEdge);\n\n // удаляем все вершины левее to\n for (const node of gridCopy.elements) {\n if (gridCopy.find(node)[1] < gridCopy.find(to)[1]) gridCopy.removeElement(node);\n }\n\n // todo: отладить scenario.issue-32.bpmn и gateway.multiple.bpmn\n return gridCopy.graph.isNodeTraced(node, to, backward); // норм проверить реверс !!!! Вот это правильно, но ломает gateway.multiple.bpmn\n}\n\n/**\n * @param grid\n * @param {[number, number]} topLeftPosition\n * @param {[number, number]} bottomRightPosition\n */\n// eslint-disable-next-line no-unused-vars\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\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 = grid.getExistingOutgoingEdgesFor(node) ;\n const incoming = grid.getExistingIncomingEdgesFor(node).map(edge => !grid.isFlipped ? edge.source : edge.target);\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, executionSequence, grid)) return false;\n\n\n // исключаем если общий родитель, так как уже расставили их правильно\n // пробуем нет входящих кроме element\n // если есть общий родитель и есть новые исходящие то выкидываем\n const targetIncoming = grid.getExistingIncomingEdgesFor(target)\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, grid, nextEl) {\n\n // todo: пока костыль\n if (grid.isFlipped && nextEl.$type === 'bpmn:BoundaryEvent' && grid.hasElement(nextEl.attachedToRef)) return grid.find(nextEl.attachedToRef);\n\n const nextOnElement = nextEl.attachedToRef === element;\n if (nextOnElement) return grid.find(element);\n\n const sourcePosition = grid.find(element);\n if (!sourcePosition) return;\n\n // по умолчанию располагаем справа от element или по диагонали\n const isBoundarySource = element.$type === 'bpmn:BoundaryEvent' && !grid.isFlipped;\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\n // todo: надо смотреть реверс\n for (const item of allItemsInElementPosition) {\n [ ...grid.getExistingOutgoingEdgesFor(item) ]\n\n // .filter(edge => edge.target !== edge.source && visited.has(edge.source) && visited.has(edge.target))\n .filter(edge => edge.target !== edge.source)\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 (grid.getTargetPosition(edge)[0] === i && grid.getTargetPosition(edge)[1] === position[1]) || grid.isIntersect(edge, point, false) || grid.isIntersect(edge, point, true);\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 // todo: убрать на после вставки?\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 ] = grid.getTargetPosition(a);\n const [ bRow, bCol ] = grid.getTargetPosition(b);\n return aRow - bRow || aCol - bCol;\n });\n const incomingEdges = [ ...grid.getExistingIncomingEdgesFor(element) ]\n .sort((a, b) => {\n const [ aRow, aCol ] = grid.getSourcePosition(a);\n const [ bRow, bCol ] = grid.getSourcePosition(b);\n return aRow - bRow || aCol - bCol;\n });\n\n const edges = [ ...outgoingEdges, ...incomingEdges ]\n .filter(edge => {\n const { target, source } = edge;\n const direction = grid.getEdgeDirection(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, stack, grid)) 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 (grid.getEdgeDirection(edge) === 'E_W' && ((!grid.isFlipped ? edge.source : edge.target).$type === 'bpmn:BoundaryEvent' && edge.id)) 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 = grid.getEdgeDirection(edge);\n\n if (direction === 'W_E' || direction === 'E_W') return;\n\n const vCrossed = grid.getCrossedElementsFor(edge, 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 = grid.getEdgeDirection(edge);\n\n // по этим направлениям не предполагается горизонтальных пересечений\n if (direction === 'S_N' || direction === 'N_S') return;\n\n const hCrossed = grid.getCrossedElementsFor(edge, false);\n\n if (hCrossed.length === 0) return;\n\n if (direction === 'SW_NE') {\n\n // поднимаем элементы выше пересечения\n const maxDown = getMaxDown(edge, grid);\n const [ baseSourceRow ] = grid.getSourcePosition(edge);\n\n for (let i = maxDown; i > 0; i--) {\n grid.createRow(baseSourceRow - 1);\n }\n\n const elements = grid.getElementsInRange({ row: grid.getSourcePosition(edge)[0], col: grid.getSourcePosition(edge)[1] + 1 }, { row: grid.rowCount - 1, col: grid.colCount - 1 });\n\n for (const element of elements) {\n const [ row, col ] = grid.find([ ...element ][0]);\n for (const innerElement of [ ...element ]) {\n 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, grid) {\n const sourcePosition = grid.getSourcePosition(edge);\n const targetPosition = grid.getTargetPosition(edge);\n\n let maxDown = sourcePosition[0];\n\n for (let rowIndex = sourcePosition[0]; rowIndex < grid.rowCount; rowIndex++) {\n if (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 { DEFAULT_CELL_HEIGHT, DEFAULT_CELL_WIDTH, getBounds } from '../utils/layoutUtils.js';\nimport { getOutgoingElements } from '../utils/elementUtils.js';\nimport { getDefaultSize, is } from '../di/DiUtil.js';\n\nexport default function createElementDi(element, row, col, diFactory, grid, shift) {\n if (element.di) return [];\n\n if (element.$type === 'bpmn:BoundaryEvent') {\n return createBEl(element, row, col, diFactory, grid, 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\nfunction createBEl(element, row, col, diFactory, grid, 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 // первыми должны отрисовываться те, у которых потомки ниже и правей\n let neighboursBoundary = element.$parent.flowElements.filter(item => item.attachedToRef === element.attachedToRef && grid.hasElement(element));\n neighboursBoundary = getSortedElementsByOutgoingPosition(neighboursBoundary, grid);\n neighboursBoundary.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}\n\n// Первыми идут те у которых исходящие ниже\nfunction getSortedElementsByOutgoingPosition(elements, grid) {\n return elements.sort((a, b) => {\n const aBottomRightChildPosition = getPositionRightBottomOutgoingElement(a, grid);\n const bBottomRightChildPosition = getPositionRightBottomOutgoingElement(b, grid);\n\n return aBottomRightChildPosition[0] - bBottomRightChildPosition[0] || aBottomRightChildPosition[1] - bBottomRightChildPosition[1];\n }).reverse();\n}\n\nfunction getPositionRightBottomOutgoingElement(element, grid) {\n return getOutgoingElements(element).reduce((prev, cur) => {\n if (!grid.hasElement(cur)) return prev;\n const curPosition = grid.find(cur);\n if (prev === undefined) return curPosition;\n if (prev[0] < curPosition[0] || prev[1] < curPosition[1]) return curPosition;\n return prev;\n }, [ 0 ,0 ]);\n}","import BPMNModdle from 'bpmn-moddle';\nimport { addToEnd, getLast, Graph } from 'graph-by-ivan-tulaev';\n\n// todo: настроить сборщик resolve js\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 { GridWithEdges } from './GridWithEdges.js';\nimport { elementExecution } from './newHandlers/outgoingHandler.js';\nimport createConnection from './newHandlers/createConnection.js';\nimport createElementDi from './newHandlers/createElementDi.js';\nimport { Edge } from './Edge.js';\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.maxDebugStep = debuggerCounter;\n this.currentDebugStep = 0;\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 // expand grids\n this.expandProcessesGrids();\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 createGridsForProcesses() {\n\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => a.level - b.level);\n\n // create and add grids for each process\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.shakeIt(true);\n grid.shakeIt(false);\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 }\n\n expandProcessesGrids() {\n\n // root processes should be processed last for element expanding\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => b.level - a.level);\n\n for (const process of processes) {\n\n // separate base grid to independent grids\n const tempGridCollection = process.grid._separateGrid() || [ process.grid ];\n\n for (const grid of tempGridCollection) {\n grid.shrinkRows();\n grid.shrinkCols();\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 const sortedProcesses = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n sortedProcesses.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 // todo: сделать понятнее для this.maxDebugStep\n if (process.isExpanded && !this.existingNodes.includes(process)) continue;\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\n get existingNodes() {\n return this.processTrees.map(graph => [ ...graph.nodes ]).flat().map(item => [ ...item.grid.elements ]).flat();\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\n // todo: debug mode сделать презентабельнее\n const existNodes = this.existingNodes;\n if (!existNodes.includes(sourceRef) || !existNodes.includes(targetRef)) continue;\n\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\n // create graph from elements\n const processGraph = new Graph();\n const grid = new GridWithEdges(processGraph);\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 // todo: переписать компактней\n for (const node of processGraph.nodes) {\n\n // boundary\n // добавляем два ребра, так как у нас направленный граф\n if (node.$type === 'bpmn:BoundaryEvent') {\n processGraph.addEdge(new Edge(node, node.attachedToRef));\n processGraph.addEdge(new Edge(node.attachedToRef, node));\n }\n\n // sequenceFlow\n for (const outgoingItem of node.outgoing || []) {\n const newEdge = new Edge(outgoingItem.sourceRef, outgoingItem.targetRef);\n newEdge.id = outgoingItem.id;\n processGraph.addEdge(newEdge);\n }\n\n // data associations - двигаемся от связанной ноды\n const dataInputAssociations = node.dataInputAssociations;\n for (const association of dataInputAssociations || []) {\n for (const dataSource of association.sourceRef || []) {\n const newEdge = new Edge(dataSource, association.$parent);\n newEdge.id = association.id;\n newEdge.propRef = association.targetRef;\n processGraph.addEdge(newEdge);\n }\n }\n\n const dataOutputAssociations = node.dataOutputAssociations;\n for (const association of dataOutputAssociations || []) {\n const source = association.$parent;\n const target = association.targetRef;\n const newEdge = new Edge(source, target);\n newEdge.id = association.id;\n processGraph.addEdge(newEdge);\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 flippedStartElement = initialGraph.nodes.find(node => {\n\n if (visited.has(node)) return false;\n\n let outgoingEdges = !grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ].filter(edge => edge.target !== edge.source);\n\n return outgoingEdges.length === 0;\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 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 // todo: костыль\n const eleByPos = layoutGrid.elementsByPosition().sort((a,b) => {\n const aType = a.element.$type === 'bpmn:BoundaryEvent' ? 0 : 1;\n const bType = b.element.$type === 'bpmn:BoundaryEvent' ? 0 : 1;\n\n return bType - aType;\n });\n\n eleByPos.forEach(({ element, row, col }) => {\n const dis = createElementDi(element, row, col, diFactory, layoutGrid, shift);\n planeElement.push(...dis);\n });\n\n // todo: заменить на ребра?\n // Step 2: Create DI for all connections\n layoutGrid._allEdges.forEach(edge => {\n const connection = createConnection(edge, layoutGrid, diFactory, shift);\n if (connection) planeElement.push(connection);\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 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 {\n connectElements,\n} from '../utils/layoutUtils.js';\n\nexport default function createConnection(edge, layoutGrid, diFactory, shift) {\n const { id } = edge;\n\n // todo: пока костыль для отрисовки только тех, которые с id\n if (!id) return;\n\n const waypoints = connectElements(edge, layoutGrid, false, shift);\n return diFactory.createDiEdge(edge, waypoints, {\n id: id + '_di'\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","getOutgoingElements","Error","outgoingElements","outgoing","map","out","targetRef","Set","isStartIntermediate","undefined","incoming","length","DEFAULT_CELL_WIDTH","DEFAULT_CELL_HEIGHT","isFlipped","utilsGetOutgoingElements","concat","attachedOutgoing","attachers","sort","a","b","attacher","reverse","flat","filter","item","index","self","indexOf","add","getAttachedOutgoingElements","connectElements","edge","layoutGrid","isBoundary","shift","source","target","sourceDi","di","targetDi","sourceBounds","get","targetBounds","sourceMid","getMid","targetMid","edgeDirection","getEdgeDirection","dX","gridPosition","col","dY","row","dockingSource","dockingTarget","x","sourceX","y","sourceY","coordinatesToPosition","targetX","sourceIsBoundary","$type","getDockingPoint","attachedToRef","isExpanded","grid","rowCount","elementsInMiddle","candidate","push","hasReversEdge","includes","firstPoint","lastPoint","maxExpanded","sourceRow","sourceCol","find","targetCol","firstCol","lastCol","elementsInRange","elements","size","reduce","acc","cur","getGridDimensions","getMaxExpandedBetween","hasSW_NEOut","getExistingOutgoingEdgesFor","some","colCount","elementsInHorizontal","directManhattan","targetRow","totalElements","bendPoint","getElementsInRange","directManhattanConnect","startPoint","endPoint","yOffset","Math","sign","bounds","point","rectangle","dockingDirection","targetOrientation","test","original","getBounds","attachedTo","hostBounds","round","sortByType","arr","types","typesArray","result","forEach","matching","DiFactory","constructor","moddle","this","create","attrs","createDiBounds","createDiLabel","createDiShape","semantic","assign","bpmnElement","createDiWaypoints","waypoints","pos","createDiWaypoint","pick","createDiEdge","waypoint","createDiPlane","createDiDiagram","Grid","newGrid","Array","i","_grid","_elements","elementsCount","firstRow","position","isValidPosition","_addStart","toRectangle","move","toPosition","has","removeElementAt","removeElement","setPos","delete","createRow","afterIndex","Number","isInteger","splice","createCol","rowIndex","expandRow","placeholder","findIndex","el","startRow","startCol","endRow","endCol","numRows","maxCols","currentRowLength","elementsByPosition","colIndex","shrinkCols","every","shrinkRows","difference","flipHorizontally","hasElement","isArray","hasIntermediateElements","firstPosition","lastPosition","onVertical","start","end","hasElementAt","Edge","GridWithEdges","initialGraph","super","graph","Graph","addNode","_createNewEdgesFor","deleteNode","allEls","edges","prev","getAllExistingEdgesFor","newEdge","id","_addEdgeToGrid","_edgeIsExist","existingEdge","addEdge","isCrossed","byVertical","_allEdges","isIntersect","hasAnyCross","getCrossedElementsFor","shakeIt","sortedElements","aPos","bPos","sortColsLeftRightRowsBottomTop","pop","chain","getChain","chainElement","deleteIndex","baseRow","baseCol","allPositionsAreFine","curPos","newPositionsAreFine","checkedRow","checkedCol","chainElementPosition","hasNewCrosses","newChain","oldChain","elementPosition","elInPos","nextElement","nextChain","nextChainEl","getIncomingEdgesFor","getOutgoingEdgesFor","getExistingIncomingEdgesFor","outgoingEdges","incomingEdges","_separateGrid","separatedGraphs","mergeGraphs","getSeparatedGraphs","grids","minRow","maxRow","node","nodes","_superAdd","_mergeGrids","rowShift","getSourcePosition","getTargetPosition","sourcePosition","targetPosition","vDifference","hDifference","getPathFor","direction","_pathForNoDirection","_pathForSouthToNorth","_pathForSouthWestToNorthEast","_pathForWestToEast","_pathForNorthWestToSouthEast","_pathForNorthToSouth","_pathForNorthEastToSouthWest","_pathForEastToWest","_pathForSouthEastToNorthWest","pathSegments","vCross","hCross","crossedElements","segment","getBackwardUpOutgoingEdgesFor","getGridCopy","removeEdge","deleteEdge","getGraphSegmentFrom","genericTraversing","visited","executionSequence","nextEdges","nextNodes","getSegmentLeftCoordinates","leftCoordinates","Map","nodeRow","nodeCol","set","elementExecution","newOutgoing","outgoingFromStack","hasNewOutgoings","elementCol","processingElements","inStackWithoutOutgoing","targetEdge","targetParent","sortElementsTopLeftBottomRight","processingElement","getOutgoingFromStack","nextElements","nextPosition","nextEl","isBoundarySource","elPos","allItemsInElementPosition","elementPositionEdges","crossedOrOccupied","getInsertPosition","fixNewCrosses","unshift","existingEdges","workingEdge","newTarget","gridCopy","realEdge","sourcePos","targetPos","graphSegment","segmentCords","from","minColPosition","minRowPosition","maxRowPosition","newMap","previousShiftPos","shiftPos","curItemPos","getShiftPos","moveTopLeftOutgoingForward","nextBoundaries","nextOther","inStack","stack","skipTopLeftOutgoing","forwardOnlyOutgoing","aRow","aCol","bRow","bCol","fixNewVerticalCrosses","fixNewHorizontalCrosses","vCrossed","pushVerticalEdgeBy","moveElementsRighterCrossLine","hCrossed","maxDown","getMaxDown","baseSourceRow","innerElement","moveElementsUpperCrossLine","moveElementsUnderCrossLine","innerItem","createElementDi","diFactory","DIs","neighboursBoundary","$parent","flowElements","aBottomRightChildPosition","getPositionRightBottomOutgoingElement","bBottomRightChildPosition","getSortedElementsByOutgoingPosition","att","attacherDi","createBEl","options","isMarkerVisible","shapeDi","curPosition","Layouter","debuggerCounter","BPMNModdle","maxDebugStep","currentDebugStep","layoutProcess","xml","moddleObj","fromXML","rootElement","diagram","bpmnModel","allElements","elementsById","Object","values","setExpandedProcesses","processTrees","createNestedSets","createGridsForProcesses","expandProcessesGrids","rootProcesses","getRootProcesses","collaboration","getCollaboration","cleanDi","createRootDi","drawParticipants","drawProcesses","drawCollaborationMessageFlows","toXML","format","processes","level","process","createGridLayout","tempGridCollection","expandGridHorizontally","expandGridVertically","participants","participant","createParticipantDi","sortedProcesses","getParticipantForProcess","participantDi","getElementDi","getProcDi","generateDi","existingNodes","baseProcDi","diagrams","plane","messageFlows","message","sourceRef","existNodes","processRef","planeElement","processGraph","allProcesses","getAllProcesses","children","getSubProcesses","child","rootProcess","getStartElement","root","left","getNextNodes","outgoingNode","maxRight","right","getLast","addToEnd","mainElement","createProcessDi","planeDi","diagramDi","origin","defaultWidth","defaultHeight","flowElement","outgoingItem","dataInputAssociations","association","dataSource","propRef","dataOutputAssociations","targetElementInGridSourceNotExist","primaryStartElements","sourceElementInGridTargetNotExist","otherStartingElement","flippedStartElement","procDi","aType","dis","connection","createConnection","elementsInCol","j","maxColCount","elementsInRow","maxRowCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../lib/di/DiUtil.js","../lib/utils/elementUtils.js","../lib/utils/layoutUtils.js","../lib/di/DiFactory.js","../lib/Grid.js","../lib/GridWithEdges.js","../lib/newHandlers/outgoingHandler.js","../lib/newHandlers/createElementDi.js","../lib/Edge.js","../lib/Layouter.js","../lib/newHandlers/createConnection.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 if (!element) throw new Error('Element is not defined in getOutgoingElements');\n const outgoingElements = (element.outgoing || []).map(out => out.targetRef);\n\n // возвращаем уникальные, так как BPMN может быть не валидным\n return [ ...new Set(outgoingElements) ];\n}\n\nexport function getIncomingElements(element) {\n if (!element) throw new Error('Element is not defined in getIncomingElements');\n let incomingElements = (element.incoming || []).map(out => out.sourceRef);\n\n // возвращаем уникальные, так как BPMN может быть не валидным\n return [ ...new Set(incomingElements) ];\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\n/**\n * Modified Manhattan layout: Uses space between grid columns to route connections\n * if direct connection is not possible.\n * @param edge\n * @param layoutGrid\n * @param shift\n * @returns waypoints\n */\nexport function connectElements(edge, layoutGrid, shift) {\n\n const { source, target } = edge;\n\n // TODO: Use GridController 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 // todo: убрать dX ???\n const edgeDirection = layoutGrid.getEdgeDirection(edge);\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 sourceIsBoundary = source.$type === 'bpmn:BoundaryEvent';\n\n // Source === Target ==> Build loop\n if (edgeDirection === 'NO_DIRECTION') {\n\n if (sourceIsBoundary) 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 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 (edgeDirection === 'S_N') {\n\n if (sourceIsBoundary) 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 const hasReversEdge = [ ...getOutgoingElements(target) ].includes(source);\n\n if (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 (edgeDirection === 'SW_NE') {\n if (sourceIsBoundary) 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 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 (edgeDirection === 'W_E') {\n\n if (sourceIsBoundary) 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 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 (edgeDirection === 'NW_SE') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l')\n ];\n\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 (edgeDirection === 'N_S') {\n\n if (sourceIsBoundary) {\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 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 (edgeDirection === 'NE_SW') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'r')\n ];\n\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 (edgeDirection === 'E_W') {\n\n if (sourceIsBoundary) {\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 // пока так по колхозному\n const hasReversEdge = utilsGetOutgoingElements(target).includes(source);\n\n // TODO: Remove by new edge drawing logic\n let hasSW_NEOut = layoutGrid ? layoutGrid.getExistingOutgoingEdgesFor(target) : [];\n hasSW_NEOut = hasSW_NEOut.some(item => layoutGrid.getEdgeDirection(item) === 'SW_NE');\n\n if (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 (edgeDirection === 'SE_NW') {\n if (sourceIsBoundary) 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 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 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 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 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 return aPos[0] - bPos[0] || bPos[1] - aPos[1];\n };\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 return aPos[1] - bPos[1] || bPos[0] - aPos[0];\n };\n}\n\n/**\n *\n * @param {*[]} arr array of BPMN elements\n * @param {string|string[]} types array of types\n * @returns {*[]} sorted array of BPMN elements\n */\nexport function sortByType(arr, types) {\n const typesArray = [ types ].flat();\n\n let result = [];\n\n if (typesArray.length > 0) {\n typesArray.forEach((type,index) => {\n const matching = arr.filter(item => is(item, type));\n result = result.concat(matching);\n if (index === typesArray.length - 1 && result.length !== arr.length) {\n for (const item of arr) {\n if (!result.includes(item)) result.push(item);\n }\n }\n });\n } else {\n result = arr;\n }\n\n return result;\n}\n\nfunction getMaxExpandedBetween(source, target, layoutGrid) {\n const [ sourceRow, sourceCol ] = layoutGrid.find(source);\n const [ , targetCol ] = layoutGrid.find(target);\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 return item.size !== undefined ? [ ...item ] : 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 return cur.grid?.getGridDimensions()[0] > acc ? cur.grid?.getGridDimensions()[0] : 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","export class Grid {\n constructor() {\n this.isFlipped = false;\n this._elements = new Map();\n this.rows = {};\n this.cols = {};\n }\n\n get rowCount() {\n return Object.keys(this.rows).length;\n }\n\n get colCount() {\n return Object.keys(this.cols).length;\n }\n\n get elementsCount() {\n return this._elements.size;\n }\n\n get elements() {\n return new Set (this._elements.keys());\n }\n\n /**\n *\n * @param element\n * @param {[number, number]} position - numbers are integer\n */\n add(element, position) {\n\n if (this._elements.has(element)) throw new Error(`Cannot add element duplicated element ${JSON.stringify(element)}`);\n\n if (!position) {\n this._addStart(element);\n return;\n }\n\n const lastRow = this.rowCount - 1;\n const lastCol = this.colCount - 1;\n\n const rowDif = position[0] - lastRow;\n const colDif = position[1] - lastCol;\n this.addRowCol(false, lastRow >= 0 ? lastRow : undefined, rowDif);\n this.addRowCol(true, lastCol >= 0 ? lastCol : undefined, colDif);\n\n this._elements.set(element, position);\n this._addElementToRowsCols(element, position);\n }\n\n _addElementToRowsCols(element) {\n const position = this._elements.get(element);\n this.rows[position[0]] ? this.rows[position[0]].add(element) : this.rows[position[0]] = new Set([ element ]);\n this.cols[position[1]] ? this.cols[position[1]].add(element) : this.cols[position[1]] = new Set([ element ]);\n }\n _removeElementFromRowsCols(element) {\n const position = this._elements.get(element);\n if (this.rows[position[0]]) this.rows[position[0]].delete(element);\n if (this.cols[position[1]]) this.cols[position[1]].delete(element);\n }\n\n _addStart(element) {\n const [ row, ] = this.getGridDimensions();\n this._elements.set(element, [ row, 0 ]);\n this._addElementToRowsCols(element, [ row, 0 ]);\n }\n\n move(element, toPosition) {\n if (!this.elements.has(element)) throw new Error(`Cannot move element not exist element ${element.toString()}`);\n if (!this.isValidPosition(toPosition)) throw new Error(`Cannot move element ${element.toString()} to invalid position ${toPosition}`);\n this._removeElementFromRowsCols(element);\n this._elements.set(element, toPosition);\n this._addElementToRowsCols(element, toPosition);\n }\n\n removeElement(element) {\n if (this._elements.has(element)) {\n this._removeElementFromRowsCols(element);\n this._elements.delete(element);\n }\n }\n\n addRowCol(addCol, afterIndex, count = 1) {\n\n // добавляем линии\n const gridCount = addCol ? this.colCount : this.rowCount;\n const addCount = afterIndex >= gridCount - 1 ? afterIndex - (gridCount - 1) + count : count;\n for (let i = 0; i < addCount; i++) {\n if (addCol) {\n this.cols[gridCount + i] = new Set();\n } else {\n this.rows[gridCount + i] = new Set();\n }\n }\n\n // перемещаем элементы\n for (const [ item, elementPosition ] of this._elements.entries()) {\n const position = addCol ? elementPosition[1] : elementPosition[0];\n\n if (position > afterIndex || afterIndex === undefined) {\n this._removeElementFromRowsCols(item);\n elementPosition[addCol ? 1 : 0] += count;\n this._addElementToRowsCols(item);\n }\n }\n }\n\n /**\n * Для добавления перед первым элементом afterIndex = undefined\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 = 1) {\n\n if (!Number.isInteger(rowIndex) || rowIndex < 0 || rowIndex > this.rowCount - 1) throw new Error (`Can't expand row with index: ${rowIndex}. Grid row count is ${this.rowCount}`);\n\n // готовим строку\n const gridColCount = this.colCount;\n const addCount = afterIndex >= gridColCount - 1 ? afterIndex - (gridColCount - 1) + colCount : colCount;\n for (let i = 0; i < addCount; i++) {\n this.cols[gridColCount + i] = new Set();\n }\n\n // перемещаем элементы\n [ ...this.rows[rowIndex] ].forEach(item => {\n const position = this.find(item);\n if (position[1] > afterIndex || afterIndex === undefined) {\n this._removeElementFromRowsCols(item);\n position[1] += colCount;\n this._addElementToRowsCols(item);\n }\n });\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 return this._elements.get(element);\n }\n\n get(row, col) {\n\n // todo: make simple to read\n const elementsAtPosition = new Set ([ ...this._elements.entries() ].filter(([ item, position ]) => position[0] === row && position[1] === col)\n .map(item => item[0]));\n\n return elementsAtPosition.size ? elementsAtPosition : null;\n }\n\n getElementsInRange({ row: startRow, col: startCol }, { row: endRow, col: endCol }) {\n\n if (startRow > endRow) {\n [ startRow, endRow ] = [ endRow, startRow ];\n }\n\n if (startCol > endCol) {\n [ startCol, endCol ] = [ endCol, startCol ];\n }\n\n return [ ...this._elements.entries() ]\n .filter(([ , position ]) => position[0] >= startRow && position[0] <= endRow && position[1] >= startCol && position[1] <= endCol)\n .map(item => item[0]);\n }\n\n getGridDimensions() {\n const rows = this.rowCount;\n const cols = this.colCount;\n\n return [ rows, cols ];\n }\n\n // todo: переписать на строки\n shrink(byVertical) {\n\n // Отсортированный массив элементов по строкам или столбцам\n const sortedElements = [ ...this._elements.entries() ]\n .sort((a, b) => {\n const aPosition = !byVertical ? a[1][1] : a[1][0];\n const bPosition = !byVertical ? b[1][1] : b[1][0];\n return aPosition - bPosition;\n });\n\n // актуальный индекс = 0\n // смещение = 0\n let shift = 0;\n let previousIndex = null;\n\n for (const element of sortedElements) {\n\n // У элемента берём позицию\n const position = !byVertical ? element[1][1] : element[1][0];\n this._removeElementFromRowsCols(element[0], element[1]);\n\n if (previousIndex === null) {\n shift = position;\n this._elements.set(element[0], !byVertical ? [ element[1][0], element[1][1] - shift ] : [ element[1][0] - shift, element[1][1] ]);\n this._addElementToRowsCols(element[0], !byVertical ? [ element[1][0], element[1][1] - shift ] : [ element[1][0] - shift, element[1][1] ]);\n previousIndex = position;\n } else if (previousIndex === position) {\n this._elements.set(element[0], !byVertical ? [ element[1][0], element[1][1] - shift ] : [ element[1][0] - shift, element[1][1] ]);\n this._addElementToRowsCols(element[0], !byVertical ? [ element[1][0], element[1][1] - shift ] : [ element[1][0] - shift, element[1][1] ]);\n } else if (position - previousIndex === 1) {\n this._elements.set(element[0], !byVertical ? [ element[1][0], element[1][1] - shift ] : [ element[1][0] - shift, element[1][1] ]);\n this._addElementToRowsCols(element[0], !byVertical ? [ element[1][0], element[1][1] - shift ] : [ element[1][0] - shift, element[1][1] ]);\n previousIndex = position;\n } else {\n shift = shift + position - previousIndex - 1;\n this._elements.set(element[0], !byVertical ? [ element[1][0], element[1][1] - shift ] : [ element[1][0] - shift, element[1][1] ]);\n this._addElementToRowsCols(element[0], !byVertical ? [ element[1][0], element[1][1] - shift ] : [ element[1][0] - shift, element[1][1] ]);\n previousIndex = position;\n }\n }\n\n // todo: пока не смотрим на размер эленментов, а просто удаляем пустые строки\n // Здесь уже все сдвинуты\n for (const [ key, value ] of Object.entries(!byVertical ? this.cols : this.rows)) {\n if (value.size === 0) {\n if (!byVertical) {\n delete this.cols[key];\n } else {\n delete this.rows[key];\n }\n }\n }\n\n }\n\n flip(byVertical) {\n\n // Получить измерения\n const [ rowCount, colCount ] = this.getGridDimensions();\n\n // Для каждой позиции\n // - измерение - 1 - позиция\n for (const [ element, position ] of this._elements.entries()) {\n this._removeElementFromRowsCols(element, position);\n this._elements.set(element, !byVertical ? [ position[0], colCount - 1 - position[1] ] : [ rowCount - 1 - position[0], position[1] ]);\n this._addElementToRowsCols(element, !byVertical ? [ position[0], colCount - 1 - position[1] ] : [ rowCount - 1 - position[0], position[1] ]);\n }\n\n // todo: add directional flip flag\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)) 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 ? firstPosition[0] !== lastPosition[0] : firstPosition[1] !== lastPosition[1]) return false;\n\n const index = !onVertical ? firstPosition[1] : firstPosition[0];\n const [ start, end ] = !onVertical ? (firstPosition[1] <= lastPosition[1] ? [ firstPosition[1] , lastPosition[1] ] : [ lastPosition[1], firstPosition[1] ]) : (firstPosition[0] <= lastPosition[0] ? [ firstPosition[0] , lastPosition[0] ] : [ lastPosition[0], firstPosition[0] ]);\n return [ ...this._elements.values() ].some(item => !onVertical ? item[0] === index && item[1] > start && item[1] < end : item[1] === index && item[0] > start && item[0] < end);\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}","import { Graph } from 'graph-by-ivan-tulaev';\n\nimport { Grid } from './Grid.js';\n\nimport {\n sortByType,\n sortColsLeftRightRowsBottomTop, sortElementsTopRightBottomLeft,\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(initialGraph) {\n super();\n\n this.initialGraph = initialGraph;\n this.graph = new Graph();\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\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n }\n\n removeElement(element) {\n this.graph.deleteNode(element);\n\n super.removeElement(element);\n }\n\n move(element, toPosition) {\n const allEls = [ ...this.get(...this.find(element)) ];\n const edges = allEls.reduce((prev, cur) => {\n return [ ...prev, ...this.getAllExistingEdgesFor(cur) ];\n }, []);\n\n for (const el of allEls) {\n this.removeElement(el);\n this.add(el, toPosition);\n }\n\n for (const edge of edges) {\n this._addEdgeToGrid(edge);\n }\n }\n\n /**\n * Проверка существования для НОВЫХ ребер\n * Со старыми только через мапу\n * @param edge\n * @returns {*}\n * @private\n */\n _edgeIsExist(edge) {\n return [ ...this.graph.edges ].includes(edge);\n }\n\n _addEdgeToGrid(edge) {\n if (!this._edgeIsExist(edge)) this.graph.addEdge(edge);\n }\n\n /**\n *\n * @param element element\n * @private\n */\n _createNewEdgesFor(element) {\n\n // todo: переписать под обертку\n const edges = [ ...this.initialGraph.getOutgoingEdgesFor(element), ...this.initialGraph.getIncomingEdgesFor(element) ]\n .filter(edge => this.hasElement(edge.source) && this.hasElement(edge.target));\n for (const edge of edges) {\n this._addEdgeToGrid(edge);\n }\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 = false) {\n\n return [ ...this._allEdges ].some(edge => this.isIntersect(edge, position, byVertical));\n }\n\n get _allEdges() {\n return this.graph.edges;\n }\n\n /**\n * Пока так наличие пересечений определим\n * @param {Edge[]=} edges\n * @returns {boolean}\n */\n hasAnyCross(edges) {\n const executedEdges = edges ? edges : this._allEdges;\n\n return [ ...executedEdges ].some(edge => this.getCrossedElementsFor(edge).length > 0 || this.getCrossedElementsFor(edge, true).length > 0);\n }\n\n /**\n * Уплотняет грид по горизонтали или по вертикали\n * @param {boolean} byVertical\n */\n shakeIt(byVertical) {\n\n const sortedElements = [ ...this.elements ].sort(byVertical ? sortElementsTopRightBottomLeft(this) : sortColsLeftRightRowsBottomTop (this)).reverse();\n\n while (sortedElements.length > 0) {\n\n // работаем по первому элементу\n const element = sortedElements.pop();\n\n // получаем цепочку противоположную направлению уплотнения\n // удаляем из стека sortedElements все элементы из цепочки\n const chain = this.getChain(element, !byVertical);\n\n for (const chainElement of chain) {\n const deleteIndex = sortedElements.indexOf(chainElement);\n if (deleteIndex >= 0) {\n sortedElements.splice(deleteIndex, 1);\n }\n }\n\n // проверяем можно ли двинуть цепочку вверх для уплотнения по вертикали и влево для уплотнения по горизонтали\n // не одна из позиций не должна быть занята или иметь пересечения\n // - цепочка не должна удлиниться\n // todo: пока под вопросом для ребра из boundary не должны закручиваться\n const [ baseRow, baseCol ] = this.find([ ...chain ][0]);\n\n // двигаться не вариант если цепочка у края грида\n if (byVertical ? baseRow <= 0 : baseCol <= 0) continue;\n\n for (let index = byVertical ? baseRow - 1 : baseCol - 1 ; index >= 0; index--) {\n\n // не двигаем если есть пересечения\n // todo: добавить оптимизации\n const allPositionsAreFine = [ ...chain ].every(element => {\n const curPos = this.find(element);\n\n return curPos && !this.isCrossed(curPos, true) && !this.isCrossed(curPos, false) ;\n });\n if (!allPositionsAreFine) break;\n\n // проверяем заняты ли новые позиции\n // todo: добавить оптимизации\n const newPositionsAreFine = [ ...chain ].every(element => {\n const curPos = this.find(element);\n const checkedRow = byVertical ? index : curPos[0];\n const checkedCol = byVertical ? curPos[1] : index;\n return !this.get(checkedRow, checkedCol);\n });\n if (!newPositionsAreFine) break;\n\n // пробно перемещаем все элементы из цепочки на новые места\n // пересечения позже всем скоупом проверим\n for (const chainElement of chain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, byVertical ? [ index, chainElementPosition[1] ] : [ chainElementPosition[0], index ]);\n }\n\n // проверяем не образовалось ли новых пересечений пока по старинке\n // и не удлинилась ли цепочка\n // todo: не пробегаться по всему гриду, а работать только по цепочке!!!\n const hasNewCrosses = this.hasAnyCross();\n const newChain = byVertical ? this.getChain(element, false) : this.getChain(element, true);\n if (hasNewCrosses || newChain.size > chain.size) {\n\n // вертаем все элементы взад\n for (const chainElement of chain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, byVertical ? [ index + 1 , chainElementPosition[1] ] : [ chainElementPosition[0], index + 1 ]);\n }\n break;\n }\n }\n\n // после каждого прохода удаляем пустые линии чтобы не ходить по пустым местам\n this.shrink(byVertical);\n }\n }\n\n /**\n * Возвращает горизонтальную или вертикальную последовательность элементов\n * @param {any} element BPMN Element\n * @param {boolean} byVertical\n * @param {Set<any>=}oldChain\n * @returns {Set<any>}\n */\n getChain(element, byVertical, 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 const edges = [];\n\n // получаем все элементы в позиции\n const elInPos = this.get(elementPosition[0], elementPosition[1]);\n for (const el of elInPos) {\n chain.add(el);\n\n // todo: возможно стоит добавить другие варианты ребер - в себя - убрать undefined\n [ ...this.getAllExistingEdgesFor(el) ]\n .filter(edge => !byVertical ? (this.getEdgeDirection(edge) === 'W_E' || this.getEdgeDirection(edge) === 'E_W') : (this.getEdgeDirection(edge) === 'N_S' || this.getEdgeDirection(edge) === 'S_N'))\n .forEach(edge => edges.push(edge));\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.getChain(nextElement, byVertical, 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.isFlipped ? [ ...this.graph.getOutgoingEdgesFor(element) ] : [ ...this.graph.getIncomingEdgesFor(element) ];\n }\n\n getExistingIncomingEdgesFor(element) {\n return !this.isFlipped ? [ ...this.graph.getIncomingEdgesFor(element) ] : [ ...this.graph.getOutgoingEdgesFor(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 _separateGrid() {\n\n // создаем копию графа\n const executedGraph = Graph.mergeGraphs(new Set([ this.graph ]));\n\n const separatedGraphs = executedGraph.getSeparatedGraphs();\n\n // todo: костыль для устранения проблемы после разделения пустого графа\n if (separatedGraphs.length === 0) return [ new GridWithEdges(this.initialGraph, this.colCount, this.rowCount) ];\n\n // todo: добавить проверку на не пересечение\n const grids = [];\n\n for (const graph of separatedGraphs) {\n const grid = new GridWithEdges(this.initialGraph, this.colCount, this.rowCount);\n\n let minRow = null;\n let maxRow = null;\n\n // todo: костыль до полного перехода на граф\n for (const node of sortByType(graph.nodes, 'bpmn:BoundaryEvent').reverse()) {\n const position = this.find(node);\n if (minRow === null || minRow > position[0]) minRow = position[0];\n if (maxRow === null || maxRow < position[0]) maxRow = position[0];\n grid._superAdd(node, position);\n grid.graph.addNode(node);\n }\n\n // todo: костыль для пролива ребер надо посмотреть почему не создаются - может в ручную делать а не при добавлении вершины\n graph.edges.forEach(edge => {\n grid._addEdgeToGrid(edge);\n });\n\n grids.push(grid);\n }\n\n return grids;\n }\n\n _superAdd(element, position) {\n super.add(element, position);\n }\n\n // todo: сделать нормальное копирование\n _mergeGrids(grids) {\n const newGrid = new GridWithEdges(grids[0].initialGraph);\n\n grids.forEach(grid => {\n let rowShift = newGrid.rowCount;\n\n Object.keys(grid.rows).forEach(rowIndex => {\n if (grid.rows[rowIndex].size === 0) {\n newGrid.addRowCol(false, rowShift + Number.parseInt(rowIndex) - 1);\n } else {\n grid.rows[rowIndex].forEach(node => {\n const newPosition = [ ...grid.find(node) ];\n newPosition[0] = newPosition[0] + rowShift;\n newGrid.add(node, newPosition);\n });\n }\n });\n });\n\n return newGrid;\n }\n\n getSourcePosition(edge) {\n const source = this.getEdgeSource(edge);\n return this.find(source);\n }\n\n getTargetPosition(edge) {\n const target = this.getEdgeTarget(edge);\n return this.find(target);\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 * @param edge\n * @returns {Direction}\n */\n getEdgeDirection(edge) {\n const sourcePosition = this.getSourcePosition(edge);\n const targetPosition = this.getTargetPosition(edge);\n\n if (!this.isValidPosition(sourcePosition) || !this.isValidPosition(targetPosition)) throw new Error(`Invalid position of source or target in ${edge.source.id}-${edge.target.id} flipped:${this.isFlipped}`);\n\n const [ sourceRow, sourceCol ] = sourcePosition;\n const [ targetRow, targetCol ] = targetPosition;\n\n const vDifference = sourceRow - targetRow;\n const hDifference = sourceCol - targetCol;\n\n // self\n if (vDifference === 0 && hDifference === 0) return 'NO_DIRECTION';\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 /**\n * @param edge\n * @returns {Array<PathSegment>}\n */\n getPathFor(edge) {\n const direction = this.getEdgeDirection(edge);\n\n if (direction === 'NO_DIRECTION') return this._pathForNoDirection();\n if (direction === 'S_N') return this._pathForSouthToNorth(edge);\n if (direction === 'SW_NE') return this._pathForSouthWestToNorthEast(edge);\n if (direction === 'W_E') return this._pathForWestToEast(edge);\n if (direction === 'NW_SE') return this._pathForNorthWestToSouthEast(edge);\n if (direction === 'N_S') return this._pathForNorthToSouth(edge);\n if (direction === 'NE_SW') return this._pathForNorthEastToSouthWest(edge);\n if (direction === 'E_W') return this._pathForEastToWest(edge);\n if (direction === 'SE_NW') return this._pathForSouthEastToNorthWest(edge);\n return [];\n }\n\n _pathForNoDirection() {\n return [];\n }\n\n getEdgeSource(edge) {\n return !this.isFlipped ? edge.source : edge.target;\n }\n\n getEdgeTarget(edge) {\n return !this.isFlipped ? edge.target : edge.source;\n }\n\n _pathForSouthToNorth(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow ] = this.getTargetPosition(edge);\n\n // если sourceIsBoundary, то сразу идем в обход, так же для реверса\n if (this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id) return pathSegments;\n\n // TODO: при реверсе флипать сегменты перед отдачей? Need tests!\n // проверяем есть ли элементы между sourcePosition, targetPosition\n // если есть, то ребро пойдет в обход\n // так же оно пойдет в обход если элементы на соседних клетках и есть обратное ребро targetPosition-sourcePosition\n let hasIntermediateElements = this.hasIntermediateElements(this.getSourcePosition(edge), this.getTargetPosition(edge), true);\n\n // идем между ячейками грида\n if (hasIntermediateElements) return pathSegments;\n\n // проверяем петлю source -> target -> source\n const targetElementOutgoingEdges = this.getExistingOutgoingEdgesFor(this.getEdgeTarget(edge));\n const targetElementOutgoing = [ ...targetElementOutgoingEdges ].map(edge => this.getEdgeTarget(edge));\n\n // идем в обход если есть ребро в противоположном направлении\n if (targetElementOutgoing.includes(this.getEdgeSource(edge))) return pathSegments;\n\n // в остальных случаях идем прямо\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // если sourceIsBoundary, то пропускаем горизонтальную часть\n if (!(this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent')) {\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ , targetCol ] = this.getTargetPosition(edge);\n\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow ] = this.getTargetPosition(edge);\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ , targetCol ] = this.getTargetPosition(edge);\n\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(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // для sourceIsBoundary пропускаем горизонталь\n if (!(this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id)) {\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.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id)) {\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 getCrossedElementsFor(edge, byVertical = false) {\n const crossedElements = [];\n for (const segment of this.getPathFor(edge)) {\n const [ row, col ] = segment.position;\n const element = this.get(row, col);\n if (element && ((byVertical && segment.vCross) || (!byVertical && segment.hCross))) crossedElements.push(element);\n }\n return crossedElements;\n }\n\n isIntersect(edge, position, byVertical) {\n\n // быстрый расчет по направлениям\n const [ row, col ] = position;\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n const direction = this.getEdgeDirection(edge);\n\n if (direction === 'S_N') {\n return byVertical && col === sourceCol && row < sourceRow && row > targetRow;\n }\n\n if (direction === 'SW_NE') {\n if (byVertical && col === targetCol && row <= sourceRow && row > targetRow) return true;\n return !byVertical && col > sourceCol && col <= targetCol && row === sourceRow;\n }\n\n if (direction === 'W_E') {\n return !byVertical && col > sourceCol && col < targetCol && row === sourceRow;\n }\n\n if (direction === 'NW_SE') {\n if (byVertical && col === sourceCol && row > sourceRow && row <= targetRow) return true;\n return !byVertical && col >= sourceCol && col < targetCol && row === targetRow;\n }\n\n if (direction === 'N_S') {\n return byVertical && col === sourceCol && row > sourceRow && row < targetRow;\n }\n\n if (direction === 'NE_SW') {\n if (byVertical && col === sourceCol && row > sourceRow && row <= targetRow) return true;\n return !byVertical && col > targetCol && col <= sourceCol && row === targetRow;\n\n }\n\n if (direction === 'E_W') {\n return !byVertical && col > targetCol && col < sourceCol && row === sourceRow;\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 return !byVertical && col >= targetCol &&\n col < sourceCol && row === sourceRow &&\n !this.getExistingIncomingEdgesFor(this.getEdgeSource(edge))\n .some(edge => this.getEdgeDirection(edge) === 'NW_SE' || this.getEdgeDirection(edge) === 'W_E');\n }\n }\n\n /**\n * Получает ребра идущие назад и вверх\n * @param node\n * @returns {*}\n */\n getBackwardUpOutgoingEdgesFor(node) {\n return this.getExistingOutgoingEdgesFor(node).filter(edge => {\n const direction = this.getEdgeDirection(edge);\n return direction === 'S_N' || direction === 'SE_NW';\n });\n }\n\n /**\n * Создает копию грида\n * @returns {GridWithEdges}\n */\n getGridCopy() {\n return this._mergeGrids([ this ]);\n }\n\n /**\n * Удаляет ребро из грида\n * @param edge\n */\n removeEdge(edge) {\n this.graph.deleteEdge(edge);\n }\n\n getGraphSegmentFrom(node) {\n\n const segment = new Graph();\n\n // проходим только вперед\n // GetStartElementFunction<N> = (visited: Set<N>, initialGraph: Graph<N>) => N | undefined\n const getStartElement = (visited, initialGraph) => {\n return !visited.has(node) ? node : undefined;\n };\n\n // GetNextNodesFunction<N> = (node: N, graph: Graph<N>, visited: Set<N>, executionSequence: Array<N>) => Array<N> | undefined\n const getNextNodes = (node, graph, visited, executionSequence) => {\n const nextEdges = this.getExistingOutgoingEdgesFor(node).filter(edge => {\n const target = this.getEdgeTarget(edge);\n const source = this.getEdgeSource(edge);\n return !visited.has(target) && target !== source;\n });\n\n segment.addNode(node);\n const nextNodes = nextEdges.map(edge => {\n return this.getEdgeTarget(edge);\n });\n\n for (const node of nextNodes) {\n segment.addNode(node);\n }\n\n for (const edge of nextEdges) {\n segment.addEdge(edge);\n }\n\n return nextNodes;\n };\n\n this.graph.genericTraversing(getNextNodes, getStartElement);\n\n return segment;\n }\n\n getSegmentLeftCoordinates(segment) {\n\n const leftCoordinates = new Map();\n\n for (const node of segment.nodes) {\n const [ nodeRow, nodeCol ] = this.find(node);\n\n if (!leftCoordinates.has(nodeRow)) leftCoordinates.set(nodeRow, nodeCol);\n\n if (nodeCol < leftCoordinates.get(nodeRow)) leftCoordinates.set(nodeRow, nodeCol);\n }\n return leftCoordinates;\n }\n}\n","import {\n sortElementsTopLeftBottomRight\n} from '../utils/layoutUtils.js';\n\n\nexport function elementExecution(node, grid, executionSequence, visited, graph) {\n if (!grid.hasElement(node)) grid.add(node);\n\n // получаем новые которых нет в гриде\n // todo: перенести код\n const newOutgoing = (!grid.isFlipped ? [ ...grid.initialGraph.getOutgoingEdgesFor(node) ] : [ ...grid.initialGraph.getIncomingEdgesFor(node) ]).filter(edge => !grid.hasElement(!grid.isFlipped ? edge.target : edge.source)).map(edge => !grid.isFlipped ? edge.target : edge.source);\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 let outgoing = [ ...newOutgoing, ...outgoingFromStack ];\n\n let nextElements = [];\n\n outgoing.forEach(nextElement => {\n\n // подготавливаем место\n const nextPosition = [ ...getInsertPosition (node, grid, nextElement) ];\n\n // вставляем элемент\n // todo: костыль вставляем attachedToRef\n if (grid.isFlipped && nextElement.$type === 'bpmn:BoundaryEvent' && nextElement.attachedToRef !== node) {\n const attachedToRef = nextElement.attachedToRef;\n if (!visited.has(attachedToRef)) {\n grid.add(attachedToRef, nextPosition);\n visited.add(attachedToRef);\n fixNewCrosses(attachedToRef, grid, executionSequence, nextElements, true);\n nextElements.unshift(nextElement);\n }\n }\n grid.add(nextElement, nextPosition);\n visited.add(nextElement);\n\n fixNewCrosses(nextElement, grid, executionSequence, nextElements, true);\n\n // выворачиваем\n // Верхние левые сдвигаем вперед и проверяем пересечения начиная с левого.\n moveTopLeftOutgoingForward(nextElement, grid);\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) {\n\n // todo: выбрать сегмент по всем идущим назад ребрами\n // двигать весь сегмент\n // нужны тестовые данные для этого кейса\n /*\n Алгоритм без выворачивания следующий.\n Вопрос по элементам ниже пока не двигаем - тоже их удаляем из копии.\n Делаем копию грида.\n Работаем по копии грида.\n Удаляем все элементы левее таргета.\n Удаляем все исходящие ребра из сорса. ---\n Строим сегмент графа из таргета.\n Если сорс в сегменте, то не двигаем.\n Находим крайние левые позиции сегмента.\n Двигаем в базовом гриде сегмент вправо таким образом, чтобы крайний левый элемент оказался правее сорса\n */\n // получаем ребра ведущие назад из элемента\n let existingEdges = grid.getBackwardUpOutgoingEdgesFor(node);\n\n // todo: пока без сортировки чтобы проверить концепцию сдвига\n while (existingEdges.length > 0) {\n\n const workingEdge = existingEdges.shift();\n\n // todo: оптимизировать\n const sourcePos = grid.getSourcePosition(workingEdge);\n const targetPos = grid.getTargetPosition(workingEdge);\n const source = grid.getEdgeSource(workingEdge);\n const target = grid.getEdgeTarget(workingEdge);\n\n if (targetPos[1] > grid.find(node)[1]) continue;\n\n const gridCopy = grid.getGridCopy();\n\n gridCopy.removeEdge(workingEdge);\n\n // оптимизированный проход без поиска в гриде\n gridCopy._elements.forEach((value, key) => {\n const [ , colIndex ] = value;\n if (colIndex < targetPos[1]) gridCopy.removeElement(key);\n });\n\n const graphSegment = gridCopy.getGraphSegmentFrom(target);\n\n if (graphSegment.nodes.includes(source)) continue;\n\n const segmentCords = Array.from(gridCopy.getSegmentLeftCoordinates(graphSegment));\n\n const minColPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[1] < acc[1] ? cur : acc;\n }, undefined);\n\n const minRowPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[0] < acc[0] ? cur : acc;\n }, undefined);\n\n const maxRowPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[0] > acc[0] ? cur : acc;\n }, undefined);\n\n const shift = sourcePos[1] - minColPosition[1] + 1;\n\n const newMap = new Map(segmentCords);\n\n let previousShiftPos = undefined; // [row, col]\n\n for (let rowIndex = 0; rowIndex < grid.rowCount; rowIndex++) {\n\n const getShiftPos = () => {\n\n // todo: погонять тесты\n // здесь надо смещать все что выше\n if (rowIndex < minRowPosition[0]) {\n previousShiftPos = minRowPosition[0];\n return minRowPosition[1] - 1; // выше сегмента\n }\n if (newMap.has(rowIndex)) {\n previousShiftPos = newMap.get(rowIndex);\n return newMap.get(rowIndex) - 1;\n }\n\n const nodePosition = grid.find(node) || [];\n\n // посреди сегмента выше ноды\n if (rowIndex > minRowPosition[0] && rowIndex < maxRowPosition[0] && rowIndex < nodePosition[0]) {\n return previousShiftPos;\n }\n\n\n if (rowIndex === nodePosition[0] || rowIndex > minRowPosition[0]) {\n previousShiftPos = nodePosition;\n\n return nodePosition[1];\n }\n\n return previousShiftPos;\n };\n\n const shiftPos = getShiftPos() ;\n\n grid.expandRow(rowIndex, shiftPos, shift);\n }\n }\n}\n\nfunction inStackWithoutOutgoing(node, executionSequence, grid) {\n const inStack = executionSequence.includes(node);\n const outgoing = grid.getExistingOutgoingEdgesFor(node);\n\n return inStack && (!outgoing?.length > 0);\n}\n\n/**\n * @param grid\n * @param {[number, number]} topLeftPosition\n * @param {[number, number]} bottomRightPosition\n */\n// eslint-disable-next-line no-unused-vars\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);\n }\n }\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 = grid.getExistingOutgoingEdgesFor(node) ;\n const incoming = grid.getExistingIncomingEdgesFor(node).map(edge => grid.getEdgeSource(edge));\n\n const [ , elementCol ] = grid.find(node);\n const processingElements = [ ...outgoing ].filter(edge => {\n\n // оставляем только те, что идут в стек и не имеют исходящих\n const target = grid.getEdgeTarget(edge);\n const targetCol = grid.find(target)[1];\n\n if (!inStackWithoutOutgoing(target, executionSequence, grid)) return false;\n\n\n // исключаем если общий родитель, так как уже расставили их правильно\n // пробуем нет входящих кроме element\n // если есть общий родитель и есть новые исходящие то выкидываем\n const targetIncoming = grid.getExistingIncomingEdgesFor(target)\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.getEdgeTarget(item)).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.shrink(true);\n grid.shrink(false);\n\n // обрабатываем их как новые исходящие\n return processingElements;\n}\n\nfunction getInsertPosition(element, grid, nextEl) {\n\n // todo: пока костыль\n if (grid.isFlipped && nextEl.$type === 'bpmn:BoundaryEvent' && grid.hasElement(nextEl.attachedToRef)) return grid.find(nextEl.attachedToRef);\n\n const nextOnElement = nextEl.attachedToRef === element;\n if (nextOnElement) return grid.find(element);\n\n const sourcePosition = grid.find(element);\n if (!sourcePosition) return;\n\n // по умолчанию располагаем справа от element или по диагонали\n const isBoundarySource = element.$type === 'bpmn:BoundaryEvent' && !grid.isFlipped;\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\n // todo: надо смотреть реверс\n for (const item of allItemsInElementPosition) {\n [ ...grid.getExistingOutgoingEdgesFor(item) ]\n\n // .filter(edge => edge.target !== edge.source && visited.has(edge.source) && visited.has(edge.target))\n .filter(edge => edge.target !== edge.source)\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 (grid.getTargetPosition(edge)[0] === i && grid.getTargetPosition(edge)[1] === position[1]) || grid.isIntersect(edge, point, false) || grid.isIntersect(edge, point, true);\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 // todo: убрать на после вставки?\n // обрабатываем занятость и вертикальные пересечения\n if (grid.get(position[0], position[1]) || grid.isCrossed(position, true)) {\n grid.addRowCol(true, position[1] - 1);\n }\n\n if (grid.isCrossed([ position[0], position[1] ])) {\n\n // todo: возможно стоит посмотреть по направлениям\n grid.addRowCol(false, 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, stack, nextElements, skipTopLeftOutgoing) {\n\n // реверс логики переноса вперед для исходящих\n // исправляем пересечения образованные исходящими и входящими ребрами новой вершины\n // получаем исходящие\n const outgoingEdges = [ ...grid.getExistingOutgoingEdgesFor(element) ]\n .sort((a, b) => {\n const [ aRow, aCol ] = grid.getTargetPosition(a);\n const [ bRow, bCol ] = grid.getTargetPosition(b);\n return aRow - bRow || aCol - bCol;\n });\n const incomingEdges = [ ...grid.getExistingIncomingEdgesFor(element) ]\n .sort((a, b) => {\n const [ aRow, aCol ] = grid.getSourcePosition(a);\n const [ bRow, bCol ] = grid.getSourcePosition(b);\n return aRow - bRow || aCol - bCol;\n });\n\n const edges = [ ...outgoingEdges, ...incomingEdges ]\n .filter(edge => {\n const { target, source } = edge;\n const direction = grid.getEdgeDirection(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, stack, grid)) 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 (grid.getEdgeDirection(edge) === 'E_W' && ((grid.getEdgeSource(edge)).$type === 'bpmn:BoundaryEvent' && edge.id)) 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 = grid.getEdgeDirection(edge);\n\n if (direction === 'W_E' || direction === 'E_W') return;\n\n const vCrossed = grid.getCrossedElementsFor(edge, 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 = grid.getEdgeDirection(edge);\n\n // по этим направлениям не предполагается горизонтальных пересечений\n if (direction === 'S_N' || direction === 'N_S') return;\n\n const hCrossed = grid.getCrossedElementsFor(edge, false);\n\n if (hCrossed.length === 0) return;\n\n if (direction === 'SW_NE') {\n\n // поднимаем элементы выше пересечения\n const maxDown = getMaxDown(edge, grid);\n const [ baseSourceRow ] = grid.getSourcePosition(edge);\n grid.addRowCol(false, baseSourceRow - 1, maxDown);\n\n const elements = grid.getElementsInRange({ row: grid.getSourcePosition(edge)[0], col: grid.getSourcePosition(edge)[1] + 1 }, { row: grid.rowCount - 1, col: grid.colCount - 1 });\n\n for (const element of elements) {\n const [ row, col ] = grid.find(element);\n for (const innerElement of [ ...grid.get(row, col) ]) {\n 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.addRowCol(false, 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.addRowCol(false, 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.addRowCol(true, 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.addRowCol(true, 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, grid) {\n const sourcePosition = grid.getSourcePosition(edge);\n const targetPosition = grid.getTargetPosition(edge);\n\n let maxDown = sourcePosition[0];\n\n for (let rowIndex = sourcePosition[0]; rowIndex < grid.rowCount; rowIndex++) {\n if (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 { DEFAULT_CELL_HEIGHT, DEFAULT_CELL_WIDTH, getBounds } from '../utils/layoutUtils.js';\nimport { getOutgoingElements } from '../utils/elementUtils.js';\nimport { getDefaultSize, is } from '../di/DiUtil.js';\n\nexport default function createElementDi(element, elementPosition, diFactory, grid, shift) {\n const [ row, col, elWidth, elHeight ] = elementPosition;\n if (element.di) return [];\n\n if (element.$type === 'bpmn:BoundaryEvent') {\n return createBEl(element, row, col, diFactory, grid, shift);\n }\n\n const bounds = getBounds(element, row, col, shift);\n\n // Todo: костыль для проверки работоспособности\n if (element.isExpanded) {\n const { width, height } = getDefaultSize(element);\n const { rowCount, colCount } = element.grid;\n\n // todo: убрать после использования ширины и высоты\n bounds.width = (colCount ? colCount : 1) * DEFAULT_CELL_WIDTH + width;\n bounds.height = (rowCount ? rowCount : 1) * 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\nfunction createBEl(element, row, col, diFactory, grid, 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 // первыми должны отрисовываться те, у которых потомки ниже и правей\n let neighboursBoundary = element.$parent.flowElements.filter(item => item.attachedToRef === element.attachedToRef && grid.hasElement(element));\n neighboursBoundary = getSortedElementsByOutgoingPosition(neighboursBoundary, grid);\n neighboursBoundary.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}\n\n// Первыми идут те у которых исходящие ниже\nfunction getSortedElementsByOutgoingPosition(elements, grid) {\n return elements.sort((a, b) => {\n const aBottomRightChildPosition = getPositionRightBottomOutgoingElement(a, grid);\n const bBottomRightChildPosition = getPositionRightBottomOutgoingElement(b, grid);\n\n return aBottomRightChildPosition[0] - bBottomRightChildPosition[0] || aBottomRightChildPosition[1] - bBottomRightChildPosition[1];\n }).reverse();\n}\n\nfunction getPositionRightBottomOutgoingElement(element, grid) {\n return getOutgoingElements(element).reduce((prev, cur) => {\n if (!grid.hasElement(cur)) return prev;\n const curPosition = grid.find(cur);\n if (prev === undefined) return curPosition;\n if (prev[0] < curPosition[0] || prev[1] < curPosition[1]) return curPosition;\n return prev;\n }, [ 0 ,0 ]);\n}","export class Edge {\n constructor(source, target) {\n this.source = source;\n this.target = target;\n }\n}","import BPMNModdle from 'bpmn-moddle';\nimport { Graph } from 'graph-by-ivan-tulaev';\n\n// todo: настроить сборщик resolve js\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 { GridWithEdges } from './GridWithEdges.js';\nimport { elementExecution } from './newHandlers/outgoingHandler.js';\nimport createConnection from './newHandlers/createConnection.js';\nimport createElementDi from './newHandlers/createElementDi.js';\nimport { Edge } from './Edge.js';\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.maxDebugStep = debuggerCounter;\n this.currentDebugStep = 0;\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 // expand grids\n this.expandProcessesGrids();\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 createGridsForProcesses() {\n\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => a.level - b.level);\n\n // create and add grids for each process\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.shrink(true);\n grid.shrink(false);\n\n grid.shakeIt(true);\n grid.shakeIt(false);\n }\n\n // merge separated grids and set new grid to the process\n process.grid = process.grid._mergeGrids(tempGridCollection);\n }\n }\n\n expandProcessesGrids() {\n\n // root processes should be processed last for element expanding\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => b.level - a.level);\n\n for (const process of processes) {\n\n // separate base grid to independent grids\n const tempGridCollection = process.grid._separateGrid() || [ process.grid ];\n\n for (const grid of tempGridCollection) {\n grid.shrink(true);\n grid.shrink(false);\n\n expandGrid(grid, false);\n expandGrid(grid, true);\n }\n\n // merge separated grids and set new grid to the process\n process.grid = process.grid._mergeGrids(tempGridCollection);\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 const sortedProcesses = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n sortedProcesses.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, { x, y }, diagram);\n continue;\n }\n\n // draw processes in expanded elements\n // todo: сделать понятнее для this.maxDebugStep\n if (process.isExpanded && !this.existingNodes.includes(process)) continue;\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, { 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, { x: 0, y: 0 }, diagram);\n }\n }\n\n get existingNodes() {\n return this.processTrees.map(graph => [ ...graph.nodes ]).flat().map(item => [ ...item.grid.elements ]).flat();\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\n // todo: debug mode сделать презентабельнее\n const existNodes = this.existingNodes;\n if (!existNodes.includes(sourceRef) || !existNodes.includes(targetRef)) continue;\n\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) => {\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 return prev === undefined || cur.right > prev.right ? cur.right : prev;\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(getNextNodes, getStartElement);\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\n // create graph from elements\n const processGraph = new Graph();\n const grid = new GridWithEdges(processGraph);\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 // todo: переписать компактней\n for (const node of processGraph.nodes) {\n\n // boundary\n // добавляем два ребра, так как у нас направленный граф\n if (node.$type === 'bpmn:BoundaryEvent') {\n processGraph.addEdge(new Edge(node, node.attachedToRef));\n processGraph.addEdge(new Edge(node.attachedToRef, node));\n }\n\n // sequenceFlow\n for (const outgoingItem of node.outgoing || []) {\n const newEdge = new Edge(outgoingItem.sourceRef, outgoingItem.targetRef);\n newEdge.id = outgoingItem.id;\n processGraph.addEdge(newEdge);\n }\n\n // data associations - двигаемся от связанной ноды\n const dataInputAssociations = node.dataInputAssociations;\n for (const association of dataInputAssociations || []) {\n for (const dataSource of association.sourceRef || []) {\n const newEdge = new Edge(dataSource, association.$parent);\n newEdge.id = association.id;\n newEdge.propRef = association.targetRef;\n processGraph.addEdge(newEdge);\n }\n }\n\n const dataOutputAssociations = node.dataOutputAssociations;\n for (const association of dataOutputAssociations || []) {\n const source = association.$parent;\n const target = association.targetRef;\n const newEdge = new Edge(source, target);\n newEdge.id = association.id;\n processGraph.addEdge(newEdge);\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 targetElementInGridSourceNotExist = [ ...visited ].find(node => {\n const incomingEdges = !grid.isFlipped ? [ ...initialGraph.getIncomingEdgesFor(node) ] : [ ...initialGraph.getOutgoingEdgesFor(node) ];\n return incomingEdges.filter(edge => !visited.has(!grid.isFlipped ? edge.source : edge.target)).length > 0;\n });\n if (targetElementInGridSourceNotExist) {\n grid.flip(false);\n\n return targetElementInGridSourceNotExist;\n }\n\n // maybe need boundaryEvents processing here\n const primaryStartElements = initialGraph.nodes.filter(node => {\n const incomingEdges = !grid.isFlipped ? initialGraph.getIncomingEdgesFor(node) : initialGraph.getOutgoingEdgesFor(node);\n return !visited.has(node) && incomingEdges.size === 0 && !isStartIntermediate(node);\n });\n if (primaryStartElements.length > 0) return sortByType(primaryStartElements, 'bpmn:StartEvent')[0];\n\n const sourceElementInGridTargetNotExist = [ ...visited ].find(node => {\n\n // todo: добавить сортировку sortElementsTopLeftBottomRight?\n const outgoing = !grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ];\n return outgoing.filter(edge => !visited.has(!grid.isFlipped ? edge.target : edge.source)).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 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) ] : [ ...initialGraph.getOutgoingEdgesFor(node) ];\n return incoming .filter(edge => node !== (!grid.isFlipped ? edge.source : edge.target)).length === 0;\n });\n if (otherStartingElement) return otherStartingElement;\n\n const flippedStartElement = initialGraph.nodes.find(node => {\n\n if (visited.has(node)) return false;\n\n let outgoingEdges = (!grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ]).filter(edge => edge.target !== edge.source);\n\n return outgoingEdges.length === 0;\n });\n\n if (flippedStartElement) {\n grid.flip(false);\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 // 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 this.currentDebugStep += 1;\n return nextElements;\n };\n\n processGraph.genericTraversing(\n dfsGetNextNodes,\n dfsGetStartElement,\n );\n\n // flip grid on end\n if (grid.isFlipped) {\n grid.flip(false);\n }\n\n return grid;\n }\n\n generateDi(process , shift, procDi) {\n const { grid: layoutGrid } = process;\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._elements.forEach((elementPosition, element) => {\n const dis = createElementDi(element, elementPosition, diFactory, layoutGrid, shift);\n planeElement.push(...dis);\n });\n\n // Step 2: Create DI for all connections\n layoutGrid._allEdges.forEach(edge => {\n const connection = createConnection(edge, layoutGrid, diFactory, shift);\n if (connection) planeElement.push(connection);\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 or rows.\n * If it has elements with isExpanded === true,\n * find the maximum size of elements grids and expand the parent grid horizontally or vertically.\n * @param grid\n * @param {boolean=} byVertical\n */\nfunction expandGrid(grid, byVertical) {\n\n // todo: здесь можно оптимизировать добавив строки и колонки в грид\n const indexesToExpand = new Map();\n const elementsToExpand = new Set();\n\n Object.entries(!byVertical ? grid.cols : grid.rows).forEach(([ index, elements ]) => {\n elements.forEach(element => {\n if (element.isExpanded) {\n elementsToExpand.add(element);\n const maxCount = indexesToExpand.get(index);\n const [ rowCount, colCount ] = element.grid.getGridDimensions();\n let curCount = !byVertical ? colCount : rowCount;\n if (!curCount) {\n curCount = 1;\n }\n if (maxCount === undefined || curCount > maxCount) {\n indexesToExpand.set(index, curCount);\n }\n }\n });\n });\n\n [ ...indexesToExpand.entries() ].sort(([ aKey ],[ bKey ]) => bKey - aKey).forEach(([ key, value ]) => {\n grid.addRowCol(!byVertical, key, value);\n });\n\n elementsToExpand.forEach((value) => {\n const position = grid.find(value);\n const [ row, col ] = value.grid.getGridDimensions();\n if (!byVertical) {\n (position[3] = col >= 2 ? col : 2);\n } else {\n (position[2] = row >= 2 ? row : 2);\n }\n });\n}\n","import {\n connectElements,\n} from '../utils/layoutUtils.js';\n\nexport default function createConnection(edge, layoutGrid, diFactory, shift) {\n const { id } = edge;\n\n // todo: пока костыль для отрисовки только тех, которые с id\n if (id) {\n const waypoints = connectElements(edge, layoutGrid, shift);\n return diFactory.createDiEdge(edge, waypoints, {\n id: id + '_di'\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","getOutgoingElements","Error","outgoingElements","outgoing","map","out","targetRef","Set","DEFAULT_CELL_WIDTH","DEFAULT_CELL_HEIGHT","isFlipped","utilsGetOutgoingElements","concat","attachedOutgoing","attachers","sort","a","b","length","attacher","reverse","flat","filter","item","index","self","indexOf","add","getAttachedOutgoingElements","connectElements","edge","layoutGrid","shift","source","target","sourceDi","di","targetDi","sourceBounds","get","targetBounds","sourceMid","getMid","targetMid","edgeDirection","getEdgeDirection","dX","gridPosition","col","dY","row","dockingSource","dockingTarget","x","sourceX","y","sourceY","coordinatesToPosition","targetX","sourceIsBoundary","$type","getDockingPoint","attachedToRef","isExpanded","grid","rowCount","includes","firstPoint","lastPoint","maxExpanded","sourceRow","sourceCol","find","targetCol","firstCol","lastCol","elementsInRange","elements","undefined","size","reduce","acc","cur","getGridDimensions","getMaxExpandedBetween","hasReversEdge","hasSW_NEOut","getExistingOutgoingEdgesFor","some","colCount","elementsInHorizontal","candidate","push","directManhattan","targetRow","totalElements","bendPoint","getElementsInRange","directManhattanConnect","startPoint","endPoint","yOffset","Math","sign","bounds","point","rectangle","dockingDirection","targetOrientation","test","original","getBounds","attachedTo","hostBounds","round","sortByType","arr","types","typesArray","result","forEach","matching","DiFactory","constructor","moddle","this","create","attrs","createDiBounds","createDiLabel","createDiShape","semantic","assign","bpmnElement","createDiWaypoints","waypoints","pos","createDiWaypoint","pick","createDiEdge","waypoint","createDiPlane","createDiDiagram","Grid","_elements","Map","rows","cols","Object","keys","elementsCount","position","has","JSON","stringify","_addStart","lastRow","rowDif","colDif","addRowCol","set","_addElementToRowsCols","_removeElementFromRowsCols","delete","move","toPosition","toString","isValidPosition","removeElement","addCol","afterIndex","count","gridCount","addCount","i","elementPosition","entries","expandRow","rowIndex","Number","isInteger","gridColCount","elementsAtPosition","startRow","startCol","endRow","endCol","shrink","byVertical","sortedElements","previousIndex","key","value","flip","hasElement","Array","isArray","hasIntermediateElements","firstPosition","lastPosition","onVertical","start","end","values","hasElementAt","GridWithEdges","initialGraph","super","graph","Graph","addNode","_createNewEdgesFor","deleteNode","allEls","edges","prev","getAllExistingEdgesFor","el","_addEdgeToGrid","_edgeIsExist","addEdge","getOutgoingEdgesFor","getIncomingEdgesFor","isCrossed","_allEdges","isIntersect","hasAnyCross","getCrossedElementsFor","shakeIt","aPos","bPos","sortColsLeftRightRowsBottomTop","pop","chain","getChain","chainElement","deleteIndex","splice","baseRow","baseCol","allPositionsAreFine","every","curPos","newPositionsAreFine","checkedRow","checkedCol","chainElementPosition","hasNewCrosses","newChain","oldChain","elInPos","nextElement","nextChain","nextChainEl","getExistingIncomingEdgesFor","outgoingEdges","incomingEdges","_separateGrid","separatedGraphs","mergeGraphs","getSeparatedGraphs","grids","minRow","maxRow","node","nodes","_superAdd","_mergeGrids","newGrid","rowShift","parseInt","newPosition","getSourcePosition","getEdgeSource","getTargetPosition","getEdgeTarget","sourcePosition","targetPosition","id","vDifference","hDifference","getPathFor","direction","_pathForNoDirection","_pathForSouthToNorth","_pathForSouthWestToNorthEast","_pathForWestToEast","_pathForNorthWestToSouthEast","_pathForNorthToSouth","_pathForNorthEastToSouthWest","_pathForEastToWest","_pathForSouthEastToNorthWest","pathSegments","vCross","colIndex","hCross","crossedElements","segment","getBackwardUpOutgoingEdgesFor","getGridCopy","removeEdge","deleteEdge","getGraphSegmentFrom","genericTraversing","visited","executionSequence","nextEdges","nextNodes","getSegmentLeftCoordinates","leftCoordinates","nodeRow","nodeCol","elementExecution","newOutgoing","outgoingFromStack","hasNewOutgoings","incoming","elementCol","processingElements","inStackWithoutOutgoing","targetEdge","targetParent","sortElementsTopLeftBottomRight","processingElement","getOutgoingFromStack","nextElements","nextPosition","getInsertPosition","fixNewCrosses","unshift","existingEdges","workingEdge","sourcePos","targetPos","gridCopy","graphSegment","segmentCords","from","minColPosition","minRowPosition","maxRowPosition","newMap","previousShiftPos","shiftPos","nodePosition","getShiftPos","moveTopLeftOutgoingForward","nextBoundaries","nextOther","inStack","nextEl","elPos","allItemsInElementPosition","elementPositionEdges","crossedOrOccupied","stack","skipTopLeftOutgoing","aRow","aCol","bRow","bCol","fixNewVerticalCrosses","fixNewHorizontalCrosses","vCrossed","pushVerticalEdgeBy","moveElementsRighterCrossLine","hCrossed","maxDown","getMaxDown","baseSourceRow","innerElement","moveElementsUpperCrossLine","moveElementsUnderCrossLine","innerItem","createElementDi","diFactory","elWidth","elHeight","DIs","neighboursBoundary","$parent","flowElements","aBottomRightChildPosition","getPositionRightBottomOutgoingElement","bBottomRightChildPosition","getSortedElementsByOutgoingPosition","att","attacherDi","createBEl","options","isMarkerVisible","shapeDi","curPosition","Edge","Layouter","debuggerCounter","BPMNModdle","maxDebugStep","currentDebugStep","layoutProcess","xml","moddleObj","fromXML","rootElement","diagram","bpmnModel","allElements","elementsById","setExpandedProcesses","processTrees","createNestedSets","createGridsForProcesses","expandProcessesGrids","rootProcesses","getRootProcesses","collaboration","getCollaboration","cleanDi","createRootDi","drawParticipants","drawProcesses","drawCollaborationMessageFlows","toXML","format","processes","level","process","createGridLayout","tempGridCollection","expandGrid","participants","participant","createParticipantDi","sortedProcesses","getParticipantForProcess","participantDi","getElementDi","getProcDi","generateDi","existingNodes","baseProcDi","diagrams","plane","messageFlows","message","sourceRef","existNodes","processRef","planeElement","processGraph","allProcesses","getAllProcesses","children","getSubProcesses","child","rootProcess","getStartElement","root","left","getNextNodes","outgoingNode","maxRight","right","mainElement","createProcessDi","planeDi","diagramDi","origin","defaultWidth","defaultHeight","flowElement","outgoingItem","newEdge","dataInputAssociations","association","dataSource","propRef","dataOutputAssociations","targetElementInGridSourceNotExist","primaryStartElements","sourceElementInGridTargetNotExist","otherStartingElement","flippedStartElement","procDi","dis","connection","createConnection","indexesToExpand","elementsToExpand","maxCount","curCount","aKey","bKey"],"mappings":"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"}
|