{"version":3,"sources":["jsdelivr-header.js","/npm/reaflow@5.4.1/src/types.ts","/npm/reaflow@5.4.1/src/layout/utils.ts","/npm/reaflow@5.4.1/src/layout/elkLayout.ts","/npm/reaflow@5.4.1/src/layout/useLayout.ts","/npm/reaflow@5.4.1/src/utils/useEdgeDrag.ts","/npm/reaflow@5.4.1/src/utils/useZoom.ts","/npm/reaflow@5.4.1/src/utils/CanvasProvider.tsx","/npm/reaflow@5.4.1/src/utils/helpers.ts","/npm/reaflow@5.4.1/src/utils/useNodeDrag.ts","/npm/reaflow@5.4.1/src/symbols/Port/Port.tsx","/npm/reaflow@5.4.1/src/symbols/Label/Label.tsx","/npm/reaflow@5.4.1/src/symbols/Remove/Remove.tsx","/npm/reaflow@5.4.1/src/symbols/Edge/utils.ts","/npm/reaflow@5.4.1/src/symbols/Add/Add.tsx","/npm/reaflow@5.4.1/src/symbols/Edge/Edge.tsx","/npm/reaflow@5.4.1/src/symbols/Node/Node.tsx","/npm/reaflow@5.4.1/src/symbols/Arrow/Arrow.tsx","/npm/reaflow@5.4.1/src/symbols/Arrow/MarkerArrow.tsx","/npm/reaflow@5.4.1/src/Canvas.tsx","/npm/reaflow@5.4.1/src/symbols/Icon/Icon.tsx","/npm/reaflow@5.4.1/src/helpers/crudHelpers.ts","/npm/reaflow@5.4.1/src/helpers/useSelection.ts","/npm/reaflow@5.4.1/src/helpers/useUndo.ts","/npm/reaflow@5.4.1/src/helpers/useProximity.ts","/npm/reaflow@5.4.1/src/helpers/graphHelpers.ts"],"names":[],"mappings":"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","file":"/npm/reaflow@5.4.1/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/reaflow@5.4.1/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import { ElkNodeLayoutOptions } from './layout';\n\nexport enum CanvasPosition {\n  CENTER = 'center',\n  TOP = 'top',\n  LEFT = 'left',\n  RIGHT = 'right',\n  BOTTOM = 'bottom'\n}\n\nexport interface NodeData<T = any> {\n  /**\n   * Unique ID for the node.\n   */\n  id: string;\n\n  /**\n   * Whether the node is disabled or not.\n   */\n  disabled?: boolean;\n\n  /**\n   * Text label for the node.\n   */\n  text?: any;\n\n  /**\n   * Optional height attribute. If not passed with calculate\n   * default sizes using text.\n   */\n  height?: number;\n\n  /**\n   * Optional width attribute. If not passed with calculate\n   * default sizes using text.\n   */\n  width?: number;\n\n  /**\n   * Parent node id for nesting.\n   */\n  parent?: string;\n\n  /**\n   * List of ports.\n   */\n  ports?: PortData[];\n\n  /**\n   * Icon for the node.\n   */\n  icon?: IconData;\n\n  /**\n   * Padding for the node.\n   */\n  nodePadding?: number | [number, number] | [number, number, number, number];\n\n  /**\n   * Data for the node.\n   */\n  data?: T;\n\n  /**\n   * CSS classname for the node.\n   */\n  className?: string;\n\n  /**\n   * ELK layout options.\n   */\n  layoutOptions?: ElkNodeLayoutOptions;\n\n  /**\n   * Whether the node can be clicked.\n   */\n  selectionDisabled?: boolean;\n}\n\nexport interface LayoutNodeData extends NodeData {\n  x: number;\n  y: number;\n  children?: LayoutNodeData[];\n}\n\nexport interface IconData {\n  /**\n   * URL for the icon.\n   */\n  url: string;\n\n  /**\n   * Height of the icon.\n   */\n  height: number;\n\n  /**\n   * Width of the icon.\n   */\n  width: number;\n}\n\nexport interface EdgeData<T = any> {\n  /**\n   * Unique ID of the edge.\n   */\n  id: string;\n\n  /**\n   * Whether the edge is disabled or not.\n   */\n  disabled?: boolean;\n\n  /**\n   * Text label for the edge.\n   */\n  text?: any;\n\n  /**\n   * ID of the from node.\n   */\n  from?: string;\n\n  /**\n   * ID of the to node.\n   */\n  to?: string;\n\n  /**\n   * Optional ID of the from port.\n   */\n  fromPort?: string;\n\n  /**\n   * Optional ID of the to port.\n   */\n  toPort?: string;\n\n  /**\n   * Data about the edge.\n   */\n  data?: T;\n\n  /**\n   * CSS class name for the edge (\"path\" element).\n   */\n  className?: string;\n\n  /**\n   * CSS class name for the edge (main \"g\" element).\n   */\n  containerClassName?: string;\n\n  /**\n   * Optional arrow head type.\n   */\n  arrowHeadType?: any;\n\n  /**\n   * Parent of the edge for nesting.\n   */\n  parent?: string;\n\n  /**\n   * Whether the edge can be clicked.\n   */\n  selectionDisabled?: boolean;\n}\n\nexport type PortSide = 'NORTH' | 'SOUTH' | 'EAST' | 'WEST';\n\nexport interface PortData {\n  /**\n   * Unique ID of the port.\n   */\n  id: string;\n\n  /**\n   * Port is disabled.\n   */\n  disabled?: boolean;\n\n  /**\n   * Height of the port.\n   */\n  height: number;\n\n  /**\n   * Width of the port.\n   */\n  width: number;\n\n  /**\n   * Whether the port is visually hidden or not.\n   */\n  hidden?: boolean;\n\n  /**\n   * Classname for the port.\n   */\n  className?: string;\n\n  /**\n   * Alignment of the port.\n   */\n  alignment?: 'CENTER';\n\n  /**\n   * Side the port is located.\n   */\n  side: PortSide;\n}\n","import calculateSize from 'calculate-size';\nimport { LayoutNodeData, NodeData } from '../types';\nimport ellipsize from 'ellipsize';\n\nconst MAX_CHAR_COUNT = 35;\nconst MIN_NODE_WIDTH = 50;\nconst DEFAULT_NODE_HEIGHT = 50;\nconst NODE_PADDING = 30;\nconst ICON_PADDING = 10;\n\nexport function measureText(text: string) {\n  let result = { height: 0, width: 0 };\n\n  if (text) {\n    // Reference: https://github.com/reaviz/reaflow/pull/229\n    // @ts-ignore\n    const fn = typeof calculateSize === 'function' ? calculateSize : calculateSize.default;\n    result = fn(text, {\n      font: 'Arial, sans-serif',\n      fontSize: '14px'\n    });\n  }\n\n  return result;\n}\n\nexport function parsePadding(padding: NodeData['nodePadding']) {\n  let top = 50;\n  let right = 50;\n  let bottom = 50;\n  let left = 50;\n\n  if (Array.isArray(padding)) {\n    if (padding.length === 2) {\n      top = padding[0];\n      bottom = padding[0];\n      left = padding[1];\n      right = padding[1];\n    } else if (padding.length === 4) {\n      top = padding[0];\n      right = padding[1];\n      bottom = padding[2];\n      left = padding[3];\n    }\n  } else if (padding !== undefined) {\n    top = padding;\n    right = padding;\n    bottom = padding;\n    left = padding;\n  }\n\n  return {\n    top,\n    right,\n    bottom,\n    left\n  };\n}\n\nexport function formatText(node: NodeData) {\n  const text = node.text ? ellipsize(node.text, MAX_CHAR_COUNT) : node.text;\n\n  const labelDim = measureText(text);\n  const nodePadding = parsePadding(node.nodePadding);\n\n  let width = node.width;\n  if (width === undefined) {\n    if (text && node.icon) {\n      width = labelDim.width + node.icon.width + NODE_PADDING + ICON_PADDING;\n    } else {\n      if (text) {\n        width = labelDim.width + NODE_PADDING;\n      } else if (node.icon) {\n        width = node.icon.width + NODE_PADDING;\n      }\n\n      width = Math.max(width, MIN_NODE_WIDTH);\n    }\n  }\n\n  let height = node.height;\n  if (height === undefined) {\n    if (text && node.icon) {\n      height = labelDim.height + node.icon.height;\n    } else if (text) {\n      height = labelDim.height + NODE_PADDING;\n    } else if (node.icon) {\n      height = node.icon.height + NODE_PADDING;\n    }\n\n    height = Math.max(height, DEFAULT_NODE_HEIGHT);\n  }\n\n  return {\n    text,\n    originalText: node.text,\n    width,\n    height,\n    nodePadding,\n    labelHeight: labelDim.height,\n    labelWidth: labelDim.width\n  };\n}\n\n/**\n * Finds a node in a tree of nodes\n * @param nodes - The nodes to search through\n * @param nodeId - The id of the node to find\n * @returns The node if found, undefined otherwise\n */\nexport const findNode = (nodes: LayoutNodeData[], nodeId: string): any | undefined => {\n  for (const node of nodes) {\n    if (node.id === nodeId) {\n      return node;\n    }\n    if (node.children) {\n      const foundNode = findNode(node.children, nodeId);\n      if (foundNode) {\n        return foundNode;\n      }\n    }\n  }\n  return undefined;\n};\n\n/**\n * Finds the number of nested children a node has\n * @param node - The node to search through\n * @returns The number of children\n */\nexport const getChildCount = (node: LayoutNodeData): number => {\n  return (\n    node.children?.reduce((acc, child) => {\n      if (child.children) {\n        return acc + 1 + getChildCount(child);\n      }\n      return acc + 1;\n    }, 0) ?? 0\n  );\n};\n\n/**\n * Calculates the zoom for a group of nodes when fitting to the viewport\n * @param nodes - The nodes to calculate the zoom for\n * @param viewportWidth - The width of the viewport\n * @param viewportHeight - The height of the viewport\n * @param maxViewportCoverage - The maximum percentage of the viewport that the node group will take up\n * @param minViewportCoverage - The minimum percentage of the viewport that the node group will take up\n * @returns The zoom\n */\nexport const calculateZoom = ({ nodes, viewportWidth, viewportHeight, maxViewportCoverage = 0.9, minViewportCoverage = 0.2 }: { nodes: LayoutNodeData[]; viewportWidth: number; viewportHeight: number; maxViewportCoverage?: number; minViewportCoverage?: number }) => {\n  const maxChildren = Math.max(\n    0,\n    nodes.map(getChildCount).reduce((acc, curr) => acc + curr, 0)\n  );\n  const boundingBox = getNodesBoundingBox(nodes);\n  const boundingBoxWidth = boundingBox.x1 - boundingBox.x0;\n  const boundingBoxHeight = boundingBox.y1 - boundingBox.y0;\n\n  // calculate the maximum zoom to ensure no single node takes up more than 20% of the viewport\n  const maxNodeWidth = Math.max(...nodes.map((node) => node.width));\n  const maxNodeHeight = Math.max(...nodes.map((node) => node.height));\n  // if a node has children, let it take up an extra 10% per child\n  const maxNodeZoomX = ((0.2 + maxChildren * 0.1) * viewportWidth) / maxNodeWidth;\n  const maxNodeZoomY = ((0.2 + maxChildren * 0.1) * viewportHeight) / maxNodeHeight;\n  const maxNodeZoom = Math.min(maxNodeZoomX, maxNodeZoomY);\n\n  const viewportCoverage = Math.max(Math.min(maxViewportCoverage, maxNodeZoom), minViewportCoverage);\n\n  const updatedHorizontalZoom = (viewportCoverage * viewportWidth) / boundingBoxWidth;\n  const updatedVerticalZoom = (viewportCoverage * viewportHeight) / boundingBoxHeight;\n  const updatedZoom = Math.min(updatedHorizontalZoom, updatedVerticalZoom, maxNodeZoom);\n\n  return updatedZoom;\n};\n\n/**\n * Calculates the scroll position for the canvas when fitting nodes to the viewport - assumes the chart is centered\n * @param nodes - The nodes to calculate the zoom and position for\n * @param viewportWidth - The width of the viewport\n * @param viewportHeight - The height of the viewport\n * @param canvasWidth - The width of the canvas\n * @param canvasHeight - The height of the canvas\n * @param chartWidth - The width of the chart\n * @param chartHeight - The height of the chart\n * @param zoom - The zoom level of the canvas\n * @returns The scroll position\n */\nexport const calculateScrollPosition = ({ nodes, viewportWidth, viewportHeight, canvasWidth, canvasHeight, chartWidth, chartHeight, zoom }: { nodes: LayoutNodeData[]; viewportWidth: number; viewportHeight: number; canvasWidth: number; canvasHeight: number; chartWidth: number; chartHeight: number; zoom: number }): [number, number] => {\n  const { x0, y0, x1, y1 } = getNodesBoundingBox(nodes);\n  const boundingBoxWidth = (x1 - x0) * zoom;\n  const boundingBoxHeight = (y1 - y0) * zoom;\n\n  // the chart is centered so we can assume the x and y positions\n  const chartPosition = {\n    x: (canvasWidth - chartWidth * zoom) / 2,\n    y: (canvasHeight - chartHeight * zoom) / 2\n  };\n\n  const boxXPosition = chartPosition.x + x0 * zoom;\n  const boxYPosition = chartPosition.y + y0 * zoom;\n\n  const boxCenterXPosition = boxXPosition + boundingBoxWidth / 2;\n  const boxCenterYPosition = boxYPosition + boundingBoxHeight / 2;\n\n  // scroll to the spot that centers the node in the viewport\n  const scrollX = boxCenterXPosition - viewportWidth / 2;\n  const scrollY = boxCenterYPosition - viewportHeight / 2;\n\n  return [scrollX, scrollY];\n};\n\n/**\n * Calculates the bounding box of a group of nodes\n * @param nodes - The nodes to calculate the bounding box for\n * @returns The bounding box\n */\nexport const getNodesBoundingBox = (nodes: LayoutNodeData[]) => {\n  return nodes.reduce(\n    (acc, node) => ({\n      x0: Math.min(acc.x0, node.x),\n      y0: Math.min(acc.y0, node.y),\n      x1: Math.max(acc.x1, node.x + node.width),\n      y1: Math.max(acc.y1, node.y + node.height)\n    }),\n    { x0: nodes[0].x, y0: nodes[0].y, x1: nodes[0].x + nodes[0].width, y1: nodes[0].y + nodes[0].height }\n  );\n};\n","import { EdgeData, NodeData } from '../types';\nimport type { ELK, ElkNode } from 'elkjs';\nimport PCancelable from 'p-cancelable';\nimport { formatText, measureText } from './utils';\n\nexport type CanvasDirection = 'LEFT' | 'RIGHT' | 'DOWN' | 'UP';\n\n/**\n * ELKjs layout options for the Canvas.\n *\n * Unfortunately, the ELKjs documentation is not straightforward.\n * You'll likely need to take a look at the ELK options reference to see all available options.\n *\n * @see https://github.com/kieler/elkjs#layout-options\n * @see https://www.eclipse.org/elk/reference/options.html\n */\nexport interface ElkCanvasLayoutOptions {\n  'elk.direction'?: CanvasDirection;\n  [key: string]: string;\n}\n\n/**\n * ELKjs layout option for a node.\n *\n * TODO add reference link, I don't know what are the available options.\n *\n * @see https://www.eclipse.org/elk/reference/options.html\n */\nexport interface ElkNodeLayoutOptions {\n  [key: string]: string;\n\n  /**\n   * @example [left=12, top=12, right=12, bottom=12]\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-padding.html\n   */\n  'elk.padding': string;\n\n  /**\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-portConstraints.html\n   */\n  portConstraints: 'UNDEFINED' | 'FREE' | 'FIXED_SIDE' | 'FIXED_ORDER' | 'FIXED_RATIO' | 'FIXED_POS';\n}\n\n/**\n * ELK layout options applied by default, unless overridden through <Canvas layoutOptions> property.\n *\n * XXX Not to be confounded with ELK \"defaultLayoutOptions\" property, which is meant to be used as fallback, when no layout option is provided.\n *\n * @see https://www.eclipse.org/elk/reference/options.html\n */\nconst defaultLayoutOptions: ElkCanvasLayoutOptions = {\n  /**\n   * Hints for where node labels are to be placed; if empty, the node label’s position is not modified.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-nodeLabels-placement.html\n   */\n  'elk.nodeLabels.placement': 'INSIDE V_CENTER H_RIGHT',\n\n  /**\n   * Select a specific layout algorithm.\n   *\n   * Uses \"layered\" strategy.\n   * It emphasizes the direction of edges by pointing as many edges as possible into the same direction.\n   * The nodes are arranged in layers, which are sometimes called “hierarchies”,\n   * and then reordered such that the number of edge crossings is minimized.\n   * Afterwards, concrete coordinates are computed for the nodes and edge bend points.\n   *\n   * @see https://www.eclipse.org/elk/reference/algorithms.html\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-algorithm.html\n   * @see https://www.eclipse.org/elk/reference/algorithms/org-eclipse-elk-layered.html\n   */\n  'elk.algorithm': 'org.eclipse.elk.layered',\n\n  /**\n   * Overall direction of edges: horizontal (right / left) or vertical (down / up).\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-direction.html\n   */\n  'elk.direction': 'DOWN',\n\n  /**\n   * The node order given by the model does not change to produce a better layout.\n   * E.g. if node A is before node B in the model this is not changed during crossing minimization.\n   * This assumes that the node model order is already respected before crossing minimization. This\n   * can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES.\n   *\n   * @see https://eclipse.dev/elk/reference/options/org-eclipse-elk-layered-crossingMinimization-forceNodeModelOrder.html\n   */\n  'layered.crossingMinimization.forceNodeModelOrder': 'true',\n\n  /**\n   * Strategy for node layering.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-layering-strategy.html\n   */\n  'org.eclipse.elk.layered.layering.strategy': 'INTERACTIVE',\n\n  /**\n   * What kind of edge routing style should be applied for the content of a parent node.\n   * Algorithms may also set this option to single edges in order to mark them as splines.\n   * The bend point list of edges with this option set to SPLINES\n   * must be interpreted as control points for a piecewise cubic spline.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-edgeRouting.html\n   */\n  'org.eclipse.elk.edgeRouting': 'ORTHOGONAL',\n\n  /**\n   * Adds bend points even if an edge does not change direction.\n   * If true, each long edge dummy will contribute a bend point to its edges\n   * and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries.\n   * By default, bend points are only added where an edge changes direction.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-unnecessaryBendpoints.html\n   */\n  'elk.layered.unnecessaryBendpoints': 'true',\n\n  /**\n   * The spacing to be preserved between nodes and edges that are routed next to the node’s layer.\n   * For the spacing between nodes and edges that cross the node’s layer ‘spacing.edgeNode’ is used.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-spacing-edgeNodeBetweenLayers.html\n   */\n  'elk.layered.spacing.edgeNodeBetweenLayers': '50',\n\n  /**\n   * Tells the BK node placer to use a certain alignment (out of its four)\n   * instead of the one producing the smallest height, or the combination of all four.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-nodePlacement-bk-fixedAlignment.html\n   */\n  'org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment': 'BALANCED',\n\n  /**\n   * Strategy for cycle breaking.\n   *\n   * Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles.\n   * Reversed edges will end up pointing to the opposite direction of regular edges\n   * (that is, reversed edges will point left if edges usually point right).\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-cycleBreaking-strategy.html\n   */\n  'org.eclipse.elk.layered.cycleBreaking.strategy': 'DEPTH_FIRST',\n\n  /**\n   * Whether this node allows to route self loops inside of it instead of around it.\n   *\n   * If set to true, this will make the node a compound node if it isn’t already,\n   * and will require the layout algorithm to support compound nodes with hierarchical ports.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-insideSelfLoops-activate.html\n   */\n  'org.eclipse.elk.insideSelfLoops.activate': 'true',\n\n  /**\n   * Whether each connected component should be processed separately.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-separateConnectedComponents.html\n   */\n  separateConnectedComponents: 'false',\n\n  /**\n   * Spacing to be preserved between pairs of connected components.\n   * This option is only relevant if ‘separateConnectedComponents’ is activated.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-spacing-componentComponent.html\n   */\n  'spacing.componentComponent': '70',\n\n  /**\n   * TODO: Should be spacing.baseValue?\n   * An optional base value for all other layout options of the ‘spacing’ group.\n   * It can be used to conveniently alter the overall ‘spaciousness’ of the drawing.\n   * Whenever an explicit value is set for the other layout options, this base value will have no effect.\n   * The base value is not inherited, i.e. it must be set for each hierarchical node.\n   *\n   * @see https://www.eclipse.org/elk/reference/groups/org-eclipse-elk-layered-spacing.html\n   */\n  spacing: '75',\n\n  /**\n   * The spacing to be preserved between any pair of nodes of two adjacent layers.\n   * Note that ‘spacing.nodeNode’ is used for the spacing between nodes within the layer itself.\n   *\n   * @see https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-spacing-nodeNodeBetweenLayers.html\n   */\n  'spacing.nodeNodeBetweenLayers': '70'\n};\n\nfunction mapNode(nodes: NodeData[], edges: EdgeData[], node: NodeData) {\n  const { text, width, height, labelHeight, labelWidth, nodePadding, originalText } = formatText(node);\n\n  const children = nodes.filter((n) => n.parent === node.id).map((n) => mapNode(nodes, edges, n));\n\n  const childEdges = edges.filter((e) => e.parent === node.id).map((e) => mapEdge({ edge: e }));\n\n  const nodeLayoutOptions: ElkNodeLayoutOptions = {\n    'elk.padding': `[left=${nodePadding.left}, top=${nodePadding.top}, right=${nodePadding.right}, bottom=${nodePadding.bottom}]`,\n    portConstraints: 'FIXED_ORDER',\n    ...(node.layoutOptions || {})\n  };\n\n  return {\n    id: node.id,\n    height,\n    width,\n    children,\n    edges: childEdges,\n    ports: node.ports\n      ? node.ports.map((port) => ({\n        id: port.id,\n        properties: {\n          ...port,\n          'port.side': port.side,\n          'port.alignment': port.alignment || 'CENTER'\n        }\n      }))\n      : [],\n    layoutOptions: nodeLayoutOptions,\n    properties: {\n      ...node\n    },\n    labels: text\n      ? [\n        {\n          width: labelWidth,\n          height: -(labelHeight / 2),\n          text,\n          originalText\n          // layoutOptions: { 'elk.nodeLabels.placement': 'INSIDE V_CENTER H_CENTER' }\n        }\n      ]\n      : []\n  };\n}\n\nfunction mapEdge({ edge: { data, ...edge }, direction }: { edge: EdgeData; direction?: CanvasDirection }) {\n  const labelDim = measureText(edge.text);\n  const validEdgeData = data ? { data } : {};\n  let labelWidth = labelDim.width / 2;\n\n  if (direction === 'LEFT' || direction === 'RIGHT') {\n    labelWidth = labelDim.width;\n  }\n\n  return {\n    id: edge.id,\n    source: edge.from,\n    target: edge.to,\n    properties: {\n      ...edge\n    },\n    ...validEdgeData,\n    sourcePort: edge.fromPort,\n    targetPort: edge.toPort,\n    labels: edge.text\n      ? [\n        {\n          width: labelWidth,\n          height: -(labelDim.height / 2),\n          text: edge.text,\n          layoutOptions: {\n            'elk.edgeLabels.placement': 'INSIDE V_CENTER H_CENTER'\n          }\n        }\n      ]\n      : []\n  };\n}\n\nfunction mapInput({ nodes, edges, direction }: { nodes: NodeData[]; edges: EdgeData[]; direction?: CanvasDirection }) {\n  const children = [];\n  const mappedEdges = [];\n\n  for (const node of nodes) {\n    if (!node.parent) {\n      const mappedNode = mapNode(nodes, edges, node);\n      if (mappedNode !== null) {\n        children.push(mappedNode);\n      }\n    }\n  }\n\n  for (const edge of edges) {\n    if (!edge.parent) {\n      const mappedEdge = mapEdge({ edge, direction });\n      if (mappedEdge !== null) {\n        mappedEdges.push(mappedEdge);\n      }\n    }\n  }\n\n  return {\n    children,\n    edges: mappedEdges\n  };\n}\n\nfunction postProcessNode(nodes: any[]): any[] {\n  for (const node of nodes) {\n    const hasLabels = node.labels?.length > 0;\n\n    if (hasLabels && node.properties.icon) {\n      const [label] = node.labels;\n      label.x = node.properties.icon.width + 25;\n      node.properties.icon.x = 25;\n      node.properties.icon.y = node.height / 2;\n    } else if (hasLabels) {\n      const [label] = node.labels;\n      label.x = (node.width - label.width) / 2;\n    } else if (node.properties.icon) {\n      node.properties.icon.x = node.width / 2;\n      node.properties.icon.y = node.height / 2;\n    }\n\n    if (node.children) {\n      postProcessNode(node.children);\n    }\n  }\n\n  return nodes;\n}\n\nconst isBrowser = typeof window !== 'undefined' && typeof Worker !== 'undefined';\nlet elkInstance: ELK | null = null;\n\nconst getElk = async () => {\n  if (elkInstance) return elkInstance;\n\n  if (!isBrowser) {\n    const ELKModule = await import('elkjs/lib/elk.bundled.js');\n    elkInstance = new ELKModule.default({\n      algorithms: ['layered']\n    });\n\n    return elkInstance;\n  } else {\n    const ELKModule = await import('elkjs/lib/elk-api');\n\n    elkInstance = new ELKModule.default({\n      algorithms: ['layered'],\n      workerFactory: () => {\n        const workerUrl = new URL('elkjs/lib/elk-worker.min.js', import.meta.url).href;\n        return new Worker(workerUrl);\n      }\n    });\n\n    return elkInstance;\n  }\n};\n\nexport const elkLayout = (nodes: NodeData[], edges: EdgeData[], options: ElkCanvasLayoutOptions) => {\n  return new PCancelable<ElkNode>(async (resolve, reject) => {\n    const graph = await getElk();\n    const layoutOptions: ElkCanvasLayoutOptions = {\n      ...defaultLayoutOptions,\n      ...options\n    };\n\n    graph\n      .layout(\n        {\n          id: 'root',\n          ...mapInput({ nodes, edges, direction: layoutOptions?.['elk.direction'] })\n        },\n        {\n          layoutOptions: layoutOptions\n        }\n      )\n      .then((data) => {\n        resolve({\n          ...data,\n          children: postProcessNode(data.children)\n        });\n      })\n      .catch(reject);\n  });\n};\n","import { RefObject, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport useDimensions from 'react-cool-dimensions';\nimport isEqual from 'react-fast-compare';\nimport { CanvasPosition, EdgeData, NodeData } from '../types';\nimport { CanvasDirection, ElkCanvasLayoutOptions, elkLayout } from './elkLayout';\nimport { calculateScrollPosition, calculateZoom, findNode } from './utils';\n\nexport interface ElkRoot {\n  x?: number;\n  y?: number;\n  width?: number;\n  height?: number;\n  children?: any[];\n  edges?: any[];\n  direction?: CanvasDirection;\n}\n\nexport interface LayoutProps {\n  maxHeight: number;\n  maxWidth: number;\n  nodes: NodeData[];\n  edges: EdgeData[];\n  pannable: boolean;\n  defaultPosition: CanvasPosition;\n  fit: boolean;\n  zoom: number;\n  layoutOptions?: ElkCanvasLayoutOptions;\n  direction: CanvasDirection;\n  setZoom: (factor: number) => void;\n  onLayoutChange: (layout: ElkRoot) => void;\n}\n\nexport interface LayoutResult {\n  /**\n   * X/Y offset.\n   */\n  xy: [number, number];\n\n  /**\n   * Scroll offset.\n   */\n  scrollXY: [number, number];\n\n  /**\n   * ELK Layout object.\n   */\n  layout: ElkRoot;\n\n  /**\n   * Ref to container div.\n   */\n  containerRef: RefObject<HTMLDivElement | null>;\n\n  /**\n   * Height of the svg.\n   */\n  canvasHeight?: number;\n\n  /**\n   * Width of the svg.\n   */\n  canvasWidth?: number;\n\n  /**\n   * Width of the container div.\n   */\n  containerWidth?: number;\n\n  /**\n   * Height of the container div.\n   */\n  containerHeight?: number;\n\n  /**\n   * Positions the canvas to the viewport.\n   */\n  positionCanvas?: (position: CanvasPosition, animated?: boolean) => void;\n\n  /**\n   * Fit the canvas to the viewport.\n   */\n  fitCanvas?: (animated?: boolean) => void;\n\n  /**\n   * Fit a group of nodes to the viewport.\n   */\n  fitNodes?: (nodeIds: string | string[], animated?: boolean) => void;\n\n  /**\n   * Scroll to X/Y\n   */\n  setScrollXY?: (xy: [number, number], animated?: boolean) => void;\n\n  observe: (el: HTMLDivElement) => void;\n}\n\nexport const useLayout = ({ maxWidth, maxHeight, nodes = [], edges = [], fit, pannable, defaultPosition, direction, layoutOptions = {}, zoom, setZoom, onLayoutChange }: LayoutProps) => {\n  const scrolled = useRef<boolean>(false);\n  const ref = useRef<HTMLDivElement>();\n  const { observe, width, height } = useDimensions<HTMLDivElement>();\n  const [layout, setLayout] = useState<ElkRoot | null>(null);\n  const [xy, setXY] = useState<[number, number]>([0, 0]);\n  const [scrollXY, setScrollXY] = useState<[number, number]>([0, 0]);\n  const canvasHeight = pannable ? maxHeight : height;\n  const canvasWidth = pannable ? maxWidth : width;\n\n  const scrollToXY = (xy: [number, number], animated = false) => {\n    ref.current.scrollTo({ left: xy[0], top: xy[1], behavior: animated ? 'smooth' : 'auto' });\n    setScrollXY(xy);\n  };\n\n  useEffect(() => {\n    const promise = elkLayout(nodes, edges, {\n      'elk.direction': direction,\n      ...layoutOptions\n    });\n\n    promise\n      .then((result) => {\n        if (!isEqual(layout, result)) {\n          setLayout(result);\n          onLayoutChange(result);\n        }\n      })\n      .catch((err) => {\n        if (err.name !== 'CancelError') {\n          console.error('Layout Error:', err);\n        }\n      });\n\n    return () => promise.cancel();\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [nodes, edges]);\n\n  const positionVector = useCallback(\n    (position: CanvasPosition) => {\n      if (layout) {\n        const centerX = (canvasWidth - layout.width * zoom) / 2;\n        const centerY = (canvasHeight - layout.height * zoom) / 2;\n        switch (position) {\n          case CanvasPosition.CENTER:\n            setXY([centerX, centerY]);\n            break;\n          case CanvasPosition.TOP:\n            setXY([centerX, 0]);\n            break;\n          case CanvasPosition.LEFT:\n            setXY([0, centerY]);\n            break;\n          case CanvasPosition.RIGHT:\n            setXY([canvasWidth - layout.width * zoom, centerY]);\n            break;\n          case CanvasPosition.BOTTOM:\n            setXY([centerX, canvasHeight - layout.height * zoom]);\n            break;\n        }\n      }\n    },\n    [canvasWidth, canvasHeight, layout, zoom]\n  );\n\n  const positionScroll = useCallback(\n    (position: CanvasPosition, animated = false) => {\n      const scrollCenterX = (canvasWidth - width) / 2;\n      const scrollCenterY = (canvasHeight - height) / 2;\n      if (pannable) {\n        switch (position) {\n          case CanvasPosition.CENTER:\n            scrollToXY([scrollCenterX, scrollCenterY], animated);\n            break;\n          case CanvasPosition.TOP:\n            scrollToXY([scrollCenterX, 0], animated);\n            break;\n          case CanvasPosition.LEFT:\n            scrollToXY([0, scrollCenterY], animated);\n            break;\n          case CanvasPosition.RIGHT:\n            scrollToXY([canvasWidth - width, scrollCenterY], animated);\n            break;\n          case CanvasPosition.BOTTOM:\n            scrollToXY([scrollCenterX, canvasHeight - height], animated);\n            break;\n        }\n      }\n    },\n    [canvasWidth, canvasHeight, width, height, pannable]\n  );\n\n  const positionCanvas = useCallback(\n    (position: CanvasPosition, animated = false) => {\n      positionVector(position);\n      positionScroll(position, animated);\n    },\n    [positionScroll, positionVector]\n  );\n\n  useEffect(() => {\n    if (scrolled.current && defaultPosition) {\n      positionVector(defaultPosition);\n    }\n  }, [positionVector, zoom, defaultPosition]);\n\n  const fitCanvas = useCallback(\n    (animated = false) => {\n      if (layout) {\n        const heightZoom = height / layout.height;\n        const widthZoom = width / layout.width;\n        const scale = Math.min(heightZoom, widthZoom, 1);\n        setZoom(scale - 1);\n        positionCanvas(CanvasPosition.CENTER, animated);\n      }\n    },\n    [height, layout, width, setZoom, positionCanvas]\n  );\n\n  /**\n   * This centers the chart on the canvas, zooms in to fit the specified nodes, and scrolls to center the nodes in the viewport\n   */\n  const fitNodes = useCallback(\n    (nodeIds: string | string[], animated = true) => {\n      if (layout && layout.children) {\n        const nodes = Array.isArray(nodeIds) ? nodeIds.map((nodeId) => findNode(layout.children, nodeId)) : [findNode(layout.children, nodeIds)];\n\n        if (nodes) {\n          // center the chart\n          positionVector(CanvasPosition.CENTER);\n\n          const updatedZoom = calculateZoom({ nodes, viewportWidth: width, viewportHeight: height, maxViewportCoverage: 0.9, minViewportCoverage: 0.2 });\n          const scrollPosition = calculateScrollPosition({ nodes, viewportWidth: width, viewportHeight: height, canvasWidth, canvasHeight, chartWidth: layout.width, chartHeight: layout.height, zoom: updatedZoom });\n\n          setZoom(updatedZoom - 1);\n          scrollToXY(scrollPosition, animated);\n        }\n      }\n    },\n    [canvasHeight, canvasWidth, height, layout, positionVector, setZoom, width]\n  );\n\n  useLayoutEffect(() => {\n    const scroller = ref.current;\n    if (scroller && !scrolled.current && layout && height && width) {\n      if (fit) {\n        fitCanvas();\n      } else if (defaultPosition) {\n        positionCanvas(defaultPosition);\n      }\n\n      scrolled.current = true;\n    }\n  }, [canvasWidth, pannable, canvasHeight, layout, height, fit, width, defaultPosition, positionCanvas, fitCanvas, ref]);\n\n  useLayoutEffect(() => {\n    function onResize() {\n      if (fit) {\n        fitCanvas();\n      } else if (defaultPosition) {\n        positionCanvas(defaultPosition);\n      }\n    }\n\n    window.addEventListener('resize', onResize);\n\n    return () => window.removeEventListener('resize', onResize);\n  }, [fit, positionCanvas, defaultPosition, fitCanvas]);\n\n  return {\n    xy,\n    observe,\n    containerRef: ref,\n    canvasHeight,\n    canvasWidth,\n    containerWidth: width,\n    containerHeight: height,\n    layout,\n    scrollXY,\n    positionCanvas,\n    fitCanvas,\n    fitNodes,\n    setScrollXY: scrollToXY\n  } as LayoutResult;\n};\n","import React, { useCallback, useState } from 'react';\nimport { EdgeSections } from '../symbols/Edge';\nimport { NodeData, PortData } from '../types';\nimport { DragEvent, NodeDragEvents, Position } from './useNodeDrag';\nimport { Point2D } from 'kld-affine';\nimport { NodeDragType } from '../symbols/Node';\n\nexport interface EdgeDragResult extends NodeDragEvents {\n  dragCoords: EdgeSections[] | null;\n  canLinkNode: boolean | null;\n  dragNode: NodeData | null;\n  dragPort: PortData | null;\n  enteredNode: NodeData | null;\n  onEnter?: (\n    event: React.MouseEvent<SVGGElement, MouseEvent>,\n    data: NodeData | PortData\n  ) => void;\n  onLeave?: (\n    event: React.MouseEvent<SVGGElement, MouseEvent>,\n    data: NodeData | PortData\n  ) => void;\n}\n\nexport const useEdgeDrag = ({\n  onNodeLink,\n  onNodeLinkCheck\n}): EdgeDragResult => {\n  const [dragNode, setDragNode] = useState<NodeData | null>(null);\n  const [dragPort, setDragPort] = useState<PortData | null>(null);\n  const [dragType, setDragType] = useState<NodeDragType | null>(null);\n  const [enteredNode, setEnteredNode] = useState<NodeData | null>(null);\n  const [dragCoords, setDragCoords] = useState<EdgeSections[] | null>(null);\n  const [canLinkNode, setCanLinkNode] = useState<boolean | null>(null);\n\n  const onDragStart = useCallback(\n    (state: DragEvent, _initial: Position, node: NodeData, port?: PortData) => {\n      setDragType(state.dragType);\n      setDragNode(node);\n      setDragPort(port);\n    },\n    []\n  );\n\n  const onDrag = useCallback(\n    ({ memo: [matrix], xy: [x, y] }: DragEvent, [ix, iy]: Position) => {\n      const endPoint = new Point2D(x, y).transform(matrix);\n      setDragCoords([\n        {\n          startPoint: {\n            x: ix,\n            y: iy\n          },\n          endPoint\n        }\n      ]);\n    },\n    []\n  );\n\n  const onDragEnd = useCallback(\n    (event: DragEvent) => {\n      if (dragNode && enteredNode && canLinkNode) {\n        onNodeLink(event, dragNode, enteredNode, dragPort);\n      }\n\n      setDragNode(null);\n      setDragPort(null);\n      setEnteredNode(null);\n      setDragCoords(null);\n    },\n    [canLinkNode, dragNode, dragPort, enteredNode, onNodeLink]\n  );\n\n  const onEnter = useCallback(\n    (event: React.MouseEvent<SVGGElement, MouseEvent>, node: NodeData) => {\n      if (dragNode && node) {\n        setEnteredNode(node);\n        const canLink = onNodeLinkCheck(event, dragNode, node, dragPort);\n        const result =\n          (canLink === undefined || canLink) &&\n          (dragNode.parent === node.parent || dragType === 'node');\n\n        setCanLinkNode(result);\n      }\n    },\n    [dragNode, dragPort, dragType, onNodeLinkCheck]\n  );\n\n  const onLeave = useCallback(\n    (event: React.MouseEvent<SVGGElement, MouseEvent>, node: NodeData) => {\n      if (dragNode && node) {\n        setEnteredNode(null);\n        setCanLinkNode(null);\n      }\n    },\n    [dragNode]\n  );\n\n  return {\n    dragCoords,\n    canLinkNode,\n    dragNode,\n    dragPort,\n    enteredNode,\n    onDragStart,\n    onDrag,\n    onDragEnd,\n    onEnter,\n    onLeave\n  };\n};\n","import { RefObject, useCallback, useRef, useState } from 'react';\nimport { useGesture } from 'react-use-gesture';\n\nconst limit = (scale: number, min: number, max: number) => (scale < max ? (scale > min ? scale : min) : max);\n\nexport interface ZoomProps {\n  disabled?: boolean;\n  zoom?: number;\n  minZoom?: number;\n  maxZoom?: number;\n  onZoomChange: (zoom: number) => void;\n}\n\nexport interface ZoomResult {\n  /**\n   * Factor of zoom.\n   */\n  zoom: number;\n\n  /**\n   * SVG Ref for the Canvas.\n   */\n  svgRef: RefObject<SVGSVGElement | null>;\n\n  /**\n   * Set a zoom factor of the canvas.\n   */\n  setZoom?: (factor: number) => void;\n\n  /**\n   * Zoom in on the canvas.\n   */\n  zoomIn?: (zoomFactor?: number) => void;\n\n  /**\n   * Zoom out on the canvas.\n   */\n  zoomOut?: (zoomFactor?: number) => void;\n}\n\nexport const useZoom = ({ disabled = false, zoom = 1, minZoom = -0.5, maxZoom = 1, onZoomChange }: ZoomProps) => {\n  const [factor, setFactor] = useState<number>(zoom - 1);\n  const svgRef = useRef<SVGSVGElement | null>(null);\n\n  useGesture(\n    {\n      onPinch: ({ offset: [d], event }) => {\n        event.preventDefault();\n        // TODO: Set X/Y on center of zoom\n        const next = limit(d / 100, minZoom, maxZoom);\n        setFactor(next);\n        onZoomChange(next + 1);\n      }\n    },\n    {\n      enabled: !disabled,\n      domTarget: svgRef,\n      eventOptions: { passive: false }\n    }\n  );\n\n  const setZoom = useCallback(\n    (f: number) => {\n      const next = limit(f, minZoom, maxZoom);\n      setFactor(next);\n      onZoomChange(next + 1);\n    },\n    [maxZoom, minZoom, onZoomChange]\n  );\n\n  const zoomIn = useCallback(\n    (zoomFactor: number = 0.1) => {\n      setZoom(factor + zoomFactor);\n    },\n    [factor, setZoom]\n  );\n\n  const zoomOut = useCallback(\n    (zoomFactor: number = -0.1) => {\n      setZoom(factor + zoomFactor);\n    },\n    [factor, setZoom]\n  );\n\n  return {\n    svgRef,\n    zoom: factor + 1,\n    setZoom,\n    zoomIn,\n    zoomOut\n  } as ZoomResult;\n};\n","import React, { createContext, useContext } from 'react';\nimport { LayoutResult, useLayout } from '../layout/useLayout';\nimport { NodeData, PortData } from '../types';\nimport { EdgeDragResult, useEdgeDrag } from './useEdgeDrag';\nimport { useZoom, ZoomResult } from './useZoom';\n\nexport interface CanvasProviderValue\n  extends EdgeDragResult,\n    LayoutResult,\n    ZoomResult {\n  selections?: string[];\n  readonly?: boolean;\n  pannable: boolean;\n  panType: 'scroll' | 'drag'; \n}\n\nexport const CanvasContext = createContext<CanvasProviderValue>({} as any);\n\nexport interface CanvasProviderProps {\n  onNodeLink?: (\n    event: any,\n    fromNode: NodeData,\n    toNode: NodeData,\n    fromPort?: PortData\n  ) => void;\n  onNodeLinkCheck?: (\n    event: any,\n    fromNode: NodeData,\n    toNode: NodeData,\n    fromPort?: PortData\n  ) => undefined | boolean;\n}\n\nexport const CanvasProvider = ({\n  selections,\n  onNodeLink,\n  readonly,\n  children,\n  nodes,\n  edges,\n  maxHeight,\n  fit,\n  maxWidth,\n  direction,\n  layoutOptions,\n  pannable,\n  panType,\n  defaultPosition,\n  zoomable,\n  zoom,\n  minZoom,\n  maxZoom,\n  onNodeLinkCheck,\n  onLayoutChange,\n  onZoomChange\n}) => {\n  const zoomProps = useZoom({\n    zoom,\n    minZoom,\n    maxZoom,\n    disabled: !zoomable,\n    onZoomChange\n  });\n\n  const layoutProps = useLayout({\n    nodes,\n    edges,\n    maxHeight,\n    maxWidth,\n    direction,\n    pannable,\n    panType,\n    defaultPosition,\n    fit,\n    layoutOptions,\n    zoom: zoomProps.zoom,\n    setZoom: zoomProps.setZoom,\n    onLayoutChange\n  });\n\n  const dragProps = useEdgeDrag({\n    onNodeLink,\n    onNodeLinkCheck\n  });\n\n  return (\n    <CanvasContext.Provider\n      value={{\n        selections,\n        readonly,\n        pannable,\n        panType,\n        ...layoutProps,\n        ...zoomProps,\n        ...dragProps\n      }}\n    >\n      {children}\n    </CanvasContext.Provider>\n  );\n};\n\nexport const useCanvas = () => {\n  const context = useContext(CanvasContext);\n\n  if (context === undefined) {\n    throw new Error(\n      '`useCanvas` hook must be used within a `CanvasContext` component'\n    );\n  }\n\n  return context;\n};\n","import { RefObject } from 'react';\nimport { NodeData } from '../types';\nimport { Matrix2D } from 'kld-affine';\n\n/**\n * Checks if the node can be linked or not.\n */\nexport function checkNodeLinkable(\n  curNode: NodeData,\n  enteredNode: NodeData | null,\n  canLinkNode: boolean | null\n) {\n  if (canLinkNode === null || !enteredNode) {\n    return null;\n  }\n\n  if (!enteredNode || !curNode) {\n    return false;\n  }\n\n  // TODO: Revisit how to do self-linking better...\n  return !(canLinkNode === false && enteredNode.id === curNode.id);\n}\n\nexport interface CoordProps {\n  zoom: number;\n  layoutXY: [number, number];\n  containerRef: RefObject<HTMLDivElement | null>;\n}\n\n/**\n * Given various dimensions and positions, create a matrix\n * used for determining position.\n */\nexport function getCoords({ zoom, layoutXY, containerRef }: CoordProps) {\n  const { top, left } = containerRef.current.getBoundingClientRect();\n  const tx = layoutXY[0] - containerRef.current.scrollLeft + left;\n  const ty = layoutXY[1] - containerRef.current.scrollTop + top;\n\n  return new Matrix2D().translate(tx, ty).scale(zoom).inverse();\n}\n\n/**\n * Given a nodeId to find, a list of nodes to check against, and an optional parentId of the node\n * find the node from the list of nodes\n */\nexport function findNestedNode(\n  nodeId: string,\n  children: any[],\n  parentId?: string\n): { [key: string]: any } {\n  if (!nodeId || !children) {\n    return {};\n  }\n\n  const foundNode = children.find((n) => n.id === nodeId);\n  if (foundNode) {\n    return foundNode;\n  }\n\n  if (parentId) {\n    const parentNode = children.find((n) => n.id === parentId);\n    if (parentNode?.children) {\n      return findNestedNode(nodeId, parentNode.children, parentId);\n    }\n  }\n\n  // Check for nested children\n  const nodesWithChildren = children.filter((n) => n.children?.length);\n  // Iterate over all nested nodes and check if any of them contain the node\n  for (const n of nodesWithChildren) {\n    const foundChild = findNestedNode(nodeId, n.children, parentId);\n\n    if (foundChild && Object.keys(foundChild).length) {\n      return foundChild;\n    }\n  }\n\n  return {};\n}\n\n/**\n * Return the layout node that is currently being dragged on the Canvas\n */\nexport function getDragNodeData(\n  dragNode: NodeData,\n  children: any[] = []\n): { [key: string]: any } {\n  if (!dragNode) {\n    return {};\n  }\n\n  const { parent } = dragNode;\n  if (!parent) {\n    return children?.find((n) => n.id === dragNode.id) || {};\n  }\n\n  return findNestedNode(dragNode.id, children, parent);\n}\n","import { useRef } from 'react';\nimport { useDrag } from 'react-use-gesture';\nimport { State } from 'react-use-gesture/dist/types';\nimport { NodeDragType } from 'symbols';\nimport { NodeData } from '../types';\nimport { useCanvas } from './CanvasProvider';\nimport { getCoords } from './helpers';\n\nexport type DragEvent = State['drag'] & { dragType?: NodeDragType };\nexport type Position = [number, number];\n\nexport interface NodeDragEvents<T = any, TT = any | undefined> {\n  onDrag?: (event: DragEvent, initial: Position, data: T, extra?: TT) => void;\n  onDragEnd?: (\n    event: DragEvent,\n    initial: Position,\n    data: T,\n    extra?: TT\n  ) => void;\n  onDragStart?: (\n    event: DragEvent,\n    initial: Position,\n    data: T,\n    extra?: TT\n  ) => void;\n}\n\nexport interface NodeDragProps extends NodeDragEvents {\n  node: NodeData;\n  height: number;\n  width: number;\n  x: number;\n  y: number;\n  disabled: boolean;\n}\n\nexport const useNodeDrag = ({\n  x,\n  y,\n  height,\n  width,\n  onDrag,\n  onDragEnd,\n  onDragStart,\n  node,\n  disabled\n}: NodeDragProps) => {\n  const initial: Position = [width / 2 + x, height + y];\n  const targetRef = useRef<EventTarget | null>(null);\n  const { zoom, xy, containerRef } = useCanvas();\n\n  const bind = useDrag(\n    (state) => {\n      if (state.event.type === 'pointerdown') {\n        targetRef.current = state.event.currentTarget;\n      }\n\n      if (!state.intentional || !targetRef.current) {\n        return;\n      }\n\n      if (state.first) {\n        const matrix = getCoords({\n          containerRef,\n          zoom,\n          layoutXY: xy\n        });\n\n        // memo will hold the difference between the\n        // first point of impact and the origin\n        const memo = [matrix];\n\n        onDragStart({ ...state, memo }, initial, node);\n\n        return memo;\n      }\n\n      onDrag(state, initial, node);\n\n      if (state.last) {\n        targetRef.current = null;\n        onDragEnd(state, initial, node);\n      }\n    },\n    {\n      enabled: !disabled,\n      triggerAllEvents: true,\n      threshold: 5\n    }\n  );\n\n  return bind;\n};\n","import React, { forwardRef, Fragment, ReactNode, Ref, useState } from 'react';\nimport { motion } from 'motion/react';\nimport { PortData } from '../../types';\nimport { NodeDragEvents, DragEvent, useNodeDrag, Position } from '../../utils/useNodeDrag';\nimport classNames from 'classnames';\nimport { useCanvas } from '../../utils/CanvasProvider';\nimport css from './Port.module.css';\n\nexport interface ElkPortProperties {\n  index: number;\n  width: number;\n  height: number;\n  'port.side': string;\n  'port.alignment': string;\n}\n\nexport interface PortChildProps {\n  port: PortData;\n  isDisabled: boolean;\n  isDragging: boolean;\n  isHovered: boolean;\n  x: number;\n  y: number;\n  rx: number;\n  ry: number;\n  offsetX: number;\n  offsetY: number;\n}\n\nexport type PortChildrenAsFunction = (portChildProps: PortChildProps) => ReactNode;\n\nexport interface PortProps extends NodeDragEvents<PortData> {\n  id: string;\n  x: number;\n  y: number;\n  rx: number;\n  ry: number;\n  offsetX: number;\n  offsetY: number;\n  disabled?: boolean;\n  className?: string;\n  properties: ElkPortProperties & PortData;\n  style?: any;\n  children?: ReactNode | PortChildrenAsFunction;\n  active?: boolean;\n  onEnter?: (event: React.MouseEvent<SVGGElement, MouseEvent>, port: PortData) => void;\n  onLeave?: (event: React.MouseEvent<SVGGElement, MouseEvent>, port: PortData) => void;\n  onClick?: (event: React.MouseEvent<SVGGElement, MouseEvent>, port: PortData) => void;\n}\n\nexport const Port = forwardRef(({ id, x, y, rx, ry, disabled, style, children, properties, offsetX, offsetY, className, active, onDrag = () => undefined, onDragStart = () => undefined, onDragEnd = () => undefined, onEnter = () => undefined, onLeave = () => undefined, onClick = () => undefined }: Partial<PortProps>, ref: Ref<SVGRectElement>) => {\n  const { readonly } = useCanvas();\n  const [isDragging, setIsDragging] = useState<boolean>(false);\n  const [isHovered, setIsHovered] = useState<boolean>(false);\n  const newX = x - properties.width / 2;\n  const newY = y - properties.height / 2;\n\n  const onDragStartInternal = (event: DragEvent, initial: Position) => {\n    onDragStart(event, initial, properties);\n    setIsDragging(true);\n  };\n\n  const onDragEndInternal = (event: DragEvent, initial: Position) => {\n    onDragEnd(event, initial, properties);\n    setIsDragging(false);\n  };\n\n  const bind = useNodeDrag({\n    x: newX + offsetX,\n    y: newY + offsetY,\n    height: properties.height,\n    width: properties.width,\n    disabled: disabled || readonly || properties?.disabled,\n    node: properties,\n    onDrag,\n    onDragStart: onDragStartInternal,\n    onDragEnd: onDragEndInternal\n  });\n\n  if (properties.hidden) {\n    return null;\n  }\n\n  const isDisabled = properties.disabled || disabled;\n\n  const portChildProps: PortChildProps = {\n    port: properties,\n    isDragging,\n    isHovered,\n    isDisabled,\n    x,\n    y,\n    rx,\n    ry,\n    offsetX,\n    offsetY\n  };\n\n  return (\n    <g id={id}>\n      <rect\n        {...bind()}\n        ref={ref}\n        height={properties.height + 14}\n        width={properties.width + 14}\n        x={newX - 7}\n        y={newY - 7}\n        className={classNames(css.clicker, { [css.disabled]: isDisabled })}\n        onMouseEnter={(event) => {\n          event.stopPropagation();\n          if (!isDisabled) {\n            setIsHovered(true);\n            onEnter(event, properties);\n          }\n        }}\n        onMouseLeave={(event) => {\n          event.stopPropagation();\n          if (!isDisabled) {\n            setIsHovered(false);\n            onLeave(event, properties);\n          }\n        }}\n        onClick={(event) => {\n          event.stopPropagation();\n          if (!isDisabled) {\n            onClick(event, properties);\n          }\n        }}\n      />\n      <motion.rect\n        key={`${x}-${y}`}\n        style={style}\n        className={classNames(css.port, className, properties?.className)}\n        height={properties.height}\n        width={properties.width}\n        rx={rx}\n        ry={ry}\n        initial={{\n          scale: 0,\n          opacity: 0,\n          x: newX,\n          y: newY\n        }}\n        animate={{\n          x: newX,\n          y: newY,\n          scale: (isDragging || active || isHovered) && !isDisabled ? 1.5 : 1,\n          opacity: 1\n        }}\n      />\n      {children && <Fragment>{typeof children === 'function' ? (children as PortChildrenAsFunction)(portChildProps) : children}</Fragment>}\n    </g>\n  );\n});\n","import React, { FC } from 'react';\nimport classNames from 'classnames';\nimport css from './Label.module.css';\n\nexport interface LabelProps {\n  x: number;\n  y: number;\n  height: number;\n  width: number;\n  text: string;\n  style?: any;\n  className?: string;\n  originalText?: string;\n}\n\nexport const Label: FC<Partial<LabelProps>> = ({ text, x, y, style, className, originalText }) => {\n  const isString = typeof originalText === 'string';\n  return (\n    <>\n      {isString && <title>{originalText}</title>}\n      <g transform={`translate(${x}, ${y})`}>\n        <text className={classNames(css.text, className)} style={style}>\n          {text}\n        </text>\n      </g>\n    </>\n  );\n};\n","import React, { FC } from 'react';\nimport classNames from 'classnames';\nimport { motion } from 'motion/react';\nimport css from './Remove.module.css';\n\nexport interface RemoveProps {\n  x: number;\n  y: number;\n  hidden?: boolean;\n  size?: number;\n  className?: string;\n  onEnter?: (event: React.MouseEvent<SVGGElement, MouseEvent>) => void;\n  onLeave?: (event: React.MouseEvent<SVGGElement, MouseEvent>) => void;\n  onClick?: (event: React.MouseEvent<SVGGElement, MouseEvent>) => void;\n}\n\nexport const Remove: FC<Partial<RemoveProps>> = ({ size = 15, className, hidden, x, y, onClick = () => undefined, onEnter = () => undefined, onLeave = () => undefined }) => {\n  if (hidden) {\n    return null;\n  }\n\n  const half = size / 2;\n  const translateX = x - half;\n  const translateY = y - half;\n\n  return (\n    <motion.g className={classNames(className, css.container)} initial={{ scale: 0, opacity: 0, translateX, translateY }} animate={{ scale: 1, opacity: 1, translateX, translateY }} whileHover={{ scale: 1.2 }} whileTap={{ scale: 0.8 }}>\n      <rect\n        height={size * 1.5}\n        width={size * 1.5}\n        className={css.drop}\n        onMouseEnter={onEnter}\n        onMouseLeave={onLeave}\n        onClick={(event) => {\n          event.preventDefault();\n          event.stopPropagation();\n          onClick(event);\n        }}\n      />\n      <rect height={size} width={size} className={css.rect} />\n      <line x1=\"2\" y1={size - 2} x2={size - 2} y2=\"2\" className={css.deleteX} strokeWidth=\"1\" />\n      <line x1=\"2\" y1=\"2\" x2={size - 2} y2={size - 2} className={css.deleteX} strokeWidth=\"1\" />\n    </motion.g>\n  );\n};\n","export interface PointCoords {\n  x: number;\n  y: number;\n}\n\nexport interface CenterCoords {\n  angle: number;\n  x: number;\n  y: number;\n}\n\n/**\n * Center helper.\n * Ref: https://github.com/wbkd/react-flow/blob/main/src/components/Edges/utils.ts#L18\n */\nfunction getBezierCenter({\n  sourceX,\n  sourceY,\n  targetX,\n  targetY\n}): [number, number, number, number] {\n  const xOffset = Math.abs(targetX - sourceX) / 2;\n  const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;\n\n  const yOffset = Math.abs(targetY - sourceY) / 2;\n  const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;\n\n  return [centerX, centerY, xOffset, yOffset];\n}\n\n/**\n * Path helper utils.\n * Ref: https://github.com/wbkd/react-flow/blob/main/src/components/Edges/BezierEdge.tsx#L19\n */\nexport function getBezierPath({\n  sourceX,\n  sourceY,\n  sourcePosition = 'bottom',\n  targetX,\n  targetY,\n  targetPosition = 'top'\n}): string {\n  const leftAndRight = ['left', 'right'];\n  const [centerX, centerY] = getBezierCenter({\n    sourceX,\n    sourceY,\n    targetX,\n    targetY\n  });\n\n  let path = `M${sourceX},${sourceY} C${sourceX},${centerY} ${targetX},${centerY} ${targetX},${targetY}`;\n\n  if (\n    leftAndRight.includes(sourcePosition) &&\n    leftAndRight.includes(targetPosition)\n  ) {\n    path = `M${sourceX},${sourceY} C${centerX},${sourceY} ${centerX},${targetY} ${targetX},${targetY}`;\n  } else if (leftAndRight.includes(targetPosition)) {\n    path = `M${sourceX},${sourceY} C${sourceX},${targetY} ${sourceX},${targetY} ${targetX},${targetY}`;\n  } else if (leftAndRight.includes(sourcePosition)) {\n    path = `M${sourceX},${sourceY} C${targetX},${sourceY} ${targetX},${sourceY} ${targetX},${targetY}`;\n  }\n\n  return path;\n}\n\n/**\n * Calculate actual center for a path element.\n */\nfunction getCenter(pathElm: SVGPathElement) {\n  const pLength = pathElm.getTotalLength();\n  const pieceSize = pLength / 2;\n  const { x, y } = pathElm.getPointAtLength(pieceSize);\n  const angle = (Math.atan2(x, y) * 180) / Math.PI;\n  return { x, y, angle };\n}\n\n/**\n * Get the angle for the path.\n */\nfunction getAngle(source: PointCoords, target: PointCoords) {\n  const dx = source.x - target.x;\n  const dy = source.y - target.y;\n\n  let theta = Math.atan2(-dy, -dx);\n  theta *= 180 / Math.PI;\n  if (theta < 0) {\n    theta += 360;\n  }\n\n  return theta;\n}\n\n/**\n * Get the center for the path element.\n */\nexport function getPathCenter(\n  pathElm: SVGPathElement,\n  firstPoint: PointCoords,\n  lastPoint: PointCoords\n): CenterCoords {\n  if (!pathElm) {\n    return null;\n  }\n\n  const angle = getAngle(firstPoint, lastPoint);\n  const point = getCenter(pathElm);\n  return {\n    ...point,\n    angle\n  };\n}\n","import React, { FC } from 'react';\nimport classNames from 'classnames';\nimport { motion } from 'motion/react';\nimport css from './Add.module.css';\n\nexport interface AddProps {\n  x: number;\n  y: number;\n  size?: number;\n  className?: string;\n  hidden?: boolean;\n  onEnter?: (event: React.MouseEvent<SVGGElement, MouseEvent>) => void;\n  onLeave?: (event: React.MouseEvent<SVGGElement, MouseEvent>) => void;\n  onClick?: (event: React.MouseEvent<SVGGElement, MouseEvent>) => void;\n}\n\nexport const Add: FC<Partial<AddProps>> = ({ x, y, className, size = 15, hidden = true, onEnter = () => undefined, onLeave = () => undefined, onClick = () => undefined }) => {\n  if (hidden) {\n    return null;\n  }\n\n  const half = size / 2;\n  const translateX = x - half;\n  const translateY = y - half;\n\n  return (\n    <motion.g className={classNames(className, css.container)} initial={{ scale: 0, opacity: 0, translateX, translateY }} animate={{ scale: 1, opacity: 1, translateX, translateY }} whileHover={{ scale: 1.2 }} whileTap={{ scale: 0.8 }}>\n      <rect\n        height={size * 2}\n        width={size * 2}\n        className={css.drop}\n        onClick={(event) => {\n          event.preventDefault();\n          event.stopPropagation();\n          onClick(event);\n        }}\n        onMouseEnter={onEnter}\n        onMouseLeave={onLeave}\n      />\n      <rect height={size} width={size} className={css.rect} />\n      <line x1=\"2\" x2={size - 2} y1={half} y2={half} className={css.plus} strokeWidth=\"1\" />\n      <line x1={half} x2={half} y1=\"2\" y2={size - 2} className={css.plus} strokeWidth=\"1\" />\n    </motion.g>\n  );\n};\n","import React, { FC, Fragment, MutableRefObject, ReactElement, ReactNode, useEffect, useMemo, useRef, useState } from 'react';\nimport { EdgeData } from '../../types';\nimport { Label, LabelProps } from '../Label';\nimport { CloneElement } from 'reablocks';\nimport classNames from 'classnames';\nimport { CenterCoords, getBezierPath, getPathCenter } from './utils';\nimport { curveBundle, line } from 'd3-shape';\nimport { Remove, RemoveProps } from '../Remove';\nimport { Add, AddProps } from '../Add';\nimport { useCanvas } from '../../utils/CanvasProvider';\nimport css from './Edge.module.css';\n\nexport interface EdgeSections {\n  id?: string;\n  startPoint?: {\n    x: number;\n    y: number;\n  };\n  endPoint?: {\n    x: number;\n    y: number;\n  };\n  bendPoints?: {\n    x: number;\n    y: number;\n  };\n}\n\nexport interface EdgeChildProps {\n  edge: EdgeData;\n  pathRef: MutableRefObject<SVGPathElement> | null;\n  center: CenterCoords | null;\n}\n\nexport type EdgeChildrenAsFunction = (edgeChildProps: EdgeChildProps) => ReactNode;\n\nexport interface EdgeProps {\n  id: string;\n  disabled?: boolean;\n  removable?: boolean;\n  selectable?: boolean;\n  upsertable?: boolean;\n  source: string;\n  sourcePort: string;\n  target: string;\n  targetPort: string;\n  properties?: EdgeData;\n  style?: any;\n  children?: ReactNode | EdgeChildrenAsFunction;\n  sections: EdgeSections[];\n  interpolation: 'linear' | 'curved' | Function;\n  labels?: LabelProps[];\n  className?: string;\n  containerClassName?: string;\n\n  add: ReactElement<AddProps, typeof Add>;\n  label: ReactElement<LabelProps, typeof Label>;\n  remove: ReactElement<RemoveProps, typeof Remove>;\n\n  onClick?: (event: React.MouseEvent<SVGGElement, MouseEvent>, data: EdgeData) => void;\n  onKeyDown?: (event: React.KeyboardEvent<SVGGElement>, data: EdgeData) => void;\n  onEnter?: (event: React.MouseEvent<SVGGElement, MouseEvent>, node: EdgeData) => void;\n  onLeave?: (event: React.MouseEvent<SVGGElement, MouseEvent>, node: EdgeData) => void;\n  onRemove?: (event: React.MouseEvent<SVGGElement, MouseEvent>, edge: EdgeData) => void;\n  onAdd?: (event: React.MouseEvent<SVGGElement, MouseEvent>, edge: EdgeData) => void;\n}\n\nexport const Edge: FC<Partial<EdgeProps>> = ({ sections, interpolation = 'curved', properties, labels, className, containerClassName, disabled, removable = true, selectable = true, upsertable = true, style, children, add = <Add />, remove = <Remove />, label = <Label />, onClick = () => undefined, onKeyDown = () => undefined, onEnter = () => undefined, onLeave = () => undefined, onRemove = () => undefined, onAdd = () => undefined }) => {\n  const pathRef = useRef<SVGPathElement | null>(null);\n  const [deleteHovered, setDeleteHovered] = useState<boolean>(false);\n  const [center, setCenter] = useState<CenterCoords | null>(null);\n  const { selections, readonly } = useCanvas();\n  const isActive: boolean = selections?.length ? selections.includes(properties?.id) : false;\n  const isDisabled = disabled || properties?.disabled;\n  const canSelect = selectable && !properties?.selectionDisabled;\n\n  // The \"d\" attribute defines a path to be drawn. See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d\n  const d = useMemo(() => {\n    if (!sections?.length) {\n      return null;\n    }\n\n    // Handle bend points that elk gives\n    // us separately from drag points\n    if (sections[0].bendPoints) {\n      const points: any[] = sections ? [sections[0].startPoint, ...(sections[0].bendPoints || ([] as any)), sections[0].endPoint] : [];\n\n      let pathFn: any = line()\n        .x((d: any) => d.x)\n        .y((d: any) => d.y);\n      if (interpolation !== 'linear') {\n        pathFn = interpolation === 'curved' ? pathFn.curve(curveBundle.beta(1)) : interpolation;\n      }\n      return pathFn(points);\n    } else {\n      return getBezierPath({\n        sourceX: sections[0].startPoint.x,\n        sourceY: sections[0].startPoint.y,\n        targetX: sections[0].endPoint.x,\n        targetY: sections[0].endPoint.y\n      });\n    }\n  }, [interpolation, sections]);\n\n  useEffect(() => {\n    if (sections?.length > 0) {\n      setCenter(getPathCenter(pathRef.current, sections[0].startPoint, sections[0].endPoint));\n    }\n  }, [sections]);\n\n  const edgeChildProps: EdgeChildProps = {\n    edge: properties,\n    center,\n    pathRef\n  };\n\n  return (\n    <g\n      className={classNames(css.edge, containerClassName, {\n        [css.disabled]: isDisabled,\n        [css.selectionDisabled]: !canSelect\n      })}\n    >\n      <path\n        ref={pathRef}\n        style={style}\n        className={classNames(css.path, properties?.className, className, {\n          [css.active]: isActive,\n          [css.deleteHovered]: deleteHovered\n        })}\n        d={d}\n        markerEnd=\"url(#end-arrow)\"\n      />\n      <path\n        className={css.clicker}\n        d={d}\n        tabIndex={-1}\n        onClick={(event) => {\n          event.preventDefault();\n          event.stopPropagation();\n          if (!isDisabled && canSelect) {\n            onClick(event, properties);\n          }\n        }}\n        onKeyDown={(event) => {\n          event.preventDefault();\n          event.stopPropagation();\n          if (!isDisabled) {\n            onKeyDown(event, properties);\n          }\n        }}\n        onMouseEnter={(event) => {\n          event.stopPropagation();\n          if (!isDisabled) {\n            onEnter(event, properties);\n          }\n        }}\n        onMouseLeave={(event) => {\n          event.stopPropagation();\n          if (!isDisabled) {\n            onLeave(event, properties);\n          }\n        }}\n      />\n      {children && <Fragment>{typeof children === 'function' ? (children as EdgeChildrenAsFunction)(edgeChildProps) : children}</Fragment>}\n      {labels?.length > 0 && labels.map((l, index) => <CloneElement<LabelProps> element={label} key={index} edgeChildProps={edgeChildProps} {...(l as LabelProps)} />)}\n      {!isDisabled && center && !readonly && remove && removable && (\n        <CloneElement<RemoveProps>\n          element={remove}\n          {...center}\n          hidden={remove.props.hidden !== undefined ? remove.props.hidden : !isActive}\n          onClick={(event: React.MouseEvent<SVGGElement, MouseEvent>) => {\n            event.preventDefault();\n            event.stopPropagation();\n            onRemove(event, properties);\n            setDeleteHovered(false);\n          }}\n          onEnter={() => setDeleteHovered(true)}\n          onLeave={() => setDeleteHovered(false)}\n        />\n      )}\n      {!isDisabled && center && !readonly && add && upsertable && (\n        <CloneElement<AddProps>\n          element={add}\n          {...center}\n          onClick={(event) => {\n            event.preventDefault();\n            event.stopPropagation();\n            onAdd(event, properties);\n          }}\n        />\n      )}\n    </g>\n  );\n};\n","import React, { FC, Fragment, ReactElement, ReactNode, useCallback, useEffect, useRef, useState } from 'react';\nimport { motion, useAnimation } from 'motion/react';\nimport { Port, PortProps } from '../Port';\nimport { Label, LabelProps } from '../Label';\nimport { EdgeData, NodeData, PortData } from '../../types';\nimport { CloneElement } from 'reablocks';\nimport { Icon, IconProps } from '../Icon';\nimport classNames from 'classnames';\nimport { Remove, RemoveProps } from '../Remove';\nimport { NodeDragEvents, DragEvent, useNodeDrag, Position } from '../../utils/useNodeDrag';\nimport { Edge, EdgeProps } from '../Edge';\nimport { useCanvas } from '../../utils/CanvasProvider';\nimport { checkNodeLinkable } from '../../utils/helpers';\nimport css from './Node.module.css';\n\nexport interface NodeChildProps {\n  height: number;\n  width: number;\n  x: number;\n  y: number;\n  node: NodeData;\n  nodes?: NodeData[];\n  edges?: EdgeData[];\n}\n\nexport type NodeDragType = 'node' | 'port' | 'multiportOnly' | 'all';\n\nexport type NodeChildrenAsFunction = (nodeChildProps: NodeChildProps) => ReactNode;\n\nexport interface NodeProps<T = any> extends NodeDragEvents<NodeData<T>, PortData> {\n  id: string;\n  height: number;\n  width: number;\n  x: number;\n  y: number;\n  rx: number;\n  ry: number;\n  offsetX?: number;\n  offsetY?: number;\n  disabled?: boolean;\n  ports?: PortProps[];\n  labels?: LabelProps[];\n  properties: NodeData<T>;\n  className?: string;\n  style?: any;\n  children?: ReactNode | NodeChildrenAsFunction;\n  parent?: string;\n  animated?: boolean;\n  draggable?: boolean;\n  linkable?: boolean;\n  selectable?: boolean;\n  removable?: boolean;\n  dragType?: NodeDragType;\n  dragCursor?: string;\n\n  nodes?: NodeData[];\n  edges?: EdgeData[];\n\n  onRemove?: (event: React.MouseEvent<SVGGElement, MouseEvent>, node: NodeData) => void;\n\n  onClick?: (event: React.MouseEvent<SVGGElement, MouseEvent>, data: NodeData) => void;\n\n  onKeyDown?: (event: React.KeyboardEvent<SVGGElement>, data: NodeData) => void;\n\n  onEnter?: (event: React.MouseEvent<SVGGElement, MouseEvent>, node: NodeData) => void;\n\n  onLeave?: (event: React.MouseEvent<SVGGElement, MouseEvent>, node: NodeData) => void;\n\n  childNode?: ReactElement<NodeProps, typeof Node> | ((node: NodeProps) => ReactElement<NodeProps, typeof Node>);\n\n  childEdge?: ReactElement<EdgeProps, typeof Edge> | ((edge: EdgeProps) => ReactElement<NodeProps, typeof Edge>);\n\n  remove: ReactElement<RemoveProps, typeof Remove>;\n  icon: ReactElement<IconProps, typeof Icon>;\n  label: ReactElement<LabelProps, typeof Label>;\n  port: ReactElement<PortProps, typeof Port>;\n}\n\nexport const Node: FC<Partial<NodeProps>> = ({ id, x, y, ports, labels, height, width, properties, animated, className, rx = 2, ry = 2, offsetX = 0, offsetY = 0, icon, disabled, style, children, nodes, edges, draggable = true, linkable = true, selectable = true, removable = true, dragType = 'multiportOnly', dragCursor = 'crosshair', childEdge = <Edge />, childNode = <Node />, remove = <Remove />, port = <Port />, label = <Label />, onRemove, onDrag, onDragStart, onDragEnd, onClick, onKeyDown, onEnter, onLeave }) => {\n  const nodeRef = useRef<SVGRectElement | null>(null);\n  const controls = useAnimation();\n  const { canLinkNode, enteredNode, selections, readonly, ...canvas } = useCanvas();\n  const [deleteHovered, setDeleteHovered] = useState<boolean>(false);\n  const [dragging, setDragging] = useState<boolean>(false);\n  const [isLinkable, setIsLinkable] = useState<boolean>(true);\n  const isActive = selections?.length ? selections.includes(properties.id) : null;\n  const isNodeDrag = id.includes('node-drag');\n  const newX = x + offsetX;\n  const newY = y + offsetY;\n  const isMultiPort = dragType === 'multiportOnly' && ports?.filter((p) => !p.properties?.hidden).length > 1;\n  const isDisabled = disabled || properties?.disabled;\n  const canDrag = ['port', 'multiportOnly'].includes(dragType) ? linkable : draggable;\n  const canSelect = selectable && !properties?.selectionDisabled;\n\n  const getDragType = useCallback(\n    (hasPort: boolean) => {\n      let activeDragType: NodeDragType = null;\n      if (!hasPort) {\n        if (dragType === 'all' || dragType === 'node') {\n          activeDragType = 'node';\n        } else if (!isMultiPort) {\n          activeDragType = 'port';\n        }\n      } else {\n        if (dragType === 'all' || dragType === 'port' || isMultiPort) {\n          activeDragType = 'port';\n        }\n      }\n      return activeDragType;\n    },\n    [dragType, isMultiPort]\n  );\n\n  const setDragCursor = useCallback((dragType: NodeDragType | null) => {\n    if (dragType) {\n      document.body.classList.add('dragging');\n      document.body.style.cursor = dragType === 'node' ? 'grab' : 'crosshair';\n    } else {\n      document.body.classList.remove('dragging');\n      document.body.style.cursor = 'auto';\n    }\n  }, []);\n\n  const bind = useNodeDrag({\n    x: newX,\n    y: newY,\n    height,\n    width,\n    disabled: isDisabled || isMultiPort || readonly || !canDrag || dragType === 'port',\n    node: properties,\n    onDrag: (...props) => {\n      if (!isDisabled && canDrag) {\n        canvas.onDrag(...props);\n        onDrag?.(...props);\n      }\n    },\n    onDragStart: (event, coords, node, port) => {\n      if (!isDisabled && canDrag) {\n        // @ts-ignore\n        event.dragType = getDragType(false);\n        // @ts-ignore\n        setDragCursor(event.dragType);\n\n        canvas.onDragStart(event, coords, node, port);\n        onDragStart?.(event, coords, node, port);\n        setDragging(true);\n      }\n    },\n    onDragEnd: (event, coords, node, port) => {\n      if (!isDisabled && canDrag) {\n        // @ts-ignore\n        event.dragType = getDragType(false);\n        // @ts-ignore\n        event.srcElement = nodeRef.current;\n\n        canvas.onDragEnd(event, coords, node, port);\n        onDragEnd?.(event, coords, node, port);\n        setDragging(false);\n        setDragCursor(null);\n      }\n    }\n  });\n\n  useEffect(() => {\n    if (enteredNode?.id === properties.id) {\n      setIsLinkable(checkNodeLinkable(properties, enteredNode, canLinkNode));\n    }\n\n    return () => setIsLinkable(true);\n  }, [canLinkNode, enteredNode, properties]);\n\n  useEffect(() => {\n    controls.set({\n      opacity: 1,\n      translateX: x,\n      translateY: y\n    });\n  }, [controls, x, y]);\n\n  const nodeChildProps: NodeChildProps = {\n    height,\n    width,\n    x,\n    y,\n    node: properties,\n    nodes,\n    edges\n  };\n\n  const onClickCallback = useCallback(\n    (event) => {\n      event.preventDefault();\n      event.stopPropagation();\n      if (!isDisabled && canSelect) {\n        onClick?.(event, properties);\n      }\n    },\n    [canSelect, isDisabled, onClick, properties]\n  );\n\n  const onKeyDownCallback = useCallback(\n    (event) => {\n      event.preventDefault();\n      if (!isDisabled) {\n        onKeyDown?.(event, properties);\n      }\n    },\n    [isDisabled, onKeyDown, properties]\n  );\n\n  const onTouchStartCallback = useCallback((event) => {\n    event.preventDefault();\n    event.stopPropagation();\n  }, []);\n\n  const onMouseEnterCallback = useCallback(\n    (event) => {\n      event.stopPropagation();\n      canvas.onEnter(event, properties);\n      if (!isDisabled) {\n        onEnter?.(event, properties);\n      }\n    },\n    [canvas, isDisabled, onEnter, properties]\n  );\n\n  const onMouseLeaveCallback = useCallback(\n    (event) => {\n      event.stopPropagation();\n      canvas.onLeave(event, properties);\n      if (!isDisabled) {\n        onLeave?.(event, properties);\n      }\n    },\n    [canvas, isDisabled, onLeave, properties]\n  );\n\n  const onDragStartCallback = useCallback(\n    (event: DragEvent, initial: Position, data: PortData) => {\n      if (!isDisabled && linkable) {\n        // @ts-ignore\n        event.dragType = getDragType(true);\n        // @ts-ignore\n        setDragCursor(event.dragType);\n\n        canvas.onDragStart(event, initial, properties, data);\n        onDragStart?.(event, initial, properties, data);\n        setDragging(true);\n      }\n    },\n    [canvas, getDragType, isDisabled, linkable, onDragStart, properties, setDragCursor]\n  );\n\n  const onDragCallback = useCallback(\n    (event: DragEvent, initial: Position, data: PortData) => {\n      if (!isDisabled && linkable) {\n        canvas.onDrag(event, initial, properties, data);\n        onDrag?.(event, initial, properties, data);\n      }\n    },\n    [canvas, isDisabled, linkable, onDrag, properties]\n  );\n\n  const onDragEndCallback = useCallback(\n    (event: DragEvent, initial: Position, data: PortData) => {\n      if (!isDisabled && linkable) {\n        // @ts-ignore\n        event.dragType = getDragType(true);\n        setDragCursor(null);\n\n        canvas.onDragEnd(event, initial, properties, data);\n        onDragEnd?.(event, initial, properties, data);\n        setDragging(false);\n      }\n    },\n    [canvas, getDragType, isDisabled, linkable, onDragEnd, properties, setDragCursor]\n  );\n\n  return (\n    <motion.g\n      id={id}\n      initial={{\n        cursor: 'initial',\n        opacity: 0,\n        translateX: x,\n        translateY: y\n      }}\n      animate={controls}\n    >\n      <motion.rect\n        {...bind()}\n        ref={nodeRef}\n        tabIndex={-1}\n        onKeyDown={onKeyDownCallback}\n        onClick={onClickCallback}\n        onTouchStart={onTouchStartCallback}\n        onMouseEnter={onMouseEnterCallback}\n        onMouseLeave={onMouseLeaveCallback}\n        className={classNames(css.rect, className, properties?.className, {\n          [css.active]: isActive,\n          [css.disabled]: isDisabled,\n          [css.unlinkable]: isLinkable === false && !isNodeDrag,\n          [css.dragging]: dragging,\n          [css.children]: nodes?.length > 0,\n          [css.deleteHovered]: deleteHovered,\n          [css.selectionDisabled]: !canSelect\n        })}\n        style={style}\n        height={height}\n        width={width}\n        rx={rx}\n        ry={ry}\n        initial={{\n          opacity: 0\n        }}\n        animate={{\n          opacity: 1,\n          transition: !animated ? { type: false, duration: 0 } : {}\n        }}\n      />\n      {children && <Fragment>{typeof children === 'function' ? (children as NodeChildrenAsFunction)(nodeChildProps) : children}</Fragment>}\n      {icon && properties.icon && <CloneElement<IconProps> element={icon} {...properties.icon} />}\n      {label && labels?.length > 0 && labels.map((l, index) => <CloneElement<LabelProps> element={label} key={index} {...(l as LabelProps)} />)}\n      {port && ports?.length > 0 && ports.map((p) => <CloneElement<PortProps> element={port} key={p.id} active={!isMultiPort && dragging} disabled={isDisabled || !linkable} offsetX={newX} offsetY={newY} onDragStart={onDragStartCallback} onDrag={onDragCallback} onDragEnd={onDragEndCallback} {...(p as PortProps)} id={`${id}-port-${p.id}`} />)}\n      {!isDisabled && isActive && !readonly && remove && removable && (\n        <CloneElement<RemoveProps>\n          element={remove}\n          y={height / 2}\n          x={width}\n          onClick={(event: React.MouseEvent<SVGGElement, MouseEvent>) => {\n            event.preventDefault();\n            event.stopPropagation();\n            onRemove?.(event, properties);\n            setDeleteHovered(false);\n          }}\n          onEnter={() => setDeleteHovered(true)}\n          onLeave={() => setDeleteHovered(false)}\n        />\n      )}\n      <g>\n        {edges?.length > 0 &&\n          edges.map((e: any) => {\n            const element = typeof childEdge === 'function' ? childEdge(e) : childEdge;\n            return (\n              <CloneElement<EdgeProps>\n                key={e.id}\n                element={element}\n                id={`${id}-edge-${e.id}`}\n                disabled={isDisabled}\n                {...e}\n                properties={{\n                  ...e.properties,\n                  ...(e.data ? { data: e.data } : {})\n                }}\n              />\n            );\n          })}\n        {nodes?.length > 0 &&\n          nodes.map(({ children, ...n }: any) => {\n            const element = typeof childNode === 'function' ? childNode(n) : childNode;\n            const elementDisabled = element.props?.disabled != null ? element.props.disabled : disabled;\n            const elementAnimated = element.props?.animated != null ? element.props.animated : animated;\n            const elementDraggable = element.props?.draggable != null ? element.props.draggable : draggable;\n            const elementLinkable = element.props?.linkable != null ? element.props.linkable : linkable;\n            const elementSelectable = element.props?.selectable != null ? element.props.selectable : selectable;\n            const elementRemovable = element.props?.removable != null ? element.props.removable : removable;\n            return <CloneElement<NodeProps> key={n.id} element={element} id={`${id}-node-${n.id}`} disabled={elementDisabled} nodes={children} offsetX={newX} offsetY={newY} animated={elementAnimated} children={element.props.children} childNode={childNode} dragCursor={dragCursor} dragType={dragType} childEdge={childEdge} draggable={elementDraggable} linkable={elementLinkable} selectable={elementSelectable} removable={elementRemovable} onDragStart={onDragStart} onDrag={onDrag} onDragEnd={onDragEnd} onClick={onClick} onEnter={onEnter} onLeave={onLeave} onKeyDown={onKeyDown} onRemove={onRemove} {...n} />;\n          })}\n      </g>\n    </motion.g>\n  );\n};\n","import React, { FC } from 'react';\nimport classNames from 'classnames';\nimport css from './Arrow.module.css';\n\nexport interface ArrowProps {\n  size?: number;\n  x?: number;\n  y?: number;\n  angle?: number;\n  className?: string;\n  style?: any;\n}\n\nexport const Arrow: FC<ArrowProps> = ({\n  size = 8,\n  y = 0,\n  x = 0,\n  angle = 0,\n  className,\n  style\n}) => (\n  <path\n    style={style}\n    transform={`translate(${x}, ${y}) rotate(${angle})`}\n    className={classNames(css.arrow, className)}\n    d={`M0,-${size / 2}L${size},0L0,${size / 2}`}\n  />\n);\n","import React, { FC } from 'react';\nimport { Arrow } from './Arrow';\n\nexport interface MarkerArrowProps {\n  size?: number;\n  style?: any;\n  className?: string;\n}\n\nexport const MarkerArrow: FC<Partial<MarkerArrowProps>> = ({\n  size = 8,\n  className,\n  style\n}) => (\n  <marker\n    id=\"end-arrow\"\n    key=\"end-arrow\"\n    viewBox={`0 -${size / 2} ${size} ${size}`}\n    refX={`${size}`}\n    markerWidth={`${size}`}\n    markerHeight={`${size}`}\n    orient=\"auto\"\n  >\n    <Arrow size={size} style={style} className={className} />\n  </marker>\n);\n","import React, { FC, ReactElement, Ref, useImperativeHandle, forwardRef, useLayoutEffect, useRef, Fragment, useMemo, useState, useCallback, useEffect } from 'react';\nimport { useId, CloneElement } from 'reablocks';\nimport { useGesture } from 'react-use-gesture';\nimport { Node, NodeDragType, NodeProps } from './symbols/Node';\nimport { Edge, EdgeProps } from './symbols/Edge';\nimport { ElkRoot, CanvasDirection, LayoutResult, ElkCanvasLayoutOptions } from './layout';\nimport { MarkerArrow, MarkerArrowProps } from './symbols/Arrow';\nimport { CanvasPosition, EdgeData, NodeData, PortData } from './types';\nimport classNames from 'classnames';\nimport { CanvasProvider, useCanvas } from './utils/CanvasProvider';\nimport { getDragNodeData } from './utils/helpers';\nimport { motion } from 'motion/react';\nimport { ZoomResult } from './utils/useZoom';\nimport css from './Canvas.module.css';\n\nexport interface CanvasContainerProps extends CanvasProps {\n  /**\n   * Nodes to render on the canvas.\n   */\n  nodes?: NodeData[];\n\n  /**\n   * Edges to render on the canvas.\n   */\n  edges?: EdgeData[];\n\n  /**\n   * Key of node/edge ids for selection.\n   */\n  selections?: string[];\n\n  /**\n   * Direction of the canvas layout.\n   */\n  direction?: CanvasDirection;\n\n  /**\n   * Whether the canvas is pannable or not.\n   */\n  pannable?: boolean;\n\n  /**\n   * Type of interaction to use for panning.\n   */\n  panType?: 'scroll' | 'drag';\n\n  /**\n   * Whether the canvas is zoomable or not.\n   */\n  zoomable?: boolean;\n\n  /**\n   * Where to position the canvas on load (if at all)\n   */\n  defaultPosition?: CanvasPosition;\n\n  /**\n   * Fit the canvas on load.\n   */\n  fit?: boolean;\n\n  /**\n   * Max height of the canvas scrollable area.\n   */\n  maxHeight?: number;\n\n  /**\n   * Max width of the canvas scrollable area.\n   */\n  maxWidth?: number;\n\n  /**\n   * Zoom factor.\n   */\n  zoom?: number;\n\n  /**\n   * Min zoom factor.\n   */\n  minZoom?: number;\n\n  /**\n   * Max zoom factor.\n   */\n  maxZoom?: number;\n\n  /**\n   * ELKJS Layout Options\n   */\n  layoutOptions?: ElkCanvasLayoutOptions;\n\n  /**\n   * Callback when a node is linked.\n   */\n  onNodeLink?: (event: any, fromNode: NodeData, toNode: NodeData, fromPort?: PortData) => void;\n\n  /**\n   * Callback to check if a node is linkable or not.\n   */\n  onNodeLinkCheck?: (event: any, fromNode: NodeData, toNode: NodeData, fromPort?: PortData) => undefined | boolean;\n\n  /**\n   * When the zoom changes.\n   */\n  onZoomChange?: (zoom: number) => void;\n\n  /**\n   * When the layout changes.\n   */\n  onLayoutChange?: (layout: ElkRoot) => void;\n}\n\nexport interface CanvasProps {\n  /**\n   * CSS classname for the container.\n   */\n  className?: string;\n\n  /**\n   * Disable all events or not.\n   */\n  disabled?: boolean;\n\n  /**\n   * Whether the nodes / edges are animated or not.\n   */\n  animated?: boolean;\n\n  /**\n   * Static height of the canvas.\n   */\n  height?: number;\n\n  /**\n   * Static width of the canvas.\n   */\n  width?: number;\n\n  /**\n   * Whether you can drag connections or not.\n   */\n  readonly?: boolean;\n\n  /**\n   * Element of the drag edge.\n   */\n  dragEdge?: ReactElement<EdgeProps, typeof Edge> | ((edge: EdgeProps) => ReactElement<EdgeProps, typeof Edge>) | null;\n\n  /**\n   * Element of the drag node.\n   */\n  dragNode?: ReactElement<NodeProps, typeof Node> | ((node: NodeProps) => ReactElement<NodeProps, typeof Node>) | null;\n\n  /**\n   * Arrow shown on the edges.\n   */\n  arrow?: ReactElement<MarkerArrowProps, typeof MarkerArrow> | null;\n\n  /**\n   * Node or node callback to return element.\n   */\n  node?: ReactElement<NodeProps, typeof Node> | ((node: NodeProps) => ReactElement<NodeProps, typeof Node>);\n\n  /**\n   * Edge or edge callback to return element.\n   */\n  edge?: ReactElement<EdgeProps, typeof Edge> | ((edge: EdgeProps) => ReactElement<NodeProps, typeof Edge>);\n\n  /**\n   * When the canvas had a mouse enter.\n   */\n  onMouseEnter?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;\n\n  /**\n   * When the canvas had a mouse leave.\n   */\n  onMouseLeave?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;\n\n  /**\n   * When the canvas was clicked.\n   */\n  onCanvasClick?: (event: React.MouseEvent<SVGGElement, MouseEvent>) => void;\n}\n\nexport type CanvasRef = LayoutResult & ZoomResult;\n\nconst InternalCanvas: FC<CanvasProps & { ref?: Ref<CanvasRef> }> = forwardRef(({ className, height = '100%', width = '100%', readonly, disabled = false, animated = true, arrow = <MarkerArrow />, node = <Node />, edge = <Edge />, dragNode = <Node />, dragEdge = <Edge />, onMouseEnter = () => undefined, onMouseLeave = () => undefined, onCanvasClick = () => undefined }, ref: Ref<CanvasRef>) => {\n  const id = useId();\n  const { pannable, dragCoords, dragNode: canvasDragNode, layout, containerRef, svgRef, canvasHeight, canvasWidth, xy, zoom, setZoom, observe, zoomIn, zoomOut, positionCanvas, fitCanvas, setScrollXY, panType, ...rest } = useCanvas();\n  const [dragType, setDragType] = useState<null | NodeDragType>(null);\n\n  useImperativeHandle(ref, () => ({\n    ...rest,\n    observe,\n    zoom,\n    xy,\n    layout,\n    canvasHeight,\n    containerRef,\n    canvasWidth,\n    svgRef,\n    positionCanvas,\n    setZoom,\n    zoomIn,\n    zoomOut,\n    fitCanvas,\n    setScrollXY\n  }));\n\n  const mount = useRef<boolean>(false);\n  const panStartScrollPosition = useRef<{ x: number; y: number }>({ x: 0, y: 0 });\n\n  const dragNodeData = useMemo(() => getDragNodeData(canvasDragNode, layout?.children), [canvasDragNode, layout?.children]);\n  const [dragNodeDataWithChildren, setDragNodeDataWithChildren] = useState<{\n    [key: string]: any;\n  }>(dragNodeData);\n  const dragNodeElement = useMemo(() => (typeof dragNode === 'function' ? dragNode(dragNodeData as NodeProps) : dragNode), [dragNode, dragNodeData]);\n  useLayoutEffect(() => {\n    if (!mount.current && layout !== null && xy[0] > 0 && xy[1] > 0) {\n      mount.current = true;\n    }\n  }, [layout, xy]);\n\n  useGesture(\n    {\n      onDrag: ({ movement: [mx, my] }) => {\n        // Update container scroll position during drag\n        if (containerRef.current && !canvasDragNode) {\n          containerRef.current.scrollLeft = panStartScrollPosition.current.x - mx;\n          containerRef.current.scrollTop = panStartScrollPosition.current.y - my;\n        }\n      },\n      onDragStart: () => {\n        // Store the initial scroll position of the container when drag starts\n        panStartScrollPosition.current = {\n          x: containerRef.current?.scrollLeft || 0,\n          y: containerRef.current?.scrollTop || 0\n        };\n      },\n      onWheel: ({ event, delta, last }) => {\n        !last && event.preventDefault();\n\n        const zoomFactor = delta[1] * -0.02;\n\n        if (delta[1] > 0) {\n          zoomOut(zoomFactor);\n        } else {\n          zoomIn(zoomFactor);\n        }\n      }\n    },\n    {\n      enabled: pannable && panType === 'drag',\n      eventOptions: { passive: false },\n      domTarget: containerRef\n    }\n  );\n\n  const onDragStart = useCallback((event) => {\n    setDragType(event.dragType);\n  }, []);\n\n  const createDragNodeChildren = useCallback(\n    (children: any) => {\n      if (!children || !Array.isArray(children)) {\n        return [];\n      }\n\n      return children.map(({ children, ...n }) => {\n        const element = typeof dragNode === 'function' ? dragNode(n as NodeProps) : dragNode;\n        return <CloneElement<NodeProps> key={`${id}-node-${n.id}-node-drag`} element={element} disabled children={element.props.children} animated={animated} nodes={children} childEdge={dragEdge} childNode={dragNode} {...n} onDragStart={onDragStart} id={`${id}-node-${n.id}-node-drag`} />;\n      });\n    },\n    // Passing in dragEdge (JSX) will cause the function to be recalculated constantly,\n    // triggering the below useEffect. Since dragEdge and dragNode are passed in props\n    // on Canvas, they are unlikely to change and can be ignored\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [animated, id]\n  );\n\n  useEffect(() => {\n    if (dragNodeData && Object.keys(dragNodeData).length > 0) {\n      const nodeCopy = { ...dragNodeData };\n      // Node children is expecting a list of React Elements, need to create a list of elements\n      nodeCopy.children = createDragNodeChildren(nodeCopy.children);\n      setDragNodeDataWithChildren(nodeCopy);\n    }\n  }, [createDragNodeChildren, dragNodeData, layout?.children]);\n\n  return (\n    <div\n      style={{ height, width }}\n      className={classNames(css.container, className, {\n        [css.pannable]: pannable,\n        [css.draggable]: panType === 'drag'\n      })}\n      ref={(el) => {\n        // Really not a fan of this API change...\n        // https://github.com/wellyshen/react-cool-dimensions#how-to-share-a-ref\n        observe(el);\n\n        // @ts-ignore\n        containerRef.current = el;\n      }}\n      onMouseEnter={onMouseEnter}\n      onMouseLeave={onMouseLeave}\n    >\n      <svg xmlns=\"http://www.w3.org/2000/svg\" id={id} ref={svgRef} height={canvasHeight} width={canvasWidth} onClick={onCanvasClick}>\n        {arrow !== null && (\n          <defs>\n            <CloneElement<MarkerArrowProps> element={arrow} {...(arrow as MarkerArrowProps)} />\n          </defs>\n        )}\n        <motion.g\n          initial={{\n            opacity: 0,\n            scale: 0,\n            transition: {\n              translateX: false,\n              translateY: false\n            }\n          }}\n          animate={{\n            opacity: 1,\n            translateX: xy[0],\n            translateY: xy[1],\n            scale: zoom,\n            transition: animated\n              ? {\n                velocity: 100,\n                translateX: { duration: mount.current ? 0.3 : 0 },\n                translateY: { duration: mount.current ? 0.3 : 0 },\n                opacity: { duration: 0.8 },\n                when: 'beforeChildren'\n              }\n              : {\n                type: false,\n                duration: 0,\n                when: 'beforeChildren'\n              }\n          }}\n        >\n          {layout?.children?.map(({ children, ...n }) => {\n            const element = typeof node === 'function' ? node(n) : node;\n            return <CloneElement<NodeProps> key={n.id} element={element} disabled={disabled} children={element.props.children} animated={animated} nodes={children} childEdge={edge} childNode={node} {...n} onDragStart={onDragStart} id={`${id}-node-${n.id}`} />;\n          })}\n          {layout?.edges?.map((e) => {\n            const element = typeof edge === 'function' ? edge(e) : edge;\n            return (\n              <CloneElement<EdgeProps>\n                key={e.id}\n                element={element}\n                disabled={disabled}\n                children={element.props.children}\n                {...e}\n                properties={{\n                  ...e.properties,\n                  ...(e.data ? { data: e.data } : {})\n                }}\n                id={`${id}-edge-${e.id}`}\n              />\n            );\n          })}\n          {dragCoords !== null && dragEdge && dragType === 'port' && !readonly && <CloneElement<EdgeProps> element={dragEdge} id={`${id}-edge-drag`} disabled sections={dragCoords} />}\n          {layout?.children?.map(({ children, ports, ...n }) => (\n            <Fragment key={n.id}>\n              {ports?.length > 0 && (\n                <motion.g\n                  key={n.id}\n                  initial={{\n                    translateX: n.x,\n                    translateY: n.y\n                  }}\n                  animate={{\n                    translateX: n.x,\n                    translateY: n.y\n                  }}\n                  transition={{ duration: 0 }}\n                >\n                  {ports.map((port, index) => (\n                    <use key={index} xlinkHref={`#${id}-node-${n.id}-port-${port.id}`} style={{ pointerEvents: 'none' }} />\n                  ))}\n                </motion.g>\n              )}\n            </Fragment>\n          ))}\n          {dragCoords !== null && dragNodeDataWithChildren && dragType === 'node' && !readonly && <CloneElement<NodeProps> {...dragNodeDataWithChildren} element={dragNodeElement} height={dragNodeDataWithChildren?.props?.height || dragNodeDataWithChildren?.height} width={dragNodeDataWithChildren?.props?.width || dragNodeDataWithChildren?.width} id={`${id}-node-drag`} animated={animated} className={css.dragNode} disabled x={dragCoords[0].endPoint.x} y={dragCoords[0].endPoint.y} />}\n        </motion.g>\n      </svg>\n    </div>\n  );\n});\n\nexport const Canvas: FC<CanvasContainerProps & { ref?: Ref<CanvasRef> }> = forwardRef(({ selections = [], readonly = false, fit = false, nodes = [], edges = [], maxHeight = 2000, maxWidth = 2000, direction = 'DOWN', pannable = true, panType = 'scroll', zoom = 1, defaultPosition = CanvasPosition.CENTER, zoomable = true, minZoom = -0.5, maxZoom = 1, onNodeLink = () => undefined, onNodeLinkCheck = () => undefined, onLayoutChange = () => undefined, onZoomChange = () => undefined, layoutOptions, ...rest }, ref: Ref<CanvasRef>) => (\n  <CanvasProvider layoutOptions={layoutOptions} nodes={nodes} edges={edges} zoom={zoom} defaultPosition={defaultPosition} minZoom={minZoom} maxZoom={maxZoom} fit={fit} maxHeight={maxHeight} maxWidth={maxWidth} direction={direction} pannable={pannable} panType={panType} zoomable={zoomable} readonly={readonly} onLayoutChange={onLayoutChange} selections={selections} onZoomChange={onZoomChange} onNodeLink={onNodeLink} onNodeLinkCheck={onNodeLinkCheck}>\n    <InternalCanvas ref={ref} {...rest} />\n  </CanvasProvider>\n));\n","import React, { FC } from 'react';\nimport classNames from 'classnames';\nimport css from './Icon.module.css';\n\nexport interface IconProps {\n  x: number;\n  y: number;\n  url: string;\n  height: number;\n  width: number;\n  style?: any;\n  className?: string;\n}\n\nexport const Icon: FC<Partial<IconProps>> = ({\n  x,\n  y,\n  url,\n  style,\n  className,\n  height = 40,\n  width = 40\n}) => (\n  <g\n    className={classNames(css.icon, className)}\n    transform={`translate(${x - width / 2}, ${y - height / 2})`}\n  >\n    <image style={style} xlinkHref={url} width={width} height={height} />\n  </g>\n);\n","import { EdgeData, NodeData, PortData } from '../types';\n\n/**\n * Helper function for upserting a node in a edge.\n */\nexport function upsertNode(\n  nodes: NodeData[],\n  edges: EdgeData[],\n  edge: EdgeData,\n  newNode: NodeData\n) {\n  const oldEdgeIndex = edges.findIndex((e) => e.id === edge.id);\n  const edgeBeforeNewNode = {\n    ...edge,\n    id: `${edge.from}-${newNode.id}`,\n    to: newNode.id\n  };\n  const edgeAfterNewNode = {\n    ...edge,\n    id: `${newNode.id}-${edge.to}`,\n    from: newNode.id\n  };\n\n  if (edge.fromPort && edge.toPort) {\n    edgeBeforeNewNode.fromPort = edge.fromPort;\n    edgeBeforeNewNode.toPort = `${newNode.id}-to`;\n\n    edgeAfterNewNode.fromPort = `${newNode.id}-from`;\n    edgeAfterNewNode.toPort = edge.toPort;\n  }\n\n  edges.splice(oldEdgeIndex, 1, edgeBeforeNewNode, edgeAfterNewNode);\n\n  return {\n    nodes: [...nodes, newNode],\n    edges: [...edges]\n  };\n}\n\n/**\n * Helper function for removing a node between edges and\n * linking the children.\n */\nexport function removeAndUpsertNodes(\n  nodes: NodeData[],\n  edges: EdgeData[],\n  removeNodes: NodeData | NodeData[],\n  onNodeLinkCheck?: (\n    newNodes: NodeData[],\n    newEdges: EdgeData[],\n    from: NodeData,\n    to: NodeData,\n    port?: PortData\n  ) => undefined | boolean\n) {\n  if (!Array.isArray(removeNodes)) {\n    removeNodes = [removeNodes];\n  }\n\n  const nodeIds = removeNodes.map((n) => n.id);\n  const newNodes = nodes.filter((n) => !nodeIds.includes(n.id));\n  const newEdges = edges.filter(\n    (e) => !nodeIds.includes(e.from) && !nodeIds.includes(e.to)\n  );\n\n  for (const nodeId of nodeIds) {\n    const sourceEdges = edges.filter((e) => e.to === nodeId);\n    const targetEdges = edges.filter((e) => e.from === nodeId);\n\n    for (const sourceEdge of sourceEdges) {\n      for (const targetEdge of targetEdges) {\n        const sourceNode = nodes.find((n) => n.id === sourceEdge.from);\n        const targetNode = nodes.find((n) => n.id === targetEdge.to);\n        if (sourceNode && targetNode) {\n          const canLink = onNodeLinkCheck?.(\n            newNodes,\n            newEdges,\n            sourceNode,\n            targetNode\n          );\n          if (canLink === undefined || canLink) {\n            newEdges.push({\n              id: `${sourceNode.id}-${targetNode.id}`,\n              from: sourceNode.id,\n              to: targetNode.id,\n              parent: sourceNode?.parent\n            });\n          }\n        }\n      }\n    }\n  }\n\n  return {\n    edges: newEdges,\n    nodes: newNodes\n  };\n}\n\n/**\n * Helper function to remove a node and its related edges.\n */\nexport function removeNode(\n  nodes: NodeData[],\n  edges: EdgeData[],\n  removeNodes: string | string[]\n) {\n  if (!Array.isArray(removeNodes)) {\n    removeNodes = [removeNodes];\n  }\n\n  const newNodes = [];\n  const newEdges = [];\n\n  for (const node of nodes) {\n    const has = removeNodes.some((n) => n === node.id);\n    if (!has) {\n      newNodes.push(node);\n    }\n  }\n\n  for (const edge of edges) {\n    const has = removeNodes.some((n) => n === edge.from || n === edge.to);\n    if (!has) {\n      newEdges.push(edge);\n    }\n  }\n\n  return {\n    nodes: newNodes,\n    edges: newEdges\n  };\n}\n\n/**\n * Helper function to remove a node's related edges.\n */\nexport function removeEdgesFromNode(nodeId: string, edges: EdgeData[]) {\n  return edges.filter((edge) => !(edge.to === nodeId || edge.from === nodeId));\n}\n\n/**\n * Remove edge(s)\n */\nexport function removeEdge(edges: EdgeData[], edge: EdgeData | EdgeData[]) {\n  const deletions: EdgeData[] = !Array.isArray(edge) ? [edge] : edge;\n  const edgeIds = deletions.map((e) => e.id);\n  return edges.filter((e) => !edgeIds.includes(e.id));\n}\n\n/**\n * Create an edge given 2 nodes.\n */\nexport function createEdgeFromNodes(fromNode: NodeData, toNode: NodeData) {\n  return {\n    id: `${fromNode.id}-${toNode.id}`,\n    from: fromNode.id,\n    to: toNode.id,\n    parent: toNode.parent\n  };\n}\n\n/**\n * Add a node and optional edge.\n */\nexport function addNodeAndEdge(\n  nodes: NodeData[],\n  edges: EdgeData[],\n  node: NodeData,\n  toNode?: NodeData\n) {\n  return {\n    nodes: [...nodes, node],\n    edges: [...edges, ...(toNode ? [createEdgeFromNodes(toNode, node)] : [])]\n  };\n}\n","import React, { useState } from 'react';\nimport { useHotkeys } from 'reakeys';\nimport { EdgeData, NodeData } from '../types';\nimport { removeNode } from './crudHelpers';\n\nexport type HotkeyTypes = 'selectAll' | 'deselect' | 'delete';\n\nexport interface SelectionProps {\n  /**\n   * Current selections.\n   *\n   * Contains both nodes and edges ids.\n   */\n  selections?: string[];\n\n  /**\n   * Node datas.\n   */\n  nodes?: NodeData[];\n\n  /**\n   * Edge datas.\n   */\n  edges?: EdgeData[];\n\n  /**\n   * Disabled or not.\n   */\n  disabled?: boolean;\n\n  /**\n   * Hotkey types\n   */\n  hotkeys?: HotkeyTypes[];\n\n  /**\n   * On selection change.\n   */\n  onSelection?: (newSelectedIds: string[]) => void;\n\n  /**\n   * On data change.\n   */\n  onDataChange?: (nodes: NodeData[], edges: EdgeData[]) => void;\n}\n\nexport interface SelectionResult {\n  /**\n   * Selections id array (of nodes and edges).\n   */\n  selections: string[];\n\n  /**\n   * Clear selections method.\n   */\n  clearSelections: (value?: string[]) => void;\n\n  /**\n   * A selection method.\n   */\n  addSelection: (value: string) => void;\n\n  /**\n   * Remove selection method.\n   */\n  removeSelection: (value: string) => void;\n\n  /**\n   * Toggle existing selection on/off method.\n   */\n  toggleSelection: (value: string) => void;\n\n  /**\n   * Set internal selections.\n   */\n  setSelections: (value: string[]) => void;\n\n  /**\n   * On click event pass through.\n   */\n  onClick?: (\n    event: React.MouseEvent<SVGGElement, MouseEvent>,\n    data: any\n  ) => void;\n\n  /**\n   * On canvas click event pass through.\n   */\n  onCanvasClick?: (event?: React.MouseEvent<SVGGElement, MouseEvent>) => void;\n\n  /**\n   * On keydown event pass through.\n   */\n  onKeyDown?: (event: React.KeyboardEvent<SVGGElement>) => void;\n}\n\nexport const useSelection = ({\n  selections = [],\n  nodes = [],\n  edges = [],\n  hotkeys = ['selectAll', 'deselect', 'delete'],\n  disabled,\n  onSelection,\n  onDataChange\n}: SelectionProps): SelectionResult => {\n  const [internalSelections, setInternalSelections] =\n    useState<string[]>(selections);\n  const [metaKeyDown, setMetaKeyDown] = useState<boolean>(false);\n\n  const addSelection = (item: string) => {\n    if (!disabled) {\n      const has = internalSelections.includes(item);\n      if (!has) {\n        const next = [...internalSelections, item];\n        onSelection?.(next);\n        setInternalSelections(next);\n      }\n    }\n  };\n\n  const removeSelection = (item: string) => {\n    if (!disabled) {\n      const has = internalSelections.includes(item);\n      if (has) {\n        const next = internalSelections.filter((i) => i !== item);\n        onSelection?.(next);\n        setInternalSelections(next);\n      }\n    }\n  };\n\n  const toggleSelection = (item: string) => {\n    const has = internalSelections.includes(item);\n    if (has) {\n      removeSelection(item);\n    } else {\n      addSelection(item);\n    }\n  };\n\n  const clearSelections = (next = []) => {\n    if (!disabled) {\n      setInternalSelections(next);\n      onSelection?.(next);\n    }\n  };\n\n  const onClick = (event, data) => {\n    event.preventDefault();\n    event.stopPropagation();\n\n    if (!metaKeyDown) {\n      clearSelections([data.id]);\n    } else {\n      toggleSelection(data.id);\n    }\n\n    setMetaKeyDown(false);\n  };\n\n  const onKeyDown = (event) => {\n    event.preventDefault();\n    setMetaKeyDown(event.metaKey || event.ctrlKey);\n  };\n\n  const onCanvasClick = () => {\n    clearSelections();\n    setMetaKeyDown(false);\n  };\n\n  useHotkeys([\n    {\n      name: 'Select All',\n      keys: 'mod+a',\n      disabled: !hotkeys.includes('selectAll'),\n      category: 'Canvas',\n      description: 'Select all nodes and edges',\n      callback: (event) => {\n        event.preventDefault();\n\n        if (!disabled) {\n          const next = nodes.map((n) => n.id);\n          onDataChange?.(nodes, edges);\n          onSelection?.(next);\n          setInternalSelections(next);\n        }\n      }\n    },\n    {\n      name: 'Delete Selections',\n      category: 'Canvas',\n      disabled: !hotkeys.includes('delete'),\n      description: 'Delete selected nodes and edges',\n      keys: 'backspace',\n      callback: (event) => {\n        if (!disabled) {\n          event.preventDefault();\n          const result = removeNode(nodes, edges, internalSelections);\n          onDataChange?.(result.nodes, result.edges);\n          onSelection?.([]);\n          setInternalSelections([]);\n        }\n      }\n    },\n    {\n      name: 'Deselect Selections',\n      category: 'Canvas',\n      disabled: !hotkeys.includes('deselect'),\n      description: 'Deselect selected nodes and edges',\n      keys: 'escape',\n      callback: (event) => {\n        if (!disabled) {\n          event.preventDefault();\n          onSelection?.([]);\n          setInternalSelections([]);\n        }\n      }\n    }\n  ]);\n\n  return {\n    onClick,\n    onKeyDown,\n    onCanvasClick,\n    selections: internalSelections,\n    clearSelections,\n    addSelection,\n    removeSelection,\n    toggleSelection,\n    setSelections: setInternalSelections\n  };\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useHotkeys } from 'reakeys';\nimport { EdgeData, NodeData } from '../types';\nimport Undoo from 'undoo';\n\nexport interface UndoRedoEvent {\n  /**\n   * Updated node datas.\n   */\n  nodes?: NodeData[];\n\n  /**\n   * Updated edge datas.\n   */\n  edges?: EdgeData[];\n\n  /**\n   * Type of change.\n   */\n  type: 'undo' | 'redo' | 'clear';\n\n  /**\n   * Whether you can undo now.\n   */\n  canUndo: boolean;\n\n  /**\n   * Whether you can redo now.\n   */\n  canRedo: boolean;\n}\n\nexport interface UndoProps {\n  /**\n   * Current node datas.\n   */\n  nodes: NodeData[];\n\n  /**\n   * Current edge datas.\n   */\n  edges: EdgeData[];\n\n  /**\n   * Max history count.\n   *\n   * @default 20\n   */\n  maxHistory?: number;\n\n  /**\n   * Disabled or not.\n   *\n   * @default false\n   */\n  disabled?: boolean;\n\n  /**\n   * On undo/redo event handler.\n   */\n  onUndoRedo: (state: UndoRedoEvent) => void;\n}\n\nexport interface UndoResult {\n  /**\n   * Can undo or not.\n   */\n  canUndo: boolean;\n\n  /**\n   * Can redo or not.\n   */\n  canRedo: boolean;\n\n  /**\n   * Count of existing changes.\n   */\n  count: () => number;\n\n  /**\n   * Clear state.\n   */\n  clear: (nodes: NodeData[], edges: EdgeData[]) => void;\n\n  /**\n   * Get history of state.\n   */\n  history: () => { nodes: NodeData[]; edges: EdgeData[] }[];\n\n  /**\n   * Perform an redo.\n   */\n  redo: () => void;\n\n  /**\n   * Perform a undo.\n   */\n  undo: () => void;\n}\n\nexport const useUndo = ({\n  nodes,\n  edges,\n  disabled,\n  maxHistory = 20,\n  onUndoRedo\n}: UndoProps): UndoResult => {\n  const [canUndo, setCanUndo] = useState<boolean>(false);\n  const [canRedo, setCanRedo] = useState<boolean>(false);\n\n  const manager = useRef<Undoo>(\n    new Undoo({\n      maxLength: maxHistory\n    })\n  );\n\n  // Reference: https://reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback\n  const callbackRef = useRef(onUndoRedo);\n  useEffect(() => {\n    callbackRef.current = onUndoRedo;\n  }, [onUndoRedo]);\n\n  useEffect(() => {\n    manager.current.save({\n      nodes,\n      edges\n    });\n\n    setCanUndo(manager.current.canUndo());\n    setCanRedo(manager.current.canRedo());\n  }, [nodes, edges]);\n\n  const undo = useCallback(() => {\n    manager.current.undo((state) => {\n      const nextUndo = manager.current.canUndo();\n      const nextRedo = manager.current.canRedo();\n      setCanUndo(nextUndo);\n      setCanRedo(nextRedo);\n\n      callbackRef.current({\n        ...state,\n        type: 'undo',\n        canUndo: nextUndo,\n        canRedo: nextRedo\n      });\n    });\n  }, []);\n\n  const redo = useCallback(() => {\n    manager.current.redo((state) => {\n      const nextUndo = manager.current.canUndo();\n      const nextRedo = manager.current.canRedo();\n      setCanUndo(nextUndo);\n      setCanRedo(nextRedo);\n\n      callbackRef.current({\n        ...state,\n        type: 'redo',\n        canUndo: nextUndo,\n        canRedo: nextRedo\n      });\n    });\n  }, []);\n\n  const clear = useCallback((nodes: NodeData[], edges: EdgeData[]) => {\n    manager.current.clear();\n    setCanUndo(false);\n    setCanRedo(false);\n\n    callbackRef.current({\n      type: 'clear',\n      canUndo: false,\n      canRedo: false\n    });\n\n    manager.current.save({\n      nodes,\n      edges\n    });\n  }, []);\n\n  useHotkeys([\n    {\n      name: 'Undo',\n      keys: 'mod+z',\n      category: 'Canvas',\n      description: 'Undo changes',\n      callback: (event) => {\n        event.preventDefault();\n        if (!disabled && canUndo) {\n          undo();\n        }\n      }\n    },\n    {\n      name: 'Redo',\n      keys: 'mod+shift+z',\n      category: 'Canvas',\n      description: 'Redo changes',\n      callback: (event) => {\n        event.preventDefault();\n        if (!disabled && canRedo) {\n          redo();\n        }\n      }\n    }\n  ]);\n\n  return {\n    canUndo,\n    canRedo,\n    count: () => manager.current.count(),\n    history: () => manager.current.history(),\n    clear,\n    redo,\n    undo\n  } as UndoResult;\n};\n","import { RefObject, useCallback, useEffect, useRef, useState } from 'react';\nimport { CanvasRef } from '../Canvas';\nimport { getCoords } from '../utils/helpers';\nimport { Matrix2D, Point2D } from 'kld-affine';\nimport { IntersectionQuery } from 'kld-intersections';\nimport { LayoutNodeData } from '../types';\n\nexport interface ProximityProps {\n  /**\n   * Disable proximity or not.\n   */\n  disabled?: boolean;\n\n  /**\n   * Min distance required before match is made.\n   *\n   * @default 40\n   */\n  minDistance?: number;\n\n  /**\n   * Ref pointer to the canvas.\n   */\n  canvasRef?: RefObject<CanvasRef>;\n\n  /**\n   * Distance from the match.\n   */\n  onDistanceChange?: (distance: number | null) => void;\n\n  /**\n   * When a match state has changed.\n   */\n  onMatchChange?: (matche: string | null, distance: number | null) => void;\n\n  /**\n   * When the pointer intersects a node.\n   */\n  onIntersects?: (matche: string | null) => void;\n}\n\nexport interface ProximityResult {\n  /**\n   * The matched id of the node.\n   */\n  match: string | null;\n\n  /**\n   * Event for drag started.\n   */\n  onDragStart: (event: PointerEvent) => void;\n\n  /**\n   * Event for active dragging.\n   */\n  onDrag: (event: PointerEvent) => void;\n\n  /**\n   * Event for drag ended.\n   */\n  onDragEnd: (event: PointerEvent) => void;\n}\n\ninterface PointNode {\n  points: Point2D[];\n  node: LayoutNodeData;\n}\n\nconst buildPoints = (nodes: LayoutNodeData[], parent?: LayoutNodeData) => {\n  const results: PointNode[] = [];\n\n  if (nodes?.length) {\n    for (const node of nodes) {\n      let x = node.x;\n      let y = node.y;\n\n      // NOTE: If we have a parent, let's update the points\n      // to account for the parent's position\n      if (parent) {\n        x = parent.x + x;\n        y = parent.y + y;\n      }\n\n      const points = [\n        // top-left\n        new Point2D(x, y),\n        // bottom-right\n        new Point2D(x + node.width, y + node.height)\n      ];\n\n      results.push({\n        points,\n        node\n      });\n\n      if (node.children?.length) {\n        results.push(...buildPoints(node.children, node));\n      }\n    }\n  }\n\n  return results;\n};\n\nconst distanceFromNode = (mousePoint: Point2D, node: PointNode) => {\n  const [tl, br] = node.points;\n  let dx = 0;\n  let dy = 0;\n\n  // Compute distance to elem in X\n  if (mousePoint.x < tl.x) {\n    dx = tl.x - mousePoint.x;\n  } else if (mousePoint.x > br.x) {\n    dx = br.x - mousePoint.x;\n  }\n\n  // Compute distance to elem in Y\n  if (mousePoint.y < tl.y) {\n    dy = tl.y - mousePoint.y;\n  } else if (mousePoint.y > br.y) {\n    dy = br.y - mousePoint.y;\n  }\n\n  return Math.floor(Math.sqrt(dx * dx + dy * dy));\n};\n\nconst findNodeIntersection = (\n  event: PointerEvent,\n  matrix: Matrix2D,\n  points: PointNode[],\n  minDistance: number\n) => {\n  const cubes = [];\n  const mousePoint = new Point2D(event.x, event.y).transform(matrix);\n\n  for (const point of points) {\n    // TODO: Make this support other shape types...\n    const intersects = IntersectionQuery.pointInRectangle(\n      mousePoint,\n      point.points[0],\n      point.points[1]\n    );\n\n    // Calc the distances\n    // https://github.com/thelonious/kld-affine/issues/24\n    const minDist = distanceFromNode(mousePoint, point);\n\n    cubes.push({\n      node: point.node,\n      minDist,\n      intersects\n    });\n  }\n\n  let foundDist = minDistance;\n  let intersectedNodeId = null;\n  let foundNodeId = null;\n  for (const cube of cubes) {\n    if (cube.minDist < foundDist && !cube.intersects) {\n      foundNodeId = cube.node.id;\n      foundDist = cube.minDist;\n    }\n\n    if (cube.intersects) {\n      intersectedNodeId = cube.node.id;\n    }\n  }\n\n  if (intersectedNodeId) {\n    // We are are just inside a node already\n    // and there is no closer children ( nested case )\n    if (!foundNodeId || foundNodeId === intersectedNodeId) {\n      // If we are inside the intersected node and its the\n      // closest node, let's reset the distance to 0\n      foundNodeId = intersectedNodeId;\n      foundDist = 0;\n    }\n  }\n\n  return {\n    intersectedNodeId,\n    foundNodeId,\n    foundDist\n  };\n};\n\nexport const useProximity = ({\n  canvasRef,\n  disabled,\n  minDistance = 40,\n  ...rest\n}: ProximityProps) => {\n  const lastIntersectRef = useRef<string | null>(null);\n  const lastMatchRef = useRef<string | null>(null);\n  const lastDistance = useRef<number | null>(null);\n  const frame = useRef<number>(0);\n\n  // Reference: https://reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback\n  const eventRefs = useRef(rest);\n  useEffect(() => {\n    eventRefs.current = rest;\n  }, [rest]);\n\n  const [match, setMatch] = useState<string | null>(null);\n  const [matrix, setMatrix] = useState<Matrix2D | null>(null);\n  const [points, setPoints] = useState<PointNode[] | null>(null);\n\n  const onDragStart = useCallback(() => {\n    if (disabled) {\n      return;\n    }\n\n    const ref = canvasRef.current;\n\n    // @ts-ignore\n    setMatrix(\n      getCoords({\n        containerRef: ref.containerRef,\n        zoom: ref.zoom,\n        layoutXY: ref.xy\n      })\n    );\n    setPoints(buildPoints(ref.layout.children));\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [disabled]);\n\n  const onDrag = useCallback(\n    (event: PointerEvent) => {\n      if (!matrix || disabled) {\n        return;\n      }\n\n      const { onMatchChange, onIntersects, onDistanceChange } =\n        eventRefs.current;\n\n      const { intersectedNodeId, foundNodeId, foundDist } =\n        findNodeIntersection(event, matrix, points, minDistance);\n      const nextDist = foundDist !== minDistance ? foundDist : null;\n\n      if (foundNodeId !== lastMatchRef.current) {\n        onMatchChange?.(foundNodeId, foundDist);\n      }\n\n      if (intersectedNodeId !== lastIntersectRef.current) {\n        onIntersects?.(intersectedNodeId);\n      }\n\n      if (onDistanceChange && nextDist !== lastDistance.current) {\n        cancelAnimationFrame(frame.current);\n        frame.current = requestAnimationFrame(() => {\n          onDistanceChange(nextDist);\n        });\n      }\n\n      // Hold these in refs for race cases\n      lastIntersectRef.current = intersectedNodeId;\n      lastMatchRef.current = foundNodeId;\n      lastDistance.current = nextDist;\n\n      setMatch(foundNodeId);\n    },\n    [matrix, disabled, minDistance, points]\n  );\n\n  useEffect(() => {\n    return () => cancelAnimationFrame(frame.current);\n  });\n\n  const onDragEnd = useCallback(() => {\n    if (!disabled) {\n      setMatch(null);\n      setMatrix(null);\n      setPoints(null);\n    }\n  }, [disabled]);\n\n  return {\n    match,\n    onDragStart,\n    onDrag,\n    onDragEnd\n  } as ProximityResult;\n};\n","import { EdgeData, NodeData } from '../types';\n\n/**\n * Helper function to determine if edge already has a link.\n */\nexport function hasLink(edges: EdgeData[], from: NodeData, to: NodeData) {\n  return edges.some((e) => e.from === from.id && e.to === to.id);\n}\n\n/**\n * Get sources pointing to a node.\n */\nfunction getSourceNodesForTargetId(\n  nodes: NodeData[],\n  edges: EdgeData[],\n  nodeId: string\n) {\n  const sourceNodeIds = edges.reduce((acc, edge) => {\n    if (edge.to === nodeId) {\n      acc.push(edge.from);\n    }\n    return acc;\n  }, []);\n\n  const node = nodes.find((n) => n.id === nodeId);\n\n  if (node?.parent) {\n    sourceNodeIds.push(node.parent);\n  }\n\n  return nodes.filter((n) => sourceNodeIds.includes(n.id));\n}\n\n/**\n * Detect if there is a circular reference from the from to the source node.\n */\nexport function detectCircular(\n  nodes: NodeData[],\n  edges: EdgeData[],\n  fromNode: NodeData,\n  toNode: NodeData\n) {\n  let found = false;\n\n  const traverse = (nodeId: string) => {\n    const sourceNodes = getSourceNodesForTargetId(nodes, edges, nodeId);\n    for (const node of sourceNodes) {\n      if (node.id !== toNode.id) {\n        traverse(node.id);\n      } else {\n        found = true;\n        break;\n      }\n    }\n  };\n\n  traverse(fromNode.id);\n\n  return found;\n}\n\n/**\n * Given a node id, get all the parent nodes recursively.\n */\nexport const getParentsForNodeId = (\n  nodes: NodeData[],\n  edges: EdgeData[],\n  startId: string\n) => {\n  const result = [];\n\n  const traverse = (nodeId: string) => {\n    const sourceNodes = getSourceNodesForTargetId(nodes, edges, nodeId);\n    for (const node of sourceNodes) {\n      const has = result.find((n) => n.id === node.id);\n      if (!has) {\n        result.push(node);\n        traverse(node.id);\n      }\n    }\n  };\n\n  traverse(startId);\n\n  return result;\n};\n\n/**\n * Get edge data given a node.\n */\nexport function getEdgesByNode(edges: EdgeData[], node: NodeData) {\n  const to = [];\n  const from = [];\n\n  for (const edge of edges) {\n    if (edge.to === node.id) {\n      to.push(edge);\n    }\n    if (edge.from === node.id) {\n      from.push(edge);\n    }\n  }\n\n  return {\n    to,\n    from,\n    all: [...to, ...from]\n  };\n}\n"]}