@3plate/graph-core 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -27
- package/dist/index.cjs +13 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +20 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/graph/graph.ts","../src/graph/node.ts","../src/log.ts","../src/graph/edge.ts","../src/graph/seg.ts","../src/graph/layer.ts","../src/graph/mutator.ts","../src/graph/services/cycles.ts","../src/graph/services/dummy.ts","../src/graph/services/layers.ts","../src/graph/services/layout.ts","../src/canvas/marker.tsx","../src/graph/services/lines.ts","../src/common.ts","../src/canvas/node.tsx","../src/canvas/seg.tsx","../src/canvas/editMode.ts","../src/canvas/newEdge.tsx","../src/canvas/modal.tsx","../src/canvas/styles.css","../src/canvas/canvas.tsx","../src/canvas/render-node.tsx","../src/api/defaults.ts","../src/api/updater.ts","../src/api/ingest.ts","../src/api/sources/WebSocketSource.ts","../src/api/sources/FileSource.ts","../src/api/sources/FileSystemSource.ts","../src/api/api.ts","../src/playground/styles.css","../src/playground/playground.ts"],"sourcesContent":["import { API } from './api/api'\nimport { APIArguments } from './api/options'\n\nexport async function graph<N, E>(args: APIArguments<N, E> = { root: 'app' }) {\n const api = new API<N, E>(args)\n await api.init()\n return api\n}\n\nexport default graph\n\nexport * from './api/ingest'\nexport * from './api/sources/WebSocketSource'\nexport * from './api/sources/FileSystemSource'\nexport * from './api/sources/FileSource'\nexport * from './playground'\n\n// Export API types\nexport type { API } from './api/api'\nexport type {\n APIArguments,\n APIOptions,\n Update,\n IngestionConfig,\n EventsOptions,\n // Callback parameter types\n NewNode,\n NewEdge,\n NodeProps,\n EdgeProps,\n PortProps,\n RenderNode,\n // Theming types\n ColorMode,\n ThemeVars,\n CanvasTheme,\n NodeTheme,\n PortTheme,\n EdgeTheme,\n} from './api/options'\nexport { Updater } from './api/updater'\n\n// Export common types\nexport type { Orientation, NodeAlign, PortStyle } from './common'\n","import { Map as IMap, List as IList, Set as ISet } from 'immutable'\nimport { Dims, Pos } from '../common'\nimport { GraphOptions } from '../api/options'\nimport { Node, NodeId, PublicNodeData } from './node'\nimport { Edge, EdgeId, PublicEdgeData } from './edge'\nimport { Seg, SegId } from './seg'\nimport { Layer, LayerId } from './layer'\nimport { Mutator } from './mutator'\nimport { Cycles } from './services/cycles'\nimport { Dummy } from './services/dummy'\nimport { Layers } from './services/layers'\nimport { Layout } from './services/layout'\nimport { Lines } from './services/lines'\nimport { logger } from '../log'\n\nconst log = logger('graph')\n\ntype GraphArgs = {\n changes?: Changes\n options?: Required<GraphOptions>\n prior?: Graph\n}\n\nexport type Changes = {\n addedNodes: PublicNodeData[],\n removedNodes: { id: string }[],\n updatedNodes: PublicNodeData[],\n addedEdges: PublicEdgeData[],\n removedEdges: { id: string }[],\n updatedEdges: PublicEdgeData[],\n description?: string,\n}\n\nconst emptyChanges: Changes = {\n addedNodes: [],\n removedNodes: [],\n updatedNodes: [],\n addedEdges: [],\n removedEdges: [],\n updatedEdges: [],\n}\n\nexport class Graph {\n prior?: Graph\n nodes!: IMap<NodeId, Node>\n edges!: IMap<EdgeId, Edge>\n segs!: IMap<SegId, Seg>\n layers!: IMap<LayerId, Layer>\n layerList!: IList<LayerId>\n nextLayerId!: number\n nextDummyId!: number\n options: Required<GraphOptions>\n changes: Changes\n\n dirtyNodes!: Set<NodeId>\n dirtyEdges!: Set<EdgeId>\n dirtyLayers!: Set<LayerId>\n dirtySegs!: Set<SegId>\n dirty!: boolean\n\n delNodes!: Set<NodeId>\n delEdges!: Set<EdgeId>\n delSegs!: Set<SegId>\n\n r: boolean\n v: boolean\n n: boolean\n h: keyof Dims\n w: keyof Dims\n x: keyof Pos\n y: keyof Pos\n d: Pos\n\n constructor({ prior, changes, options }: GraphArgs) {\n this.options = prior?.options ?? options!\n this.changes = changes ?? emptyChanges\n this.initFromPrior(prior)\n\n // Set orientation-based properties\n this.r = this.options.orientation === 'BT' || this.options.orientation === 'RL'\n this.v = this.options.orientation === 'TB' || this.options.orientation === 'BT'\n this.h = this.v ? 'h' : 'w'\n this.w = this.v ? 'w' : 'h'\n this.x = this.v ? 'x' : 'y'\n this.y = this.v ? 'y' : 'x'\n this.d = {\n x: this.v ? 0 : (this.r ? -1 : 1),\n y: this.v ? (this.r ? -1 : 1) : 0,\n }\n\n // n means the node alignment follows the natural orientation\n // For each orientation, we map it to the corresponding alignment\n const natAligns = { TB: 'top', BT: 'bottom', LR: 'left', RL: 'right' };\n if (this.options.nodeAlign == 'natural')\n this.n = true\n else\n this.n = natAligns[this.options.orientation] == this.options.nodeAlign\n\n if (this.dirty) this.processUpdate()\n }\n\n processUpdate() {\n try {\n this.beginMutate()\n this.applyChanges()\n Cycles.checkCycles(this)\n Layers.updateLayers(this)\n /* debug removed */\n Dummy.updateDummies(this)\n Dummy.mergeDummies(this)\n Layout.positionNodes(this)\n Layout.alignAll(this)\n Lines.trackEdges(this)\n Layout.getCoords(this)\n Lines.pathEdges(this)\n } catch (e) {\n this.initFromPrior(this.prior)\n throw e\n } finally {\n this.endMutate()\n }\n }\n\n applyChanges() {\n for (const edge of this.changes.removedEdges)\n Edge.del(this, edge)\n for (const node of this.changes.removedNodes)\n Node.del(this, node)\n for (const node of this.changes.addedNodes)\n Node.addNormal(this, node)\n for (const edge of this.changes.addedEdges)\n Edge.add(this, edge)\n for (const node of this.changes.updatedNodes)\n Node.update(this, node)\n for (const edge of this.changes.updatedEdges)\n Edge.update(this, edge)\n }\n\n layerAt(index: number): Layer {\n while (index >= this.layerList.size)\n this.addLayer()\n const layerId = this.layerList.get(index)!\n return this.getLayer(layerId)\n }\n\n private addLayer() {\n const id = `${Layer.prefix}${this.nextLayerId++}`\n this.layers.set(id, new Layer({\n id,\n index: this.layerList.size,\n nodeIds: ISet()\n }))\n this.layerList.push(id)\n this.dirtyLayers.add(id)\n }\n\n isEdgeId(id: string): boolean {\n return id.startsWith(Edge.prefix)\n }\n\n isSegId(id: string): boolean {\n return id.startsWith(Seg.prefix)\n }\n\n getNode(nodeId: NodeId): Node {\n const node = this.nodes.get(nodeId)\n if (!node) throw new Error(`cannot find node ${nodeId}`)\n return node\n }\n\n getEdge(edgeId: EdgeId): Edge {\n const edge = this.edges.get(edgeId)\n if (!edge) throw new Error(`cannot find edge ${edgeId}`)\n return edge\n }\n\n getSeg(segId: SegId): Seg {\n const seg = this.segs.get(segId)\n if (!seg) throw new Error(`cannot find seg ${segId}`)\n return seg\n }\n\n getLayer(layerId: LayerId): Layer {\n const layer = this.layers.get(layerId)\n if (!layer) throw new Error(`cannot find layer ${layerId}`)\n return layer\n }\n\n layerIndex(nodeId: NodeId): number {\n return this.getNode(nodeId).layerIndex(this)\n }\n\n getRel(relId: EdgeId | SegId): Edge | Seg {\n return this.isSegId(relId)\n ? this.getSeg(relId)\n : this.getEdge(relId)\n }\n\n * getNodes(includeDummy: boolean = false): Generator<Node> {\n const gen = this.nodes.values()\n for (const node of this.nodes.values())\n if (includeDummy || !node.isDummy)\n yield node\n }\n\n * getEdges(): Generator<Edge> {\n yield* this.edges.values()\n }\n\n * getSegs(): Generator<Seg> {\n yield* this.segs.values()\n }\n\n withMutations(callback: (mut: Mutator) => void): Graph {\n const mut = new Mutator()\n callback(mut)\n return new Graph({ prior: this, changes: mut.changes })\n }\n\n addNode(node: PublicNodeData) {\n return this.withMutations(mutator => {\n mutator.addNode(node)\n })\n }\n\n addNodes(...nodes: PublicNodeData[]) {\n return this.withMutations(mutator => {\n nodes.forEach(node => mutator.addNode(node))\n })\n }\n\n removeNodes(...nodes: { id: string }[]) {\n return this.withMutations(mutator => {\n nodes.forEach(node => mutator.removeNode(node))\n })\n }\n\n removeNode(node: { id: string }) {\n return this.withMutations(mutator => {\n mutator.removeNode(node)\n })\n }\n\n addEdges(...edges: PublicEdgeData[]) {\n return this.withMutations(mutator => {\n edges.forEach(edge => mutator.addEdge(edge))\n })\n }\n\n addEdge(edge: PublicEdgeData) {\n return this.withMutations(mutator => {\n mutator.addEdge(edge)\n })\n }\n\n removeEdges(...edges: PublicEdgeData[]) {\n return this.withMutations(mutator => {\n edges.forEach(edge => mutator.removeEdge(edge))\n })\n }\n\n removeEdge(edge: PublicEdgeData) {\n return this.withMutations(mutator => {\n mutator.removeEdge(edge)\n })\n }\n\n mutateNode(node: Node): Node {\n if (node.mutable) return node\n node = node.asMutable().set('mutable', true)\n this.nodes.set(node.id, node)\n this.dirtyNodes.add(node.id)\n return node\n }\n\n mutateEdge(edge: Edge): Edge {\n if (edge.mutable) return edge\n edge = edge.asMutable().set('mutable', true)\n this.edges.set(edge.id, edge)\n this.dirtyEdges.add(edge.id)\n return edge\n }\n\n mutateLayer(layer: Layer): Layer {\n if (layer.mutable) return layer\n layer = layer.asMutable().set('mutable', true)\n this.layers.set(layer.id, layer)\n this.dirtyLayers.add(layer.id)\n return layer\n }\n\n mutateSeg(seg: Seg): Seg {\n if (seg.mutable) return seg\n seg = seg.asMutable().set('mutable', true)\n this.segs.set(seg.id, seg)\n this.dirtySegs.add(seg.id)\n return seg\n }\n\n private initFromPrior(prior?: Graph) {\n this.nodes = prior?.nodes ?? IMap()\n this.edges = prior?.edges ?? IMap()\n this.layers = prior?.layers ?? IMap()\n this.layerList = prior?.layerList ?? IList()\n this.segs = prior?.segs ?? IMap()\n this.nextLayerId = prior?.nextLayerId ?? 0\n this.nextDummyId = prior?.nextDummyId ?? 0\n this.prior = prior\n this.dirtyNodes = new Set()\n this.dirtyEdges = new Set()\n this.dirtyLayers = new Set()\n this.dirtySegs = new Set()\n this.delNodes = new Set()\n this.delEdges = new Set()\n this.delSegs = new Set()\n this.dirty =\n this.changes.addedNodes.length > 0 ||\n this.changes.removedNodes.length > 0 ||\n this.changes.updatedNodes.length > 0 ||\n this.changes.addedEdges.length > 0 ||\n this.changes.removedEdges.length > 0\n }\n\n private beginMutate() {\n this.nodes = this.nodes.asMutable()\n this.edges = this.edges.asMutable()\n this.layers = this.layers.asMutable()\n this.layerList = this.layerList.asMutable()\n this.segs = this.segs.asMutable()\n }\n\n private endMutate() {\n for (const nodeId of this.dirtyNodes)\n if (this.nodes.has(nodeId))\n this.nodes.set(nodeId, this.nodes.get(nodeId)!.final())\n for (const edgeId of this.dirtyEdges)\n if (this.edges.has(edgeId))\n this.edges.set(edgeId, this.edges.get(edgeId)!.final())\n for (const segId of this.dirtySegs)\n if (this.segs.has(segId))\n this.segs.set(segId, this.segs.get(segId)!.final())\n for (const layerId of this.dirtyLayers)\n if (this.layers.has(layerId))\n this.layers.set(layerId, this.layers.get(layerId)!.final())\n this.nodes = this.nodes.asImmutable()\n this.edges = this.edges.asImmutable()\n this.layers = this.layers.asImmutable()\n this.layerList = this.layerList.asImmutable()\n this.segs = this.segs.asImmutable()\n }\n\n}\n","import { Record, Set as ISet } from 'immutable'\nimport { LayerId } from './layer'\nimport { EdgeId, Edge } from './edge'\nimport { SegId, Seg } from './seg'\nimport { Dir, Side, Dims, Pos, LinkType } from '../common'\nimport { NodeStyle, RenderNode } from '../api/options'\nimport { Graph } from './graph'\nimport { Layer } from './layer'\nimport { logger } from '../log'\n\nconst log = logger('node')\n\nexport type NodeId = string\nexport type PortId = string\nexport type NodeKey = string\n\nexport type PortData = {\n id: string,\n label?: string,\n offset?: number,\n size?: number,\n}\n\nexport type PublicNodeData = {\n id: NodeId,\n data: any,\n version: number,\n title?: string\n text?: string\n type?: string\n ports: { in?: PortData[], out?: PortData[] }\n render?: RenderNode<any>\n dims?: Dims\n}\n\ntype NodeData = PublicNodeData & {\n aligned: { in?: NodeId, out?: NodeId }\n edges: { in: ISet<EdgeId>, out: ISet<EdgeId> }\n segs: { in: ISet<SegId>, out: ISet<SegId> }\n layerId: LayerId\n isDummy: boolean\n isMerged: boolean\n edgeIds: EdgeId[]\n index?: number\n pos?: Pos\n lpos?: number\n mutable: boolean\n}\n\nconst defNodeData: NodeData = {\n id: '',\n data: undefined,\n version: 0,\n title: undefined,\n text: undefined,\n type: undefined,\n render: undefined,\n ports: {},\n aligned: {},\n edges: { in: ISet(), out: ISet() },\n segs: { in: ISet(), out: ISet() },\n layerId: '',\n isDummy: false,\n isMerged: false,\n edgeIds: [],\n index: undefined,\n pos: undefined,\n lpos: undefined,\n dims: undefined,\n mutable: false,\n}\n\nexport class Node extends Record(defNodeData) {\n static dummyPrefix = 'd:'\n\n // get edgeId(): EdgeId {\n // if (!this.isDummy)\n // throw new Error(`node ${this.id} is not a dummy`)\n // if (this.isMerged)\n // throw new Error(`node ${this.id} is merged`)\n // return this.get('edgeIds')[0]\n // }\n\n // get edgeIds(): EdgeId[] {\n // if (!this.isDummy)\n // throw new Error(`node ${this.id} is not a dummy`)\n // if (!this.isMerged)\n // throw new Error(`node ${this.id} is not merged`)\n // return this.get('edgeIds')\n // }\n\n get key(): NodeKey {\n return this.isDummy ? this.id : Node.key(this)\n }\n\n static key(node: PublicNodeData): NodeKey {\n return `k:${node.id}:${node.version}`\n }\n\n static addNormal(g: Graph, data: PublicNodeData): Node {\n const layer = g.layerAt(0)\n const node = new Node({\n ...data,\n edges: { in: ISet(), out: ISet() },\n segs: { in: ISet(), out: ISet() },\n aligned: {},\n edgeIds: [],\n layerId: layer.id,\n lpos: undefined,\n pos: undefined,\n })\n layer.addNode(g, node.id)\n g.nodes.set(node.id, node)\n g.dirtyNodes.add(node.id)\n return node\n }\n\n static addDummy(g: Graph, data: Partial<NodeData>): Node {\n const layer = g.getLayer(data.layerId!)\n const node = new Node({\n ...data,\n id: `${Node.dummyPrefix}${g.nextDummyId++}`,\n edges: { in: ISet(), out: ISet() },\n segs: { in: ISet(), out: ISet() },\n aligned: {},\n isDummy: true,\n dims: {\n w: g.options.dummyNodeSize,\n h: g.options.dummyNodeSize,\n }\n })\n layer.addNode(g, node.id)\n g.nodes.set(node.id, node)\n g.dirtyNodes.add(node.id)\n return node\n }\n\n static del(g: Graph, node: { id: string }): null {\n return g.getNode(node.id).delSelf(g)\n }\n\n static update(g: Graph, data: PublicNodeData): Node {\n return g.getNode(data.id).mut(g).merge(data)\n }\n\n mut(g: Graph): Node {\n if (this.mutable) return this\n return g.mutateNode(this)\n }\n\n final(): Node {\n if (!this.mutable) return this\n return this.merge({\n edges: { in: this.edges.in.asImmutable(), out: this.edges.out.asImmutable() },\n segs: { in: this.segs.in.asImmutable(), out: this.segs.out.asImmutable() },\n mutable: false,\n }).asImmutable()\n }\n\n dirty(g: Graph): Node {\n g.dirtyNodes.add(this.id)\n return this\n }\n\n cur(g: Graph): Node {\n return g.getNode(this.id)\n }\n\n isUnlinked(): boolean {\n return this.edges.in.size == 0 &&\n this.edges.out.size == 0 &&\n this.segs.in.size == 0 &&\n this.segs.out.size == 0\n }\n\n hasPorts(): boolean {\n return !!this.ports?.in?.length || !!this.ports?.out?.length\n }\n\n layerIndex(g: Graph): number {\n return this.getLayer(g).index\n }\n\n getLayer(g: Graph): Layer {\n return g.getLayer(this.layerId)\n }\n\n margin(g: Graph): number {\n return this.isDummy ? g.options.edgeSpacing - g.options.dummyNodeSize : g.options.nodeMargin\n }\n\n marginWith(g: Graph, other: Node): number {\n return Math.max(this.margin(g), other.margin(g))\n }\n\n width(g: Graph): number {\n return this.dims?.[g.w] ?? 0\n }\n\n right(g: Graph): number {\n return this.lpos! + this.width(g)\n }\n\n setIndex(g: Graph, index: number): Node {\n if (this.index == index) return this\n return this.mut(g).set('index', index)\n }\n\n setLayerPos(g: Graph, lpos: number): Node {\n if (this.lpos == lpos) return this\n return this.mut(g).set('lpos', lpos)\n }\n\n setLayer(g: Graph, layerId: LayerId): Node {\n if (this.layerId == layerId) return this\n return this.mut(g).set('layerId', layerId)\n }\n\n setPos(g: Graph, pos: Pos): Node {\n if (!this.pos || this.pos.x != pos.x || this.pos.y != pos.y)\n return this.mut(g).set('pos', pos)\n return this\n }\n\n moveToLayer(g: Graph, layer: Layer): Node {\n this.getLayer(g).delNode(g, this.id)\n layer.addNode(g, this.id)\n return this.setLayer(g, layer.id)\n }\n\n moveToLayerIndex(g: Graph, index: number): Node {\n return this.moveToLayer(g, g.layerAt(index))\n }\n\n setAligned(g: Graph, dir: Dir, nodeId: NodeId | undefined): Node {\n if (this.aligned[dir] === nodeId) return this\n return this.mut(g).set('aligned', { ...this.aligned, [dir]: nodeId })\n }\n\n addRel(g: Graph, type: LinkType, dir: Dir, relId: EdgeId | SegId): Node {\n const sets = this.get(type)\n const set = sets[dir]\n if (set.has(relId)) return this\n return this.mut(g).set(type, { ...sets, [dir]: set.asMutable().add(relId) })\n }\n\n delRel(g: Graph, type: LinkType, dir: Dir, relId: EdgeId | SegId): Node | null {\n let sets = this.get(type)\n const set = sets[dir]\n if (!set.has(relId)) return this\n sets = { ...sets, [dir]: set.asMutable().remove(relId) }\n const node = this.mut(g).set(type, sets)\n if (node.isDummy && node.isUnlinked())\n return node.delSelf(g)\n return node\n }\n\n delSelf(g: Graph): null {\n // Clear alignment references from partner nodes\n if (this.aligned.in)\n g.getNode(this.aligned.in).setAligned(g, 'out', undefined)\n if (this.aligned.out)\n g.getNode(this.aligned.out).setAligned(g, 'in', undefined)\n this.getLayer(g).delNode(g, this.id)\n // Phase 1: delete edges first (which should also remove segs)\n for (const edge of this.rels(g, 'edges', 'both'))\n edge.delSelf(g)\n // Phase 2: clean up any remaining segs defensively (in case of iteration ordering)\n const remainingSegIds = [...this.segs.in, ...this.segs.out]\n if (remainingSegIds.length > 0) {\n for (const segId of remainingSegIds) {\n // Only delete if seg still exists on graph\n if ((g as any).segs?.has?.(segId)) {\n g.getSeg(segId).delSelf(g)\n } else {\n // seg already removed; nothing to do\n }\n }\n }\n g.nodes.delete(this.id)\n g.dirtyNodes.delete(this.id)\n g.delNodes.add(this.id)\n return null\n }\n\n addInEdge(g: Graph, edgeId: EdgeId): Node {\n return this.addRel(g, 'edges', 'in', edgeId)\n }\n\n addOutEdge(g: Graph, edgeId: EdgeId): Node {\n return this.addRel(g, 'edges', 'out', edgeId)\n }\n\n addInSeg(g: Graph, segId: SegId): Node {\n return this.addRel(g, 'segs', 'in', segId)\n }\n\n addOutSeg(g: Graph, segId: SegId): Node {\n return this.addRel(g, 'segs', 'out', segId)\n }\n\n delInEdge(g: Graph, edgeId: EdgeId): Node | null {\n return this.delRel(g, 'edges', 'in', edgeId)\n }\n\n delOutEdge(g: Graph, edgeId: EdgeId): Node | null {\n return this.delRel(g, 'edges', 'out', edgeId)\n }\n\n delInSeg(g: Graph, segId: SegId): Node | null {\n return this.delRel(g, 'segs', 'in', segId)\n }\n\n delOutSeg(g: Graph, segId: SegId): Node | null {\n return this.delRel(g, 'segs', 'out', segId)\n }\n\n *relIds(type: LinkType | 'both' = 'both', dir: Dir | 'both' = 'both'): Generator<EdgeId | SegId> {\n const types: LinkType[] = type == 'both' ? ['edges', 'segs'] : [type]\n const dirs: Dir[] = dir == 'both' ? ['in', 'out'] : [dir]\n for (const type of types)\n for (const dir of dirs)\n yield* this.get(type)[dir]\n }\n\n rels(g: Graph, type: 'edges', dir?: Dir | 'both'): Generator<Edge>\n rels(g: Graph, type: 'segs', dir?: Dir | 'both'): Generator<Seg>\n rels(g: Graph, type: 'both', dir?: Dir | 'both'): Generator<Edge | Seg>\n rels(g: Graph, type: LinkType | 'both', dir: Dir | 'both'): Generator<Edge | Seg>\n rels(g: Graph, type: LinkType | 'both'): Generator<Edge | Seg>\n rels(g: Graph): Generator<Edge | Seg>\n *rels(g: Graph, type: LinkType | 'both' = 'both', dir: Dir | 'both' = 'both'): Generator<Edge | Seg> {\n for (const relId of this.relIds(type, dir))\n yield g.getRel(relId)\n }\n\n *adjIds(g: Graph, type: LinkType | 'both' = 'both', dir: Dir | 'both' = 'both'): Generator<NodeId> {\n const dirs: Dir[] = dir == 'both' ? ['in', 'out'] : [dir]\n for (const dir of dirs) {\n const side: Side = dir == 'in' ? 'source' : 'target'\n for (const rel of this.rels(g, type, dir))\n yield rel[side].id\n }\n }\n\n *adjs(g: Graph, type: LinkType | 'both' = 'both', dir: Dir | 'both' = 'both'): Generator<Node> {\n for (const nodeId of this.adjIds(g, type, dir))\n yield g.getNode(nodeId)\n }\n\n *inEdgeIds(): Generator<EdgeId> {\n yield* this.relIds('edges', 'in')\n }\n\n *outEdgeIds(): Generator<EdgeId> {\n yield* this.relIds('edges', 'out')\n }\n\n *inSegIds(): Generator<SegId> {\n yield* this.relIds('segs', 'in')\n }\n\n *outSegIds(): Generator<SegId> {\n yield* this.relIds('segs', 'out')\n }\n\n *inEdges(g: Graph): Generator<Edge> {\n yield* this.rels(g, 'edges', 'in')\n }\n\n *outEdges(g: Graph): Generator<Edge> {\n yield* this.rels(g, 'edges', 'out')\n }\n\n *inSegs(g: Graph): Generator<Seg> {\n yield* this.rels(g, 'segs', 'in')\n }\n\n *outSegs(g: Graph): Generator<Seg> {\n yield* this.rels(g, 'segs', 'out')\n }\n\n *inNodeIds(g: Graph): Generator<NodeId> {\n yield* this.adjIds(g, 'edges', 'in')\n }\n\n *outNodeIds(g: Graph): Generator<NodeId> {\n yield* this.adjIds(g, 'edges', 'out')\n }\n\n *inNodes(g: Graph): Generator<Node> {\n yield* this.adjs(g, 'edges', 'in')\n }\n\n *outNodes(g: Graph): Generator<Node> {\n yield* this.adjs(g, 'edges', 'out')\n }\n}\n","import pino from 'pino'\n\ntype LogLevel = 'error' | 'warn' | 'info' | 'debug'\n\n// Resolve log level from environment or default to 'debug' (matches previous behavior)\nconst resolvedLevel: LogLevel =\n (typeof globalThis !== 'undefined' && (globalThis as any).__LOG_LEVEL) ||\n (typeof process !== 'undefined' && (process as any).env?.LOG_LEVEL) ||\n 'debug'\n\n// Configure browser options: emit objects, optionally transmit to collector\nconst browserOpts: any = { asObject: true }\nbrowserOpts.transmit = {\n level: resolvedLevel,\n send: (level: string, log: Record<string, unknown>) => {\n try {\n const endpoint: string | undefined =\n (typeof globalThis !== 'undefined' && (globalThis as any).__LOG_INGEST_URL) ||\n (typeof process !== 'undefined' && (process as any).env?.LOG_INGEST_URL) ||\n undefined\n if (!endpoint || typeof window === 'undefined') {\n // Dev aid: show why transmit may be inactive\n try { console.debug('[graph-core] transmit skipped', { endpoint, hasWindow: typeof window !== 'undefined', level }) } catch { }\n return\n }\n const line = JSON.stringify({ level, ...log, ts: Date.now() }) + '\\n'\n try { console.debug('[graph-core] transmit sending', { endpoint, level, bytes: line.length }) } catch { }\n // Always use fetch with no-cors and omit credentials to avoid preflight and credentialed requests\n fetch(endpoint, {\n method: 'POST',\n mode: 'no-cors',\n credentials: 'omit',\n body: line,\n keepalive: true,\n })\n .then(() => { try { console.debug('[graph-core] transmit fetch ok') } catch { } })\n .catch((err) => { try { console.debug('[graph-core] transmit fetch error', err?.message || err) } catch { } })\n } catch (e) {\n try { console.debug('[graph-core] transmit error', (e as any)?.message || e) } catch { }\n }\n },\n}\n\n// Create a singleton pino base logger\nconst base = pino({\n level: resolvedLevel,\n browser: browserOpts,\n})\n\nexport function logger(module: string) {\n const child = base.child({ module })\n return {\n error: (msg: string, ...args: any[]) => child.error({ args }, msg),\n warn: (msg: string, ...args: any[]) => child.warn({ args }, msg),\n info: (msg: string, ...args: any[]) => child.info({ args }, msg),\n debug: (msg: string, ...args: any[]) => child.debug({ args }, msg),\n }\n}\n\nexport const log = logger('core')\n","import { Record } from 'immutable'\nimport { NodeId, Node } from \"./node\"\nimport { Graph } from \"./graph\"\nimport { Side } from \"../common\"\nimport { SegId, Seg } from \"./seg\"\nimport { EdgeStyle } from \"../api/options\"\nimport { logger } from \"../log\"\nimport { MarkerType } from \"../canvas/marker\"\n\nconst log = logger('edge')\n\nexport type EdgeId = string\n\nexport type PublicEdgeData = {\n id: string\n data: any\n label?: string\n source: { id: string, port?: string, marker?: MarkerType }\n target: { id: string, port?: string, marker?: MarkerType }\n type?: string\n}\n\ntype EdgeData = PublicEdgeData & {\n segIds: SegId[]\n mutable: boolean\n}\n\nconst defEdgeData: EdgeData = {\n id: '',\n data: null,\n label: undefined,\n source: { id: '' },\n target: { id: '' },\n type: undefined,\n mutable: false,\n segIds: [],\n}\n\nexport class Edge extends Record(defEdgeData) {\n static prefix = 'e:'\n\n mut(g: Graph): Edge {\n if (this.mutable) return this\n return g.mutateEdge(this)\n }\n\n final(): Edge {\n if (!this.mutable) return this\n return this.merge({\n mutable: false\n }).asImmutable()\n }\n\n link(g: Graph): Edge {\n this.sourceNode(g).addOutEdge(g, this.id)\n this.targetNode(g).addInEdge(g, this.id)\n return this\n }\n\n unlink(g: Graph): Edge {\n this.sourceNode(g).delOutEdge(g, this.id)\n this.targetNode(g).delInEdge(g, this.id)\n return this\n }\n\n delSelf(g: Graph): null {\n for (const seg of this.segs(g))\n seg.delEdgeId(g, this.id)\n this.unlink(g)\n g.edges.delete(this.id)\n g.dirtyEdges.delete(this.id)\n g.delEdges.add(this.id)\n return null\n }\n\n delSegId(g: Graph, segId: SegId): Edge {\n return this.setSegIds(g, this.segIds.filter(id => id != segId))\n }\n\n replaceSegId(g: Graph, oldId: SegId, newId: SegId): Edge {\n return this.setSegIds(g, this.segIds.map(id => id == oldId ? newId : id))\n }\n\n setSegIds(g: Graph, segIds: SegId[]): Edge {\n if (segIds.join(',') == this.segIds.join(',')) return this\n return this.mut(g).set('segIds', segIds)\n }\n\n *segs(g: Graph): Generator<Seg> {\n for (const segId of this.segIds)\n yield g.getSeg(segId)\n }\n\n node(g: Graph, side: Side): Node {\n return g.getNode(this[side].id)\n }\n\n sourceNode(g: Graph): Node {\n return this.node(g, 'source')\n }\n\n targetNode(g: Graph): Node {\n return this.node(g, 'target')\n }\n\n get str(): string {\n return Edge.str(this)\n }\n\n static str(edge: Partial<EdgeData>): string {\n let source = edge.source?.id\n if (!source) throw new Error('edge source is undefined')\n if (edge.source?.port)\n source = `${source} (port ${edge.source.port})`\n let target = edge.target?.id\n if (!target) throw new Error('edge target is undefined')\n if (edge.target?.port)\n target = `${target} (port ${edge.target.port})`\n let str = `edge from ${source} to ${target}`\n if (edge.type) str += ` of type ${edge.type}`\n return str\n }\n\n static key(edge: Partial<EdgeData>, prefix: string = Edge.prefix, side: Side | 'both' = 'both'): string {\n let source = '', target = ''\n if (side == 'source' || side == 'both') {\n if (!edge.source?.id) throw new Error('edge source is undefined')\n source = edge.source.id\n if (edge.source?.port)\n source = `${source}.${edge.source.port}`\n const marker = edge.source?.marker\n if (marker && marker != 'none') source += `[${marker}]`\n source += '-'\n }\n if (side == 'target' || side == 'both') {\n if (!edge.target?.id) throw new Error('edge target is undefined')\n target = edge.target.id\n if (edge.target.port)\n target = `${target}.${edge.target.port}`\n target = '-' + target\n const marker = edge.target?.marker ?? 'arrow'\n if (marker && marker != 'none') target += `[${marker}]`\n }\n const type = edge.type || ''\n return `${prefix}${source}${type}${target}`\n }\n\n static add(g: Graph, data: Partial<EdgeData>): Edge {\n const edge = new Edge({\n ...data,\n segIds: [],\n })\n edge.link(g)\n g.edges.set(edge.id, edge)\n g.dirtyEdges.add(edge.id)\n return edge\n }\n\n static del(g: Graph, data: { id: string }): null {\n return g.getEdge(data.id).delSelf(g)\n }\n\n static update(g: Graph, data: PublicEdgeData): Edge {\n let edge = g.getEdge(data.id)\n let relink = false\n if (\n data.source.id !== edge.source.id ||\n data.target.id !== edge.target.id ||\n data.source.port !== edge.source.port ||\n data.target.port !== edge.target.port ||\n data.type !== edge.type\n ) {\n for (const seg of edge.segs(g))\n seg.delEdgeId(g, edge.id)\n edge.unlink(g)\n relink = true\n }\n edge = edge.mut(g).merge(data)\n if (relink)\n edge.link(g)\n return edge\n }\n}","import { Record, Set as ISet } from 'immutable'\nimport { Node, NodeId, PortId } from './node'\nimport { EdgeId, Edge } from './edge'\nimport { Graph } from './graph'\nimport { Side } from '../common'\nimport { EdgeStyle } from '../api/options'\nimport { MarkerType } from '../canvas/marker'\n\nexport type SegId = string\n\ntype SegEnd = {\n id: NodeId\n port?: PortId\n pos?: number\n marker?: MarkerType\n}\n\ntype SegData = {\n id: string\n source: SegEnd\n target: SegEnd\n type?: string\n edgeIds: ISet<EdgeId>\n trackPos?: number\n svg?: string\n mutable: boolean\n}\n\nconst defSegData: SegData = {\n id: '',\n source: { id: '' },\n target: { id: '' },\n type: undefined,\n edgeIds: ISet(),\n trackPos: undefined,\n svg: undefined,\n mutable: false,\n}\n\nexport class Seg extends Record(defSegData) {\n static prefix = 's:'\n\n mut(g: Graph): Seg {\n if (this.mutable) return this\n return g.mutateSeg(this)\n }\n\n final(): Seg {\n if (!this.mutable) return this\n return this.merge({\n edgeIds: this.edgeIds.asImmutable(),\n mutable: false,\n }).asImmutable()\n }\n\n get p1(): number {\n return this.source.pos!\n }\n\n get p2(): number {\n return this.target.pos!\n }\n\n anySameEnd(other: Seg): boolean {\n return this.sameEnd(other, 'source') || this.sameEnd(other, 'target')\n }\n\n sameEnd(other: Seg, side: Side): boolean {\n const mine = this[side]\n const yours = other[side]\n return true &&\n mine.id === yours.id &&\n mine.port === yours.port &&\n mine.marker === yours.marker &&\n this.type === other.type\n }\n\n setPos(g: Graph, source: number, target: number): Seg {\n return this.mut(g).merge({\n source: { ...this.source, pos: source },\n target: { ...this.target, pos: target },\n })\n }\n\n setTrackPos(g: Graph, trackPos?: number): Seg {\n if (this.trackPos == trackPos) return this\n return this.mut(g).set('trackPos', trackPos)\n }\n\n setSVG(g: Graph, svg: string): Seg {\n if (this.svg == svg) return this\n return this.mut(g).set('svg', svg)\n }\n\n link(g: Graph): Seg {\n this.sourceNode(g).addOutSeg(g, this.id)\n this.targetNode(g).addInSeg(g, this.id)\n return this\n }\n\n unlink(g: Graph): Seg {\n this.sourceNode(g).delOutSeg(g, this.id)\n this.targetNode(g).delInSeg(g, this.id)\n return this\n }\n\n delSelf(g: Graph): null {\n this.unlink(g)\n g.segs.delete(this.id)\n g.dirtySegs.delete(this.id)\n g.delSegs.add(this.id)\n return null\n }\n\n *edges(g: Graph): Generator<Edge> {\n for (const edgeId of this.edgeIds)\n yield g.getEdge(edgeId)\n }\n\n node(g: Graph, side: Side): Node {\n return g.getNode(this[side].id)\n }\n\n sourceNode(g: Graph): Node {\n return this.node(g, 'source')\n }\n\n targetNode(g: Graph): Node {\n return this.node(g, 'target')\n }\n\n addEdgeId(g: Graph, edgeId: EdgeId): Seg {\n if (this.edgeIds.has(edgeId)) return this\n return this.mut(g).set('edgeIds', this.edgeIds.asMutable().add(edgeId))\n }\n\n delEdgeId(g: Graph, edgeId: EdgeId): Seg | null {\n if (!this.edgeIds.has(edgeId)) return this\n if (this.edgeIds.size == 1) {\n this.delSelf(g)\n return null\n }\n return this.mut(g).set('edgeIds', this.edgeIds.asMutable().remove(edgeId))\n }\n\n static add(g: Graph, data: Partial<SegData>): Seg {\n const seg = new Seg({\n ...data,\n id: Edge.key(data, Seg.prefix),\n })\n seg.link(g)\n g.segs.set(seg.id, seg)\n g.dirtySegs.add(seg.id)\n return seg\n }\n}","import { Record, Set as ISet } from 'immutable'\nimport { Node, NodeId } from './node'\nimport { Graph } from './graph'\nimport { SegId } from './seg'\nimport { Edge } from './edge'\nimport { logger } from '../log'\n\nconst log = logger('layer')\n\nexport type LayerId = string\n\nexport type LayerData = {\n id: LayerId\n index: number\n nodeIds: ISet<NodeId>\n sorted: NodeId[]\n tracks: SegId[][]\n size: number\n pos: number\n isSorted: boolean\n mutable: boolean\n}\n\nconst defLayerData: LayerData = {\n id: '',\n index: 0,\n nodeIds: ISet(),\n sorted: [],\n tracks: [],\n size: 0,\n pos: 0,\n isSorted: false,\n mutable: false,\n}\n\nexport class Layer extends Record(defLayerData) {\n static prefix = 'l:'\n\n mut(g: Graph): Layer {\n if (this.mutable) return this\n return g.mutateLayer(this)\n }\n\n final(): Layer {\n if (!this.mutable) return this\n return this.merge({\n nodeIds: this.nodeIds.asImmutable(),\n mutable: false,\n }).asImmutable()\n }\n\n get nodeCount(): number {\n return this.nodeIds.size\n }\n\n *nodes(g: Graph): Generator<Node> {\n for (const nodeId of this.nodeIds.values())\n yield g.getNode(nodeId)\n }\n\n hasSortOrder(order: NodeId[]): boolean {\n return order.length == this.sorted.length &&\n this.sorted.every((nodeId, i) => order[i] == nodeId)\n }\n\n canCrush(g: Graph): boolean {\n for (const node of this.nodes(g))\n if (!node.isDummy)\n return false\n return true\n }\n\n crush(g: Graph): null {\n g.layerList.remove(this.index)\n g.layers.delete(this.id)\n g.dirtyLayers.delete(this.id)\n for (let i = this.index; i < g.layerList.size; i++)\n g.getLayer(g.layerList.get(i)!).setIndex(g, i)\n for (const node of this.nodes(g))\n if (node.isDummy) node.delSelf(g)\n return null\n }\n\n setIndex(g: Graph, index: number): Layer {\n if (this.index == index) return this\n return this.mut(g).set('index', index)\n }\n\n setTracks(g: Graph, tracks: SegId[][]): Layer {\n if (this.tracks == tracks) return this\n return this.mut(g).set('tracks', tracks)\n }\n\n setSize(g: Graph, size: number): Layer {\n if (this.size == size) return this\n return this.mut(g).set('size', size)\n }\n\n setPos(g: Graph, pos: number): Layer {\n if (this.pos == pos) return this\n return this.mut(g).set('pos', pos)\n }\n\n addNode(g: Graph, nodeId: NodeId): Layer {\n if (this.nodeIds.has(nodeId)) return this\n return this.mut(g).set('nodeIds', this.nodeIds.asMutable().add(nodeId))\n }\n\n willCrush(g: Graph, nodeId: NodeId): boolean {\n for (const node of this.nodes(g))\n if (!node.isDummy && node.id != nodeId)\n return false\n return true\n }\n\n reindex(g: Graph, nodeId: NodeId): NodeId[] | undefined {\n if (!this.isSorted) return undefined\n const sorted = this.sorted.filter(id => id != nodeId)\n for (const [i, id] of this.sorted.entries())\n g.getNode(id).setIndex(g, i)\n return sorted\n }\n\n delNode(g: Graph, nodeId: NodeId): Layer | null {\n if (!this.nodeIds.has(nodeId)) return this\n if (this.willCrush(g, nodeId)) return this.crush(g)\n const nodeIds = this.nodeIds.asMutable().remove(nodeId)\n const sorted = this.reindex(g, nodeId)\n return this.mut(g).merge({ nodeIds, sorted })\n }\n\n setSorted(g: Graph, nodeIds: NodeId[]): Layer {\n if (this.hasSortOrder(nodeIds)) return this\n nodeIds.forEach((nodeId, i) => g.getNode(nodeId).setIndex(g, i))\n return this.mut(g).merge({ sorted: nodeIds, isSorted: true })\n }\n\n *outEdges(g: Graph): Generator<Edge> {\n for (const node of this.nodes(g))\n yield* node.outEdges(g)\n }\n}\n","import { PublicNodeData } from './node'\nimport { PublicEdgeData } from './edge'\nimport { Changes } from './graph'\n\nexport class Mutator {\n changes: Changes\n\n constructor() {\n this.changes = {\n addedNodes: [],\n removedNodes: [],\n updatedNodes: [],\n addedEdges: [],\n removedEdges: [],\n updatedEdges: [],\n }\n }\n\n describe(description: string) {\n this.changes.description = description\n }\n\n addNode(node: PublicNodeData) {\n this.changes.addedNodes.push(node)\n }\n\n addNodes(...nodes: PublicNodeData[]) {\n nodes.forEach(node => this.addNode(node))\n }\n\n removeNode(node: { id: string }) {\n this.changes.removedNodes.push(node)\n }\n\n removeNodes(...nodes: { id: string }[]) {\n nodes.forEach(node => this.removeNode(node))\n }\n\n updateNode(node: PublicNodeData) {\n this.changes.updatedNodes.push(node)\n }\n\n updateNodes(...nodes: PublicNodeData[]) {\n nodes.forEach(node => this.updateNode(node))\n }\n\n addEdge(edge: PublicEdgeData) {\n this.changes.addedEdges.push(edge)\n }\n\n addEdges(...edges: PublicEdgeData[]) {\n edges.forEach(edge => this.addEdge(edge))\n }\n\n removeEdge(edge: PublicEdgeData) {\n this.changes.removedEdges.push(edge)\n }\n\n removeEdges(...edges: PublicEdgeData[]) {\n edges.forEach(edge => this.removeEdge(edge))\n }\n\n updateEdge(edge: PublicEdgeData) {\n this.changes.updatedEdges.push(edge)\n }\n\n updateEdges(...edges: PublicEdgeData[]) {\n edges.forEach(edge => this.updateEdge(edge))\n }\n}","import { Graph } from '../graph'\nimport { Node } from '../node'\n\nexport class Cycles {\n static info(g: Graph, node: Node) {\n return node.id\n }\n\n static checkCycles(g: Graph) {\n const totalNodes = g.nodes.size\n const newStuff = g.changes.addedNodes.length + g.changes.addedEdges.length\n const changeRatio = newStuff / totalNodes\n if (changeRatio > 0.2 || totalNodes < 20)\n Cycles.checkCyclesFull(g)\n else\n Cycles.checkCyclesIncremental(g)\n }\n\n private static checkCyclesFull(g: Graph) {\n const colorMap: Map<Node, number> = new Map()\n const parentMap: Map<Node, Node> = new Map()\n let start: Node | undefined, end: Node | undefined\n const white = 0, gray = 1, black = 2\n\n const visit = (node: Node) => {\n colorMap.set(node, gray)\n for (const next of node.outNodes(g)) {\n switch (colorMap.get(next) ?? white) {\n case gray:\n start = next\n end = node\n return true\n case white:\n parentMap.set(next, node)\n if (visit(next)) return true\n }\n }\n colorMap.set(node, black)\n return false\n }\n\n for (const node of g.getNodes())\n if ((colorMap.get(node) ?? white) == white)\n if (visit(node)) break\n\n if (!start || !end) return\n\n const cycle = [start]\n let node = end\n while (node != start) {\n cycle.push(node)\n node = parentMap.get(node)!\n }\n\n Cycles.throwCycle(g, cycle)\n }\n\n private static checkCyclesIncremental(g: Graph) {\n for (const edge of g.changes.addedEdges) {\n const source = g.getNode(edge.source.id)\n const target = g.getNode(edge.target.id)\n const layer1 = source.layerIndex(g)\n const layer2 = target.layerIndex(g)\n if (layer1 < layer2) continue\n const route = Cycles.findRoute(g, target, source)\n if (!route) continue\n Cycles.throwCycle(g, route)\n }\n }\n\n private static throwCycle(g: Graph, cycle: Node[]) {\n cycle.push(cycle[0])\n cycle.reverse()\n const info = cycle.map(node => Cycles.info(g, node))\n throw new Error(`Cycle detected: ${info.join(' → ')}`)\n }\n\n private static findRoute(g: Graph, source: Node, target: Node): Node[] | null {\n const parentMap: Map<Node, Node> = new Map()\n const queue = [source]\n const visited = new Set([source])\n\n while (queue.length > 0) {\n const node = queue.shift()!\n if (node == target) {\n const route = []\n let currNode = target\n while (currNode != source) {\n route.push(currNode)\n currNode = parentMap.get(currNode)!\n }\n route.push(source)\n route.reverse()\n return route\n }\n\n for (const next of node.outNodes(g)) {\n if (!visited.has(next)) {\n visited.add(next)\n parentMap.set(next, node)\n queue.push(next)\n }\n }\n }\n\n return null\n }\n}","import { Set as ISet } from 'immutable'\nimport { Node } from '../node'\nimport { Edge } from '../edge'\nimport { logger } from '../../log'\nimport { Seg } from '../seg'\nimport { Graph } from '../graph'\nimport { Side } from '../../common'\n\nconst log = logger('dummy')\n\nexport class Dummy {\n static updateDummies(g: Graph) {\n // check all dirty edges to see if they need segments added or removed\n for (const edgeId of g.dirtyEdges) {\n const edge = g.getEdge(edgeId)\n const { type } = edge\n const sourceLayer = edge.sourceNode(g).layerIndex(g)\n const targetLayer = edge.targetNode(g).layerIndex(g)\n let segIndex = 0\n let changed = false\n let source = edge.source\n // adjust edge segments\n const segs = edge.segIds\n // loop over layers between source and target\n for (let layerIndex = sourceLayer + 1; layerIndex <= targetLayer; layerIndex++) {\n const layer = g.layerAt(layerIndex)\n // update segments until the current layer is reached\n while (true) {\n const segId = segs[segIndex]\n let seg = segId ? g.getSeg(segId) : null\n const segLayer = seg ? seg.targetNode(g).layerIndex(g) : null\n if (segIndex == segs.length || segLayer! > layerIndex) {\n // either a gap existed, or we reached the end; either way, add a new segment\n let target: Edge['target']\n if (layerIndex == targetLayer) {\n target = edge.target\n } else {\n const dummy = Node.addDummy(g, {\n edgeIds: [edgeId],\n layerId: layer.id,\n })\n target = { id: dummy.id }\n }\n seg = Seg.add(g, { source, target, type, edgeIds: ISet([edgeId]) })\n segs.splice(segIndex, 0, seg.id)\n changed = true\n } else if (\n segLayer! < layerIndex ||\n seg!.source.id != source.id ||\n seg!.source.port != source.port ||\n layerIndex == targetLayer && (\n seg!.target.id != edge.target.id ||\n seg!.target.port != edge.target.port\n )\n ) {\n seg = seg!.delEdgeId(g, edgeId)\n segs.splice(segIndex, 1)\n changed = true\n continue\n }\n // advance to next segment, keep track of source id chain\n source = seg!.target\n segIndex++\n break\n }\n }\n // remove any remaining segments\n while (segIndex < segs.length) {\n g.getSeg(segs[segIndex]).delEdgeId(g, edgeId)\n segs.splice(segIndex, 1)\n changed = true\n segIndex++\n }\n // update edge with new segments if a change occurred\n if (changed) {\n edge.setSegIds(g, segs)\n /* debug removed */\n }\n }\n }\n\n static mergeDummies(g: Graph) {\n for (const side of g.options.mergeOrder)\n Dummy.mergeScan(g, side)\n }\n\n static mergeScan(g: Graph, side: Side) {\n // find dirty layers\n let layerIds = [...g.layerList]\n .filter(layerId => g.dirtyLayers.has(layerId))\n if (side == 'target') layerIds.reverse()\n const dir = side == 'source' ? 'in' : 'out'\n const altSide = side == 'source' ? 'target' : 'source'\n const altDir = altSide == 'source' ? 'in' : 'out'\n for (const layerId of layerIds) {\n // for each layer, we'll find merge-able dummy nodes\n let layer = g.getLayer(layerId)\n const groups: Map<string, Set<Node>> = new Map()\n // group layer dummies by edge-based keys\n for (const nodeId of layer.nodeIds) {\n const node = g.getNode(nodeId)\n if (!node.isDummy || node.isMerged) continue\n const edge = g.getEdge(node.edgeIds[0])\n const key = Edge.key(edge, 'k:', side)\n if (!groups.has(key)) groups.set(key, new Set())\n groups.get(key)!.add(node)\n }\n // for each group, we'll merge the dummies\n for (const [key, group] of groups) {\n if (group.size == 1) continue\n const edgeIds = [...group].map(node => node.edgeIds[0])\n const dummy = Node.addDummy(g, { edgeIds, layerId, isMerged: true })\n let seg: Seg | undefined\n // all 'in' segs are merged into a single new in seg\n for (const old of group) {\n let edge = g.getEdge(old.edgeIds[0])\n for (const segId of old.relIds('segs', dir)) {\n if (!seg) {\n const example = g.getSeg(segId)\n seg = Seg.add(g, {\n ...example,\n edgeIds: ISet(edgeIds),\n [side]: { ...example[side] },\n [altSide]: { ...example[altSide], id: dummy.id, port: undefined },\n })\n }\n edge = edge.replaceSegId(g, segId, seg.id)\n }\n }\n // all 'out' segs are replaced with individual new out segs\n for (const old of group) {\n let edge = g.getEdge(old.edgeIds[0])\n for (const segId of old.relIds('segs', altDir)) {\n const example = g.getSeg(segId)\n const seg = Seg.add(g, {\n ...example,\n edgeIds: ISet([old.edgeIds[0]]),\n [altSide]: { ...example[altSide] },\n [side]: { ...example[side], id: dummy.id, port: undefined },\n })\n edge = edge.replaceSegId(g, segId, seg.id)\n }\n }\n // remove old dummies\n for (const old of group)\n old.delSelf(g)\n }\n }\n }\n}\n","import { Set as ISet, Seq } from 'immutable'\nimport { Graph } from '../graph'\nimport { Node, NodeId } from '../node'\nimport { logger } from '../../log'\nimport { LayerId } from '../layer'\n\nconst log = logger('layers')\n\nexport class Layers {\n static updateLayers(g: Graph) {\n // phase 1: DFS to fix child layers based on parents\n // visit at least each dirty node\n const stack: NodeId[] = [...g.dirtyNodes]\n .map(id => g.getNode(id))\n .filter(node => !node.isDummy)\n .sort((a, b) => b.layerIndex(g) - a.layerIndex(g))\n .map(node => node.id)\n const phase2 = new Set(stack)\n const moved: Set<NodeId> = new Set()\n while (stack.length > 0) {\n let node = g.getNode(stack.pop()!)\n const curLayer = node.layerIndex(g)\n let correctLayer = 0\n const parents = node.inNodes(g)\n for (const parent of parents) {\n const pidx = parent.layerIndex(g)\n if (pidx >= correctLayer) correctLayer = pidx + 1\n }\n // if needs a move, move it and push children to stack\n // also add parents to phase 2\n if (curLayer != correctLayer) {\n node = node.moveToLayerIndex(g, correctLayer)\n stack.push(...node.outNodeIds(g))\n moved.add(node.id)\n for (const parent of parents)\n phase2.add(parent.id)\n }\n }\n // phase 2: reverse topo order to fix parents based on children\n const byLayer: Map<LayerId, Set<NodeId>> = new Map()\n // start by grouping by layer\n const addParent = (nodeId: NodeId) => {\n let set: Set<NodeId>\n const layerId = g.getNode(nodeId).layerId\n if (!byLayer.has(layerId)) {\n set = new Set()\n byLayer.set(layerId, set)\n } else {\n set = byLayer.get(layerId)!\n }\n set.add(nodeId)\n }\n for (const id of phase2) addParent(id)\n // take layers in reverse topo order\n const layerIds = [...byLayer.keys()].sort(\n (a, b) => g.getLayer(b).index - g.getLayer(a).index)\n for (const layerId of layerIds) {\n const curLayer = g.getLayer(layerId).index\n // visit each parent of this layer\n for (const parentId of byLayer.get(layerId)!) {\n let parent = g.getNode(parentId)\n const children = [...parent.outNodes(g)]\n if (children.length == 0) continue\n // should be just above min child\n const minChild = Seq(children).map(node => node.layerIndex(g)).min()!\n const correctLayer = minChild - 1\n // if needs a move, move it and push parents to stack\n if (curLayer != correctLayer) {\n moved.add(parentId)\n parent = parent.moveToLayerIndex(g, correctLayer)\n for (const gpId of parent.inNodeIds(g))\n addParent(gpId)\n }\n }\n }\n // mark edges as dirty\n for (const id of moved)\n for (const edgeId of g.getNode(id).relIds('edges'))\n g.dirtyEdges.add(edgeId)\n }\n}","import { logger } from '../../log'\nimport { Seq } from 'immutable'\nimport { Node, NodeId, PortId } from '../node'\nimport { Graph } from '../graph'\nimport { Dir, Side, Pos } from '../../common'\nimport { LayerId } from '../layer'\nimport { Seg } from '../seg'\nimport { MarkerType } from '../../canvas/marker'\n\nconst log = logger('layout')\n\nexport type LayoutStep = 'alignChildren' | 'alignParents' | 'compact'\n\nexport class Layout {\n static parentIndex(g: Graph, node: Node): number {\n const parents = Seq([...node.adjs(g, 'segs', 'in')])\n const pidx = parents.map(p => p.index).min()\n if (pidx !== undefined) return pidx\n return node.isDummy ? -Infinity : Infinity\n }\n\n static compareNodes(g: Graph, aId: NodeId, bId: NodeId, pidxs: Map<NodeId, number>): number {\n const ai = pidxs.get(aId)!\n const bi = pidxs.get(bId)!\n if (ai !== bi) return ai - bi\n const a = g.getNode(aId)\n const b = g.getNode(bId)\n if (a.isDummy && !b.isDummy) return -1\n if (!a.isDummy && b.isDummy) return 1\n if (!a.isDummy) return a.id.localeCompare(b.id)\n const minA = Seq(a.edgeIds).min()!\n const minB = Seq(b.edgeIds).min()!\n return minA.localeCompare(minB)\n }\n\n static positionNodes(g: Graph) {\n for (const nodeId of g.dirtyNodes)\n g.dirtyLayers.add(g.getNode(nodeId).layerId)\n let adjustNext = false\n for (const layerId of g.layerList) {\n if (!adjustNext && !g.dirtyLayers.has(layerId)) continue\n adjustNext = false\n let layer = g.getLayer(layerId)\n const pidxs: Map<NodeId, number> = new Map()\n for (const nodeId of layer.nodeIds)\n pidxs.set(nodeId, Layout.parentIndex(g, g.getNode(nodeId)))\n const sorted = [...layer.nodeIds].sort(\n (aId, bId) => Layout.compareNodes(g, aId, bId, pidxs))\n if (layer.hasSortOrder(sorted)) continue\n g.dirtyLayers.add(layerId)\n layer = layer.setSorted(g, sorted)\n adjustNext = true\n let lpos = 0\n for (let i = 0; i < sorted.length; i++) {\n let node = g.getNode(sorted[i])\n node = node.setIndex(g, i).setLayerPos(g, lpos)\n const size = node.dims?.[g.w] ?? 0\n let margin = node.margin(g)\n if (i + 1 < sorted.length) {\n const next = g.getNode(sorted[i + 1])\n margin = node.marginWith(g, next)\n }\n lpos += size + margin\n }\n }\n }\n\n static alignAll(g: Graph) {\n if (g.options.layoutSteps) {\n for (const step of g.options.layoutSteps)\n Layout[step](g)\n } else {\n for (let i = 0; i < g.options.alignIterations; i++) {\n let anyChanged =\n Layout.alignChildren(g) ||\n Layout.alignParents(g) ||\n Layout.compact(g)\n if (!anyChanged) break\n }\n }\n }\n\n static alignChildren(g: Graph) {\n return Layout.alignNodes(g, false, false, false, 'in', false)\n }\n\n static alignParents(g: Graph) {\n return Layout.alignNodes(g, true, true, false, 'out', true)\n }\n\n static alignNodes(\n g: Graph,\n reverseLayers: boolean,\n reverseNodes: boolean,\n reverseMove: boolean,\n dir: Dir,\n conservative: boolean\n ) {\n let layerIds = [...g.layerList]\n let anyChanged = false\n if (reverseLayers) layerIds.reverse()\n let adjustNext = false\n for (const layerId of layerIds) {\n if (!adjustNext && !g.dirtyLayers.has(layerId)) continue\n adjustNext = false\n let iterations = 0\n while (true) {\n if (++iterations > 10) {\n log.error(`alignNodes: infinite loop detected in layer ${layerId}`)\n break\n }\n let changed = false\n const nodeIds = Layout.sortLayer(g, layerId, reverseNodes)\n for (const nodeId of nodeIds) {\n const {\n isAligned,\n pos: newPos,\n nodeId: otherId\n } = Layout.nearestNode(g, nodeId, dir, reverseMove, !reverseMove)\n if (isAligned || (newPos === undefined)) continue\n if (Layout.shiftNode(g, nodeId, otherId, dir, newPos, reverseMove, conservative)) {\n changed = true\n anyChanged = true\n break\n }\n }\n if (!changed) break\n g.dirtyLayers.add(layerId)\n adjustNext = true\n }\n }\n return anyChanged\n }\n\n static sortLayer(g: Graph, layerId: LayerId, reverseNodes: boolean) {\n const layer = g.getLayer(layerId)\n const sorted = [...layer.nodeIds]\n sorted.sort((a, b) => g.getNode(a).lpos! - g.getNode(b).lpos!)\n layer.setSorted(g, sorted)\n if (reverseNodes)\n return sorted.toReversed()\n return sorted\n }\n\n static nearestNode(g: Graph, nodeId: NodeId, dir: Dir, allowLeft: boolean, allowRight: boolean) {\n const node = g.getNode(nodeId)\n let minDist = Infinity\n let bestPos, bestNodeId\n const mySide = dir == 'in' ? 'target' : 'source'\n const altSide = dir == 'in' ? 'source' : 'target'\n for (const seg of node.rels(g, 'segs', dir)) {\n const altId = seg[altSide].id\n const myPos = Layout.anchorPos(g, seg, mySide)[g.x]\n const altPos = Layout.anchorPos(g, seg, altSide)[g.x]\n const diff = altPos - myPos\n if (diff == 0) return { nodeId: altId, isAligned: true }\n if ((diff < 0) && !allowLeft) continue\n if ((diff > 0) && !allowRight) continue\n const dist = Math.abs(diff)\n if (dist < minDist) {\n minDist = dist\n bestNodeId = altId\n bestPos = node.lpos! + diff\n }\n }\n return { nodeId: bestNodeId, pos: bestPos, isAligned: false }\n }\n\n static anchorPos(g: Graph, seg: Seg, side: Side): Pos {\n const nodeId = seg[side].id\n const node = g.getNode(nodeId)\n let p = { [g.x]: node.lpos!, [g.y]: node.pos?.[g.y] ?? 0 } as Pos\n let w = node.dims?.[g.w] ?? 0\n let h = node.dims?.[g.h] ?? 0\n\n if (node.isDummy)\n return {\n [g.x]: p[g.x] + w / 2,\n [g.y]: p[g.y] + h / 2,\n } as Pos\n\n p[g.x] += Layout.nodePortOffset(g, nodeId, seg, side)\n if ((side == 'target') == g.r)\n p[g.y] += h\n\n return p\n }\n\n static nodePortOffset(g: Graph, nodeId: NodeId, seg: Seg, side: Side) {\n const node = g.getNode(nodeId)\n const dir = side == 'source' ? 'out' : 'in'\n const portId = seg[side].port\n let min = 0, size = node.dims?.[g.w] ?? 0\n\n if (portId) {\n const ports = node.ports?.[dir]\n const port = ports?.find(p => p.id === portId)\n if (port?.offset !== undefined) {\n min = port.offset\n size = port.size ?? 0\n }\n }\n\n const alt = side == 'source' ? 'target' : 'source'\n let segs = []\n const keyOf = (seg: Seg) => `${seg.type ?? ''}:${seg[side].marker ?? ''}`\n for (const segId of node.segs[dir])\n segs.push(g.getSeg(segId))\n if (portId) segs = segs.filter(s => s[side].port == portId)\n const groups = Object.groupBy(segs, s => keyOf(s))\n const posMap = new Map()\n for (const [key, segs] of Object.entries(groups)) {\n let pos = Infinity\n for (const seg of segs!) pos = Math.min(pos, seg.node(g, alt).lpos!)\n posMap.set(key, pos)\n }\n const keys = [...posMap.keys()].sort((a, b) => posMap.get(a)! - posMap.get(b)!)\n const gap = size / (keys.length + 1)\n const index = keys.indexOf(keyOf(seg))\n return min + (index + 1) * gap\n }\n\n static shiftNode(\n g: Graph,\n nodeId: NodeId,\n alignId: NodeId | undefined,\n dir: Dir,\n lpos: number,\n reverseMove: boolean,\n conservative: boolean\n ) {\n const node = g.getNode(nodeId)\n if (!conservative)\n Layout.markAligned(g, nodeId, alignId, dir, lpos)\n const nodeRight = lpos + node.width(g)\n repeat:\n for (const otherId of node.getLayer(g).nodeIds) {\n if (otherId == nodeId) continue\n const other = g.getNode(otherId)\n const margin = node.marginWith(g, other)\n // Calculate gap using proposed lpos, not current node.lpos\n const gap = (lpos < other.lpos!)\n ? other.lpos! - nodeRight\n : lpos - other.right(g)\n if (gap < margin) {\n if (conservative) return false\n const safePos = reverseMove ? lpos - other.width(g) - margin : nodeRight + margin\n Layout.shiftNode(g, otherId, undefined, dir, safePos, reverseMove, conservative)\n continue repeat\n }\n }\n if (conservative)\n Layout.markAligned(g, nodeId, alignId, dir, lpos)\n return true\n }\n\n static markAligned(g: Graph, nodeId: NodeId, otherId: NodeId | undefined, dir: Dir, lpos: number) {\n const node = g.getNode(nodeId)\n const alt = dir == 'in' ? 'out' : 'in'\n if (node.aligned[dir])\n g.getNode(node.aligned[dir]).setAligned(g, alt, undefined)\n if (otherId)\n g.getNode(otherId).setAligned(g, alt, nodeId)\n node.setAligned(g, dir, otherId).setLayerPos(g, lpos)\n }\n\n static *aligned(g: Graph, nodeId: NodeId, dir: Dir | 'both') {\n const visit = function* (node: Node, dir: Dir): Generator<Node> {\n const otherId = node.aligned[dir]\n if (!otherId) return\n const other = g.getNode(otherId)\n yield other\n yield* visit(other, dir)\n }\n const node = g.getNode(nodeId)\n yield node\n if (dir == 'both') {\n yield* visit(node, 'in')\n yield* visit(node, 'out')\n } else {\n yield* visit(node, dir)\n }\n }\n\n static leftOf(g: Graph, node: Node): NodeId | null {\n if (node.index == 0) return null\n return node.getLayer(g).sorted[node.index! - 1]\n }\n\n static rightOf(g: Graph, node: Node): NodeId | null {\n const layer = node.getLayer(g)\n if (node.index == layer.sorted.length - 1) return null\n return layer.sorted[node.index! + 1]\n }\n\n static compact(g: Graph) {\n let anyChanged = false\n for (const layerId of g.layerList) {\n const layer = g.getLayer(layerId)\n if (layer.sorted.length < 2) continue\n for (const [i, nodeId] of layer.sorted.entries()) {\n const node = g.getNode(nodeId)\n if (node.index == 0) continue\n let minGap = Infinity\n const stack = []\n let maxMargin = 0\n for (const right of Layout.aligned(g, nodeId, 'both')) {\n stack.push(right)\n const leftId = Layout.leftOf(g, right)\n if (!leftId) return\n const left = g.getNode(leftId)\n const leftWidth = left.dims?.[g.w] ?? 0\n const gap = right.lpos! - left.lpos! - leftWidth\n if (gap < minGap) minGap = gap\n // Use margin between right and its left neighbor\n const margin = right.marginWith(g, left)\n if (margin > maxMargin) maxMargin = margin\n }\n const delta = minGap - maxMargin\n if (delta <= 0) continue\n anyChanged = true\n for (const right of stack)\n right.setLayerPos(g, right.lpos! - delta)\n }\n }\n return anyChanged\n }\n\n static getCoords(g: Graph) {\n let pos = 0\n const dir = g.r ? -1 : 1\n const trackSep = Math.max(\n g.options.edgeSpacing,\n g.options.turnRadius\n )\n const marginSep = Math.max(\n g.options.edgeSpacing,\n g.options.layerMargin,\n g.options.turnRadius + g.options.markerSize\n )\n for (const layerId of g.layerList) {\n let layer = g.getLayer(layerId)\n let height: number\n if (g.dirtyLayers.has(layerId)) {\n height = Seq(layer.nodes(g)).map(node => node.dims?.[g.h] ?? 0).max() ?? 0\n layer = layer.setSize(g, height)\n } else height = layer.size\n for (const node of layer.nodes(g)) {\n if (!g.dirtyNodes.has(node.id) && pos == layer.pos) continue\n const npos: Pos = { [g.x]: node.lpos!, [g.y]: pos } as Pos\n if (!g.n) npos[g.y] += dir * height\n if (g.r == g.n) npos[g.y] -= node.dims?.[g.h] ?? 0\n node.setPos(g, npos)\n }\n layer = layer.setPos(g, pos)\n pos += dir * (height + marginSep)\n for (const track of layer.tracks) {\n for (const segId of track)\n g.getSeg(segId).setTrackPos(g, pos)\n pos += dir * trackSep\n }\n pos += dir * (marginSep - trackSep)\n }\n }\n}","import { PublicEdgeData } from '../graph/edge'\n\nexport type MarkerType = 'arrow' | 'circle' | 'diamond' | 'bar' | 'none'\n\nexport type Markers = {\n source?: MarkerType\n target?: MarkerType\n}\n\nexport function arrow(size: number, reverse: boolean = false, prefix: string = ''): SVGElement {\n const h = size / 1.5\n const w = size\n const ry = h / 2\n const suffix = reverse ? '-reverse' : ''\n const id = prefix ? `${prefix}-g3p-marker-arrow${suffix}` : `g3p-marker-arrow${suffix}`\n return (\n <marker\n id={id}\n className=\"g3p-marker g3p-marker-arrow\"\n markerWidth={size}\n markerHeight={size}\n refX=\"2\"\n refY={ry}\n orient={reverse ? 'auto-start-reverse' : 'auto'}\n markerUnits=\"userSpaceOnUse\"\n >\n <path d={`M0,0 L0,${h} L${w},${ry} z`} />\n </marker>\n ) as SVGElement\n}\n\nexport function circle(size: number, reverse: boolean = false, prefix: string = ''): SVGElement {\n const r = size / 3\n const cy = size / 2\n const suffix = reverse ? '-reverse' : ''\n const id = prefix ? `${prefix}-g3p-marker-circle${suffix}` : `g3p-marker-circle${suffix}`\n return (\n <marker\n id={id}\n className=\"g3p-marker g3p-marker-circle\"\n markerWidth={size}\n markerHeight={size}\n refX=\"2\"\n refY={cy}\n orient={reverse ? 'auto-start-reverse' : 'auto'}\n markerUnits=\"userSpaceOnUse\"\n >\n <circle cx={r + 2} cy={cy} r={r} />\n </marker>\n ) as SVGElement\n}\n\nexport function diamond(size: number, reverse: boolean = false, prefix: string = ''): SVGElement {\n const w = size * 0.7\n const h = size / 2\n const cy = size / 2\n const suffix = reverse ? '-reverse' : ''\n const id = prefix ? `${prefix}-g3p-marker-diamond${suffix}` : `g3p-marker-diamond${suffix}`\n return (\n <marker\n id={id}\n className=\"g3p-marker g3p-marker-diamond\"\n markerWidth={size}\n markerHeight={size}\n refX=\"2\"\n refY={cy}\n orient={reverse ? 'auto-start-reverse' : 'auto'}\n markerUnits=\"userSpaceOnUse\"\n >\n <path d={`M2,${cy} L${2 + w / 2},${cy - h / 2} L${2 + w},${cy} L${2 + w / 2},${cy + h / 2} z`} />\n </marker>\n ) as SVGElement\n}\n\nexport function bar(size: number, reverse: boolean = false, prefix: string = ''): SVGElement {\n const h = size * 0.6\n const cy = size / 2\n const suffix = reverse ? '-reverse' : ''\n const id = prefix ? `${prefix}-g3p-marker-bar${suffix}` : `g3p-marker-bar${suffix}`\n return (\n <marker\n id={id}\n className=\"g3p-marker g3p-marker-bar\"\n markerWidth={size}\n markerHeight={size}\n refX=\"2\"\n refY={cy}\n orient={reverse ? 'auto-start-reverse' : 'auto'}\n markerUnits=\"userSpaceOnUse\"\n >\n <line x1=\"2\" y1={cy - h / 2} x2=\"2\" y2={cy + h / 2} stroke-width=\"2\" />\n </marker>\n ) as SVGElement\n}\n\nexport function none(size: number, reverse: boolean = false, prefix: string = ''): SVGElement | undefined {\n return undefined\n}\n\ntype MarkerObj = {\n source?: { marker?: MarkerType }\n target?: { marker?: MarkerType }\n style?: { marker?: { source?: MarkerType, target?: MarkerType } }\n}\n\nexport function normalize(data: MarkerObj): Markers {\n let source: MarkerType | undefined = data.source?.marker ?? data.style?.marker?.source\n let target: MarkerType | undefined = data.target?.marker ?? data.style?.marker?.target ?? 'arrow'\n if (source == 'none') source = undefined\n if (target == 'none') target = undefined\n return { source, target }\n}\n\ntype MarkerFunc = (size: number, reverse?: boolean, prefix?: string) => SVGElement | undefined\n\nexport const markerDefs: Record<MarkerType, MarkerFunc> = {\n arrow,\n circle,\n diamond,\n bar,\n none,\n}\n","import { Graph } from \"../graph\"\nimport { Seg } from \"../seg\"\nimport { Layer } from \"../layer\"\nimport { Layout } from \"./layout\"\nimport { Pos } from \"../../common\"\nimport { logger } from \"../../log\"\nimport { normalize, Markers } from \"../../canvas/marker\"\n\nconst log = logger('lines')\n\ntype TPos = Partial<Pos> & { s?: number }\n\ntype PathBuilder = {\n x: keyof Pos\n y: keyof Pos\n lr: boolean\n d: -1 | 1\n o: -1 | 1\n rd: number\n ro: number\n t: number\n s: 0 | 1\n p: TPos\n path: Line[]\n advance: (p2: TPos, type: LineType) => void\n}\n\nexport type LineType = 'line' | 'arc'\n\nexport type Line = {\n type: LineType\n x1: number\n y1: number\n x2: number\n y2: number\n radius?: number\n sweep?: number\n}\n\nexport class Lines {\n\n static layoutSeg(g: Graph, seg: Seg): Seg {\n const sourcePos = Layout.anchorPos(g, seg, 'source')\n const targetPos = Layout.anchorPos(g, seg, 'target')\n return seg.setPos(g, sourcePos[g.x], targetPos[g.x])\n }\n\n static layerSegs(g: Graph, layer: Layer): Seg[] {\n const segs: Seg[] = []\n for (const node of layer.nodes(g))\n for (const seg of node.outSegs(g))\n segs.push(Lines.layoutSeg(g, seg))\n return segs\n }\n\n static trackEdges(g: Graph) {\n // first, make sure dirty segs make their source layers dirty\n for (const segId of g.dirtySegs.values())\n g.dirtyLayers.add(g.getSeg(segId).sourceNode(g).layerId)\n const minLength = g.options.turnRadius * 2\n // then process each dirty layer\n for (const layerId of g.dirtyLayers.values()) {\n const layer = g.getLayer(layerId)\n // TODO: could start with prior tracks with dirty segs removed?\n const leftTracks: Seg[][] = []\n const rightTracks: Seg[][] = []\n const allTracks: Seg[][] = []\n // get all outgoing segs and their start/end positions\n const segs = Lines.layerSegs(g, layer)\n .sort((a, b) => a.p1 - b.p1)\n for (const seg of segs) {\n // skip nearly-vertical segs\n if (Math.abs(seg.p1 - seg.p2) < minLength) {\n seg.setTrackPos(g, undefined)\n continue\n }\n // choose left, right, or both\n let trackSet\n if (!g.options.separateTrackSets)\n trackSet = allTracks\n else if (seg.p1 < seg.p2)\n trackSet = rightTracks\n else\n trackSet = leftTracks\n // check track sets in reverse order\n let validTrack\n for (let i = trackSet.length - 1; i >= 0; i--) {\n const track = trackSet[i]\n let overlap = false\n for (const other of track) {\n // if seg shares an end with an existing track, add it\n if (seg.anySameEnd(other)) {\n track.push(seg)\n validTrack = track\n break\n }\n // if seg overlaps another, go to next track set\n const minA = Math.min(seg.p1, seg.p2)\n const maxA = Math.max(seg.p1, seg.p2)\n const minB = Math.min(other.p1, other.p2)\n const maxB = Math.max(other.p1, other.p2)\n if (minA < maxB && minB < maxA) {\n overlap = true\n break\n }\n }\n if (!overlap) {\n validTrack = track\n break\n }\n }\n // either add to existing track or create new track\n if (validTrack)\n validTrack.push(seg)\n else\n trackSet.push([seg])\n }\n // sort tracks to minimize crossings\n // use the midpoint (average of source and target) to group edges traveling through similar regions\n // for right-going: larger midpoint = inner track (closer to source)\n // for left-going: smaller midpoint = inner track (closer to source)\n const midpoint = (s: Seg) => (s.p1 + s.p2) / 2\n const sortTracks = (tracks: Seg[][], goingRight: boolean) => {\n tracks.sort((a, b) => {\n const midA = Math.max(...a.map(midpoint))\n const midB = Math.max(...b.map(midpoint))\n return goingRight ? (midB - midA) : (midA - midB)\n })\n }\n sortTracks(rightTracks, true)\n sortTracks(leftTracks, false)\n // for allTracks, use average midpoint (descending)\n allTracks.sort((a, b) => {\n const avgA = a.reduce((sum, s) => sum + midpoint(s), 0) / a.length\n const avgB = b.reduce((sum, s) => sum + midpoint(s), 0) / b.length\n return avgB - avgA\n })\n\n // convert tracks to seg ids and store on layer\n const tracks = []\n const all = leftTracks.concat(rightTracks).concat(allTracks)\n for (const track of all)\n tracks.push(track.map(seg => seg.id))\n layer.setTracks(g, tracks)\n }\n return this\n }\n\n static pathEdges(g: Graph) {\n for (const seg of g.segs.values()) {\n if (!g.dirtySegs.has(seg.id)) continue\n const radius = g.options.turnRadius\n const p1 = Layout.anchorPos(g, seg, 'source')\n const p2 = Layout.anchorPos(g, seg, 'target')\n const source = seg.sourceNode(g)\n const target = seg.targetNode(g)\n const marker = normalize(seg)\n if (source.isDummy) marker.source = undefined\n if (target.isDummy) marker.target = undefined\n const path = seg.trackPos !== undefined\n ? Lines.createRailroadPath(g, p1, p2, seg.trackPos, radius, marker)\n : Lines.createDirectPath(g, p1, p2, radius, marker)\n const svg = Lines.pathToSVG(path)\n seg.setSVG(g, svg)\n }\n return this\n }\n\n static pathLine(p1: TPos, p2: TPos, type: LineType, radius: number): Line {\n if (p2.x === undefined) p2.x = p1.x\n if (p2.y === undefined) p2.y = p1.y\n if (p2.s === undefined) p2.s = p1.s\n const line: Line = {\n type,\n x1: p1.x!, y1: p1.y!,\n x2: p2.x!, y2: p2.y!,\n }\n p1.x = p2.x\n p1.y = p2.y\n p1.s = p2.s\n if (type == 'arc') {\n line.radius = radius\n line.sweep = p1.s\n }\n return line\n }\n\n static pathBuilder(g: Graph, start: Pos, end: Pos, trackPos: number, radius: number, marker: Markers): PathBuilder {\n const { x, y } = g\n const lr = end[x] > start[x] // true for left to right\n const d = lr ? 1 : -1 // d = 1 for left to right, -1 for right to left\n const o = g.r ? -1 : 1 // o = 1 for forward, -1 for reverse\n const rd = radius * d // rd = radius * d\n const ro = radius * o // ro = radius * o\n const t = trackPos // t = track position\n\n // getting the sweep direction right in all orientations is tricky \n let s = 0 // s (sweep) = 0 for CCW, 1 for CW\n if (g.r) s = 1 - s // flip direction if reverse orientation\n if (!lr) s = 1 - s // flip direction if left to right\n if (!g.v) s = 1 - s // flip direction if horizontal\n\n // adjust start/end for markers\n if (marker.source) start[y] += o * (g.options.markerSize - 1)\n if (marker.target) end[y] -= o * (g.options.markerSize - 1)\n\n // set up an incremental drawing function\n const p = { ...start, s }\n const path: Line[] = []\n const advance = (p2: TPos, type: LineType) => {\n path.push(this.pathLine(p, p2, type, radius))\n }\n\n // return everything that might be useful\n return { x, y, lr, d, o, rd, ro, t, s: s as (0 | 1), p, path, advance }\n }\n\n // Create a railroad-style path with two 90-degree turns\n static createRailroadPath(g: Graph, start: Pos, end: Pos, trackPos: number, radius: number, marker: Markers): Line[] {\n const { x, y, rd, ro, t, s, p, path, advance } = this.pathBuilder(g, start, end, trackPos, radius, marker)\n\n // draw the path; notes assume TB layout and LR edge\n advance({ [y]: t - ro }, 'line') // straight line down to just above track \n advance({ [x]: p[x]! + rd, [y]: t }, 'arc') // arc CCW towards the right\n advance({ [x]: end[x] - rd }, 'line') // stright line right to just left of end position\n advance({ [x]: end[x], [y]: t + ro, s: 1 - s }, 'arc') // arc CW towards down\n advance({ [y]: end[y] }, 'line') // stright line down to end position\n\n return path\n }\n\n // Create a mostly-vertical path with optional S-curve\n static createDirectPath(g: Graph, start: Pos, end: Pos, radius: number, marker: Markers): Line[] {\n const { x, y, d, o, s, p, path, advance } = this.pathBuilder(g, start, end, 0, radius, marker)\n const dx = Math.abs(end.x - start.x)\n const dy = Math.abs(end.y - start.y)\n const d_ = { x: dx, y: dy }\n\n // for very straight lines, just draw a line \n if (dx < 0.1) {\n advance({ ...end }, 'line')\n return path\n }\n\n // try to use S-curve with matching radius\n const curve = Lines.calculateSCurve(d_[x], d_[y], radius)\n\n // if we can't use an S-curve, just draw a line\n if (!curve || curve.Ly == 0) {\n advance({ ...end }, 'line')\n return path\n }\n\n const m = {\n [x]: d * (d_[x] - curve.Lx) / 2,\n [y]: o * (d_[y] - curve.Ly) / 2\n }\n\n // draw the S shape\n advance({ [x]: p[x]! + m[x], [y]: p[y]! + m[y] }, 'arc')\n advance({ [x]: end[x] - m[x], [y]: end[y] - m[y] }, 'line')\n advance({ [x]: end[x], [y]: end[y], s: 1 - s }, 'arc')\n\n return path\n }\n\n static solveSCurveAngle(dx: number, dy: number, r: number): number | null {\n // The equation to solve:\n // dx * cos(α) - dy * sin(α) = 2r * (cos(α) - 1)\n // Rearranged: f(α) = dx * cos(α) - dy * sin(α) - 2r * cos(α) + 2r = 0\n\n const f = (alpha: number) => {\n return dx * Math.cos(alpha) - dy * Math.sin(alpha) - 2 * r * Math.cos(alpha) + 2 * r\n }\n\n // Derivative: f'(α) = -dx * sin(α) - dy * cos(α) + 2r * sin(α)\n const fPrime = (alpha: number) => {\n return -dx * Math.sin(alpha) - dy * Math.cos(alpha) + 2 * r * Math.sin(alpha)\n }\n\n // Newton-Raphson method\n // Start with a small initial guess (works well when points are mostly vertical)\n let alpha = Math.min(0.1, Math.abs(dx) / dy) // Initial guess based on aspect ratio\n const maxIterations = 20\n const tolerance = 1e-6\n\n for (let i = 0; i < maxIterations; i++) {\n const fVal = f(alpha)\n const fPrimeVal = fPrime(alpha)\n\n // Check if we've converged\n if (Math.abs(fVal) < tolerance) {\n // Verify this is a valid solution (L_y should be positive)\n const Ly = dy - 2 * r * Math.sin(alpha)\n if (Ly >= 0 && alpha > 0 && alpha < Math.PI / 2) {\n return alpha\n }\n return null\n }\n\n // Avoid division by zero\n if (Math.abs(fPrimeVal) < 1e-10) {\n break\n }\n\n // Newton-Raphson update\n const nextAlpha = alpha - fVal / fPrimeVal\n\n // Keep angle in reasonable bounds [0, π/2]\n if (nextAlpha < 0 || nextAlpha > Math.PI / 2) {\n break\n }\n\n alpha = nextAlpha\n }\n\n // If Newton-Raphson didn't converge, return null\n return null\n }\n\n static calculateSCurve(dx: number, dy: number, r: number) {\n const alpha = Lines.solveSCurveAngle(dx, dy, r)\n\n if (alpha === null) {\n return null\n }\n\n const Ly = dy - 2 * r * Math.sin(alpha)\n const Lx = Ly * Math.tan(alpha)\n const L = Ly / Math.cos(alpha)\n\n return {\n alpha, // Angle of each arc (radians)\n Lx, // Horizontal component of straight section\n Ly, // Vertical component of straight section\n L, // Length of straight section\n }\n }\n\n static pathToSVG(path: Line[]): string {\n if (!path || path.length === 0) return ''\n\n const lines = []\n\n // Start with Move command to first point\n const first = path[0]\n lines.push(`M ${first.x1},${first.y1}`)\n\n for (const line of path) {\n if (line.type === 'line') {\n lines.push(`L ${line.x2},${line.y2}`)\n } else if (line.type === 'arc') {\n const r = line.radius\n const largeArc = 0\n const sweep = line.sweep || 0\n lines.push(`A ${r},${r} 0 ${largeArc} ${sweep} ${line.x2},${line.y2}`)\n }\n }\n\n return lines.join(' ')\n }\n}","export type Dir = 'in' | 'out'\nexport type Side = 'source' | 'target'\nexport type MergeOrder = Side[]\nexport type NodeAlign = 'natural' | 'top' | 'bottom' | 'left' | 'right'\nexport type Orientation = 'TB' | 'BT' | 'LR' | 'RL'\nexport type Nav = 'first' | 'last' | 'prev' | 'next'\nexport type PortStyle = 'inside' | 'outside' | 'custom'\nexport type LayoutStep = 'alignChildren' | 'alignParents' | 'compact'\nexport type LinkType = 'edges' | 'segs'\n\nexport type Dims = {\n w: number\n h: number\n}\n\nexport type Pos = {\n x: number\n y: number\n}\n\n/** Screen coordinates - pixels relative to the browser viewport */\nexport type ScreenPos = Pos & { _brand: 'screen' }\n\n/** Canvas coordinates - pixels relative to the canvas container element */\nexport type CanvasPos = Pos & { _brand: 'canvas' }\n\n/** Graph coordinates - SVG units in the graph's coordinate space */\nexport type GraphPos = Pos & { _brand: 'graph' }\n\n/** Create a ScreenPos from x, y values */\nexport const screenPos = (x: number, y: number): ScreenPos => ({ x, y } as ScreenPos)\n\n/** Create a CanvasPos from x, y values */\nexport const canvasPos = (x: number, y: number): CanvasPos => ({ x, y } as CanvasPos)\n\n/** Create a GraphPos from x, y values */\nexport const graphPos = (x: number, y: number): GraphPos => ({ x, y } as GraphPos)\n","import { Dims, Pos, Orientation, Dir } from '../common'\nimport { Canvas } from './canvas'\nimport { PublicNodeData } from '../graph/node'\n\nexport class Node {\n selected: boolean\n hovered: boolean\n container!: SVGElement\n content!: HTMLElement\n canvas: Canvas<any, any>\n data: PublicNodeData\n isDummy: boolean\n pos?: Pos\n\n constructor(canvas: Canvas<any, any>, data: PublicNodeData, isDummy: boolean = false) {\n this.canvas = canvas\n this.data = data\n this.selected = false\n this.hovered = false\n this.isDummy = isDummy\n\n if (this.isDummy) {\n const size = canvas.dummyNodeSize\n } else {\n const render = data!.render ?? canvas.renderNode\n this.content = this.renderContent(render(data!.data, data!))\n }\n }\n\n remove() {\n this.container.remove()\n }\n\n append() {\n this.canvas.group!.appendChild(this.container)\n }\n\n needsContentSize(): boolean {\n return !this.isDummy && this.content instanceof HTMLElement\n }\n\n needsContainerSize(): boolean {\n return !this.isDummy\n }\n\n setPos(pos: Pos) {\n this.pos = pos\n const { x, y } = pos\n this.container!.setAttribute('transform', `translate(${x}, ${y})`)\n }\n\n hasPorts(): boolean {\n return !!this.data?.ports?.in?.length || !!this.data?.ports?.out?.length\n }\n\n renderContent(el: HTMLElement): HTMLElement {\n const hasPorts = this.hasPorts()\n // Ports rendered outside by default\n el = this.renderBorder(el)\n if (hasPorts)\n el = this.renderOutsidePorts(el)\n return el\n }\n\n renderContainer() {\n const hasPorts = this.hasPorts()\n const inner = this.isDummy ? this.renderDummy() : this.renderForeign()\n const nodeType = this.data?.type\n const typeClass = nodeType ? `g3p-node-type-${nodeType}` : ''\n this.container = (\n <g\n className={`g3p-node-container ${this.isDummy ? 'g3p-node-dummy' : ''} ${typeClass}`.trim()}\n data-node-id={this.data?.id}\n >\n {inner}\n </g>\n ) as SVGElement\n }\n\n renderForeign(): SVGElement {\n const { w, h } = this.data!.dims!\n return (\n <foreignObject width={w} height={h}>\n {this.content}\n </foreignObject>\n ) as SVGElement\n }\n\n renderDummy(): SVGElement {\n let w = this.canvas.dummyNodeSize\n let h = this.canvas.dummyNodeSize\n w /= 2\n h /= 2\n return (<g>\n <ellipse\n cx={w} cy={h} rx={w} ry={h}\n className=\"g3p-node-background\"\n />\n <ellipse\n cx={w} cy={h} rx={w} ry={h}\n fill=\"none\"\n className=\"g3p-node-border\"\n />\n </g>) as SVGElement\n }\n\n measure(isVertical: boolean) {\n const rect = this.content.getBoundingClientRect()\n const data = this.data!\n data.dims = { w: rect.width, h: rect.height }\n for (const dir of ['in', 'out'] as const) {\n const ports = data.ports?.[dir]\n if (!ports) continue\n for (const port of ports) {\n const el = this.content.querySelector(`.g3p-node-port[data-node-id=\"${data.id}\"][data-port-id=\"${port.id}\"]`)\n if (!el) continue\n const portRect = el.getBoundingClientRect()\n if (isVertical) {\n port.offset = portRect.left - rect.left\n port.size = portRect.width\n } else {\n port.offset = portRect.top - rect.top\n port.size = portRect.height\n }\n }\n }\n }\n\n private getPortPosition(dir: Dir): 'top' | 'bottom' | 'left' | 'right' {\n const o = this.canvas.orientation\n if (dir === 'in') {\n if (o === 'TB') return 'top'\n if (o === 'BT') return 'bottom'\n if (o === 'LR') return 'left'\n return 'right' // RL\n } else {\n if (o === 'TB') return 'bottom'\n if (o === 'BT') return 'top'\n if (o === 'LR') return 'right'\n return 'left' // RL\n }\n }\n\n private isVerticalOrientation(): boolean {\n const o = this.canvas.orientation\n return o === 'TB' || o === 'BT'\n }\n\n private isReversedOrientation(): boolean {\n const o = this.canvas.orientation\n return o === 'BT' || o === 'RL'\n }\n\n private renderPortRow(dir: Dir, inout: Dir): HTMLElement | null {\n const ports = this.data?.ports?.[dir]\n if (!ports?.length) return null\n\n const pos = this.getPortPosition(dir)\n const isVertical = this.isVerticalOrientation()\n const layoutClass = isVertical ? 'row' : 'col'\n const rotateLabels = false // TODO: make configurable via CSS class\n const rotateClass = rotateLabels ? `port-rotated-${pos}` : ''\n\n return (\n <div className={`g3p-node-ports g3p-node-ports-${layoutClass}`}>\n {ports.map(port => (\n <div\n className={`g3p-node-port g3p-node-port-${inout}-${pos} ${rotateClass}`}\n data-node-id={this.data!.id}\n data-port-id={port.id}\n >\n {port.label ?? port.id}\n </div>\n ))}\n </div>\n ) as HTMLElement\n }\n\n renderInsidePorts(el: HTMLElement): HTMLElement {\n const isVertical = this.isVerticalOrientation()\n const isReversed = this.isReversedOrientation()\n let inPorts = this.renderPortRow('in', 'in')\n let outPorts = this.renderPortRow('out', 'in')\n\n if (!inPorts && !outPorts) return el\n if (isReversed) [inPorts, outPorts] = [outPorts, inPorts]\n const wrapperClass = isVertical ? 'v' : 'h'\n\n return (\n <div className={`g3p-node-with-ports g3p-node-with-ports-${wrapperClass}`}>\n {inPorts}\n {el}\n {outPorts}\n </div>\n ) as HTMLElement\n }\n\n renderOutsidePorts(el: HTMLElement): HTMLElement {\n const isVertical = this.isVerticalOrientation()\n const isReversed = this.isReversedOrientation()\n let inPorts = this.renderPortRow('in', 'out')\n let outPorts = this.renderPortRow('out', 'out')\n\n if (!inPorts && !outPorts) return el\n if (isReversed) [inPorts, outPorts] = [outPorts, inPorts]\n const wrapperClass = isVertical ? 'v' : 'h'\n\n return (\n <div className={`g3p-node-with-ports g3p-node-with-ports-${wrapperClass}`}>\n {inPorts}\n {el}\n {outPorts}\n </div>\n ) as HTMLElement\n }\n\n renderBorder(el: HTMLElement): HTMLElement {\n return <div className=\"g3p-node-border\">\n {el}\n </div> as HTMLElement\n }\n}\n","import { Canvas } from './canvas'\nimport { normalize } from './marker'\nimport { Seg as GraphSeg } from '../graph/seg'\nimport { Graph } from '../graph/graph'\nimport { MarkerType } from './marker'\n\nexport class Seg {\n id: string\n selected: boolean\n hovered: boolean\n canvas: Canvas\n type: string | undefined\n svg: string\n el: SVGElement\n source: { marker?: MarkerType, isDummy?: boolean }\n target: { marker?: MarkerType, isDummy?: boolean }\n edgeIds: string[]\n\n constructor(canvas: Canvas, data: GraphSeg, g: Graph) {\n this.id = data.id\n this.canvas = canvas\n this.selected = false\n this.hovered = false\n this.svg = data.svg!\n this.source = { ...data.source, isDummy: data.sourceNode(g).isDummy }\n this.target = { ...data.target, isDummy: data.targetNode(g).isDummy }\n this.type = data.type\n this.edgeIds = data.edgeIds.toArray()\n this.el = this.render()\n }\n\n append() {\n this.canvas.group!.appendChild(this.el!)\n }\n\n remove() {\n this.el!.remove()\n }\n\n update(data: GraphSeg, g: Graph) {\n this.svg = data.svg!\n this.type = data.type\n this.source = { ...data.source, isDummy: data.sourceNode(g).isDummy }\n this.target = { ...data.target, isDummy: data.targetNode(g).isDummy }\n this.edgeIds = data.edgeIds.toArray()\n this.remove()\n this.el = this.render()\n this.append()\n }\n\n render(): SVGElement {\n let { source, target } = normalize(this)\n if (this.source.isDummy) source = undefined\n if (this.target.isDummy) target = undefined\n const typeClass = this.type ? `g3p-edge-type-${this.type}` : ''\n const prefix = this.canvas.markerPrefix\n const markerStartId = source ? (prefix ? `${prefix}-g3p-marker-${source}-reverse` : `g3p-marker-${source}-reverse`) : undefined\n const markerEndId = target ? (prefix ? `${prefix}-g3p-marker-${target}` : `g3p-marker-${target}`) : undefined\n return (\n <g\n ref={(el: SVGElement) => this.el = el}\n id={`g3p-seg-${this.id}`}\n className={`g3p-seg-container ${typeClass}`.trim()}\n data-edge-id={this.id}\n >\n <path\n d={this.svg}\n fill=\"none\"\n className=\"g3p-seg-line\"\n markerStart={markerStartId ? `url(#${markerStartId})` : undefined}\n markerEnd={markerEndId ? `url(#${markerEndId})` : undefined}\n />\n <path\n d={this.svg}\n stroke=\"transparent\"\n fill=\"none\"\n className=\"g3p-seg-hitbox\"\n style={{ cursor: 'pointer' }}\n />\n </g>\n ) as SVGElement\n }\n}\n","import { CanvasPos, GraphPos } from '../common'\n\n/** Target for edge drop */\nexport type EdgeDropTarget =\n | { type: 'node'; id: string; port?: string }\n | { type: 'canvas' }\n | null\n\n/**\n * Edit mode states for the canvas.\n */\nexport type EditState =\n | { type: 'idle' }\n | { type: 'panning'; startCanvas: CanvasPos; startTransform: { x: number; y: number; scale: number } }\n | { type: 'new-edge'; source: { id: string, port?: string }; startGraph: GraphPos; currentGraph: GraphPos; target: EdgeDropTarget }\n\n/**\n * Edit mode state machine for the canvas.\n * Manages transitions between idle, panning, and new-edge creation states.\n */\nexport class EditMode {\n private _state: EditState = { type: 'idle' }\n private _editable: boolean = false\n\n get state(): EditState {\n return this._state\n }\n\n get editable(): boolean {\n return this._editable\n }\n\n set editable(value: boolean) {\n this._editable = value\n if (!value) {\n this.reset()\n }\n }\n\n get isIdle(): boolean {\n return this._state.type === 'idle'\n }\n\n get isPanning(): boolean {\n return this._state.type === 'panning'\n }\n\n get isCreatingEdge(): boolean {\n return this._state.type === 'new-edge'\n }\n\n /** Start panning the canvas */\n startPan(startCanvas: CanvasPos, startTransform: { x: number; y: number; scale: number }): void {\n this._state = { type: 'panning', startCanvas, startTransform }\n }\n\n /** Start creating a new edge from a node or port */\n startNewEdge(id: string, startGraph: GraphPos, port?: string): void {\n if (!this._editable) return\n this._state = {\n type: 'new-edge',\n source: { id, port },\n startGraph,\n currentGraph: startGraph,\n target: null,\n }\n }\n\n /** Update the current position during new-edge mode */\n updateNewEdgePosition(currentGraph: GraphPos): void {\n if (this._state.type === 'new-edge') {\n this._state = { ...this._state, currentGraph }\n }\n }\n\n /** Update the hover target during new-edge mode */\n setHoverTarget(target: EdgeDropTarget): void {\n if (this._state.type === 'new-edge') {\n this._state = { ...this._state, target }\n }\n }\n\n /** Get the new-edge state if active */\n getNewEdgeState(): Extract<EditState, { type: 'new-edge' }> | null {\n if (this._state.type === 'new-edge') {\n return this._state\n }\n return null\n }\n\n /** Reset to idle state */\n reset(): void {\n this._state = { type: 'idle' }\n }\n}\n","import { GraphPos } from '../common'\n\nimport styles from './newEdge.css?raw'\n\nexport type NewEdgeProps = {\n start: GraphPos\n end: GraphPos\n}\n\n/**\n * Renders the animated dashed line during new-edge creation mode.\n */\nexport function renderNewEdge({ start, end }: NewEdgeProps): SVGElement {\n return (\n <g className=\"g3p-new-edge-container\">\n {/* Origin indicator */}\n <circle\n cx={start.x}\n cy={start.y}\n r={4}\n className=\"g3p-new-edge-origin\"\n />\n {/* Animated dashed line */}\n <line\n x1={start.x}\n y1={start.y}\n x2={end.x}\n y2={end.y}\n className=\"g3p-new-edge-line\"\n />\n {/* End indicator */}\n <circle\n cx={end.x}\n cy={end.y}\n r={3}\n className=\"g3p-new-edge-end\"\n />\n </g>\n ) as SVGElement\n}\n","import { ScreenPos } from '../common'\nimport { MarkerType } from './marker'\nimport { PublicEdgeData } from '../graph/edge'\nimport { PublicNodeData } from '../graph/node'\nimport { EditEdgeProps, EditNodeProps } from '../api/api'\nimport { NewNode } from '../api/options'\n\nexport type FieldType = 'string' | 'number' | 'boolean'\nexport type DetectedFields = Map<string, FieldType>\n\nexport type ModalResult<T> = T | null\n\nexport interface ModalOptions {\n title: string\n position?: ScreenPos\n onClose: () => void\n}\n\n/**\n * Base modal component for edit mode dialogs\n */\nexport class Modal {\n protected container: HTMLElement\n protected overlay: HTMLElement\n protected dialog: HTMLElement\n protected onClose: () => void\n private mouseDownOnOverlay = false\n\n constructor(options: ModalOptions) {\n this.onClose = options.onClose\n\n // Create overlay - track mousedown origin to avoid closing when dragging text selection\n this.overlay = (\n <div\n className=\"g3p-modal-overlay\"\n onMouseDown={(e) => {\n this.mouseDownOnOverlay = e.target === this.overlay\n }}\n onMouseUp={(e) => {\n if (this.mouseDownOnOverlay && e.target === this.overlay) this.close()\n this.mouseDownOnOverlay = false\n }}\n />\n ) as HTMLElement\n\n // Create dialog\n this.dialog = (\n <div className=\"g3p-modal-dialog\">\n <div className=\"g3p-modal-header\">\n <span className=\"g3p-modal-title\">{options.title}</span>\n <button\n className=\"g3p-modal-close\"\n onClick={() => this.close()}\n >×</button>\n </div>\n <div className=\"g3p-modal-body\" />\n <div className=\"g3p-modal-footer\" />\n </div>\n ) as HTMLElement\n\n // Position dialog if specified\n if (options.position) {\n this.dialog.style.position = 'absolute'\n this.dialog.style.left = `${options.position.x}px`\n this.dialog.style.top = `${options.position.y}px`\n this.dialog.style.transform = 'translate(-50%, -50%)'\n }\n\n this.overlay.appendChild(this.dialog)\n this.container = this.overlay\n\n // Handle escape key\n this.handleKeyDown = this.handleKeyDown.bind(this)\n document.addEventListener('keydown', this.handleKeyDown)\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n this.close()\n }\n }\n\n protected get body(): HTMLElement {\n return this.dialog.querySelector('.g3p-modal-body') as HTMLElement\n }\n\n protected get footer(): HTMLElement {\n return this.dialog.querySelector('.g3p-modal-footer') as HTMLElement\n }\n\n show(parent: HTMLElement) {\n parent.appendChild(this.container)\n // Focus first input\n const firstInput = this.dialog.querySelector('input, select, button') as HTMLElement\n if (firstInput) firstInput.focus()\n }\n\n close() {\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.onClose()\n }\n}\n\n// ==================== New Node Modal ====================\n\nexport interface NewNodeModalOptions {\n nodeTypes?: string[]\n fields?: DetectedFields\n onSubmit: (data: Record<string, any>) => void\n onCancel?: () => void\n}\n\nexport class NewNodeModal extends Modal {\n private fieldInputs: Map<string, HTMLInputElement | HTMLSelectElement> = new Map()\n private typeSelect?: HTMLSelectElement\n private submitCallback: NewNodeModalOptions['onSubmit']\n private fields: DetectedFields\n\n constructor(options: NewNodeModalOptions) {\n super({\n title: 'New Node',\n onClose: () => options.onCancel?.()\n })\n this.submitCallback = options.onSubmit\n this.fields = options.fields ?? new Map([['title', 'string']])\n this.renderBody(options.nodeTypes)\n this.renderFooter()\n }\n\n private renderBody(nodeTypes?: string[]) {\n this.body.innerHTML = ''\n\n // Render dynamic fields\n for (const [name, type] of this.fields) {\n const label = name.charAt(0).toUpperCase() + name.slice(1)\n const fieldGroup = this.renderField(name, label, type)\n this.body.appendChild(fieldGroup)\n }\n\n // Type selector (if types provided)\n if (nodeTypes && nodeTypes.length > 0) {\n const typeGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Type</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.typeSelect = el}\n >\n <option value=\"\">Default</option>\n {nodeTypes.map(type => (\n <option value={type}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(typeGroup)\n }\n }\n\n private renderField(name: string, label: string, type: FieldType): HTMLElement {\n if (type === 'boolean') {\n return (\n <div className=\"g3p-modal-field g3p-modal-field-checkbox\">\n <label className=\"g3p-modal-label\">\n <input\n type=\"checkbox\"\n className=\"g3p-modal-checkbox\"\n ref={(el: HTMLInputElement) => this.fieldInputs.set(name, el)}\n />\n {label}\n </label>\n </div>\n ) as HTMLElement\n }\n return (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">{label}</label>\n <input\n type={type === 'number' ? 'number' : 'text'}\n className=\"g3p-modal-input\"\n placeholder={`Enter ${label.toLowerCase()}`}\n ref={(el: HTMLInputElement) => this.fieldInputs.set(name, el)}\n />\n </div>\n ) as HTMLElement\n }\n\n private renderFooter() {\n this.footer.innerHTML = ''\n this.footer.appendChild(\n <div className=\"g3p-modal-buttons\">\n <button\n className=\"g3p-modal-btn g3p-modal-btn-secondary\"\n onClick={() => this.close()}\n >Cancel</button>\n <button\n className=\"g3p-modal-btn g3p-modal-btn-primary\"\n onClick={() => this.submit()}\n >Create</button>\n </div> as HTMLElement\n )\n }\n\n private submit() {\n const data: Record<string, any> = {}\n\n // Collect field values\n for (const [name, type] of this.fields) {\n const input = this.fieldInputs.get(name)\n if (!input) continue\n if (type === 'boolean') {\n data[name] = (input as HTMLInputElement).checked\n } else if (type === 'number') {\n const val = (input as HTMLInputElement).value\n if (val) data[name] = Number(val)\n } else {\n const val = (input as HTMLInputElement).value.trim()\n if (val) data[name] = val\n }\n }\n\n // Require at least one field to be filled\n if (Object.keys(data).length === 0) {\n const firstInput = this.fieldInputs.values().next().value\n if (firstInput) firstInput.focus()\n return\n }\n\n if (this.typeSelect?.value) {\n data.type = this.typeSelect.value\n }\n\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.submitCallback(data)\n }\n}\n\n// ==================== Edit Node Modal ====================\n\nexport interface EditNodeModalOptions {\n node: Record<string, any>\n position?: ScreenPos\n nodeTypes?: string[]\n fields?: DetectedFields\n onSubmit: (data: Record<string, any>) => void\n onDelete?: () => void\n onCancel?: () => void\n}\n\nexport class EditNodeModal extends Modal {\n private fieldInputs: Map<string, HTMLInputElement | HTMLSelectElement> = new Map()\n private typeSelect?: HTMLSelectElement\n private node: Record<string, any>\n private fields: DetectedFields\n private submitCallback: EditNodeModalOptions['onSubmit']\n private deleteCallback?: () => void\n\n constructor(options: EditNodeModalOptions) {\n super({\n title: 'Edit Node',\n position: options.position,\n onClose: () => options.onCancel?.()\n })\n this.node = options.node\n this.submitCallback = options.onSubmit\n this.deleteCallback = options.onDelete\n this.fields = options.fields ?? new Map([['title', 'string']])\n if (!options.fields && !this.node.title)\n this.node = { ...this.node, title: this.node.id }\n this.renderBody(options.nodeTypes)\n this.renderFooter()\n }\n\n private renderBody(nodeTypes?: string[]) {\n console.log(`renderBody`, this.node)\n this.body.innerHTML = ''\n\n // Render dynamic fields with current values\n for (const [name, type] of this.fields) {\n const label = name.charAt(0).toUpperCase() + name.slice(1)\n const currentValue = this.node[name]\n const fieldGroup = this.renderField(name, label, type, currentValue)\n this.body.appendChild(fieldGroup)\n }\n\n // Type selector (if types provided)\n if (nodeTypes && nodeTypes.length > 0) {\n const currentType = this.node.type ?? ''\n const typeGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Type</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.typeSelect = el}\n >\n <option value=\"\" selected={!currentType}>Default</option>\n {nodeTypes.map(type => (\n <option value={type} selected={type === currentType}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(typeGroup)\n }\n }\n\n private renderField(name: string, label: string, type: FieldType, currentValue?: any): HTMLElement {\n if (type === 'boolean') {\n return (\n <div className=\"g3p-modal-field g3p-modal-field-checkbox\">\n <label className=\"g3p-modal-label\">\n <input\n type=\"checkbox\"\n className=\"g3p-modal-checkbox\"\n checked={!!currentValue}\n ref={(el: HTMLInputElement) => this.fieldInputs.set(name, el)}\n />\n {label}\n </label>\n </div>\n ) as HTMLElement\n }\n return (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">{label}</label>\n <input\n type={type === 'number' ? 'number' : 'text'}\n className=\"g3p-modal-input\"\n value={currentValue ?? ''}\n ref={(el: HTMLInputElement) => this.fieldInputs.set(name, el)}\n />\n </div>\n ) as HTMLElement\n }\n\n private renderFooter() {\n this.footer.innerHTML = ''\n this.footer.appendChild(\n <div className=\"g3p-modal-buttons\">\n {this.deleteCallback && (\n <button\n className=\"g3p-modal-btn g3p-modal-btn-danger\"\n onClick={() => this.delete()}\n >Delete</button>\n )}\n <div className=\"g3p-modal-spacer\" />\n <button\n className=\"g3p-modal-btn g3p-modal-btn-secondary\"\n onClick={() => this.close()}\n >Cancel</button>\n <button\n className=\"g3p-modal-btn g3p-modal-btn-primary\"\n onClick={() => this.submit()}\n >Save</button>\n </div> as HTMLElement\n )\n }\n\n private submit() {\n const data: Record<string, any> = { ...this.node }\n\n // Collect field values\n for (const [name, type] of this.fields) {\n const input = this.fieldInputs.get(name)\n if (!input) continue\n if (type === 'boolean') {\n data[name] = (input as HTMLInputElement).checked\n } else if (type === 'number') {\n const val = (input as HTMLInputElement).value\n data[name] = val ? Number(val) : undefined\n } else {\n const val = (input as HTMLInputElement).value.trim()\n data[name] = val || undefined\n }\n }\n\n if (this.typeSelect) {\n data.type = this.typeSelect.value || undefined\n }\n\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.submitCallback(data)\n }\n\n private delete() {\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.deleteCallback?.()\n }\n}\n\n// ==================== Edit Edge Modal ====================\n\nexport interface EditEdgeModalOptions {\n edge: EditEdgeProps\n edgeTypes?: string[]\n onSubmit: (data: EditEdgeProps) => void\n onCancel?: () => void\n onDelete?: () => void\n}\n\nexport class EditEdgeModal extends Modal {\n private sourceMarkerSelect!: HTMLSelectElement\n private targetMarkerSelect!: HTMLSelectElement\n private typeSelect?: HTMLSelectElement\n private edge: EditEdgeProps\n private submitCallback: EditEdgeModalOptions['onSubmit']\n private deleteCallback?: () => void\n\n private static markerTypes: MarkerType[] = ['none', 'arrow', 'circle', 'diamond', 'bar']\n\n constructor(options: EditEdgeModalOptions) {\n super({\n title: 'Edit Edge',\n onClose: () => options.onCancel?.()\n })\n this.edge = options.edge\n this.submitCallback = options.onSubmit\n this.deleteCallback = options.onDelete\n this.renderBody(options.edgeTypes)\n this.renderFooter()\n }\n\n private renderBody(edgeTypes?: string[]) {\n this.body.innerHTML = ''\n\n const currentSourceMarker = this.edge.source?.marker ?? 'none'\n const currentTargetMarker = this.edge.target?.marker ?? 'arrow'\n\n // Source marker\n const sourceGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Source Marker</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.sourceMarkerSelect = el}\n >\n {EditEdgeModal.markerTypes.map(type => (\n <option value={type} selected={type === currentSourceMarker}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(sourceGroup)\n\n // Target marker\n const targetGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Target Marker</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.targetMarkerSelect = el}\n >\n {EditEdgeModal.markerTypes.map(type => (\n <option value={type} selected={type === currentTargetMarker}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(targetGroup)\n\n // Type selector (if types provided)\n if (edgeTypes && edgeTypes.length > 0) {\n const currentType = this.edge.type ?? ''\n const typeGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Type</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.typeSelect = el}\n >\n <option value=\"\" selected={!currentType}>Default</option>\n {edgeTypes.map(type => (\n <option value={type} selected={type === currentType}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(typeGroup)\n }\n }\n\n private renderFooter() {\n this.footer.innerHTML = ''\n this.footer.appendChild(\n <div className=\"g3p-modal-buttons\">\n {this.deleteCallback && (\n <button\n className=\"g3p-modal-btn g3p-modal-btn-danger\"\n onClick={() => this.delete()}\n >Delete</button>\n )}\n <div className=\"g3p-modal-spacer\" />\n <button\n className=\"g3p-modal-btn g3p-modal-btn-secondary\"\n onClick={() => this.close()}\n >Cancel</button>\n <button\n className=\"g3p-modal-btn g3p-modal-btn-primary\"\n onClick={() => this.submit()}\n >Save</button>\n </div> as HTMLElement\n )\n }\n\n private submit() {\n const data: EditEdgeProps = {\n ...this.edge,\n source: {\n ...this.edge.source,\n marker: this.sourceMarkerSelect.value === 'none' ? undefined : this.sourceMarkerSelect.value as MarkerType,\n },\n target: {\n ...this.edge.target,\n marker: this.targetMarkerSelect.value === 'none' ? undefined : this.targetMarkerSelect.value as MarkerType,\n },\n }\n\n if (this.typeSelect) {\n data.type = this.typeSelect.value || undefined\n }\n\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.submitCallback(data)\n }\n\n private delete() {\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.deleteCallback?.()\n }\n}\n","/* ==================== Theme Variables ==================== */\n\n/* Light theme (default) */\n:root {\n --g3p-bg: #fafafa;\n --g3p-bg-node: #ffffff;\n --g3p-bg-secondary: #f8fafc;\n --g3p-border: #e2e8f0;\n --g3p-border-hover: #cbd5e1;\n --g3p-border-selected: #3b82f6;\n --g3p-text: #1e293b;\n --g3p-text-muted: #475569;\n --g3p-text-subtle: #64748b;\n --g3p-edge-color: #64748b;\n --g3p-port-bg: #e2e8f0;\n --g3p-port-bg-hover: #cbd5e1;\n --g3p-shadow: rgba(0, 0, 0, 0.15);\n}\n\n/* Dark theme (auto via prefers-color-scheme) */\n@media (prefers-color-scheme: dark) {\n :root {\n --g3p-bg: #1a1a1a;\n --g3p-bg-node: #333333;\n --g3p-bg-secondary: #2a2a2a;\n --g3p-border: #4a4a4a;\n --g3p-border-hover: #5a5a5a;\n --g3p-border-selected: #60a5fa;\n --g3p-text: #f0f0f0;\n --g3p-text-muted: #c0c0c0;\n --g3p-text-subtle: #909090;\n --g3p-edge-color: #b0b0b0;\n --g3p-port-bg: #444444;\n --g3p-port-bg-hover: #555555;\n --g3p-shadow: rgba(0, 0, 0, 0.5);\n }\n}\n\n/* Explicit light mode override */\n.g3p-light {\n --g3p-bg: #fafafa;\n --g3p-bg-node: #ffffff;\n --g3p-bg-secondary: #f8fafc;\n --g3p-border: #e2e8f0;\n --g3p-border-hover: #cbd5e1;\n --g3p-border-selected: #3b82f6;\n --g3p-text: #1e293b;\n --g3p-text-muted: #475569;\n --g3p-text-subtle: #64748b;\n --g3p-edge-color: #64748b;\n --g3p-port-bg: #e2e8f0;\n --g3p-port-bg-hover: #cbd5e1;\n --g3p-shadow: rgba(0, 0, 0, 0.15);\n}\n\n/* Explicit dark mode override */\n.g3p-dark {\n --g3p-bg: #1a1a1a;\n --g3p-bg-node: #333333;\n --g3p-bg-secondary: #2a2a2a;\n --g3p-border: #4a4a4a;\n --g3p-border-hover: #5a5a5a;\n --g3p-border-selected: #60a5fa;\n --g3p-text: #f0f0f0;\n --g3p-text-muted: #c0c0c0;\n --g3p-text-subtle: #909090;\n --g3p-edge-color: #b0b0b0;\n --g3p-port-bg: #444444;\n --g3p-port-bg-hover: #555555;\n --g3p-shadow: rgba(0, 0, 0, 0.5);\n}\n\n/* ==================== Canvas ==================== */\n\n.g3p-canvas-container {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.g3p-canvas-root {\n display: block;\n width: 100%;\n height: 100%;\n user-select: none;\n background: var(--g3p-bg);\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n/* ==================== Zoom Controls ==================== */\n\n.g3p-zoom-controls {\n position: absolute;\n bottom: 1rem;\n right: 1rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n background: var(--g3p-bg-node);\n border-radius: 8px;\n padding: 0.5rem;\n box-shadow: 0 2px 8px var(--g3p-shadow);\n z-index: 10;\n}\n\n.g3p-zoom-btn {\n width: 36px;\n height: 36px;\n border: 1px solid var(--g3p-border);\n background: var(--g3p-bg-node);\n border-radius: 6px;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--g3p-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n}\n\n.g3p-zoom-btn:hover {\n background: var(--g3p-bg-secondary);\n border-color: var(--g3p-border-hover);\n color: var(--g3p-text);\n}\n\n.g3p-zoom-btn:active {\n transform: scale(0.95);\n}\n\n.g3p-zoom-reset {\n font-size: 1.1rem;\n}\n\n.g3p-zoom-level {\n text-align: center;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--g3p-text-subtle);\n padding: 0.25rem 0;\n}\n\n/* ==================== Nodes ==================== */\n\n/* Default node content styles */\n.g3p-node-default {\n padding: 8px 12px;\n font: 14px/1.4 system-ui, sans-serif;\n color: var(--g3p-text);\n}\n\n.g3p-node-title {\n font-weight: 500;\n}\n\n.g3p-node-detail {\n font-size: 12px;\n color: var(--g3p-text-muted);\n margin-top: 2px;\n}\n\n.g3p-node-container {\n transition: opacity 0.2s ease;\n}\n\n.g3p-node-border {\n background: var(--g3p-bg-node);\n border: 1px solid var(--g3p-border);\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.15s ease;\n}\n\n.g3p-node-border:hover {\n border-color: var(--g3p-border-hover);\n}\n\n.g3p-node-border.selected {\n outline: 2px solid var(--g3p-border-selected);\n}\n\n.g3p-node-content-wrapper {\n pointer-events: none;\n}\n\n.g3p-node-content {\n pointer-events: auto;\n box-sizing: border-box;\n}\n\n.g3p-node-content>div {\n width: 100%;\n height: 100%;\n}\n\n/* Dummy node styles - these remain SVG since dummies are ellipses */\n.g3p-node-dummy .g3p-node-background {\n fill: var(--g3p-bg-secondary);\n opacity: 0.8;\n}\n\n.g3p-node-dummy {\n stroke: var(--g3p-border-hover);\n stroke-dasharray: 3, 3;\n cursor: default;\n}\n\n/* Port container styles */\n.g3p-node-ports {\n display: flex;\n gap: 4px;\n}\n\n.g3p-node-ports-row {\n flex-direction: row;\n justify-content: center;\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.g3p-node-ports-col {\n flex-direction: column;\n justify-content: center;\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n/* Port styles */\n.g3p-node-port {\n background: var(--g3p-port-bg);\n border: 1px solid var(--g3p-border-hover);\n padding: 2px 6px;\n font-size: 0.5em;\n color: var(--g3p-text-muted);\n white-space: nowrap;\n transition: all 0.15s ease;\n}\n\n.g3p-node-port:hover {\n background: var(--g3p-port-bg-hover);\n border-color: var(--g3p-text-subtle);\n}\n\n.g3p-node-port-rotated-left {\n writing-mode: vertical-lr;\n}\n\n.g3p-node-port-rotated-right {\n writing-mode: vertical-rl;\n}\n\n/* Outside ports: rounded corners away from the node rectangle, no border on touching side */\n.g3p-node-port-out-top {\n border-radius: 4px 4px 0 0;\n border-bottom: none;\n}\n\n.g3p-node-port-out-bottom {\n border-radius: 0 0 4px 4px;\n border-top: none;\n}\n\n.g3p-node-port-out-left {\n border-radius: 4px 0 0 4px;\n border-right: none;\n}\n\n.g3p-node-port-out-right {\n border-radius: 0 4px 4px 0;\n border-left: none;\n}\n\n/* Inside ports: rounded corners toward the content, no border on outer edge */\n.g3p-node-port-in-top {\n border-radius: 0 0 4px 4px;\n border-top: none;\n}\n\n.g3p-node-port-in-bottom {\n border-radius: 4px 4px 0 0;\n border-bottom: none;\n}\n\n.g3p-node-port-in-left {\n border-radius: 0 4px 4px 0;\n border-left: none;\n}\n\n.g3p-node-port-in-right {\n border-radius: 4px 0 0 4px;\n border-right: none;\n}\n\n/* Port wrapper */\n.g3p-node-with-ports {\n display: flex;\n}\n\n.g3p-node-with-ports-v {\n flex-direction: column;\n}\n\n.g3p-node-with-ports-h {\n flex-direction: row;\n}\n\n/* ==================== Edges (Segments) ==================== */\n\n.g3p-seg-container {\n transition: opacity 0.2s ease;\n}\n\n.g3p-seg-line {\n stroke: var(--g3p-edge-color);\n stroke-width: 1;\n transition: stroke 0.2s ease, stroke-width 0.2s ease;\n}\n\n.g3p-seg-marker {\n fill: var(--g3p-edge-color);\n}\n\n.g3p-seg-line.hovered {\n stroke-width: 2;\n opacity: 1;\n}\n\n.g3p-seg-line.selected {\n stroke: var(--g3p-border-selected);\n stroke-width: 2;\n}\n\n.g3p-seg-hitbox {\n cursor: pointer;\n}\n\n/* ==================== Markers ==================== */\n\n.g3p-marker {\n fill: context-stroke;\n stroke: none;\n}\n\n.g3p-marker-bar {\n fill: none;\n stroke: context-stroke;\n stroke-width: 2;\n}\n\n.g3p-marker.hovered {\n fill: var(--g3p-text-muted);\n}\n\n.g3p-marker.selected {\n fill: var(--g3p-border-selected);\n}\n\n.g3p-marker-bar.hovered {\n stroke: var(--g3p-text-muted);\n}\n\n.g3p-marker-bar.selected {\n stroke: var(--g3p-border-selected);\n}\n\n/* ==================== New Edge (Edit Mode) ==================== */\n\n.g3p-new-edge-container {\n pointer-events: none;\n}\n\n.g3p-new-edge-origin {\n fill: var(--g3p-edge-color, #64748b);\n stroke: none;\n}\n\n.g3p-new-edge-line {\n stroke: var(--g3p-edge-color, #64748b);\n stroke-width: 2;\n stroke-dasharray: 6 4;\n stroke-linecap: round;\n fill: none;\n animation: g3p-dash-animation 0.5s linear infinite;\n}\n\n.g3p-new-edge-end {\n fill: var(--g3p-edge-color, #64748b);\n stroke: white;\n stroke-width: 1.5;\n}\n\n@keyframes g3p-dash-animation {\n to {\n stroke-dashoffset: -10;\n }\n}\n\n/* ==================== Edit Mode Hover States ==================== */\n\n.g3p-node-container.g3p-drop-target .g3p-node-border {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n.g3p-node-port.g3p-drop-target {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n/* ==================== Modals ==================== */\n\n.g3p-modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.g3p-modal-dialog {\n background: var(--g3p-bg-node);\n border: 1px solid var(--g3p-border);\n border-radius: 8px;\n box-shadow: 0 4px 20px var(--g3p-shadow);\n min-width: 280px;\n max-width: 400px;\n}\n\n.g3p-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--g3p-border);\n}\n\n.g3p-modal-title {\n font-weight: 600;\n font-size: 14px;\n color: var(--g3p-text);\n}\n\n.g3p-modal-close {\n background: none;\n border: none;\n font-size: 20px;\n color: var(--g3p-text-muted);\n cursor: pointer;\n padding: 0;\n line-height: 1;\n}\n\n.g3p-modal-close:hover {\n color: var(--g3p-text);\n}\n\n.g3p-modal-body {\n padding: 16px;\n}\n\n.g3p-modal-field {\n margin-bottom: 12px;\n}\n\n.g3p-modal-field:last-child {\n margin-bottom: 0;\n}\n\n.g3p-modal-label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--g3p-text-muted);\n margin-bottom: 4px;\n}\n\n.g3p-modal-input,\n.g3p-modal-select {\n width: 100%;\n padding: 8px 10px;\n font-size: 13px;\n border: 1px solid var(--g3p-border);\n border-radius: 4px;\n background: var(--g3p-bg);\n color: var(--g3p-text);\n box-sizing: border-box;\n}\n\n.g3p-modal-input:focus,\n.g3p-modal-select:focus {\n outline: none;\n border-color: var(--g3p-border-selected);\n}\n\n.g3p-modal-footer {\n padding: 12px 16px;\n border-top: 1px solid var(--g3p-border);\n}\n\n.g3p-modal-buttons {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.g3p-modal-spacer {\n flex: 1;\n}\n\n.g3p-modal-btn {\n padding: 6px 12px;\n font-size: 13px;\n font-weight: 500;\n border-radius: 4px;\n cursor: pointer;\n border: 1px solid transparent;\n transition: all 0.15s ease;\n}\n\n.g3p-modal-btn-primary {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n.g3p-modal-btn-primary:hover {\n filter: brightness(1.1);\n}\n\n.g3p-modal-btn-secondary {\n background: var(--g3p-bg);\n border-color: var(--g3p-border);\n color: var(--g3p-text);\n}\n\n.g3p-modal-btn-secondary:hover {\n background: var(--g3p-bg-secondary);\n}\n\n.g3p-modal-btn-danger {\n background: #ef4444;\n color: white;\n}\n\n.g3p-modal-btn-danger:hover {\n background: #dc2626;\n}","import { Pos, Orientation, ScreenPos, CanvasPos, GraphPos, screenPos, canvasPos, graphPos } from '../common'\nimport { Node } from './node'\nimport { Seg } from './seg'\nimport { Graph } from '../graph/graph'\nimport { CanvasOptions, RenderNode, ThemeVars, NewEdge, NewNode } from '../api/options'\nimport { NodeId, NodeKey, PublicNodeData, PortId, Node as GraphNode } from '../graph/node'\nimport { SegId, Seg as GraphSeg } from '../graph/seg'\nimport { logger } from '../log'\nimport { markerDefs } from './marker'\nimport { EditMode } from './editMode'\nimport { renderNewEdge } from './newEdge'\nimport { NewNodeModal, EditNodeModal, EditEdgeModal } from './modal'\nimport { API, EditNodeProps, EditEdgeProps } from '../api/api'\n\nimport styles from './styles.css?raw'\n\nconst log = logger('canvas')\n\ntype ViewportTransform = {\n x: number\n y: number\n scale: number\n}\n\ntype Bounds = {\n min: Pos\n max: Pos\n}\n\ntype CanvasData<N, E> = Required<CanvasOptions<N>> & {\n renderNode: RenderNode<N>\n dummyNodeSize: number\n orientation: Orientation\n}\n\nexport interface Canvas<N, E> extends CanvasData<N, E> { }\n\nexport class Canvas<N, E> {\n container?: HTMLElement\n root?: SVGElement\n group?: SVGElement\n transform!: ViewportTransform\n bounds!: Bounds\n measurement?: HTMLElement\n allNodes!: Map<NodeKey, Node>\n curNodes!: Map<NodeId, Node>\n curSegs!: Map<SegId, Seg>\n updating!: boolean\n\n // Unique marker ID prefix for this canvas instance\n markerPrefix: string\n\n // Dynamic style element for this instance (for cleanup)\n private dynamicStyleEl?: HTMLStyleElement\n\n // Pan-zoom state\n private panScale: { x: number, y: number } | null = null\n private zoomControls?: HTMLElement\n\n // Edit mode state machine\n editMode!: EditMode\n api: API<N, E>\n\n // New-edge visual element\n private newEdgeEl?: SVGElement\n\n // Pending drag state (for double-click debounce)\n private pendingDrag: { timeout: number, nodeId: string, startGraph: GraphPos, portId?: string } | null = null\n\n constructor(api: API<N, E>, options: CanvasData<N, E>) {\n Object.assign(this, options)\n this.api = api\n this.reset()\n // Generate unique marker prefix based on root ID (sanitize for use in IDs)\n this.markerPrefix = api.root.replace(/[^a-zA-Z0-9-_]/g, '-')\n this.createMeasurementContainer()\n this.createCanvasContainer()\n if (this.panZoom) this.setupPanZoom()\n }\n\n reset() {\n this.allNodes = new Map()\n this.curNodes = new Map()\n this.curSegs = new Map()\n this.updating = false\n this.bounds = { min: { x: 0, y: 0 }, max: { x: 0, y: 0 } }\n this.transform = { x: 0, y: 0, scale: 1 }\n this.editMode = new EditMode()\n this.editMode.editable = this.editable\n if (this.group) this.group.innerHTML = ''\n }\n\n private createMeasurementContainer() {\n this.measurement = document.createElement('div')\n this.measurement.style.cssText = `\n position: absolute;\n left: -9999px;\n top: -9999px;\n visibility: hidden;\n pointer-events: none;\n `\n document.body.appendChild(this.measurement)\n }\n\n getNode(key: NodeKey): Node {\n const node = this.allNodes.get(key)\n if (!node) throw new Error(`node not found: ${key}`)\n return node\n }\n\n update() {\n let bx0 = Infinity, by0 = Infinity\n let bx1 = -Infinity, by1 = -Infinity\n for (const node of this.curNodes.values()) {\n const { x, y } = node.pos!\n const { w, h } = node.data!.dims!\n const nx0 = x, nx1 = x + w\n const ny0 = y, ny1 = y + h\n bx0 = Math.min(bx0, nx0)\n by0 = Math.min(by0, ny0)\n bx1 = Math.max(bx1, nx1)\n by1 = Math.max(by1, ny1)\n }\n this.bounds = { min: { x: bx0, y: by0 }, max: { x: bx1, y: by1 } }\n this.root!.setAttribute('viewBox', this.viewBox())\n }\n\n addNode(gnode: GraphNode) {\n if (this.curNodes.has(gnode.id))\n throw new Error('node already exists')\n const { key } = gnode\n let node: Node\n if (gnode.isDummy) {\n node = new Node(this, gnode, true)\n node.renderContainer()\n this.allNodes.set(key, node)\n } else {\n if (!this.allNodes.has(key))\n throw new Error('node has not been measured')\n node = this.getNode(key)\n }\n this.curNodes.set(gnode.id, node)\n node.append()\n node.setPos(gnode.pos!)\n }\n\n updateNode(gnode: GraphNode) {\n if (gnode.isDummy) throw new Error('dummy node cannot be updated')\n const node = this.getNode(gnode.key)\n const cur = this.curNodes.get(gnode.id)\n if (cur) cur.remove()\n this.curNodes.set(gnode.id, node)\n node.append()\n }\n\n deleteNode(gnode: GraphNode) {\n const node = this.getNode(gnode.key)\n this.curNodes.delete(gnode.id)\n node.remove()\n }\n\n addSeg(gseg: GraphSeg, g: Graph) {\n if (this.curSegs.has(gseg.id))\n throw new Error('seg already exists')\n const seg = new Seg(this, gseg, g)\n this.curSegs.set(gseg.id, seg)\n seg.append()\n }\n\n updateSeg(gseg: GraphSeg, g: Graph) {\n const seg = this.curSegs.get(gseg.id)\n if (!seg) throw new Error('seg not found')\n seg.update(gseg, g)\n }\n\n deleteSeg(gseg: GraphSeg) {\n const seg = this.curSegs.get(gseg.id)\n if (!seg) throw new Error('seg not found')\n this.curSegs.delete(gseg.id)\n seg.remove()\n }\n\n async measureNodes(nodes: PublicNodeData[]): Promise<Map<any, Node>> {\n const newNodes: Map<any, Node> = new Map()\n for (const data of nodes) {\n const node = new Node(this, data)\n newNodes.set(data.data, node)\n this.measurement!.appendChild(node.content)\n }\n await new Promise(requestAnimationFrame)\n const isVertical = this.orientation === 'TB' || this.orientation === 'BT'\n for (const node of newNodes.values()) {\n node.measure(isVertical)\n const { id, version } = node.data!\n const key = `k:${id}:${version}`\n this.allNodes.set(key, node)\n node.renderContainer()\n }\n this.measurement!.innerHTML = ''\n return newNodes\n }\n\n // ========== Mouse event handlers ==========\n\n private onClick(e: MouseEvent) {\n const hit = this.hitTest(e.clientX, e.clientY)\n if (hit.type === 'node') {\n this.api.handleClickNode(hit.node.data.id)\n } else if (hit.type === 'edge') {\n this.api.handleClickEdge(hit.segId)\n }\n }\n\n private onDoubleClick(e: MouseEvent) {\n // Cancel any pending drag\n if (this.pendingDrag) {\n window.clearTimeout(this.pendingDrag.timeout)\n this.pendingDrag = null\n }\n if (!this.editMode.editable) return\n const hit = this.hitTest(e.clientX, e.clientY)\n if (hit.type === 'node') {\n if (hit.node.isDummy) return\n this.api.handleEditNode(hit.node.data.id)\n } else if (hit.type === 'edge') {\n this.api.handleEditEdge(hit.segId)\n } else {\n this.api.handleNewNode()\n }\n }\n\n // ========== Built-in Modals ==========\n\n /** Show the new node modal */\n showNewNodeModal(callback: (data: NewNode) => void) {\n const nodeTypes = Object.keys(this.nodeTypes)\n const fields = this.api.getNodeFields()\n const modal = new NewNodeModal({\n nodeTypes: nodeTypes.length > 0 ? nodeTypes : undefined,\n fields: fields.size > 0 ? fields : undefined,\n onSubmit: (data) => { callback(data) }\n })\n modal.show(document.body)\n }\n\n /** Show the edit node modal */\n showEditNodeModal(node: Record<string, any>, callback: (data: Record<string, any>) => void) {\n const nodeTypes = Object.keys(this.nodeTypes)\n const fields = this.api.getNodeFields()\n const modal = new EditNodeModal({\n node,\n nodeTypes: nodeTypes.length > 0 ? nodeTypes : undefined,\n fields: fields.size > 0 ? fields : undefined,\n onSubmit: (data) => { callback(data) },\n onDelete: () => { this.api.handleDeleteNode(node.id) }\n })\n modal.show(document.body)\n }\n\n /** Show the edit edge modal */\n showEditEdgeModal(edge: EditEdgeProps, callback: (data: EditEdgeProps) => void) {\n const modal = new EditEdgeModal({\n edge,\n edgeTypes: Object.keys(this.edgeTypes),\n onSubmit: callback,\n onDelete: () => { this.api.handleDeleteEdge(edge.id) },\n })\n modal.show(document.body)\n }\n\n private onContextMenu(e: MouseEvent) {\n // Context menu - could be used for right-click menus\n }\n\n private groupTransform(): string {\n return `translate(${this.transform.x}, ${this.transform.y}) scale(${this.transform.scale})`\n }\n\n private viewBox(): string {\n const p = this.padding\n const x = this.bounds.min.x - p\n const y = this.bounds.min.y - p\n const w = this.bounds.max.x - this.bounds.min.x + p * 2\n const h = this.bounds.max.y - this.bounds.min.y + p * 2\n return `${x} ${y} ${w} ${h}`\n }\n\n private generateDynamicStyles(): string {\n let css = ''\n const scope = `[data-g3p-instance=\"${this.markerPrefix}\"]`\n\n // Global theme overrides (scoped to this instance)\n css += themeToCSS(this.theme, scope)\n\n // Node type styles (scoped to this instance)\n for (const [type, vars] of Object.entries(this.nodeTypes)) {\n css += themeToCSS(vars, `${scope} .g3p-node-type-${type}`, 'node')\n }\n\n // Edge type styles (scoped to this instance)\n for (const [type, vars] of Object.entries(this.edgeTypes)) {\n css += themeToCSS(vars, `${scope} .g3p-edge-type-${type}`)\n }\n\n return css\n }\n\n private createCanvasContainer() {\n // Inject base styles once\n if (!document.getElementById('g3p-styles')) {\n const baseStyleEl = document.createElement('style')\n baseStyleEl.id = 'g3p-styles'\n baseStyleEl.textContent = styles\n document.head.appendChild(baseStyleEl)\n }\n\n // Inject dynamic styles (node/edge types) scoped to this canvas instance\n const dynamicStyles = this.generateDynamicStyles()\n if (dynamicStyles) {\n // Remove any previous dynamic styles for this instance\n this.dynamicStyleEl?.remove()\n this.dynamicStyleEl = document.createElement('style')\n this.dynamicStyleEl.id = `g3p-styles-${this.markerPrefix}`\n this.dynamicStyleEl.textContent = dynamicStyles\n document.head.appendChild(this.dynamicStyleEl)\n }\n\n // Build color mode class\n const colorModeClass = this.colorMode !== 'system' ? `g3p-${this.colorMode}` : ''\n\n this.container = (<div\n className={`g3p-canvas-container ${colorModeClass}`.trim()}\n data-g3p-instance={this.markerPrefix}\n ref={(el: HTMLElement) => this.container = el}\n onContextMenu={this.onContextMenu.bind(this)}\n >\n <svg\n ref={(el: SVGElement) => this.root = el}\n className=\"g3p-canvas-root\"\n width={this.width}\n height={this.height}\n viewBox={this.viewBox()}\n preserveAspectRatio=\"xMidYMid meet\"\n onClick={this.onClick.bind(this)}\n onDblClick={this.onDoubleClick.bind(this)}\n >\n <defs>\n {Object.values(markerDefs).map(marker => marker(this.markerSize, false, this.markerPrefix))}\n {Object.values(markerDefs).map(marker => marker(this.markerSize, true, this.markerPrefix))}\n </defs>\n <g\n ref={(el: SVGElement) => this.group = el}\n transform={this.groupTransform()}\n />\n </svg>\n </div>) as HTMLElement\n }\n\n // ==================== Pan-Zoom ====================\n\n private setupPanZoom() {\n // Mouse wheel zoom\n this.container!.addEventListener('wheel', this.onWheel.bind(this), { passive: false })\n\n // Pan with left mouse button\n this.container!.addEventListener('mousedown', this.onMouseDown.bind(this))\n document.addEventListener('mousemove', this.onMouseMove.bind(this))\n document.addEventListener('mouseup', this.onMouseUp.bind(this))\n\n // Keyboard handler for escape to cancel new-edge mode\n document.addEventListener('keydown', this.onKeyDown.bind(this))\n\n // Create zoom controls\n this.createZoomControls()\n }\n\n private onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape' && this.editMode.isCreatingEdge) {\n this.endNewEdge(true) // cancelled\n }\n }\n\n /** Convert screen coordinates to canvas-relative coordinates */\n private screenToCanvas(screen: ScreenPos): CanvasPos {\n const rect = this.container!.getBoundingClientRect()\n return canvasPos(screen.x - rect.left, screen.y - rect.top)\n }\n\n /** Convert canvas coordinates to graph coordinates */\n private canvasToGraph(canvas: CanvasPos): GraphPos {\n const vb = this.currentViewBox()\n const { scale, offsetX, offsetY } = this.getEffectiveScale()\n\n // Convert canvas position to graph position, accounting for centering\n return graphPos(\n vb.x - offsetX + canvas.x * scale,\n vb.y - offsetY + canvas.y * scale\n )\n }\n\n /** Convert screen coordinates to graph coordinates */\n private screenToGraph(screen: ScreenPos): GraphPos {\n const canvas = this.screenToCanvas(screen)\n return this.canvasToGraph(canvas)\n }\n\n /**\n * Get the effective scale from canvas pixels to graph units,\n * accounting for preserveAspectRatio=\"xMidYMid meet\" which uses\n * the smaller scale (to fit) and centers the content.\n */\n private getEffectiveScale(): { scale: number, offsetX: number, offsetY: number } {\n const vb = this.currentViewBox()\n const rect = this.container!.getBoundingClientRect()\n\n const scaleX = vb.w / rect.width\n const scaleY = vb.h / rect.height\n\n // \"meet\" uses the larger scale value (smaller zoom) to fit content\n const scale = Math.max(scaleX, scaleY)\n\n // Calculate offset due to centering (xMidYMid)\n const actualW = rect.width * scale\n const actualH = rect.height * scale\n const offsetX = (actualW - vb.w) / 2\n const offsetY = (actualH - vb.h) / 2\n\n return { scale, offsetX, offsetY }\n }\n\n /** Get current viewBox as an object */\n private currentViewBox(): { x: number, y: number, w: number, h: number } {\n const p = this.padding\n const t = this.transform\n const baseX = this.bounds.min.x - p\n const baseY = this.bounds.min.y - p\n const baseW = this.bounds.max.x - this.bounds.min.x + p * 2\n const baseH = this.bounds.max.y - this.bounds.min.y + p * 2\n\n // Apply transform: scale around center, then translate\n const cx = baseX + baseW / 2\n const cy = baseY + baseH / 2\n const w = baseW / t.scale\n const h = baseH / t.scale\n const x = cx - w / 2 - t.x\n const y = cy - h / 2 - t.y\n\n return { x, y, w, h }\n }\n\n private onWheel(e: WheelEvent) {\n e.preventDefault()\n\n const zoomFactor = 1.1\n const delta = e.deltaY > 0 ? 1 / zoomFactor : zoomFactor\n\n // Get cursor position in canvas coordinates\n const screenCursor = screenPos(e.clientX, e.clientY)\n const canvasCursor = this.screenToCanvas(screenCursor)\n\n // Get cursor position in graph coordinates BEFORE zoom\n const graphCursor = this.canvasToGraph(canvasCursor)\n\n // Apply zoom\n const oldScale = this.transform.scale\n const newScale = Math.max(0.1, Math.min(10, oldScale * delta))\n this.transform.scale = newScale\n\n // Get cursor position in graph coordinates AFTER zoom\n const newGraphCursor = this.canvasToGraph(canvasCursor)\n\n // Adjust translation to keep cursor at same graph position\n this.transform.x += (newGraphCursor.x - graphCursor.x)\n this.transform.y += (newGraphCursor.y - graphCursor.y)\n\n this.applyTransform()\n }\n\n private onMouseDown(e: MouseEvent) {\n // Only handle left button\n if (e.button !== 0) return\n if ((e.target as HTMLElement).closest('.g3p-zoom-controls')) return\n\n const hit = this.hitTest(e.clientX, e.clientY)\n\n // In editable mode, schedule new-edge from node or port (not dummy nodes)\n // Use a timeout to allow double-click to cancel the drag\n if (this.editMode.editable && (hit.type === 'node' || hit.type === 'port')) {\n const node = hit.node\n if (node.isDummy) return // Dummy nodes can't be edge endpoints\n\n e.preventDefault()\n e.stopPropagation()\n const startGraph = this.screenToGraph(hit.center)\n const portId = hit.type === 'port' ? hit.port : undefined\n\n // Schedule drag start after a short delay (to allow double-click)\n this.pendingDrag = {\n timeout: window.setTimeout(() => {\n if (this.pendingDrag) {\n this.startNewEdge(this.pendingDrag.nodeId, this.pendingDrag.startGraph, this.pendingDrag.portId)\n this.pendingDrag = null\n }\n }, 200),\n nodeId: node.data.id,\n startGraph,\n portId,\n }\n return\n }\n\n // Start panning on canvas\n if (hit.type === 'canvas' || hit.type === 'edge') {\n const startCanvas = this.screenToCanvas(screenPos(e.clientX, e.clientY))\n this.editMode.startPan(startCanvas, { ...this.transform })\n\n const { scale } = this.getEffectiveScale()\n this.panScale = { x: scale, y: scale }\n\n this.container!.style.cursor = 'grabbing'\n e.preventDefault()\n }\n }\n\n private onMouseMove(e: MouseEvent) {\n // Handle new-edge mode\n if (this.editMode.isCreatingEdge) {\n const screenCursor = screenPos(e.clientX, e.clientY)\n const canvasCursor = this.screenToCanvas(screenCursor)\n const graphCursor = this.canvasToGraph(canvasCursor)\n this.editMode.updateNewEdgePosition(graphCursor)\n this.updateNewEdgeVisual()\n\n // Detect hover target using elementFromPoint\n this.detectHoverTarget(e.clientX, e.clientY)\n return\n }\n\n // Handle panning\n if (!this.editMode.isPanning || !this.panScale) return\n\n const panState = this.editMode.state\n if (panState.type !== 'panning') return\n\n const current = this.screenToCanvas(screenPos(e.clientX, e.clientY))\n\n // Calculate delta in canvas pixels\n const dx = current.x - panState.startCanvas.x\n const dy = current.y - panState.startCanvas.y\n\n // Update transform using scale captured at pan start\n this.transform.x = panState.startTransform.x + dx * this.panScale.x\n this.transform.y = panState.startTransform.y + dy * this.panScale.y\n\n this.applyTransform()\n }\n\n private onMouseUp(e: MouseEvent) {\n // Cancel any pending drag that didn't start\n if (this.pendingDrag) {\n window.clearTimeout(this.pendingDrag.timeout)\n this.pendingDrag = null\n }\n\n // Handle new-edge mode\n if (this.editMode.isCreatingEdge) {\n this.endNewEdge(false)\n return\n }\n\n // Handle panning\n if (!this.editMode.isPanning) return\n this.editMode.reset()\n this.panScale = null\n this.container!.style.cursor = ''\n }\n\n private applyTransform() {\n const vb = this.currentViewBox()\n this.root!.setAttribute('viewBox', `${vb.x} ${vb.y} ${vb.w} ${vb.h}`)\n this.updateZoomLevel()\n }\n\n private createZoomControls() {\n this.zoomControls = (<div className=\"g3p-zoom-controls\">\n <button className=\"g3p-zoom-btn\" onClick={() => this.zoomIn()}>+</button>\n <div className=\"g3p-zoom-level\" id=\"g3p-zoom-level\">100%</div>\n <button className=\"g3p-zoom-btn\" onClick={() => this.zoomOut()}>−</button>\n <button className=\"g3p-zoom-btn g3p-zoom-reset\" onClick={() => this.zoomReset()}>⟲</button>\n </div>) as HTMLElement\n\n this.container!.appendChild(this.zoomControls)\n }\n\n private updateZoomLevel() {\n const level = this.container!.querySelector('#g3p-zoom-level')\n if (level) {\n level.textContent = `${Math.round(this.transform.scale * 100)}%`\n }\n }\n\n zoomIn() {\n this.transform.scale = Math.min(10, this.transform.scale * 1.2)\n this.applyTransform()\n }\n\n zoomOut() {\n this.transform.scale = Math.max(0.1, this.transform.scale / 1.2)\n this.applyTransform()\n }\n\n zoomReset() {\n this.transform = { x: 0, y: 0, scale: 1 }\n this.applyTransform()\n }\n\n // ==================== New-Edge Mode ====================\n\n /** Start creating a new edge from a node */\n startNewEdge(sourceNodeId: string, startGraph: GraphPos, sourcePortId?: string) {\n this.editMode.startNewEdge(sourceNodeId, startGraph, sourcePortId)\n this.updateNewEdgeVisual()\n this.container!.style.cursor = 'crosshair'\n }\n\n /** Update the new-edge visual during drag */\n private updateNewEdgeVisual() {\n const state = this.editMode.getNewEdgeState()\n if (!state) {\n this.removeNewEdgeVisual()\n return\n }\n\n // Remove old element\n if (this.newEdgeEl) {\n this.newEdgeEl.remove()\n }\n\n // Create new element\n this.newEdgeEl = renderNewEdge({\n start: state.startGraph,\n end: state.currentGraph,\n })\n\n this.group!.appendChild(this.newEdgeEl)\n }\n\n /** Remove the new-edge visual */\n private removeNewEdgeVisual() {\n if (this.newEdgeEl) {\n this.newEdgeEl.remove()\n this.newEdgeEl = undefined\n }\n }\n\n /** Complete or cancel the new-edge creation */\n endNewEdge(cancelled: boolean = false) {\n const state = this.editMode.getNewEdgeState()\n if (!state) return\n\n if (!cancelled) {\n const { target, source } = state\n if (target?.type == 'node') {\n this.api.handleAddEdge({ id: '', source, target })\n } else {\n this.api.handleNewNodeFrom(source)\n }\n }\n\n this.removeNewEdgeVisual()\n this.clearDropTargetHighlight()\n this.editMode.reset()\n this.container!.style.cursor = ''\n }\n\n /** Find node data by internal ID */\n private findNodeDataById(nodeId: string): any | null {\n for (const node of this.curNodes.values()) {\n if (node.data?.id === nodeId) {\n return node.data.data\n }\n }\n return null\n }\n\n /** Set hover target for new-edge mode */\n setNewEdgeHoverTarget(id: string, port?: string) {\n // Clear previous highlight\n this.clearDropTargetHighlight()\n this.editMode.setHoverTarget({ type: 'node', id, port })\n if (port) {\n const portEl = this.container?.querySelector(`.g3p-node-port[data-node-id=\"${id}\"][data-port-id=\"${port}\"]`)\n if (portEl) portEl.classList.add('g3p-drop-target')\n } else {\n const node = this.curNodes.get(id)\n if (node?.container) node.container.classList.add('g3p-drop-target')\n }\n }\n\n /** Clear hover target for new-edge mode */\n clearNewEdgeHoverTarget() {\n this.clearDropTargetHighlight()\n this.editMode.setHoverTarget(null)\n }\n\n /** Remove drop target highlight from all elements */\n private clearDropTargetHighlight() {\n // Clear from nodes\n for (const node of this.curNodes.values()) {\n node.container?.classList.remove('g3p-drop-target')\n }\n // Clear from ports\n this.container?.querySelectorAll('.g3p-drop-target').forEach(el => {\n el.classList.remove('g3p-drop-target')\n })\n }\n\n /** Detect hover target during new-edge drag using elementFromPoint */\n private detectHoverTarget(clientX: number, clientY: number) {\n // Temporarily hide the new-edge visual so it doesn't block hit testing\n if (this.newEdgeEl) {\n this.newEdgeEl.style.display = 'none'\n }\n\n const el = document.elementFromPoint(clientX, clientY)\n\n // Restore the new-edge visual\n if (this.newEdgeEl) {\n this.newEdgeEl.style.display = ''\n }\n\n if (!el) {\n this.clearNewEdgeHoverTarget()\n return\n }\n\n // Check for port first (more specific)\n const portEl = el.closest('.g3p-node-port')\n if (portEl) {\n const nodeId = portEl.getAttribute('data-node-id')\n const portId = portEl.getAttribute('data-port-id')\n if (nodeId && portId) {\n const node = this.curNodes.get(nodeId)\n if (node && !node.isDummy) {\n this.setNewEdgeHoverTarget(nodeId, portId)\n return\n }\n }\n }\n\n // Check for node container\n const nodeEl = el.closest('.g3p-node-container')\n if (nodeEl) {\n const nodeId = nodeEl.getAttribute('data-node-id')\n if (nodeId) {\n const node = this.curNodes.get(nodeId)\n if (node && !node.isDummy) {\n this.setNewEdgeHoverTarget(node.data.id)\n return\n }\n }\n }\n\n // Not over a node or port\n this.clearNewEdgeHoverTarget()\n }\n\n // ==================== Hit Testing ====================\n\n /** Result of a hit test */\n private hitTest(clientX: number, clientY: number): HitTestResult {\n const el = document.elementFromPoint(clientX, clientY)\n if (!el) return { type: 'canvas' }\n\n const getCenter = (el: Element) => {\n const rect = el.getBoundingClientRect()\n return screenPos(rect.left + rect.width / 2, rect.top + rect.height / 2)\n }\n\n // Check for port first (more specific)\n const portEl = el.closest('.g3p-node-port')\n if (portEl) {\n const nodeId = portEl.getAttribute('data-node-id')\n const portId = portEl.getAttribute('data-port-id')\n if (nodeId && portId) {\n const center = getCenter(portEl)\n const node = this.curNodes.get(nodeId)\n if (node) {\n return { type: 'port', node, port: portId, center }\n }\n }\n }\n\n // Check for node\n const nodeEl = el.closest('.g3p-node-container')\n if (nodeEl) {\n const nodeId = nodeEl.getAttribute('data-node-id')\n if (nodeId) {\n const borderEl = el.closest('.g3p-node-border')\n const center = getCenter(borderEl ?? nodeEl)\n const node = this.curNodes.get(nodeId)\n if (node) {\n return { type: 'node', node, center }\n }\n }\n }\n\n // Check for edge (segment)\n const edgeEl = el.closest('.g3p-seg-container')\n if (edgeEl) {\n const segId = edgeEl.getAttribute('data-edge-id')\n if (segId) {\n return { type: 'edge', segId }\n }\n }\n\n return { type: 'canvas' }\n }\n\n /** Update theme and type styles dynamically */\n updateStyles(options: { theme?: ThemeVars, nodeTypes?: Record<string, ThemeVars>, edgeTypes?: Record<string, ThemeVars> }) {\n if (options.theme !== undefined) this.theme = options.theme\n if (options.nodeTypes !== undefined) this.nodeTypes = options.nodeTypes\n if (options.edgeTypes !== undefined) this.edgeTypes = options.edgeTypes\n\n // Regenerate and replace dynamic styles\n const dynamicStyles = this.generateDynamicStyles()\n if (dynamicStyles) {\n if (!this.dynamicStyleEl) {\n this.dynamicStyleEl = document.createElement('style')\n this.dynamicStyleEl.id = `g3p-styles-${this.markerPrefix}`\n document.head.appendChild(this.dynamicStyleEl)\n }\n this.dynamicStyleEl.textContent = dynamicStyles\n } else if (this.dynamicStyleEl) {\n // No dynamic styles needed, remove the element\n this.dynamicStyleEl.remove()\n this.dynamicStyleEl = undefined\n }\n }\n\n /** Update color mode without recreating the canvas */\n setColorMode(colorMode: 'light' | 'dark' | 'system') {\n if (!this.container) return\n this.colorMode = colorMode\n // Remove existing color mode classes\n this.container.classList.remove('g3p-light', 'g3p-dark')\n // Add new color mode class if not system\n if (colorMode !== 'system') {\n this.container.classList.add(`g3p-${colorMode}`)\n }\n }\n\n /** Cleanup resources when the canvas is destroyed */\n destroy() {\n this.dynamicStyleEl?.remove()\n this.dynamicStyleEl = undefined\n this.measurement?.remove()\n this.measurement = undefined\n }\n}\n\n/** Hit test result types */\ntype HitTestResult =\n | { type: 'canvas' }\n | { type: 'node'; node: Node, center: ScreenPos }\n | { type: 'port'; node: Node; port: string, center: ScreenPos }\n | { type: 'edge'; segId: string }\n\n/** Maps ThemeVars property names to CSS variable names */\nconst themeVarMap: Partial<Record<keyof ThemeVars, string>> = {\n // Canvas\n bg: '--g3p-bg',\n shadow: '--g3p-shadow',\n // Node\n border: '--g3p-border',\n borderHover: '--g3p-border-hover',\n borderSelected: '--g3p-border-selected',\n text: '--g3p-text',\n textMuted: '--g3p-text-muted',\n // Port\n bgHover: '--g3p-port-bg-hover',\n // Edge\n color: '--g3p-edge-color',\n}\n\nfunction themeToCSS(theme: ThemeVars, selector: string, prefix: string = ''): string {\n const entries = Object.entries(theme).filter(([_, v]) => v !== undefined)\n if (!entries.length) return ''\n\n let css = `${selector} {\\n`\n for (const [key, value] of entries) {\n let cssVar = themeVarMap[key as keyof ThemeVars]\n // Handle 'bg' specially based on context (node vs port)\n if (key === 'bg' && prefix === 'node') {\n cssVar = '--g3p-bg-node'\n } else if (key === 'bg' && prefix === 'port') {\n cssVar = '--g3p-port-bg'\n }\n if (cssVar) {\n css += ` ${cssVar}: ${value};\\n`\n }\n }\n css += '}\\n'\n return css\n}\n","import { NodeProps } from '../api/options'\n\nexport function renderNode(node: any, props?: NodeProps<any>): HTMLElement {\n if (typeof node == 'string') node = { id: node }\n\n const title = node?.title ?? props?.title ?? node?.label ?? node?.name ?? node?.text ?? props?.text ?? node?.id ?? '?'\n const detail = node?.detail ?? node?.description ?? node?.subtitle\n\n return (\n <div className=\"g3p-node-default\">\n <div className=\"g3p-node-title\">{title}</div>\n {detail && (\n <div className=\"g3p-node-detail\">{detail}</div>\n )}\n </div>\n ) as HTMLElement\n}\n","import { renderNode } from '../canvas/render-node'\nimport {\n APIOptions,\n GraphOptions,\n CanvasOptions,\n PropsOptions,\n NodeProps,\n EdgeProps,\n PortProps,\n} from './options'\n\nexport type Defaults<N, E> = {\n graph: Required<GraphOptions>\n canvas: Required<CanvasOptions<N>>\n props: PropsOptions<N, E>\n}\n\nexport function applyDefaults<N, E>(options?: APIOptions<N, E>): Defaults<N, E> {\n const { graph, canvas, props } = defaults<N, E>()\n return {\n graph: { ...graph, ...options?.graph },\n canvas: { ...canvas, ...options?.canvas },\n props: { ...props, ...options?.props },\n }\n}\n\nfunction defaults<N, E>(): Defaults<N, E> {\n return {\n graph: {\n mergeOrder: ['target', 'source'],\n nodeMargin: 15,\n dummyNodeSize: 15,\n nodeAlign: 'natural',\n edgeSpacing: 10,\n turnRadius: 10,\n orientation: 'TB',\n layerMargin: 5,\n alignIterations: 5,\n alignThreshold: 10,\n separateTrackSets: true,\n markerSize: 10,\n layoutSteps: null,\n },\n canvas: {\n renderNode,\n width: '100%',\n height: '100%',\n padding: 20,\n editable: false,\n panZoom: true,\n markerSize: 10,\n colorMode: 'system',\n theme: {},\n nodeTypes: {},\n edgeTypes: {},\n },\n props: {},\n }\n}","import { Update } from \"./options\"\n\nexport class Updater<N, E> {\n update: Update<N, E>\n\n constructor() {\n this.update = {\n addNodes: [],\n removeNodes: [],\n updateNodes: [],\n addEdges: [],\n removeEdges: [],\n updateEdges: [],\n }\n }\n\n describe(desc: string): Updater<N, E> {\n this.update.description = desc\n return this\n }\n\n addNode(node: any): Updater<N, E> {\n this.update.addNodes!.push(node)\n return this\n }\n\n addNodes(...nodes: any[]): Updater<N, E> {\n this.update.addNodes!.push(...nodes)\n return this\n }\n\n deleteNode(node: any): Updater<N, E> {\n this.update.removeNodes!.push(node)\n return this\n }\n\n deleteNodes(...nodes: any[]): Updater<N, E> {\n this.update.removeNodes!.push(...nodes)\n return this\n }\n\n updateNode(node: any): Updater<N, E> {\n this.update.updateNodes!.push(node)\n return this\n }\n\n updateNodes(...nodes: any[]): Updater<N, E> {\n this.update.updateNodes!.push(...nodes)\n return this\n }\n\n addEdge(edge: any): Updater<N, E> {\n this.update.addEdges!.push(edge)\n return this\n }\n\n addEdges(...edges: any[]): Updater<N, E> {\n this.update.addEdges!.push(...edges)\n return this\n }\n\n deleteEdge(edge: any): Updater<N, E> {\n this.update.removeEdges!.push(edge)\n return this\n }\n\n deleteEdges(...edges: any[]): Updater<N, E> {\n this.update.removeEdges!.push(...edges)\n return this\n }\n\n updateEdge(edge: any): Updater<N, E> {\n this.update.updateEdges!.push(edge)\n return this\n }\n\n updateEdges(...edges: any[]): Updater<N, E> {\n this.update.updateEdges!.push(...edges)\n return this\n }\n\n static add<N, E>(nodes: N[], edges: E[]): Updater<N, E> {\n const updater = new Updater<N, E>()\n updater.update.addNodes = nodes\n updater.update.addEdges = edges\n return updater\n }\n}\n","import { Update } from './options'\nimport { API } from './api'\n\nexport type SnapshotMessage<N, E> = {\n type: 'snapshot'\n nodes: N[]\n edges: E[]\n description?: string\n}\n\nexport type UpdateMessage<N, E> = {\n type: 'update'\n description?: string\n} & Update<N, E>\n\nexport type HistoryMessage<N, E> = {\n type: 'history'\n history: Update<N, E>[]\n}\n\nexport type IngestMessage<N, E> =\n | SnapshotMessage<N, E>\n | UpdateMessage<N, E>\n | HistoryMessage<N, E>\n\n/**\n * Ingest class handles applying ingest messages to an API instance.\n * This is the core ingestion functionality, separate from UI concerns.\n */\nexport class Ingest<N, E> {\n constructor(public api: API<N, E>) { }\n\n /**\n * Apply an incoming ingest message to the API.\n * - snapshot: rebuild state from nodes/edges (clears prior history)\n * - update: apply incremental update\n * - history: initialize from a set of updates (clears prior history)\n */\n async apply(msg: IngestMessage<N, E>): Promise<void> {\n switch (msg.type) {\n case 'snapshot': {\n await this.api.replaceSnapshot(msg.nodes, msg.edges, msg.description)\n break\n }\n case 'update': {\n await this.api.update(u => {\n if (msg.addNodes) u.addNodes(...msg.addNodes)\n if (msg.removeNodes) u.deleteNodes(...msg.removeNodes)\n if (msg.updateNodes) u.updateNodes(...msg.updateNodes)\n if (msg.addEdges) u.addEdges(...msg.addEdges)\n if (msg.removeEdges) u.deleteEdges(...msg.removeEdges)\n if (msg.updateEdges) u.updateEdges(...msg.updateEdges)\n if (msg.description) u.describe(msg.description)\n })\n break\n }\n case 'history': {\n await this.api.replaceHistory(msg.history)\n break\n }\n }\n }\n}\n","import type { IngestMessage } from '../ingest'\n\nexport type WebSocketStatus = 'connecting' | 'connected' | 'reconnecting' | 'closed' | 'error'\nexport type WebSocketStatusListener = (status: WebSocketStatus, detail?: any) => void\nexport type WebSocketSourceArgs<N, E> = {\n url: string\n onMessage: (msg: IngestMessage<N, E>) => void\n onStatus?: WebSocketStatusListener\n reconnectMs?: number\n}\n\nexport class WebSocketSource<N, E> {\n private url: string\n private ws: WebSocket | null = null\n private onMessage: (msg: IngestMessage<N, E>) => void\n private onStatus?: WebSocketStatusListener\n private reconnectMs: number\n private closedByUser = false\n private connectStartTime: number | null = null\n private totalTimeoutMs: number = 10000\n private totalTimeoutTimer: number | null = null\n\n constructor(args: WebSocketSourceArgs<N, E>) {\n this.url = args.url\n this.onMessage = args.onMessage\n this.onStatus = args.onStatus\n this.reconnectMs = args.reconnectMs ?? 1500\n }\n\n connect() {\n this.closedByUser = false\n this.connectStartTime = Date.now()\n this.startTotalTimeout()\n this.open()\n }\n\n disconnect() {\n this.closedByUser = true\n this.clearTotalTimeout()\n if (this.ws) {\n try { this.ws.close() } catch { }\n this.ws = null\n }\n this.onStatus?.('closed')\n }\n\n private startTotalTimeout() {\n this.clearTotalTimeout()\n this.totalTimeoutTimer = window.setTimeout(() => {\n if (!this.closedByUser && this.ws?.readyState !== WebSocket.OPEN) {\n // Total timeout elapsed, abort connection attempts\n this.closedByUser = true\n if (this.ws) {\n try { this.ws.close() } catch { }\n this.ws = null\n }\n this.clearTotalTimeout()\n this.onStatus?.('error', new Error('Connection timeout after 10 seconds'))\n }\n }, this.totalTimeoutMs)\n }\n\n private clearTotalTimeout() {\n if (this.totalTimeoutTimer !== null) {\n clearTimeout(this.totalTimeoutTimer)\n this.totalTimeoutTimer = null\n }\n this.connectStartTime = null\n }\n\n private open() {\n // Check if we've exceeded total timeout\n if (this.connectStartTime && Date.now() - this.connectStartTime >= this.totalTimeoutMs) {\n if (!this.closedByUser) {\n this.closedByUser = true\n this.clearTotalTimeout()\n this.onStatus?.('error', new Error('Connection timeout after 10 seconds'))\n }\n return\n }\n\n this.onStatus?.(this.ws ? 'reconnecting' : 'connecting')\n const ws = new WebSocket(this.url)\n this.ws = ws\n\n ws.onopen = () => {\n this.clearTotalTimeout()\n this.onStatus?.('connected')\n }\n ws.onerror = (e) => {\n // Don't clear timeout on error, let it continue trying until total timeout\n this.onStatus?.('error', e)\n }\n ws.onclose = () => {\n if (this.closedByUser) {\n this.onStatus?.('closed')\n return\n }\n\n // Check if we've exceeded total timeout before reconnecting\n if (this.connectStartTime && Date.now() - this.connectStartTime >= this.totalTimeoutMs) {\n this.closedByUser = true\n this.clearTotalTimeout()\n this.onStatus?.('error', new Error('Connection timeout after 10 seconds'))\n return\n }\n\n this.onStatus?.('reconnecting')\n setTimeout(() => this.open(), this.reconnectMs)\n }\n ws.onmessage = (ev) => {\n const data = typeof ev.data === 'string' ? ev.data : ''\n // Accept either single JSON object or NDJSON lines\n const lines = data.split('\\n').map(l => l.trim()).filter(Boolean)\n for (const line of lines) {\n try {\n const obj = JSON.parse(line)\n this.onMessage(obj)\n } catch {\n // ignore bad lines\n }\n }\n }\n }\n}\n\n","import type { IngestMessage } from '../ingest'\n\nexport type FileStatus = 'idle' | 'opened' | 'reading' | 'error' | 'closed'\nexport type FileStatusListener = (status: FileStatus, detail?: any) => void\nexport type FileSourceArgs<N, E> = {\n url: string\n onMessage: (msg: IngestMessage<N, E>) => void\n onStatus?: FileStatusListener\n intervalMs?: number\n}\n\nexport class FileSource<N, E> {\n private url: string\n private onMessage: (msg: IngestMessage<N, E>) => void\n private onStatus?: FileStatusListener\n private timer: number | null = null\n private lastETag: string | null = null\n private lastContent: string = ''\n private intervalMs: number = 1000\n private closed = false\n\n constructor(args: FileSourceArgs<N, E>) {\n this.url = args.url\n this.onMessage = args.onMessage\n this.onStatus = args.onStatus\n this.intervalMs = args.intervalMs ?? 1000\n }\n\n async connect() {\n this.closed = false\n this.lastETag = null\n this.lastContent = ''\n this.onStatus?.('opened')\n this.startPolling()\n }\n\n close() {\n this.closed = true\n if (this.timer) {\n window.clearInterval(this.timer)\n this.timer = null\n }\n this.onStatus?.('closed')\n }\n\n private startPolling() {\n if (this.timer) window.clearInterval(this.timer)\n this.timer = window.setInterval(() => this.poll(), this.intervalMs)\n // Poll immediately\n this.poll()\n }\n\n private async poll() {\n if (this.closed) return\n\n try {\n this.onStatus?.('reading')\n const headers: HeadersInit = {}\n if (this.lastETag) {\n headers['If-None-Match'] = this.lastETag\n }\n\n const response = await fetch(this.url, { headers })\n\n if (response.status === 304) {\n // Not modified, no new content\n return\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const etag = response.headers.get('ETag')\n if (etag) {\n this.lastETag = etag\n }\n\n const content = await response.text()\n\n if (content === this.lastContent) {\n return\n }\n\n // Parse new content (NDJSON)\n const lines = content.split('\\n').map(l => l.trim()).filter(Boolean)\n const lastContentLines = this.lastContent.split('\\n').map(l => l.trim()).filter(Boolean)\n const newLines = lines.slice(lastContentLines.length)\n\n for (const line of newLines) {\n try {\n const obj = JSON.parse(line) as IngestMessage<N, E>\n this.onMessage(obj)\n } catch {\n // ignore malformed lines\n }\n }\n\n this.lastContent = content\n } catch (e) {\n this.onStatus?.('error', e)\n }\n }\n}\n\n","import type { IngestMessage } from '../ingest'\n\ntype StatusListener = (status: 'idle' | 'opened' | 'reading' | 'error' | 'closed', detail?: any) => void\n\nexport type FileSystemSourceArgs<N, E> = {\n filename: string\n onMessage: (msg: IngestMessage<N, E>) => void\n onStatus?: StatusListener\n intervalMs?: number\n}\n\nexport class FileSystemSource<N, E> {\n private handle: FileSystemFileHandle | null = null\n private onMessage: (msg: IngestMessage<N, E>) => void\n private onStatus?: StatusListener\n private timer: number | null = null\n private lastSize = 0\n private filename: string\n private intervalMs: number\n\n constructor(args: FileSystemSourceArgs<N, E>) {\n this.filename = args.filename\n this.onMessage = args.onMessage\n this.onStatus = args.onStatus\n this.intervalMs = args.intervalMs ?? 1000\n }\n\n async openDirectory() {\n try {\n // @ts-ignore\n const dir = await (window as any).showDirectoryPicker?.()\n if (!dir) throw new Error('File System Access not supported or cancelled')\n const handle = await dir.getFileHandle(this.filename, { create: false })\n this.handle = handle\n this.onStatus?.('opened', { file: this.filename })\n this.lastSize = 0\n this.startPolling()\n } catch (e) {\n this.onStatus?.('error', e)\n }\n }\n\n close() {\n if (this.timer) {\n window.clearInterval(this.timer)\n this.timer = null\n }\n this.handle = null\n this.onStatus?.('closed')\n }\n\n private startPolling() {\n if (this.timer) window.clearInterval(this.timer)\n this.timer = window.setInterval(() => this.readNewLines(), this.intervalMs)\n }\n\n private async readNewLines() {\n try {\n if (!this.handle) return\n this.onStatus?.('reading')\n const file = await this.handle.getFile()\n if (file.size === this.lastSize) return\n const slice = await file.slice(this.lastSize).text()\n this.lastSize = file.size\n const lines = slice.split('\\n').map(l => l.trim()).filter(Boolean)\n for (const line of lines) {\n try {\n const obj = JSON.parse(line) as IngestMessage<N, E>\n this.onMessage(obj)\n } catch {\n // ignore malformed lines\n }\n }\n } catch (e) {\n this.onStatus?.('error', e)\n }\n }\n}\n\n","import { Graph } from '../graph/graph'\nimport { Canvas } from '../canvas/canvas'\nimport { EdgeId, PublicEdgeData } from '../graph/edge'\nimport { SegId } from '../graph/seg'\nimport { Mutator } from '../graph/mutator'\nimport { MarkerType } from '../canvas/marker'\nimport { APIArguments, APIOptions, Update, NodeProps, EdgeProps, EdgeEnd, EventsOptions, NewNode, NewEdge, ThemeVars, IngestionConfig } from './options'\nimport { Defaults, applyDefaults } from './defaults'\nimport { PublicNodeData, NodeId, PortId } from '../graph/node'\nimport { Node } from '../canvas/node'\nimport { Nav, Dir } from '../common'\nimport { Updater } from './updater'\nimport { Ingest, IngestMessage } from './ingest'\nimport { WebSocketSource } from './sources/WebSocketSource'\nimport { FileSource } from './sources/FileSource'\nimport { FileSystemSource } from './sources/FileSystemSource'\nimport { logger } from '../log'\n\nconst log = logger('api')\n\ntype State<N, E> = {\n graph: Graph\n update: Update<N, E> | null\n}\n\nexport type EditNodeProps = NewNode & {\n id: string\n}\n\nexport type EditEdgeProps = {\n id: string\n type?: string\n source: { id: string, port?: string, marker?: MarkerType }\n target: { id: string, port?: string, marker?: MarkerType }\n}\n\n/** Core graph API */\nexport class API<N, E> {\n private state!: State<N, E>\n private seq!: State<N, E>[]\n private index!: number\n private canvas: Canvas<N, E>\n private options: Defaults<N, E>\n private history: Update<N, E>[]\n private nodeIds!: Map<N, string>\n private edgeIds!: Map<E, string>\n private nodeVersions!: Map<N, number>\n private nodeOverrides!: Map<N, Partial<NodeProps<N>>>\n private edgeOverrides!: Map<E, Partial<EdgeProps<N>>>\n private nodeFields!: Map<string, 'string' | 'number' | 'boolean'>\n private nextNodeId!: number\n private nextEdgeId!: number\n private events: EventsOptions<N, E>\n private ingest?: Ingest<N, E>\n private ingestionSource?: WebSocketSource<N, E> | FileSource<N, E>\n private ingestionConfig?: IngestionConfig\n private prevProps: { nodes?: N[], edges?: E[], history?: Update<N, E>[], options?: APIOptions<N, E> } = {}\n root: string\n\n constructor(args: APIArguments<N, E>) {\n this.root = args.root\n this.options = applyDefaults(args.options)\n this.events = args.events || {}\n this.ingestionConfig = args.ingestion\n\n // reset graph state\n this.reset()\n\n // create canvas\n this.canvas = new Canvas<N, E>(this, {\n ...this.options.canvas,\n dummyNodeSize: this.options.graph.dummyNodeSize,\n orientation: this.options.graph.orientation,\n })\n\n // store initial update or history (ingestion starts empty)\n if (args.history) {\n this.history = args.history\n } else if (args.nodes) {\n this.history = [Updater.add(args.nodes, args.edges || []).update]\n } else {\n this.history = []\n }\n\n // Store initial props for applyProps diffing\n this.prevProps = {\n nodes: args.nodes,\n edges: args.edges,\n history: args.history,\n options: args.options,\n }\n\n // setup ingestion if configured\n if (this.ingestionConfig) {\n this.ingest = new Ingest(this)\n }\n }\n\n reset() {\n let graph = new Graph({ options: this.options.graph })\n this.state = { graph, update: null }\n this.seq = [this.state]\n this.index = 0\n this.nodeIds = new Map()\n this.edgeIds = new Map()\n this.nodeVersions = new Map()\n this.nodeOverrides = new Map()\n this.edgeOverrides = new Map()\n this.nodeFields = new Map()\n this.nextNodeId = 1\n this.nextEdgeId = 1\n this.canvas?.reset?.()\n }\n\n /** Initialize the API */\n async init() {\n const root = document.getElementById(this.root)\n if (!root) throw new Error('root element not found')\n root.appendChild(this.canvas.container!)\n await this.applyHistory()\n\n // Connect ingestion source if configured\n if (this.ingestionConfig && this.ingest) {\n this.connectIngestion()\n }\n\n if (this.events.onInit) {\n this.events.onInit()\n }\n }\n\n /** Connect to the configured ingestion source */\n private connectIngestion() {\n if (!this.ingestionConfig || !this.ingest) return\n\n const args: any = {\n ...this.ingestionConfig,\n onMessage: (msg: IngestMessage<N, E>) => {\n this.ingest!.apply(msg)\n },\n }\n\n const source = {\n 'websocket': WebSocketSource<N, E>,\n 'file': FileSource<N, E>,\n 'filesystem': FileSystemSource<N, E>,\n }[this.ingestionConfig.type] as any\n\n this.ingestionSource = new source[this.ingestionConfig.type](args)\n this.ingestionSource?.connect()\n }\n\n /** Disconnect from the ingestion source */\n private disconnectIngestion() {\n if (!this.ingestionSource) return\n\n if (this.ingestionSource instanceof WebSocketSource) {\n this.ingestionSource.disconnect()\n } else if (this.ingestionSource instanceof FileSource) {\n this.ingestionSource.close()\n }\n this.ingestionSource = undefined\n }\n\n private async applyHistory() {\n for (const update of this.history)\n await this.applyUpdate(update)\n }\n\n /** Current history index (0-based) */\n getHistoryIndex(): number {\n return this.index\n }\n\n /** Current history length */\n getHistoryLength(): number {\n return this.seq.length\n }\n\n /** Toggle canvas editable mode without re-creating the graph */\n setEditable(editable: boolean): void {\n this.canvas.editMode.editable = editable\n }\n\n /** Replace entire history (clears prior) */\n async replaceHistory(history: Update<N, E>[]) {\n this.reset()\n this.history = history\n await this.applyHistory()\n }\n\n /** Rebuild from snapshot (nodes/edges) */\n async replaceSnapshot(nodes: N[], edges: E[], description?: string) {\n this.reset()\n this.history = [{\n addNodes: nodes,\n addEdges: edges,\n description,\n }]\n await this.applyHistory()\n }\n\n private get graph() {\n return this.state.graph\n }\n\n /** Navigate to a different state */\n nav(nav: Nav) {\n let newIndex: number\n switch (nav) {\n case 'first':\n newIndex = 0\n break\n case 'last':\n newIndex = this.seq.length - 1\n break\n case 'prev':\n newIndex = this.index - 1\n break\n case 'next':\n newIndex = this.index + 1\n break\n }\n if (newIndex < 0 ||\n newIndex >= this.seq.length ||\n newIndex == this.index)\n return\n this.applyDiff(this.index, newIndex)\n this.index = newIndex\n this.state = this.seq[this.index]\n // Notify history change\n if (this.events.historyChange)\n this.events.historyChange(this.index, this.seq.length)\n }\n\n private applyDiff(oldIndex: number, newIndex: number) {\n const oldGraph = this.seq[oldIndex].graph\n const newGraph = this.seq[newIndex].graph\n\n for (const oldNode of oldGraph.nodes.values()) {\n const newNode = newGraph.nodes.get(oldNode.id)\n if (!newNode) this.canvas.deleteNode(oldNode)\n }\n for (const newNode of newGraph.nodes.values()) {\n const oldNode = oldGraph.nodes.get(newNode.id)\n if (!oldNode) {\n this.canvas.addNode(newNode)\n } else if (oldNode.key !== newNode.key) {\n // Node version changed (e.g., during rebuild) - delete old and add new\n this.canvas.deleteNode(oldNode)\n this.canvas.addNode(newNode)\n } else if (oldNode.pos !== newNode.pos) {\n // Same node, just update position\n this.canvas.getNode(newNode.key).setPos(newNode.pos!)\n }\n }\n for (const oldSeg of oldGraph.segs.values()) {\n const newSeg = newGraph.segs.get(oldSeg.id)\n if (!newSeg) {\n this.canvas.deleteSeg(oldSeg)\n } else if (oldSeg !== newSeg) {\n this.canvas.updateSeg(newSeg, newGraph)\n }\n }\n for (const newSeg of newGraph.segs.values()) {\n if (!oldGraph.segs.has(newSeg.id)) {\n this.canvas.addSeg(newSeg, newGraph)\n }\n }\n\n this.canvas.update()\n }\n\n /** Add a node */\n async addNode(node: N) {\n await this.update(update => update.addNode(node))\n }\n\n /** Delete a node */\n async deleteNode(node: N) {\n await this.update(update => update.deleteNode(node))\n }\n\n /** Update a node */\n async updateNode(node: N) {\n await this.update(update => update.updateNode(node))\n }\n\n /** Add an edge */\n async addEdge(edge: E) {\n await this.update(update => update.addEdge(edge))\n }\n\n /** Delete an edge */\n async deleteEdge(edge: E) {\n await this.update(update => update.deleteEdge(edge))\n }\n\n /** Update an edge */\n async updateEdge(edge: E) {\n await this.update(update => update.updateEdge(edge))\n }\n\n /** Perform a batch of updates */\n async update(callback: (updater: Updater<N, E>) => void) {\n // collect updates from the caller\n const updater = new Updater<N, E>()\n callback(updater)\n await this.applyUpdate(updater.update)\n }\n\n /** Rebuild the graph from scratch (removes all then re-adds all nodes/edges) */\n async rebuild() {\n // Collect current nodes and edges from the nodeIds/edgeIds maps\n const nodes: N[] = [...this.nodeIds.keys()]\n const edges: E[] = [...this.edgeIds.keys()]\n\n await this.update(updater => {\n // Remove all edges and nodes\n for (const edge of edges) updater.deleteEdge(edge)\n for (const node of nodes) updater.deleteNode(node)\n // Re-add all nodes first, then edges\n for (const node of nodes) updater.addNode(node)\n for (const edge of edges) updater.addEdge(edge)\n })\n }\n\n private async applyUpdate(update: Update<N, E>) {\n log.info('applyUpdate', update)\n // create nodes in canvas and wait for their measurements\n const nodes = await this.measureNodes(update)\n // apply updates to get a new version of the graph\n const graph = this.state.graph!.withMutations((mut: Mutator) => {\n for (const edge of update.removeEdges ?? [])\n this._removeEdge(edge, mut)\n for (const node of update.removeNodes ?? [])\n this._removeNode(node, mut)\n for (const node of update.addNodes ?? [])\n this._addNode(nodes.get(node)!, mut)\n for (const node of update.updateNodes ?? [])\n this._updateNode(nodes.get(node)!, mut)\n for (const edge of update.addEdges ?? [])\n this._addEdge(edge, mut)\n for (const edge of update.updateEdges ?? [])\n this._updateEdge(edge, mut)\n this.nodeOverrides.clear()\n this.edgeOverrides.clear()\n })\n // add the new state, then nav to it\n this.state = { graph, update }\n this.setNodePositions()\n this.seq.splice(this.index + 1)\n this.seq.push(this.state)\n this.nav('last')\n // In case the consumer doesn't call nav, still notify\n if (this.events.historyChange)\n this.events.historyChange(this.index, this.seq.length)\n }\n\n private setNodePositions() {\n const { graph } = this.state\n for (const nodeId of graph.dirtyNodes) {\n const node = graph.getNode(nodeId)\n if (!node.isDummy)\n this.canvas.getNode(node.key).setPos(node.pos!)\n }\n }\n\n private async measureNodes(update: Update<N, E>): Promise<Map<N, Node>> {\n const data: PublicNodeData[] = []\n for (const set of [update.updateNodes, update.addNodes])\n for (const node of set ?? [])\n data.push(this.parseNode(node, true))\n return await this.canvas.measureNodes(data)\n }\n\n private parseNode(data: N, bumpVersion: boolean = false): PublicNodeData {\n const get = this.options.props.node\n let props: NodeProps<N>\n if (get) props = get(data)\n else if (!data) throw new Error(`invalid node ${data}`)\n else if (typeof data == 'string') props = { id: data }\n else if (typeof data == 'object') props = data\n else throw new Error(`invalid node ${JSON.stringify(data)}`)\n // Detect fields from the raw node data\n this.detectNodeFields(data)\n // Apply overrides (from built-in modal edits on opaque types)\n const overrides = this.nodeOverrides.get(data)\n if (overrides) props = { ...props, ...overrides }\n let { id, title, text, type, render } = props\n id ??= this.getNodeId(data)\n const ports = this.parsePorts(props.ports)\n let version = this.nodeVersions.get(data)\n if (!version) version = 1\n else if (bumpVersion) version++\n this.nodeVersions.set(data, version)\n return { id, data, ports, title, text, type, render, version }\n }\n\n private detectNodeFields(data: N) {\n if (typeof data != 'object' || !data) return\n // Skip internal/complex fields\n const skip = new Set(['id', 'ports', 'render', 'version'])\n for (const [key, value] of Object.entries(data)) {\n if (skip.has(key)) continue\n if (value === null || value === undefined) continue\n const type = typeof value\n if (type === 'string' || type === 'number' || type === 'boolean') {\n this.nodeFields.set(key, type)\n }\n }\n }\n\n getNodeFields(): Map<string, 'string' | 'number' | 'boolean'> {\n return this.nodeFields\n }\n\n private parseEdge(data: E): PublicEdgeData {\n const get = this.options.props.edge\n let props: Partial<EdgeProps<N>>\n if (get) props = get(data)\n else if (!data) throw new Error(`invalid edge ${data}`)\n else if (typeof data == 'string') props = this.parseStringEdge(data)\n else if (typeof data == 'object') props = data\n else throw new Error(`invalid edge ${data}`)\n // Apply overrides (from built-in modal edits on opaque types)\n const overrides = this.edgeOverrides.get(data)\n if (overrides) props = { ...props, ...overrides }\n let { id, source, target, type } = props\n if (!id) id = this.getEdgeId(data)\n source = this.parseEdgeEnd(source)\n target = this.parseEdgeEnd(target)\n const edge = { id, source, target, type, data }\n return edge\n }\n\n private parseEdgeEnd(end?: EdgeEnd<N>): { id: string, port?: string }\n private parseEdgeEnd(end?: any): { id: string, port?: string } {\n if (!end) throw new Error(`edge has an undefined source or target`)\n if (typeof end == 'string') return { id: end }\n if (typeof end == 'object') {\n const keys = Object.keys(end)\n const pidx = keys.indexOf('port')\n if (pidx != -1) {\n // port must be string or undefined; if it's something else, return as-is\n if (end.port !== undefined && typeof end.port != 'string') return end\n keys.splice(pidx, 1)\n }\n if (keys.length != 1) return end\n if (keys[0] == 'id') return end\n if (keys[0] != 'node') return end\n const id = this.nodeIds.get(end.node)\n if (!id) throw new Error(`edge end references unknown node ${end.node}`)\n return { id, port: end.port }\n }\n throw new Error(`invalid edge end ${end}`)\n }\n\n private parseStringEdge(str: string): EdgeProps<N> {\n const [source, target] = str.split(/\\s*(?::|-+>?)\\s*/)\n return { source, target }\n }\n\n private parsePorts(ports?: NodeProps<N>['ports']): PublicNodeData['ports'] {\n const fixed: PublicNodeData['ports'] = {}\n for (const key of ['in', 'out'] as Dir[]) {\n if (ports?.[key] && ports[key].length > 0)\n fixed[key] = ports[key].map(port =>\n typeof port == 'string' ? { id: port } : port)\n }\n return fixed\n }\n\n getNode(id: NodeId): PublicNodeData {\n return this.graph.getNode(id)\n }\n\n getEdge(id: EdgeId): PublicEdgeData {\n return this.graph.getEdge(id)\n }\n\n private getNodeId(node: N): string {\n let id = this.nodeIds.get(node)\n if (!id) {\n id = `n${this.nextNodeId++}`\n this.nodeIds.set(node, id)\n }\n return id\n }\n\n private getEdgeId(edge: E): string {\n let id = this.edgeIds.get(edge)\n if (!id) {\n id = `e${this.nextEdgeId++}`\n this.edgeIds.set(edge, id)\n }\n return id\n }\n\n private _addNode(node: Node, mut: Mutator) {\n const { data, id: newId } = node.data!\n const oldId = this.nodeIds.get(data)\n if (oldId && oldId != newId)\n throw new Error(`node id of ${data} changed from ${oldId} to ${newId}`)\n this.nodeIds.set(data, newId)\n mut.addNode(node.data!)\n }\n\n private _removeNode(node: any, mut: Mutator) {\n const id = this.nodeIds.get(node)\n if (!id) throw new Error(`removing node ${JSON.stringify(node)} which does not exist`)\n mut.removeNode({ id })\n }\n\n private _updateNode(node: Node, mut: Mutator) {\n const { data, id: newId } = node.data!\n const oldId = this.nodeIds.get(data)\n if (!oldId) throw new Error(`updating unknown node ${JSON.stringify(node)} `)\n if (oldId != newId) throw new Error(`node id changed from ${oldId} to ${newId} `)\n mut.updateNode(node.data!)\n }\n\n private _addEdge(edge: any, mut: Mutator) {\n const data = this.parseEdge(edge)\n const id = this.edgeIds.get(edge)\n if (id && id != data.id)\n throw new Error(`edge id changed from ${id} to ${data.id} `)\n this.edgeIds.set(edge, data.id)\n mut.addEdge(data)\n }\n\n private _removeEdge(edge: any, mut: Mutator) {\n const id = this.edgeIds.get(edge)\n if (!id) throw new Error(`removing edge ${JSON.stringify(edge)} which does not exist`)\n mut.removeEdge(this.parseEdge(edge))\n }\n\n private _updateEdge(edge: any, mut: Mutator) {\n const id = this.edgeIds.get(edge)\n if (!id) throw new Error(`updating unknown edge ${JSON.stringify(edge)} `)\n const data = this.parseEdge(edge)\n if (data.id !== id) throw new Error(`edge id changed from ${id} to ${data.id} `)\n mut.updateEdge(data)\n }\n\n // Event Handlers\n\n handleClickNode(id: NodeId) {\n const handler = this.events.nodeClick\n const node = this.graph.getNode(id)\n if (handler) handler(node.data)\n }\n\n handleClickEdge(id: SegId) {\n const handler = this.events.edgeClick\n if (!handler) return\n const seg = this.graph.getSeg(id)\n if (seg.edgeIds.size != 1) return\n const edge = this.graph.getEdge(seg.edgeIds.values().next().value)\n handler(edge.data)\n }\n\n async handleNewNode() {\n const gotNode = async (node: N) => {\n await this.addNode(node)\n }\n if (this.events.newNode)\n this.events.newNode(gotNode)\n else\n this.canvas.showNewNodeModal(async (data) => {\n if (this.events.addNode)\n this.events.addNode(data, gotNode)\n else\n await gotNode(data as N)\n })\n }\n\n async handleNewNodeFrom(source: { id: string, port?: string }) {\n const gotNode = async (node: N) => {\n const gotEdge = async (edge: E) => {\n await this.update(u => {\n u.addNode(node).addEdge(edge)\n })\n }\n const data = this.graph.getNode(source.id).data\n const newEdge: NewEdge<N> = {\n source: { node: data, port: source.port },\n target: { node }\n }\n if (this.events.addEdge)\n this.events.addEdge(newEdge, gotEdge)\n else\n await gotEdge(newEdge as E)\n }\n if (this.events.newNode)\n this.events.newNode(gotNode)\n else\n this.canvas.showNewNodeModal(async (data: Record<string, any>) => {\n if (this.events.addNode)\n this.events.addNode(data, gotNode)\n else\n await gotNode(data as N)\n })\n }\n\n async handleEditNode(id: NodeId) {\n const node = this.graph.getNode(id)\n const gotNode = async (node: N) => {\n if (node) await this.updateNode(node)\n }\n if (this.events.editNode)\n this.events.editNode(node.data, gotNode)\n else {\n this.canvas.showEditNodeModal(node, async (data: Record<string, any>) => {\n if (this.events.updateNode)\n this.events.updateNode(node.data, data, gotNode)\n else {\n // Store overrides for opaque N types, then update with original data\n this.nodeOverrides.set(node.data, data)\n await gotNode(node.data)\n }\n })\n }\n }\n\n async handleEditEdge(id: SegId) {\n const seg = this.graph.getSeg(id)\n if (seg.edgeIds.size != 1) return\n const edge = this.graph.getEdge(seg.edgeIds.values().next().value)\n const gotEdge = async (edge: E | null) => {\n if (edge) await this.updateEdge(edge)\n }\n if (this.events.editEdge)\n this.events.editEdge(edge.data, gotEdge)\n else\n this.canvas.showEditEdgeModal(edge, async (data: EditEdgeProps) => {\n const sourceNode = edge.sourceNode(this.graph)\n const targetNode = edge.targetNode(this.graph)\n const update: NewEdge<N> = {\n source: { node: sourceNode.data, port: data.source.port, marker: data.source.marker },\n target: { node: targetNode.data, port: data.target.port, marker: data.target.marker },\n }\n if (this.events.updateEdge)\n this.events.updateEdge(edge.data, update, gotEdge)\n else {\n // Store overrides for opaque E types, then update with original data\n this.edgeOverrides.set(edge.data, {\n source: { id: sourceNode.id, port: data.source.port, marker: data.source.marker },\n target: { id: targetNode.id, port: data.target.port, marker: data.target.marker },\n type: data.type,\n })\n await gotEdge(edge.data)\n }\n })\n }\n\n async handleAddEdge(data: EditEdgeProps) {\n const gotEdge = async (edge: E | null) => {\n if (edge) await this.addEdge(edge)\n }\n const newEdge: NewEdge<N> = {\n source: { node: this.graph.getNode(data.source.id).data, port: data.source.port, marker: data.source.marker },\n target: { node: this.graph.getNode(data.target.id).data, port: data.target.port, marker: data.target.marker },\n }\n if (this.events.addEdge)\n this.events.addEdge(newEdge, gotEdge)\n else\n await gotEdge(data as E)\n }\n\n async handleDeleteNode(id: NodeId) {\n const node = this.getNode(id)\n if (this.events.removeNode)\n this.events.removeNode(node.data, async (remove) => {\n if (remove) await this.deleteNode(node.data)\n })\n else\n await this.deleteNode(node.data)\n }\n\n async handleDeleteEdge(id: EdgeId) {\n const edge = this.getEdge(id)\n if (this.events.removeEdge)\n this.events.removeEdge(edge.data, async (remove) => {\n if (remove) await this.deleteEdge(edge.data)\n })\n else\n await this.deleteEdge(edge.data)\n }\n\n /** Update theme and type styles dynamically */\n updateStyles(options: { theme?: ThemeVars, nodeTypes?: Record<string, ThemeVars>, edgeTypes?: Record<string, ThemeVars> }) {\n this.canvas?.updateStyles(options)\n }\n\n /** Update color mode without recreating the canvas */\n setColorMode(colorMode: 'light' | 'dark' | 'system') {\n this.canvas?.setColorMode(colorMode)\n }\n\n /**\n * Apply prop changes by diffing against previously applied props.\n * This is a convenience method for framework wrappers that centralizes\n * the logic for detecting and applying changes to nodes, edges, history, and options.\n * The API stores the previous props internally, so you just pass the new props.\n *\n * @param props - The new props to apply\n */\n applyProps(props: { nodes?: N[], edges?: E[], history?: Update<N, E>[], options?: APIOptions<N, E> }): void {\n const prev = this.prevProps\n\n // Check if nodes/edges changed\n const nodesChanged = !shallowEqualArray(props.nodes, prev.nodes)\n const edgesChanged = !shallowEqualArray(props.edges, prev.edges)\n\n if (nodesChanged || edgesChanged) {\n if (props.nodes) {\n this.replaceSnapshot(props.nodes, props.edges || [], undefined)\n }\n }\n\n // Check if history changed (only if nodes/edges didn't change)\n if (!nodesChanged && !edgesChanged && props.history !== prev.history) {\n if (props.history === undefined) {\n // History was removed - if we have nodes/edges, use those\n if (props.nodes) {\n this.replaceSnapshot(props.nodes, props.edges || [], undefined)\n }\n } else if (prev.history && isHistoryPrefix(prev.history, props.history)) {\n // History was appended - apply only the new updates\n const prevLength = prev.history.length\n const newUpdates = props.history.slice(prevLength)\n for (const frame of newUpdates) {\n this.update(u => {\n if (frame.addNodes) u.addNodes(...frame.addNodes)\n if (frame.removeNodes) u.deleteNodes(...frame.removeNodes)\n if (frame.updateNodes) u.updateNodes(...frame.updateNodes)\n if (frame.addEdges) u.addEdges(...frame.addEdges)\n if (frame.removeEdges) u.deleteEdges(...frame.removeEdges)\n if (frame.updateEdges) u.updateEdges(...frame.updateEdges)\n if (frame.description) u.describe(frame.description)\n })\n }\n } else {\n // History was completely replaced\n this.replaceHistory(props.history)\n }\n }\n\n // Check if canvas options changed\n const prevCanvas = prev.options?.canvas as any\n const currCanvas = props.options?.canvas as any\n\n // Handle color mode changes\n const colorModeChanged = prevCanvas?.colorMode !== currCanvas?.colorMode\n if (colorModeChanged && currCanvas?.colorMode) {\n this.setColorMode(currCanvas.colorMode)\n }\n\n // Handle theme/type style changes\n const themeChanged = prevCanvas?.theme !== currCanvas?.theme\n const nodeTypesChanged = prevCanvas?.nodeTypes !== currCanvas?.nodeTypes\n const edgeTypesChanged = prevCanvas?.edgeTypes !== currCanvas?.edgeTypes\n\n if (themeChanged || nodeTypesChanged || edgeTypesChanged) {\n this.updateStyles({\n theme: currCanvas?.theme,\n nodeTypes: currCanvas?.nodeTypes,\n edgeTypes: currCanvas?.edgeTypes,\n })\n }\n\n // Update prevProps with all changed values\n this.prevProps = {\n nodes: props.nodes,\n edges: props.edges,\n history: props.history,\n options: props.options,\n }\n }\n\n /** Cleanup resources when the graph is destroyed */\n destroy() {\n this.disconnectIngestion()\n this.canvas?.destroy()\n }\n}\n\n/** Shallow comparison of arrays with object property comparison */\nfunction shallowEqualArray<T>(a: T[] | undefined, b: T[] | undefined): boolean {\n if (a === b) return true\n if (!a || !b) return false\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n if (typeof a[i] === 'object' && a[i] !== null && typeof b[i] === 'object' && b[i] !== null) {\n const aObj = a[i] as any\n const bObj = b[i] as any\n const aKeys = Object.keys(aObj)\n const bKeys = Object.keys(bObj)\n if (aKeys.length !== bKeys.length) return false\n for (const key of aKeys) {\n if (aObj[key] !== bObj[key]) return false\n }\n } else {\n return false\n }\n }\n }\n return true\n}\n\n/** Check if oldHistory is a prefix of newHistory */\nfunction isHistoryPrefix<N, E>(oldHistory: Update<N, E>[], newHistory: Update<N, E>[]): boolean {\n if (newHistory.length < oldHistory.length) return false\n for (let i = 0; i < oldHistory.length; i++) {\n if (!shallowEqualUpdate(oldHistory[i], newHistory[i])) {\n return false\n }\n }\n return true\n}\n\n/** Shallow comparison of Update objects */\nfunction shallowEqualUpdate<N, E>(a: Update<N, E>, b: Update<N, E>): boolean {\n if (a === b) return true\n if (a.description !== b.description) return false\n if (!shallowEqualArray(a.addNodes, b.addNodes)) return false\n if (!shallowEqualArray(a.removeNodes, b.removeNodes)) return false\n if (!shallowEqualArray(a.updateNodes, b.updateNodes)) return false\n if (!shallowEqualArray(a.addEdges, b.addEdges)) return false\n if (!shallowEqualArray(a.removeEdges, b.removeEdges)) return false\n if (!shallowEqualArray(a.updateEdges, b.updateEdges)) return false\n return true\n}\n",".playground {\n display: flex;\n height: calc(100vh - 60px);\n}\n\n.sidebar {\n width: 280px;\n background: var(--color-bg);\n border-right: 1px solid var(--color-border);\n padding: 1.5rem;\n overflow-y: auto;\n}\n\n.sidebar h2 {\n font-size: 0.875rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-text-muted);\n margin-bottom: 0.75rem;\n margin-top: 1.5rem;\n}\n\n.sidebar h2:first-child {\n margin-top: 0;\n}\n\n.example-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.example-btn {\n padding: 0.75rem 1rem;\n background: var(--color-bg-secondary);\n border: 1px solid var(--color-border);\n border-radius: 0.5rem;\n text-align: left;\n cursor: pointer;\n font-size: 0.875rem;\n color: var(--color-text);\n transition: all 0.15s;\n}\n\n.example-btn:hover {\n background: var(--color-border);\n}\n\n.example-btn.active {\n background: var(--color-primary);\n color: white;\n border-color: var(--color-primary);\n}\n\n.options {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.option-group {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.option-group label {\n font-size: 0.875rem;\n color: var(--color-text-muted);\n}\n\n.option-group select {\n padding: 0.5rem;\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n font-size: 0.875rem;\n}\n\n.option-group input[type=\"checkbox\"] {\n margin-right: 0.5rem;\n}\n\n.graph-area {\n flex: 1;\n padding: 1.5rem;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.graph-toolbar {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.nav-controls {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.nav-btn {\n padding: 0.5rem 0.75rem;\n background: var(--color-bg-secondary);\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n cursor: pointer;\n font-size: 0.875rem;\n color: var(--color-text);\n transition: all 0.15s;\n height: 2.25rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n.nav-btn:hover:not(:disabled) {\n background: var(--color-border);\n}\n\n.nav-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* Prominent edit toggle */\n#edit-toggle {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n font-weight: 600;\n}\n\n/* Source Icon Button */\n.source-icon-btn {\n font-size: 1.1rem;\n padding: 0.5rem;\n min-width: 2.5rem;\n position: relative;\n height: 2.25rem;\n}\n\n.source-icon-btn::after {\n content: '';\n position: absolute;\n bottom: 2px;\n right: 2px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--color-border);\n border: 1px solid var(--color-bg);\n}\n\n.source-icon-btn.active::after {\n background: rgb(34, 197, 94);\n box-shadow: 0 0 4px rgba(34, 197, 94, 0.5);\n}\n\n.source-icon-btn.connecting::after {\n background: rgb(251, 191, 36);\n box-shadow: 0 0 4px rgba(251, 191, 36, 0.5);\n animation: pulse-dot 1.5s ease-in-out infinite;\n}\n\n.source-icon-btn.error::after {\n background: rgb(239, 68, 68);\n box-shadow: 0 0 4px rgba(239, 68, 68, 0.5);\n}\n\n.source-icon-btn.active {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n}\n\n.source-icon-btn.connecting {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n opacity: 0.7;\n animation: pulse 1.5s ease-in-out infinite;\n}\n\n.source-icon-btn.error {\n border-color: rgb(239, 68, 68);\n}\n\n@keyframes pulse-dot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.8); }\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 0.7; }\n 50% { opacity: 1; }\n}\n\n.graph-container {\n flex: 1;\n background: var(--color-bg);\n border-radius: 0.75rem;\n box-shadow: var(--shadow-md);\n overflow: hidden;\n}\n\n/* Modal styles (global) */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.35);\n display: none;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal {\n width: min(680px, calc(100vw - 2rem));\n background: var(--color-bg);\n color: var(--color-text);\n border: 1px solid var(--color-border);\n border-radius: 0.75rem;\n box-shadow: var(--shadow-lg);\n overflow: hidden;\n}\n\n.modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--color-border);\n background: var(--color-bg-secondary);\n}\n\n.modal-header h3 {\n font-size: 1rem;\n font-weight: 600;\n}\n\n.modal-close {\n background: transparent;\n border: none;\n color: var(--color-text);\n font-size: 1.25rem;\n cursor: pointer;\n}\n\n.modal-body {\n padding: 1rem;\n line-height: 1.6;\n}\n\n.modal-body ul {\n margin: 0.5rem 0 0 1.25rem;\n}\n\n.modal-body .form-group {\n margin-bottom: 1rem;\n}\n\n.modal-body label {\n display: block;\n font-size: 0.875rem;\n color: var(--color-text-muted);\n margin-bottom: 0.5rem;\n}\n\n.modal-body input[type=\"text\"] {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n font-size: 0.875rem;\n background: var(--color-bg);\n color: var(--color-text);\n}\n\n.modal-body .button-group {\n display: flex;\n gap: 0.5rem;\n margin-top: 1rem;\n}\n\n.modal-body .button-group button {\n flex: 1;\n padding: 0.5rem 1rem;\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n background: var(--color-bg-secondary);\n color: var(--color-text);\n cursor: pointer;\n font-size: 0.875rem;\n transition: all 0.15s;\n}\n\n.modal-body .button-group button:hover:not(:disabled) {\n background: var(--color-border);\n}\n\n.modal-body .button-group button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.modal-body .button-group button.primary {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n}\n\n.modal-body .button-group button.primary:hover:not(:disabled) {\n background: var(--color-primary);\n opacity: 0.9;\n}\n\n.modal-body .status-message {\n margin-top: 1rem;\n padding: 0.75rem;\n border-radius: 0.25rem;\n font-size: 0.875rem;\n}\n\n.modal-body .status-message.info {\n background: rgba(59, 130, 246, 0.1);\n color: rgb(59, 130, 246);\n border: 1px solid rgba(59, 130, 246, 0.2);\n}\n\n.modal-body .status-message.error {\n background: rgba(239, 68, 68, 0.1);\n color: rgb(239, 68, 68);\n border: 1px solid rgba(239, 68, 68, 0.2);\n}\n\n.modal-body .status-message.success {\n background: rgba(34, 197, 94, 0.1);\n color: rgb(34, 197, 94);\n border: 1px solid rgba(34, 197, 94, 0.2);\n}\n\n.modal-body .loading-spinner {\n display: inline-block;\n width: 1rem;\n height: 1rem;\n border: 2px solid var(--color-border);\n border-top-color: var(--color-primary);\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n margin-right: 0.5rem;\n vertical-align: middle;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n.modal-body .source-type-selector {\n display: flex;\n gap: 0.5rem;\n margin-bottom: 1rem;\n padding: 0.5rem;\n background: var(--color-bg-secondary);\n border-radius: 0.25rem;\n}\n\n.modal-body .source-type-option {\n flex: 1;\n padding: 0.5rem;\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n background: var(--color-bg);\n color: var(--color-text);\n cursor: pointer;\n text-align: center;\n font-size: 0.875rem;\n transition: all 0.15s;\n}\n\n.modal-body .source-type-option:hover {\n background: var(--color-border);\n}\n\n.modal-body .source-type-option.active {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n}\n\n.modal-body .source-controls {\n display: none;\n}\n\n.modal-body .source-controls.active {\n display: block;\n}\n\n","import { graph } from '../index'\nimport { Ingest } from '../api/ingest'\nimport type { API } from '../api/api'\nimport { WebSocketSource } from '../api/sources/WebSocketSource'\nimport { FileSystemSource } from '../api/sources/FileSystemSource'\nimport { FileSource } from '../api/sources/FileSource'\nimport type { PlaygroundOptions, Example } from './types'\nimport styles from './styles.css?raw'\n\nexport class Playground {\n private options: PlaygroundOptions\n private rootElement: HTMLElement\n private currentExample: string\n private examples: Record<string, Example>\n private currentGraph: API<any, any> | null = null\n private ingest: Ingest<any, any> | null = null\n private isEditable = false\n private wsSource: WebSocketSource<any, any> | null = null\n private fsSource: FileSystemSource<any, any> | null = null\n private fileSource: FileSource<any, any> | null = null\n private wsStatus: 'disconnected' | 'connecting' | 'connected' | 'error' = 'disconnected'\n private fsStatus: 'disconnected' | 'opening' | 'connected' | 'error' = 'disconnected'\n private fileStatus: 'disconnected' | 'connecting' | 'connected' | 'error' = 'disconnected'\n private activeSourceType: 'ws' | 'folder' | 'file' | null = null\n private wsUrl = 'ws://localhost:8787'\n private sourceModal: HTMLElement | null = null\n private helpOverlay: HTMLElement | null = null\n private exampleList: string[]\n private graphContainerId: string\n\n constructor(options: PlaygroundOptions) {\n this.options = options\n this.examples = { ...options.examples }\n this.exampleList = Object.keys(this.examples)\n this.currentExample = options.defaultExample || this.exampleList[0]\n this.graphContainerId = `playground-graph-${Math.random().toString(36).substr(2, 9)}`\n\n // Resolve root element\n if (typeof options.root === 'string') {\n const el = document.getElementById(options.root)\n if (!el) throw new Error(`Element with id \"${options.root}\" not found`)\n this.rootElement = el\n } else {\n this.rootElement = options.root\n }\n }\n\n async init() {\n this.injectStyles()\n this.createDOM()\n this.setupEventListeners()\n await this.renderGraph()\n this.updateSourceIcon()\n this.connectExampleSource()\n\n // Set initial rebuild button state\n const rebuildBtn = this.rootElement.querySelector('#rebuild') as HTMLButtonElement | null\n if (rebuildBtn) rebuildBtn.disabled = !this.isEditable\n }\n\n private injectStyles() {\n if (!document.getElementById('g3p-playground-styles')) {\n const styleEl = document.createElement('style')\n styleEl.id = 'g3p-playground-styles'\n styleEl.textContent = styles\n document.head.appendChild(styleEl)\n }\n }\n\n private createDOM() {\n const exampleList = this.exampleList.map((key, i) => {\n const example = this.examples[key]\n const isActive = i === 0 || key === this.currentExample\n return `\n <button class=\"example-btn ${isActive ? 'active' : ''}\" data-example=\"${key}\">\n ${example.name}\n </button>\n `\n }).join('')\n\n this.rootElement.innerHTML = `\n <main class=\"playground\">\n <div class=\"sidebar\">\n <h2>Examples</h2>\n <div class=\"example-list\">\n ${exampleList}\n </div>\n\n <h2>Options</h2>\n <div class=\"options\">\n <div class=\"option-group\">\n <label>Orientation</label>\n <select id=\"orientation\">\n <option value=\"TB\">Top to Bottom</option>\n <option value=\"BT\">Bottom to Top</option>\n <option value=\"LR\">Left to Right</option>\n <option value=\"RL\">Right to Left</option>\n </select>\n </div>\n\n <div class=\"option-group\">\n <label>Port Style</label>\n <select id=\"portStyle\">\n <option value=\"outside\">Outside</option>\n <option value=\"inside\">Inside</option>\n </select>\n </div>\n\n <div class=\"option-group\">\n <label>\n <input type=\"checkbox\" id=\"portLabelRotate\" />\n Rotate Port Labels\n </label>\n </div>\n\n <div class=\"option-group\">\n <label>Theme</label>\n <select id=\"colorMode\">\n <option value=\"system\">System</option>\n <option value=\"light\">Light</option>\n <option value=\"dark\">Dark</option>\n </select>\n </div>\n </div>\n </div>\n\n <div class=\"graph-area\">\n <div class=\"graph-toolbar\">\n <div class=\"nav-controls\">\n <button class=\"nav-btn\" id=\"nav-first\" title=\"First (Home)\">⏮</button>\n <button class=\"nav-btn\" id=\"nav-prev\" title=\"Previous (←)\">◀</button>\n <span id=\"history-label\" style=\"min-width: 4rem; text-align: center; display: inline-flex; align-items: center; justify-content: center; height: 2.25rem;\">— / —</span>\n <button class=\"nav-btn\" id=\"nav-next\" title=\"Next (→)\">▶</button>\n <button class=\"nav-btn\" id=\"nav-last\" title=\"Last (End)\">⏭</button>\n </div>\n <div class=\"connect-controls\" style=\"display:flex; gap:.5rem; align-items:center;\">\n <button class=\"nav-btn source-icon-btn\" id=\"source-icon\" title=\"Data Source Connection\">📡</button>\n </div>\n <button class=\"nav-btn\" id=\"help-btn\" title=\"How to edit\">❓</button>\n <button class=\"nav-btn\" id=\"edit-toggle\" title=\"Toggle edit mode\">✎ Edit</button>\n <button class=\"nav-btn\" id=\"rebuild\" title=\"Rebuild graph from scratch\">🔄 Rebuild</button>\n </div>\n <div class=\"graph-container\" id=\"${this.graphContainerId}\"></div>\n </div>\n </main>\n `\n }\n\n private setupEventListeners() {\n // Example button handlers\n this.rootElement.querySelectorAll('.example-btn').forEach(btn => {\n btn.addEventListener('click', () => {\n this.rootElement.querySelectorAll('.example-btn').forEach(b => b.classList.remove('active'))\n btn.classList.add('active')\n this.currentExample = btn.getAttribute('data-example') || this.exampleList[0]\n this.renderGraph()\n this.connectExampleSource()\n })\n })\n\n // Option change handlers\n this.rootElement.querySelectorAll('.options select, .options input').forEach(el => {\n el.addEventListener('change', () => {\n // Handle color mode changes efficiently without re-rendering\n if (el.id === 'colorMode' && this.currentGraph) {\n const mode = (el as HTMLSelectElement).value as 'light' | 'dark' | 'system'\n this.currentGraph.setColorMode(mode)\n } else {\n this.renderGraph()\n }\n })\n })\n\n // Navigation controls\n this.rootElement.querySelector('#nav-first')?.addEventListener('click', () => {\n this.currentGraph?.nav('first')\n this.updateHistoryLabel()\n })\n this.rootElement.querySelector('#nav-prev')?.addEventListener('click', () => {\n this.currentGraph?.nav('prev')\n this.updateHistoryLabel()\n })\n this.rootElement.querySelector('#nav-next')?.addEventListener('click', () => {\n this.currentGraph?.nav('next')\n this.updateHistoryLabel()\n })\n this.rootElement.querySelector('#nav-last')?.addEventListener('click', () => {\n this.currentGraph?.nav('last')\n this.updateHistoryLabel()\n })\n\n // Rebuild button\n this.rootElement.querySelector('#rebuild')?.addEventListener('click', () => {\n this.currentGraph?.rebuild()\n })\n\n // Edit toggle\n this.rootElement.querySelector('#edit-toggle')?.addEventListener('click', () => {\n this.isEditable = !this.isEditable\n const btn = this.rootElement.querySelector('#edit-toggle')\n if (btn) btn.textContent = this.isEditable ? '✓ Done' : '✎ Edit'\n const rebuildBtn = this.rootElement.querySelector('#rebuild') as HTMLButtonElement | null\n if (rebuildBtn) rebuildBtn.disabled = !this.isEditable\n try {\n this.currentGraph?.setEditable?.(this.isEditable)\n } catch { }\n })\n\n // Help button\n this.rootElement.querySelector('#help-btn')?.addEventListener('click', () => this.openHelp())\n\n // Source icon button\n const sourceIconBtn = this.rootElement.querySelector('#source-icon')\n if (sourceIconBtn) {\n sourceIconBtn.addEventListener('click', (e) => {\n e.preventDefault()\n e.stopPropagation()\n this.openSourceModal()\n })\n }\n\n // Keyboard shortcuts\n document.addEventListener('keydown', (e) => {\n if (!this.currentGraph) return\n if (e.target instanceof HTMLInputElement || e.target instanceof HTMLSelectElement) return\n\n switch (e.key) {\n case 'Home':\n this.currentGraph.nav('first')\n this.updateHistoryLabel()\n break\n case 'End':\n this.currentGraph.nav('last')\n this.updateHistoryLabel()\n break\n case 'ArrowLeft':\n this.currentGraph.nav('prev')\n this.updateHistoryLabel()\n break\n case 'ArrowRight':\n this.currentGraph.nav('next')\n this.updateHistoryLabel()\n break\n }\n })\n }\n\n private getResolvedColorMode(): 'light' | 'dark' {\n const mode = (this.rootElement.querySelector('#colorMode') as HTMLSelectElement)?.value\n if (mode === 'system') {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n }\n return mode as 'light' | 'dark'\n }\n\n private getOptions(exampleOptions?: any) {\n const orientation = (this.rootElement.querySelector('#orientation') as HTMLSelectElement)?.value\n\n return {\n graph: { orientation },\n canvas: {\n width: '100%',\n height: '100%',\n colorMode: this.getResolvedColorMode(),\n editable: this.isEditable,\n ...exampleOptions?.canvas,\n }\n }\n }\n\n private async renderGraph() {\n const container = this.rootElement.querySelector(`#${this.graphContainerId}`) as HTMLElement\n if (!container) return\n\n // Destroy previous graph to clean up styles\n this.currentGraph?.destroy()\n this.currentGraph = null\n\n container.innerHTML = ''\n\n const example = this.examples[this.currentExample]\n const options = this.getOptions(example.options)\n\n try {\n this.currentGraph = await graph({\n root: this.graphContainerId,\n nodes: example.nodes as any,\n edges: example.edges as any,\n options,\n events: {\n historyChange: () => this.updateHistoryLabel(),\n }\n } as any)\n this.ingest = new Ingest(this.currentGraph)\n this.updateHistoryLabel()\n } catch (e) {\n console.error('Failed to render graph:', e)\n container.innerHTML = '<p style=\"padding: 2rem; color: #ef4444;\">Failed to load graph</p>'\n }\n }\n\n private updateHistoryLabel() {\n const label = this.rootElement.querySelector('#history-label')\n if (!label || !this.currentGraph) return\n try {\n const idx = this.currentGraph.getHistoryIndex?.() ?? 0\n const len = this.currentGraph.getHistoryLength?.() ?? 1\n label.textContent = `${idx + 1} / ${len}`\n } catch {\n label.textContent = '— / —'\n }\n }\n\n private connectExampleSource() {\n const example = this.examples[this.currentExample]\n if (!example.source) {\n // No source specified, disconnect any active sources\n this.disconnectAllSources()\n return\n }\n\n // Disconnect existing sources first\n this.disconnectAllSources()\n\n if (example.source.type === 'websocket') {\n this.wsUrl = example.source.url\n this.wsSource = new WebSocketSource({\n url: example.source.url,\n onMessage: this.handleIngestMessage.bind(this),\n onStatus: this.updateWsStatus,\n })\n this.wsSource.connect()\n } else if (example.source.type === 'file') {\n this.fileSource = new FileSource({\n url: example.source.path,\n onMessage: this.handleIngestMessage.bind(this),\n onStatus: this.updateFileStatus,\n })\n this.fileSource.connect()\n }\n }\n\n private disconnectAllSources() {\n this.wsSource?.disconnect()\n this.fsSource?.close()\n this.fileSource?.close()\n this.wsSource = null\n this.fsSource = null\n this.fileSource = null\n this.activeSourceType = null\n this.wsStatus = 'disconnected'\n this.fsStatus = 'disconnected'\n this.fileStatus = 'disconnected'\n this.updateSourceIcon()\n }\n\n private openHelp() {\n if (!this.helpOverlay) {\n this.helpOverlay = document.createElement('div')\n this.helpOverlay.className = 'modal-overlay'\n this.helpOverlay.innerHTML = `\n <div class=\"modal\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"help-title\">\n <div class=\"modal-header\">\n <h3 id=\"help-title\">Editing the Graph</h3>\n <button class=\"modal-close\" title=\"Close\" aria-label=\"Close\">×</button>\n </div>\n <div class=\"modal-body\">\n <p>Here's how to edit the graph:</p>\n <ul>\n <li><strong>Enable editing</strong>: Click \"Edit\"</li>\n <li><strong>Add a node</strong>: Double‑click an empty area</li>\n <li><strong>Edit a node</strong>: Double‑click a node</li>\n <li><strong>Edit an edge</strong>: Double‑click an edge</li>\n <li><strong>Create an edge</strong>: Click and drag from a node (or its port) onto another node; press Esc to cancel</li>\n <li><strong>Pan</strong>: Drag on canvas or edges; <strong>Zoom</strong>: Mouse wheel or controls</li>\n <li><strong>Rebuild</strong>: Use \"Rebuild\" to re-layout from scratch (enabled in edit mode)</li>\n </ul>\n <p>When you're done, click \"Done\" to lock the canvas.</p>\n </div>\n </div>\n `\n document.body.appendChild(this.helpOverlay)\n this.helpOverlay.addEventListener('click', (e) => {\n const target = e.target as HTMLElement\n if (target.classList.contains('modal-overlay') || target.classList.contains('modal-close')) {\n this.closeHelp()\n }\n })\n }\n this.helpOverlay.style.display = 'flex'\n }\n\n private closeHelp() {\n if (this.helpOverlay) this.helpOverlay.style.display = 'none'\n }\n\n private handleIngestMessage = async (msg: any) => {\n if (!this.ingest) return\n await this.ingest.apply(msg)\n }\n\n private updateSourceIcon() {\n const iconBtn = this.rootElement.querySelector('#source-icon')\n if (!iconBtn) return\n iconBtn.classList.remove('active', 'connecting', 'error')\n\n const isConnected = (this.activeSourceType === 'ws' && this.wsStatus === 'connected') ||\n (this.activeSourceType === 'folder' && this.fsStatus === 'connected') ||\n (this.activeSourceType === 'file' && this.fileStatus === 'connected')\n const isConnecting = (this.activeSourceType === 'ws' && this.wsStatus === 'connecting') ||\n (this.activeSourceType === 'folder' && this.fsStatus === 'opening') ||\n (this.activeSourceType === 'file' && this.fileStatus === 'connecting')\n const hasError = (this.activeSourceType === 'ws' && this.wsStatus === 'error') ||\n (this.activeSourceType === 'folder' && this.fsStatus === 'error') ||\n (this.activeSourceType === 'file' && this.fileStatus === 'error')\n\n let icon = '📡'\n if (this.activeSourceType === 'folder') {\n icon = '📁'\n } else if (this.activeSourceType === 'file') {\n icon = '📄'\n }\n\n if (isConnected) {\n iconBtn.classList.add('active')\n iconBtn.textContent = icon\n } else if (isConnecting) {\n iconBtn.classList.add('connecting')\n iconBtn.textContent = icon\n } else if (hasError) {\n iconBtn.classList.add('error')\n iconBtn.textContent = icon\n } else {\n iconBtn.textContent = '📡'\n }\n }\n\n private updateWsStatus = (status: 'connecting' | 'connected' | 'reconnecting' | 'closed' | 'error', detail?: any) => {\n if (status === 'connecting' || status === 'reconnecting') {\n this.wsStatus = 'connecting'\n this.activeSourceType = 'ws'\n } else if (status === 'connected') {\n this.wsStatus = 'connected'\n this.activeSourceType = 'ws'\n if (this.fsSource && this.fsStatus === 'connected') {\n this.fsSource.close()\n }\n if (this.fileSource && this.fileStatus === 'connected') {\n this.fileSource.close()\n }\n } else if (status === 'error') {\n this.wsStatus = 'error'\n } else {\n this.wsStatus = 'disconnected'\n if (this.activeSourceType === 'ws') {\n this.activeSourceType = null\n }\n }\n this.updateSourceIcon()\n this.updateSourceModal()\n }\n\n private updateFsStatus = (status: 'idle' | 'opened' | 'reading' | 'error' | 'closed', detail?: any) => {\n if (status === 'opened') {\n this.fsStatus = 'opening'\n this.activeSourceType = 'folder'\n if (this.wsSource && this.wsStatus === 'connected') {\n this.wsSource.disconnect()\n }\n } else if (status === 'reading') {\n this.fsStatus = 'connected'\n this.activeSourceType = 'folder'\n } else if (status === 'error') {\n this.fsStatus = 'error'\n } else if (status === 'closed') {\n this.fsStatus = 'disconnected'\n if (this.activeSourceType === 'folder') {\n this.activeSourceType = null\n }\n } else {\n this.fsStatus = 'disconnected'\n }\n this.updateSourceIcon()\n this.updateSourceModal()\n }\n\n private updateFileStatus = (status: 'idle' | 'opened' | 'reading' | 'error' | 'closed', detail?: any) => {\n if (status === 'opened') {\n this.fileStatus = 'connecting'\n this.activeSourceType = 'file'\n if (this.wsSource && this.wsStatus === 'connected') {\n this.wsSource.disconnect()\n }\n if (this.fsSource && this.fsStatus === 'connected') {\n this.fsSource.close()\n }\n } else if (status === 'reading') {\n this.fileStatus = 'connected'\n this.activeSourceType = 'file'\n } else if (status === 'error') {\n this.fileStatus = 'error'\n } else if (status === 'closed') {\n this.fileStatus = 'disconnected'\n if (this.activeSourceType === 'file') {\n this.activeSourceType = null\n }\n } else {\n this.fileStatus = 'disconnected'\n }\n this.updateSourceIcon()\n this.updateSourceModal()\n }\n\n private createSourceModal() {\n if (this.sourceModal) return this.sourceModal\n\n this.sourceModal = document.createElement('div')\n this.sourceModal.className = 'modal-overlay'\n this.sourceModal.style.display = 'none'\n this.sourceModal.innerHTML = `\n <div class=\"modal\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"source-modal-title\">\n <div class=\"modal-header\">\n <h3 id=\"source-modal-title\">Data Source Connection</h3>\n <button class=\"modal-close\" title=\"Close\" aria-label=\"Close\">×</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"source-type-selector\">\n <button class=\"source-type-option\" data-source=\"ws\">📡 WebSocket</button>\n <button class=\"source-type-option\" data-source=\"folder\">📁 Folder</button>\n </div>\n\n <div class=\"source-controls\" data-source=\"ws\">\n <div class=\"form-group\">\n <label for=\"source-modal-url\">WebSocket URL</label>\n <input type=\"text\" id=\"source-modal-url\" value=\"${this.wsUrl}\" />\n </div>\n <div class=\"button-group\">\n <button id=\"source-modal-connect-ws\" class=\"primary\">Connect</button>\n <button id=\"source-modal-disconnect-ws\">Disconnect</button>\n <button id=\"source-modal-change-ws\">Change Connection</button>\n </div>\n </div>\n\n <div class=\"source-controls\" data-source=\"folder\">\n <div class=\"form-group\">\n <label>File System Source</label>\n <p style=\"font-size: 0.875rem; color: var(--color-text-muted); margin-top: 0.25rem;\">\n Select a directory containing a graph.ndjson file to watch for changes.\n </p>\n </div>\n <div class=\"button-group\">\n <button id=\"source-modal-connect-folder\" class=\"primary\">Open Folder</button>\n <button id=\"source-modal-disconnect-folder\">Disconnect</button>\n </div>\n </div>\n\n <div id=\"source-modal-status\"></div>\n </div>\n </div>\n `\n document.body.appendChild(this.sourceModal)\n\n this.sourceModal.addEventListener('click', (e) => {\n const target = e.target as HTMLElement\n if (target.classList.contains('modal-overlay') || target.classList.contains('modal-close')) {\n this.closeSourceModal()\n }\n })\n\n this.sourceModal.querySelectorAll('.source-type-option').forEach(btn => {\n btn.addEventListener('click', () => {\n const sourceType = btn.getAttribute('data-source')\n if (sourceType) {\n this.selectSourceType(sourceType as 'ws' | 'folder')\n }\n })\n })\n\n document.getElementById('source-modal-connect-ws')?.addEventListener('click', () => this.handleConnect())\n document.getElementById('source-modal-disconnect-ws')?.addEventListener('click', () => this.handleDisconnect())\n document.getElementById('source-modal-change-ws')?.addEventListener('click', () => this.handleChangeConnection())\n document.getElementById('source-modal-connect-folder')?.addEventListener('click', () => this.handleOpenFolder())\n document.getElementById('source-modal-disconnect-folder')?.addEventListener('click', () => this.handleCloseFolder())\n\n document.getElementById('source-modal-url')?.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && this.wsStatus !== 'connected') {\n this.handleConnect()\n }\n })\n\n return this.sourceModal\n }\n\n private selectSourceType(type: 'ws' | 'folder', skipUpdate = false) {\n if (!this.sourceModal) return\n\n this.sourceModal.querySelectorAll('.source-type-option').forEach(btn => {\n if (btn.getAttribute('data-source') === type) {\n btn.classList.add('active')\n } else {\n btn.classList.remove('active')\n }\n })\n\n this.sourceModal.querySelectorAll('.source-controls').forEach(controls => {\n if (controls.getAttribute('data-source') === type) {\n controls.classList.add('active')\n } else {\n controls.classList.remove('active')\n }\n })\n\n if (!skipUpdate) {\n this.updateSourceModalContent()\n }\n }\n\n private updateSourceModalContent() {\n if (!this.sourceModal) return\n\n const urlInput = document.getElementById('source-modal-url') as HTMLInputElement\n const connectWsBtn = document.getElementById('source-modal-connect-ws') as HTMLButtonElement\n const disconnectWsBtn = document.getElementById('source-modal-disconnect-ws') as HTMLButtonElement\n const changeWsBtn = document.getElementById('source-modal-change-ws') as HTMLButtonElement\n\n if (urlInput && connectWsBtn && disconnectWsBtn && changeWsBtn) {\n const isWsConnected = this.wsStatus === 'connected'\n const isWsConnecting = this.wsStatus === 'connecting'\n\n connectWsBtn.disabled = isWsConnected || isWsConnecting\n disconnectWsBtn.disabled = !isWsConnected || isWsConnecting\n changeWsBtn.disabled = !isWsConnected || isWsConnecting\n urlInput.disabled = isWsConnecting\n }\n\n const connectFolderBtn = document.getElementById('source-modal-connect-folder') as HTMLButtonElement\n const disconnectFolderBtn = document.getElementById('source-modal-disconnect-folder') as HTMLButtonElement\n\n if (connectFolderBtn && disconnectFolderBtn) {\n const isFolderConnected = this.fsStatus === 'connected'\n const isFolderOpening = this.fsStatus === 'opening'\n\n connectFolderBtn.disabled = isFolderConnected || isFolderOpening\n disconnectFolderBtn.disabled = !isFolderConnected || isFolderOpening\n }\n\n const statusDiv = document.getElementById('source-modal-status')\n if (!statusDiv) return\n\n const currentUrl = urlInput?.value || this.wsUrl\n statusDiv.innerHTML = ''\n\n if (this.activeSourceType === 'ws') {\n if (this.wsStatus === 'connecting') {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n <span class=\"loading-spinner\"></span>\n Connecting to ${currentUrl}...\n </div>\n `\n } else if (this.wsStatus === 'connected') {\n statusDiv.innerHTML = `\n <div class=\"status-message success\">\n ✓ Connected to ${currentUrl}\n </div>\n `\n } else if (this.wsStatus === 'error') {\n statusDiv.innerHTML = `\n <div class=\"status-message error\">\n ✗ Connection error. Please check the URL and try again.\n </div>\n `\n } else {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n Not connected\n </div>\n `\n }\n } else if (this.activeSourceType === 'folder') {\n if (this.fsStatus === 'opening') {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n <span class=\"loading-spinner\"></span>\n Opening folder...\n </div>\n `\n } else if (this.fsStatus === 'connected') {\n statusDiv.innerHTML = `\n <div class=\"status-message success\">\n ✓ Folder connected and watching for changes\n </div>\n `\n } else if (this.fsStatus === 'error') {\n statusDiv.innerHTML = `\n <div class=\"status-message error\">\n ✗ Error opening folder. Please try again.\n </div>\n `\n } else {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n Not connected\n </div>\n `\n }\n } else if (this.activeSourceType === 'file') {\n const example = this.examples[this.currentExample]\n const filePath = example.source?.type === 'file' ? example.source.path : ''\n if (this.fileStatus === 'connecting') {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n <span class=\"loading-spinner\"></span>\n Connecting to ${filePath}...\n </div>\n `\n } else if (this.fileStatus === 'connected') {\n statusDiv.innerHTML = `\n <div class=\"status-message success\">\n ✓ Connected to ${filePath}\n </div>\n `\n } else if (this.fileStatus === 'error') {\n statusDiv.innerHTML = `\n <div class=\"status-message error\">\n ✗ Error loading file. Please check the path and try again.\n </div>\n `\n } else {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n Not connected\n </div>\n `\n }\n } else {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n Select a source type to connect\n </div>\n `\n }\n }\n\n private updateSourceModal() {\n if (!this.sourceModal) return\n\n // Map file source to ws for modal display (file sources are handled via examples)\n const activeType = (this.activeSourceType === 'file' ? 'ws' : this.activeSourceType) || 'ws'\n this.selectSourceType(activeType as 'ws' | 'folder', true)\n this.updateSourceModalContent()\n }\n\n private openSourceModal() {\n this.createSourceModal()\n if (this.sourceModal) {\n const urlInput = document.getElementById('source-modal-url') as HTMLInputElement\n if (urlInput) {\n urlInput.value = this.wsUrl\n }\n // Map file source to ws for modal display (file sources are handled via examples)\n const activeType = (this.activeSourceType === 'file' ? 'ws' : this.activeSourceType) || 'ws'\n this.selectSourceType(activeType as 'ws' | 'folder')\n this.updateSourceModal()\n this.sourceModal.style.display = 'flex'\n }\n }\n\n private closeSourceModal() {\n if (this.sourceModal) {\n this.sourceModal.style.display = 'none'\n }\n }\n\n private handleConnect() {\n const urlInput = document.getElementById('source-modal-url') as HTMLInputElement\n if (!urlInput) return\n\n const url = urlInput.value.trim() || 'ws://localhost:8787'\n this.wsUrl = url\n\n if (this.wsSource) {\n this.wsSource.disconnect()\n }\n\n this.wsSource = new WebSocketSource({\n url: url,\n onMessage: this.handleIngestMessage.bind(this),\n onStatus: this.updateWsStatus,\n })\n this.wsSource.connect()\n this.updateSourceModal()\n }\n\n private handleDisconnect() {\n this.wsSource?.disconnect()\n this.updateSourceModal()\n }\n\n private handleChangeConnection() {\n if (this.wsSource) {\n this.wsSource.disconnect()\n }\n const urlInput = document.getElementById('source-modal-url') as HTMLInputElement\n if (urlInput) {\n urlInput.focus()\n urlInput.select()\n }\n this.updateSourceModal()\n }\n\n private async handleOpenFolder() {\n if (!this.fsSource) {\n this.fsSource = new FileSystemSource({\n filename: 'graph.ndjson',\n onMessage: this.handleIngestMessage.bind(this),\n onStatus: this.updateFsStatus,\n })\n }\n this.updateSourceModal()\n await this.fsSource.openDirectory()\n }\n\n private handleCloseFolder() {\n this.fsSource?.close()\n this.updateSourceModal()\n }\n\n /**\n * Add or update an example\n */\n addExample(key: string, example: Example) {\n this.examples[key] = example\n this.updateExampleList()\n // If this is the current example, re-render\n if (this.currentExample === key) {\n this.renderGraph()\n this.connectExampleSource()\n }\n }\n\n /**\n * Remove an example\n */\n removeExample(key: string) {\n delete this.examples[key]\n if (this.currentExample === key) {\n // If we removed the current example, switch to the first available\n this.exampleList = Object.keys(this.examples)\n this.currentExample = this.exampleList[0] || ''\n if (this.currentExample) {\n this.renderGraph()\n this.connectExampleSource()\n }\n }\n this.updateExampleList()\n }\n\n /**\n * Update the example list in the DOM\n */\n private updateExampleList() {\n this.exampleList = Object.keys(this.examples)\n const exampleListEl = this.rootElement.querySelector('.example-list')\n if (!exampleListEl) return\n\n exampleListEl.innerHTML = this.exampleList.map((key, i) => {\n const example = this.examples[key]\n const isActive = key === this.currentExample\n return `\n <button class=\"example-btn ${isActive ? 'active' : ''}\" data-example=\"${key}\">\n ${example.name}\n </button>\n `\n }).join('')\n\n // Re-attach event listeners\n exampleListEl.querySelectorAll('.example-btn').forEach(btn => {\n btn.addEventListener('click', () => {\n this.rootElement.querySelectorAll('.example-btn').forEach(b => b.classList.remove('active'))\n btn.classList.add('active')\n this.currentExample = btn.getAttribute('data-example') || this.exampleList[0]\n this.renderGraph()\n this.connectExampleSource()\n })\n })\n }\n}\n\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["import_immutable","log","pino","module","log","ISet","type","dir","import_immutable","log","import_immutable","ISet","import_immutable","log","ISet","node","import_immutable","log","ISet","seg","import_immutable","log","import_immutable","log","seg","segs","node","dir","log","tracks","alpha","log","ISet","IMap","IList","import_jsx_runtime","Node","import_jsx_runtime","Seg","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","log","Node","Seg","el","import_jsx_runtime","graph","log","graph","node","edge","styles_default","styles_default"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/graph/graph.ts","../src/graph/node.ts","../src/log.ts","../src/graph/edge.ts","../src/graph/seg.ts","../src/graph/layer.ts","../src/graph/mutator.ts","../src/graph/services/cycles.ts","../src/graph/services/dummy.ts","../src/graph/services/layers.ts","../src/graph/services/layout.ts","../src/canvas/marker.tsx","../src/graph/services/lines.ts","../src/common.ts","../src/canvas/node.tsx","../src/canvas/seg.tsx","../src/canvas/editMode.ts","../src/canvas/newEdge.tsx","../src/canvas/modal.tsx","../src/canvas/styles.css","../src/canvas/canvas.tsx","../src/canvas/render-node.tsx","../src/api/defaults.ts","../src/api/updater.ts","../src/api/ingest.ts","../src/api/sources/WebSocketSource.ts","../src/api/sources/FileSource.ts","../src/api/sources/FileSystemSource.ts","../src/api/api.ts","../src/playground/styles.css","../src/playground/playground.ts"],"sourcesContent":["import { API } from './api/api'\nimport { APIArguments } from './api/options'\n\nexport async function graph<N, E>(args: APIArguments<N, E> = { root: 'app' }) {\n const api = new API<N, E>(args)\n await api.init()\n return api\n}\n\nexport default graph\n\nexport * from './api/ingest'\nexport * from './api/sources/WebSocketSource'\nexport * from './api/sources/FileSystemSource'\nexport * from './api/sources/FileSource'\nexport * from './playground'\n\n// Export API types\nexport type { API } from './api/api'\nexport type {\n APIArguments,\n APIOptions,\n CanvasOptions,\n Update,\n IngestionConfig,\n EventsOptions,\n // Callback parameter types\n NewNode,\n NewEdge,\n NodeProps,\n EdgeProps,\n PortProps,\n RenderNode,\n MountNode,\n // Theming types\n ColorMode,\n ThemeVars,\n CanvasTheme,\n NodeTheme,\n PortTheme,\n EdgeTheme,\n} from './api/options'\nexport { Updater } from './api/updater'\n\n// Export common types\nexport type { Orientation, NodeAlign, PortStyle } from './common'\n","import { Map as IMap, List as IList, Set as ISet } from 'immutable'\nimport { Dims, Pos } from '../common'\nimport { GraphOptions } from '../api/options'\nimport { Node, NodeId, PublicNodeData } from './node'\nimport { Edge, EdgeId, PublicEdgeData } from './edge'\nimport { Seg, SegId } from './seg'\nimport { Layer, LayerId } from './layer'\nimport { Mutator } from './mutator'\nimport { Cycles } from './services/cycles'\nimport { Dummy } from './services/dummy'\nimport { Layers } from './services/layers'\nimport { Layout } from './services/layout'\nimport { Lines } from './services/lines'\nimport { logger } from '../log'\n\nconst log = logger('graph')\n\ntype GraphArgs = {\n changes?: Changes\n options?: Required<GraphOptions>\n prior?: Graph\n}\n\nexport type Changes = {\n addedNodes: PublicNodeData[],\n removedNodes: { id: string }[],\n updatedNodes: PublicNodeData[],\n addedEdges: PublicEdgeData[],\n removedEdges: { id: string }[],\n updatedEdges: PublicEdgeData[],\n description?: string,\n}\n\nconst emptyChanges: Changes = {\n addedNodes: [],\n removedNodes: [],\n updatedNodes: [],\n addedEdges: [],\n removedEdges: [],\n updatedEdges: [],\n}\n\nexport class Graph {\n prior?: Graph\n nodes!: IMap<NodeId, Node>\n edges!: IMap<EdgeId, Edge>\n segs!: IMap<SegId, Seg>\n layers!: IMap<LayerId, Layer>\n layerList!: IList<LayerId>\n nextLayerId!: number\n nextDummyId!: number\n options: Required<GraphOptions>\n changes: Changes\n\n dirtyNodes!: Set<NodeId>\n dirtyEdges!: Set<EdgeId>\n dirtyLayers!: Set<LayerId>\n dirtySegs!: Set<SegId>\n dirty!: boolean\n\n delNodes!: Set<NodeId>\n delEdges!: Set<EdgeId>\n delSegs!: Set<SegId>\n\n r: boolean\n v: boolean\n n: boolean\n h: keyof Dims\n w: keyof Dims\n x: keyof Pos\n y: keyof Pos\n d: Pos\n\n constructor({ prior, changes, options }: GraphArgs) {\n this.options = prior?.options ?? options!\n this.changes = changes ?? emptyChanges\n this.initFromPrior(prior)\n\n // Set orientation-based properties\n this.r = this.options.orientation === 'BT' || this.options.orientation === 'RL'\n this.v = this.options.orientation === 'TB' || this.options.orientation === 'BT'\n this.h = this.v ? 'h' : 'w'\n this.w = this.v ? 'w' : 'h'\n this.x = this.v ? 'x' : 'y'\n this.y = this.v ? 'y' : 'x'\n this.d = {\n x: this.v ? 0 : (this.r ? -1 : 1),\n y: this.v ? (this.r ? -1 : 1) : 0,\n }\n\n // n means the node alignment follows the natural orientation\n // For each orientation, we map it to the corresponding alignment\n const natAligns = { TB: 'top', BT: 'bottom', LR: 'left', RL: 'right' };\n if (this.options.nodeAlign == 'natural')\n this.n = true\n else\n this.n = natAligns[this.options.orientation] == this.options.nodeAlign\n\n if (this.dirty) this.processUpdate()\n }\n\n processUpdate() {\n try {\n this.beginMutate()\n this.applyChanges()\n Cycles.checkCycles(this)\n Layers.updateLayers(this)\n /* debug removed */\n Dummy.updateDummies(this)\n Dummy.mergeDummies(this)\n Layout.positionNodes(this)\n Layout.alignAll(this)\n Lines.trackEdges(this)\n Layout.getCoords(this)\n Lines.pathEdges(this)\n } catch (e) {\n this.initFromPrior(this.prior)\n throw e\n } finally {\n this.endMutate()\n }\n }\n\n applyChanges() {\n for (const edge of this.changes.removedEdges)\n Edge.del(this, edge)\n for (const node of this.changes.removedNodes)\n Node.del(this, node)\n for (const node of this.changes.addedNodes)\n Node.addNormal(this, node)\n for (const edge of this.changes.addedEdges)\n Edge.add(this, edge)\n for (const node of this.changes.updatedNodes)\n Node.update(this, node)\n for (const edge of this.changes.updatedEdges)\n Edge.update(this, edge)\n }\n\n layerAt(index: number): Layer {\n while (index >= this.layerList.size)\n this.addLayer()\n const layerId = this.layerList.get(index)!\n return this.getLayer(layerId)\n }\n\n private addLayer() {\n const id = `${Layer.prefix}${this.nextLayerId++}`\n this.layers.set(id, new Layer({\n id,\n index: this.layerList.size,\n nodeIds: ISet()\n }))\n this.layerList.push(id)\n this.dirtyLayers.add(id)\n }\n\n isEdgeId(id: string): boolean {\n return id.startsWith(Edge.prefix)\n }\n\n isSegId(id: string): boolean {\n return id.startsWith(Seg.prefix)\n }\n\n getNode(nodeId: NodeId): Node {\n const node = this.nodes.get(nodeId)\n if (!node) throw new Error(`cannot find node ${nodeId}`)\n return node\n }\n\n getEdge(edgeId: EdgeId): Edge {\n const edge = this.edges.get(edgeId)\n if (!edge) throw new Error(`cannot find edge ${edgeId}`)\n return edge\n }\n\n getSeg(segId: SegId): Seg {\n const seg = this.segs.get(segId)\n if (!seg) throw new Error(`cannot find seg ${segId}`)\n return seg\n }\n\n getLayer(layerId: LayerId): Layer {\n const layer = this.layers.get(layerId)\n if (!layer) throw new Error(`cannot find layer ${layerId}`)\n return layer\n }\n\n layerIndex(nodeId: NodeId): number {\n return this.getNode(nodeId).layerIndex(this)\n }\n\n getRel(relId: EdgeId | SegId): Edge | Seg {\n return this.isSegId(relId)\n ? this.getSeg(relId)\n : this.getEdge(relId)\n }\n\n * getNodes(includeDummy: boolean = false): Generator<Node> {\n const gen = this.nodes.values()\n for (const node of this.nodes.values())\n if (includeDummy || !node.isDummy)\n yield node\n }\n\n * getEdges(): Generator<Edge> {\n yield* this.edges.values()\n }\n\n * getSegs(): Generator<Seg> {\n yield* this.segs.values()\n }\n\n withMutations(callback: (mut: Mutator) => void): Graph {\n const mut = new Mutator()\n callback(mut)\n return new Graph({ prior: this, changes: mut.changes })\n }\n\n addNode(node: PublicNodeData) {\n return this.withMutations(mutator => {\n mutator.addNode(node)\n })\n }\n\n addNodes(...nodes: PublicNodeData[]) {\n return this.withMutations(mutator => {\n nodes.forEach(node => mutator.addNode(node))\n })\n }\n\n removeNodes(...nodes: { id: string }[]) {\n return this.withMutations(mutator => {\n nodes.forEach(node => mutator.removeNode(node))\n })\n }\n\n removeNode(node: { id: string }) {\n return this.withMutations(mutator => {\n mutator.removeNode(node)\n })\n }\n\n addEdges(...edges: PublicEdgeData[]) {\n return this.withMutations(mutator => {\n edges.forEach(edge => mutator.addEdge(edge))\n })\n }\n\n addEdge(edge: PublicEdgeData) {\n return this.withMutations(mutator => {\n mutator.addEdge(edge)\n })\n }\n\n removeEdges(...edges: PublicEdgeData[]) {\n return this.withMutations(mutator => {\n edges.forEach(edge => mutator.removeEdge(edge))\n })\n }\n\n removeEdge(edge: PublicEdgeData) {\n return this.withMutations(mutator => {\n mutator.removeEdge(edge)\n })\n }\n\n mutateNode(node: Node): Node {\n if (node.mutable) return node\n node = node.asMutable().set('mutable', true)\n this.nodes.set(node.id, node)\n this.dirtyNodes.add(node.id)\n return node\n }\n\n mutateEdge(edge: Edge): Edge {\n if (edge.mutable) return edge\n edge = edge.asMutable().set('mutable', true)\n this.edges.set(edge.id, edge)\n this.dirtyEdges.add(edge.id)\n return edge\n }\n\n mutateLayer(layer: Layer): Layer {\n if (layer.mutable) return layer\n layer = layer.asMutable().set('mutable', true)\n this.layers.set(layer.id, layer)\n this.dirtyLayers.add(layer.id)\n return layer\n }\n\n mutateSeg(seg: Seg): Seg {\n if (seg.mutable) return seg\n seg = seg.asMutable().set('mutable', true)\n this.segs.set(seg.id, seg)\n this.dirtySegs.add(seg.id)\n return seg\n }\n\n private initFromPrior(prior?: Graph) {\n this.nodes = prior?.nodes ?? IMap()\n this.edges = prior?.edges ?? IMap()\n this.layers = prior?.layers ?? IMap()\n this.layerList = prior?.layerList ?? IList()\n this.segs = prior?.segs ?? IMap()\n this.nextLayerId = prior?.nextLayerId ?? 0\n this.nextDummyId = prior?.nextDummyId ?? 0\n this.prior = prior\n this.dirtyNodes = new Set()\n this.dirtyEdges = new Set()\n this.dirtyLayers = new Set()\n this.dirtySegs = new Set()\n this.delNodes = new Set()\n this.delEdges = new Set()\n this.delSegs = new Set()\n this.dirty =\n this.changes.addedNodes.length > 0 ||\n this.changes.removedNodes.length > 0 ||\n this.changes.updatedNodes.length > 0 ||\n this.changes.addedEdges.length > 0 ||\n this.changes.removedEdges.length > 0\n }\n\n private beginMutate() {\n this.nodes = this.nodes.asMutable()\n this.edges = this.edges.asMutable()\n this.layers = this.layers.asMutable()\n this.layerList = this.layerList.asMutable()\n this.segs = this.segs.asMutable()\n }\n\n private endMutate() {\n for (const nodeId of this.dirtyNodes)\n if (this.nodes.has(nodeId))\n this.nodes.set(nodeId, this.nodes.get(nodeId)!.final())\n for (const edgeId of this.dirtyEdges)\n if (this.edges.has(edgeId))\n this.edges.set(edgeId, this.edges.get(edgeId)!.final())\n for (const segId of this.dirtySegs)\n if (this.segs.has(segId))\n this.segs.set(segId, this.segs.get(segId)!.final())\n for (const layerId of this.dirtyLayers)\n if (this.layers.has(layerId))\n this.layers.set(layerId, this.layers.get(layerId)!.final())\n this.nodes = this.nodes.asImmutable()\n this.edges = this.edges.asImmutable()\n this.layers = this.layers.asImmutable()\n this.layerList = this.layerList.asImmutable()\n this.segs = this.segs.asImmutable()\n }\n\n}\n","import { Record, Set as ISet } from 'immutable'\nimport { LayerId } from './layer'\nimport { EdgeId, Edge } from './edge'\nimport { SegId, Seg } from './seg'\nimport { Dir, Side, Dims, Pos, LinkType } from '../common'\nimport { NodeStyle, RenderNode } from '../api/options'\nimport { Graph } from './graph'\nimport { Layer } from './layer'\nimport { logger } from '../log'\n\nconst log = logger('node')\n\nexport type NodeId = string\nexport type PortId = string\nexport type NodeKey = string\n\nexport type PortData = {\n id: string,\n label?: string,\n offset?: number,\n size?: number,\n}\n\nexport type PublicNodeData = {\n id: NodeId,\n data: any,\n version: number,\n title?: string\n text?: string\n type?: string\n ports: { in?: PortData[], out?: PortData[] }\n render?: RenderNode<any>\n dims?: Dims\n}\n\ntype NodeData = PublicNodeData & {\n aligned: { in?: NodeId, out?: NodeId }\n edges: { in: ISet<EdgeId>, out: ISet<EdgeId> }\n segs: { in: ISet<SegId>, out: ISet<SegId> }\n layerId: LayerId\n isDummy: boolean\n isMerged: boolean\n edgeIds: EdgeId[]\n index?: number\n pos?: Pos\n lpos?: number\n mutable: boolean\n}\n\nconst defNodeData: NodeData = {\n id: '',\n data: undefined,\n version: 0,\n title: undefined,\n text: undefined,\n type: undefined,\n render: undefined,\n ports: {},\n aligned: {},\n edges: { in: ISet(), out: ISet() },\n segs: { in: ISet(), out: ISet() },\n layerId: '',\n isDummy: false,\n isMerged: false,\n edgeIds: [],\n index: undefined,\n pos: undefined,\n lpos: undefined,\n dims: undefined,\n mutable: false,\n}\n\nexport class Node extends Record(defNodeData) {\n static dummyPrefix = 'd:'\n\n // get edgeId(): EdgeId {\n // if (!this.isDummy)\n // throw new Error(`node ${this.id} is not a dummy`)\n // if (this.isMerged)\n // throw new Error(`node ${this.id} is merged`)\n // return this.get('edgeIds')[0]\n // }\n\n // get edgeIds(): EdgeId[] {\n // if (!this.isDummy)\n // throw new Error(`node ${this.id} is not a dummy`)\n // if (!this.isMerged)\n // throw new Error(`node ${this.id} is not merged`)\n // return this.get('edgeIds')\n // }\n\n get key(): NodeKey {\n return this.isDummy ? this.id : Node.key(this)\n }\n\n static key(node: PublicNodeData): NodeKey {\n return `k:${node.id}:${node.version}`\n }\n\n static addNormal(g: Graph, data: PublicNodeData): Node {\n const layer = g.layerAt(0)\n const node = new Node({\n ...data,\n edges: { in: ISet(), out: ISet() },\n segs: { in: ISet(), out: ISet() },\n aligned: {},\n edgeIds: [],\n layerId: layer.id,\n lpos: undefined,\n pos: undefined,\n })\n layer.addNode(g, node.id)\n g.nodes.set(node.id, node)\n g.dirtyNodes.add(node.id)\n return node\n }\n\n static addDummy(g: Graph, data: Partial<NodeData>): Node {\n const layer = g.getLayer(data.layerId!)\n const node = new Node({\n ...data,\n id: `${Node.dummyPrefix}${g.nextDummyId++}`,\n edges: { in: ISet(), out: ISet() },\n segs: { in: ISet(), out: ISet() },\n aligned: {},\n isDummy: true,\n dims: {\n w: g.options.dummyNodeSize,\n h: g.options.dummyNodeSize,\n }\n })\n layer.addNode(g, node.id)\n g.nodes.set(node.id, node)\n g.dirtyNodes.add(node.id)\n return node\n }\n\n static del(g: Graph, node: { id: string }): null {\n return g.getNode(node.id).delSelf(g)\n }\n\n static update(g: Graph, data: PublicNodeData): Node {\n return g.getNode(data.id).mut(g).merge(data)\n }\n\n mut(g: Graph): Node {\n if (this.mutable) return this\n return g.mutateNode(this)\n }\n\n final(): Node {\n if (!this.mutable) return this\n return this.merge({\n edges: { in: this.edges.in.asImmutable(), out: this.edges.out.asImmutable() },\n segs: { in: this.segs.in.asImmutable(), out: this.segs.out.asImmutable() },\n mutable: false,\n }).asImmutable()\n }\n\n dirty(g: Graph): Node {\n g.dirtyNodes.add(this.id)\n return this\n }\n\n cur(g: Graph): Node {\n return g.getNode(this.id)\n }\n\n isUnlinked(): boolean {\n return this.edges.in.size == 0 &&\n this.edges.out.size == 0 &&\n this.segs.in.size == 0 &&\n this.segs.out.size == 0\n }\n\n hasPorts(): boolean {\n return !!this.ports?.in?.length || !!this.ports?.out?.length\n }\n\n layerIndex(g: Graph): number {\n return this.getLayer(g).index\n }\n\n getLayer(g: Graph): Layer {\n return g.getLayer(this.layerId)\n }\n\n margin(g: Graph): number {\n return this.isDummy ? g.options.edgeSpacing - g.options.dummyNodeSize : g.options.nodeMargin\n }\n\n marginWith(g: Graph, other: Node): number {\n return Math.max(this.margin(g), other.margin(g))\n }\n\n width(g: Graph): number {\n return this.dims?.[g.w] ?? 0\n }\n\n right(g: Graph): number {\n return this.lpos! + this.width(g)\n }\n\n setIndex(g: Graph, index: number): Node {\n if (this.index == index) return this\n return this.mut(g).set('index', index)\n }\n\n setLayerPos(g: Graph, lpos: number): Node {\n if (this.lpos == lpos) return this\n return this.mut(g).set('lpos', lpos)\n }\n\n setLayer(g: Graph, layerId: LayerId): Node {\n if (this.layerId == layerId) return this\n return this.mut(g).set('layerId', layerId)\n }\n\n setPos(g: Graph, pos: Pos): Node {\n if (!this.pos || this.pos.x != pos.x || this.pos.y != pos.y)\n return this.mut(g).set('pos', pos)\n return this\n }\n\n moveToLayer(g: Graph, layer: Layer): Node {\n this.getLayer(g).delNode(g, this.id)\n layer.addNode(g, this.id)\n return this.setLayer(g, layer.id)\n }\n\n moveToLayerIndex(g: Graph, index: number): Node {\n return this.moveToLayer(g, g.layerAt(index))\n }\n\n setAligned(g: Graph, dir: Dir, nodeId: NodeId | undefined): Node {\n if (this.aligned[dir] === nodeId) return this\n return this.mut(g).set('aligned', { ...this.aligned, [dir]: nodeId })\n }\n\n addRel(g: Graph, type: LinkType, dir: Dir, relId: EdgeId | SegId): Node {\n const sets = this.get(type)\n const set = sets[dir]\n if (set.has(relId)) return this\n return this.mut(g).set(type, { ...sets, [dir]: set.asMutable().add(relId) })\n }\n\n delRel(g: Graph, type: LinkType, dir: Dir, relId: EdgeId | SegId): Node | null {\n let sets = this.get(type)\n const set = sets[dir]\n if (!set.has(relId)) return this\n sets = { ...sets, [dir]: set.asMutable().remove(relId) }\n const node = this.mut(g).set(type, sets)\n if (node.isDummy && node.isUnlinked())\n return node.delSelf(g)\n return node\n }\n\n delSelf(g: Graph): null {\n // Clear alignment references from partner nodes\n if (this.aligned.in)\n g.getNode(this.aligned.in).setAligned(g, 'out', undefined)\n if (this.aligned.out)\n g.getNode(this.aligned.out).setAligned(g, 'in', undefined)\n this.getLayer(g).delNode(g, this.id)\n // Phase 1: delete edges first (which should also remove segs)\n for (const edge of this.rels(g, 'edges', 'both'))\n edge.delSelf(g)\n // Phase 2: clean up any remaining segs defensively (in case of iteration ordering)\n const remainingSegIds = [...this.segs.in, ...this.segs.out]\n if (remainingSegIds.length > 0) {\n for (const segId of remainingSegIds) {\n // Only delete if seg still exists on graph\n if ((g as any).segs?.has?.(segId)) {\n g.getSeg(segId).delSelf(g)\n } else {\n // seg already removed; nothing to do\n }\n }\n }\n g.nodes.delete(this.id)\n g.dirtyNodes.delete(this.id)\n g.delNodes.add(this.id)\n return null\n }\n\n addInEdge(g: Graph, edgeId: EdgeId): Node {\n return this.addRel(g, 'edges', 'in', edgeId)\n }\n\n addOutEdge(g: Graph, edgeId: EdgeId): Node {\n return this.addRel(g, 'edges', 'out', edgeId)\n }\n\n addInSeg(g: Graph, segId: SegId): Node {\n return this.addRel(g, 'segs', 'in', segId)\n }\n\n addOutSeg(g: Graph, segId: SegId): Node {\n return this.addRel(g, 'segs', 'out', segId)\n }\n\n delInEdge(g: Graph, edgeId: EdgeId): Node | null {\n return this.delRel(g, 'edges', 'in', edgeId)\n }\n\n delOutEdge(g: Graph, edgeId: EdgeId): Node | null {\n return this.delRel(g, 'edges', 'out', edgeId)\n }\n\n delInSeg(g: Graph, segId: SegId): Node | null {\n return this.delRel(g, 'segs', 'in', segId)\n }\n\n delOutSeg(g: Graph, segId: SegId): Node | null {\n return this.delRel(g, 'segs', 'out', segId)\n }\n\n *relIds(type: LinkType | 'both' = 'both', dir: Dir | 'both' = 'both'): Generator<EdgeId | SegId> {\n const types: LinkType[] = type == 'both' ? ['edges', 'segs'] : [type]\n const dirs: Dir[] = dir == 'both' ? ['in', 'out'] : [dir]\n for (const type of types)\n for (const dir of dirs)\n yield* this.get(type)[dir]\n }\n\n rels(g: Graph, type: 'edges', dir?: Dir | 'both'): Generator<Edge>\n rels(g: Graph, type: 'segs', dir?: Dir | 'both'): Generator<Seg>\n rels(g: Graph, type: 'both', dir?: Dir | 'both'): Generator<Edge | Seg>\n rels(g: Graph, type: LinkType | 'both', dir: Dir | 'both'): Generator<Edge | Seg>\n rels(g: Graph, type: LinkType | 'both'): Generator<Edge | Seg>\n rels(g: Graph): Generator<Edge | Seg>\n *rels(g: Graph, type: LinkType | 'both' = 'both', dir: Dir | 'both' = 'both'): Generator<Edge | Seg> {\n for (const relId of this.relIds(type, dir))\n yield g.getRel(relId)\n }\n\n *adjIds(g: Graph, type: LinkType | 'both' = 'both', dir: Dir | 'both' = 'both'): Generator<NodeId> {\n const dirs: Dir[] = dir == 'both' ? ['in', 'out'] : [dir]\n for (const dir of dirs) {\n const side: Side = dir == 'in' ? 'source' : 'target'\n for (const rel of this.rels(g, type, dir))\n yield rel[side].id\n }\n }\n\n *adjs(g: Graph, type: LinkType | 'both' = 'both', dir: Dir | 'both' = 'both'): Generator<Node> {\n for (const nodeId of this.adjIds(g, type, dir))\n yield g.getNode(nodeId)\n }\n\n *inEdgeIds(): Generator<EdgeId> {\n yield* this.relIds('edges', 'in')\n }\n\n *outEdgeIds(): Generator<EdgeId> {\n yield* this.relIds('edges', 'out')\n }\n\n *inSegIds(): Generator<SegId> {\n yield* this.relIds('segs', 'in')\n }\n\n *outSegIds(): Generator<SegId> {\n yield* this.relIds('segs', 'out')\n }\n\n *inEdges(g: Graph): Generator<Edge> {\n yield* this.rels(g, 'edges', 'in')\n }\n\n *outEdges(g: Graph): Generator<Edge> {\n yield* this.rels(g, 'edges', 'out')\n }\n\n *inSegs(g: Graph): Generator<Seg> {\n yield* this.rels(g, 'segs', 'in')\n }\n\n *outSegs(g: Graph): Generator<Seg> {\n yield* this.rels(g, 'segs', 'out')\n }\n\n *inNodeIds(g: Graph): Generator<NodeId> {\n yield* this.adjIds(g, 'edges', 'in')\n }\n\n *outNodeIds(g: Graph): Generator<NodeId> {\n yield* this.adjIds(g, 'edges', 'out')\n }\n\n *inNodes(g: Graph): Generator<Node> {\n yield* this.adjs(g, 'edges', 'in')\n }\n\n *outNodes(g: Graph): Generator<Node> {\n yield* this.adjs(g, 'edges', 'out')\n }\n}\n","import pino from 'pino'\n\ntype LogLevel = 'error' | 'warn' | 'info' | 'debug'\n\n// Resolve log level from environment or default to 'debug' (matches previous behavior)\nconst resolvedLevel: LogLevel =\n (typeof globalThis !== 'undefined' && (globalThis as any).__LOG_LEVEL) ||\n (typeof process !== 'undefined' && (process as any).env?.LOG_LEVEL) ||\n 'debug'\n\n// Configure browser options: emit objects, optionally transmit to collector\nconst browserOpts: any = { asObject: true }\nbrowserOpts.transmit = {\n level: resolvedLevel,\n send: (level: string, log: Record<string, unknown>) => {\n try {\n const endpoint: string | undefined =\n (typeof globalThis !== 'undefined' && (globalThis as any).__LOG_INGEST_URL) ||\n (typeof process !== 'undefined' && (process as any).env?.LOG_INGEST_URL) ||\n undefined\n if (!endpoint || typeof window === 'undefined') {\n // Dev aid: show why transmit may be inactive\n try { console.debug('[graph-core] transmit skipped', { endpoint, hasWindow: typeof window !== 'undefined', level }) } catch { }\n return\n }\n const line = JSON.stringify({ level, ...log, ts: Date.now() }) + '\\n'\n try { console.debug('[graph-core] transmit sending', { endpoint, level, bytes: line.length }) } catch { }\n // Always use fetch with no-cors and omit credentials to avoid preflight and credentialed requests\n fetch(endpoint, {\n method: 'POST',\n mode: 'no-cors',\n credentials: 'omit',\n body: line,\n keepalive: true,\n })\n .then(() => { try { console.debug('[graph-core] transmit fetch ok') } catch { } })\n .catch((err) => { try { console.debug('[graph-core] transmit fetch error', err?.message || err) } catch { } })\n } catch (e) {\n try { console.debug('[graph-core] transmit error', (e as any)?.message || e) } catch { }\n }\n },\n}\n\n// Create a singleton pino base logger\nconst base = pino({\n level: resolvedLevel,\n browser: browserOpts,\n})\n\nexport function logger(module: string) {\n const child = base.child({ module })\n return {\n error: (msg: string, ...args: any[]) => child.error({ args }, msg),\n warn: (msg: string, ...args: any[]) => child.warn({ args }, msg),\n info: (msg: string, ...args: any[]) => child.info({ args }, msg),\n debug: (msg: string, ...args: any[]) => child.debug({ args }, msg),\n }\n}\n\nexport const log = logger('core')\n","import { Record } from 'immutable'\nimport { NodeId, Node } from \"./node\"\nimport { Graph } from \"./graph\"\nimport { Side } from \"../common\"\nimport { SegId, Seg } from \"./seg\"\nimport { EdgeStyle } from \"../api/options\"\nimport { logger } from \"../log\"\nimport { MarkerType } from \"../canvas/marker\"\n\nconst log = logger('edge')\n\nexport type EdgeId = string\n\nexport type PublicEdgeData = {\n id: string\n data: any\n label?: string\n source: { id: string, port?: string, marker?: MarkerType }\n target: { id: string, port?: string, marker?: MarkerType }\n type?: string\n}\n\ntype EdgeData = PublicEdgeData & {\n segIds: SegId[]\n mutable: boolean\n}\n\nconst defEdgeData: EdgeData = {\n id: '',\n data: null,\n label: undefined,\n source: { id: '' },\n target: { id: '' },\n type: undefined,\n mutable: false,\n segIds: [],\n}\n\nexport class Edge extends Record(defEdgeData) {\n static prefix = 'e:'\n\n mut(g: Graph): Edge {\n if (this.mutable) return this\n return g.mutateEdge(this)\n }\n\n final(): Edge {\n if (!this.mutable) return this\n return this.merge({\n mutable: false\n }).asImmutable()\n }\n\n link(g: Graph): Edge {\n this.sourceNode(g).addOutEdge(g, this.id)\n this.targetNode(g).addInEdge(g, this.id)\n return this\n }\n\n unlink(g: Graph): Edge {\n this.sourceNode(g).delOutEdge(g, this.id)\n this.targetNode(g).delInEdge(g, this.id)\n return this\n }\n\n delSelf(g: Graph): null {\n for (const seg of this.segs(g))\n seg.delEdgeId(g, this.id)\n this.unlink(g)\n g.edges.delete(this.id)\n g.dirtyEdges.delete(this.id)\n g.delEdges.add(this.id)\n return null\n }\n\n delSegId(g: Graph, segId: SegId): Edge {\n return this.setSegIds(g, this.segIds.filter(id => id != segId))\n }\n\n replaceSegId(g: Graph, oldId: SegId, newId: SegId): Edge {\n return this.setSegIds(g, this.segIds.map(id => id == oldId ? newId : id))\n }\n\n setSegIds(g: Graph, segIds: SegId[]): Edge {\n if (segIds.join(',') == this.segIds.join(',')) return this\n return this.mut(g).set('segIds', segIds)\n }\n\n *segs(g: Graph): Generator<Seg> {\n for (const segId of this.segIds)\n yield g.getSeg(segId)\n }\n\n node(g: Graph, side: Side): Node {\n return g.getNode(this[side].id)\n }\n\n sourceNode(g: Graph): Node {\n return this.node(g, 'source')\n }\n\n targetNode(g: Graph): Node {\n return this.node(g, 'target')\n }\n\n get str(): string {\n return Edge.str(this)\n }\n\n static str(edge: Partial<EdgeData>): string {\n let source = edge.source?.id\n if (!source) throw new Error('edge source is undefined')\n if (edge.source?.port)\n source = `${source} (port ${edge.source.port})`\n let target = edge.target?.id\n if (!target) throw new Error('edge target is undefined')\n if (edge.target?.port)\n target = `${target} (port ${edge.target.port})`\n let str = `edge from ${source} to ${target}`\n if (edge.type) str += ` of type ${edge.type}`\n return str\n }\n\n static key(edge: Partial<EdgeData>, prefix: string = Edge.prefix, side: Side | 'both' = 'both'): string {\n let source = '', target = ''\n if (side == 'source' || side == 'both') {\n if (!edge.source?.id) throw new Error('edge source is undefined')\n source = edge.source.id\n if (edge.source?.port)\n source = `${source}.${edge.source.port}`\n const marker = edge.source?.marker\n if (marker && marker != 'none') source += `[${marker}]`\n source += '-'\n }\n if (side == 'target' || side == 'both') {\n if (!edge.target?.id) throw new Error('edge target is undefined')\n target = edge.target.id\n if (edge.target.port)\n target = `${target}.${edge.target.port}`\n target = '-' + target\n const marker = edge.target?.marker ?? 'arrow'\n if (marker && marker != 'none') target += `[${marker}]`\n }\n const type = edge.type || ''\n return `${prefix}${source}${type}${target}`\n }\n\n static add(g: Graph, data: Partial<EdgeData>): Edge {\n const edge = new Edge({\n ...data,\n segIds: [],\n })\n edge.link(g)\n g.edges.set(edge.id, edge)\n g.dirtyEdges.add(edge.id)\n return edge\n }\n\n static del(g: Graph, data: { id: string }): null {\n return g.getEdge(data.id).delSelf(g)\n }\n\n static update(g: Graph, data: PublicEdgeData): Edge {\n let edge = g.getEdge(data.id)\n let relink = false\n if (\n data.source.id !== edge.source.id ||\n data.target.id !== edge.target.id ||\n data.source.port !== edge.source.port ||\n data.target.port !== edge.target.port ||\n data.type !== edge.type\n ) {\n for (const seg of edge.segs(g))\n seg.delEdgeId(g, edge.id)\n edge.unlink(g)\n relink = true\n }\n edge = edge.mut(g).merge(data)\n if (relink)\n edge.link(g)\n return edge\n }\n}","import { Record, Set as ISet } from 'immutable'\nimport { Node, NodeId, PortId } from './node'\nimport { EdgeId, Edge } from './edge'\nimport { Graph } from './graph'\nimport { Side } from '../common'\nimport { EdgeStyle } from '../api/options'\nimport { MarkerType } from '../canvas/marker'\n\nexport type SegId = string\n\ntype SegEnd = {\n id: NodeId\n port?: PortId\n pos?: number\n marker?: MarkerType\n}\n\ntype SegData = {\n id: string\n source: SegEnd\n target: SegEnd\n type?: string\n edgeIds: ISet<EdgeId>\n trackPos?: number\n svg?: string\n mutable: boolean\n}\n\nconst defSegData: SegData = {\n id: '',\n source: { id: '' },\n target: { id: '' },\n type: undefined,\n edgeIds: ISet(),\n trackPos: undefined,\n svg: undefined,\n mutable: false,\n}\n\nexport class Seg extends Record(defSegData) {\n static prefix = 's:'\n\n mut(g: Graph): Seg {\n if (this.mutable) return this\n return g.mutateSeg(this)\n }\n\n final(): Seg {\n if (!this.mutable) return this\n return this.merge({\n edgeIds: this.edgeIds.asImmutable(),\n mutable: false,\n }).asImmutable()\n }\n\n get p1(): number {\n return this.source.pos!\n }\n\n get p2(): number {\n return this.target.pos!\n }\n\n anySameEnd(other: Seg): boolean {\n return this.sameEnd(other, 'source') || this.sameEnd(other, 'target')\n }\n\n sameEnd(other: Seg, side: Side): boolean {\n const mine = this[side]\n const yours = other[side]\n return true &&\n mine.id === yours.id &&\n mine.port === yours.port &&\n mine.marker === yours.marker &&\n this.type === other.type\n }\n\n setPos(g: Graph, source: number, target: number): Seg {\n return this.mut(g).merge({\n source: { ...this.source, pos: source },\n target: { ...this.target, pos: target },\n })\n }\n\n setTrackPos(g: Graph, trackPos?: number): Seg {\n if (this.trackPos == trackPos) return this\n return this.mut(g).set('trackPos', trackPos)\n }\n\n setSVG(g: Graph, svg: string): Seg {\n if (this.svg == svg) return this\n return this.mut(g).set('svg', svg)\n }\n\n link(g: Graph): Seg {\n this.sourceNode(g).addOutSeg(g, this.id)\n this.targetNode(g).addInSeg(g, this.id)\n return this\n }\n\n unlink(g: Graph): Seg {\n this.sourceNode(g).delOutSeg(g, this.id)\n this.targetNode(g).delInSeg(g, this.id)\n return this\n }\n\n delSelf(g: Graph): null {\n this.unlink(g)\n g.segs.delete(this.id)\n g.dirtySegs.delete(this.id)\n g.delSegs.add(this.id)\n return null\n }\n\n *edges(g: Graph): Generator<Edge> {\n for (const edgeId of this.edgeIds)\n yield g.getEdge(edgeId)\n }\n\n node(g: Graph, side: Side): Node {\n return g.getNode(this[side].id)\n }\n\n sourceNode(g: Graph): Node {\n return this.node(g, 'source')\n }\n\n targetNode(g: Graph): Node {\n return this.node(g, 'target')\n }\n\n addEdgeId(g: Graph, edgeId: EdgeId): Seg {\n if (this.edgeIds.has(edgeId)) return this\n return this.mut(g).set('edgeIds', this.edgeIds.asMutable().add(edgeId))\n }\n\n delEdgeId(g: Graph, edgeId: EdgeId): Seg | null {\n if (!this.edgeIds.has(edgeId)) return this\n if (this.edgeIds.size == 1) {\n this.delSelf(g)\n return null\n }\n return this.mut(g).set('edgeIds', this.edgeIds.asMutable().remove(edgeId))\n }\n\n static add(g: Graph, data: Partial<SegData>): Seg {\n const seg = new Seg({\n ...data,\n id: Edge.key(data, Seg.prefix),\n })\n seg.link(g)\n g.segs.set(seg.id, seg)\n g.dirtySegs.add(seg.id)\n return seg\n }\n}","import { Record, Set as ISet } from 'immutable'\nimport { Node, NodeId } from './node'\nimport { Graph } from './graph'\nimport { SegId } from './seg'\nimport { Edge } from './edge'\nimport { logger } from '../log'\n\nconst log = logger('layer')\n\nexport type LayerId = string\n\nexport type LayerData = {\n id: LayerId\n index: number\n nodeIds: ISet<NodeId>\n sorted: NodeId[]\n tracks: SegId[][]\n size: number\n pos: number\n isSorted: boolean\n mutable: boolean\n}\n\nconst defLayerData: LayerData = {\n id: '',\n index: 0,\n nodeIds: ISet(),\n sorted: [],\n tracks: [],\n size: 0,\n pos: 0,\n isSorted: false,\n mutable: false,\n}\n\nexport class Layer extends Record(defLayerData) {\n static prefix = 'l:'\n\n mut(g: Graph): Layer {\n if (this.mutable) return this\n return g.mutateLayer(this)\n }\n\n final(): Layer {\n if (!this.mutable) return this\n return this.merge({\n nodeIds: this.nodeIds.asImmutable(),\n mutable: false,\n }).asImmutable()\n }\n\n get nodeCount(): number {\n return this.nodeIds.size\n }\n\n *nodes(g: Graph): Generator<Node> {\n for (const nodeId of this.nodeIds.values())\n yield g.getNode(nodeId)\n }\n\n hasSortOrder(order: NodeId[]): boolean {\n return order.length == this.sorted.length &&\n this.sorted.every((nodeId, i) => order[i] == nodeId)\n }\n\n canCrush(g: Graph): boolean {\n for (const node of this.nodes(g))\n if (!node.isDummy)\n return false\n return true\n }\n\n crush(g: Graph): null {\n g.layerList.remove(this.index)\n g.layers.delete(this.id)\n g.dirtyLayers.delete(this.id)\n for (let i = this.index; i < g.layerList.size; i++)\n g.getLayer(g.layerList.get(i)!).setIndex(g, i)\n for (const node of this.nodes(g))\n if (node.isDummy) node.delSelf(g)\n return null\n }\n\n setIndex(g: Graph, index: number): Layer {\n if (this.index == index) return this\n return this.mut(g).set('index', index)\n }\n\n setTracks(g: Graph, tracks: SegId[][]): Layer {\n if (this.tracks == tracks) return this\n return this.mut(g).set('tracks', tracks)\n }\n\n setSize(g: Graph, size: number): Layer {\n if (this.size == size) return this\n return this.mut(g).set('size', size)\n }\n\n setPos(g: Graph, pos: number): Layer {\n if (this.pos == pos) return this\n return this.mut(g).set('pos', pos)\n }\n\n addNode(g: Graph, nodeId: NodeId): Layer {\n if (this.nodeIds.has(nodeId)) return this\n return this.mut(g).set('nodeIds', this.nodeIds.asMutable().add(nodeId))\n }\n\n willCrush(g: Graph, nodeId: NodeId): boolean {\n for (const node of this.nodes(g))\n if (!node.isDummy && node.id != nodeId)\n return false\n return true\n }\n\n reindex(g: Graph, nodeId: NodeId): NodeId[] | undefined {\n if (!this.isSorted) return undefined\n const sorted = this.sorted.filter(id => id != nodeId)\n for (const [i, id] of this.sorted.entries())\n g.getNode(id).setIndex(g, i)\n return sorted\n }\n\n delNode(g: Graph, nodeId: NodeId): Layer | null {\n if (!this.nodeIds.has(nodeId)) return this\n if (this.willCrush(g, nodeId)) return this.crush(g)\n const nodeIds = this.nodeIds.asMutable().remove(nodeId)\n const sorted = this.reindex(g, nodeId)\n return this.mut(g).merge({ nodeIds, sorted })\n }\n\n setSorted(g: Graph, nodeIds: NodeId[]): Layer {\n if (this.hasSortOrder(nodeIds)) return this\n nodeIds.forEach((nodeId, i) => g.getNode(nodeId).setIndex(g, i))\n return this.mut(g).merge({ sorted: nodeIds, isSorted: true })\n }\n\n *outEdges(g: Graph): Generator<Edge> {\n for (const node of this.nodes(g))\n yield* node.outEdges(g)\n }\n}\n","import { PublicNodeData } from './node'\nimport { PublicEdgeData } from './edge'\nimport { Changes } from './graph'\n\nexport class Mutator {\n changes: Changes\n\n constructor() {\n this.changes = {\n addedNodes: [],\n removedNodes: [],\n updatedNodes: [],\n addedEdges: [],\n removedEdges: [],\n updatedEdges: [],\n }\n }\n\n describe(description: string) {\n this.changes.description = description\n }\n\n addNode(node: PublicNodeData) {\n this.changes.addedNodes.push(node)\n }\n\n addNodes(...nodes: PublicNodeData[]) {\n nodes.forEach(node => this.addNode(node))\n }\n\n removeNode(node: { id: string }) {\n this.changes.removedNodes.push(node)\n }\n\n removeNodes(...nodes: { id: string }[]) {\n nodes.forEach(node => this.removeNode(node))\n }\n\n updateNode(node: PublicNodeData) {\n this.changes.updatedNodes.push(node)\n }\n\n updateNodes(...nodes: PublicNodeData[]) {\n nodes.forEach(node => this.updateNode(node))\n }\n\n addEdge(edge: PublicEdgeData) {\n this.changes.addedEdges.push(edge)\n }\n\n addEdges(...edges: PublicEdgeData[]) {\n edges.forEach(edge => this.addEdge(edge))\n }\n\n removeEdge(edge: PublicEdgeData) {\n this.changes.removedEdges.push(edge)\n }\n\n removeEdges(...edges: PublicEdgeData[]) {\n edges.forEach(edge => this.removeEdge(edge))\n }\n\n updateEdge(edge: PublicEdgeData) {\n this.changes.updatedEdges.push(edge)\n }\n\n updateEdges(...edges: PublicEdgeData[]) {\n edges.forEach(edge => this.updateEdge(edge))\n }\n}","import { Graph } from '../graph'\nimport { Node } from '../node'\n\nexport class Cycles {\n static info(g: Graph, node: Node) {\n return node.id\n }\n\n static checkCycles(g: Graph) {\n const totalNodes = g.nodes.size\n const newStuff = g.changes.addedNodes.length + g.changes.addedEdges.length\n const changeRatio = newStuff / totalNodes\n if (changeRatio > 0.2 || totalNodes < 20)\n Cycles.checkCyclesFull(g)\n else\n Cycles.checkCyclesIncremental(g)\n }\n\n private static checkCyclesFull(g: Graph) {\n const colorMap: Map<Node, number> = new Map()\n const parentMap: Map<Node, Node> = new Map()\n let start: Node | undefined, end: Node | undefined\n const white = 0, gray = 1, black = 2\n\n const visit = (node: Node) => {\n colorMap.set(node, gray)\n for (const next of node.outNodes(g)) {\n switch (colorMap.get(next) ?? white) {\n case gray:\n start = next\n end = node\n return true\n case white:\n parentMap.set(next, node)\n if (visit(next)) return true\n }\n }\n colorMap.set(node, black)\n return false\n }\n\n for (const node of g.getNodes())\n if ((colorMap.get(node) ?? white) == white)\n if (visit(node)) break\n\n if (!start || !end) return\n\n const cycle = [start]\n let node = end\n while (node != start) {\n cycle.push(node)\n node = parentMap.get(node)!\n }\n\n Cycles.throwCycle(g, cycle)\n }\n\n private static checkCyclesIncremental(g: Graph) {\n for (const edge of g.changes.addedEdges) {\n const source = g.getNode(edge.source.id)\n const target = g.getNode(edge.target.id)\n const layer1 = source.layerIndex(g)\n const layer2 = target.layerIndex(g)\n if (layer1 < layer2) continue\n const route = Cycles.findRoute(g, target, source)\n if (!route) continue\n Cycles.throwCycle(g, route)\n }\n }\n\n private static throwCycle(g: Graph, cycle: Node[]) {\n cycle.push(cycle[0])\n cycle.reverse()\n const info = cycle.map(node => Cycles.info(g, node))\n throw new Error(`Cycle detected: ${info.join(' → ')}`)\n }\n\n private static findRoute(g: Graph, source: Node, target: Node): Node[] | null {\n const parentMap: Map<Node, Node> = new Map()\n const queue = [source]\n const visited = new Set([source])\n\n while (queue.length > 0) {\n const node = queue.shift()!\n if (node == target) {\n const route = []\n let currNode = target\n while (currNode != source) {\n route.push(currNode)\n currNode = parentMap.get(currNode)!\n }\n route.push(source)\n route.reverse()\n return route\n }\n\n for (const next of node.outNodes(g)) {\n if (!visited.has(next)) {\n visited.add(next)\n parentMap.set(next, node)\n queue.push(next)\n }\n }\n }\n\n return null\n }\n}","import { Set as ISet } from 'immutable'\nimport { Node } from '../node'\nimport { Edge } from '../edge'\nimport { logger } from '../../log'\nimport { Seg } from '../seg'\nimport { Graph } from '../graph'\nimport { Side } from '../../common'\n\nconst log = logger('dummy')\n\nexport class Dummy {\n static updateDummies(g: Graph) {\n // check all dirty edges to see if they need segments added or removed\n for (const edgeId of g.dirtyEdges) {\n const edge = g.getEdge(edgeId)\n const { type } = edge\n const sourceLayer = edge.sourceNode(g).layerIndex(g)\n const targetLayer = edge.targetNode(g).layerIndex(g)\n let segIndex = 0\n let changed = false\n let source = edge.source\n // adjust edge segments\n const segs = edge.segIds\n // loop over layers between source and target\n for (let layerIndex = sourceLayer + 1; layerIndex <= targetLayer; layerIndex++) {\n const layer = g.layerAt(layerIndex)\n // update segments until the current layer is reached\n while (true) {\n const segId = segs[segIndex]\n let seg = segId ? g.getSeg(segId) : null\n const segLayer = seg ? seg.targetNode(g).layerIndex(g) : null\n if (segIndex == segs.length || segLayer! > layerIndex) {\n // either a gap existed, or we reached the end; either way, add a new segment\n let target: Edge['target']\n if (layerIndex == targetLayer) {\n target = edge.target\n } else {\n const dummy = Node.addDummy(g, {\n edgeIds: [edgeId],\n layerId: layer.id,\n })\n target = { id: dummy.id }\n }\n seg = Seg.add(g, { source, target, type, edgeIds: ISet([edgeId]) })\n segs.splice(segIndex, 0, seg.id)\n changed = true\n } else if (\n segLayer! < layerIndex ||\n seg!.source.id != source.id ||\n seg!.source.port != source.port ||\n layerIndex == targetLayer && (\n seg!.target.id != edge.target.id ||\n seg!.target.port != edge.target.port\n )\n ) {\n seg = seg!.delEdgeId(g, edgeId)\n segs.splice(segIndex, 1)\n changed = true\n continue\n }\n // advance to next segment, keep track of source id chain\n source = seg!.target\n segIndex++\n break\n }\n }\n // remove any remaining segments\n while (segIndex < segs.length) {\n g.getSeg(segs[segIndex]).delEdgeId(g, edgeId)\n segs.splice(segIndex, 1)\n changed = true\n segIndex++\n }\n // update edge with new segments if a change occurred\n if (changed) {\n edge.setSegIds(g, segs)\n /* debug removed */\n }\n }\n }\n\n static mergeDummies(g: Graph) {\n for (const side of g.options.mergeOrder)\n Dummy.mergeScan(g, side)\n }\n\n static mergeScan(g: Graph, side: Side) {\n // find dirty layers\n let layerIds = [...g.layerList]\n .filter(layerId => g.dirtyLayers.has(layerId))\n if (side == 'target') layerIds.reverse()\n const dir = side == 'source' ? 'in' : 'out'\n const altSide = side == 'source' ? 'target' : 'source'\n const altDir = altSide == 'source' ? 'in' : 'out'\n for (const layerId of layerIds) {\n // for each layer, we'll find merge-able dummy nodes\n let layer = g.getLayer(layerId)\n const groups: Map<string, Set<Node>> = new Map()\n // group layer dummies by edge-based keys\n for (const nodeId of layer.nodeIds) {\n const node = g.getNode(nodeId)\n if (!node.isDummy || node.isMerged) continue\n const edge = g.getEdge(node.edgeIds[0])\n const key = Edge.key(edge, 'k:', side)\n if (!groups.has(key)) groups.set(key, new Set())\n groups.get(key)!.add(node)\n }\n // for each group, we'll merge the dummies\n for (const [key, group] of groups) {\n if (group.size == 1) continue\n const edgeIds = [...group].map(node => node.edgeIds[0])\n const dummy = Node.addDummy(g, { edgeIds, layerId, isMerged: true })\n let seg: Seg | undefined\n // all 'in' segs are merged into a single new in seg\n for (const old of group) {\n let edge = g.getEdge(old.edgeIds[0])\n for (const segId of old.relIds('segs', dir)) {\n if (!seg) {\n const example = g.getSeg(segId)\n seg = Seg.add(g, {\n ...example,\n edgeIds: ISet(edgeIds),\n [side]: { ...example[side] },\n [altSide]: { ...example[altSide], id: dummy.id, port: undefined },\n })\n }\n edge = edge.replaceSegId(g, segId, seg.id)\n }\n }\n // all 'out' segs are replaced with individual new out segs\n for (const old of group) {\n let edge = g.getEdge(old.edgeIds[0])\n for (const segId of old.relIds('segs', altDir)) {\n const example = g.getSeg(segId)\n const seg = Seg.add(g, {\n ...example,\n edgeIds: ISet([old.edgeIds[0]]),\n [altSide]: { ...example[altSide] },\n [side]: { ...example[side], id: dummy.id, port: undefined },\n })\n edge = edge.replaceSegId(g, segId, seg.id)\n }\n }\n // remove old dummies\n for (const old of group)\n old.delSelf(g)\n }\n }\n }\n}\n","import { Set as ISet, Seq } from 'immutable'\nimport { Graph } from '../graph'\nimport { Node, NodeId } from '../node'\nimport { logger } from '../../log'\nimport { LayerId } from '../layer'\n\nconst log = logger('layers')\n\nexport class Layers {\n static updateLayers(g: Graph) {\n // phase 1: DFS to fix child layers based on parents\n // visit at least each dirty node\n const stack: NodeId[] = [...g.dirtyNodes]\n .map(id => g.getNode(id))\n .filter(node => !node.isDummy)\n .sort((a, b) => b.layerIndex(g) - a.layerIndex(g))\n .map(node => node.id)\n const phase2 = new Set(stack)\n const moved: Set<NodeId> = new Set()\n while (stack.length > 0) {\n let node = g.getNode(stack.pop()!)\n const curLayer = node.layerIndex(g)\n let correctLayer = 0\n const parents = node.inNodes(g)\n for (const parent of parents) {\n const pidx = parent.layerIndex(g)\n if (pidx >= correctLayer) correctLayer = pidx + 1\n }\n // if needs a move, move it and push children to stack\n // also add parents to phase 2\n if (curLayer != correctLayer) {\n node = node.moveToLayerIndex(g, correctLayer)\n stack.push(...node.outNodeIds(g))\n moved.add(node.id)\n for (const parent of parents)\n phase2.add(parent.id)\n }\n }\n // phase 2: reverse topo order to fix parents based on children\n const byLayer: Map<LayerId, Set<NodeId>> = new Map()\n // start by grouping by layer\n const addParent = (nodeId: NodeId) => {\n let set: Set<NodeId>\n const layerId = g.getNode(nodeId).layerId\n if (!byLayer.has(layerId)) {\n set = new Set()\n byLayer.set(layerId, set)\n } else {\n set = byLayer.get(layerId)!\n }\n set.add(nodeId)\n }\n for (const id of phase2) addParent(id)\n // take layers in reverse topo order\n const layerIds = [...byLayer.keys()].sort(\n (a, b) => g.getLayer(b).index - g.getLayer(a).index)\n for (const layerId of layerIds) {\n const curLayer = g.getLayer(layerId).index\n // visit each parent of this layer\n for (const parentId of byLayer.get(layerId)!) {\n let parent = g.getNode(parentId)\n const children = [...parent.outNodes(g)]\n if (children.length == 0) continue\n // should be just above min child\n const minChild = Seq(children).map(node => node.layerIndex(g)).min()!\n const correctLayer = minChild - 1\n // if needs a move, move it and push parents to stack\n if (curLayer != correctLayer) {\n moved.add(parentId)\n parent = parent.moveToLayerIndex(g, correctLayer)\n for (const gpId of parent.inNodeIds(g))\n addParent(gpId)\n }\n }\n }\n // mark edges as dirty\n for (const id of moved)\n for (const edgeId of g.getNode(id).relIds('edges'))\n g.dirtyEdges.add(edgeId)\n }\n}","import { logger } from '../../log'\nimport { Seq } from 'immutable'\nimport { Node, NodeId, PortId } from '../node'\nimport { Graph } from '../graph'\nimport { Dir, Side, Pos } from '../../common'\nimport { LayerId } from '../layer'\nimport { Seg } from '../seg'\nimport { MarkerType } from '../../canvas/marker'\n\nconst log = logger('layout')\n\nexport type LayoutStep = 'alignChildren' | 'alignParents' | 'compact'\n\nexport class Layout {\n static parentIndex(g: Graph, node: Node): number {\n const parents = Seq([...node.adjs(g, 'segs', 'in')])\n const pidx = parents.map(p => p.index).min()\n if (pidx !== undefined) return pidx\n return node.isDummy ? -Infinity : Infinity\n }\n\n static compareNodes(g: Graph, aId: NodeId, bId: NodeId, pidxs: Map<NodeId, number>): number {\n const ai = pidxs.get(aId)!\n const bi = pidxs.get(bId)!\n if (ai !== bi) return ai - bi\n const a = g.getNode(aId)\n const b = g.getNode(bId)\n if (a.isDummy && !b.isDummy) return -1\n if (!a.isDummy && b.isDummy) return 1\n if (!a.isDummy) return a.id.localeCompare(b.id)\n const minA = Seq(a.edgeIds).min()!\n const minB = Seq(b.edgeIds).min()!\n return minA.localeCompare(minB)\n }\n\n static positionNodes(g: Graph) {\n for (const nodeId of g.dirtyNodes)\n g.dirtyLayers.add(g.getNode(nodeId).layerId)\n let adjustNext = false\n for (const layerId of g.layerList) {\n if (!adjustNext && !g.dirtyLayers.has(layerId)) continue\n adjustNext = false\n let layer = g.getLayer(layerId)\n const pidxs: Map<NodeId, number> = new Map()\n for (const nodeId of layer.nodeIds)\n pidxs.set(nodeId, Layout.parentIndex(g, g.getNode(nodeId)))\n const sorted = [...layer.nodeIds].sort(\n (aId, bId) => Layout.compareNodes(g, aId, bId, pidxs))\n if (layer.hasSortOrder(sorted)) continue\n g.dirtyLayers.add(layerId)\n layer = layer.setSorted(g, sorted)\n adjustNext = true\n let lpos = 0\n for (let i = 0; i < sorted.length; i++) {\n let node = g.getNode(sorted[i])\n node = node.setIndex(g, i).setLayerPos(g, lpos)\n const size = node.dims?.[g.w] ?? 0\n let margin = node.margin(g)\n if (i + 1 < sorted.length) {\n const next = g.getNode(sorted[i + 1])\n margin = node.marginWith(g, next)\n }\n lpos += size + margin\n }\n }\n }\n\n static alignAll(g: Graph) {\n if (g.options.layoutSteps) {\n for (const step of g.options.layoutSteps)\n Layout[step](g)\n } else {\n for (let i = 0; i < g.options.alignIterations; i++) {\n let anyChanged =\n Layout.alignChildren(g) ||\n Layout.alignParents(g) ||\n Layout.compact(g)\n if (!anyChanged) break\n }\n }\n }\n\n static alignChildren(g: Graph) {\n return Layout.alignNodes(g, false, false, false, 'in', false)\n }\n\n static alignParents(g: Graph) {\n return Layout.alignNodes(g, true, true, false, 'out', true)\n }\n\n static alignNodes(\n g: Graph,\n reverseLayers: boolean,\n reverseNodes: boolean,\n reverseMove: boolean,\n dir: Dir,\n conservative: boolean\n ) {\n let layerIds = [...g.layerList]\n let anyChanged = false\n if (reverseLayers) layerIds.reverse()\n let adjustNext = false\n for (const layerId of layerIds) {\n if (!adjustNext && !g.dirtyLayers.has(layerId)) continue\n adjustNext = false\n let iterations = 0\n while (true) {\n if (++iterations > 10) {\n log.error(`alignNodes: infinite loop detected in layer ${layerId}`)\n break\n }\n let changed = false\n const nodeIds = Layout.sortLayer(g, layerId, reverseNodes)\n for (const nodeId of nodeIds) {\n const {\n isAligned,\n pos: newPos,\n nodeId: otherId\n } = Layout.nearestNode(g, nodeId, dir, reverseMove, !reverseMove)\n if (isAligned || (newPos === undefined)) continue\n if (Layout.shiftNode(g, nodeId, otherId, dir, newPos, reverseMove, conservative)) {\n changed = true\n anyChanged = true\n break\n }\n }\n if (!changed) break\n g.dirtyLayers.add(layerId)\n adjustNext = true\n }\n }\n return anyChanged\n }\n\n static sortLayer(g: Graph, layerId: LayerId, reverseNodes: boolean) {\n const layer = g.getLayer(layerId)\n const sorted = [...layer.nodeIds]\n sorted.sort((a, b) => g.getNode(a).lpos! - g.getNode(b).lpos!)\n layer.setSorted(g, sorted)\n if (reverseNodes)\n return sorted.toReversed()\n return sorted\n }\n\n static nearestNode(g: Graph, nodeId: NodeId, dir: Dir, allowLeft: boolean, allowRight: boolean) {\n const node = g.getNode(nodeId)\n let minDist = Infinity\n let bestPos, bestNodeId\n const mySide = dir == 'in' ? 'target' : 'source'\n const altSide = dir == 'in' ? 'source' : 'target'\n for (const seg of node.rels(g, 'segs', dir)) {\n const altId = seg[altSide].id\n const myPos = Layout.anchorPos(g, seg, mySide)[g.x]\n const altPos = Layout.anchorPos(g, seg, altSide)[g.x]\n const diff = altPos - myPos\n if (diff == 0) return { nodeId: altId, isAligned: true }\n if ((diff < 0) && !allowLeft) continue\n if ((diff > 0) && !allowRight) continue\n const dist = Math.abs(diff)\n if (dist < minDist) {\n minDist = dist\n bestNodeId = altId\n bestPos = node.lpos! + diff\n }\n }\n return { nodeId: bestNodeId, pos: bestPos, isAligned: false }\n }\n\n static anchorPos(g: Graph, seg: Seg, side: Side): Pos {\n const nodeId = seg[side].id\n const node = g.getNode(nodeId)\n let p = { [g.x]: node.lpos!, [g.y]: node.pos?.[g.y] ?? 0 } as Pos\n let w = node.dims?.[g.w] ?? 0\n let h = node.dims?.[g.h] ?? 0\n\n if (node.isDummy)\n return {\n [g.x]: p[g.x] + w / 2,\n [g.y]: p[g.y] + h / 2,\n } as Pos\n\n p[g.x] += Layout.nodePortOffset(g, nodeId, seg, side)\n if ((side == 'target') == g.r)\n p[g.y] += h\n\n return p\n }\n\n static nodePortOffset(g: Graph, nodeId: NodeId, seg: Seg, side: Side) {\n const node = g.getNode(nodeId)\n const dir = side == 'source' ? 'out' : 'in'\n const portId = seg[side].port\n let min = 0, size = node.dims?.[g.w] ?? 0\n\n if (portId) {\n const ports = node.ports?.[dir]\n const port = ports?.find(p => p.id === portId)\n if (port?.offset !== undefined) {\n min = port.offset\n size = port.size ?? 0\n }\n }\n\n const alt = side == 'source' ? 'target' : 'source'\n let segs = []\n const keyOf = (seg: Seg) => `${seg.type ?? ''}:${seg[side].marker ?? ''}`\n for (const segId of node.segs[dir])\n segs.push(g.getSeg(segId))\n if (portId) segs = segs.filter(s => s[side].port == portId)\n const groups = Object.groupBy(segs, s => keyOf(s))\n const posMap = new Map()\n for (const [key, segs] of Object.entries(groups)) {\n let pos = Infinity\n for (const seg of segs!) pos = Math.min(pos, seg.node(g, alt).lpos!)\n posMap.set(key, pos)\n }\n const keys = [...posMap.keys()].sort((a, b) => posMap.get(a)! - posMap.get(b)!)\n const gap = size / (keys.length + 1)\n const index = keys.indexOf(keyOf(seg))\n return min + (index + 1) * gap\n }\n\n static shiftNode(\n g: Graph,\n nodeId: NodeId,\n alignId: NodeId | undefined,\n dir: Dir,\n lpos: number,\n reverseMove: boolean,\n conservative: boolean\n ) {\n const node = g.getNode(nodeId)\n if (!conservative)\n Layout.markAligned(g, nodeId, alignId, dir, lpos)\n const nodeRight = lpos + node.width(g)\n repeat:\n for (const otherId of node.getLayer(g).nodeIds) {\n if (otherId == nodeId) continue\n const other = g.getNode(otherId)\n const margin = node.marginWith(g, other)\n // Calculate gap using proposed lpos, not current node.lpos\n const gap = (lpos < other.lpos!)\n ? other.lpos! - nodeRight\n : lpos - other.right(g)\n if (gap < margin) {\n if (conservative) return false\n const safePos = reverseMove ? lpos - other.width(g) - margin : nodeRight + margin\n Layout.shiftNode(g, otherId, undefined, dir, safePos, reverseMove, conservative)\n continue repeat\n }\n }\n if (conservative)\n Layout.markAligned(g, nodeId, alignId, dir, lpos)\n return true\n }\n\n static markAligned(g: Graph, nodeId: NodeId, otherId: NodeId | undefined, dir: Dir, lpos: number) {\n const node = g.getNode(nodeId)\n const alt = dir == 'in' ? 'out' : 'in'\n if (node.aligned[dir])\n g.getNode(node.aligned[dir]).setAligned(g, alt, undefined)\n if (otherId)\n g.getNode(otherId).setAligned(g, alt, nodeId)\n node.setAligned(g, dir, otherId).setLayerPos(g, lpos)\n }\n\n static *aligned(g: Graph, nodeId: NodeId, dir: Dir | 'both') {\n const visit = function* (node: Node, dir: Dir): Generator<Node> {\n const otherId = node.aligned[dir]\n if (!otherId) return\n const other = g.getNode(otherId)\n yield other\n yield* visit(other, dir)\n }\n const node = g.getNode(nodeId)\n yield node\n if (dir == 'both') {\n yield* visit(node, 'in')\n yield* visit(node, 'out')\n } else {\n yield* visit(node, dir)\n }\n }\n\n static leftOf(g: Graph, node: Node): NodeId | null {\n if (node.index == 0) return null\n return node.getLayer(g).sorted[node.index! - 1]\n }\n\n static rightOf(g: Graph, node: Node): NodeId | null {\n const layer = node.getLayer(g)\n if (node.index == layer.sorted.length - 1) return null\n return layer.sorted[node.index! + 1]\n }\n\n static compact(g: Graph) {\n let anyChanged = false\n for (const layerId of g.layerList) {\n const layer = g.getLayer(layerId)\n if (layer.sorted.length < 2) continue\n for (const [i, nodeId] of layer.sorted.entries()) {\n const node = g.getNode(nodeId)\n if (node.index == 0) continue\n let minGap = Infinity\n const stack = []\n let maxMargin = 0\n for (const right of Layout.aligned(g, nodeId, 'both')) {\n stack.push(right)\n const leftId = Layout.leftOf(g, right)\n if (!leftId) return\n const left = g.getNode(leftId)\n const leftWidth = left.dims?.[g.w] ?? 0\n const gap = right.lpos! - left.lpos! - leftWidth\n if (gap < minGap) minGap = gap\n // Use margin between right and its left neighbor\n const margin = right.marginWith(g, left)\n if (margin > maxMargin) maxMargin = margin\n }\n const delta = minGap - maxMargin\n if (delta <= 0) continue\n anyChanged = true\n for (const right of stack)\n right.setLayerPos(g, right.lpos! - delta)\n }\n }\n return anyChanged\n }\n\n static getCoords(g: Graph) {\n let pos = 0\n const dir = g.r ? -1 : 1\n const trackSep = Math.max(\n g.options.edgeSpacing,\n g.options.turnRadius\n )\n const marginSep = Math.max(\n g.options.edgeSpacing,\n g.options.layerMargin,\n g.options.turnRadius + g.options.markerSize\n )\n for (const layerId of g.layerList) {\n let layer = g.getLayer(layerId)\n let height: number\n if (g.dirtyLayers.has(layerId)) {\n height = Seq(layer.nodes(g)).map(node => node.dims?.[g.h] ?? 0).max() ?? 0\n layer = layer.setSize(g, height)\n } else height = layer.size\n for (const node of layer.nodes(g)) {\n if (!g.dirtyNodes.has(node.id) && pos == layer.pos) continue\n const npos: Pos = { [g.x]: node.lpos!, [g.y]: pos } as Pos\n if (!g.n) npos[g.y] += dir * height\n if (g.r == g.n) npos[g.y] -= node.dims?.[g.h] ?? 0\n node.setPos(g, npos)\n }\n layer = layer.setPos(g, pos)\n pos += dir * (height + marginSep)\n for (const track of layer.tracks) {\n for (const segId of track)\n g.getSeg(segId).setTrackPos(g, pos)\n pos += dir * trackSep\n }\n pos += dir * (marginSep - trackSep)\n }\n }\n}","import { PublicEdgeData } from '../graph/edge'\n\nexport type MarkerType = 'arrow' | 'circle' | 'diamond' | 'bar' | 'none'\n\nexport type Markers = {\n source?: MarkerType\n target?: MarkerType\n}\n\nexport function arrow(size: number, reverse: boolean = false, prefix: string = ''): SVGElement {\n const h = size / 1.5\n const w = size\n const ry = h / 2\n const suffix = reverse ? '-reverse' : ''\n const id = prefix ? `${prefix}-g3p-marker-arrow${suffix}` : `g3p-marker-arrow${suffix}`\n return (\n <marker\n id={id}\n className=\"g3p-marker g3p-marker-arrow\"\n markerWidth={size}\n markerHeight={size}\n refX=\"2\"\n refY={ry}\n orient={reverse ? 'auto-start-reverse' : 'auto'}\n markerUnits=\"userSpaceOnUse\"\n >\n <path d={`M0,0 L0,${h} L${w},${ry} z`} />\n </marker>\n ) as SVGElement\n}\n\nexport function circle(size: number, reverse: boolean = false, prefix: string = ''): SVGElement {\n const r = size / 3\n const cy = size / 2\n const suffix = reverse ? '-reverse' : ''\n const id = prefix ? `${prefix}-g3p-marker-circle${suffix}` : `g3p-marker-circle${suffix}`\n return (\n <marker\n id={id}\n className=\"g3p-marker g3p-marker-circle\"\n markerWidth={size}\n markerHeight={size}\n refX=\"2\"\n refY={cy}\n orient={reverse ? 'auto-start-reverse' : 'auto'}\n markerUnits=\"userSpaceOnUse\"\n >\n <circle cx={r + 2} cy={cy} r={r} />\n </marker>\n ) as SVGElement\n}\n\nexport function diamond(size: number, reverse: boolean = false, prefix: string = ''): SVGElement {\n const w = size * 0.7\n const h = size / 2\n const cy = size / 2\n const suffix = reverse ? '-reverse' : ''\n const id = prefix ? `${prefix}-g3p-marker-diamond${suffix}` : `g3p-marker-diamond${suffix}`\n return (\n <marker\n id={id}\n className=\"g3p-marker g3p-marker-diamond\"\n markerWidth={size}\n markerHeight={size}\n refX=\"2\"\n refY={cy}\n orient={reverse ? 'auto-start-reverse' : 'auto'}\n markerUnits=\"userSpaceOnUse\"\n >\n <path d={`M2,${cy} L${2 + w / 2},${cy - h / 2} L${2 + w},${cy} L${2 + w / 2},${cy + h / 2} z`} />\n </marker>\n ) as SVGElement\n}\n\nexport function bar(size: number, reverse: boolean = false, prefix: string = ''): SVGElement {\n const h = size * 0.6\n const cy = size / 2\n const suffix = reverse ? '-reverse' : ''\n const id = prefix ? `${prefix}-g3p-marker-bar${suffix}` : `g3p-marker-bar${suffix}`\n return (\n <marker\n id={id}\n className=\"g3p-marker g3p-marker-bar\"\n markerWidth={size}\n markerHeight={size}\n refX=\"2\"\n refY={cy}\n orient={reverse ? 'auto-start-reverse' : 'auto'}\n markerUnits=\"userSpaceOnUse\"\n >\n <line x1=\"2\" y1={cy - h / 2} x2=\"2\" y2={cy + h / 2} stroke-width=\"2\" />\n </marker>\n ) as SVGElement\n}\n\nexport function none(size: number, reverse: boolean = false, prefix: string = ''): SVGElement | undefined {\n return undefined\n}\n\ntype MarkerObj = {\n source?: { marker?: MarkerType }\n target?: { marker?: MarkerType }\n style?: { marker?: { source?: MarkerType, target?: MarkerType } }\n}\n\nexport function normalize(data: MarkerObj): Markers {\n let source: MarkerType | undefined = data.source?.marker ?? data.style?.marker?.source\n let target: MarkerType | undefined = data.target?.marker ?? data.style?.marker?.target ?? 'arrow'\n if (source == 'none') source = undefined\n if (target == 'none') target = undefined\n return { source, target }\n}\n\ntype MarkerFunc = (size: number, reverse?: boolean, prefix?: string) => SVGElement | undefined\n\nexport const markerDefs: Record<MarkerType, MarkerFunc> = {\n arrow,\n circle,\n diamond,\n bar,\n none,\n}\n","import { Graph } from \"../graph\"\nimport { Seg } from \"../seg\"\nimport { Layer } from \"../layer\"\nimport { Layout } from \"./layout\"\nimport { Pos } from \"../../common\"\nimport { logger } from \"../../log\"\nimport { normalize, Markers } from \"../../canvas/marker\"\n\nconst log = logger('lines')\n\ntype TPos = Partial<Pos> & { s?: number }\n\ntype PathBuilder = {\n x: keyof Pos\n y: keyof Pos\n lr: boolean\n d: -1 | 1\n o: -1 | 1\n rd: number\n ro: number\n t: number\n s: 0 | 1\n p: TPos\n path: Line[]\n advance: (p2: TPos, type: LineType) => void\n}\n\nexport type LineType = 'line' | 'arc'\n\nexport type Line = {\n type: LineType\n x1: number\n y1: number\n x2: number\n y2: number\n radius?: number\n sweep?: number\n}\n\nexport class Lines {\n\n static layoutSeg(g: Graph, seg: Seg): Seg {\n const sourcePos = Layout.anchorPos(g, seg, 'source')\n const targetPos = Layout.anchorPos(g, seg, 'target')\n return seg.setPos(g, sourcePos[g.x], targetPos[g.x])\n }\n\n static layerSegs(g: Graph, layer: Layer): Seg[] {\n const segs: Seg[] = []\n for (const node of layer.nodes(g))\n for (const seg of node.outSegs(g))\n segs.push(Lines.layoutSeg(g, seg))\n return segs\n }\n\n static trackEdges(g: Graph) {\n // first, make sure dirty segs make their source layers dirty\n for (const segId of g.dirtySegs.values())\n g.dirtyLayers.add(g.getSeg(segId).sourceNode(g).layerId)\n const minLength = g.options.turnRadius * 2\n // then process each dirty layer\n for (const layerId of g.dirtyLayers.values()) {\n const layer = g.getLayer(layerId)\n // TODO: could start with prior tracks with dirty segs removed?\n const leftTracks: Seg[][] = []\n const rightTracks: Seg[][] = []\n const allTracks: Seg[][] = []\n // get all outgoing segs and their start/end positions\n const segs = Lines.layerSegs(g, layer)\n .sort((a, b) => a.p1 - b.p1)\n for (const seg of segs) {\n // skip nearly-vertical segs\n if (Math.abs(seg.p1 - seg.p2) < minLength) {\n seg.setTrackPos(g, undefined)\n continue\n }\n // choose left, right, or both\n let trackSet\n if (!g.options.separateTrackSets)\n trackSet = allTracks\n else if (seg.p1 < seg.p2)\n trackSet = rightTracks\n else\n trackSet = leftTracks\n // check track sets in reverse order\n let validTrack\n for (let i = trackSet.length - 1; i >= 0; i--) {\n const track = trackSet[i]\n let overlap = false\n for (const other of track) {\n // if seg shares an end with an existing track, add it\n if (seg.anySameEnd(other)) {\n track.push(seg)\n validTrack = track\n break\n }\n // if seg overlaps another, go to next track set\n const minA = Math.min(seg.p1, seg.p2)\n const maxA = Math.max(seg.p1, seg.p2)\n const minB = Math.min(other.p1, other.p2)\n const maxB = Math.max(other.p1, other.p2)\n if (minA < maxB && minB < maxA) {\n overlap = true\n break\n }\n }\n if (!overlap) {\n validTrack = track\n break\n }\n }\n // either add to existing track or create new track\n if (validTrack)\n validTrack.push(seg)\n else\n trackSet.push([seg])\n }\n // sort tracks to minimize crossings\n // use the midpoint (average of source and target) to group edges traveling through similar regions\n // for right-going: larger midpoint = inner track (closer to source)\n // for left-going: smaller midpoint = inner track (closer to source)\n const midpoint = (s: Seg) => (s.p1 + s.p2) / 2\n const sortTracks = (tracks: Seg[][], goingRight: boolean) => {\n tracks.sort((a, b) => {\n const midA = Math.max(...a.map(midpoint))\n const midB = Math.max(...b.map(midpoint))\n return goingRight ? (midB - midA) : (midA - midB)\n })\n }\n sortTracks(rightTracks, true)\n sortTracks(leftTracks, false)\n // for allTracks, use average midpoint (descending)\n allTracks.sort((a, b) => {\n const avgA = a.reduce((sum, s) => sum + midpoint(s), 0) / a.length\n const avgB = b.reduce((sum, s) => sum + midpoint(s), 0) / b.length\n return avgB - avgA\n })\n\n // convert tracks to seg ids and store on layer\n const tracks = []\n const all = leftTracks.concat(rightTracks).concat(allTracks)\n for (const track of all)\n tracks.push(track.map(seg => seg.id))\n layer.setTracks(g, tracks)\n }\n return this\n }\n\n static pathEdges(g: Graph) {\n for (const seg of g.segs.values()) {\n if (!g.dirtySegs.has(seg.id)) continue\n const radius = g.options.turnRadius\n const p1 = Layout.anchorPos(g, seg, 'source')\n const p2 = Layout.anchorPos(g, seg, 'target')\n const source = seg.sourceNode(g)\n const target = seg.targetNode(g)\n const marker = normalize(seg)\n if (source.isDummy) marker.source = undefined\n if (target.isDummy) marker.target = undefined\n const path = seg.trackPos !== undefined\n ? Lines.createRailroadPath(g, p1, p2, seg.trackPos, radius, marker)\n : Lines.createDirectPath(g, p1, p2, radius, marker)\n const svg = Lines.pathToSVG(path)\n seg.setSVG(g, svg)\n }\n return this\n }\n\n static pathLine(p1: TPos, p2: TPos, type: LineType, radius: number): Line {\n if (p2.x === undefined) p2.x = p1.x\n if (p2.y === undefined) p2.y = p1.y\n if (p2.s === undefined) p2.s = p1.s\n const line: Line = {\n type,\n x1: p1.x!, y1: p1.y!,\n x2: p2.x!, y2: p2.y!,\n }\n p1.x = p2.x\n p1.y = p2.y\n p1.s = p2.s\n if (type == 'arc') {\n line.radius = radius\n line.sweep = p1.s\n }\n return line\n }\n\n static pathBuilder(g: Graph, start: Pos, end: Pos, trackPos: number, radius: number, marker: Markers): PathBuilder {\n const { x, y } = g\n const lr = end[x] > start[x] // true for left to right\n const d = lr ? 1 : -1 // d = 1 for left to right, -1 for right to left\n const o = g.r ? -1 : 1 // o = 1 for forward, -1 for reverse\n const rd = radius * d // rd = radius * d\n const ro = radius * o // ro = radius * o\n const t = trackPos // t = track position\n\n // getting the sweep direction right in all orientations is tricky \n let s = 0 // s (sweep) = 0 for CCW, 1 for CW\n if (g.r) s = 1 - s // flip direction if reverse orientation\n if (!lr) s = 1 - s // flip direction if left to right\n if (!g.v) s = 1 - s // flip direction if horizontal\n\n // adjust start/end for markers\n if (marker.source) start[y] += o * (g.options.markerSize - 1)\n if (marker.target) end[y] -= o * (g.options.markerSize - 1)\n\n // set up an incremental drawing function\n const p = { ...start, s }\n const path: Line[] = []\n const advance = (p2: TPos, type: LineType) => {\n path.push(this.pathLine(p, p2, type, radius))\n }\n\n // return everything that might be useful\n return { x, y, lr, d, o, rd, ro, t, s: s as (0 | 1), p, path, advance }\n }\n\n // Create a railroad-style path with two 90-degree turns\n static createRailroadPath(g: Graph, start: Pos, end: Pos, trackPos: number, radius: number, marker: Markers): Line[] {\n const { x, y, rd, ro, t, s, p, path, advance } = this.pathBuilder(g, start, end, trackPos, radius, marker)\n\n // draw the path; notes assume TB layout and LR edge\n advance({ [y]: t - ro }, 'line') // straight line down to just above track \n advance({ [x]: p[x]! + rd, [y]: t }, 'arc') // arc CCW towards the right\n advance({ [x]: end[x] - rd }, 'line') // stright line right to just left of end position\n advance({ [x]: end[x], [y]: t + ro, s: 1 - s }, 'arc') // arc CW towards down\n advance({ [y]: end[y] }, 'line') // stright line down to end position\n\n return path\n }\n\n // Create a mostly-vertical path with optional S-curve\n static createDirectPath(g: Graph, start: Pos, end: Pos, radius: number, marker: Markers): Line[] {\n const { x, y, d, o, s, p, path, advance } = this.pathBuilder(g, start, end, 0, radius, marker)\n const dx = Math.abs(end.x - start.x)\n const dy = Math.abs(end.y - start.y)\n const d_ = { x: dx, y: dy }\n\n // for very straight lines, just draw a line \n if (dx < 0.1) {\n advance({ ...end }, 'line')\n return path\n }\n\n // try to use S-curve with matching radius\n const curve = Lines.calculateSCurve(d_[x], d_[y], radius)\n\n // if we can't use an S-curve, just draw a line\n if (!curve || curve.Ly == 0) {\n advance({ ...end }, 'line')\n return path\n }\n\n const m = {\n [x]: d * (d_[x] - curve.Lx) / 2,\n [y]: o * (d_[y] - curve.Ly) / 2\n }\n\n // draw the S shape\n advance({ [x]: p[x]! + m[x], [y]: p[y]! + m[y] }, 'arc')\n advance({ [x]: end[x] - m[x], [y]: end[y] - m[y] }, 'line')\n advance({ [x]: end[x], [y]: end[y], s: 1 - s }, 'arc')\n\n return path\n }\n\n static solveSCurveAngle(dx: number, dy: number, r: number): number | null {\n // The equation to solve:\n // dx * cos(α) - dy * sin(α) = 2r * (cos(α) - 1)\n // Rearranged: f(α) = dx * cos(α) - dy * sin(α) - 2r * cos(α) + 2r = 0\n\n const f = (alpha: number) => {\n return dx * Math.cos(alpha) - dy * Math.sin(alpha) - 2 * r * Math.cos(alpha) + 2 * r\n }\n\n // Derivative: f'(α) = -dx * sin(α) - dy * cos(α) + 2r * sin(α)\n const fPrime = (alpha: number) => {\n return -dx * Math.sin(alpha) - dy * Math.cos(alpha) + 2 * r * Math.sin(alpha)\n }\n\n // Newton-Raphson method\n // Start with a small initial guess (works well when points are mostly vertical)\n let alpha = Math.min(0.1, Math.abs(dx) / dy) // Initial guess based on aspect ratio\n const maxIterations = 20\n const tolerance = 1e-6\n\n for (let i = 0; i < maxIterations; i++) {\n const fVal = f(alpha)\n const fPrimeVal = fPrime(alpha)\n\n // Check if we've converged\n if (Math.abs(fVal) < tolerance) {\n // Verify this is a valid solution (L_y should be positive)\n const Ly = dy - 2 * r * Math.sin(alpha)\n if (Ly >= 0 && alpha > 0 && alpha < Math.PI / 2) {\n return alpha\n }\n return null\n }\n\n // Avoid division by zero\n if (Math.abs(fPrimeVal) < 1e-10) {\n break\n }\n\n // Newton-Raphson update\n const nextAlpha = alpha - fVal / fPrimeVal\n\n // Keep angle in reasonable bounds [0, π/2]\n if (nextAlpha < 0 || nextAlpha > Math.PI / 2) {\n break\n }\n\n alpha = nextAlpha\n }\n\n // If Newton-Raphson didn't converge, return null\n return null\n }\n\n static calculateSCurve(dx: number, dy: number, r: number) {\n const alpha = Lines.solveSCurveAngle(dx, dy, r)\n\n if (alpha === null) {\n return null\n }\n\n const Ly = dy - 2 * r * Math.sin(alpha)\n const Lx = Ly * Math.tan(alpha)\n const L = Ly / Math.cos(alpha)\n\n return {\n alpha, // Angle of each arc (radians)\n Lx, // Horizontal component of straight section\n Ly, // Vertical component of straight section\n L, // Length of straight section\n }\n }\n\n static pathToSVG(path: Line[]): string {\n if (!path || path.length === 0) return ''\n\n const lines = []\n\n // Start with Move command to first point\n const first = path[0]\n lines.push(`M ${first.x1},${first.y1}`)\n\n for (const line of path) {\n if (line.type === 'line') {\n lines.push(`L ${line.x2},${line.y2}`)\n } else if (line.type === 'arc') {\n const r = line.radius\n const largeArc = 0\n const sweep = line.sweep || 0\n lines.push(`A ${r},${r} 0 ${largeArc} ${sweep} ${line.x2},${line.y2}`)\n }\n }\n\n return lines.join(' ')\n }\n}","export type Dir = 'in' | 'out'\nexport type Side = 'source' | 'target'\nexport type MergeOrder = Side[]\nexport type NodeAlign = 'natural' | 'top' | 'bottom' | 'left' | 'right'\nexport type Orientation = 'TB' | 'BT' | 'LR' | 'RL'\nexport type Nav = 'first' | 'last' | 'prev' | 'next'\nexport type PortStyle = 'inside' | 'outside' | 'custom'\nexport type LayoutStep = 'alignChildren' | 'alignParents' | 'compact'\nexport type LinkType = 'edges' | 'segs'\n\nexport type Dims = {\n w: number\n h: number\n}\n\nexport type Pos = {\n x: number\n y: number\n}\n\n/** Screen coordinates - pixels relative to the browser viewport */\nexport type ScreenPos = Pos & { _brand: 'screen' }\n\n/** Canvas coordinates - pixels relative to the canvas container element */\nexport type CanvasPos = Pos & { _brand: 'canvas' }\n\n/** Graph coordinates - SVG units in the graph's coordinate space */\nexport type GraphPos = Pos & { _brand: 'graph' }\n\n/** Create a ScreenPos from x, y values */\nexport const screenPos = (x: number, y: number): ScreenPos => ({ x, y } as ScreenPos)\n\n/** Create a CanvasPos from x, y values */\nexport const canvasPos = (x: number, y: number): CanvasPos => ({ x, y } as CanvasPos)\n\n/** Create a GraphPos from x, y values */\nexport const graphPos = (x: number, y: number): GraphPos => ({ x, y } as GraphPos)\n","import { Dims, Pos, Orientation, Dir } from '../common'\nimport { Canvas } from './canvas'\nimport { PublicNodeData } from '../graph/node'\n\nexport class Node {\n selected: boolean\n hovered: boolean\n container!: SVGElement\n content!: HTMLElement\n innerContent?: HTMLElement\n cleanup?: () => void\n canvas: Canvas<any, any>\n data: PublicNodeData\n isDummy: boolean\n pos?: Pos\n\n constructor(canvas: Canvas<any, any>, data: PublicNodeData, isDummy: boolean = false) {\n this.canvas = canvas\n this.data = data\n this.selected = false\n this.hovered = false\n this.isDummy = isDummy\n\n if (this.isDummy) {\n const size = canvas.dummyNodeSize\n } else {\n const render = data!.render ?? canvas.renderNode\n const innerEl = render(data!.data, data!)\n this.innerContent = innerEl\n this.content = this.renderContent(innerEl)\n }\n }\n\n remove() {\n this.cleanup?.()\n this.container.remove()\n }\n\n append() {\n this.canvas.group!.appendChild(this.container)\n }\n\n needsContentSize(): boolean {\n return !this.isDummy && this.content instanceof HTMLElement\n }\n\n needsContainerSize(): boolean {\n return !this.isDummy\n }\n\n setPos(pos: Pos) {\n this.pos = pos\n const { x, y } = pos\n this.container!.setAttribute('transform', `translate(${x}, ${y})`)\n }\n\n hasPorts(): boolean {\n return !!this.data?.ports?.in?.length || !!this.data?.ports?.out?.length\n }\n\n renderContent(el: HTMLElement): HTMLElement {\n const hasPorts = this.hasPorts()\n // Ports rendered outside by default\n el = this.renderBorder(el)\n if (hasPorts)\n el = this.renderOutsidePorts(el)\n return el\n }\n\n renderContainer() {\n const hasPorts = this.hasPorts()\n const inner = this.isDummy ? this.renderDummy() : this.renderForeign()\n const nodeType = this.data?.type\n const typeClass = nodeType ? `g3p-node-type-${nodeType}` : ''\n this.container = (\n <g\n className={`g3p-node-container ${this.isDummy ? 'g3p-node-dummy' : ''} ${typeClass}`.trim()}\n data-node-id={this.data?.id}\n >\n {inner}\n </g>\n ) as SVGElement\n }\n\n renderForeign(): SVGElement {\n const { w, h } = this.data!.dims!\n return (\n <foreignObject width={w} height={h}>\n {this.content}\n </foreignObject>\n ) as SVGElement\n }\n\n renderDummy(): SVGElement {\n let w = this.canvas.dummyNodeSize\n let h = this.canvas.dummyNodeSize\n w /= 2\n h /= 2\n return (<g>\n <ellipse\n cx={w} cy={h} rx={w} ry={h}\n className=\"g3p-node-background\"\n />\n <ellipse\n cx={w} cy={h} rx={w} ry={h}\n fill=\"none\"\n className=\"g3p-node-border\"\n />\n </g>) as SVGElement\n }\n\n measure(isVertical: boolean) {\n const rect = this.content.getBoundingClientRect()\n const data = this.data!\n data.dims = { w: rect.width, h: rect.height }\n for (const dir of ['in', 'out'] as const) {\n const ports = data.ports?.[dir]\n if (!ports) continue\n for (const port of ports) {\n const el = this.content.querySelector(`.g3p-node-port[data-node-id=\"${data.id}\"][data-port-id=\"${port.id}\"]`)\n if (!el) continue\n const portRect = el.getBoundingClientRect()\n if (isVertical) {\n port.offset = portRect.left - rect.left\n port.size = portRect.width\n } else {\n port.offset = portRect.top - rect.top\n port.size = portRect.height\n }\n }\n }\n }\n\n private getPortPosition(dir: Dir): 'top' | 'bottom' | 'left' | 'right' {\n const o = this.canvas.orientation\n if (dir === 'in') {\n if (o === 'TB') return 'top'\n if (o === 'BT') return 'bottom'\n if (o === 'LR') return 'left'\n return 'right' // RL\n } else {\n if (o === 'TB') return 'bottom'\n if (o === 'BT') return 'top'\n if (o === 'LR') return 'right'\n return 'left' // RL\n }\n }\n\n private isVerticalOrientation(): boolean {\n const o = this.canvas.orientation\n return o === 'TB' || o === 'BT'\n }\n\n private isReversedOrientation(): boolean {\n const o = this.canvas.orientation\n return o === 'BT' || o === 'RL'\n }\n\n private renderPortRow(dir: Dir, inout: Dir): HTMLElement | null {\n const ports = this.data?.ports?.[dir]\n if (!ports?.length) return null\n\n const pos = this.getPortPosition(dir)\n const isVertical = this.isVerticalOrientation()\n const layoutClass = isVertical ? 'row' : 'col'\n const rotateLabels = false // TODO: make configurable via CSS class\n const rotateClass = rotateLabels ? `port-rotated-${pos}` : ''\n\n return (\n <div className={`g3p-node-ports g3p-node-ports-${layoutClass}`}>\n {ports.map(port => (\n <div\n className={`g3p-node-port g3p-node-port-${inout}-${pos} ${rotateClass}`}\n data-node-id={this.data!.id}\n data-port-id={port.id}\n >\n {port.label ?? port.id}\n </div>\n ))}\n </div>\n ) as HTMLElement\n }\n\n renderInsidePorts(el: HTMLElement): HTMLElement {\n const isVertical = this.isVerticalOrientation()\n const isReversed = this.isReversedOrientation()\n let inPorts = this.renderPortRow('in', 'in')\n let outPorts = this.renderPortRow('out', 'in')\n\n if (!inPorts && !outPorts) return el\n if (isReversed) [inPorts, outPorts] = [outPorts, inPorts]\n const wrapperClass = isVertical ? 'v' : 'h'\n\n return (\n <div className={`g3p-node-with-ports g3p-node-with-ports-${wrapperClass}`}>\n {inPorts}\n {el}\n {outPorts}\n </div>\n ) as HTMLElement\n }\n\n renderOutsidePorts(el: HTMLElement): HTMLElement {\n const isVertical = this.isVerticalOrientation()\n const isReversed = this.isReversedOrientation()\n let inPorts = this.renderPortRow('in', 'out')\n let outPorts = this.renderPortRow('out', 'out')\n\n if (!inPorts && !outPorts) return el\n if (isReversed) [inPorts, outPorts] = [outPorts, inPorts]\n const wrapperClass = isVertical ? 'v' : 'h'\n\n return (\n <div className={`g3p-node-with-ports g3p-node-with-ports-${wrapperClass}`}>\n {inPorts}\n {el}\n {outPorts}\n </div>\n ) as HTMLElement\n }\n\n renderBorder(el: HTMLElement): HTMLElement {\n return <div className=\"g3p-node-border\">\n {el}\n </div> as HTMLElement\n }\n}\n","import { Canvas } from './canvas'\nimport { normalize } from './marker'\nimport { Seg as GraphSeg } from '../graph/seg'\nimport { Graph } from '../graph/graph'\nimport { MarkerType } from './marker'\n\nexport class Seg {\n id: string\n selected: boolean\n hovered: boolean\n canvas: Canvas\n type: string | undefined\n svg: string\n el: SVGElement\n source: { marker?: MarkerType, isDummy?: boolean }\n target: { marker?: MarkerType, isDummy?: boolean }\n edgeIds: string[]\n\n constructor(canvas: Canvas, data: GraphSeg, g: Graph) {\n this.id = data.id\n this.canvas = canvas\n this.selected = false\n this.hovered = false\n this.svg = data.svg!\n this.source = { ...data.source, isDummy: data.sourceNode(g).isDummy }\n this.target = { ...data.target, isDummy: data.targetNode(g).isDummy }\n this.type = data.type\n this.edgeIds = data.edgeIds.toArray()\n this.el = this.render()\n }\n\n append() {\n this.canvas.group!.appendChild(this.el!)\n }\n\n remove() {\n this.el!.remove()\n }\n\n update(data: GraphSeg, g: Graph) {\n this.svg = data.svg!\n this.type = data.type\n this.source = { ...data.source, isDummy: data.sourceNode(g).isDummy }\n this.target = { ...data.target, isDummy: data.targetNode(g).isDummy }\n this.edgeIds = data.edgeIds.toArray()\n this.remove()\n this.el = this.render()\n this.append()\n }\n\n render(): SVGElement {\n let { source, target } = normalize(this)\n if (this.source.isDummy) source = undefined\n if (this.target.isDummy) target = undefined\n const typeClass = this.type ? `g3p-edge-type-${this.type}` : ''\n const prefix = this.canvas.markerPrefix\n const markerStartId = source ? (prefix ? `${prefix}-g3p-marker-${source}-reverse` : `g3p-marker-${source}-reverse`) : undefined\n const markerEndId = target ? (prefix ? `${prefix}-g3p-marker-${target}` : `g3p-marker-${target}`) : undefined\n return (\n <g\n ref={(el: SVGElement) => this.el = el}\n id={`g3p-seg-${this.id}`}\n className={`g3p-seg-container ${typeClass}`.trim()}\n data-edge-id={this.id}\n >\n <path\n d={this.svg}\n fill=\"none\"\n className=\"g3p-seg-line\"\n markerStart={markerStartId ? `url(#${markerStartId})` : undefined}\n markerEnd={markerEndId ? `url(#${markerEndId})` : undefined}\n />\n <path\n d={this.svg}\n stroke=\"transparent\"\n fill=\"none\"\n className=\"g3p-seg-hitbox\"\n style={{ cursor: 'pointer' }}\n />\n </g>\n ) as SVGElement\n }\n}\n","import { CanvasPos, GraphPos } from '../common'\n\n/** Target for edge drop */\nexport type EdgeDropTarget =\n | { type: 'node'; id: string; port?: string }\n | { type: 'canvas' }\n | null\n\n/**\n * Edit mode states for the canvas.\n */\nexport type EditState =\n | { type: 'idle' }\n | { type: 'panning'; startCanvas: CanvasPos; startTransform: { x: number; y: number; scale: number } }\n | { type: 'new-edge'; source: { id: string, port?: string }; startGraph: GraphPos; currentGraph: GraphPos; target: EdgeDropTarget }\n\n/**\n * Edit mode state machine for the canvas.\n * Manages transitions between idle, panning, and new-edge creation states.\n */\nexport class EditMode {\n private _state: EditState = { type: 'idle' }\n private _editable: boolean = false\n\n get state(): EditState {\n return this._state\n }\n\n get editable(): boolean {\n return this._editable\n }\n\n set editable(value: boolean) {\n this._editable = value\n if (!value) {\n this.reset()\n }\n }\n\n get isIdle(): boolean {\n return this._state.type === 'idle'\n }\n\n get isPanning(): boolean {\n return this._state.type === 'panning'\n }\n\n get isCreatingEdge(): boolean {\n return this._state.type === 'new-edge'\n }\n\n /** Start panning the canvas */\n startPan(startCanvas: CanvasPos, startTransform: { x: number; y: number; scale: number }): void {\n this._state = { type: 'panning', startCanvas, startTransform }\n }\n\n /** Start creating a new edge from a node or port */\n startNewEdge(id: string, startGraph: GraphPos, port?: string): void {\n if (!this._editable) return\n this._state = {\n type: 'new-edge',\n source: { id, port },\n startGraph,\n currentGraph: startGraph,\n target: null,\n }\n }\n\n /** Update the current position during new-edge mode */\n updateNewEdgePosition(currentGraph: GraphPos): void {\n if (this._state.type === 'new-edge') {\n this._state = { ...this._state, currentGraph }\n }\n }\n\n /** Update the hover target during new-edge mode */\n setHoverTarget(target: EdgeDropTarget): void {\n if (this._state.type === 'new-edge') {\n this._state = { ...this._state, target }\n }\n }\n\n /** Get the new-edge state if active */\n getNewEdgeState(): Extract<EditState, { type: 'new-edge' }> | null {\n if (this._state.type === 'new-edge') {\n return this._state\n }\n return null\n }\n\n /** Reset to idle state */\n reset(): void {\n this._state = { type: 'idle' }\n }\n}\n","import { GraphPos } from '../common'\n\nimport styles from './newEdge.css?raw'\n\nexport type NewEdgeProps = {\n start: GraphPos\n end: GraphPos\n}\n\n/**\n * Renders the animated dashed line during new-edge creation mode.\n */\nexport function renderNewEdge({ start, end }: NewEdgeProps): SVGElement {\n return (\n <g className=\"g3p-new-edge-container\">\n {/* Origin indicator */}\n <circle\n cx={start.x}\n cy={start.y}\n r={4}\n className=\"g3p-new-edge-origin\"\n />\n {/* Animated dashed line */}\n <line\n x1={start.x}\n y1={start.y}\n x2={end.x}\n y2={end.y}\n className=\"g3p-new-edge-line\"\n />\n {/* End indicator */}\n <circle\n cx={end.x}\n cy={end.y}\n r={3}\n className=\"g3p-new-edge-end\"\n />\n </g>\n ) as SVGElement\n}\n","import { ScreenPos } from '../common'\nimport { MarkerType } from './marker'\nimport { PublicEdgeData } from '../graph/edge'\nimport { PublicNodeData } from '../graph/node'\nimport { EditEdgeProps, EditNodeProps } from '../api/api'\nimport { NewNode } from '../api/options'\n\nexport type FieldType = 'string' | 'number' | 'boolean'\nexport type DetectedFields = Map<string, FieldType>\n\nexport type ModalResult<T> = T | null\n\nexport interface ModalOptions {\n title: string\n position?: ScreenPos\n onClose: () => void\n}\n\n/**\n * Base modal component for edit mode dialogs\n */\nexport class Modal {\n protected container: HTMLElement\n protected overlay: HTMLElement\n protected dialog: HTMLElement\n protected onClose: () => void\n private mouseDownOnOverlay = false\n\n constructor(options: ModalOptions) {\n this.onClose = options.onClose\n\n // Create overlay - track mousedown origin to avoid closing when dragging text selection\n this.overlay = (\n <div\n className=\"g3p-modal-overlay\"\n onMouseDown={(e) => {\n this.mouseDownOnOverlay = e.target === this.overlay\n }}\n onMouseUp={(e) => {\n if (this.mouseDownOnOverlay && e.target === this.overlay) this.close()\n this.mouseDownOnOverlay = false\n }}\n />\n ) as HTMLElement\n\n // Create dialog\n this.dialog = (\n <div className=\"g3p-modal-dialog\">\n <div className=\"g3p-modal-header\">\n <span className=\"g3p-modal-title\">{options.title}</span>\n <button\n className=\"g3p-modal-close\"\n onClick={() => this.close()}\n >×</button>\n </div>\n <div className=\"g3p-modal-body\" />\n <div className=\"g3p-modal-footer\" />\n </div>\n ) as HTMLElement\n\n // Position dialog if specified\n if (options.position) {\n this.dialog.style.position = 'absolute'\n this.dialog.style.left = `${options.position.x}px`\n this.dialog.style.top = `${options.position.y}px`\n this.dialog.style.transform = 'translate(-50%, -50%)'\n }\n\n this.overlay.appendChild(this.dialog)\n this.container = this.overlay\n\n // Handle escape key\n this.handleKeyDown = this.handleKeyDown.bind(this)\n document.addEventListener('keydown', this.handleKeyDown)\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n this.close()\n }\n }\n\n protected get body(): HTMLElement {\n return this.dialog.querySelector('.g3p-modal-body') as HTMLElement\n }\n\n protected get footer(): HTMLElement {\n return this.dialog.querySelector('.g3p-modal-footer') as HTMLElement\n }\n\n show(parent: HTMLElement) {\n parent.appendChild(this.container)\n // Focus first input\n const firstInput = this.dialog.querySelector('input, select, button') as HTMLElement\n if (firstInput) firstInput.focus()\n }\n\n close() {\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.onClose()\n }\n}\n\n// ==================== New Node Modal ====================\n\nexport interface NewNodeModalOptions {\n nodeTypes?: string[]\n fields?: DetectedFields\n onSubmit: (data: Record<string, any>) => void\n onCancel?: () => void\n}\n\nexport class NewNodeModal extends Modal {\n private fieldInputs: Map<string, HTMLInputElement | HTMLSelectElement> = new Map()\n private typeSelect?: HTMLSelectElement\n private submitCallback: NewNodeModalOptions['onSubmit']\n private fields: DetectedFields\n\n constructor(options: NewNodeModalOptions) {\n super({\n title: 'New Node',\n onClose: () => options.onCancel?.()\n })\n this.submitCallback = options.onSubmit\n this.fields = options.fields ?? new Map([['title', 'string']])\n this.renderBody(options.nodeTypes)\n this.renderFooter()\n }\n\n private renderBody(nodeTypes?: string[]) {\n this.body.innerHTML = ''\n\n // Render dynamic fields\n for (const [name, type] of this.fields) {\n const label = name.charAt(0).toUpperCase() + name.slice(1)\n const fieldGroup = this.renderField(name, label, type)\n this.body.appendChild(fieldGroup)\n }\n\n // Type selector (if types provided)\n if (nodeTypes && nodeTypes.length > 0) {\n const typeGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Type</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.typeSelect = el}\n >\n <option value=\"\">Default</option>\n {nodeTypes.map(type => (\n <option value={type}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(typeGroup)\n }\n }\n\n private renderField(name: string, label: string, type: FieldType): HTMLElement {\n if (type === 'boolean') {\n return (\n <div className=\"g3p-modal-field g3p-modal-field-checkbox\">\n <label className=\"g3p-modal-label\">\n <input\n type=\"checkbox\"\n className=\"g3p-modal-checkbox\"\n ref={(el: HTMLInputElement) => this.fieldInputs.set(name, el)}\n />\n {label}\n </label>\n </div>\n ) as HTMLElement\n }\n return (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">{label}</label>\n <input\n type={type === 'number' ? 'number' : 'text'}\n className=\"g3p-modal-input\"\n placeholder={`Enter ${label.toLowerCase()}`}\n ref={(el: HTMLInputElement) => this.fieldInputs.set(name, el)}\n />\n </div>\n ) as HTMLElement\n }\n\n private renderFooter() {\n this.footer.innerHTML = ''\n this.footer.appendChild(\n <div className=\"g3p-modal-buttons\">\n <button\n className=\"g3p-modal-btn g3p-modal-btn-secondary\"\n onClick={() => this.close()}\n >Cancel</button>\n <button\n className=\"g3p-modal-btn g3p-modal-btn-primary\"\n onClick={() => this.submit()}\n >Create</button>\n </div> as HTMLElement\n )\n }\n\n private submit() {\n const data: Record<string, any> = {}\n\n // Collect field values\n for (const [name, type] of this.fields) {\n const input = this.fieldInputs.get(name)\n if (!input) continue\n if (type === 'boolean') {\n data[name] = (input as HTMLInputElement).checked\n } else if (type === 'number') {\n const val = (input as HTMLInputElement).value\n if (val) data[name] = Number(val)\n } else {\n const val = (input as HTMLInputElement).value.trim()\n if (val) data[name] = val\n }\n }\n\n // Require at least one field to be filled\n if (Object.keys(data).length === 0) {\n const firstInput = this.fieldInputs.values().next().value\n if (firstInput) firstInput.focus()\n return\n }\n\n if (this.typeSelect?.value) {\n data.type = this.typeSelect.value\n }\n\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.submitCallback(data)\n }\n}\n\n// ==================== Edit Node Modal ====================\n\nexport interface EditNodeModalOptions {\n node: Record<string, any>\n position?: ScreenPos\n nodeTypes?: string[]\n fields?: DetectedFields\n onSubmit: (data: Record<string, any>) => void\n onDelete?: () => void\n onCancel?: () => void\n}\n\nexport class EditNodeModal extends Modal {\n private fieldInputs: Map<string, HTMLInputElement | HTMLSelectElement> = new Map()\n private typeSelect?: HTMLSelectElement\n private node: Record<string, any>\n private fields: DetectedFields\n private submitCallback: EditNodeModalOptions['onSubmit']\n private deleteCallback?: () => void\n\n constructor(options: EditNodeModalOptions) {\n super({\n title: 'Edit Node',\n position: options.position,\n onClose: () => options.onCancel?.()\n })\n this.node = options.node\n this.submitCallback = options.onSubmit\n this.deleteCallback = options.onDelete\n this.fields = options.fields ?? new Map([['title', 'string']])\n if (!options.fields && !this.node.title)\n this.node = { ...this.node, title: this.node.id }\n this.renderBody(options.nodeTypes)\n this.renderFooter()\n }\n\n private renderBody(nodeTypes?: string[]) {\n console.log(`renderBody`, this.node)\n this.body.innerHTML = ''\n\n // Render dynamic fields with current values\n for (const [name, type] of this.fields) {\n const label = name.charAt(0).toUpperCase() + name.slice(1)\n const currentValue = this.node[name]\n const fieldGroup = this.renderField(name, label, type, currentValue)\n this.body.appendChild(fieldGroup)\n }\n\n // Type selector (if types provided)\n if (nodeTypes && nodeTypes.length > 0) {\n const currentType = this.node.type ?? ''\n const typeGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Type</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.typeSelect = el}\n >\n <option value=\"\" selected={!currentType}>Default</option>\n {nodeTypes.map(type => (\n <option value={type} selected={type === currentType}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(typeGroup)\n }\n }\n\n private renderField(name: string, label: string, type: FieldType, currentValue?: any): HTMLElement {\n if (type === 'boolean') {\n return (\n <div className=\"g3p-modal-field g3p-modal-field-checkbox\">\n <label className=\"g3p-modal-label\">\n <input\n type=\"checkbox\"\n className=\"g3p-modal-checkbox\"\n checked={!!currentValue}\n ref={(el: HTMLInputElement) => this.fieldInputs.set(name, el)}\n />\n {label}\n </label>\n </div>\n ) as HTMLElement\n }\n return (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">{label}</label>\n <input\n type={type === 'number' ? 'number' : 'text'}\n className=\"g3p-modal-input\"\n value={currentValue ?? ''}\n ref={(el: HTMLInputElement) => this.fieldInputs.set(name, el)}\n />\n </div>\n ) as HTMLElement\n }\n\n private renderFooter() {\n this.footer.innerHTML = ''\n this.footer.appendChild(\n <div className=\"g3p-modal-buttons\">\n {this.deleteCallback && (\n <button\n className=\"g3p-modal-btn g3p-modal-btn-danger\"\n onClick={() => this.delete()}\n >Delete</button>\n )}\n <div className=\"g3p-modal-spacer\" />\n <button\n className=\"g3p-modal-btn g3p-modal-btn-secondary\"\n onClick={() => this.close()}\n >Cancel</button>\n <button\n className=\"g3p-modal-btn g3p-modal-btn-primary\"\n onClick={() => this.submit()}\n >Save</button>\n </div> as HTMLElement\n )\n }\n\n private submit() {\n const data: Record<string, any> = { ...this.node }\n\n // Collect field values\n for (const [name, type] of this.fields) {\n const input = this.fieldInputs.get(name)\n if (!input) continue\n if (type === 'boolean') {\n data[name] = (input as HTMLInputElement).checked\n } else if (type === 'number') {\n const val = (input as HTMLInputElement).value\n data[name] = val ? Number(val) : undefined\n } else {\n const val = (input as HTMLInputElement).value.trim()\n data[name] = val || undefined\n }\n }\n\n if (this.typeSelect) {\n data.type = this.typeSelect.value || undefined\n }\n\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.submitCallback(data)\n }\n\n private delete() {\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.deleteCallback?.()\n }\n}\n\n// ==================== Edit Edge Modal ====================\n\nexport interface EditEdgeModalOptions {\n edge: EditEdgeProps\n edgeTypes?: string[]\n onSubmit: (data: EditEdgeProps) => void\n onCancel?: () => void\n onDelete?: () => void\n}\n\nexport class EditEdgeModal extends Modal {\n private sourceMarkerSelect!: HTMLSelectElement\n private targetMarkerSelect!: HTMLSelectElement\n private typeSelect?: HTMLSelectElement\n private edge: EditEdgeProps\n private submitCallback: EditEdgeModalOptions['onSubmit']\n private deleteCallback?: () => void\n\n private static markerTypes: MarkerType[] = ['none', 'arrow', 'circle', 'diamond', 'bar']\n\n constructor(options: EditEdgeModalOptions) {\n super({\n title: 'Edit Edge',\n onClose: () => options.onCancel?.()\n })\n this.edge = options.edge\n this.submitCallback = options.onSubmit\n this.deleteCallback = options.onDelete\n this.renderBody(options.edgeTypes)\n this.renderFooter()\n }\n\n private renderBody(edgeTypes?: string[]) {\n this.body.innerHTML = ''\n\n const currentSourceMarker = this.edge.source?.marker ?? 'none'\n const currentTargetMarker = this.edge.target?.marker ?? 'arrow'\n\n // Source marker\n const sourceGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Source Marker</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.sourceMarkerSelect = el}\n >\n {EditEdgeModal.markerTypes.map(type => (\n <option value={type} selected={type === currentSourceMarker}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(sourceGroup)\n\n // Target marker\n const targetGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Target Marker</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.targetMarkerSelect = el}\n >\n {EditEdgeModal.markerTypes.map(type => (\n <option value={type} selected={type === currentTargetMarker}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(targetGroup)\n\n // Type selector (if types provided)\n if (edgeTypes && edgeTypes.length > 0) {\n const currentType = this.edge.type ?? ''\n const typeGroup = (\n <div className=\"g3p-modal-field\">\n <label className=\"g3p-modal-label\">Type</label>\n <select\n className=\"g3p-modal-select\"\n ref={(el: HTMLSelectElement) => this.typeSelect = el}\n >\n <option value=\"\" selected={!currentType}>Default</option>\n {edgeTypes.map(type => (\n <option value={type} selected={type === currentType}>{type}</option>\n ))}\n </select>\n </div>\n ) as HTMLElement\n this.body.appendChild(typeGroup)\n }\n }\n\n private renderFooter() {\n this.footer.innerHTML = ''\n this.footer.appendChild(\n <div className=\"g3p-modal-buttons\">\n {this.deleteCallback && (\n <button\n className=\"g3p-modal-btn g3p-modal-btn-danger\"\n onClick={() => this.delete()}\n >Delete</button>\n )}\n <div className=\"g3p-modal-spacer\" />\n <button\n className=\"g3p-modal-btn g3p-modal-btn-secondary\"\n onClick={() => this.close()}\n >Cancel</button>\n <button\n className=\"g3p-modal-btn g3p-modal-btn-primary\"\n onClick={() => this.submit()}\n >Save</button>\n </div> as HTMLElement\n )\n }\n\n private submit() {\n const data: EditEdgeProps = {\n ...this.edge,\n source: {\n ...this.edge.source,\n marker: this.sourceMarkerSelect.value === 'none' ? undefined : this.sourceMarkerSelect.value as MarkerType,\n },\n target: {\n ...this.edge.target,\n marker: this.targetMarkerSelect.value === 'none' ? undefined : this.targetMarkerSelect.value as MarkerType,\n },\n }\n\n if (this.typeSelect) {\n data.type = this.typeSelect.value || undefined\n }\n\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.submitCallback(data)\n }\n\n private delete() {\n document.removeEventListener('keydown', this.handleKeyDown)\n this.container.remove()\n this.deleteCallback?.()\n }\n}\n","/* ==================== Theme Variables ==================== */\n\n/* Light theme (default) */\n:root {\n --g3p-bg: #fafafa;\n --g3p-bg-node: #ffffff;\n --g3p-bg-secondary: #f8fafc;\n --g3p-border: #e2e8f0;\n --g3p-border-hover: #cbd5e1;\n --g3p-border-selected: #3b82f6;\n --g3p-text: #1e293b;\n --g3p-text-muted: #475569;\n --g3p-text-subtle: #64748b;\n --g3p-edge-color: #64748b;\n --g3p-port-bg: #e2e8f0;\n --g3p-port-bg-hover: #cbd5e1;\n --g3p-shadow: rgba(0, 0, 0, 0.15);\n}\n\n/* Dark theme (auto via prefers-color-scheme) */\n@media (prefers-color-scheme: dark) {\n :root {\n --g3p-bg: #1a1a1a;\n --g3p-bg-node: #333333;\n --g3p-bg-secondary: #2a2a2a;\n --g3p-border: #4a4a4a;\n --g3p-border-hover: #5a5a5a;\n --g3p-border-selected: #60a5fa;\n --g3p-text: #f0f0f0;\n --g3p-text-muted: #c0c0c0;\n --g3p-text-subtle: #909090;\n --g3p-edge-color: #b0b0b0;\n --g3p-port-bg: #444444;\n --g3p-port-bg-hover: #555555;\n --g3p-shadow: rgba(0, 0, 0, 0.5);\n }\n}\n\n/* Explicit light mode override */\n.g3p-light {\n --g3p-bg: #fafafa;\n --g3p-bg-node: #ffffff;\n --g3p-bg-secondary: #f8fafc;\n --g3p-border: #e2e8f0;\n --g3p-border-hover: #cbd5e1;\n --g3p-border-selected: #3b82f6;\n --g3p-text: #1e293b;\n --g3p-text-muted: #475569;\n --g3p-text-subtle: #64748b;\n --g3p-edge-color: #64748b;\n --g3p-port-bg: #e2e8f0;\n --g3p-port-bg-hover: #cbd5e1;\n --g3p-shadow: rgba(0, 0, 0, 0.15);\n}\n\n/* Explicit dark mode override */\n.g3p-dark {\n --g3p-bg: #1a1a1a;\n --g3p-bg-node: #333333;\n --g3p-bg-secondary: #2a2a2a;\n --g3p-border: #4a4a4a;\n --g3p-border-hover: #5a5a5a;\n --g3p-border-selected: #60a5fa;\n --g3p-text: #f0f0f0;\n --g3p-text-muted: #c0c0c0;\n --g3p-text-subtle: #909090;\n --g3p-edge-color: #b0b0b0;\n --g3p-port-bg: #444444;\n --g3p-port-bg-hover: #555555;\n --g3p-shadow: rgba(0, 0, 0, 0.5);\n}\n\n/* ==================== Canvas ==================== */\n\n.g3p-canvas-container {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.g3p-canvas-root {\n display: block;\n width: 100%;\n height: 100%;\n user-select: none;\n background: var(--g3p-bg);\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n/* ==================== Zoom Controls ==================== */\n\n.g3p-zoom-controls {\n position: absolute;\n bottom: 1rem;\n right: 1rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n background: var(--g3p-bg-node);\n border-radius: 8px;\n padding: 0.5rem;\n box-shadow: 0 2px 8px var(--g3p-shadow);\n z-index: 10;\n}\n\n.g3p-zoom-btn {\n width: 36px;\n height: 36px;\n border: 1px solid var(--g3p-border);\n background: var(--g3p-bg-node);\n border-radius: 6px;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--g3p-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n}\n\n.g3p-zoom-btn:hover {\n background: var(--g3p-bg-secondary);\n border-color: var(--g3p-border-hover);\n color: var(--g3p-text);\n}\n\n.g3p-zoom-btn:active {\n transform: scale(0.95);\n}\n\n.g3p-zoom-reset {\n font-size: 1.1rem;\n}\n\n.g3p-zoom-level {\n text-align: center;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--g3p-text-subtle);\n padding: 0.25rem 0;\n}\n\n/* ==================== Nodes ==================== */\n\n/* Default node content styles */\n.g3p-node-default {\n padding: 8px 12px;\n font: 14px/1.4 system-ui, sans-serif;\n color: var(--g3p-text);\n}\n\n.g3p-node-title {\n font-weight: 500;\n}\n\n.g3p-node-detail {\n font-size: 12px;\n color: var(--g3p-text-muted);\n margin-top: 2px;\n}\n\n.g3p-node-container {\n transition: opacity 0.2s ease;\n}\n\n.g3p-node-border {\n background: var(--g3p-bg-node);\n border: 1px solid var(--g3p-border);\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.15s ease;\n}\n\n.g3p-node-border:hover {\n border-color: var(--g3p-border-hover);\n}\n\n.g3p-node-border.selected {\n outline: 2px solid var(--g3p-border-selected);\n}\n\n.g3p-node-content-wrapper {\n pointer-events: none;\n}\n\n.g3p-node-content {\n pointer-events: auto;\n box-sizing: border-box;\n}\n\n.g3p-node-content>div {\n width: 100%;\n height: 100%;\n}\n\n/* Dummy node styles - these remain SVG since dummies are ellipses */\n.g3p-node-dummy .g3p-node-background {\n fill: var(--g3p-bg-secondary);\n opacity: 0.8;\n}\n\n.g3p-node-dummy {\n stroke: var(--g3p-border-hover);\n stroke-dasharray: 3, 3;\n cursor: default;\n}\n\n/* Port container styles */\n.g3p-node-ports {\n display: flex;\n gap: 4px;\n}\n\n.g3p-node-ports-row {\n flex-direction: row;\n justify-content: center;\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.g3p-node-ports-col {\n flex-direction: column;\n justify-content: center;\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n/* Port styles */\n.g3p-node-port {\n background: var(--g3p-port-bg);\n border: 1px solid var(--g3p-border-hover);\n padding: 2px 6px;\n font-size: 0.5em;\n color: var(--g3p-text-muted);\n white-space: nowrap;\n transition: all 0.15s ease;\n}\n\n.g3p-node-port:hover {\n background: var(--g3p-port-bg-hover);\n border-color: var(--g3p-text-subtle);\n}\n\n.g3p-node-port-rotated-left {\n writing-mode: vertical-lr;\n}\n\n.g3p-node-port-rotated-right {\n writing-mode: vertical-rl;\n}\n\n/* Outside ports: rounded corners away from the node rectangle, no border on touching side */\n.g3p-node-port-out-top {\n border-radius: 4px 4px 0 0;\n border-bottom: none;\n}\n\n.g3p-node-port-out-bottom {\n border-radius: 0 0 4px 4px;\n border-top: none;\n}\n\n.g3p-node-port-out-left {\n border-radius: 4px 0 0 4px;\n border-right: none;\n}\n\n.g3p-node-port-out-right {\n border-radius: 0 4px 4px 0;\n border-left: none;\n}\n\n/* Inside ports: rounded corners toward the content, no border on outer edge */\n.g3p-node-port-in-top {\n border-radius: 0 0 4px 4px;\n border-top: none;\n}\n\n.g3p-node-port-in-bottom {\n border-radius: 4px 4px 0 0;\n border-bottom: none;\n}\n\n.g3p-node-port-in-left {\n border-radius: 0 4px 4px 0;\n border-left: none;\n}\n\n.g3p-node-port-in-right {\n border-radius: 4px 0 0 4px;\n border-right: none;\n}\n\n/* Port wrapper */\n.g3p-node-with-ports {\n display: flex;\n}\n\n.g3p-node-with-ports-v {\n flex-direction: column;\n}\n\n.g3p-node-with-ports-h {\n flex-direction: row;\n}\n\n/* ==================== Edges (Segments) ==================== */\n\n.g3p-seg-container {\n transition: opacity 0.2s ease;\n}\n\n.g3p-seg-line {\n stroke: var(--g3p-edge-color);\n stroke-width: 1;\n transition: stroke 0.2s ease, stroke-width 0.2s ease;\n}\n\n.g3p-seg-marker {\n fill: var(--g3p-edge-color);\n}\n\n.g3p-seg-line.hovered {\n stroke-width: 2;\n opacity: 1;\n}\n\n.g3p-seg-line.selected {\n stroke: var(--g3p-border-selected);\n stroke-width: 2;\n}\n\n.g3p-seg-hitbox {\n cursor: pointer;\n}\n\n/* ==================== Markers ==================== */\n\n.g3p-marker {\n fill: context-stroke;\n stroke: none;\n}\n\n.g3p-marker-bar {\n fill: none;\n stroke: context-stroke;\n stroke-width: 2;\n}\n\n.g3p-marker.hovered {\n fill: var(--g3p-text-muted);\n}\n\n.g3p-marker.selected {\n fill: var(--g3p-border-selected);\n}\n\n.g3p-marker-bar.hovered {\n stroke: var(--g3p-text-muted);\n}\n\n.g3p-marker-bar.selected {\n stroke: var(--g3p-border-selected);\n}\n\n/* ==================== New Edge (Edit Mode) ==================== */\n\n.g3p-new-edge-container {\n pointer-events: none;\n}\n\n.g3p-new-edge-origin {\n fill: var(--g3p-edge-color, #64748b);\n stroke: none;\n}\n\n.g3p-new-edge-line {\n stroke: var(--g3p-edge-color, #64748b);\n stroke-width: 2;\n stroke-dasharray: 6 4;\n stroke-linecap: round;\n fill: none;\n animation: g3p-dash-animation 0.5s linear infinite;\n}\n\n.g3p-new-edge-end {\n fill: var(--g3p-edge-color, #64748b);\n stroke: white;\n stroke-width: 1.5;\n}\n\n@keyframes g3p-dash-animation {\n to {\n stroke-dashoffset: -10;\n }\n}\n\n/* ==================== Edit Mode Hover States ==================== */\n\n.g3p-node-container.g3p-drop-target .g3p-node-border {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n.g3p-node-port.g3p-drop-target {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n/* ==================== Modals ==================== */\n\n.g3p-modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.g3p-modal-dialog {\n background: var(--g3p-bg-node);\n border: 1px solid var(--g3p-border);\n border-radius: 8px;\n box-shadow: 0 4px 20px var(--g3p-shadow);\n min-width: 280px;\n max-width: 400px;\n}\n\n.g3p-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--g3p-border);\n}\n\n.g3p-modal-title {\n font-weight: 600;\n font-size: 14px;\n color: var(--g3p-text);\n}\n\n.g3p-modal-close {\n background: none;\n border: none;\n font-size: 20px;\n color: var(--g3p-text-muted);\n cursor: pointer;\n padding: 0;\n line-height: 1;\n}\n\n.g3p-modal-close:hover {\n color: var(--g3p-text);\n}\n\n.g3p-modal-body {\n padding: 16px;\n}\n\n.g3p-modal-field {\n margin-bottom: 12px;\n}\n\n.g3p-modal-field:last-child {\n margin-bottom: 0;\n}\n\n.g3p-modal-label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--g3p-text-muted);\n margin-bottom: 4px;\n}\n\n.g3p-modal-input,\n.g3p-modal-select {\n width: 100%;\n padding: 8px 10px;\n font-size: 13px;\n border: 1px solid var(--g3p-border);\n border-radius: 4px;\n background: var(--g3p-bg);\n color: var(--g3p-text);\n box-sizing: border-box;\n}\n\n.g3p-modal-input:focus,\n.g3p-modal-select:focus {\n outline: none;\n border-color: var(--g3p-border-selected);\n}\n\n.g3p-modal-footer {\n padding: 12px 16px;\n border-top: 1px solid var(--g3p-border);\n}\n\n.g3p-modal-buttons {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.g3p-modal-spacer {\n flex: 1;\n}\n\n.g3p-modal-btn {\n padding: 6px 12px;\n font-size: 13px;\n font-weight: 500;\n border-radius: 4px;\n cursor: pointer;\n border: 1px solid transparent;\n transition: all 0.15s ease;\n}\n\n.g3p-modal-btn-primary {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n.g3p-modal-btn-primary:hover {\n filter: brightness(1.1);\n}\n\n.g3p-modal-btn-secondary {\n background: var(--g3p-bg);\n border-color: var(--g3p-border);\n color: var(--g3p-text);\n}\n\n.g3p-modal-btn-secondary:hover {\n background: var(--g3p-bg-secondary);\n}\n\n.g3p-modal-btn-danger {\n background: #ef4444;\n color: white;\n}\n\n.g3p-modal-btn-danger:hover {\n background: #dc2626;\n}","import { Pos, Orientation, ScreenPos, CanvasPos, GraphPos, screenPos, canvasPos, graphPos } from '../common'\nimport { Node } from './node'\nimport { Seg } from './seg'\nimport { Graph } from '../graph/graph'\nimport { CanvasOptions, RenderNode, MountNode, ThemeVars, NewEdge, NewNode } from '../api/options'\nimport { NodeId, NodeKey, PublicNodeData, PortId, Node as GraphNode } from '../graph/node'\nimport { SegId, Seg as GraphSeg } from '../graph/seg'\nimport { logger } from '../log'\nimport { markerDefs } from './marker'\nimport { EditMode } from './editMode'\nimport { renderNewEdge } from './newEdge'\nimport { NewNodeModal, EditNodeModal, EditEdgeModal } from './modal'\nimport { API, EditNodeProps, EditEdgeProps } from '../api/api'\n\nimport styles from './styles.css?raw'\n\nconst log = logger('canvas')\n\ntype ViewportTransform = {\n x: number\n y: number\n scale: number\n}\n\ntype Bounds = {\n min: Pos\n max: Pos\n}\n\ntype CanvasData<N, E> = Required<Omit<CanvasOptions<N>, 'mountNode'>> & {\n renderNode: RenderNode<N>\n dummyNodeSize: number\n orientation: Orientation\n mountNode?: MountNode<N>\n}\n\nexport interface Canvas<N, E> extends CanvasData<N, E> { }\n\nexport class Canvas<N, E> {\n container?: HTMLElement\n root?: SVGElement\n group?: SVGElement\n transform!: ViewportTransform\n bounds!: Bounds\n measurement?: HTMLElement\n allNodes!: Map<NodeKey, Node>\n curNodes!: Map<NodeId, Node>\n curSegs!: Map<SegId, Seg>\n updating!: boolean\n\n // Unique marker ID prefix for this canvas instance\n markerPrefix: string\n\n // Dynamic style element for this instance (for cleanup)\n private dynamicStyleEl?: HTMLStyleElement\n\n // Pan-zoom state\n private panScale: { x: number, y: number } | null = null\n private zoomControls?: HTMLElement\n\n // Edit mode state machine\n editMode!: EditMode\n api: API<N, E>\n\n // New-edge visual element\n private newEdgeEl?: SVGElement\n\n // Pending drag state (for double-click debounce)\n private pendingDrag: { timeout: number, nodeId: string, startGraph: GraphPos, portId?: string } | null = null\n\n constructor(api: API<N, E>, options: CanvasData<N, E>) {\n Object.assign(this, options)\n this.api = api\n this.reset()\n // Generate unique marker prefix based on root ID (sanitize for use in IDs)\n this.markerPrefix = api.root.replace(/[^a-zA-Z0-9-_]/g, '-')\n this.createMeasurementContainer()\n this.createCanvasContainer()\n if (this.panZoom) this.setupPanZoom()\n }\n\n reset() {\n this.allNodes = new Map()\n this.curNodes = new Map()\n this.curSegs = new Map()\n this.updating = false\n this.bounds = { min: { x: 0, y: 0 }, max: { x: 0, y: 0 } }\n this.transform = { x: 0, y: 0, scale: 1 }\n this.editMode = new EditMode()\n this.editMode.editable = this.editable\n if (this.group) this.group.innerHTML = ''\n }\n\n private createMeasurementContainer() {\n this.measurement = document.createElement('div')\n this.measurement.style.cssText = `\n position: absolute;\n left: -9999px;\n top: -9999px;\n visibility: hidden;\n pointer-events: none;\n `\n document.body.appendChild(this.measurement)\n }\n\n getNode(key: NodeKey): Node {\n const node = this.allNodes.get(key)\n if (!node) throw new Error(`node not found: ${key}`)\n return node\n }\n\n update() {\n let bx0 = Infinity, by0 = Infinity\n let bx1 = -Infinity, by1 = -Infinity\n for (const node of this.curNodes.values()) {\n const { x, y } = node.pos!\n const { w, h } = node.data!.dims!\n const nx0 = x, nx1 = x + w\n const ny0 = y, ny1 = y + h\n bx0 = Math.min(bx0, nx0)\n by0 = Math.min(by0, ny0)\n bx1 = Math.max(bx1, nx1)\n by1 = Math.max(by1, ny1)\n }\n this.bounds = { min: { x: bx0, y: by0 }, max: { x: bx1, y: by1 } }\n this.root!.setAttribute('viewBox', this.viewBox())\n }\n\n addNode(gnode: GraphNode) {\n if (this.curNodes.has(gnode.id))\n throw new Error('node already exists')\n const { key } = gnode\n let node: Node\n if (gnode.isDummy) {\n node = new Node(this, gnode, true)\n node.renderContainer()\n this.allNodes.set(key, node)\n } else {\n if (!this.allNodes.has(key))\n throw new Error('node has not been measured')\n node = this.getNode(key)\n }\n this.curNodes.set(gnode.id, node)\n node.append()\n node.setPos(gnode.pos!)\n }\n\n updateNode(gnode: GraphNode) {\n if (gnode.isDummy) throw new Error('dummy node cannot be updated')\n const node = this.getNode(gnode.key)\n const cur = this.curNodes.get(gnode.id)\n if (cur) cur.remove()\n this.curNodes.set(gnode.id, node)\n node.append()\n }\n\n deleteNode(gnode: GraphNode) {\n const node = this.getNode(gnode.key)\n this.curNodes.delete(gnode.id)\n node.remove()\n }\n\n addSeg(gseg: GraphSeg, g: Graph) {\n if (this.curSegs.has(gseg.id))\n throw new Error('seg already exists')\n const seg = new Seg(this, gseg, g)\n this.curSegs.set(gseg.id, seg)\n seg.append()\n }\n\n updateSeg(gseg: GraphSeg, g: Graph) {\n const seg = this.curSegs.get(gseg.id)\n if (!seg) throw new Error('seg not found')\n seg.update(gseg, g)\n }\n\n deleteSeg(gseg: GraphSeg) {\n const seg = this.curSegs.get(gseg.id)\n if (!seg) throw new Error('seg not found')\n this.curSegs.delete(gseg.id)\n seg.remove()\n }\n\n async measureNodes(nodes: PublicNodeData[]): Promise<Map<any, Node>> {\n const newNodes: Map<any, Node> = new Map()\n for (const data of nodes) {\n const node = new Node(this, data)\n newNodes.set(data.data, node)\n this.measurement!.appendChild(node.content)\n }\n if (this.mountNode) {\n for (const node of newNodes.values()) {\n if (node.innerContent) {\n node.cleanup = this.mountNode(node.data!.data, node.innerContent) ?? undefined\n }\n }\n }\n await new Promise(requestAnimationFrame)\n const isVertical = this.orientation === 'TB' || this.orientation === 'BT'\n for (const node of newNodes.values()) {\n node.measure(isVertical)\n const { id, version } = node.data!\n const key = `k:${id}:${version}`\n this.allNodes.set(key, node)\n node.renderContainer()\n }\n this.measurement!.innerHTML = ''\n return newNodes\n }\n\n // ========== Mouse event handlers ==========\n\n private onClick(e: MouseEvent) {\n const hit = this.hitTest(e.clientX, e.clientY)\n if (hit.type === 'node') {\n this.api.handleClickNode(hit.node.data.id)\n } else if (hit.type === 'edge') {\n this.api.handleClickEdge(hit.segId)\n }\n }\n\n private onDoubleClick(e: MouseEvent) {\n // Cancel any pending drag\n if (this.pendingDrag) {\n window.clearTimeout(this.pendingDrag.timeout)\n this.pendingDrag = null\n }\n if (!this.editMode.editable) return\n const hit = this.hitTest(e.clientX, e.clientY)\n if (hit.type === 'node') {\n if (hit.node.isDummy) return\n this.api.handleEditNode(hit.node.data.id)\n } else if (hit.type === 'edge') {\n this.api.handleEditEdge(hit.segId)\n } else {\n this.api.handleNewNode()\n }\n }\n\n // ========== Built-in Modals ==========\n\n /** Show the new node modal */\n showNewNodeModal(callback: (data: NewNode) => void) {\n const nodeTypes = Object.keys(this.nodeTypes)\n const fields = this.api.getNodeFields()\n const modal = new NewNodeModal({\n nodeTypes: nodeTypes.length > 0 ? nodeTypes : undefined,\n fields: fields.size > 0 ? fields : undefined,\n onSubmit: (data) => { callback(data) }\n })\n modal.show(document.body)\n }\n\n /** Show the edit node modal */\n showEditNodeModal(node: Record<string, any>, callback: (data: Record<string, any>) => void) {\n const nodeTypes = Object.keys(this.nodeTypes)\n const fields = this.api.getNodeFields()\n const modal = new EditNodeModal({\n node,\n nodeTypes: nodeTypes.length > 0 ? nodeTypes : undefined,\n fields: fields.size > 0 ? fields : undefined,\n onSubmit: (data) => { callback(data) },\n onDelete: () => { this.api.handleDeleteNode(node.id) }\n })\n modal.show(document.body)\n }\n\n /** Show the edit edge modal */\n showEditEdgeModal(edge: EditEdgeProps, callback: (data: EditEdgeProps) => void) {\n const modal = new EditEdgeModal({\n edge,\n edgeTypes: Object.keys(this.edgeTypes),\n onSubmit: callback,\n onDelete: () => { this.api.handleDeleteEdge(edge.id) },\n })\n modal.show(document.body)\n }\n\n private onContextMenu(e: MouseEvent) {\n // Context menu - could be used for right-click menus\n }\n\n private groupTransform(): string {\n return `translate(${this.transform.x}, ${this.transform.y}) scale(${this.transform.scale})`\n }\n\n private viewBox(): string {\n const p = this.padding\n const x = this.bounds.min.x - p\n const y = this.bounds.min.y - p\n const w = this.bounds.max.x - this.bounds.min.x + p * 2\n const h = this.bounds.max.y - this.bounds.min.y + p * 2\n return `${x} ${y} ${w} ${h}`\n }\n\n private generateDynamicStyles(): string {\n let css = ''\n const scope = `[data-g3p-instance=\"${this.markerPrefix}\"]`\n\n // Global theme overrides (scoped to this instance)\n css += themeToCSS(this.theme, scope)\n\n // Node type styles (scoped to this instance)\n for (const [type, vars] of Object.entries(this.nodeTypes)) {\n css += themeToCSS(vars, `${scope} .g3p-node-type-${type}`, 'node')\n }\n\n // Edge type styles (scoped to this instance)\n for (const [type, vars] of Object.entries(this.edgeTypes)) {\n css += themeToCSS(vars, `${scope} .g3p-edge-type-${type}`)\n }\n\n return css\n }\n\n private createCanvasContainer() {\n // Inject base styles once\n if (!document.getElementById('g3p-styles')) {\n const baseStyleEl = document.createElement('style')\n baseStyleEl.id = 'g3p-styles'\n baseStyleEl.textContent = styles\n document.head.appendChild(baseStyleEl)\n }\n\n // Inject dynamic styles (node/edge types) scoped to this canvas instance\n const dynamicStyles = this.generateDynamicStyles()\n if (dynamicStyles) {\n // Remove any previous dynamic styles for this instance\n this.dynamicStyleEl?.remove()\n this.dynamicStyleEl = document.createElement('style')\n this.dynamicStyleEl.id = `g3p-styles-${this.markerPrefix}`\n this.dynamicStyleEl.textContent = dynamicStyles\n document.head.appendChild(this.dynamicStyleEl)\n }\n\n // Build color mode class\n const colorModeClass = this.colorMode !== 'system' ? `g3p-${this.colorMode}` : ''\n\n this.container = (<div\n className={`g3p-canvas-container ${colorModeClass}`.trim()}\n data-g3p-instance={this.markerPrefix}\n ref={(el: HTMLElement) => this.container = el}\n onContextMenu={this.onContextMenu.bind(this)}\n >\n <svg\n ref={(el: SVGElement) => this.root = el}\n className=\"g3p-canvas-root\"\n width={this.width}\n height={this.height}\n viewBox={this.viewBox()}\n preserveAspectRatio=\"xMidYMid meet\"\n onClick={this.onClick.bind(this)}\n onDblClick={this.onDoubleClick.bind(this)}\n >\n <defs>\n {Object.values(markerDefs).map(marker => marker(this.markerSize, false, this.markerPrefix))}\n {Object.values(markerDefs).map(marker => marker(this.markerSize, true, this.markerPrefix))}\n </defs>\n <g\n ref={(el: SVGElement) => this.group = el}\n transform={this.groupTransform()}\n />\n </svg>\n </div>) as HTMLElement\n }\n\n // ==================== Pan-Zoom ====================\n\n private setupPanZoom() {\n // Mouse wheel zoom\n this.container!.addEventListener('wheel', this.onWheel.bind(this), { passive: false })\n\n // Pan with left mouse button\n this.container!.addEventListener('mousedown', this.onMouseDown.bind(this))\n document.addEventListener('mousemove', this.onMouseMove.bind(this))\n document.addEventListener('mouseup', this.onMouseUp.bind(this))\n\n // Keyboard handler for escape to cancel new-edge mode\n document.addEventListener('keydown', this.onKeyDown.bind(this))\n\n // Create zoom controls\n this.createZoomControls()\n }\n\n private onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape' && this.editMode.isCreatingEdge) {\n this.endNewEdge(true) // cancelled\n }\n }\n\n /** Convert screen coordinates to canvas-relative coordinates */\n private screenToCanvas(screen: ScreenPos): CanvasPos {\n const rect = this.container!.getBoundingClientRect()\n return canvasPos(screen.x - rect.left, screen.y - rect.top)\n }\n\n /** Convert canvas coordinates to graph coordinates */\n private canvasToGraph(canvas: CanvasPos): GraphPos {\n const vb = this.currentViewBox()\n const { scale, offsetX, offsetY } = this.getEffectiveScale()\n\n // Convert canvas position to graph position, accounting for centering\n return graphPos(\n vb.x - offsetX + canvas.x * scale,\n vb.y - offsetY + canvas.y * scale\n )\n }\n\n /** Convert screen coordinates to graph coordinates */\n private screenToGraph(screen: ScreenPos): GraphPos {\n const canvas = this.screenToCanvas(screen)\n return this.canvasToGraph(canvas)\n }\n\n /**\n * Get the effective scale from canvas pixels to graph units,\n * accounting for preserveAspectRatio=\"xMidYMid meet\" which uses\n * the smaller scale (to fit) and centers the content.\n */\n private getEffectiveScale(): { scale: number, offsetX: number, offsetY: number } {\n const vb = this.currentViewBox()\n const rect = this.container!.getBoundingClientRect()\n\n const scaleX = vb.w / rect.width\n const scaleY = vb.h / rect.height\n\n // \"meet\" uses the larger scale value (smaller zoom) to fit content\n const scale = Math.max(scaleX, scaleY)\n\n // Calculate offset due to centering (xMidYMid)\n const actualW = rect.width * scale\n const actualH = rect.height * scale\n const offsetX = (actualW - vb.w) / 2\n const offsetY = (actualH - vb.h) / 2\n\n return { scale, offsetX, offsetY }\n }\n\n /** Get current viewBox as an object */\n private currentViewBox(): { x: number, y: number, w: number, h: number } {\n const p = this.padding\n const t = this.transform\n const baseX = this.bounds.min.x - p\n const baseY = this.bounds.min.y - p\n const baseW = this.bounds.max.x - this.bounds.min.x + p * 2\n const baseH = this.bounds.max.y - this.bounds.min.y + p * 2\n\n // Apply transform: scale around center, then translate\n const cx = baseX + baseW / 2\n const cy = baseY + baseH / 2\n const w = baseW / t.scale\n const h = baseH / t.scale\n const x = cx - w / 2 - t.x\n const y = cy - h / 2 - t.y\n\n return { x, y, w, h }\n }\n\n private onWheel(e: WheelEvent) {\n e.preventDefault()\n\n const zoomFactor = 1.1\n const delta = e.deltaY > 0 ? 1 / zoomFactor : zoomFactor\n\n // Get cursor position in canvas coordinates\n const screenCursor = screenPos(e.clientX, e.clientY)\n const canvasCursor = this.screenToCanvas(screenCursor)\n\n // Get cursor position in graph coordinates BEFORE zoom\n const graphCursor = this.canvasToGraph(canvasCursor)\n\n // Apply zoom\n const oldScale = this.transform.scale\n const newScale = Math.max(0.1, Math.min(10, oldScale * delta))\n this.transform.scale = newScale\n\n // Get cursor position in graph coordinates AFTER zoom\n const newGraphCursor = this.canvasToGraph(canvasCursor)\n\n // Adjust translation to keep cursor at same graph position\n this.transform.x += (newGraphCursor.x - graphCursor.x)\n this.transform.y += (newGraphCursor.y - graphCursor.y)\n\n this.applyTransform()\n }\n\n private onMouseDown(e: MouseEvent) {\n // Only handle left button\n if (e.button !== 0) return\n if ((e.target as HTMLElement).closest('.g3p-zoom-controls')) return\n\n const hit = this.hitTest(e.clientX, e.clientY)\n\n // In editable mode, schedule new-edge from node or port (not dummy nodes)\n // Use a timeout to allow double-click to cancel the drag\n if (this.editMode.editable && (hit.type === 'node' || hit.type === 'port')) {\n const node = hit.node\n if (node.isDummy) return // Dummy nodes can't be edge endpoints\n\n e.preventDefault()\n e.stopPropagation()\n const startGraph = this.screenToGraph(hit.center)\n const portId = hit.type === 'port' ? hit.port : undefined\n\n // Schedule drag start after a short delay (to allow double-click)\n this.pendingDrag = {\n timeout: window.setTimeout(() => {\n if (this.pendingDrag) {\n this.startNewEdge(this.pendingDrag.nodeId, this.pendingDrag.startGraph, this.pendingDrag.portId)\n this.pendingDrag = null\n }\n }, 200),\n nodeId: node.data.id,\n startGraph,\n portId,\n }\n return\n }\n\n // Start panning on canvas\n if (hit.type === 'canvas' || hit.type === 'edge') {\n const startCanvas = this.screenToCanvas(screenPos(e.clientX, e.clientY))\n this.editMode.startPan(startCanvas, { ...this.transform })\n\n const { scale } = this.getEffectiveScale()\n this.panScale = { x: scale, y: scale }\n\n this.container!.style.cursor = 'grabbing'\n e.preventDefault()\n }\n }\n\n private onMouseMove(e: MouseEvent) {\n // Handle new-edge mode\n if (this.editMode.isCreatingEdge) {\n const screenCursor = screenPos(e.clientX, e.clientY)\n const canvasCursor = this.screenToCanvas(screenCursor)\n const graphCursor = this.canvasToGraph(canvasCursor)\n this.editMode.updateNewEdgePosition(graphCursor)\n this.updateNewEdgeVisual()\n\n // Detect hover target using elementFromPoint\n this.detectHoverTarget(e.clientX, e.clientY)\n return\n }\n\n // Handle panning\n if (!this.editMode.isPanning || !this.panScale) return\n\n const panState = this.editMode.state\n if (panState.type !== 'panning') return\n\n const current = this.screenToCanvas(screenPos(e.clientX, e.clientY))\n\n // Calculate delta in canvas pixels\n const dx = current.x - panState.startCanvas.x\n const dy = current.y - panState.startCanvas.y\n\n // Update transform using scale captured at pan start\n this.transform.x = panState.startTransform.x + dx * this.panScale.x\n this.transform.y = panState.startTransform.y + dy * this.panScale.y\n\n this.applyTransform()\n }\n\n private onMouseUp(e: MouseEvent) {\n // Cancel any pending drag that didn't start\n if (this.pendingDrag) {\n window.clearTimeout(this.pendingDrag.timeout)\n this.pendingDrag = null\n }\n\n // Handle new-edge mode\n if (this.editMode.isCreatingEdge) {\n this.endNewEdge(false)\n return\n }\n\n // Handle panning\n if (!this.editMode.isPanning) return\n this.editMode.reset()\n this.panScale = null\n this.container!.style.cursor = ''\n }\n\n private applyTransform() {\n const vb = this.currentViewBox()\n this.root!.setAttribute('viewBox', `${vb.x} ${vb.y} ${vb.w} ${vb.h}`)\n this.updateZoomLevel()\n }\n\n private createZoomControls() {\n this.zoomControls = (<div className=\"g3p-zoom-controls\">\n <button className=\"g3p-zoom-btn\" onClick={() => this.zoomIn()}>+</button>\n <div className=\"g3p-zoom-level\" id=\"g3p-zoom-level\">100%</div>\n <button className=\"g3p-zoom-btn\" onClick={() => this.zoomOut()}>−</button>\n <button className=\"g3p-zoom-btn g3p-zoom-reset\" onClick={() => this.zoomReset()}>⟲</button>\n </div>) as HTMLElement\n\n this.container!.appendChild(this.zoomControls)\n }\n\n private updateZoomLevel() {\n const level = this.container!.querySelector('#g3p-zoom-level')\n if (level) {\n level.textContent = `${Math.round(this.transform.scale * 100)}%`\n }\n }\n\n zoomIn() {\n this.transform.scale = Math.min(10, this.transform.scale * 1.2)\n this.applyTransform()\n }\n\n zoomOut() {\n this.transform.scale = Math.max(0.1, this.transform.scale / 1.2)\n this.applyTransform()\n }\n\n zoomReset() {\n this.transform = { x: 0, y: 0, scale: 1 }\n this.applyTransform()\n }\n\n // ==================== New-Edge Mode ====================\n\n /** Start creating a new edge from a node */\n startNewEdge(sourceNodeId: string, startGraph: GraphPos, sourcePortId?: string) {\n this.editMode.startNewEdge(sourceNodeId, startGraph, sourcePortId)\n this.updateNewEdgeVisual()\n this.container!.style.cursor = 'crosshair'\n }\n\n /** Update the new-edge visual during drag */\n private updateNewEdgeVisual() {\n const state = this.editMode.getNewEdgeState()\n if (!state) {\n this.removeNewEdgeVisual()\n return\n }\n\n // Remove old element\n if (this.newEdgeEl) {\n this.newEdgeEl.remove()\n }\n\n // Create new element\n this.newEdgeEl = renderNewEdge({\n start: state.startGraph,\n end: state.currentGraph,\n })\n\n this.group!.appendChild(this.newEdgeEl)\n }\n\n /** Remove the new-edge visual */\n private removeNewEdgeVisual() {\n if (this.newEdgeEl) {\n this.newEdgeEl.remove()\n this.newEdgeEl = undefined\n }\n }\n\n /** Complete or cancel the new-edge creation */\n endNewEdge(cancelled: boolean = false) {\n const state = this.editMode.getNewEdgeState()\n if (!state) return\n\n if (!cancelled) {\n const { target, source } = state\n if (target?.type == 'node') {\n this.api.handleAddEdge({ id: '', source, target })\n } else {\n this.api.handleNewNodeFrom(source)\n }\n }\n\n this.removeNewEdgeVisual()\n this.clearDropTargetHighlight()\n this.editMode.reset()\n this.container!.style.cursor = ''\n }\n\n /** Find node data by internal ID */\n private findNodeDataById(nodeId: string): any | null {\n for (const node of this.curNodes.values()) {\n if (node.data?.id === nodeId) {\n return node.data.data\n }\n }\n return null\n }\n\n /** Set hover target for new-edge mode */\n setNewEdgeHoverTarget(id: string, port?: string) {\n // Clear previous highlight\n this.clearDropTargetHighlight()\n this.editMode.setHoverTarget({ type: 'node', id, port })\n if (port) {\n const portEl = this.container?.querySelector(`.g3p-node-port[data-node-id=\"${id}\"][data-port-id=\"${port}\"]`)\n if (portEl) portEl.classList.add('g3p-drop-target')\n } else {\n const node = this.curNodes.get(id)\n if (node?.container) node.container.classList.add('g3p-drop-target')\n }\n }\n\n /** Clear hover target for new-edge mode */\n clearNewEdgeHoverTarget() {\n this.clearDropTargetHighlight()\n this.editMode.setHoverTarget(null)\n }\n\n /** Remove drop target highlight from all elements */\n private clearDropTargetHighlight() {\n // Clear from nodes\n for (const node of this.curNodes.values()) {\n node.container?.classList.remove('g3p-drop-target')\n }\n // Clear from ports\n this.container?.querySelectorAll('.g3p-drop-target').forEach(el => {\n el.classList.remove('g3p-drop-target')\n })\n }\n\n /** Detect hover target during new-edge drag using elementFromPoint */\n private detectHoverTarget(clientX: number, clientY: number) {\n // Temporarily hide the new-edge visual so it doesn't block hit testing\n if (this.newEdgeEl) {\n this.newEdgeEl.style.display = 'none'\n }\n\n const el = document.elementFromPoint(clientX, clientY)\n\n // Restore the new-edge visual\n if (this.newEdgeEl) {\n this.newEdgeEl.style.display = ''\n }\n\n if (!el) {\n this.clearNewEdgeHoverTarget()\n return\n }\n\n // Check for port first (more specific)\n const portEl = el.closest('.g3p-node-port')\n if (portEl) {\n const nodeId = portEl.getAttribute('data-node-id')\n const portId = portEl.getAttribute('data-port-id')\n if (nodeId && portId) {\n const node = this.curNodes.get(nodeId)\n if (node && !node.isDummy) {\n this.setNewEdgeHoverTarget(nodeId, portId)\n return\n }\n }\n }\n\n // Check for node container\n const nodeEl = el.closest('.g3p-node-container')\n if (nodeEl) {\n const nodeId = nodeEl.getAttribute('data-node-id')\n if (nodeId) {\n const node = this.curNodes.get(nodeId)\n if (node && !node.isDummy) {\n this.setNewEdgeHoverTarget(node.data.id)\n return\n }\n }\n }\n\n // Not over a node or port\n this.clearNewEdgeHoverTarget()\n }\n\n // ==================== Hit Testing ====================\n\n /** Result of a hit test */\n private hitTest(clientX: number, clientY: number): HitTestResult {\n const el = document.elementFromPoint(clientX, clientY)\n if (!el) return { type: 'canvas' }\n\n const getCenter = (el: Element) => {\n const rect = el.getBoundingClientRect()\n return screenPos(rect.left + rect.width / 2, rect.top + rect.height / 2)\n }\n\n // Check for port first (more specific)\n const portEl = el.closest('.g3p-node-port')\n if (portEl) {\n const nodeId = portEl.getAttribute('data-node-id')\n const portId = portEl.getAttribute('data-port-id')\n if (nodeId && portId) {\n const center = getCenter(portEl)\n const node = this.curNodes.get(nodeId)\n if (node) {\n return { type: 'port', node, port: portId, center }\n }\n }\n }\n\n // Check for node\n const nodeEl = el.closest('.g3p-node-container')\n if (nodeEl) {\n const nodeId = nodeEl.getAttribute('data-node-id')\n if (nodeId) {\n const borderEl = el.closest('.g3p-node-border')\n const center = getCenter(borderEl ?? nodeEl)\n const node = this.curNodes.get(nodeId)\n if (node) {\n return { type: 'node', node, center }\n }\n }\n }\n\n // Check for edge (segment)\n const edgeEl = el.closest('.g3p-seg-container')\n if (edgeEl) {\n const segId = edgeEl.getAttribute('data-edge-id')\n if (segId) {\n return { type: 'edge', segId }\n }\n }\n\n return { type: 'canvas' }\n }\n\n /** Update theme and type styles dynamically */\n updateStyles(options: { theme?: ThemeVars, nodeTypes?: Record<string, ThemeVars>, edgeTypes?: Record<string, ThemeVars> }) {\n if (options.theme !== undefined) this.theme = options.theme\n if (options.nodeTypes !== undefined) this.nodeTypes = options.nodeTypes\n if (options.edgeTypes !== undefined) this.edgeTypes = options.edgeTypes\n\n // Regenerate and replace dynamic styles\n const dynamicStyles = this.generateDynamicStyles()\n if (dynamicStyles) {\n if (!this.dynamicStyleEl) {\n this.dynamicStyleEl = document.createElement('style')\n this.dynamicStyleEl.id = `g3p-styles-${this.markerPrefix}`\n document.head.appendChild(this.dynamicStyleEl)\n }\n this.dynamicStyleEl.textContent = dynamicStyles\n } else if (this.dynamicStyleEl) {\n // No dynamic styles needed, remove the element\n this.dynamicStyleEl.remove()\n this.dynamicStyleEl = undefined\n }\n }\n\n /** Update color mode without recreating the canvas */\n setColorMode(colorMode: 'light' | 'dark' | 'system') {\n if (!this.container) return\n this.colorMode = colorMode\n // Remove existing color mode classes\n this.container.classList.remove('g3p-light', 'g3p-dark')\n // Add new color mode class if not system\n if (colorMode !== 'system') {\n this.container.classList.add(`g3p-${colorMode}`)\n }\n }\n\n /** Cleanup resources when the canvas is destroyed */\n destroy() {\n this.dynamicStyleEl?.remove()\n this.dynamicStyleEl = undefined\n this.measurement?.remove()\n this.measurement = undefined\n }\n}\n\n/** Hit test result types */\ntype HitTestResult =\n | { type: 'canvas' }\n | { type: 'node'; node: Node, center: ScreenPos }\n | { type: 'port'; node: Node; port: string, center: ScreenPos }\n | { type: 'edge'; segId: string }\n\n/** Maps ThemeVars property names to CSS variable names */\nconst themeVarMap: Partial<Record<keyof ThemeVars, string>> = {\n // Canvas\n bg: '--g3p-bg',\n shadow: '--g3p-shadow',\n // Node\n border: '--g3p-border',\n borderHover: '--g3p-border-hover',\n borderSelected: '--g3p-border-selected',\n text: '--g3p-text',\n textMuted: '--g3p-text-muted',\n // Port\n bgHover: '--g3p-port-bg-hover',\n // Edge\n color: '--g3p-edge-color',\n}\n\nfunction themeToCSS(theme: ThemeVars, selector: string, prefix: string = ''): string {\n const entries = Object.entries(theme).filter(([_, v]) => v !== undefined)\n if (!entries.length) return ''\n\n let css = `${selector} {\\n`\n for (const [key, value] of entries) {\n let cssVar = themeVarMap[key as keyof ThemeVars]\n // Handle 'bg' specially based on context (node vs port)\n if (key === 'bg' && prefix === 'node') {\n cssVar = '--g3p-bg-node'\n } else if (key === 'bg' && prefix === 'port') {\n cssVar = '--g3p-port-bg'\n }\n if (cssVar) {\n css += ` ${cssVar}: ${value};\\n`\n }\n }\n css += '}\\n'\n return css\n}\n","import { NodeProps } from '../api/options'\n\nexport function renderNode(node: any, props?: NodeProps<any>): HTMLElement {\n if (typeof node == 'string') node = { id: node }\n\n const title = node?.title ?? props?.title ?? node?.label ?? node?.name ?? node?.text ?? props?.text ?? node?.id ?? '?'\n const detail = node?.detail ?? node?.description ?? node?.subtitle\n\n return (\n <div className=\"g3p-node-default\">\n <div className=\"g3p-node-title\">{title}</div>\n {detail && (\n <div className=\"g3p-node-detail\">{detail}</div>\n )}\n </div>\n ) as HTMLElement\n}\n","import { renderNode } from '../canvas/render-node'\nimport {\n APIOptions,\n GraphOptions,\n CanvasOptions,\n PropsOptions,\n NodeProps,\n EdgeProps,\n PortProps,\n} from './options'\n\nexport type Defaults<N, E> = {\n graph: Required<GraphOptions>\n // mountNode has no sensible default so it is kept optional\n canvas: Required<Omit<CanvasOptions<N>, 'mountNode'>>\n props: PropsOptions<N, E>\n}\n\nexport function applyDefaults<N, E>(options?: APIOptions<N, E>): Defaults<N, E> {\n const { graph, canvas, props } = defaults<N, E>()\n return {\n graph: { ...graph, ...options?.graph },\n canvas: { ...canvas, ...options?.canvas },\n props: { ...props, ...options?.props },\n }\n}\n\nfunction defaults<N, E>(): Defaults<N, E> {\n return {\n graph: {\n mergeOrder: ['target', 'source'],\n nodeMargin: 15,\n dummyNodeSize: 15,\n nodeAlign: 'natural',\n edgeSpacing: 10,\n turnRadius: 10,\n orientation: 'TB',\n layerMargin: 5,\n alignIterations: 5,\n alignThreshold: 10,\n separateTrackSets: true,\n markerSize: 10,\n layoutSteps: null,\n },\n canvas: {\n renderNode,\n width: '100%',\n height: '100%',\n padding: 20,\n editable: false,\n panZoom: true,\n markerSize: 10,\n colorMode: 'system',\n theme: {},\n nodeTypes: {},\n edgeTypes: {},\n },\n props: {},\n }\n}","import { Update } from \"./options\"\n\nexport class Updater<N, E> {\n update: Update<N, E>\n\n constructor() {\n this.update = {\n addNodes: [],\n removeNodes: [],\n updateNodes: [],\n addEdges: [],\n removeEdges: [],\n updateEdges: [],\n }\n }\n\n describe(desc: string): Updater<N, E> {\n this.update.description = desc\n return this\n }\n\n addNode(node: any): Updater<N, E> {\n this.update.addNodes!.push(node)\n return this\n }\n\n addNodes(...nodes: any[]): Updater<N, E> {\n this.update.addNodes!.push(...nodes)\n return this\n }\n\n deleteNode(node: any): Updater<N, E> {\n this.update.removeNodes!.push(node)\n return this\n }\n\n deleteNodes(...nodes: any[]): Updater<N, E> {\n this.update.removeNodes!.push(...nodes)\n return this\n }\n\n updateNode(node: any): Updater<N, E> {\n this.update.updateNodes!.push(node)\n return this\n }\n\n updateNodes(...nodes: any[]): Updater<N, E> {\n this.update.updateNodes!.push(...nodes)\n return this\n }\n\n addEdge(edge: any): Updater<N, E> {\n this.update.addEdges!.push(edge)\n return this\n }\n\n addEdges(...edges: any[]): Updater<N, E> {\n this.update.addEdges!.push(...edges)\n return this\n }\n\n deleteEdge(edge: any): Updater<N, E> {\n this.update.removeEdges!.push(edge)\n return this\n }\n\n deleteEdges(...edges: any[]): Updater<N, E> {\n this.update.removeEdges!.push(...edges)\n return this\n }\n\n updateEdge(edge: any): Updater<N, E> {\n this.update.updateEdges!.push(edge)\n return this\n }\n\n updateEdges(...edges: any[]): Updater<N, E> {\n this.update.updateEdges!.push(...edges)\n return this\n }\n\n static add<N, E>(nodes: N[], edges: E[]): Updater<N, E> {\n const updater = new Updater<N, E>()\n updater.update.addNodes = nodes\n updater.update.addEdges = edges\n return updater\n }\n}\n","import { Update } from './options'\nimport { API } from './api'\n\nexport type SnapshotMessage<N, E> = {\n type: 'snapshot'\n nodes: N[]\n edges: E[]\n description?: string\n}\n\nexport type UpdateMessage<N, E> = {\n type: 'update'\n description?: string\n} & Update<N, E>\n\nexport type HistoryMessage<N, E> = {\n type: 'history'\n history: Update<N, E>[]\n}\n\nexport type IngestMessage<N, E> =\n | SnapshotMessage<N, E>\n | UpdateMessage<N, E>\n | HistoryMessage<N, E>\n\n/**\n * Ingest class handles applying ingest messages to an API instance.\n * This is the core ingestion functionality, separate from UI concerns.\n */\nexport class Ingest<N, E> {\n constructor(public api: API<N, E>) { }\n\n /**\n * Apply an incoming ingest message to the API.\n * - snapshot: rebuild state from nodes/edges (clears prior history)\n * - update: apply incremental update\n * - history: initialize from a set of updates (clears prior history)\n */\n async apply(msg: IngestMessage<N, E>): Promise<void> {\n switch (msg.type) {\n case 'snapshot': {\n await this.api.replaceSnapshot(msg.nodes, msg.edges, msg.description)\n break\n }\n case 'update': {\n await this.api.update(u => {\n if (msg.addNodes) u.addNodes(...msg.addNodes)\n if (msg.removeNodes) u.deleteNodes(...msg.removeNodes)\n if (msg.updateNodes) u.updateNodes(...msg.updateNodes)\n if (msg.addEdges) u.addEdges(...msg.addEdges)\n if (msg.removeEdges) u.deleteEdges(...msg.removeEdges)\n if (msg.updateEdges) u.updateEdges(...msg.updateEdges)\n if (msg.description) u.describe(msg.description)\n })\n break\n }\n case 'history': {\n await this.api.replaceHistory(msg.history)\n break\n }\n }\n }\n}\n","import type { IngestMessage } from '../ingest'\n\nexport type WebSocketStatus = 'connecting' | 'connected' | 'reconnecting' | 'closed' | 'error'\nexport type WebSocketStatusListener = (status: WebSocketStatus, detail?: any) => void\nexport type WebSocketSourceArgs<N, E> = {\n url: string\n onMessage: (msg: IngestMessage<N, E>) => void\n onStatus?: WebSocketStatusListener\n reconnectMs?: number\n}\n\nexport class WebSocketSource<N, E> {\n private url: string\n private ws: WebSocket | null = null\n private onMessage: (msg: IngestMessage<N, E>) => void\n private onStatus?: WebSocketStatusListener\n private reconnectMs: number\n private closedByUser = false\n private connectStartTime: number | null = null\n private totalTimeoutMs: number = 10000\n private totalTimeoutTimer: number | null = null\n\n constructor(args: WebSocketSourceArgs<N, E>) {\n this.url = args.url\n this.onMessage = args.onMessage\n this.onStatus = args.onStatus\n this.reconnectMs = args.reconnectMs ?? 1500\n }\n\n connect() {\n this.closedByUser = false\n this.connectStartTime = Date.now()\n this.startTotalTimeout()\n this.open()\n }\n\n disconnect() {\n this.closedByUser = true\n this.clearTotalTimeout()\n if (this.ws) {\n try { this.ws.close() } catch { }\n this.ws = null\n }\n this.onStatus?.('closed')\n }\n\n private startTotalTimeout() {\n this.clearTotalTimeout()\n this.totalTimeoutTimer = window.setTimeout(() => {\n if (!this.closedByUser && this.ws?.readyState !== WebSocket.OPEN) {\n // Total timeout elapsed, abort connection attempts\n this.closedByUser = true\n if (this.ws) {\n try { this.ws.close() } catch { }\n this.ws = null\n }\n this.clearTotalTimeout()\n this.onStatus?.('error', new Error('Connection timeout after 10 seconds'))\n }\n }, this.totalTimeoutMs)\n }\n\n private clearTotalTimeout() {\n if (this.totalTimeoutTimer !== null) {\n clearTimeout(this.totalTimeoutTimer)\n this.totalTimeoutTimer = null\n }\n this.connectStartTime = null\n }\n\n private open() {\n // Check if we've exceeded total timeout\n if (this.connectStartTime && Date.now() - this.connectStartTime >= this.totalTimeoutMs) {\n if (!this.closedByUser) {\n this.closedByUser = true\n this.clearTotalTimeout()\n this.onStatus?.('error', new Error('Connection timeout after 10 seconds'))\n }\n return\n }\n\n this.onStatus?.(this.ws ? 'reconnecting' : 'connecting')\n const ws = new WebSocket(this.url)\n this.ws = ws\n\n ws.onopen = () => {\n this.clearTotalTimeout()\n this.onStatus?.('connected')\n }\n ws.onerror = (e) => {\n // Don't clear timeout on error, let it continue trying until total timeout\n this.onStatus?.('error', e)\n }\n ws.onclose = () => {\n if (this.closedByUser) {\n this.onStatus?.('closed')\n return\n }\n\n // Check if we've exceeded total timeout before reconnecting\n if (this.connectStartTime && Date.now() - this.connectStartTime >= this.totalTimeoutMs) {\n this.closedByUser = true\n this.clearTotalTimeout()\n this.onStatus?.('error', new Error('Connection timeout after 10 seconds'))\n return\n }\n\n this.onStatus?.('reconnecting')\n setTimeout(() => this.open(), this.reconnectMs)\n }\n ws.onmessage = (ev) => {\n const data = typeof ev.data === 'string' ? ev.data : ''\n // Accept either single JSON object or NDJSON lines\n const lines = data.split('\\n').map(l => l.trim()).filter(Boolean)\n for (const line of lines) {\n try {\n const obj = JSON.parse(line)\n this.onMessage(obj)\n } catch {\n // ignore bad lines\n }\n }\n }\n }\n}\n\n","import type { IngestMessage } from '../ingest'\n\nexport type FileStatus = 'idle' | 'opened' | 'reading' | 'error' | 'closed'\nexport type FileStatusListener = (status: FileStatus, detail?: any) => void\nexport type FileSourceArgs<N, E> = {\n url: string\n onMessage: (msg: IngestMessage<N, E>) => void\n onStatus?: FileStatusListener\n intervalMs?: number\n}\n\nexport class FileSource<N, E> {\n private url: string\n private onMessage: (msg: IngestMessage<N, E>) => void\n private onStatus?: FileStatusListener\n private timer: number | null = null\n private lastETag: string | null = null\n private lastContent: string = ''\n private intervalMs: number = 1000\n private closed = false\n\n constructor(args: FileSourceArgs<N, E>) {\n this.url = args.url\n this.onMessage = args.onMessage\n this.onStatus = args.onStatus\n this.intervalMs = args.intervalMs ?? 1000\n }\n\n async connect() {\n this.closed = false\n this.lastETag = null\n this.lastContent = ''\n this.onStatus?.('opened')\n this.startPolling()\n }\n\n close() {\n this.closed = true\n if (this.timer) {\n window.clearInterval(this.timer)\n this.timer = null\n }\n this.onStatus?.('closed')\n }\n\n private startPolling() {\n if (this.timer) window.clearInterval(this.timer)\n this.timer = window.setInterval(() => this.poll(), this.intervalMs)\n // Poll immediately\n this.poll()\n }\n\n private async poll() {\n if (this.closed) return\n\n try {\n this.onStatus?.('reading')\n const headers: HeadersInit = {}\n if (this.lastETag) {\n headers['If-None-Match'] = this.lastETag\n }\n\n const response = await fetch(this.url, { headers })\n\n if (response.status === 304) {\n // Not modified, no new content\n return\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const etag = response.headers.get('ETag')\n if (etag) {\n this.lastETag = etag\n }\n\n const content = await response.text()\n\n if (content === this.lastContent) {\n return\n }\n\n // Parse new content (NDJSON)\n const lines = content.split('\\n').map(l => l.trim()).filter(Boolean)\n const lastContentLines = this.lastContent.split('\\n').map(l => l.trim()).filter(Boolean)\n const newLines = lines.slice(lastContentLines.length)\n\n for (const line of newLines) {\n try {\n const obj = JSON.parse(line) as IngestMessage<N, E>\n this.onMessage(obj)\n } catch {\n // ignore malformed lines\n }\n }\n\n this.lastContent = content\n } catch (e) {\n this.onStatus?.('error', e)\n }\n }\n}\n\n","import type { IngestMessage } from '../ingest'\n\ntype StatusListener = (status: 'idle' | 'opened' | 'reading' | 'error' | 'closed', detail?: any) => void\n\nexport type FileSystemSourceArgs<N, E> = {\n filename: string\n onMessage: (msg: IngestMessage<N, E>) => void\n onStatus?: StatusListener\n intervalMs?: number\n}\n\nexport class FileSystemSource<N, E> {\n private handle: FileSystemFileHandle | null = null\n private onMessage: (msg: IngestMessage<N, E>) => void\n private onStatus?: StatusListener\n private timer: number | null = null\n private lastSize = 0\n private filename: string\n private intervalMs: number\n\n constructor(args: FileSystemSourceArgs<N, E>) {\n this.filename = args.filename\n this.onMessage = args.onMessage\n this.onStatus = args.onStatus\n this.intervalMs = args.intervalMs ?? 1000\n }\n\n async openDirectory() {\n try {\n // @ts-ignore\n const dir = await (window as any).showDirectoryPicker?.()\n if (!dir) throw new Error('File System Access not supported or cancelled')\n const handle = await dir.getFileHandle(this.filename, { create: false })\n this.handle = handle\n this.onStatus?.('opened', { file: this.filename })\n this.lastSize = 0\n this.startPolling()\n } catch (e) {\n this.onStatus?.('error', e)\n }\n }\n\n close() {\n if (this.timer) {\n window.clearInterval(this.timer)\n this.timer = null\n }\n this.handle = null\n this.onStatus?.('closed')\n }\n\n private startPolling() {\n if (this.timer) window.clearInterval(this.timer)\n this.timer = window.setInterval(() => this.readNewLines(), this.intervalMs)\n }\n\n private async readNewLines() {\n try {\n if (!this.handle) return\n this.onStatus?.('reading')\n const file = await this.handle.getFile()\n if (file.size === this.lastSize) return\n const slice = await file.slice(this.lastSize).text()\n this.lastSize = file.size\n const lines = slice.split('\\n').map(l => l.trim()).filter(Boolean)\n for (const line of lines) {\n try {\n const obj = JSON.parse(line) as IngestMessage<N, E>\n this.onMessage(obj)\n } catch {\n // ignore malformed lines\n }\n }\n } catch (e) {\n this.onStatus?.('error', e)\n }\n }\n}\n\n","import { Graph } from '../graph/graph'\nimport { Canvas } from '../canvas/canvas'\nimport { EdgeId, PublicEdgeData } from '../graph/edge'\nimport { SegId } from '../graph/seg'\nimport { Mutator } from '../graph/mutator'\nimport { MarkerType } from '../canvas/marker'\nimport { APIArguments, APIOptions, Update, NodeProps, EdgeProps, EdgeEnd, EventsOptions, NewNode, NewEdge, ThemeVars, IngestionConfig } from './options'\nimport { Defaults, applyDefaults } from './defaults'\nimport { PublicNodeData, NodeId, PortId } from '../graph/node'\nimport { Node } from '../canvas/node'\nimport { Nav, Dir } from '../common'\nimport { Updater } from './updater'\nimport { Ingest, IngestMessage } from './ingest'\nimport { WebSocketSource } from './sources/WebSocketSource'\nimport { FileSource } from './sources/FileSource'\nimport { FileSystemSource } from './sources/FileSystemSource'\nimport { logger } from '../log'\n\nconst log = logger('api')\n\ntype State<N, E> = {\n graph: Graph\n update: Update<N, E> | null\n}\n\nexport type EditNodeProps = NewNode & {\n id: string\n}\n\nexport type EditEdgeProps = {\n id: string\n type?: string\n source: { id: string, port?: string, marker?: MarkerType }\n target: { id: string, port?: string, marker?: MarkerType }\n}\n\n/** Core graph API */\nexport class API<N, E> {\n private state!: State<N, E>\n private seq!: State<N, E>[]\n private index!: number\n private canvas: Canvas<N, E>\n private options: Defaults<N, E>\n private history: Update<N, E>[]\n private nodeIds!: Map<N, string>\n private edgeIds!: Map<E, string>\n private nodeVersions!: Map<N, number>\n private nodeOverrides!: Map<N, Partial<NodeProps<N>>>\n private edgeOverrides!: Map<E, Partial<EdgeProps<N>>>\n private nodeFields!: Map<string, 'string' | 'number' | 'boolean'>\n private nextNodeId!: number\n private nextEdgeId!: number\n private events: EventsOptions<N, E>\n private ingest?: Ingest<N, E>\n private ingestionSource?: WebSocketSource<N, E> | FileSource<N, E>\n private ingestionConfig?: IngestionConfig\n private prevProps: { nodes?: N[], edges?: E[], history?: Update<N, E>[], options?: APIOptions<N, E> } = {}\n root: string\n\n constructor(args: APIArguments<N, E>) {\n this.root = args.root\n this.options = applyDefaults(args.options)\n this.events = args.events || {}\n this.ingestionConfig = args.ingestion\n\n // reset graph state\n this.reset()\n\n // create canvas\n this.canvas = new Canvas<N, E>(this, {\n ...this.options.canvas,\n dummyNodeSize: this.options.graph.dummyNodeSize,\n orientation: this.options.graph.orientation,\n })\n\n // store initial update or history (ingestion starts empty)\n if (args.history) {\n this.history = args.history\n } else if (args.nodes) {\n this.history = [Updater.add(args.nodes, args.edges || []).update]\n } else {\n this.history = []\n }\n\n // Store initial props for applyProps diffing\n this.prevProps = {\n nodes: args.nodes,\n edges: args.edges,\n history: args.history,\n options: args.options,\n }\n\n // setup ingestion if configured\n if (this.ingestionConfig) {\n this.ingest = new Ingest(this)\n }\n }\n\n reset() {\n let graph = new Graph({ options: this.options.graph })\n this.state = { graph, update: null }\n this.seq = [this.state]\n this.index = 0\n this.nodeIds = new Map()\n this.edgeIds = new Map()\n this.nodeVersions = new Map()\n this.nodeOverrides = new Map()\n this.edgeOverrides = new Map()\n this.nodeFields = new Map()\n this.nextNodeId = 1\n this.nextEdgeId = 1\n this.canvas?.reset?.()\n }\n\n /** Initialize the API */\n async init() {\n const root = document.getElementById(this.root)\n if (!root) throw new Error('root element not found')\n root.appendChild(this.canvas.container!)\n await this.applyHistory()\n\n // Connect ingestion source if configured\n if (this.ingestionConfig && this.ingest) {\n this.connectIngestion()\n }\n\n if (this.events.onInit) {\n this.events.onInit()\n }\n }\n\n /** Connect to the configured ingestion source */\n private connectIngestion() {\n if (!this.ingestionConfig || !this.ingest) return\n\n const args: any = {\n ...this.ingestionConfig,\n onMessage: (msg: IngestMessage<N, E>) => {\n this.ingest!.apply(msg)\n },\n }\n\n const source = {\n 'websocket': WebSocketSource<N, E>,\n 'file': FileSource<N, E>,\n 'filesystem': FileSystemSource<N, E>,\n }[this.ingestionConfig.type] as any\n\n this.ingestionSource = new source[this.ingestionConfig.type](args)\n this.ingestionSource?.connect()\n }\n\n /** Disconnect from the ingestion source */\n private disconnectIngestion() {\n if (!this.ingestionSource) return\n\n if (this.ingestionSource instanceof WebSocketSource) {\n this.ingestionSource.disconnect()\n } else if (this.ingestionSource instanceof FileSource) {\n this.ingestionSource.close()\n }\n this.ingestionSource = undefined\n }\n\n private async applyHistory() {\n for (const update of this.history)\n await this.applyUpdate(update)\n }\n\n /** Current history index (0-based) */\n getHistoryIndex(): number {\n return this.index\n }\n\n /** Current history length */\n getHistoryLength(): number {\n return this.seq.length\n }\n\n /** Toggle canvas editable mode without re-creating the graph */\n setEditable(editable: boolean): void {\n this.canvas.editMode.editable = editable\n }\n\n /** Replace entire history (clears prior) */\n async replaceHistory(history: Update<N, E>[]) {\n this.reset()\n this.history = history\n await this.applyHistory()\n }\n\n /** Rebuild from snapshot (nodes/edges) */\n async replaceSnapshot(nodes: N[], edges: E[], description?: string) {\n this.reset()\n this.history = [{\n addNodes: nodes,\n addEdges: edges,\n description,\n }]\n await this.applyHistory()\n }\n\n private get graph() {\n return this.state.graph\n }\n\n /** Navigate to a different state */\n nav(nav: Nav) {\n let newIndex: number\n switch (nav) {\n case 'first':\n newIndex = 0\n break\n case 'last':\n newIndex = this.seq.length - 1\n break\n case 'prev':\n newIndex = this.index - 1\n break\n case 'next':\n newIndex = this.index + 1\n break\n }\n if (newIndex < 0 ||\n newIndex >= this.seq.length ||\n newIndex == this.index)\n return\n this.applyDiff(this.index, newIndex)\n this.index = newIndex\n this.state = this.seq[this.index]\n // Notify history change\n if (this.events.historyChange)\n this.events.historyChange(this.index, this.seq.length)\n }\n\n private applyDiff(oldIndex: number, newIndex: number) {\n const oldGraph = this.seq[oldIndex].graph\n const newGraph = this.seq[newIndex].graph\n\n for (const oldNode of oldGraph.nodes.values()) {\n const newNode = newGraph.nodes.get(oldNode.id)\n if (!newNode) this.canvas.deleteNode(oldNode)\n }\n for (const newNode of newGraph.nodes.values()) {\n const oldNode = oldGraph.nodes.get(newNode.id)\n if (!oldNode) {\n this.canvas.addNode(newNode)\n } else if (oldNode.key !== newNode.key) {\n // Node version changed (e.g., during rebuild) - delete old and add new\n this.canvas.deleteNode(oldNode)\n this.canvas.addNode(newNode)\n } else if (oldNode.pos !== newNode.pos) {\n // Same node, just update position\n this.canvas.getNode(newNode.key).setPos(newNode.pos!)\n }\n }\n for (const oldSeg of oldGraph.segs.values()) {\n const newSeg = newGraph.segs.get(oldSeg.id)\n if (!newSeg) {\n this.canvas.deleteSeg(oldSeg)\n } else if (oldSeg !== newSeg) {\n this.canvas.updateSeg(newSeg, newGraph)\n }\n }\n for (const newSeg of newGraph.segs.values()) {\n if (!oldGraph.segs.has(newSeg.id)) {\n this.canvas.addSeg(newSeg, newGraph)\n }\n }\n\n this.canvas.update()\n }\n\n /** Add a node */\n async addNode(node: N) {\n await this.update(update => update.addNode(node))\n }\n\n /** Delete a node */\n async deleteNode(node: N) {\n await this.update(update => update.deleteNode(node))\n }\n\n /** Update a node */\n async updateNode(node: N) {\n await this.update(update => update.updateNode(node))\n }\n\n /** Add an edge */\n async addEdge(edge: E) {\n await this.update(update => update.addEdge(edge))\n }\n\n /** Delete an edge */\n async deleteEdge(edge: E) {\n await this.update(update => update.deleteEdge(edge))\n }\n\n /** Update an edge */\n async updateEdge(edge: E) {\n await this.update(update => update.updateEdge(edge))\n }\n\n /** Perform a batch of updates */\n async update(callback: (updater: Updater<N, E>) => void) {\n // collect updates from the caller\n const updater = new Updater<N, E>()\n callback(updater)\n await this.applyUpdate(updater.update)\n }\n\n /** Rebuild the graph from scratch (removes all then re-adds all nodes/edges) */\n async rebuild() {\n // Collect current nodes and edges from the nodeIds/edgeIds maps\n const nodes: N[] = [...this.nodeIds.keys()]\n const edges: E[] = [...this.edgeIds.keys()]\n\n await this.update(updater => {\n // Remove all edges and nodes\n for (const edge of edges) updater.deleteEdge(edge)\n for (const node of nodes) updater.deleteNode(node)\n // Re-add all nodes first, then edges\n for (const node of nodes) updater.addNode(node)\n for (const edge of edges) updater.addEdge(edge)\n })\n }\n\n private async applyUpdate(update: Update<N, E>) {\n log.info('applyUpdate', update)\n // create nodes in canvas and wait for their measurements\n const nodes = await this.measureNodes(update)\n // apply updates to get a new version of the graph\n const graph = this.state.graph!.withMutations((mut: Mutator) => {\n for (const edge of update.removeEdges ?? [])\n this._removeEdge(edge, mut)\n for (const node of update.removeNodes ?? [])\n this._removeNode(node, mut)\n for (const node of update.addNodes ?? [])\n this._addNode(nodes.get(node)!, mut)\n for (const node of update.updateNodes ?? [])\n this._updateNode(nodes.get(node)!, mut)\n for (const edge of update.addEdges ?? [])\n this._addEdge(edge, mut)\n for (const edge of update.updateEdges ?? [])\n this._updateEdge(edge, mut)\n this.nodeOverrides.clear()\n this.edgeOverrides.clear()\n })\n // add the new state, then nav to it\n this.state = { graph, update }\n this.setNodePositions()\n this.seq.splice(this.index + 1)\n this.seq.push(this.state)\n this.nav('last')\n // In case the consumer doesn't call nav, still notify\n if (this.events.historyChange)\n this.events.historyChange(this.index, this.seq.length)\n }\n\n private setNodePositions() {\n const { graph } = this.state\n for (const nodeId of graph.dirtyNodes) {\n const node = graph.getNode(nodeId)\n if (!node.isDummy)\n this.canvas.getNode(node.key).setPos(node.pos!)\n }\n }\n\n private async measureNodes(update: Update<N, E>): Promise<Map<N, Node>> {\n const data: PublicNodeData[] = []\n for (const set of [update.updateNodes, update.addNodes])\n for (const node of set ?? [])\n data.push(this.parseNode(node, true))\n return await this.canvas.measureNodes(data)\n }\n\n private parseNode(data: N, bumpVersion: boolean = false): PublicNodeData {\n const get = this.options.props.node\n let props: NodeProps<N>\n if (get) props = get(data)\n else if (!data) throw new Error(`invalid node ${data}`)\n else if (typeof data == 'string') props = { id: data }\n else if (typeof data == 'object') props = data\n else throw new Error(`invalid node ${JSON.stringify(data)}`)\n // Detect fields from the raw node data\n this.detectNodeFields(data)\n // Apply overrides (from built-in modal edits on opaque types)\n const overrides = this.nodeOverrides.get(data)\n if (overrides) props = { ...props, ...overrides }\n let { id, title, text, type, render } = props\n id ??= this.getNodeId(data)\n const ports = this.parsePorts(props.ports)\n let version = this.nodeVersions.get(data)\n if (!version) version = 1\n else if (bumpVersion) version++\n this.nodeVersions.set(data, version)\n return { id, data, ports, title, text, type, render, version }\n }\n\n private detectNodeFields(data: N) {\n if (typeof data != 'object' || !data) return\n // Skip internal/complex fields\n const skip = new Set(['id', 'ports', 'render', 'version'])\n for (const [key, value] of Object.entries(data)) {\n if (skip.has(key)) continue\n if (value === null || value === undefined) continue\n const type = typeof value\n if (type === 'string' || type === 'number' || type === 'boolean') {\n this.nodeFields.set(key, type)\n }\n }\n }\n\n getNodeFields(): Map<string, 'string' | 'number' | 'boolean'> {\n return this.nodeFields\n }\n\n private parseEdge(data: E): PublicEdgeData {\n const get = this.options.props.edge\n let props: Partial<EdgeProps<N>>\n if (get) props = get(data)\n else if (!data) throw new Error(`invalid edge ${data}`)\n else if (typeof data == 'string') props = this.parseStringEdge(data)\n else if (typeof data == 'object') props = data\n else throw new Error(`invalid edge ${data}`)\n // Apply overrides (from built-in modal edits on opaque types)\n const overrides = this.edgeOverrides.get(data)\n if (overrides) props = { ...props, ...overrides }\n let { id, source, target, type } = props\n if (!id) id = this.getEdgeId(data)\n source = this.parseEdgeEnd(source)\n target = this.parseEdgeEnd(target)\n const edge = { id, source, target, type, data }\n return edge\n }\n\n private parseEdgeEnd(end?: EdgeEnd<N>): { id: string, port?: string }\n private parseEdgeEnd(end?: any): { id: string, port?: string } {\n if (!end) throw new Error(`edge has an undefined source or target`)\n if (typeof end == 'string') return { id: end }\n if (typeof end == 'object') {\n const keys = Object.keys(end)\n const pidx = keys.indexOf('port')\n if (pidx != -1) {\n // port must be string or undefined; if it's something else, return as-is\n if (end.port !== undefined && typeof end.port != 'string') return end\n keys.splice(pidx, 1)\n }\n if (keys.length != 1) return end\n if (keys[0] == 'id') return end\n if (keys[0] != 'node') return end\n const id = this.nodeIds.get(end.node)\n if (!id) throw new Error(`edge end references unknown node ${end.node}`)\n return { id, port: end.port }\n }\n throw new Error(`invalid edge end ${end}`)\n }\n\n private parseStringEdge(str: string): EdgeProps<N> {\n const [source, target] = str.split(/\\s*(?::|-+>?)\\s*/)\n return { source, target }\n }\n\n private parsePorts(ports?: NodeProps<N>['ports']): PublicNodeData['ports'] {\n const fixed: PublicNodeData['ports'] = {}\n for (const key of ['in', 'out'] as Dir[]) {\n if (ports?.[key] && ports[key].length > 0)\n fixed[key] = ports[key].map(port =>\n typeof port == 'string' ? { id: port } : port)\n }\n return fixed\n }\n\n getNode(id: NodeId): PublicNodeData {\n return this.graph.getNode(id)\n }\n\n getEdge(id: EdgeId): PublicEdgeData {\n return this.graph.getEdge(id)\n }\n\n private getNodeId(node: N): string {\n let id = this.nodeIds.get(node)\n if (!id) {\n id = `n${this.nextNodeId++}`\n this.nodeIds.set(node, id)\n }\n return id\n }\n\n private getEdgeId(edge: E): string {\n let id = this.edgeIds.get(edge)\n if (!id) {\n id = `e${this.nextEdgeId++}`\n this.edgeIds.set(edge, id)\n }\n return id\n }\n\n private _addNode(node: Node, mut: Mutator) {\n const { data, id: newId } = node.data!\n const oldId = this.nodeIds.get(data)\n if (oldId && oldId != newId)\n throw new Error(`node id of ${data} changed from ${oldId} to ${newId}`)\n this.nodeIds.set(data, newId)\n mut.addNode(node.data!)\n }\n\n private _removeNode(node: any, mut: Mutator) {\n const id = this.nodeIds.get(node)\n if (!id) throw new Error(`removing node ${JSON.stringify(node)} which does not exist`)\n mut.removeNode({ id })\n }\n\n private _updateNode(node: Node, mut: Mutator) {\n const { data, id: newId } = node.data!\n const oldId = this.nodeIds.get(data)\n if (!oldId) throw new Error(`updating unknown node ${JSON.stringify(node)} `)\n if (oldId != newId) throw new Error(`node id changed from ${oldId} to ${newId} `)\n mut.updateNode(node.data!)\n }\n\n private _addEdge(edge: any, mut: Mutator) {\n const data = this.parseEdge(edge)\n const id = this.edgeIds.get(edge)\n if (id && id != data.id)\n throw new Error(`edge id changed from ${id} to ${data.id} `)\n this.edgeIds.set(edge, data.id)\n mut.addEdge(data)\n }\n\n private _removeEdge(edge: any, mut: Mutator) {\n const id = this.edgeIds.get(edge)\n if (!id) throw new Error(`removing edge ${JSON.stringify(edge)} which does not exist`)\n mut.removeEdge(this.parseEdge(edge))\n }\n\n private _updateEdge(edge: any, mut: Mutator) {\n const id = this.edgeIds.get(edge)\n if (!id) throw new Error(`updating unknown edge ${JSON.stringify(edge)} `)\n const data = this.parseEdge(edge)\n if (data.id !== id) throw new Error(`edge id changed from ${id} to ${data.id} `)\n mut.updateEdge(data)\n }\n\n // Event Handlers\n\n handleClickNode(id: NodeId) {\n const handler = this.events.nodeClick\n const node = this.graph.getNode(id)\n if (handler) handler(node.data)\n }\n\n handleClickEdge(id: SegId) {\n const handler = this.events.edgeClick\n if (!handler) return\n const seg = this.graph.getSeg(id)\n if (seg.edgeIds.size != 1) return\n const edge = this.graph.getEdge(seg.edgeIds.values().next().value)\n handler(edge.data)\n }\n\n async handleNewNode() {\n const gotNode = async (node: N) => {\n await this.addNode(node)\n }\n if (this.events.newNode)\n this.events.newNode(gotNode)\n else\n this.canvas.showNewNodeModal(async (data) => {\n if (this.events.addNode)\n this.events.addNode(data, gotNode)\n else\n await gotNode(data as N)\n })\n }\n\n async handleNewNodeFrom(source: { id: string, port?: string }) {\n const gotNode = async (node: N) => {\n const gotEdge = async (edge: E) => {\n await this.update(u => {\n u.addNode(node).addEdge(edge)\n })\n }\n const data = this.graph.getNode(source.id).data\n const newEdge: NewEdge<N> = {\n source: { node: data, port: source.port },\n target: { node }\n }\n if (this.events.addEdge)\n this.events.addEdge(newEdge, gotEdge)\n else\n await gotEdge(newEdge as E)\n }\n if (this.events.newNode)\n this.events.newNode(gotNode)\n else\n this.canvas.showNewNodeModal(async (data: Record<string, any>) => {\n if (this.events.addNode)\n this.events.addNode(data, gotNode)\n else\n await gotNode(data as N)\n })\n }\n\n async handleEditNode(id: NodeId) {\n const node = this.graph.getNode(id)\n const gotNode = async (node: N) => {\n if (node) await this.updateNode(node)\n }\n if (this.events.editNode)\n this.events.editNode(node.data, gotNode)\n else {\n this.canvas.showEditNodeModal(node, async (data: Record<string, any>) => {\n if (this.events.updateNode)\n this.events.updateNode(node.data, data, gotNode)\n else {\n // Store overrides for opaque N types, then update with original data\n this.nodeOverrides.set(node.data, data)\n await gotNode(node.data)\n }\n })\n }\n }\n\n async handleEditEdge(id: SegId) {\n const seg = this.graph.getSeg(id)\n if (seg.edgeIds.size != 1) return\n const edge = this.graph.getEdge(seg.edgeIds.values().next().value)\n const gotEdge = async (edge: E | null) => {\n if (edge) await this.updateEdge(edge)\n }\n if (this.events.editEdge)\n this.events.editEdge(edge.data, gotEdge)\n else\n this.canvas.showEditEdgeModal(edge, async (data: EditEdgeProps) => {\n const sourceNode = edge.sourceNode(this.graph)\n const targetNode = edge.targetNode(this.graph)\n const update: NewEdge<N> = {\n source: { node: sourceNode.data, port: data.source.port, marker: data.source.marker },\n target: { node: targetNode.data, port: data.target.port, marker: data.target.marker },\n }\n if (this.events.updateEdge)\n this.events.updateEdge(edge.data, update, gotEdge)\n else {\n // Store overrides for opaque E types, then update with original data\n this.edgeOverrides.set(edge.data, {\n source: { id: sourceNode.id, port: data.source.port, marker: data.source.marker },\n target: { id: targetNode.id, port: data.target.port, marker: data.target.marker },\n type: data.type,\n })\n await gotEdge(edge.data)\n }\n })\n }\n\n async handleAddEdge(data: EditEdgeProps) {\n const gotEdge = async (edge: E | null) => {\n if (edge) await this.addEdge(edge)\n }\n const newEdge: NewEdge<N> = {\n source: { node: this.graph.getNode(data.source.id).data, port: data.source.port, marker: data.source.marker },\n target: { node: this.graph.getNode(data.target.id).data, port: data.target.port, marker: data.target.marker },\n }\n if (this.events.addEdge)\n this.events.addEdge(newEdge, gotEdge)\n else\n await gotEdge(data as E)\n }\n\n async handleDeleteNode(id: NodeId) {\n const node = this.getNode(id)\n if (this.events.removeNode)\n this.events.removeNode(node.data, async (remove) => {\n if (remove) await this.deleteNode(node.data)\n })\n else\n await this.deleteNode(node.data)\n }\n\n async handleDeleteEdge(id: EdgeId) {\n const edge = this.getEdge(id)\n if (this.events.removeEdge)\n this.events.removeEdge(edge.data, async (remove) => {\n if (remove) await this.deleteEdge(edge.data)\n })\n else\n await this.deleteEdge(edge.data)\n }\n\n /** Update theme and type styles dynamically */\n updateStyles(options: { theme?: ThemeVars, nodeTypes?: Record<string, ThemeVars>, edgeTypes?: Record<string, ThemeVars> }) {\n this.canvas?.updateStyles(options)\n }\n\n /** Update color mode without recreating the canvas */\n setColorMode(colorMode: 'light' | 'dark' | 'system') {\n this.canvas?.setColorMode(colorMode)\n }\n\n /**\n * Apply prop changes by diffing against previously applied props.\n * This is a convenience method for framework wrappers that centralizes\n * the logic for detecting and applying changes to nodes, edges, history, and options.\n * The API stores the previous props internally, so you just pass the new props.\n *\n * @param props - The new props to apply\n */\n applyProps(props: { nodes?: N[], edges?: E[], history?: Update<N, E>[], options?: APIOptions<N, E> }): void {\n const prev = this.prevProps\n\n // Check if nodes/edges changed\n const nodesChanged = !shallowEqualArray(props.nodes, prev.nodes)\n const edgesChanged = !shallowEqualArray(props.edges, prev.edges)\n\n if (nodesChanged || edgesChanged) {\n if (props.nodes) {\n this.replaceSnapshot(props.nodes, props.edges || [], undefined)\n }\n }\n\n // Check if history changed (only if nodes/edges didn't change)\n if (!nodesChanged && !edgesChanged && props.history !== prev.history) {\n if (props.history === undefined) {\n // History was removed - if we have nodes/edges, use those\n if (props.nodes) {\n this.replaceSnapshot(props.nodes, props.edges || [], undefined)\n }\n } else if (prev.history && isHistoryPrefix(prev.history, props.history)) {\n // History was appended - apply only the new updates\n const prevLength = prev.history.length\n const newUpdates = props.history.slice(prevLength)\n for (const frame of newUpdates) {\n this.update(u => {\n if (frame.addNodes) u.addNodes(...frame.addNodes)\n if (frame.removeNodes) u.deleteNodes(...frame.removeNodes)\n if (frame.updateNodes) u.updateNodes(...frame.updateNodes)\n if (frame.addEdges) u.addEdges(...frame.addEdges)\n if (frame.removeEdges) u.deleteEdges(...frame.removeEdges)\n if (frame.updateEdges) u.updateEdges(...frame.updateEdges)\n if (frame.description) u.describe(frame.description)\n })\n }\n } else {\n // History was completely replaced\n this.replaceHistory(props.history)\n }\n }\n\n // Check if canvas options changed\n const prevCanvas = prev.options?.canvas as any\n const currCanvas = props.options?.canvas as any\n\n // Handle color mode changes\n const colorModeChanged = prevCanvas?.colorMode !== currCanvas?.colorMode\n if (colorModeChanged && currCanvas?.colorMode) {\n this.setColorMode(currCanvas.colorMode)\n }\n\n // Handle theme/type style changes\n const themeChanged = prevCanvas?.theme !== currCanvas?.theme\n const nodeTypesChanged = prevCanvas?.nodeTypes !== currCanvas?.nodeTypes\n const edgeTypesChanged = prevCanvas?.edgeTypes !== currCanvas?.edgeTypes\n\n if (themeChanged || nodeTypesChanged || edgeTypesChanged) {\n this.updateStyles({\n theme: currCanvas?.theme,\n nodeTypes: currCanvas?.nodeTypes,\n edgeTypes: currCanvas?.edgeTypes,\n })\n }\n\n // Update prevProps with all changed values\n this.prevProps = {\n nodes: props.nodes,\n edges: props.edges,\n history: props.history,\n options: props.options,\n }\n }\n\n /** Cleanup resources when the graph is destroyed */\n destroy() {\n this.disconnectIngestion()\n this.canvas?.destroy()\n }\n}\n\n/** Shallow comparison of arrays with object property comparison */\nfunction shallowEqualArray<T>(a: T[] | undefined, b: T[] | undefined): boolean {\n if (a === b) return true\n if (!a || !b) return false\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n if (typeof a[i] === 'object' && a[i] !== null && typeof b[i] === 'object' && b[i] !== null) {\n const aObj = a[i] as any\n const bObj = b[i] as any\n const aKeys = Object.keys(aObj)\n const bKeys = Object.keys(bObj)\n if (aKeys.length !== bKeys.length) return false\n for (const key of aKeys) {\n if (aObj[key] !== bObj[key]) return false\n }\n } else {\n return false\n }\n }\n }\n return true\n}\n\n/** Check if oldHistory is a prefix of newHistory */\nfunction isHistoryPrefix<N, E>(oldHistory: Update<N, E>[], newHistory: Update<N, E>[]): boolean {\n if (newHistory.length < oldHistory.length) return false\n for (let i = 0; i < oldHistory.length; i++) {\n if (!shallowEqualUpdate(oldHistory[i], newHistory[i])) {\n return false\n }\n }\n return true\n}\n\n/** Shallow comparison of Update objects */\nfunction shallowEqualUpdate<N, E>(a: Update<N, E>, b: Update<N, E>): boolean {\n if (a === b) return true\n if (a.description !== b.description) return false\n if (!shallowEqualArray(a.addNodes, b.addNodes)) return false\n if (!shallowEqualArray(a.removeNodes, b.removeNodes)) return false\n if (!shallowEqualArray(a.updateNodes, b.updateNodes)) return false\n if (!shallowEqualArray(a.addEdges, b.addEdges)) return false\n if (!shallowEqualArray(a.removeEdges, b.removeEdges)) return false\n if (!shallowEqualArray(a.updateEdges, b.updateEdges)) return false\n return true\n}\n",".playground {\n display: flex;\n height: calc(100vh - 60px);\n}\n\n.sidebar {\n width: 280px;\n background: var(--color-bg);\n border-right: 1px solid var(--color-border);\n padding: 1.5rem;\n overflow-y: auto;\n}\n\n.sidebar h2 {\n font-size: 0.875rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-text-muted);\n margin-bottom: 0.75rem;\n margin-top: 1.5rem;\n}\n\n.sidebar h2:first-child {\n margin-top: 0;\n}\n\n.example-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.example-btn {\n padding: 0.75rem 1rem;\n background: var(--color-bg-secondary);\n border: 1px solid var(--color-border);\n border-radius: 0.5rem;\n text-align: left;\n cursor: pointer;\n font-size: 0.875rem;\n color: var(--color-text);\n transition: all 0.15s;\n}\n\n.example-btn:hover {\n background: var(--color-border);\n}\n\n.example-btn.active {\n background: var(--color-primary);\n color: white;\n border-color: var(--color-primary);\n}\n\n.options {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.option-group {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.option-group label {\n font-size: 0.875rem;\n color: var(--color-text-muted);\n}\n\n.option-group select {\n padding: 0.5rem;\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n font-size: 0.875rem;\n}\n\n.option-group input[type=\"checkbox\"] {\n margin-right: 0.5rem;\n}\n\n.graph-area {\n flex: 1;\n padding: 1.5rem;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.graph-toolbar {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.nav-controls {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.nav-btn {\n padding: 0.5rem 0.75rem;\n background: var(--color-bg-secondary);\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n cursor: pointer;\n font-size: 0.875rem;\n color: var(--color-text);\n transition: all 0.15s;\n height: 2.25rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n.nav-btn:hover:not(:disabled) {\n background: var(--color-border);\n}\n\n.nav-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* Prominent edit toggle */\n#edit-toggle {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n font-weight: 600;\n}\n\n/* Source Icon Button */\n.source-icon-btn {\n font-size: 1.1rem;\n padding: 0.5rem;\n min-width: 2.5rem;\n position: relative;\n height: 2.25rem;\n}\n\n.source-icon-btn::after {\n content: '';\n position: absolute;\n bottom: 2px;\n right: 2px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--color-border);\n border: 1px solid var(--color-bg);\n}\n\n.source-icon-btn.active::after {\n background: rgb(34, 197, 94);\n box-shadow: 0 0 4px rgba(34, 197, 94, 0.5);\n}\n\n.source-icon-btn.connecting::after {\n background: rgb(251, 191, 36);\n box-shadow: 0 0 4px rgba(251, 191, 36, 0.5);\n animation: pulse-dot 1.5s ease-in-out infinite;\n}\n\n.source-icon-btn.error::after {\n background: rgb(239, 68, 68);\n box-shadow: 0 0 4px rgba(239, 68, 68, 0.5);\n}\n\n.source-icon-btn.active {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n}\n\n.source-icon-btn.connecting {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n opacity: 0.7;\n animation: pulse 1.5s ease-in-out infinite;\n}\n\n.source-icon-btn.error {\n border-color: rgb(239, 68, 68);\n}\n\n@keyframes pulse-dot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.8); }\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 0.7; }\n 50% { opacity: 1; }\n}\n\n.graph-container {\n flex: 1;\n background: var(--color-bg);\n border-radius: 0.75rem;\n box-shadow: var(--shadow-md);\n overflow: hidden;\n}\n\n/* Modal styles (global) */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.35);\n display: none;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal {\n width: min(680px, calc(100vw - 2rem));\n background: var(--color-bg);\n color: var(--color-text);\n border: 1px solid var(--color-border);\n border-radius: 0.75rem;\n box-shadow: var(--shadow-lg);\n overflow: hidden;\n}\n\n.modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--color-border);\n background: var(--color-bg-secondary);\n}\n\n.modal-header h3 {\n font-size: 1rem;\n font-weight: 600;\n}\n\n.modal-close {\n background: transparent;\n border: none;\n color: var(--color-text);\n font-size: 1.25rem;\n cursor: pointer;\n}\n\n.modal-body {\n padding: 1rem;\n line-height: 1.6;\n}\n\n.modal-body ul {\n margin: 0.5rem 0 0 1.25rem;\n}\n\n.modal-body .form-group {\n margin-bottom: 1rem;\n}\n\n.modal-body label {\n display: block;\n font-size: 0.875rem;\n color: var(--color-text-muted);\n margin-bottom: 0.5rem;\n}\n\n.modal-body input[type=\"text\"] {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n font-size: 0.875rem;\n background: var(--color-bg);\n color: var(--color-text);\n}\n\n.modal-body .button-group {\n display: flex;\n gap: 0.5rem;\n margin-top: 1rem;\n}\n\n.modal-body .button-group button {\n flex: 1;\n padding: 0.5rem 1rem;\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n background: var(--color-bg-secondary);\n color: var(--color-text);\n cursor: pointer;\n font-size: 0.875rem;\n transition: all 0.15s;\n}\n\n.modal-body .button-group button:hover:not(:disabled) {\n background: var(--color-border);\n}\n\n.modal-body .button-group button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.modal-body .button-group button.primary {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n}\n\n.modal-body .button-group button.primary:hover:not(:disabled) {\n background: var(--color-primary);\n opacity: 0.9;\n}\n\n.modal-body .status-message {\n margin-top: 1rem;\n padding: 0.75rem;\n border-radius: 0.25rem;\n font-size: 0.875rem;\n}\n\n.modal-body .status-message.info {\n background: rgba(59, 130, 246, 0.1);\n color: rgb(59, 130, 246);\n border: 1px solid rgba(59, 130, 246, 0.2);\n}\n\n.modal-body .status-message.error {\n background: rgba(239, 68, 68, 0.1);\n color: rgb(239, 68, 68);\n border: 1px solid rgba(239, 68, 68, 0.2);\n}\n\n.modal-body .status-message.success {\n background: rgba(34, 197, 94, 0.1);\n color: rgb(34, 197, 94);\n border: 1px solid rgba(34, 197, 94, 0.2);\n}\n\n.modal-body .loading-spinner {\n display: inline-block;\n width: 1rem;\n height: 1rem;\n border: 2px solid var(--color-border);\n border-top-color: var(--color-primary);\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n margin-right: 0.5rem;\n vertical-align: middle;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n.modal-body .source-type-selector {\n display: flex;\n gap: 0.5rem;\n margin-bottom: 1rem;\n padding: 0.5rem;\n background: var(--color-bg-secondary);\n border-radius: 0.25rem;\n}\n\n.modal-body .source-type-option {\n flex: 1;\n padding: 0.5rem;\n border: 1px solid var(--color-border);\n border-radius: 0.25rem;\n background: var(--color-bg);\n color: var(--color-text);\n cursor: pointer;\n text-align: center;\n font-size: 0.875rem;\n transition: all 0.15s;\n}\n\n.modal-body .source-type-option:hover {\n background: var(--color-border);\n}\n\n.modal-body .source-type-option.active {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: #fff;\n}\n\n.modal-body .source-controls {\n display: none;\n}\n\n.modal-body .source-controls.active {\n display: block;\n}\n\n","import { graph } from '../index'\nimport { Ingest } from '../api/ingest'\nimport type { API } from '../api/api'\nimport { WebSocketSource } from '../api/sources/WebSocketSource'\nimport { FileSystemSource } from '../api/sources/FileSystemSource'\nimport { FileSource } from '../api/sources/FileSource'\nimport type { PlaygroundOptions, Example } from './types'\nimport styles from './styles.css?raw'\n\nexport class Playground {\n private options: PlaygroundOptions\n private rootElement: HTMLElement\n private currentExample: string\n private examples: Record<string, Example>\n private currentGraph: API<any, any> | null = null\n private ingest: Ingest<any, any> | null = null\n private isEditable = false\n private wsSource: WebSocketSource<any, any> | null = null\n private fsSource: FileSystemSource<any, any> | null = null\n private fileSource: FileSource<any, any> | null = null\n private wsStatus: 'disconnected' | 'connecting' | 'connected' | 'error' = 'disconnected'\n private fsStatus: 'disconnected' | 'opening' | 'connected' | 'error' = 'disconnected'\n private fileStatus: 'disconnected' | 'connecting' | 'connected' | 'error' = 'disconnected'\n private activeSourceType: 'ws' | 'folder' | 'file' | null = null\n private wsUrl = 'ws://localhost:8787'\n private sourceModal: HTMLElement | null = null\n private helpOverlay: HTMLElement | null = null\n private exampleList: string[]\n private graphContainerId: string\n\n constructor(options: PlaygroundOptions) {\n this.options = options\n this.examples = { ...options.examples }\n this.exampleList = Object.keys(this.examples)\n this.currentExample = options.defaultExample || this.exampleList[0]\n this.graphContainerId = `playground-graph-${Math.random().toString(36).substr(2, 9)}`\n\n // Resolve root element\n if (typeof options.root === 'string') {\n const el = document.getElementById(options.root)\n if (!el) throw new Error(`Element with id \"${options.root}\" not found`)\n this.rootElement = el\n } else {\n this.rootElement = options.root\n }\n }\n\n async init() {\n this.injectStyles()\n this.createDOM()\n this.setupEventListeners()\n await this.renderGraph()\n this.updateSourceIcon()\n this.connectExampleSource()\n\n // Set initial rebuild button state\n const rebuildBtn = this.rootElement.querySelector('#rebuild') as HTMLButtonElement | null\n if (rebuildBtn) rebuildBtn.disabled = !this.isEditable\n }\n\n private injectStyles() {\n if (!document.getElementById('g3p-playground-styles')) {\n const styleEl = document.createElement('style')\n styleEl.id = 'g3p-playground-styles'\n styleEl.textContent = styles\n document.head.appendChild(styleEl)\n }\n }\n\n private createDOM() {\n const exampleList = this.exampleList.map((key, i) => {\n const example = this.examples[key]\n const isActive = i === 0 || key === this.currentExample\n return `\n <button class=\"example-btn ${isActive ? 'active' : ''}\" data-example=\"${key}\">\n ${example.name}\n </button>\n `\n }).join('')\n\n this.rootElement.innerHTML = `\n <main class=\"playground\">\n <div class=\"sidebar\">\n <h2>Examples</h2>\n <div class=\"example-list\">\n ${exampleList}\n </div>\n\n <h2>Options</h2>\n <div class=\"options\">\n <div class=\"option-group\">\n <label>Orientation</label>\n <select id=\"orientation\">\n <option value=\"TB\">Top to Bottom</option>\n <option value=\"BT\">Bottom to Top</option>\n <option value=\"LR\">Left to Right</option>\n <option value=\"RL\">Right to Left</option>\n </select>\n </div>\n\n <div class=\"option-group\">\n <label>Port Style</label>\n <select id=\"portStyle\">\n <option value=\"outside\">Outside</option>\n <option value=\"inside\">Inside</option>\n </select>\n </div>\n\n <div class=\"option-group\">\n <label>\n <input type=\"checkbox\" id=\"portLabelRotate\" />\n Rotate Port Labels\n </label>\n </div>\n\n <div class=\"option-group\">\n <label>Theme</label>\n <select id=\"colorMode\">\n <option value=\"system\">System</option>\n <option value=\"light\">Light</option>\n <option value=\"dark\">Dark</option>\n </select>\n </div>\n </div>\n </div>\n\n <div class=\"graph-area\">\n <div class=\"graph-toolbar\">\n <div class=\"nav-controls\">\n <button class=\"nav-btn\" id=\"nav-first\" title=\"First (Home)\">⏮</button>\n <button class=\"nav-btn\" id=\"nav-prev\" title=\"Previous (←)\">◀</button>\n <span id=\"history-label\" style=\"min-width: 4rem; text-align: center; display: inline-flex; align-items: center; justify-content: center; height: 2.25rem;\">— / —</span>\n <button class=\"nav-btn\" id=\"nav-next\" title=\"Next (→)\">▶</button>\n <button class=\"nav-btn\" id=\"nav-last\" title=\"Last (End)\">⏭</button>\n </div>\n <div class=\"connect-controls\" style=\"display:flex; gap:.5rem; align-items:center;\">\n <button class=\"nav-btn source-icon-btn\" id=\"source-icon\" title=\"Data Source Connection\">📡</button>\n </div>\n <button class=\"nav-btn\" id=\"help-btn\" title=\"How to edit\">❓</button>\n <button class=\"nav-btn\" id=\"edit-toggle\" title=\"Toggle edit mode\">✎ Edit</button>\n <button class=\"nav-btn\" id=\"rebuild\" title=\"Rebuild graph from scratch\">🔄 Rebuild</button>\n </div>\n <div class=\"graph-container\" id=\"${this.graphContainerId}\"></div>\n </div>\n </main>\n `\n }\n\n private setupEventListeners() {\n // Example button handlers\n this.rootElement.querySelectorAll('.example-btn').forEach(btn => {\n btn.addEventListener('click', () => {\n this.rootElement.querySelectorAll('.example-btn').forEach(b => b.classList.remove('active'))\n btn.classList.add('active')\n this.currentExample = btn.getAttribute('data-example') || this.exampleList[0]\n this.renderGraph()\n this.connectExampleSource()\n })\n })\n\n // Option change handlers\n this.rootElement.querySelectorAll('.options select, .options input').forEach(el => {\n el.addEventListener('change', () => {\n // Handle color mode changes efficiently without re-rendering\n if (el.id === 'colorMode' && this.currentGraph) {\n const mode = (el as HTMLSelectElement).value as 'light' | 'dark' | 'system'\n this.currentGraph.setColorMode(mode)\n } else {\n this.renderGraph()\n }\n })\n })\n\n // Navigation controls\n this.rootElement.querySelector('#nav-first')?.addEventListener('click', () => {\n this.currentGraph?.nav('first')\n this.updateHistoryLabel()\n })\n this.rootElement.querySelector('#nav-prev')?.addEventListener('click', () => {\n this.currentGraph?.nav('prev')\n this.updateHistoryLabel()\n })\n this.rootElement.querySelector('#nav-next')?.addEventListener('click', () => {\n this.currentGraph?.nav('next')\n this.updateHistoryLabel()\n })\n this.rootElement.querySelector('#nav-last')?.addEventListener('click', () => {\n this.currentGraph?.nav('last')\n this.updateHistoryLabel()\n })\n\n // Rebuild button\n this.rootElement.querySelector('#rebuild')?.addEventListener('click', () => {\n this.currentGraph?.rebuild()\n })\n\n // Edit toggle\n this.rootElement.querySelector('#edit-toggle')?.addEventListener('click', () => {\n this.isEditable = !this.isEditable\n const btn = this.rootElement.querySelector('#edit-toggle')\n if (btn) btn.textContent = this.isEditable ? '✓ Done' : '✎ Edit'\n const rebuildBtn = this.rootElement.querySelector('#rebuild') as HTMLButtonElement | null\n if (rebuildBtn) rebuildBtn.disabled = !this.isEditable\n try {\n this.currentGraph?.setEditable?.(this.isEditable)\n } catch { }\n })\n\n // Help button\n this.rootElement.querySelector('#help-btn')?.addEventListener('click', () => this.openHelp())\n\n // Source icon button\n const sourceIconBtn = this.rootElement.querySelector('#source-icon')\n if (sourceIconBtn) {\n sourceIconBtn.addEventListener('click', (e) => {\n e.preventDefault()\n e.stopPropagation()\n this.openSourceModal()\n })\n }\n\n // Keyboard shortcuts\n document.addEventListener('keydown', (e) => {\n if (!this.currentGraph) return\n if (e.target instanceof HTMLInputElement || e.target instanceof HTMLSelectElement) return\n\n switch (e.key) {\n case 'Home':\n this.currentGraph.nav('first')\n this.updateHistoryLabel()\n break\n case 'End':\n this.currentGraph.nav('last')\n this.updateHistoryLabel()\n break\n case 'ArrowLeft':\n this.currentGraph.nav('prev')\n this.updateHistoryLabel()\n break\n case 'ArrowRight':\n this.currentGraph.nav('next')\n this.updateHistoryLabel()\n break\n }\n })\n }\n\n private getResolvedColorMode(): 'light' | 'dark' {\n const mode = (this.rootElement.querySelector('#colorMode') as HTMLSelectElement)?.value\n if (mode === 'system') {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n }\n return mode as 'light' | 'dark'\n }\n\n private getOptions(exampleOptions?: any) {\n const orientation = (this.rootElement.querySelector('#orientation') as HTMLSelectElement)?.value\n\n return {\n graph: { orientation },\n canvas: {\n width: '100%',\n height: '100%',\n colorMode: this.getResolvedColorMode(),\n editable: this.isEditable,\n ...exampleOptions?.canvas,\n }\n }\n }\n\n private async renderGraph() {\n const container = this.rootElement.querySelector(`#${this.graphContainerId}`) as HTMLElement\n if (!container) return\n\n // Destroy previous graph to clean up styles\n this.currentGraph?.destroy()\n this.currentGraph = null\n\n container.innerHTML = ''\n\n const example = this.examples[this.currentExample]\n const options = this.getOptions(example.options)\n\n try {\n this.currentGraph = await graph({\n root: this.graphContainerId,\n nodes: example.nodes as any,\n edges: example.edges as any,\n options,\n events: {\n historyChange: () => this.updateHistoryLabel(),\n }\n } as any)\n this.ingest = new Ingest(this.currentGraph)\n this.updateHistoryLabel()\n } catch (e) {\n console.error('Failed to render graph:', e)\n container.innerHTML = '<p style=\"padding: 2rem; color: #ef4444;\">Failed to load graph</p>'\n }\n }\n\n private updateHistoryLabel() {\n const label = this.rootElement.querySelector('#history-label')\n if (!label || !this.currentGraph) return\n try {\n const idx = this.currentGraph.getHistoryIndex?.() ?? 0\n const len = this.currentGraph.getHistoryLength?.() ?? 1\n label.textContent = `${idx + 1} / ${len}`\n } catch {\n label.textContent = '— / —'\n }\n }\n\n private connectExampleSource() {\n const example = this.examples[this.currentExample]\n if (!example.source) {\n // No source specified, disconnect any active sources\n this.disconnectAllSources()\n return\n }\n\n // Disconnect existing sources first\n this.disconnectAllSources()\n\n if (example.source.type === 'websocket') {\n this.wsUrl = example.source.url\n this.wsSource = new WebSocketSource({\n url: example.source.url,\n onMessage: this.handleIngestMessage.bind(this),\n onStatus: this.updateWsStatus,\n })\n this.wsSource.connect()\n } else if (example.source.type === 'file') {\n this.fileSource = new FileSource({\n url: example.source.path,\n onMessage: this.handleIngestMessage.bind(this),\n onStatus: this.updateFileStatus,\n })\n this.fileSource.connect()\n }\n }\n\n private disconnectAllSources() {\n this.wsSource?.disconnect()\n this.fsSource?.close()\n this.fileSource?.close()\n this.wsSource = null\n this.fsSource = null\n this.fileSource = null\n this.activeSourceType = null\n this.wsStatus = 'disconnected'\n this.fsStatus = 'disconnected'\n this.fileStatus = 'disconnected'\n this.updateSourceIcon()\n }\n\n private openHelp() {\n if (!this.helpOverlay) {\n this.helpOverlay = document.createElement('div')\n this.helpOverlay.className = 'modal-overlay'\n this.helpOverlay.innerHTML = `\n <div class=\"modal\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"help-title\">\n <div class=\"modal-header\">\n <h3 id=\"help-title\">Editing the Graph</h3>\n <button class=\"modal-close\" title=\"Close\" aria-label=\"Close\">×</button>\n </div>\n <div class=\"modal-body\">\n <p>Here's how to edit the graph:</p>\n <ul>\n <li><strong>Enable editing</strong>: Click \"Edit\"</li>\n <li><strong>Add a node</strong>: Double‑click an empty area</li>\n <li><strong>Edit a node</strong>: Double‑click a node</li>\n <li><strong>Edit an edge</strong>: Double‑click an edge</li>\n <li><strong>Create an edge</strong>: Click and drag from a node (or its port) onto another node; press Esc to cancel</li>\n <li><strong>Pan</strong>: Drag on canvas or edges; <strong>Zoom</strong>: Mouse wheel or controls</li>\n <li><strong>Rebuild</strong>: Use \"Rebuild\" to re-layout from scratch (enabled in edit mode)</li>\n </ul>\n <p>When you're done, click \"Done\" to lock the canvas.</p>\n </div>\n </div>\n `\n document.body.appendChild(this.helpOverlay)\n this.helpOverlay.addEventListener('click', (e) => {\n const target = e.target as HTMLElement\n if (target.classList.contains('modal-overlay') || target.classList.contains('modal-close')) {\n this.closeHelp()\n }\n })\n }\n this.helpOverlay.style.display = 'flex'\n }\n\n private closeHelp() {\n if (this.helpOverlay) this.helpOverlay.style.display = 'none'\n }\n\n private handleIngestMessage = async (msg: any) => {\n if (!this.ingest) return\n await this.ingest.apply(msg)\n }\n\n private updateSourceIcon() {\n const iconBtn = this.rootElement.querySelector('#source-icon')\n if (!iconBtn) return\n iconBtn.classList.remove('active', 'connecting', 'error')\n\n const isConnected = (this.activeSourceType === 'ws' && this.wsStatus === 'connected') ||\n (this.activeSourceType === 'folder' && this.fsStatus === 'connected') ||\n (this.activeSourceType === 'file' && this.fileStatus === 'connected')\n const isConnecting = (this.activeSourceType === 'ws' && this.wsStatus === 'connecting') ||\n (this.activeSourceType === 'folder' && this.fsStatus === 'opening') ||\n (this.activeSourceType === 'file' && this.fileStatus === 'connecting')\n const hasError = (this.activeSourceType === 'ws' && this.wsStatus === 'error') ||\n (this.activeSourceType === 'folder' && this.fsStatus === 'error') ||\n (this.activeSourceType === 'file' && this.fileStatus === 'error')\n\n let icon = '📡'\n if (this.activeSourceType === 'folder') {\n icon = '📁'\n } else if (this.activeSourceType === 'file') {\n icon = '📄'\n }\n\n if (isConnected) {\n iconBtn.classList.add('active')\n iconBtn.textContent = icon\n } else if (isConnecting) {\n iconBtn.classList.add('connecting')\n iconBtn.textContent = icon\n } else if (hasError) {\n iconBtn.classList.add('error')\n iconBtn.textContent = icon\n } else {\n iconBtn.textContent = '📡'\n }\n }\n\n private updateWsStatus = (status: 'connecting' | 'connected' | 'reconnecting' | 'closed' | 'error', detail?: any) => {\n if (status === 'connecting' || status === 'reconnecting') {\n this.wsStatus = 'connecting'\n this.activeSourceType = 'ws'\n } else if (status === 'connected') {\n this.wsStatus = 'connected'\n this.activeSourceType = 'ws'\n if (this.fsSource && this.fsStatus === 'connected') {\n this.fsSource.close()\n }\n if (this.fileSource && this.fileStatus === 'connected') {\n this.fileSource.close()\n }\n } else if (status === 'error') {\n this.wsStatus = 'error'\n } else {\n this.wsStatus = 'disconnected'\n if (this.activeSourceType === 'ws') {\n this.activeSourceType = null\n }\n }\n this.updateSourceIcon()\n this.updateSourceModal()\n }\n\n private updateFsStatus = (status: 'idle' | 'opened' | 'reading' | 'error' | 'closed', detail?: any) => {\n if (status === 'opened') {\n this.fsStatus = 'opening'\n this.activeSourceType = 'folder'\n if (this.wsSource && this.wsStatus === 'connected') {\n this.wsSource.disconnect()\n }\n } else if (status === 'reading') {\n this.fsStatus = 'connected'\n this.activeSourceType = 'folder'\n } else if (status === 'error') {\n this.fsStatus = 'error'\n } else if (status === 'closed') {\n this.fsStatus = 'disconnected'\n if (this.activeSourceType === 'folder') {\n this.activeSourceType = null\n }\n } else {\n this.fsStatus = 'disconnected'\n }\n this.updateSourceIcon()\n this.updateSourceModal()\n }\n\n private updateFileStatus = (status: 'idle' | 'opened' | 'reading' | 'error' | 'closed', detail?: any) => {\n if (status === 'opened') {\n this.fileStatus = 'connecting'\n this.activeSourceType = 'file'\n if (this.wsSource && this.wsStatus === 'connected') {\n this.wsSource.disconnect()\n }\n if (this.fsSource && this.fsStatus === 'connected') {\n this.fsSource.close()\n }\n } else if (status === 'reading') {\n this.fileStatus = 'connected'\n this.activeSourceType = 'file'\n } else if (status === 'error') {\n this.fileStatus = 'error'\n } else if (status === 'closed') {\n this.fileStatus = 'disconnected'\n if (this.activeSourceType === 'file') {\n this.activeSourceType = null\n }\n } else {\n this.fileStatus = 'disconnected'\n }\n this.updateSourceIcon()\n this.updateSourceModal()\n }\n\n private createSourceModal() {\n if (this.sourceModal) return this.sourceModal\n\n this.sourceModal = document.createElement('div')\n this.sourceModal.className = 'modal-overlay'\n this.sourceModal.style.display = 'none'\n this.sourceModal.innerHTML = `\n <div class=\"modal\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"source-modal-title\">\n <div class=\"modal-header\">\n <h3 id=\"source-modal-title\">Data Source Connection</h3>\n <button class=\"modal-close\" title=\"Close\" aria-label=\"Close\">×</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"source-type-selector\">\n <button class=\"source-type-option\" data-source=\"ws\">📡 WebSocket</button>\n <button class=\"source-type-option\" data-source=\"folder\">📁 Folder</button>\n </div>\n\n <div class=\"source-controls\" data-source=\"ws\">\n <div class=\"form-group\">\n <label for=\"source-modal-url\">WebSocket URL</label>\n <input type=\"text\" id=\"source-modal-url\" value=\"${this.wsUrl}\" />\n </div>\n <div class=\"button-group\">\n <button id=\"source-modal-connect-ws\" class=\"primary\">Connect</button>\n <button id=\"source-modal-disconnect-ws\">Disconnect</button>\n <button id=\"source-modal-change-ws\">Change Connection</button>\n </div>\n </div>\n\n <div class=\"source-controls\" data-source=\"folder\">\n <div class=\"form-group\">\n <label>File System Source</label>\n <p style=\"font-size: 0.875rem; color: var(--color-text-muted); margin-top: 0.25rem;\">\n Select a directory containing a graph.ndjson file to watch for changes.\n </p>\n </div>\n <div class=\"button-group\">\n <button id=\"source-modal-connect-folder\" class=\"primary\">Open Folder</button>\n <button id=\"source-modal-disconnect-folder\">Disconnect</button>\n </div>\n </div>\n\n <div id=\"source-modal-status\"></div>\n </div>\n </div>\n `\n document.body.appendChild(this.sourceModal)\n\n this.sourceModal.addEventListener('click', (e) => {\n const target = e.target as HTMLElement\n if (target.classList.contains('modal-overlay') || target.classList.contains('modal-close')) {\n this.closeSourceModal()\n }\n })\n\n this.sourceModal.querySelectorAll('.source-type-option').forEach(btn => {\n btn.addEventListener('click', () => {\n const sourceType = btn.getAttribute('data-source')\n if (sourceType) {\n this.selectSourceType(sourceType as 'ws' | 'folder')\n }\n })\n })\n\n document.getElementById('source-modal-connect-ws')?.addEventListener('click', () => this.handleConnect())\n document.getElementById('source-modal-disconnect-ws')?.addEventListener('click', () => this.handleDisconnect())\n document.getElementById('source-modal-change-ws')?.addEventListener('click', () => this.handleChangeConnection())\n document.getElementById('source-modal-connect-folder')?.addEventListener('click', () => this.handleOpenFolder())\n document.getElementById('source-modal-disconnect-folder')?.addEventListener('click', () => this.handleCloseFolder())\n\n document.getElementById('source-modal-url')?.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && this.wsStatus !== 'connected') {\n this.handleConnect()\n }\n })\n\n return this.sourceModal\n }\n\n private selectSourceType(type: 'ws' | 'folder', skipUpdate = false) {\n if (!this.sourceModal) return\n\n this.sourceModal.querySelectorAll('.source-type-option').forEach(btn => {\n if (btn.getAttribute('data-source') === type) {\n btn.classList.add('active')\n } else {\n btn.classList.remove('active')\n }\n })\n\n this.sourceModal.querySelectorAll('.source-controls').forEach(controls => {\n if (controls.getAttribute('data-source') === type) {\n controls.classList.add('active')\n } else {\n controls.classList.remove('active')\n }\n })\n\n if (!skipUpdate) {\n this.updateSourceModalContent()\n }\n }\n\n private updateSourceModalContent() {\n if (!this.sourceModal) return\n\n const urlInput = document.getElementById('source-modal-url') as HTMLInputElement\n const connectWsBtn = document.getElementById('source-modal-connect-ws') as HTMLButtonElement\n const disconnectWsBtn = document.getElementById('source-modal-disconnect-ws') as HTMLButtonElement\n const changeWsBtn = document.getElementById('source-modal-change-ws') as HTMLButtonElement\n\n if (urlInput && connectWsBtn && disconnectWsBtn && changeWsBtn) {\n const isWsConnected = this.wsStatus === 'connected'\n const isWsConnecting = this.wsStatus === 'connecting'\n\n connectWsBtn.disabled = isWsConnected || isWsConnecting\n disconnectWsBtn.disabled = !isWsConnected || isWsConnecting\n changeWsBtn.disabled = !isWsConnected || isWsConnecting\n urlInput.disabled = isWsConnecting\n }\n\n const connectFolderBtn = document.getElementById('source-modal-connect-folder') as HTMLButtonElement\n const disconnectFolderBtn = document.getElementById('source-modal-disconnect-folder') as HTMLButtonElement\n\n if (connectFolderBtn && disconnectFolderBtn) {\n const isFolderConnected = this.fsStatus === 'connected'\n const isFolderOpening = this.fsStatus === 'opening'\n\n connectFolderBtn.disabled = isFolderConnected || isFolderOpening\n disconnectFolderBtn.disabled = !isFolderConnected || isFolderOpening\n }\n\n const statusDiv = document.getElementById('source-modal-status')\n if (!statusDiv) return\n\n const currentUrl = urlInput?.value || this.wsUrl\n statusDiv.innerHTML = ''\n\n if (this.activeSourceType === 'ws') {\n if (this.wsStatus === 'connecting') {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n <span class=\"loading-spinner\"></span>\n Connecting to ${currentUrl}...\n </div>\n `\n } else if (this.wsStatus === 'connected') {\n statusDiv.innerHTML = `\n <div class=\"status-message success\">\n ✓ Connected to ${currentUrl}\n </div>\n `\n } else if (this.wsStatus === 'error') {\n statusDiv.innerHTML = `\n <div class=\"status-message error\">\n ✗ Connection error. Please check the URL and try again.\n </div>\n `\n } else {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n Not connected\n </div>\n `\n }\n } else if (this.activeSourceType === 'folder') {\n if (this.fsStatus === 'opening') {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n <span class=\"loading-spinner\"></span>\n Opening folder...\n </div>\n `\n } else if (this.fsStatus === 'connected') {\n statusDiv.innerHTML = `\n <div class=\"status-message success\">\n ✓ Folder connected and watching for changes\n </div>\n `\n } else if (this.fsStatus === 'error') {\n statusDiv.innerHTML = `\n <div class=\"status-message error\">\n ✗ Error opening folder. Please try again.\n </div>\n `\n } else {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n Not connected\n </div>\n `\n }\n } else if (this.activeSourceType === 'file') {\n const example = this.examples[this.currentExample]\n const filePath = example.source?.type === 'file' ? example.source.path : ''\n if (this.fileStatus === 'connecting') {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n <span class=\"loading-spinner\"></span>\n Connecting to ${filePath}...\n </div>\n `\n } else if (this.fileStatus === 'connected') {\n statusDiv.innerHTML = `\n <div class=\"status-message success\">\n ✓ Connected to ${filePath}\n </div>\n `\n } else if (this.fileStatus === 'error') {\n statusDiv.innerHTML = `\n <div class=\"status-message error\">\n ✗ Error loading file. Please check the path and try again.\n </div>\n `\n } else {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n Not connected\n </div>\n `\n }\n } else {\n statusDiv.innerHTML = `\n <div class=\"status-message info\">\n Select a source type to connect\n </div>\n `\n }\n }\n\n private updateSourceModal() {\n if (!this.sourceModal) return\n\n // Map file source to ws for modal display (file sources are handled via examples)\n const activeType = (this.activeSourceType === 'file' ? 'ws' : this.activeSourceType) || 'ws'\n this.selectSourceType(activeType as 'ws' | 'folder', true)\n this.updateSourceModalContent()\n }\n\n private openSourceModal() {\n this.createSourceModal()\n if (this.sourceModal) {\n const urlInput = document.getElementById('source-modal-url') as HTMLInputElement\n if (urlInput) {\n urlInput.value = this.wsUrl\n }\n // Map file source to ws for modal display (file sources are handled via examples)\n const activeType = (this.activeSourceType === 'file' ? 'ws' : this.activeSourceType) || 'ws'\n this.selectSourceType(activeType as 'ws' | 'folder')\n this.updateSourceModal()\n this.sourceModal.style.display = 'flex'\n }\n }\n\n private closeSourceModal() {\n if (this.sourceModal) {\n this.sourceModal.style.display = 'none'\n }\n }\n\n private handleConnect() {\n const urlInput = document.getElementById('source-modal-url') as HTMLInputElement\n if (!urlInput) return\n\n const url = urlInput.value.trim() || 'ws://localhost:8787'\n this.wsUrl = url\n\n if (this.wsSource) {\n this.wsSource.disconnect()\n }\n\n this.wsSource = new WebSocketSource({\n url: url,\n onMessage: this.handleIngestMessage.bind(this),\n onStatus: this.updateWsStatus,\n })\n this.wsSource.connect()\n this.updateSourceModal()\n }\n\n private handleDisconnect() {\n this.wsSource?.disconnect()\n this.updateSourceModal()\n }\n\n private handleChangeConnection() {\n if (this.wsSource) {\n this.wsSource.disconnect()\n }\n const urlInput = document.getElementById('source-modal-url') as HTMLInputElement\n if (urlInput) {\n urlInput.focus()\n urlInput.select()\n }\n this.updateSourceModal()\n }\n\n private async handleOpenFolder() {\n if (!this.fsSource) {\n this.fsSource = new FileSystemSource({\n filename: 'graph.ndjson',\n onMessage: this.handleIngestMessage.bind(this),\n onStatus: this.updateFsStatus,\n })\n }\n this.updateSourceModal()\n await this.fsSource.openDirectory()\n }\n\n private handleCloseFolder() {\n this.fsSource?.close()\n this.updateSourceModal()\n }\n\n /**\n * Add or update an example\n */\n addExample(key: string, example: Example) {\n this.examples[key] = example\n this.updateExampleList()\n // If this is the current example, re-render\n if (this.currentExample === key) {\n this.renderGraph()\n this.connectExampleSource()\n }\n }\n\n /**\n * Remove an example\n */\n removeExample(key: string) {\n delete this.examples[key]\n if (this.currentExample === key) {\n // If we removed the current example, switch to the first available\n this.exampleList = Object.keys(this.examples)\n this.currentExample = this.exampleList[0] || ''\n if (this.currentExample) {\n this.renderGraph()\n this.connectExampleSource()\n }\n }\n this.updateExampleList()\n }\n\n /**\n * Update the example list in the DOM\n */\n private updateExampleList() {\n this.exampleList = Object.keys(this.examples)\n const exampleListEl = this.rootElement.querySelector('.example-list')\n if (!exampleListEl) return\n\n exampleListEl.innerHTML = this.exampleList.map((key, i) => {\n const example = this.examples[key]\n const isActive = key === this.currentExample\n return `\n <button class=\"example-btn ${isActive ? 'active' : ''}\" data-example=\"${key}\">\n ${example.name}\n </button>\n `\n }).join('')\n\n // Re-attach event listeners\n exampleListEl.querySelectorAll('.example-btn').forEach(btn => {\n btn.addEventListener('click', () => {\n this.rootElement.querySelectorAll('.example-btn').forEach(b => b.classList.remove('active'))\n btn.classList.add('active')\n this.currentExample = btn.getAttribute('data-example') || this.exampleList[0]\n this.renderGraph()\n this.connectExampleSource()\n })\n })\n }\n}\n\n"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","names":["import_immutable","log","pino","module","log","ISet","type","dir","import_immutable","log","import_immutable","ISet","import_immutable","log","ISet","node","import_immutable","log","ISet","seg","import_immutable","log","import_immutable","log","seg","segs","node","dir","log","tracks","alpha","log","ISet","IMap","IList","import_jsx_runtime","Node","import_jsx_runtime","Seg","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","log","Node","Seg","el","import_jsx_runtime","graph","log","graph","node","edge","styles_default","styles_default"]}
|