{"version":3,"file":"index.mjs","names":[],"sources":["../src/config/alpha.ts","../src/config/forces.ts","../src/config/initial.ts","../src/lib/utils.ts","../src/config/marker.ts","../src/config/position.ts","../src/config/config.ts","../src/lib/canvas.ts","../src/lib/drag.ts","../src/lib/filter.ts","../src/lib/paths.ts","../src/lib/link.ts","../src/lib/marker.ts","../src/lib/node.ts","../src/lib/simulation.ts","../src/lib/zoom.ts","../src/controller.ts","../src/model/graph.ts","../src/model/link.ts","../src/model/node.ts"],"sourcesContent":["import type { NodeTypeToken } from '../model/graph'\nimport type { GraphNode } from '../model/node'\n\n/**\n * Alpha values when label display changes.\n */\nexport interface LabelAlphas {\n  /**\n   * Alpha value when labels are turned off.\n   */\n  readonly hide: number\n  /**\n   * Alpha value when labels are turned on.\n   */\n  readonly show: number\n}\n\n/**\n * Context of a resize.\n */\nexport interface ResizeContext {\n  /**\n   * The old height.\n   */\n  readonly oldHeight: number\n  /**\n   * The old width.\n   */\n  readonly oldWidth: number\n  /**\n   * The new height.\n   */\n  readonly newHeight: number\n  /**\n   * The new width.\n   */\n  readonly newWidth: number\n}\n\n/**\n * Alpha value configuration for controlling simulation activity.\n */\nexport interface AlphaConfig<T extends NodeTypeToken, Node extends GraphNode<T>> {\n  /**\n   * Target alpha values for dragging.\n   */\n  readonly drag: {\n    /**\n     * Target alpha when a drag starts.\n     * Should be larger than 0.\n     */\n    readonly start: number\n    /**\n     * Target alpha when a drag stops.\n     * Should generally be 0.\n     */\n    readonly end: number\n  }\n  /**\n   * Alpha values for filter changes.\n   */\n  readonly filter: {\n    /**\n     * Alpha value when the link filter changes.\n     */\n    readonly link: number\n    /**\n     * Alpha value when the node type filter changes.\n     */\n    readonly type: number\n    /**\n     * Alpha values when the inclusion of unlinked nodes changes.\n     */\n    readonly unlinked: {\n      /**\n       * Alpha value when unlinked nodes are included.\n       */\n      readonly include: number\n      /**\n       * Alpha value when unlinked nodes are excluded.\n       */\n      readonly exclude: number\n    }\n  }\n  /**\n   * Alpha values when node focus changes.\n   */\n  readonly focus: {\n    /**\n     * Alpha value when a node is focused.\n     * @param node - The focused node.\n     * @returns The alpha value.\n     */\n    readonly acquire: (node: Node) => number\n    /**\n     * Alpha value when a node is unfocused.\n     * @param node - The unfocused node.\n     * @returns The alpha value.\n     */\n    readonly release: (node: Node) => number\n  }\n  /**\n   * Alpha value when the graph is initialized.\n   */\n  readonly initialize: number\n  /**\n   * Alpha values when label display changes.\n   */\n  readonly labels: {\n    /**\n     * Alpha values when link label display changes.\n     */\n    readonly links: LabelAlphas\n    /**\n     * Alpha values when node label display changes.\n     */\n    readonly nodes: LabelAlphas\n  }\n  /**\n   * Alpha values when the graph is resized.\n   */\n  readonly resize: number | ((context: ResizeContext) => number)\n}\n\n/**\n * Create the default alpha configuration.\n */\nexport function createDefaultAlphaConfig<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n>(): AlphaConfig<T, Node> {\n  return {\n    drag: {\n      end: 0,\n      start: 0.1,\n    },\n    filter: {\n      link: 1,\n      type: 0.1,\n      unlinked: {\n        include: 0.1,\n        exclude: 0.1,\n      },\n    },\n    focus: {\n      acquire: () => 0.1,\n      release: () => 0.1,\n    },\n    initialize: 1,\n    labels: {\n      links: {\n        hide: 0,\n        show: 0,\n      },\n      nodes: {\n        hide: 0,\n        show: 0,\n      },\n    },\n    resize: 0.5,\n  }\n}\n","import type { NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\n\n/**\n * Simulation force.\n */\nexport interface Force<Subject> {\n  /**\n   * Whether the force is enabled.\n   */\n  readonly enabled: boolean\n  /**\n   * The strength of the force.\n   * Can be a static number or a function receiving the force's subject and returning a number.\n   */\n  readonly strength: number | ((subject: Subject) => number)\n}\n\n/**\n * Simulation force applied to nodes.\n */\nexport type NodeForce<T extends NodeTypeToken, Node extends GraphNode<T>> = Force<Node>\n\n/**\n * Collision force applied to nodes.\n */\nexport interface CollisionForce<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n> extends NodeForce<T, Node> {\n  /**\n   * Multiplier of the node radius.\n   * Tip: Large values can drastically reduce link intersection.\n   */\n  readonly radiusMultiplier: number\n}\n\n/**\n * Simulation force applied to links.\n */\nexport interface LinkForce<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> extends Force<Link> {\n  /**\n   * Define the length of a link for the simulation.\n   */\n  readonly length: number | ((link: Link) => number)\n}\n\n/**\n * Simulation force configuration.\n */\nexport interface SimulationForceConfig<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  /**\n   * Centering force applied to nodes.\n   */\n  readonly centering: false | NodeForce<T, Node>\n  /**\n   * Charge force applied to nodes.\n   */\n  readonly charge: false | NodeForce<T, Node>\n  /**\n   * Collision force applied to nodes.\n   */\n  readonly collision: false | CollisionForce<T, Node>\n  /**\n   * Link force applied to links.\n   */\n  readonly link: false | LinkForce<T, Node, Link>\n}\n\n/**\n * Create the default force configuration.\n */\nexport function createDefaultForceConfig<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(): SimulationForceConfig<T, Node, Link> {\n  return {\n    centering: {\n      enabled: true,\n      strength: 0.1,\n    },\n    charge: {\n      enabled: true,\n      strength: -1,\n    },\n    collision: {\n      enabled: true,\n      strength: 1,\n      radiusMultiplier: 2,\n    },\n    link: {\n      enabled: true,\n      strength: 1,\n      length: 128,\n    },\n  }\n}\n","import type { NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport type { LinkFilter } from './filter'\n\n/**\n * Initial settings of a controller.\n */\nexport interface InitialGraphSettings<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  /**\n   * Whether nodes without incoming or outgoing links will be shown or not.\n   */\n  readonly includeUnlinked: boolean\n  /**\n   * Link filter that decides whether links should be included or not.\n   */\n  readonly linkFilter: LinkFilter<T, Node, Link>\n  /**\n   * Node types that should be included.\n   * If undefined, all node types will be included.\n   */\n  readonly nodeTypeFilter?: T[] | undefined\n  /**\n   * Whether link labels are shown or not.\n   */\n  readonly showLinkLabels: boolean\n  /**\n   * Whether node labels are shown or not.\n   */\n  readonly showNodeLabels: boolean\n}\n\n/**\n * Create default initial settings.\n */\nexport function createDefaultInitialGraphSettings<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(): InitialGraphSettings<T, Node, Link> {\n  return {\n    includeUnlinked: true,\n    linkFilter: () => true,\n    nodeTypeFilter: undefined,\n    showLinkLabels: true,\n    showNodeLabels: true,\n  }\n}\n","import type { GraphConfig } from '../config/config'\nimport type { NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\n\nexport function terminateEvent(event: Event): void {\n  event.preventDefault()\n  event.stopPropagation()\n}\n\nexport function isNumber(value: unknown): value is number {\n  return typeof value === 'number'\n}\n\nexport function getNodeRadius<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(config: GraphConfig<T, Node, Link>, node: Node): number {\n  return isNumber(config.nodeRadius) ? config.nodeRadius : config.nodeRadius(node)\n}\n\n/**\n * Get the id of a link.\n * @param link - The link.\n */\nexport function getLinkId<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(link: Link): string {\n  return `${link.source.id}-${link.target.id}`\n}\n\n/**\n * Get the ID of a marker.\n * @param color - The color of the link.\n */\nexport function getMarkerId(color: string): string {\n  return `link-arrow-${color}`.replace(/[()]/g, '~')\n}\n\n/**\n * Get the URL of a marker.\n * @param link - The link of the marker.\n */\nexport function getMarkerUrl<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(link: Link): string {\n  return `url(#${getMarkerId(link.color)})`\n}\n","import { getNodeRadius } from '../lib/utils'\nimport type { NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport type { GraphConfig } from './config'\n\n/**\n * Marker configuration.\n */\nexport interface MarkerConfig {\n  /**\n   * Size of the marker's box.\n   */\n  readonly size: number\n  /**\n   * Get padding of the marker for calculating link paths.\n   * @param node - The node the marker is pointing at.\n   * @param config - The current config.\n   * @returns The padding of the marker.\n   */\n  readonly padding: <\n    T extends NodeTypeToken,\n    Node extends GraphNode<T>,\n    Link extends GraphLink<T, Node>,\n  >(\n    node: Node,\n    config: GraphConfig<T, Node, Link>,\n  ) => number\n  /**\n   * The ref of the marker.\n   */\n  readonly ref: [number, number]\n  /**\n   * The path of the marker.\n   */\n  readonly path: [number, number][]\n  /**\n   * The ViewBox of the marker.\n   */\n  readonly viewBox: string\n}\n\nfunction defaultMarkerConfig(size: number): MarkerConfig {\n  return {\n    size,\n    padding: <T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>>(\n      node: Node,\n      config: GraphConfig<T, Node, Link>,\n    ) => getNodeRadius(config, node) + 2 * size,\n    ref: [size / 2, size / 2],\n    path: [\n      [0, 0],\n      [0, size],\n      [size, size / 2],\n    ] as [number, number][],\n    viewBox: [0, 0, size, size].join(','),\n  }\n}\n\n/**\n * Collection of built-in markers.\n */\nexport const Markers = {\n  /**\n   * Create an arrow marker configuration.\n   * @param size - The size of the arrow\n   */\n  Arrow: (size: number): MarkerConfig => defaultMarkerConfig(size),\n}\n","import type { Graph, NodeTypeToken } from '../model/graph'\nimport type { GraphNode } from '../model/node'\n\n/**\n * Initializes a node's position in context of a graph's width and height.\n */\nexport type PositionInitializer<T extends NodeTypeToken, Node extends GraphNode<T>> = (\n  node: Node,\n  width: number,\n  height: number,\n) => [number, number]\n\nconst Centered: PositionInitializer<NodeTypeToken, GraphNode> = (_, width, height) => [\n  width / 2,\n  height / 2,\n]\n\nconst Randomized: PositionInitializer<NodeTypeToken, GraphNode> = (_, width, height) => [\n  randomInRange(0, width),\n  randomInRange(0, height),\n]\n\nfunction randomInRange(min: number, max: number): number {\n  return Math.random() * (max - min) + min\n}\n\nfunction Stable<T extends NodeTypeToken, Node extends GraphNode<T>>(\n  previousGraph: Graph<T, Node>,\n): PositionInitializer<T, Node> {\n  const positions = Object.fromEntries(\n    previousGraph.nodes.map((node) => [node.id, [node.x, node.y]] as const),\n  )\n  return (node, width, height) => {\n    const [x, y] = positions[node.id] ?? []\n    if (!x || !y) {\n      return Randomized(node, width, height)\n    }\n    return [x, y]\n  }\n}\n\n/**\n * Collection of built-in position initializers.\n */\nexport const PositionInitializers: {\n  /**\n   * Initializes node positions to a graph's center.\n   */\n  Centered: PositionInitializer<string, GraphNode<string>>\n  /**\n   * Randomly initializes node positions within the visible area.\n   */\n  Randomized: PositionInitializer<string, GraphNode<string>>\n  /**\n   * Initializes node positions based on other graph.\n   */\n  Stable: typeof Stable\n} = {\n  Centered,\n  Randomized,\n  Stable,\n}\n","import deepmerge from 'deepmerge'\n\nimport type { NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport { createDefaultAlphaConfig } from './alpha'\nimport type { Callbacks } from './callbacks'\nimport { createDefaultForceConfig } from './forces'\nimport type { InitialGraphSettings } from './initial'\nimport { createDefaultInitialGraphSettings } from './initial'\nimport type { MarkerConfig } from './marker'\nimport { Markers } from './marker'\nimport type { Modifiers } from './modifiers'\nimport type { PositionInitializer } from './position'\nimport { PositionInitializers } from './position'\nimport type { SimulationConfig } from './simulation'\nimport type { ZoomConfig } from './zoom'\n\nexport interface GraphConfig<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  /**\n   * Set to true to enable automatic resizing.\n   * Warning: Do call shutdown(), once the controller is no longer required.\n   */\n  readonly autoResize: boolean\n  /**\n   * Callback configuration.\n   */\n  readonly callbacks: Callbacks<T, Node>\n  readonly hooks: {\n    afterZoom?: (scale: number, xOffset: number, yOffset: number) => void\n  }\n  /**\n   * Initial settings of a controller.\n   */\n  readonly initial: InitialGraphSettings<T, Node, Link>\n  /**\n   * Marker configuration.\n   */\n  readonly marker: MarkerConfig\n  /**\n   * Low-level callbacks for modifying the underlying d3-selection.\n   */\n  readonly modifiers: Modifiers<T, Node, Link>\n  /**\n   * Define the radius of a node for the simulation and visualization.\n   * Can be a static number or a function receiving a node as its parameter.\n   */\n  readonly nodeRadius: number | ((node: Node) => number)\n  /**\n   * Initializes a node's position in context of a graph's width and height.\n   */\n  readonly positionInitializer: PositionInitializer<T, Node>\n  /**\n   * Simulation configuration.\n   */\n  readonly simulation: SimulationConfig<T, Node, Link>\n  /**\n   * Zoom configuration.\n   */\n  readonly zoom: ZoomConfig\n}\n\nfunction defaultGraphConfig<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(): GraphConfig<T, Node, Link> {\n  return {\n    autoResize: false,\n    callbacks: {},\n    hooks: {},\n    initial: createDefaultInitialGraphSettings(),\n    nodeRadius: 16,\n    marker: Markers.Arrow(4),\n    modifiers: {},\n    positionInitializer: PositionInitializers.Centered,\n    simulation: {\n      alphas: createDefaultAlphaConfig(),\n      forces: createDefaultForceConfig(),\n    },\n    zoom: {\n      initial: 1,\n      min: 0.1,\n      max: 2,\n    },\n  }\n}\n\n/**\n * Utility type for deeply partial objects.\n */\nexport type DeepPartial<T> = {\n  readonly [P in keyof T]?: DeepPartial<T[P]>\n}\n\n/**\n * Define the configuration of a controller.\n * Will be merged with the default configuration.\n * @param config - The partial configuration.\n * @returns The merged configuration.\n */\nexport function defineGraphConfig<\n  T extends NodeTypeToken = NodeTypeToken,\n  Node extends GraphNode<T> = GraphNode<T>,\n  Link extends GraphLink<T, Node> = GraphLink<T, Node>,\n>(config: DeepPartial<GraphConfig<T, Node, Link>> = {}): GraphConfig<T, Node, Link> {\n  return deepmerge(defaultGraphConfig<T, Node, Link>(), config, {\n    arrayMerge: (_target, source) => source,\n  }) as GraphConfig<T, Node, Link>\n}\n","import { zoomIdentity } from 'd3-zoom'\n\nimport type { Canvas, GraphHost, Zoom } from './types'\nimport { terminateEvent } from './utils'\n\nexport interface DefineCanvasParams {\n  readonly applyZoom: boolean\n  readonly container: GraphHost\n  readonly offset: [number, number]\n  readonly onDoubleClick?: (event: PointerEvent) => void\n  readonly onPointerMoved?: (event: PointerEvent) => void\n  readonly onPointerUp?: (event: PointerEvent) => void\n  readonly scale: number\n  readonly zoom: Zoom\n}\n\nexport function defineCanvas({\n  applyZoom,\n  container,\n  onDoubleClick,\n  onPointerMoved,\n  onPointerUp,\n  offset: [xOffset, yOffset],\n  scale,\n  zoom,\n}: DefineCanvasParams): Canvas {\n  const svg = container\n    .classed('graph', true)\n    .append('svg')\n    .attr('height', '100%')\n    .attr('width', '100%')\n    .call(zoom)\n    .on('contextmenu', (event: MouseEvent) => terminateEvent(event))\n    .on('dblclick', (event: PointerEvent) => onDoubleClick?.(event))\n    .on('dblclick.zoom', null)\n    .on('pointermove', (event: PointerEvent) => onPointerMoved?.(event))\n    .on('pointerup', (event: PointerEvent) => onPointerUp?.(event))\n    .style('cursor', 'grab')\n\n  if (applyZoom) {\n    // oxlint-disable-next-line typescript/unbound-method\n    svg.call(zoom.transform, zoomIdentity.translate(xOffset, yOffset).scale(scale))\n  }\n\n  return svg.append('g')\n}\n\nexport interface UpdateCanvasParams {\n  readonly canvas?: Canvas | undefined\n  readonly scale: number\n  readonly xOffset: number\n  readonly yOffset: number\n}\n\nexport function updateCanvasTransform({\n  canvas,\n  scale,\n  xOffset,\n  yOffset,\n}: UpdateCanvasParams): void {\n  canvas?.attr('transform', `translate(${xOffset},${yOffset})scale(${scale})`)\n}\n","import { drag } from 'd3-drag'\nimport { select } from 'd3-selection'\n\nimport type { GraphConfig } from '../config/config'\nimport type { NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport type { Drag, NodeDragEvent } from './types'\n\nexport interface DefineDragParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly config: GraphConfig<T, Node, Link>\n  readonly onDragStart: (event: NodeDragEvent<T, Node>, d: Node) => void\n  readonly onDragEnd: (event: NodeDragEvent<T, Node>, d: Node) => void\n}\n\nexport function defineDrag<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ config, onDragStart, onDragEnd }: DefineDragParams<T, Node, Link>): Drag<T, Node> {\n  const drg = drag<SVGGElement, Node, Node>()\n    .filter((event: MouseEvent | TouchEvent) => {\n      if (event.type === 'mousedown') {\n        return (event as MouseEvent).button === 0 // primary (left) mouse button\n      } else if (event.type === 'touchstart') {\n        return (event as TouchEvent).touches.length === 1\n      }\n      return false\n    })\n    .on('start', (event: NodeDragEvent<T, Node>, d) => {\n      if (event.active === 0) {\n        onDragStart(event, d)\n      }\n      select(event.sourceEvent.target).classed('grabbed', true)\n      d.fx = d.x\n      d.fy = d.y\n    })\n    .on('drag', (event: NodeDragEvent<T, Node>, d) => {\n      d.fx = event.x\n      d.fy = event.y\n    })\n    .on('end', (event: NodeDragEvent<T, Node>, d) => {\n      if (event.active === 0) {\n        onDragEnd(event, d)\n      }\n      select(event.sourceEvent.target).classed('grabbed', false)\n      d.fx = undefined\n      d.fy = undefined\n    })\n\n  config.modifiers.drag?.(drg)\n\n  return drg\n}\n","import type { LinkFilter } from '../config/filter'\nimport type { Graph, NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\n\nexport interface GraphFilterParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly graph: Graph<T, Node, Link>\n  readonly filter: T[]\n  readonly focusedNode?: Node | undefined\n  readonly includeUnlinked: boolean\n  readonly linkFilter: LinkFilter<T, Node, Link>\n}\n\nexport function filterGraph<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({\n  graph,\n  filter,\n  focusedNode,\n  includeUnlinked,\n  linkFilter,\n}: GraphFilterParams<T, Node, Link>): Graph<T, Node, Link> {\n  const links = graph.links.filter(\n    (d) => filter.includes(d.source.type) && filter.includes(d.target.type) && linkFilter(d),\n  )\n\n  const isLinked = (node: Node) =>\n    links.find((link) => link.source.id === node.id || link.target.id === node.id) !== undefined\n  const nodes = graph.nodes.filter(\n    (d) => filter.includes(d.type) && (includeUnlinked || isLinked(d)),\n  )\n\n  if (focusedNode === undefined || !filter.includes(focusedNode.type)) {\n    return {\n      nodes,\n      links,\n    }\n  }\n\n  return getFocusedSubgraph({ nodes, links }, focusedNode)\n}\n\nfunction getFocusedSubgraph<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(graph: Graph<T, Node, Link>, source: Node): Graph<T, Node, Link> {\n  const links = [\n    ...getIncomingLinksTransitively(graph, source),\n    ...getOutgoingLinksTransitively(graph, source),\n  ]\n\n  const nodes = links.flatMap((link) => [link.source, link.target])\n\n  return {\n    nodes: [...new Set([...nodes, source])],\n    links: [...new Set(links)],\n  }\n}\n\nfunction getIncomingLinksTransitively<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(graph: Graph<T, Node, Link>, source: Node): Link[] {\n  return getLinksInDirectionTransitively(graph, source, (link, node) => link.target.id === node.id)\n}\n\nfunction getOutgoingLinksTransitively<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(graph: Graph<T, Node, Link>, source: Node): Link[] {\n  return getLinksInDirectionTransitively(graph, source, (link, node) => link.source.id === node.id)\n}\n\nfunction getLinksInDirectionTransitively<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(\n  graph: Graph<T, Node, Link>,\n  source: Node,\n  directionPredicate: (link: Link, node: Node) => boolean,\n): Link[] {\n  const remainingLinks = new Set(graph.links)\n  const foundNodes = new Set([source])\n  const foundLinks: Link[] = []\n\n  while (remainingLinks.size > 0) {\n    const newLinks = [...remainingLinks].filter((link) =>\n      [...foundNodes].some((node) => directionPredicate(link, node)),\n    )\n\n    if (newLinks.length === 0) {\n      return foundLinks\n    }\n\n    newLinks.forEach((link) => {\n      foundNodes.add(link.source)\n      foundNodes.add(link.target)\n      foundLinks.push(link)\n      remainingLinks.delete(link)\n    })\n  }\n\n  return foundLinks\n}\n","import { Vector } from 'vecti'\n\nimport type { GraphConfig } from '../config/config'\nimport type { NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport { getNodeRadius } from './utils'\n\n// ##################################################\n// COMMON\n// ##################################################\n\nexport interface PathParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly config: GraphConfig<T, Node, Link>\n  readonly source: Node\n  readonly target: Node\n}\n\nexport interface ReflexivePathParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly config: GraphConfig<T, Node, Link>\n  readonly node: Node\n  readonly center: Vector\n}\n\nfunction getX<T extends NodeTypeToken, Node extends GraphNode<T>>(node: Node): number {\n  return node.x ?? 0\n}\n\nfunction getY<T extends NodeTypeToken, Node extends GraphNode<T>>(node: Node): number {\n  return node.y ?? 0\n}\n\ninterface VectorData {\n  readonly s: Vector\n  readonly t: Vector\n  readonly dist: number\n  readonly norm: Vector\n  readonly endNorm: Vector\n}\n\nfunction calculateVectorData<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ source, target }: PathParams<T, Node, Link>): VectorData {\n  const s = new Vector(getX(source), getY(source))\n  const t = new Vector(getX(target), getY(target))\n  const diff = t.subtract(s)\n  const dist = diff.length()\n  const norm = diff.normalize()\n  const endNorm = norm.multiply(-1)\n  return {\n    s,\n    t,\n    dist,\n    norm,\n    endNorm,\n  }\n}\n\nfunction calculateCenter<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ center, node }: ReflexivePathParams<T, Node, Link>) {\n  const n = new Vector(getX(node), getY(node))\n  let c = center\n  if (n.x === c.x && n.y === c.y) {\n    // Nodes at the exact center of the Graph should have their reflexive edge above them.\n    c = c.add(new Vector(0, 1))\n  }\n  return {\n    n,\n    c,\n  }\n}\n\nfunction calculateSourceAndTarget<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ config, source, target }: PathParams<T, Node, Link>) {\n  const { s, t, norm } = calculateVectorData({ config, source, target })\n  const start = s.add(norm.multiply(getNodeRadius(config, source) - 1))\n  const end = t.subtract(norm.multiply(config.marker.padding(target, config)))\n  return {\n    start,\n    end,\n  }\n}\n\n// ##################################################\n// LINE\n// ##################################################\n\nfunction paddedLinePath<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(params: PathParams<T, Node, Link>): string {\n  const { start, end } = calculateSourceAndTarget(params)\n  return `M${start.x},${start.y}\n          L${end.x},${end.y}`\n}\n\nfunction lineLinkTextTransform<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(params: PathParams<T, Node, Link>): string {\n  const { start, end } = calculateSourceAndTarget(params)\n\n  const midpoint = end.subtract(start).multiply(0.5)\n  const result = start.add(midpoint)\n\n  return `translate(${result.x - 8},${result.y - 4})`\n}\n\n// ##################################################\n// ARC\n// ##################################################\n\nfunction paddedArcPath<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ config, source, target }: PathParams<T, Node, Link>): string {\n  const { s, t, dist, norm, endNorm } = calculateVectorData({\n    config,\n    source,\n    target,\n  })\n  const rotation = 10\n  const start = norm\n    .rotateByDegrees(-rotation)\n    .multiply(getNodeRadius(config, source) - 1)\n    .add(s)\n  const end = endNorm\n    .rotateByDegrees(rotation)\n    .multiply(getNodeRadius(config, target))\n    .add(t)\n    .add(endNorm.rotateByDegrees(rotation).multiply(2 * config.marker.size))\n  const arcRadius = 1.2 * dist\n  return `M${start.x},${start.y}\n          A${arcRadius},${arcRadius},0,0,1,${end.x},${end.y}`\n}\n\n// ##################################################\n// REFLEXIVE\n// ##################################################\n\nfunction paddedReflexivePath<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ center, config, node }: ReflexivePathParams<T, Node, Link>): string {\n  const { n, c } = calculateCenter({ center, config, node })\n  const radius = getNodeRadius(config, node)\n  const diff = n.subtract(c)\n  const norm = diff.multiply(1 / diff.length())\n  const rotation = 40\n  const start = norm\n    .rotateByDegrees(rotation)\n    .multiply(radius - 1)\n    .add(n)\n  const end = norm\n    .rotateByDegrees(-rotation)\n    .multiply(radius)\n    .add(n)\n    .add(norm.rotateByDegrees(-rotation).multiply(2 * config.marker.size))\n  return `M${start.x},${start.y}\n          A${radius},${radius},0,1,0,${end.x},${end.y}`\n}\n\nfunction bidirectionalLinkTextTransform<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ config, source, target }: PathParams<T, Node, Link>): string {\n  const { t, dist, endNorm } = calculateVectorData({ config, source, target })\n  const rotation = 10\n  const end = endNorm\n    .rotateByDegrees(rotation)\n    .multiply(0.5 * dist)\n    .add(t)\n  return `translate(${end.x},${end.y})`\n}\n\nfunction reflexiveLinkTextTransform<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ center, config, node }: ReflexivePathParams<T, Node, Link>): string {\n  const { n, c } = calculateCenter({ center, config, node })\n  const diff = n.subtract(c)\n  const offset = diff\n    .multiply(1 / diff.length())\n    .multiply(3 * getNodeRadius(config, node) + 8)\n    .add(n)\n  return `translate(${offset.x},${offset.y})`\n}\n\n// ##################################################\n// EXPORT\n// ##################################################\n\nexport const Paths = {\n  line: {\n    labelTransform:\n      lineLinkTextTransform satisfies typeof lineLinkTextTransform as typeof lineLinkTextTransform,\n    path: paddedLinePath satisfies typeof paddedLinePath as typeof paddedLinePath,\n  },\n  arc: {\n    labelTransform:\n      bidirectionalLinkTextTransform satisfies typeof bidirectionalLinkTextTransform as typeof bidirectionalLinkTextTransform,\n    path: paddedArcPath satisfies typeof paddedArcPath as typeof paddedArcPath,\n  },\n  reflexive: {\n    labelTransform:\n      reflexiveLinkTextTransform satisfies typeof reflexiveLinkTextTransform as typeof reflexiveLinkTextTransform,\n    path: paddedReflexivePath satisfies typeof paddedReflexivePath as typeof paddedReflexivePath,\n  },\n}\n","import type { Vector } from 'vecti'\n\nimport type { GraphConfig } from '../config/config'\nimport type { Graph, NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport { Paths } from './paths'\nimport type { Canvas, LinkSelection } from './types'\nimport { getLinkId, getMarkerUrl } from './utils'\n\nexport function defineLinkSelection<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(canvas: Canvas): LinkSelection<T, Node, Link> {\n  return canvas.append('g').classed('links', true).selectAll('path')\n}\n\nexport interface CreateLinksParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly config: GraphConfig<T, Node, Link>\n  readonly graph: Graph<T, Node, Link>\n  readonly selection?: LinkSelection<T, Node, Link> | undefined\n  readonly showLabels: boolean\n}\n\nexport function createLinks<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({\n  config,\n  graph,\n  selection,\n  showLabels,\n}: CreateLinksParams<T, Node, Link>): LinkSelection<T, Node, Link> | undefined {\n  const result = selection\n    ?.data(graph.links, (d) => getLinkId(d))\n    .join((enter) => {\n      const linkGroup = enter.append('g')\n\n      const linkPath = linkGroup\n        .append('path')\n        .classed('link', true)\n        .style('marker-end', (d) => getMarkerUrl(d))\n        .style('stroke', (d) => d.color)\n\n      config.modifiers.link?.(linkPath)\n\n      const linkLabel = linkGroup\n        .append('text')\n        .classed('link__label', true)\n        .style('fill', (d) => (d.label ? d.label.color : null))\n        .style('font-size', (d) => (d.label ? d.label.fontSize : null))\n        .text((d) => (d.label ? d.label.text : null))\n\n      config.modifiers.linkLabel?.(linkLabel)\n\n      return linkGroup\n    })\n\n  result?.select('.link__label').attr('opacity', (d) => (d.label && showLabels ? 1 : 0))\n\n  return result\n}\n\nexport interface UpdateLinksParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly center: Vector\n  readonly config: GraphConfig<T, Node, Link>\n  readonly graph: Graph<T, Node, Link>\n  readonly selection: LinkSelection<T, Node, Link> | undefined\n}\n\nexport function updateLinks<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(params: UpdateLinksParams<T, Node, Link>): void {\n  updateLinkPaths(params)\n  updateLinkLabels(params)\n}\n\nfunction updateLinkPaths<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ center, config, graph, selection }: UpdateLinksParams<T, Node, Link>): void {\n  selection?.selectAll<SVGPathElement, Link>('path').attr('d', (d) => {\n    if (\n      d.source.x === undefined ||\n      d.source.y === undefined ||\n      d.target.x === undefined ||\n      d.target.y === undefined\n    ) {\n      return ''\n    }\n    if (d.source.id === d.target.id) {\n      return Paths.reflexive.path({\n        config,\n        node: d.source,\n        center,\n      })\n    } else if (areBidirectionallyConnected(graph, d.source, d.target)) {\n      return Paths.arc.path({ config, source: d.source, target: d.target })\n    } else {\n      return Paths.line.path({ config, source: d.source, target: d.target })\n    }\n  })\n}\n\nfunction updateLinkLabels<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ config, center, graph, selection }: UpdateLinksParams<T, Node, Link>): void {\n  selection?.select('.link__label').attr('transform', (d) => {\n    if (\n      d.source.x === undefined ||\n      d.source.y === undefined ||\n      d.target.x === undefined ||\n      d.target.y === undefined\n    ) {\n      return 'translate(0, 0)'\n    }\n    if (d.source.id === d.target.id) {\n      return Paths.reflexive.labelTransform({\n        config,\n        node: d.source,\n        center,\n      })\n    } else if (areBidirectionallyConnected(graph, d.source, d.target)) {\n      return Paths.arc.labelTransform({\n        config,\n        source: d.source,\n        target: d.target,\n      })\n    } else {\n      return Paths.line.labelTransform({\n        config,\n        source: d.source,\n        target: d.target,\n      })\n    }\n  })\n}\n\nfunction areBidirectionallyConnected<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(graph: Graph<T, Node, Link>, source: Node, target: Node): boolean {\n  return (\n    source.id !== target.id &&\n    graph.links.some((l) => l.target.id === source.id && l.source.id === target.id) &&\n    graph.links.some((l) => l.target.id === target.id && l.source.id === source.id)\n  )\n}\n","import type { GraphConfig } from '../config/config'\nimport type { Graph, NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport type { Canvas, MarkerSelection } from './types'\nimport { getMarkerId } from './utils'\n\nexport function defineMarkerSelection(canvas: Canvas): MarkerSelection {\n  return canvas.append('defs').selectAll('marker')\n}\n\nexport interface CreateMarkerParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly config: GraphConfig<T, Node, Link>\n  readonly graph: Graph<T, Node, Link>\n  readonly selection?: MarkerSelection | undefined\n}\n\nexport function createMarkers<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ config, graph, selection }: CreateMarkerParams<T, Node, Link>): MarkerSelection | undefined {\n  return selection\n    ?.data(getUniqueColors(graph), (d) => d)\n    .join((enter) => {\n      const marker = enter\n        .append('marker')\n        .attr('id', (d) => getMarkerId(d))\n        .attr('markerHeight', 4 * config.marker.size)\n        .attr('markerWidth', 4 * config.marker.size)\n        .attr('markerUnits', 'userSpaceOnUse')\n        .attr('orient', 'auto')\n        .attr('refX', config.marker.ref[0])\n        .attr('refY', config.marker.ref[1])\n        .attr('viewBox', config.marker.viewBox)\n        .style('fill', (d) => d)\n      marker.append('path').attr('d', makeLine(config.marker.path))\n      return marker\n    })\n}\n\nfunction getUniqueColors<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>(graph: Graph<T, Node, Link>): string[] {\n  return [...new Set(graph.links.map((link) => link.color))]\n}\n\nfunction makeLine(points: [number, number][]): string {\n  const [start, ...rest] = points\n  if (!start) {\n    return 'M0,0'\n  }\n  const [startX, startY] = start\n  return rest.reduce((line, [x, y]) => `${line}L${x},${y}`, `M${startX},${startY}`)\n}\n","import type { GraphConfig } from '../config/config'\nimport type { Graph, NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport type { Canvas, Drag, NodeSelection } from './types'\nimport { getNodeRadius, terminateEvent } from './utils'\n\nexport function defineNodeSelection<T extends NodeTypeToken, Node extends GraphNode<T>>(\n  canvas: Canvas,\n): NodeSelection<T, Node> {\n  return canvas.append('g').classed('nodes', true).selectAll('circle')\n}\n\nexport interface CreateNodesParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly config: GraphConfig<T, Node, Link>\n  readonly drag?: Drag<T, Node> | undefined\n  readonly graph: Graph<T, Node, Link>\n  readonly onNodeSelected: ((node: Node) => void) | undefined\n  readonly onNodeContext: (node: Node) => void\n  readonly selection?: NodeSelection<T, Node> | undefined\n  readonly showLabels: boolean\n}\n\nexport function createNodes<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({\n  config,\n  drag,\n  graph,\n  onNodeContext,\n  onNodeSelected,\n  selection,\n  showLabels,\n}: CreateNodesParams<T, Node, Link>): NodeSelection<T, Node> | undefined {\n  const result = selection\n    ?.data(graph.nodes, (d) => d.id)\n    .join((enter) => {\n      const nodeGroup = enter.append('g')\n\n      if (drag !== undefined) {\n        nodeGroup.call(drag)\n      }\n\n      const nodeCircle = nodeGroup\n        .append('circle')\n        .classed('node', true)\n        .attr('r', (d) => getNodeRadius(config, d))\n        .on('contextmenu', (event, d) => {\n          terminateEvent(event)\n          onNodeContext(d)\n        })\n        .on('pointerdown', (event: PointerEvent, d) =>\n          onPointerDown(event, d, onNodeSelected ?? onNodeContext),\n        )\n        .style('fill', (d) => d.color)\n\n      config.modifiers.node?.(nodeCircle)\n\n      const nodeLabel = nodeGroup\n        .append('text')\n        .classed('node__label', true)\n        .attr('dy', `0.33em`)\n        .style('fill', (d) => (d.label ? d.label.color : null))\n        .style('font-size', (d) => (d.label ? d.label.fontSize : null))\n        .style('stroke', 'none')\n        .text((d) => (d.label ? d.label.text : null))\n\n      config.modifiers.nodeLabel?.(nodeLabel)\n\n      return nodeGroup\n    })\n\n  result?.select('.node').classed('focused', (d) => d.isFocused)\n  result?.select('.node__label').attr('opacity', showLabels ? 1 : 0)\n\n  return result\n}\n\nconst DOUBLE_CLICK_INTERVAL_MS = 500\n\nfunction onPointerDown<T extends NodeTypeToken, Node extends GraphNode<T>>(\n  event: PointerEvent,\n  node: Node,\n  onNodeSelected: (node: Node) => void,\n): void {\n  if (event.button !== undefined && event.button !== 0) {\n    return\n  }\n\n  const lastInteractionTimestamp = node.lastInteractionTimestamp\n  const now = Date.now()\n  if (\n    lastInteractionTimestamp === undefined ||\n    now - lastInteractionTimestamp > DOUBLE_CLICK_INTERVAL_MS\n  ) {\n    node.lastInteractionTimestamp = now\n    return\n  }\n  node.lastInteractionTimestamp = undefined\n  onNodeSelected(node)\n}\n\nexport function updateNodes<T extends NodeTypeToken, Node extends GraphNode<T>>(\n  selection?: NodeSelection<T, Node>,\n): void {\n  selection?.attr('transform', (d) => `translate(${d.x ?? 0},${d.y ?? 0})`)\n}\n","import { forceCollide, forceLink, forceManyBody, forceSimulation, forceX, forceY } from 'd3-force'\nimport type { Vector } from 'vecti'\n\nimport type { GraphConfig } from '../config/config'\nimport type { Graph, NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport type { GraphSimulation } from './types'\nimport { getNodeRadius } from './utils'\n\nexport interface DefineSimulationParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly center: () => Vector\n  readonly config: GraphConfig<T, Node, Link>\n  readonly graph: Graph<T, Node, Link>\n  readonly onTick: () => void\n}\n\nexport function defineSimulation<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({\n  center,\n  config,\n  graph,\n  onTick,\n}: DefineSimulationParams<T, Node, Link>): GraphSimulation<T, Node, Link> {\n  const simulation = forceSimulation<Node, Link>(graph.nodes)\n\n  const centeringForce = config.simulation.forces.centering\n  if (centeringForce && centeringForce.enabled) {\n    const strength = centeringForce.strength\n    simulation\n      .force('x', forceX<Node>(() => center().x).strength(strength))\n      .force('y', forceY<Node>(() => center().y).strength(strength))\n  }\n\n  const chargeForce = config.simulation.forces.charge\n  if (chargeForce && chargeForce.enabled) {\n    simulation.force('charge', forceManyBody<Node>().strength(chargeForce.strength))\n  }\n\n  const collisionForce = config.simulation.forces.collision\n  if (collisionForce && collisionForce.enabled) {\n    simulation.force(\n      'collision',\n      forceCollide<Node>().radius(\n        (d) => collisionForce.radiusMultiplier * getNodeRadius(config, d),\n      ),\n    )\n  }\n\n  const linkForce = config.simulation.forces.link\n  if (linkForce && linkForce.enabled) {\n    simulation.force(\n      'link',\n      forceLink<Node, Link>(graph.links)\n        .id((d) => d.id)\n        .distance(config.simulation.forces.link.length)\n        .strength(linkForce.strength),\n    )\n  }\n\n  simulation.on('tick', () => onTick())\n\n  config.modifiers.simulation?.(simulation)\n\n  return simulation\n}\n","import type { Selection } from 'd3-selection'\nimport type { D3ZoomEvent } from 'd3-zoom'\nimport { zoom } from 'd3-zoom'\n\nimport type { GraphConfig } from '../config/config'\nimport type { NodeTypeToken } from '../model/graph'\nimport type { GraphLink } from '../model/link'\nimport type { GraphNode } from '../model/node'\nimport type { Zoom } from './types'\n\nexport interface DefineZoomParams<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n> {\n  readonly canvasContainer: () => Selection<SVGSVGElement, unknown, null, undefined>\n  readonly config: GraphConfig<T, Node, Link>\n  readonly min: number\n  readonly max: number\n  readonly onZoom: (event: D3ZoomEvent<SVGSVGElement, undefined>) => void\n}\n\nexport function defineZoom<\n  T extends NodeTypeToken,\n  Node extends GraphNode<T>,\n  Link extends GraphLink<T, Node>,\n>({ canvasContainer, config, min, max, onZoom }: DefineZoomParams<T, Node, Link>): Zoom {\n  const z = zoom<SVGSVGElement, undefined>()\n    .scaleExtent([min, max])\n    .filter((event) => event.button === 0 || event.touches?.length >= 2)\n    .on('start', () => canvasContainer().classed('grabbed', true))\n    .on('zoom', (event) => onZoom(event))\n    .on('end', () => canvasContainer().classed('grabbed', false))\n\n  config.modifiers.zoom?.(z)\n\n  return z\n}\n","import { debounce } from '@yeger/debounce'\nimport { select } from 'd3-selection'\nimport type { D3ZoomEvent } from 'd3-zoom'\nimport { Vector } from 'vecti'\n\nimport type { GraphConfig } from './config/config'\nimport type { LinkFilter } from './config/filter'\nimport { defineCanvas, updateCanvasTransform } from './lib/canvas'\nimport { defineDrag } from './lib/drag'\nimport { filterGraph } from './lib/filter'\nimport { createLinks, defineLinkSelection, updateLinks } from './lib/link'\nimport { createMarkers, defineMarkerSelection } from './lib/marker'\nimport { createNodes, defineNodeSelection, updateNodes } from './lib/node'\nimport { defineSimulation } from './lib/simulation'\nimport type {\n  Canvas,\n  Drag,\n  GraphSimulation,\n  LinkSelection,\n  MarkerSelection,\n  NodeSelection,\n  Zoom,\n} from './lib/types'\nimport { isNumber } from './lib/utils'\nimport { defineZoom } from './lib/zoom'\nimport type { Graph, NodeTypeToken } from './model/graph'\nimport type { GraphLink } from './model/link'\nimport type { GraphNode } from './model/node'\n\n/**\n * Controller for a graph view.\n */\nexport class GraphController<\n  T extends NodeTypeToken = NodeTypeToken,\n  Node extends GraphNode<T> = GraphNode<T>,\n  Link extends GraphLink<T, Node> = GraphLink<T, Node>,\n> {\n  /**\n   * Array of all node types included in the controller's graph.\n   */\n  public readonly nodeTypes: T[]\n  private _nodeTypeFilter: T[]\n  private _includeUnlinked = true\n\n  private _linkFilter: LinkFilter<T, Node, Link> = () => true\n\n  private _showLinkLabels = true\n  private _showNodeLabels = true\n\n  private filteredGraph!: Graph<T, Node, Link>\n\n  private width = 0\n  private height = 0\n\n  private simulation: GraphSimulation<T, Node, Link> | undefined\n\n  private canvas: Canvas | undefined\n  private linkSelection: LinkSelection<T, Node, Link> | undefined\n  private nodeSelection: NodeSelection<T, Node> | undefined\n  private markerSelection: MarkerSelection | undefined\n\n  private zoom: Zoom | undefined\n  private drag: Drag<T, Node> | undefined\n\n  private xOffset = 0\n  private yOffset = 0\n  private scale: number\n\n  private focusedNode: Node | undefined = undefined\n\n  private resizeObserver?: ResizeObserver\n\n  private readonly container: HTMLDivElement\n  private readonly graph: Graph<T, Node, Link>\n  private readonly config: GraphConfig<T, Node, Link>\n\n  /**\n   * Create a new controller and initialize the view.\n   * @param container - The container the graph will be placed in.\n   * @param graph - The graph of the controller.\n   * @param config - The config of the controller.\n   */\n  public constructor(\n    container: HTMLDivElement,\n    graph: Graph<T, Node, Link>,\n    config: GraphConfig<T, Node, Link>,\n  ) {\n    this.container = container\n    this.graph = graph\n    this.config = config\n\n    this.scale = config.zoom.initial\n\n    this.resetView()\n\n    this.graph.nodes.forEach((node) => {\n      const [x, y] = config.positionInitializer(node, this.effectiveWidth, this.effectiveHeight)\n      node.x = node.x ?? x\n      node.y = node.y ?? y\n    })\n\n    this.nodeTypes = [...new Set(graph.nodes.map((d) => d.type))]\n    this._nodeTypeFilter = [...this.nodeTypes]\n\n    if (config.initial) {\n      const { includeUnlinked, nodeTypeFilter, linkFilter, showLinkLabels, showNodeLabels } =\n        config.initial\n      this._includeUnlinked = includeUnlinked ?? this._includeUnlinked\n      this._showLinkLabels = showLinkLabels ?? this._showLinkLabels\n      this._showNodeLabels = showNodeLabels ?? this._showNodeLabels\n      this._nodeTypeFilter = nodeTypeFilter ?? this._nodeTypeFilter\n      this._linkFilter = linkFilter ?? this._linkFilter\n    }\n\n    this.filterGraph(undefined)\n    this.initGraph()\n    this.restart(config.simulation.alphas.initialize)\n\n    if (config.autoResize) {\n      this.resizeObserver = new ResizeObserver(debounce(() => this.resize()))\n      this.resizeObserver.observe(this.container)\n    }\n  }\n\n  /**\n   * Get the current node type filter.\n   * Only nodes whose type is included will be shown.\n   */\n  public get nodeTypeFilter(): T[] {\n    return this._nodeTypeFilter\n  }\n\n  /**\n   * Get whether nodes without incoming or outgoing links will be shown or not.\n   */\n  public get includeUnlinked(): boolean {\n    return this._includeUnlinked\n  }\n\n  /**\n   * Set whether nodes without incoming or outgoing links will be shown or not.\n   * @param value - The value.\n   */\n  public set includeUnlinked(value: boolean) {\n    this._includeUnlinked = value\n    this.filterGraph(this.focusedNode)\n    const { include, exclude } = this.config.simulation.alphas.filter.unlinked\n    const alpha = value ? include : exclude\n    this.restart(alpha)\n  }\n\n  /**\n   * Set a new link filter and update the controller's state.\n   * @param value - The new link filter.\n   */\n  public set linkFilter(value: LinkFilter<T, Node, Link>) {\n    this._linkFilter = value\n    this.filterGraph(this.focusedNode)\n    this.restart(this.config.simulation.alphas.filter.link)\n  }\n\n  /**\n   * Get the current link filter.\n   * @returns - The current link filter.\n   */\n  public get linkFilter(): LinkFilter<T, Node, Link> {\n    return this._linkFilter\n  }\n\n  /**\n   * Get whether node labels are shown or not.\n   */\n  public get showNodeLabels(): boolean {\n    return this._showNodeLabels\n  }\n\n  /**\n   * Set whether node labels will be shown or not.\n   * @param value - The value.\n   */\n  public set showNodeLabels(value: boolean) {\n    this._showNodeLabels = value\n    const { hide, show } = this.config.simulation.alphas.labels.nodes\n    const alpha = value ? show : hide\n    this.restart(alpha)\n  }\n\n  /**\n   * Get whether link labels are shown or not.\n   */\n  public get showLinkLabels(): boolean {\n    return this._showLinkLabels\n  }\n\n  /**\n   * Set whether link labels will be shown or not.\n   * @param value - The value.\n   */\n  public set showLinkLabels(value: boolean) {\n    this._showLinkLabels = value\n    const { hide, show } = this.config.simulation.alphas.labels.links\n    const alpha = value ? show : hide\n    this.restart(alpha)\n  }\n\n  private get effectiveWidth(): number {\n    return this.width / this.scale\n  }\n\n  private get effectiveHeight(): number {\n    return this.height / this.scale\n  }\n\n  private get effectiveCenter(): Vector {\n    return Vector.of([this.width, this.height])\n      .divide(2)\n      .subtract(Vector.of([this.xOffset, this.yOffset]))\n      .divide(this.scale)\n  }\n\n  /**\n   * Resize the graph to fit its container.\n   */\n  public resize(): void {\n    const oldWidth = this.width\n    const oldHeight = this.height\n    const newWidth = this.container.getBoundingClientRect().width\n    const newHeight = this.container.getBoundingClientRect().height\n    const widthDiffers = oldWidth.toFixed() !== newWidth.toFixed()\n    const heightDiffers = oldHeight.toFixed() !== newHeight.toFixed()\n\n    if (!widthDiffers && !heightDiffers) {\n      return\n    }\n\n    this.width = this.container.getBoundingClientRect().width\n    this.height = this.container.getBoundingClientRect().height\n\n    const alpha = this.config.simulation.alphas.resize\n\n    this.restart(isNumber(alpha) ? alpha : alpha({ oldWidth, oldHeight, newWidth, newHeight }))\n  }\n\n  /**\n   * Restart the controller.\n   * @param alpha - The alpha value of the controller's simulation after the restart.\n   */\n  public restart(alpha: number): void {\n    this.markerSelection = createMarkers({\n      config: this.config,\n      graph: this.filteredGraph,\n      selection: this.markerSelection,\n    })\n\n    this.linkSelection = createLinks({\n      config: this.config,\n      graph: this.filteredGraph,\n      selection: this.linkSelection,\n      showLabels: this._showLinkLabels,\n    })\n\n    this.nodeSelection = createNodes({\n      config: this.config,\n      drag: this.drag,\n      graph: this.filteredGraph,\n      onNodeContext: (d) => this.toggleNodeFocus(d),\n      onNodeSelected: this.config.callbacks.nodeClicked,\n      selection: this.nodeSelection,\n      showLabels: this._showNodeLabels,\n    })\n\n    this.simulation?.stop()\n    this.simulation = defineSimulation({\n      center: () => this.effectiveCenter,\n      config: this.config,\n      graph: this.filteredGraph,\n      onTick: () => this.onTick(),\n    })\n      .alpha(alpha)\n      .restart()\n  }\n\n  /**\n   * Update the node type filter by either including or removing the specified type from the filter.\n   * @param include - Whether the type will be included or removed from the filter.\n   * @param nodeType - The type to be added or removed from the filter.\n   */\n  public filterNodesByType(include: boolean, nodeType: T): void {\n    if (include) {\n      this._nodeTypeFilter.push(nodeType)\n    } else {\n      this._nodeTypeFilter = this._nodeTypeFilter.filter((type) => type !== nodeType)\n    }\n    this.filterGraph(this.focusedNode)\n    this.restart(this.config.simulation.alphas.filter.type)\n  }\n\n  /**\n   * Shut down the controller's simulation and (optional) automatic resizing.\n   */\n  public shutdown(): void {\n    if (this.focusedNode !== undefined) {\n      this.focusedNode.isFocused = false\n      this.focusedNode = undefined\n    }\n    this.resizeObserver?.unobserve(this.container)\n    this.simulation?.stop()\n  }\n\n  private initGraph(): void {\n    this.zoom = defineZoom({\n      config: this.config,\n      canvasContainer: () => select(this.container).select('svg'),\n      min: this.config.zoom.min,\n      max: this.config.zoom.max,\n      onZoom: (event) => this.onZoom(event),\n    })\n    this.canvas = defineCanvas({\n      applyZoom: this.scale !== 1,\n      container: select(this.container),\n      offset: [this.xOffset, this.yOffset],\n      scale: this.scale,\n      zoom: this.zoom,\n    })\n    this.applyZoom()\n    this.linkSelection = defineLinkSelection(this.canvas)\n    this.nodeSelection = defineNodeSelection(this.canvas)\n    this.markerSelection = defineMarkerSelection(this.canvas)\n    this.drag = defineDrag({\n      config: this.config,\n      onDragStart: () =>\n        this.simulation?.alphaTarget(this.config.simulation.alphas.drag.start).restart(),\n      onDragEnd: () =>\n        this.simulation?.alphaTarget(this.config.simulation.alphas.drag.end).restart(),\n    })\n  }\n\n  private onTick(): void {\n    updateNodes(this.nodeSelection)\n\n    updateLinks({\n      config: this.config,\n      center: this.effectiveCenter,\n      graph: this.filteredGraph,\n      selection: this.linkSelection,\n    })\n  }\n\n  private resetView(): void {\n    this.simulation?.stop()\n    select(this.container).selectChildren().remove()\n    this.zoom = undefined\n    this.canvas = undefined\n    this.linkSelection = undefined\n    this.nodeSelection = undefined\n    this.markerSelection = undefined\n    this.simulation = undefined\n    this.width = this.container.getBoundingClientRect().width\n    this.height = this.container.getBoundingClientRect().height\n  }\n\n  private onZoom(event: D3ZoomEvent<SVGSVGElement, undefined>): void {\n    this.xOffset = event.transform.x\n    this.yOffset = event.transform.y\n    this.scale = event.transform.k\n    this.applyZoom()\n    this.config.hooks.afterZoom?.(this.scale, this.xOffset, this.yOffset)\n    this.simulation?.restart()\n  }\n\n  private applyZoom() {\n    updateCanvasTransform({\n      canvas: this.canvas,\n      scale: this.scale,\n      xOffset: this.xOffset,\n      yOffset: this.yOffset,\n    })\n  }\n\n  private toggleNodeFocus(node: Node): void {\n    if (node.isFocused) {\n      this.filterGraph(undefined)\n      this.restart(this.config.simulation.alphas.focus.release(node))\n    } else {\n      this.focusNode(node)\n    }\n  }\n\n  private focusNode(node: Node): void {\n    this.filterGraph(node)\n    this.restart(this.config.simulation.alphas.focus.acquire(node))\n  }\n\n  private filterGraph(nodeToFocus?: Node): void {\n    if (this.focusedNode !== undefined) {\n      this.focusedNode.isFocused = false\n      this.focusedNode = undefined\n    }\n\n    if (nodeToFocus !== undefined && this._nodeTypeFilter.includes(nodeToFocus.type)) {\n      nodeToFocus.isFocused = true\n      this.focusedNode = nodeToFocus\n    }\n\n    this.filteredGraph = filterGraph({\n      graph: this.graph,\n      filter: this._nodeTypeFilter,\n      focusedNode: this.focusedNode,\n      includeUnlinked: this._includeUnlinked,\n      linkFilter: this._linkFilter,\n    })\n  }\n}\n","import type { GraphLink } from './link'\nimport type { GraphNode } from './node'\n\n/**\n * Type token for nodes.\n */\nexport type NodeTypeToken = string\n\n/**\n * Graph containing nodes and links.\n */\nexport interface Graph<\n  T extends NodeTypeToken = NodeTypeToken,\n  Node extends GraphNode<T> = GraphNode<T>,\n  Link extends GraphLink<T, Node> = GraphLink<T, Node>,\n> {\n  /**\n   * The nodes of the graph.\n   */\n  readonly nodes: Node[]\n  /**\n   * The links of the graph.\n   */\n  readonly links: Link[]\n}\n\n/**\n * Define a graph with type inference.\n * @param data - The nodes and links of the graph. If either are omitted, they default to an empty array.\n */\nexport function defineGraph<\n  T extends NodeTypeToken = NodeTypeToken,\n  Node extends GraphNode<T> = GraphNode<T>,\n  Link extends GraphLink<T, Node> = GraphLink<T, Node>,\n>({ nodes, links }: Partial<Graph<T, Node, Link>>): Graph<T, Node, Link> {\n  return {\n    nodes: nodes ?? ([] as Node[]),\n    links: links ?? ([] as Link[]),\n  }\n}\n","import type { SimulationLinkDatum } from 'd3-force'\n\nimport type { NodeTypeToken } from './graph'\nimport type { GraphNode } from './node'\nimport type { Label } from './shared'\n\n/**\n * Link defining an edge from one node to another.\n */\nexport interface GraphLink<\n  T extends NodeTypeToken = NodeTypeToken,\n  SourceNode extends GraphNode<T> = GraphNode<T>,\n  TargetNode extends GraphNode<T> = SourceNode,\n> extends SimulationLinkDatum<SourceNode | TargetNode> {\n  /**\n   * The source node of the link.\n   */\n  readonly source: SourceNode\n  /**\n   * The target node of the link\n   */\n  readonly target: TargetNode\n  /**\n   * The color of the link.\n   * Can be any valid CSS expression.\n   */\n  readonly color: string\n  /**\n   * The label of the node.\n   * Using false will disable the node's label.\n   */\n  readonly label: false | Label\n}\n\n/**\n * Define a link with type inference.\n * @param data - The data of the link.\n */\nexport function defineLink<\n  T extends NodeTypeToken = NodeTypeToken,\n  SourceNode extends GraphNode<T> = GraphNode<T>,\n  TargetNode extends GraphNode<T> = SourceNode,\n  Link extends GraphLink<T, SourceNode, TargetNode> = GraphLink<T, SourceNode, TargetNode>,\n>(data: Link): Link {\n  return {\n    ...data,\n  }\n}\n","import type { SimulationNodeDatum } from 'd3-force'\n\nimport type { NodeTypeToken } from './graph'\nimport type { Label } from './shared'\n\n/**\n * Node representing a datum of a graph.\n */\nexport interface GraphNode<T extends NodeTypeToken = NodeTypeToken> extends SimulationNodeDatum {\n  /**\n   * The type of the node.\n   */\n  readonly type: T\n  /**\n   * The ID of the node.\n   */\n  readonly id: string\n  /**\n   * The color of the node.\n   * Can be any valid CSS expression.\n   */\n  readonly color: string\n  /**\n   * The label of the node.\n   * Using false will disable the node's label.\n   */\n  readonly label: false | Label\n  /**\n   * The focus state of a node.\n   * Warning: Used for internal logic. Should not be set manually!\n   */\n  isFocused: boolean\n  /**\n   * The x-coordinate of a node.\n   */\n  x?: number | undefined\n  /**\n   * The y-coordinate of a node.\n   */\n  y?: number | undefined\n  /**\n   * The fixed x-coordinate of a node.\n   * If set, the node will not be simulated.\n   */\n  fx?: number | undefined\n  /**\n   * The fixed y-coordinate of a node.\n   * If set, the node will not be simulated.\n   */\n  fy?: number | undefined\n  /**\n   * Timestamp of the node's last interaction.\n   * Warning: Used for internal logic. Should not be set manually!\n   */\n  lastInteractionTimestamp?: number | undefined\n}\n\n/**\n * Define a node with type inference.\n * @param data - The data of the node.\n */\nexport function defineNode<\n  T extends NodeTypeToken = NodeTypeToken,\n  Node extends GraphNode<T> = GraphNode<T>,\n>(data: Node): Node {\n  return {\n    ...data,\n    isFocused: false,\n    lastInteractionTimestamp: undefined,\n  }\n}\n\nconst nodeDefaults: Omit<GraphNode, 'id' | 'type'> = {\n  color: 'lightgray',\n  label: {\n    color: 'black',\n    fontSize: '1rem',\n    text: '',\n  },\n  isFocused: false,\n}\n\n/**\n * Define a node with type inference and some default values.\n * @param data - The data of the node.\n */\nexport function defineNodeWithDefaults<T extends NodeTypeToken = NodeTypeToken>(\n  data: Partial<GraphNode<T>> & Pick<GraphNode, 'id' | 'type'>,\n): GraphNode<T> {\n  return defineNode<T>({\n    ...nodeDefaults,\n    ...data,\n  })\n}\n"],"mappings":"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"}