graphwise 1.8.0 → 1.9.0

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.
Files changed (125) hide show
  1. package/dist/adjacency-map-BtKzcuJq.js +229 -0
  2. package/dist/adjacency-map-BtKzcuJq.js.map +1 -0
  3. package/dist/adjacency-map-JqBnMNkF.cjs +234 -0
  4. package/dist/adjacency-map-JqBnMNkF.cjs.map +1 -0
  5. package/dist/async/index.cjs +15 -242
  6. package/dist/async/index.js +2 -229
  7. package/dist/expansion/index.cjs +43 -0
  8. package/dist/expansion/index.js +2 -0
  9. package/dist/expansion-ClDhlMK8.js +1704 -0
  10. package/dist/expansion-ClDhlMK8.js.map +1 -0
  11. package/dist/expansion-DaTroIyv.cjs +1949 -0
  12. package/dist/expansion-DaTroIyv.cjs.map +1 -0
  13. package/dist/extraction/index.cjs +630 -0
  14. package/dist/extraction/index.cjs.map +1 -0
  15. package/dist/extraction/index.js +621 -0
  16. package/dist/extraction/index.js.map +1 -0
  17. package/dist/gpu/csr.d.ts +29 -30
  18. package/dist/gpu/csr.d.ts.map +1 -1
  19. package/dist/gpu/dispatch.d.ts +31 -0
  20. package/dist/gpu/dispatch.d.ts.map +1 -0
  21. package/dist/gpu/dispatch.unit.test.d.ts +5 -0
  22. package/dist/gpu/dispatch.unit.test.d.ts.map +1 -0
  23. package/dist/gpu/index.cjs +15 -410
  24. package/dist/gpu/index.d.ts +3 -1
  25. package/dist/gpu/index.d.ts.map +1 -1
  26. package/dist/gpu/index.js +2 -400
  27. package/dist/gpu/kernels/bfs/kernel.d.ts +59 -0
  28. package/dist/gpu/kernels/bfs/kernel.d.ts.map +1 -0
  29. package/dist/gpu/kernels/bfs/logic.d.ts +47 -0
  30. package/dist/gpu/kernels/bfs/logic.d.ts.map +1 -0
  31. package/dist/gpu/kernels/bfs/logic.unit.test.d.ts +2 -0
  32. package/dist/gpu/kernels/bfs/logic.unit.test.d.ts.map +1 -0
  33. package/dist/gpu/kernels/degree-histogram/kernel.d.ts +32 -0
  34. package/dist/gpu/kernels/degree-histogram/kernel.d.ts.map +1 -0
  35. package/dist/gpu/kernels/degree-histogram/logic.d.ts +45 -0
  36. package/dist/gpu/kernels/degree-histogram/logic.d.ts.map +1 -0
  37. package/dist/gpu/kernels/degree-histogram/logic.unit.test.d.ts +2 -0
  38. package/dist/gpu/kernels/degree-histogram/logic.unit.test.d.ts.map +1 -0
  39. package/dist/gpu/kernels/jaccard/kernel.d.ts +40 -0
  40. package/dist/gpu/kernels/jaccard/kernel.d.ts.map +1 -0
  41. package/dist/gpu/kernels/jaccard/logic.d.ts +43 -0
  42. package/dist/gpu/kernels/jaccard/logic.d.ts.map +1 -0
  43. package/dist/gpu/kernels/jaccard/logic.unit.test.d.ts +2 -0
  44. package/dist/gpu/kernels/jaccard/logic.unit.test.d.ts.map +1 -0
  45. package/dist/gpu/kernels/pagerank/kernel.d.ts +44 -0
  46. package/dist/gpu/kernels/pagerank/kernel.d.ts.map +1 -0
  47. package/dist/gpu/kernels/pagerank/logic.d.ts +50 -0
  48. package/dist/gpu/kernels/pagerank/logic.d.ts.map +1 -0
  49. package/dist/gpu/kernels/pagerank/logic.unit.test.d.ts +2 -0
  50. package/dist/gpu/kernels/pagerank/logic.unit.test.d.ts.map +1 -0
  51. package/dist/gpu/kernels/spmv/kernel.d.ts +43 -0
  52. package/dist/gpu/kernels/spmv/kernel.d.ts.map +1 -0
  53. package/dist/gpu/kernels/spmv/logic.d.ts +31 -0
  54. package/dist/gpu/kernels/spmv/logic.d.ts.map +1 -0
  55. package/dist/gpu/kernels/spmv/logic.unit.test.d.ts +2 -0
  56. package/dist/gpu/kernels/spmv/logic.unit.test.d.ts.map +1 -0
  57. package/dist/gpu/operations.d.ts +76 -0
  58. package/dist/gpu/operations.d.ts.map +1 -0
  59. package/dist/gpu/operations.unit.test.d.ts +5 -0
  60. package/dist/gpu/operations.unit.test.d.ts.map +1 -0
  61. package/dist/gpu/root.d.ts +53 -0
  62. package/dist/gpu/root.d.ts.map +1 -0
  63. package/dist/gpu/root.unit.test.d.ts +2 -0
  64. package/dist/gpu/root.unit.test.d.ts.map +1 -0
  65. package/dist/gpu/types.d.ts +3 -8
  66. package/dist/gpu/types.d.ts.map +1 -1
  67. package/dist/gpu-CHiCN0wa.js +16945 -0
  68. package/dist/gpu-CHiCN0wa.js.map +1 -0
  69. package/dist/gpu-Y6owRVMi.cjs +17028 -0
  70. package/dist/gpu-Y6owRVMi.cjs.map +1 -0
  71. package/dist/graph/index.cjs +2 -229
  72. package/dist/graph/index.js +1 -228
  73. package/dist/index/index.cjs +141 -4040
  74. package/dist/index/index.js +15 -3917
  75. package/dist/jaccard-3rCdilwm.js +39 -0
  76. package/dist/jaccard-3rCdilwm.js.map +1 -0
  77. package/dist/jaccard-Bys9_dGW.cjs +50 -0
  78. package/dist/jaccard-Bys9_dGW.cjs.map +1 -0
  79. package/dist/{kmeans-BIgSyGKu.cjs → kmeans-B8x9D1kt.cjs} +1 -1
  80. package/dist/{kmeans-BIgSyGKu.cjs.map → kmeans-B8x9D1kt.cjs.map} +1 -1
  81. package/dist/{kmeans-87ExSUNZ.js → kmeans-DKkL9rAN.js} +1 -1
  82. package/dist/{kmeans-87ExSUNZ.js.map → kmeans-DKkL9rAN.js.map} +1 -1
  83. package/dist/ops-djAsQQSh.cjs +277 -0
  84. package/dist/ops-djAsQQSh.cjs.map +1 -0
  85. package/dist/ops-upIi6JIi.js +212 -0
  86. package/dist/ops-upIi6JIi.js.map +1 -0
  87. package/dist/priority-queue-BIiD1L0k.cjs +148 -0
  88. package/dist/priority-queue-BIiD1L0k.cjs.map +1 -0
  89. package/dist/priority-queue-CFDd5cBg.js +143 -0
  90. package/dist/priority-queue-CFDd5cBg.js.map +1 -0
  91. package/dist/ranking/index.cjs +43 -0
  92. package/dist/ranking/index.js +4 -0
  93. package/dist/ranking/mi/index.cjs +581 -0
  94. package/dist/ranking/mi/index.cjs.map +1 -0
  95. package/dist/ranking/mi/index.js +555 -0
  96. package/dist/ranking/mi/index.js.map +1 -0
  97. package/dist/ranking-3ez5m67U.js +1016 -0
  98. package/dist/ranking-3ez5m67U.js.map +1 -0
  99. package/dist/ranking-DVvajgUZ.cjs +1093 -0
  100. package/dist/ranking-DVvajgUZ.cjs.map +1 -0
  101. package/dist/seeds/index.cjs +1 -1
  102. package/dist/seeds/index.js +1 -1
  103. package/dist/structures/index.cjs +2 -143
  104. package/dist/structures/index.js +1 -142
  105. package/dist/utils/index.cjs +1 -1
  106. package/dist/utils/index.js +1 -1
  107. package/dist/utils-BodeE2Mo.js +22 -0
  108. package/dist/utils-BodeE2Mo.js.map +1 -0
  109. package/dist/utils-CDtCcsyF.cjs +33 -0
  110. package/dist/utils-CDtCcsyF.cjs.map +1 -0
  111. package/package.json +3 -1
  112. package/dist/async/index.cjs.map +0 -1
  113. package/dist/async/index.js.map +0 -1
  114. package/dist/gpu/context.d.ts +0 -118
  115. package/dist/gpu/context.d.ts.map +0 -1
  116. package/dist/gpu/context.unit.test.d.ts +0 -2
  117. package/dist/gpu/context.unit.test.d.ts.map +0 -1
  118. package/dist/gpu/index.cjs.map +0 -1
  119. package/dist/gpu/index.js.map +0 -1
  120. package/dist/graph/index.cjs.map +0 -1
  121. package/dist/graph/index.js.map +0 -1
  122. package/dist/index/index.cjs.map +0 -1
  123. package/dist/index/index.js.map +0 -1
  124. package/dist/structures/index.cjs.map +0 -1
  125. package/dist/structures/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/extraction/ego-network.ts","../../src/extraction/k-core.ts","../../src/extraction/truss.ts","../../src/extraction/motif.ts","../../src/extraction/induced-subgraph.ts","../../src/extraction/node-filter.ts"],"sourcesContent":["/**\n * Ego-network (k-hop neighbourhood) extraction.\n *\n * Extracts the induced subgraph of all nodes within k hops of a centre node.\n */\n\nimport type { NodeId, NodeData, EdgeData, ReadableGraph } from \"../graph\";\nimport { AdjacencyMapGraph } from \"../graph/adjacency-map\";\n\n/**\n * Options for ego-network extraction.\n */\nexport interface EgoNetworkOptions {\n\t/** Number of hops from the centre node. Default: 1. */\n\treadonly hops?: number;\n}\n\n/**\n * Extract the ego-network (k-hop neighbourhood) of a centre node.\n *\n * The ego-network includes all nodes reachable within k hops from the\n * centre node, plus all edges between those nodes (induced subgraph).\n *\n * For directed graphs, the search follows outgoing edges by default.\n * To include incoming edges, use direction 'both' in the underlying traversal.\n *\n * @param graph - The source graph\n * @param centre - The centre node ID\n * @param options - Extraction options\n * @returns An induced subgraph of the k-hop neighbourhood\n * @throws Error if the centre node does not exist in the graph\n *\n * @example\n * ```typescript\n * // 2-hop neighbourhood\n * const ego = extractEgoNetwork(graph, 'A', { hops: 2 });\n * ```\n */\nexport function extractEgoNetwork<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tcentre: NodeId,\n\toptions?: EgoNetworkOptions,\n): AdjacencyMapGraph<N, E> {\n\tconst hops = options?.hops ?? 1;\n\n\tif (!graph.hasNode(centre)) {\n\t\tthrow new Error(`Centre node '${centre}' does not exist in the graph`);\n\t}\n\n\tif (hops < 0) {\n\t\tthrow new Error(`Hops must be non-negative, got ${String(hops)}`);\n\t}\n\n\t// Find all nodes within k hops using BFS\n\tconst nodesInEgoNetwork = new Set<NodeId>([centre]);\n\n\tif (hops > 0) {\n\t\tconst visited = new Set<NodeId>([centre]);\n\t\t// Queue entries: [nodeId, distance from centre]\n\t\tconst queue: [NodeId, number][] = [[centre, 0]];\n\n\t\twhile (queue.length > 0) {\n\t\t\tconst entry = queue.shift();\n\t\t\tif (entry === undefined) break;\n\t\t\tconst [current, distance] = entry;\n\n\t\t\tif (distance < hops) {\n\t\t\t\tfor (const neighbour of graph.neighbours(current)) {\n\t\t\t\t\tif (!visited.has(neighbour)) {\n\t\t\t\t\t\tvisited.add(neighbour);\n\t\t\t\t\t\tnodesInEgoNetwork.add(neighbour);\n\t\t\t\t\t\tqueue.push([neighbour, distance + 1]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Build induced subgraph\n\tconst result = graph.directed\n\t\t? AdjacencyMapGraph.directed<N, E>()\n\t\t: AdjacencyMapGraph.undirected<N, E>();\n\n\t// Add nodes\n\tfor (const nodeId of nodesInEgoNetwork) {\n\t\tconst nodeData = graph.getNode(nodeId);\n\t\tif (nodeData !== undefined) {\n\t\t\tresult.addNode(nodeData);\n\t\t}\n\t}\n\n\t// Add edges between nodes in the ego network\n\tfor (const edge of graph.edges()) {\n\t\tif (\n\t\t\tnodesInEgoNetwork.has(edge.source) &&\n\t\t\tnodesInEgoNetwork.has(edge.target)\n\t\t) {\n\t\t\tresult.addEdge(edge);\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * K-core decomposition algorithm.\n *\n * A k-core is the maximal subgraph where every node has degree at least k.\n * The decomposition is computed by iteratively removing nodes with degree < k.\n */\n\nimport type { NodeId, NodeData, EdgeData, ReadableGraph } from \"../graph\";\nimport { AdjacencyMapGraph } from \"../graph/adjacency-map\";\n\n/**\n * Extract the k-core of a graph.\n *\n * The k-core is the maximal connected subgraph where every node has\n * degree at least k. This is computed using a peeling algorithm that\n * iteratively removes nodes with degree less than k.\n *\n * For undirected graphs, degree counts all adjacent nodes.\n * For directed graphs, degree counts both in- and out-neighbours.\n *\n * @param graph - The source graph\n * @param k - The minimum degree threshold\n * @returns A new graph containing the k-core (may be empty)\n *\n * @example\n * ```typescript\n * // Extract the 3-core (nodes with at least 3 neighbours)\n * const core3 = extractKCore(graph, 3);\n * ```\n */\nexport function extractKCore<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tk: number,\n): AdjacencyMapGraph<N, E> {\n\tif (k < 0) {\n\t\tthrow new Error(`k must be non-negative, got ${String(k)}`);\n\t}\n\n\t// Track remaining nodes and their degrees\n\tconst remaining = new Set<NodeId>();\n\tconst degrees = new Map<NodeId, number>();\n\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tremaining.add(nodeId);\n\t\t// For directed graphs, use total degree (both directions)\n\t\tconst deg = graph.directed\n\t\t\t? graph.degree(nodeId, \"both\")\n\t\t\t: graph.degree(nodeId);\n\t\tdegrees.set(nodeId, deg);\n\t}\n\n\t// Use a queue for nodes to remove (degree < k)\n\tconst toRemove: NodeId[] = [];\n\n\tfor (const [nodeId, deg] of degrees) {\n\t\tif (deg < k) {\n\t\t\ttoRemove.push(nodeId);\n\t\t}\n\t}\n\n\t// Iteratively remove nodes with degree < k\n\twhile (toRemove.length > 0) {\n\t\tconst nodeId = toRemove.shift();\n\t\tif (nodeId === undefined) break;\n\n\t\tif (!remaining.has(nodeId)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tremaining.delete(nodeId);\n\n\t\t// Update degrees of neighbours\n\t\tconst neighbours = graph.directed\n\t\t\t? graph.neighbours(nodeId, \"both\")\n\t\t\t: graph.neighbours(nodeId);\n\n\t\tfor (const neighbour of neighbours) {\n\t\t\tif (remaining.has(neighbour)) {\n\t\t\t\tconst currentDeg = degrees.get(neighbour) ?? 0;\n\t\t\t\tconst newDeg = currentDeg - 1;\n\t\t\t\tdegrees.set(neighbour, newDeg);\n\n\t\t\t\tif (newDeg < k && newDeg === k - 1) {\n\t\t\t\t\t// Only add to queue if crossing below k threshold\n\t\t\t\t\ttoRemove.push(neighbour);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Build the result as an induced subgraph\n\tconst result = graph.directed\n\t\t? AdjacencyMapGraph.directed<N, E>()\n\t\t: AdjacencyMapGraph.undirected<N, E>();\n\n\t// Add remaining nodes\n\tfor (const nodeId of remaining) {\n\t\tconst nodeData = graph.getNode(nodeId);\n\t\tif (nodeData !== undefined) {\n\t\t\tresult.addNode(nodeData);\n\t\t}\n\t}\n\n\t// Add edges between remaining nodes\n\tfor (const edge of graph.edges()) {\n\t\tif (remaining.has(edge.source) && remaining.has(edge.target)) {\n\t\t\tresult.addEdge(edge);\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * K-truss decomposition algorithm.\n *\n * A k-truss is the maximal subgraph where every edge participates in at\n * least k-2 triangles. The 2-truss is the entire graph, the 3-truss\n * requires each edge to be in at least one triangle, etc.\n */\n\nimport type { NodeId, NodeData, EdgeData, ReadableGraph } from \"../graph\";\nimport { AdjacencyMapGraph } from \"../graph/adjacency-map\";\n\n/**\n * Count triangles involving a given edge.\n *\n * For an edge (u, v), count common neighbours of u and v.\n * Each common neighbour w forms a triangle u-v-w.\n *\n * @param graph - The graph\n * @param u - First endpoint\n * @param v - Second endpoint\n * @returns Number of triangles containing the edge (u, v)\n */\nfunction countEdgeTriangles(\n\tgraph: ReadableGraph,\n\tu: NodeId,\n\tv: NodeId,\n): number {\n\tconst uNeighbours = new Set(graph.neighbours(u));\n\tlet count = 0;\n\n\tfor (const w of graph.neighbours(v)) {\n\t\tif (w !== u && uNeighbours.has(w)) {\n\t\t\tcount++;\n\t\t}\n\t}\n\n\treturn count;\n}\n\n/**\n * Extract the k-truss of a graph.\n *\n * The k-truss is the maximal subgraph where every edge participates in\n * at least k-2 triangles. This is computed by iteratively removing edges\n * with fewer than k-2 triangles, then removing isolated nodes.\n *\n * Note: K-truss is typically defined for undirected graphs. For directed\n * graphs, this treats the graph as undirected for triangle counting.\n *\n * @param graph - The source graph\n * @param k - The minimum triangle count threshold (edge must be in >= k-2 triangles)\n * @returns A new graph containing the k-truss (may be empty)\n *\n * @example\n * ```typescript\n * // Extract the 3-truss (edges in at least 1 triangle)\n * const truss3 = extractKTruss(graph, 3);\n * ```\n */\nexport function extractKTruss<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tk: number,\n): AdjacencyMapGraph<N, E> {\n\tif (k < 2) {\n\t\tthrow new Error(`k must be at least 2, got ${String(k)}`);\n\t}\n\n\tconst minTriangles = k - 2;\n\n\t// Build undirected adjacency for triangle counting\n\t// Store as Map<NodeId, Set<NodeId>> for efficient lookup\n\tconst adjacency = new Map<NodeId, Set<NodeId>>();\n\tconst edgeData = new Map<string, E>();\n\tconst remainingEdges = new Set<string>();\n\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tadjacency.set(nodeId, new Set());\n\t}\n\n\t// Build adjacency (treating as undirected)\n\tfor (const edge of graph.edges()) {\n\t\tconst { source, target } = edge;\n\n\t\t// Add to adjacency (both directions)\n\t\tadjacency.get(source)?.add(target);\n\t\tadjacency.get(target)?.add(source);\n\n\t\t// Store edge data with canonical key\n\t\tconst key =\n\t\t\tsource < target ? `${source}::${target}` : `${target}::${source}`;\n\t\tedgeData.set(key, edge);\n\t\tremainingEdges.add(key);\n\t}\n\n\t// Compute initial triangle counts for each edge\n\tconst triangleCounts = new Map<string, number>();\n\tconst edgesToRemove: string[] = [];\n\n\tfor (const key of remainingEdges) {\n\t\tconst edge = edgeData.get(key);\n\t\tif (edge !== undefined) {\n\t\t\tconst count = countEdgeTriangles(graph, edge.source, edge.target);\n\t\t\ttriangleCounts.set(key, count);\n\t\t\tif (count < minTriangles) {\n\t\t\t\tedgesToRemove.push(key);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Iteratively remove edges with insufficient triangles\n\twhile (edgesToRemove.length > 0) {\n\t\tconst edgeKey = edgesToRemove.shift();\n\t\tif (edgeKey === undefined) break;\n\n\t\tif (!remainingEdges.has(edgeKey)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tremainingEdges.delete(edgeKey);\n\t\tconst edge = edgeData.get(edgeKey);\n\n\t\tif (edge === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { source, target } = edge;\n\n\t\t// Remove from adjacency\n\t\tadjacency.get(source)?.delete(target);\n\t\tadjacency.get(target)?.delete(source);\n\n\t\t// Find triangles that were broken and update counts\n\t\t// Common neighbours form triangles (source, target, neighbour)\n\t\tconst sourceNeighbours = adjacency.get(source);\n\t\tif (sourceNeighbours !== undefined) {\n\t\t\tfor (const w of adjacency.get(target) ?? []) {\n\t\t\t\tif (sourceNeighbours.has(w)) {\n\t\t\t\t\t// Triangle (source, target, w) is broken\n\t\t\t\t\t// Update triangle counts for edges (source, w) and (target, w)\n\t\t\t\t\tconst keySw = source < w ? `${source}::${w}` : `${w}::${source}`;\n\t\t\t\t\tconst keyTw = target < w ? `${target}::${w}` : `${w}::${target}`;\n\n\t\t\t\t\tfor (const keyToUpdate of [keySw, keyTw]) {\n\t\t\t\t\t\tif (remainingEdges.has(keyToUpdate)) {\n\t\t\t\t\t\t\tconst currentCount = triangleCounts.get(keyToUpdate) ?? 0;\n\t\t\t\t\t\t\tconst newCount = currentCount - 1;\n\t\t\t\t\t\t\ttriangleCounts.set(keyToUpdate, newCount);\n\n\t\t\t\t\t\t\tif (newCount < minTriangles && newCount === minTriangles - 1) {\n\t\t\t\t\t\t\t\tedgesToRemove.push(keyToUpdate);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Determine which nodes are still connected by remaining edges\n\tconst nodesWithEdges = new Set<NodeId>();\n\tfor (const key of remainingEdges) {\n\t\tconst edge = edgeData.get(key);\n\t\tif (edge !== undefined) {\n\t\t\tnodesWithEdges.add(edge.source);\n\t\t\tnodesWithEdges.add(edge.target);\n\t\t}\n\t}\n\n\t// Build the result\n\tconst result = graph.directed\n\t\t? AdjacencyMapGraph.directed<N, E>()\n\t\t: AdjacencyMapGraph.undirected<N, E>();\n\n\t// Add nodes that have at least one remaining edge\n\tfor (const nodeId of nodesWithEdges) {\n\t\tconst nodeData = graph.getNode(nodeId);\n\t\tif (nodeData !== undefined) {\n\t\t\tresult.addNode(nodeData);\n\t\t}\n\t}\n\n\t// Add remaining edges\n\tfor (const key of remainingEdges) {\n\t\tconst edge = edgeData.get(key);\n\t\tif (\n\t\t\tedge !== undefined &&\n\t\t\tresult.hasNode(edge.source) &&\n\t\t\tresult.hasNode(edge.target)\n\t\t) {\n\t\t\tresult.addEdge(edge);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Compute the truss number for each edge.\n *\n * The truss number of an edge is the largest k such that the edge\n * belongs to the k-truss.\n *\n * @param graph - The source graph\n * @returns Map from edge key (canonical \"u::v\") to truss number\n *\n * @example\n * ```typescript\n * const trussNumbers = computeTrussNumbers(graph);\n * const edgeKey = 'A::B'; // where A < B lexicographically\n * console.log(`Edge A-B is in the ${trussNumbers.get(edgeKey)}-truss`);\n * ```\n */\nexport function computeTrussNumbers<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n): Map<string, number> {\n\t// Build adjacency and edge tracking\n\tconst adjacency = new Map<NodeId, Set<NodeId>>();\n\tconst edgeData = new Map<string, E>();\n\tconst remainingEdges = new Set<string>();\n\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tadjacency.set(nodeId, new Set());\n\t}\n\n\tfor (const edge of graph.edges()) {\n\t\tconst { source, target } = edge;\n\t\tadjacency.get(source)?.add(target);\n\t\tadjacency.get(target)?.add(source);\n\n\t\tconst key =\n\t\t\tsource < target ? `${source}::${target}` : `${target}::${source}`;\n\t\tedgeData.set(key, edge);\n\t\tremainingEdges.add(key);\n\t}\n\n\t// Compute initial triangle counts\n\tconst triangleCounts = new Map<string, number>();\n\tfor (const key of remainingEdges) {\n\t\tconst edge = edgeData.get(key);\n\t\tif (edge !== undefined) {\n\t\t\ttriangleCounts.set(\n\t\t\t\tkey,\n\t\t\t\tcountEdgeTriangles(graph, edge.source, edge.target),\n\t\t\t);\n\t\t}\n\t}\n\n\t// Result map\n\tconst trussNumbers = new Map<string, number>();\n\n\t// Process edges in order of triangle count\n\tconst edgesByTriangleCount = new Map<number, Set<string>>();\n\n\tfor (const [key, count] of triangleCounts) {\n\t\tif (!edgesByTriangleCount.has(count)) {\n\t\t\tedgesByTriangleCount.set(count, new Set());\n\t\t}\n\t\tedgesByTriangleCount.get(count)?.add(key);\n\t}\n\n\t// Process from lowest triangle count upwards\n\tconst sortedCounts = [...edgesByTriangleCount.keys()].sort((a, b) => a - b);\n\n\tfor (const currentCount of sortedCounts) {\n\t\tconst bucket = edgesByTriangleCount.get(currentCount);\n\t\tif (bucket === undefined) continue;\n\n\t\twhile (bucket.size > 0) {\n\t\t\tconst edgeKey = bucket.values().next().value;\n\t\t\tif (edgeKey === undefined) break;\n\t\t\tbucket.delete(edgeKey);\n\n\t\t\tif (!remainingEdges.has(edgeKey)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Truss number is triangle count + 2\n\t\t\tconst trussNumber = currentCount + 2;\n\t\t\ttrussNumbers.set(edgeKey, trussNumber);\n\t\t\tremainingEdges.delete(edgeKey);\n\n\t\t\tconst edge = edgeData.get(edgeKey);\n\t\t\tif (edge === undefined) continue;\n\n\t\t\tconst { source, target } = edge;\n\n\t\t\t// Remove from adjacency\n\t\t\tadjacency.get(source)?.delete(target);\n\t\t\tadjacency.get(target)?.delete(source);\n\n\t\t\t// Update triangle counts for affected edges\n\t\t\tconst sourceNeighbours = adjacency.get(source);\n\t\t\tif (sourceNeighbours !== undefined) {\n\t\t\t\tfor (const w of adjacency.get(target) ?? []) {\n\t\t\t\t\tif (sourceNeighbours.has(w)) {\n\t\t\t\t\t\tconst keySw = source < w ? `${source}::${w}` : `${w}::${source}`;\n\t\t\t\t\t\tconst keyTw = target < w ? `${target}::${w}` : `${w}::${target}`;\n\n\t\t\t\t\t\tfor (const keyToUpdate of [keySw, keyTw]) {\n\t\t\t\t\t\t\tif (remainingEdges.has(keyToUpdate)) {\n\t\t\t\t\t\t\t\tconst oldCount = triangleCounts.get(keyToUpdate) ?? 0;\n\t\t\t\t\t\t\t\tconst newCount = oldCount - 1;\n\t\t\t\t\t\t\t\ttriangleCounts.set(keyToUpdate, newCount);\n\n\t\t\t\t\t\t\t\t// Move to new bucket\n\t\t\t\t\t\t\t\tedgesByTriangleCount.get(oldCount)?.delete(keyToUpdate);\n\t\t\t\t\t\t\t\tif (!edgesByTriangleCount.has(newCount)) {\n\t\t\t\t\t\t\t\t\tedgesByTriangleCount.set(newCount, new Set());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tedgesByTriangleCount.get(newCount)?.add(keyToUpdate);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn trussNumbers;\n}\n","/**\n * Motif enumeration algorithms.\n *\n * Motifs are small recurring subgraph patterns. This module provides\n * enumeration and counting of motifs of size 3 and 4.\n */\n\nimport type { NodeId, NodeData, EdgeData, ReadableGraph } from \"../graph\";\n\n/**\n * Result of a motif census operation.\n */\nexport interface MotifCensus {\n\t/** Map from motif type identifier to count */\n\treadonly counts: ReadonlyMap<string, number>;\n\t/** Optional map from motif type to node instances */\n\treadonly instances?: ReadonlyMap<string, readonly NodeId[][]>;\n}\n\n/**\n * Canonicalise an edge pattern for hashing.\n *\n * Returns a canonical string representation of a small graph pattern.\n */\nfunction canonicalisePattern(\n\tnodeCount: number,\n\tedges: readonly (readonly [number, number])[],\n): string {\n\t// For small graphs (3-4 nodes), we enumerate all permutations\n\t// and return the lexicographically smallest edge list\n\n\tconst permutations = getPermutations(nodeCount);\n\tlet minPattern: string | null = null;\n\n\tfor (const perm of permutations) {\n\t\t// Transform edges according to permutation\n\t\tconst transformedEdges = edges\n\t\t\t.map(([u, v]) => {\n\t\t\t\tconst pu = perm[u] ?? -1;\n\t\t\t\tconst pv = perm[v] ?? -1;\n\t\t\t\tif (pu < 0 || pv < 0) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\treturn pu < pv\n\t\t\t\t\t? `${String(pu)}-${String(pv)}`\n\t\t\t\t\t: `${String(pv)}-${String(pu)}`;\n\t\t\t})\n\t\t\t.filter((edge): edge is string => edge !== undefined)\n\t\t\t.sort()\n\t\t\t.join(\",\");\n\n\t\tif (minPattern === null || transformedEdges < minPattern) {\n\t\t\tminPattern = transformedEdges;\n\t\t}\n\t}\n\n\treturn minPattern ?? \"\";\n}\n\n/**\n * Generate all permutations of [0, n-1].\n */\nfunction getPermutations(n: number): number[][] {\n\tif (n === 0) return [[]];\n\tif (n === 1) return [[0]];\n\n\tconst result: number[][] = [];\n\tconst arr = Array.from({ length: n }, (_, i) => i);\n\n\tfunction permute(start: number): void {\n\t\tif (start === n - 1) {\n\t\t\tresult.push([...arr]);\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = start; i < n; i++) {\n\t\t\tconst startVal = arr[start];\n\t\t\tconst iVal = arr[i];\n\t\t\tif (startVal === undefined || iVal === undefined) continue;\n\t\t\tarr[start] = iVal;\n\t\t\tarr[i] = startVal;\n\t\t\tpermute(start + 1);\n\t\t\tarr[start] = startVal;\n\t\t\tarr[i] = iVal;\n\t\t}\n\t}\n\n\tpermute(0);\n\treturn result;\n}\n\n/**\n * Enumerate all 3-node motifs in the graph.\n *\n * A 3-node motif (triad) can be one of 4 isomorphism classes for undirected graphs:\n * - Empty: no edges\n * - 1-edge: single edge\n * - 2-star: two edges sharing a node (path of length 2)\n * - Triangle: three edges (complete graph K3)\n *\n * For directed graphs, there are 16 isomorphism classes.\n *\n * @param graph - The source graph\n * @param includeInstances - Whether to include node instances in the result\n * @returns Motif census with counts and optionally instances\n */\nfunction enumerate3NodeMotifs<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tincludeInstances: boolean,\n): MotifCensus {\n\tconst counts = new Map<string, number>();\n\tconst instances = includeInstances\n\t\t? new Map<string, NodeId[][]>()\n\t\t: undefined;\n\n\tconst nodeList = [...graph.nodeIds()];\n\tconst n = nodeList.length;\n\n\t// Iterate over all triples of nodes\n\tfor (let i = 0; i < n; i++) {\n\t\tconst ni = nodeList[i];\n\t\tif (ni === undefined) continue;\n\t\tfor (let j = i + 1; j < n; j++) {\n\t\t\tconst nj = nodeList[j];\n\t\t\tif (nj === undefined) continue;\n\t\t\tfor (let k = j + 1; k < n; k++) {\n\t\t\t\tconst nk = nodeList[k];\n\t\t\t\tif (nk === undefined) continue;\n\n\t\t\t\tconst nodes: [NodeId, NodeId, NodeId] = [ni, nj, nk];\n\t\t\t\tconst edges: [number, number][] = [];\n\n\t\t\t\t// Check all 3 possible edges\n\t\t\t\tconst edgeChecks: [number, number][] = [\n\t\t\t\t\t[0, 1],\n\t\t\t\t\t[0, 2],\n\t\t\t\t\t[1, 2],\n\t\t\t\t];\n\n\t\t\t\tfor (const [u, v] of edgeChecks) {\n\t\t\t\t\tconst nu = nodes[u];\n\t\t\t\t\tconst nv = nodes[v];\n\t\t\t\t\tif (nu === undefined || nv === undefined) continue;\n\n\t\t\t\t\tif (graph.getEdge(nu, nv) !== undefined) {\n\t\t\t\t\t\tedges.push([u, v]);\n\t\t\t\t\t} else if (!graph.directed && graph.getEdge(nv, nu) !== undefined) {\n\t\t\t\t\t\tedges.push([u, v]);\n\t\t\t\t\t} else if (graph.directed && graph.getEdge(nv, nu) !== undefined) {\n\t\t\t\t\t\t// For directed graphs, store directed edge\n\t\t\t\t\t\tedges.push([v, u]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst pattern = canonicalisePattern(3, edges);\n\t\t\t\tconst count = counts.get(pattern) ?? 0;\n\t\t\t\tcounts.set(pattern, count + 1);\n\n\t\t\t\tif (includeInstances && instances !== undefined) {\n\t\t\t\t\tif (!instances.has(pattern)) {\n\t\t\t\t\t\tinstances.set(pattern, []);\n\t\t\t\t\t}\n\t\t\t\t\tconst patternInstances = instances.get(pattern);\n\t\t\t\t\tif (patternInstances !== undefined) {\n\t\t\t\t\t\tpatternInstances.push([ni, nj, nk]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (instances !== undefined) {\n\t\treturn { counts, instances };\n\t}\n\treturn { counts };\n}\n\n/**\n * Enumerate all 4-node motifs in the graph.\n *\n * A 4-node motif can be one of 11 isomorphism classes for undirected graphs\n * (ranging from empty to complete K4), or many more for directed graphs.\n *\n * @param graph - The source graph\n * @param includeInstances - Whether to include node instances in the result\n * @returns Motif census with counts and optionally instances\n */\nfunction enumerate4NodeMotifs<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tincludeInstances: boolean,\n): MotifCensus {\n\tconst counts = new Map<string, number>();\n\tconst instances = includeInstances\n\t\t? new Map<string, NodeId[][]>()\n\t\t: undefined;\n\n\tconst nodeList = [...graph.nodeIds()];\n\tconst n = nodeList.length;\n\n\t// Iterate over all quadruples of nodes\n\tfor (let i = 0; i < n; i++) {\n\t\tconst ni = nodeList[i];\n\t\tif (ni === undefined) continue;\n\t\tfor (let j = i + 1; j < n; j++) {\n\t\t\tconst nj = nodeList[j];\n\t\t\tif (nj === undefined) continue;\n\t\t\tfor (let k = j + 1; k < n; k++) {\n\t\t\t\tconst nk = nodeList[k];\n\t\t\t\tif (nk === undefined) continue;\n\t\t\t\tfor (let l = k + 1; l < n; l++) {\n\t\t\t\t\tconst nl = nodeList[l];\n\t\t\t\t\tif (nl === undefined) continue;\n\n\t\t\t\t\tconst nodes: [NodeId, NodeId, NodeId, NodeId] = [ni, nj, nk, nl];\n\t\t\t\t\tconst edges: [number, number][] = [];\n\n\t\t\t\t\t// Check all 6 possible edges\n\t\t\t\t\tconst edgeChecks: [number, number][] = [\n\t\t\t\t\t\t[0, 1],\n\t\t\t\t\t\t[0, 2],\n\t\t\t\t\t\t[0, 3],\n\t\t\t\t\t\t[1, 2],\n\t\t\t\t\t\t[1, 3],\n\t\t\t\t\t\t[2, 3],\n\t\t\t\t\t];\n\n\t\t\t\t\tfor (const [u, v] of edgeChecks) {\n\t\t\t\t\t\tconst nu = nodes[u];\n\t\t\t\t\t\tconst nv = nodes[v];\n\t\t\t\t\t\tif (nu === undefined || nv === undefined) continue;\n\n\t\t\t\t\t\tif (graph.getEdge(nu, nv) !== undefined) {\n\t\t\t\t\t\t\tedges.push([u, v]);\n\t\t\t\t\t\t} else if (!graph.directed && graph.getEdge(nv, nu) !== undefined) {\n\t\t\t\t\t\t\tedges.push([u, v]);\n\t\t\t\t\t\t} else if (graph.directed && graph.getEdge(nv, nu) !== undefined) {\n\t\t\t\t\t\t\t// For directed graphs, store directed edge\n\t\t\t\t\t\t\tedges.push([v, u]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst pattern = canonicalisePattern(4, edges);\n\t\t\t\t\tconst count = counts.get(pattern) ?? 0;\n\t\t\t\t\tcounts.set(pattern, count + 1);\n\n\t\t\t\t\tif (includeInstances && instances !== undefined) {\n\t\t\t\t\t\tif (!instances.has(pattern)) {\n\t\t\t\t\t\t\tinstances.set(pattern, []);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst patternInstances = instances.get(pattern);\n\t\t\t\t\t\tif (patternInstances !== undefined) {\n\t\t\t\t\t\t\tpatternInstances.push([ni, nj, nk, nl]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (instances !== undefined) {\n\t\treturn { counts, instances };\n\t}\n\treturn { counts };\n}\n\n/**\n * Human-readable names for common 3-node motifs.\n */\nconst MOTIF_3_NAMES: ReadonlyMap<string, string> = new Map([\n\t[\"\", \"empty\"], // No edges\n\t[\"0-1\", \"1-edge\"], // Single edge\n\t[\"0-1,0-2\", \"2-star\"], // Path of length 2 (V-shape)\n\t[\"0-1,1-2\", \"path-3\"], // Path of length 2 (alternative)\n\t[\"0-1,0-2,1-2\", \"triangle\"], // Complete K3\n]);\n\n/**\n * Human-readable names for common 4-node motifs.\n */\nconst MOTIF_4_NAMES: ReadonlyMap<string, string> = new Map([\n\t[\"\", \"empty\"],\n\t[\"0-1\", \"1-edge\"],\n\t[\"0-1,0-2\", \"2-star\"],\n\t[\"0-1,0-2,0-3\", \"3-star\"],\n\t[\"0-1,0-2,1-2\", \"triangle\"], // K3 + isolated\n\t[\"0-1,0-2,1-2,2-3\", \"paw\"], // Triangle with tail\n\t[\"0-1,0-2,2-3\", \"path-4\"], // Path of length 3\n\t[\"0-1,0-2,1-3,2-3\", \"4-cycle\"], // Cycle C4\n\t[\"0-1,0-2,1-2,0-3,1-3\", \"diamond\"], // K4 minus one edge\n\t[\"0-1,0-2,0-3,1-2,1-3,2-3\", \"K4\"], // Complete graph\n]);\n\n/**\n * Enumerate motifs of a given size in the graph.\n *\n * This function counts all occurrences of each distinct motif type\n * (isomorphism class) in the graph. For graphs with many nodes,\n * 4-motif enumeration can be expensive (O(n^4) worst case).\n *\n * @param graph - The source graph\n * @param size - Motif size (3 or 4 nodes)\n * @returns Motif census with counts per motif type\n *\n * @example\n * ```typescript\n * // Count all triangles and other 3-node patterns\n * const census3 = enumerateMotifs(graph, 3);\n * console.log(`Triangles: ${census3.counts.get('0-1,0-2,1-2')}`);\n *\n * // Count 4-node patterns\n * const census4 = enumerateMotifs(graph, 4);\n * ```\n */\nexport function enumerateMotifs<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tsize: 3 | 4,\n): MotifCensus {\n\t// Don't include instances by default for efficiency\n\treturn size === 3\n\t\t? enumerate3NodeMotifs(graph, false)\n\t\t: enumerate4NodeMotifs(graph, false);\n}\n\n/**\n * Enumerate motifs with optional instance tracking.\n *\n * @param graph - The source graph\n * @param size - Motif size (3 or 4 nodes)\n * @param includeInstances - Whether to include node instances\n * @returns Motif census with counts and optionally instances\n */\nexport function enumerateMotifsWithInstances<\n\tN extends NodeData,\n\tE extends EdgeData,\n>(\n\tgraph: ReadableGraph<N, E>,\n\tsize: 3 | 4,\n\tincludeInstances: boolean,\n): MotifCensus {\n\treturn size === 3\n\t\t? enumerate3NodeMotifs(graph, includeInstances)\n\t\t: enumerate4NodeMotifs(graph, includeInstances);\n}\n\n/**\n * Get a human-readable name for a motif pattern.\n *\n * @param pattern - The canonical pattern string\n * @param size - Motif size (3 or 4 nodes)\n * @returns A human-readable name, or the pattern itself if unknown\n */\nexport function getMotifName(pattern: string, size: 3 | 4): string {\n\tconst names = size === 3 ? MOTIF_3_NAMES : MOTIF_4_NAMES;\n\treturn names.get(pattern) ?? pattern;\n}\n","/**\n * Induced subgraph extraction.\n *\n * Extracts a subgraph containing exactly the specified nodes and all\n * edges between them from the original graph.\n */\n\nimport type { NodeId, NodeData, EdgeData, ReadableGraph } from \"../graph\";\nimport { AdjacencyMapGraph } from \"../graph/adjacency-map\";\n\n/**\n * Extract the induced subgraph containing exactly the specified nodes.\n *\n * The induced subgraph includes all nodes from the input set that exist\n * in the original graph, plus all edges where both endpoints are in the set.\n *\n * @param graph - The source graph\n * @param nodes - Set of node IDs to include in the subgraph\n * @returns A new graph containing the induced subgraph\n *\n * @example\n * ```typescript\n * const subgraph = extractInducedSubgraph(graph, new Set(['A', 'B', 'C']));\n * ```\n */\nexport function extractInducedSubgraph<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tnodes: ReadonlySet<NodeId>,\n): AdjacencyMapGraph<N, E> {\n\tconst result = graph.directed\n\t\t? AdjacencyMapGraph.directed<N, E>()\n\t\t: AdjacencyMapGraph.undirected<N, E>();\n\n\t// Add nodes that exist in both the set and the graph\n\tfor (const nodeId of nodes) {\n\t\tconst nodeData = graph.getNode(nodeId);\n\t\tif (nodeData !== undefined) {\n\t\t\tresult.addNode(nodeData);\n\t\t}\n\t}\n\n\t// Add edges where both endpoints exist in the result\n\tfor (const edge of graph.edges()) {\n\t\tif (result.hasNode(edge.source) && result.hasNode(edge.target)) {\n\t\t\tresult.addEdge(edge);\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * Filtered subgraph extraction.\n *\n * Extracts a subgraph based on predicate functions for nodes and edges.\n */\n\nimport type { NodeId, NodeData, EdgeData, ReadableGraph } from \"../graph\";\nimport { AdjacencyMapGraph } from \"../graph/adjacency-map\";\n\n/**\n * Options for filtering a subgraph.\n */\nexport interface FilterOptions<N extends NodeData, E extends EdgeData> {\n\t/** Predicate to filter nodes. Return true to include the node. */\n\treadonly nodePredicate?: (node: N) => boolean;\n\t/** Predicate to filter edges. Return true to include the edge. */\n\treadonly edgePredicate?: (edge: E) => boolean;\n\t/** Whether to remove nodes that become isolated after edge filtering. Default: false. */\n\treadonly removeIsolated?: boolean;\n}\n\n/**\n * Extract a filtered subgraph based on node and edge predicates.\n *\n * Nodes are first filtered by the node predicate (if provided).\n * Edges are then filtered by the edge predicate (if provided), and only\n * retained if both endpoints pass the node predicate.\n *\n * @param graph - The source graph\n * @param options - Filter options specifying node/edge predicates\n * @returns A new graph containing only nodes and edges that pass the predicates\n *\n * @example\n * ```typescript\n * // Extract subgraph of high-weight nodes\n * const filtered = filterSubgraph(graph, {\n * nodePredicate: (node) => (node.weight ?? 0) > 0.5,\n * removeIsolated: true\n * });\n * ```\n */\nexport function filterSubgraph<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\toptions?: FilterOptions<N, E>,\n): AdjacencyMapGraph<N, E> {\n\tconst {\n\t\tnodePredicate,\n\t\tedgePredicate,\n\t\tremoveIsolated = false,\n\t} = options ?? {};\n\n\tconst result = graph.directed\n\t\t? AdjacencyMapGraph.directed<N, E>()\n\t\t: AdjacencyMapGraph.undirected<N, E>();\n\n\t// Track which nodes were added\n\tconst includedNodes = new Set<NodeId>();\n\n\t// Add nodes that pass the predicate\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tconst nodeData = graph.getNode(nodeId);\n\t\tif (nodeData !== undefined) {\n\t\t\tif (nodePredicate === undefined || nodePredicate(nodeData)) {\n\t\t\t\tresult.addNode(nodeData);\n\t\t\t\tincludedNodes.add(nodeId);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add edges that pass both endpoint and edge predicates\n\tfor (const edge of graph.edges()) {\n\t\tif (!includedNodes.has(edge.source) || !includedNodes.has(edge.target)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (edgePredicate === undefined || edgePredicate(edge)) {\n\t\t\tresult.addEdge(edge);\n\t\t}\n\t}\n\n\t// Remove isolated nodes if requested\n\tif (removeIsolated) {\n\t\tconst isolatedNodes: NodeId[] = [];\n\t\tfor (const nodeId of result.nodeIds()) {\n\t\t\tif (result.degree(nodeId) === 0) {\n\t\t\t\tisolatedNodes.push(nodeId);\n\t\t\t}\n\t\t}\n\t\tfor (const nodeId of isolatedNodes) {\n\t\t\tresult.removeNode(nodeId);\n\t\t}\n\t}\n\n\treturn result;\n}\n"],"mappings":"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"}