@graphty/layout 1.2.9 → 1.4.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.
- package/README.md +400 -409
- package/dist/layout.js +884 -817
- package/dist/layout.js.map +1 -1
- package/dist/src/algorithms/index.d.ts +3 -2
- package/dist/src/algorithms/index.d.ts.map +1 -0
- package/dist/src/algorithms/index.js +2 -2
- package/dist/src/algorithms/index.js.map +1 -1
- package/dist/src/algorithms/optimization/index.d.ts +5 -4
- package/dist/src/algorithms/optimization/index.d.ts.map +1 -0
- package/dist/src/algorithms/optimization/index.js +3 -3
- package/dist/src/algorithms/optimization/index.js.map +1 -1
- package/dist/src/algorithms/optimization/kamada-kawai-solver.d.ts +3 -5
- package/dist/src/algorithms/optimization/kamada-kawai-solver.d.ts.map +1 -0
- package/dist/src/algorithms/optimization/kamada-kawai-solver.js +6 -9
- package/dist/src/algorithms/optimization/kamada-kawai-solver.js.map +1 -1
- package/dist/src/algorithms/optimization/lbfgs.d.ts +3 -3
- package/dist/src/algorithms/optimization/lbfgs.d.ts.map +1 -0
- package/dist/src/algorithms/optimization/lbfgs.js +5 -7
- package/dist/src/algorithms/optimization/lbfgs.js.map +1 -1
- package/dist/src/algorithms/optimization/line-search.d.ts +1 -1
- package/dist/src/algorithms/optimization/line-search.d.ts.map +1 -0
- package/dist/src/algorithms/optimization/line-search.js +0 -1
- package/dist/src/algorithms/optimization/line-search.js.map +1 -1
- package/dist/src/algorithms/optimization/types.d.ts +2 -1
- package/dist/src/algorithms/optimization/types.d.ts.map +1 -0
- package/dist/src/algorithms/planarity/check.d.ts +5 -4
- package/dist/src/algorithms/planarity/check.d.ts.map +1 -0
- package/dist/src/algorithms/planarity/check.js +6 -6
- package/dist/src/algorithms/planarity/check.js.map +1 -1
- package/dist/src/algorithms/planarity/embedding.d.ts +5 -6
- package/dist/src/algorithms/planarity/embedding.d.ts.map +1 -0
- package/dist/src/algorithms/planarity/embedding.js +15 -14
- package/dist/src/algorithms/planarity/embedding.js.map +1 -1
- package/dist/src/algorithms/planarity/index.d.ts +5 -4
- package/dist/src/algorithms/planarity/index.d.ts.map +1 -0
- package/dist/src/algorithms/planarity/index.js +4 -4
- package/dist/src/algorithms/planarity/index.js.map +1 -1
- package/dist/src/algorithms/planarity/lr-test.d.ts +3 -2
- package/dist/src/algorithms/planarity/lr-test.d.ts.map +1 -0
- package/dist/src/algorithms/planarity/lr-test.js +2 -2
- package/dist/src/algorithms/planarity/lr-test.js.map +1 -1
- package/dist/src/algorithms/planarity/special-graphs.d.ts +2 -4
- package/dist/src/algorithms/planarity/special-graphs.d.ts.map +1 -0
- package/dist/src/algorithms/planarity/special-graphs.js +18 -15
- package/dist/src/algorithms/planarity/special-graphs.js.map +1 -1
- package/dist/src/generators/basic.d.ts +2 -1
- package/dist/src/generators/basic.d.ts.map +1 -0
- package/dist/src/generators/basic.js +4 -4
- package/dist/src/generators/basic.js.map +1 -1
- package/dist/src/generators/bipartite.d.ts +2 -1
- package/dist/src/generators/bipartite.d.ts.map +1 -0
- package/dist/src/generators/bipartite.js +2 -2
- package/dist/src/generators/bipartite.js.map +1 -1
- package/dist/src/generators/grid.d.ts +2 -1
- package/dist/src/generators/grid.d.ts.map +1 -0
- package/dist/src/generators/grid.js +1 -1
- package/dist/src/generators/grid.js.map +1 -1
- package/dist/src/generators/index.d.ts +6 -5
- package/dist/src/generators/index.d.ts.map +1 -0
- package/dist/src/generators/index.js +5 -5
- package/dist/src/generators/index.js.map +1 -1
- package/dist/src/generators/random.d.ts +2 -1
- package/dist/src/generators/random.d.ts.map +1 -0
- package/dist/src/generators/random.js +2 -2
- package/dist/src/generators/random.js.map +1 -1
- package/dist/src/generators/scale-free.d.ts +2 -1
- package/dist/src/generators/scale-free.d.ts.map +1 -0
- package/dist/src/generators/scale-free.js +4 -4
- package/dist/src/generators/scale-free.js.map +1 -1
- package/dist/src/index.d.ts +5 -4
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +4 -4
- package/dist/src/layouts/basic/index.d.ts +2 -1
- package/dist/src/layouts/basic/index.d.ts.map +1 -0
- package/dist/src/layouts/basic/index.js +1 -1
- package/dist/src/layouts/basic/random.d.ts +2 -2
- package/dist/src/layouts/basic/random.d.ts.map +1 -0
- package/dist/src/layouts/basic/random.js +4 -5
- package/dist/src/layouts/basic/random.js.map +1 -1
- package/dist/src/layouts/force-directed/arf.d.ts +2 -2
- package/dist/src/layouts/force-directed/arf.d.ts.map +1 -0
- package/dist/src/layouts/force-directed/arf.js +13 -8
- package/dist/src/layouts/force-directed/arf.js.map +1 -1
- package/dist/src/layouts/force-directed/forceatlas2.d.ts +4 -4
- package/dist/src/layouts/force-directed/forceatlas2.d.ts.map +1 -0
- package/dist/src/layouts/force-directed/forceatlas2.js +83 -51
- package/dist/src/layouts/force-directed/forceatlas2.js.map +1 -1
- package/dist/src/layouts/force-directed/fruchterman-reingold.d.ts +12 -12
- package/dist/src/layouts/force-directed/fruchterman-reingold.d.ts.map +1 -0
- package/dist/src/layouts/force-directed/fruchterman-reingold.js +18 -18
- package/dist/src/layouts/force-directed/fruchterman-reingold.js.map +1 -1
- package/dist/src/layouts/force-directed/index.d.ts +6 -5
- package/dist/src/layouts/force-directed/index.d.ts.map +1 -0
- package/dist/src/layouts/force-directed/index.js +5 -5
- package/dist/src/layouts/force-directed/index.js.map +1 -1
- package/dist/src/layouts/force-directed/kamada-kawai.d.ts +3 -3
- package/dist/src/layouts/force-directed/kamada-kawai.d.ts.map +1 -0
- package/dist/src/layouts/force-directed/kamada-kawai.js +13 -11
- package/dist/src/layouts/force-directed/kamada-kawai.js.map +1 -1
- package/dist/src/layouts/force-directed/spring.d.ts +12 -12
- package/dist/src/layouts/force-directed/spring.d.ts.map +1 -0
- package/dist/src/layouts/force-directed/spring.js +11 -12
- package/dist/src/layouts/force-directed/spring.js.map +1 -1
- package/dist/src/layouts/geometric/circular.d.ts +2 -2
- package/dist/src/layouts/geometric/circular.d.ts.map +1 -0
- package/dist/src/layouts/geometric/circular.js +11 -10
- package/dist/src/layouts/geometric/circular.js.map +1 -1
- package/dist/src/layouts/geometric/index.d.ts +4 -3
- package/dist/src/layouts/geometric/index.d.ts.map +1 -0
- package/dist/src/layouts/geometric/index.js +3 -3
- package/dist/src/layouts/geometric/shell.d.ts +2 -2
- package/dist/src/layouts/geometric/shell.d.ts.map +1 -0
- package/dist/src/layouts/geometric/shell.js +6 -6
- package/dist/src/layouts/geometric/shell.js.map +1 -1
- package/dist/src/layouts/geometric/spiral.d.ts +2 -2
- package/dist/src/layouts/geometric/spiral.d.ts.map +1 -0
- package/dist/src/layouts/geometric/spiral.js +6 -10
- package/dist/src/layouts/geometric/spiral.js.map +1 -1
- package/dist/src/layouts/hierarchical/bfs.d.ts +3 -3
- package/dist/src/layouts/hierarchical/bfs.d.ts.map +1 -0
- package/dist/src/layouts/hierarchical/bfs.js +6 -7
- package/dist/src/layouts/hierarchical/bfs.js.map +1 -1
- package/dist/src/layouts/hierarchical/bipartite.d.ts +3 -3
- package/dist/src/layouts/hierarchical/bipartite.d.ts.map +1 -0
- package/dist/src/layouts/hierarchical/bipartite.js +9 -10
- package/dist/src/layouts/hierarchical/bipartite.js.map +1 -1
- package/dist/src/layouts/hierarchical/index.d.ts +4 -3
- package/dist/src/layouts/hierarchical/index.d.ts.map +1 -0
- package/dist/src/layouts/hierarchical/index.js +3 -3
- package/dist/src/layouts/hierarchical/index.js.map +1 -1
- package/dist/src/layouts/hierarchical/multipartite.d.ts +3 -3
- package/dist/src/layouts/hierarchical/multipartite.d.ts.map +1 -0
- package/dist/src/layouts/hierarchical/multipartite.js +9 -10
- package/dist/src/layouts/hierarchical/multipartite.js.map +1 -1
- package/dist/src/layouts/index.d.ts +6 -5
- package/dist/src/layouts/index.d.ts.map +1 -0
- package/dist/src/layouts/index.js +5 -5
- package/dist/src/layouts/index.js.map +1 -1
- package/dist/src/layouts/specialized/index.d.ts +3 -2
- package/dist/src/layouts/specialized/index.d.ts.map +1 -0
- package/dist/src/layouts/specialized/index.js +2 -2
- package/dist/src/layouts/specialized/index.js.map +1 -1
- package/dist/src/layouts/specialized/planar.d.ts +2 -2
- package/dist/src/layouts/specialized/planar.d.ts.map +1 -0
- package/dist/src/layouts/specialized/planar.js +6 -7
- package/dist/src/layouts/specialized/planar.js.map +1 -1
- package/dist/src/layouts/specialized/spectral.d.ts +2 -2
- package/dist/src/layouts/specialized/spectral.d.ts.map +1 -0
- package/dist/src/layouts/specialized/spectral.js +31 -21
- package/dist/src/layouts/specialized/spectral.js.map +1 -1
- package/dist/src/types/embedding.d.ts +2 -1
- package/dist/src/types/embedding.d.ts.map +1 -0
- package/dist/src/types/graph.d.ts +2 -1
- package/dist/src/types/graph.d.ts.map +1 -0
- package/dist/src/types/index.d.ts +4 -3
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +3 -3
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/layout.d.ts +2 -1
- package/dist/src/types/layout.d.ts.map +1 -0
- package/dist/src/utils/graph.d.ts +2 -5
- package/dist/src/utils/graph.d.ts.map +1 -0
- package/dist/src/utils/graph.js +4 -6
- package/dist/src/utils/graph.js.map +1 -1
- package/dist/src/utils/index.d.ts +6 -5
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +5 -5
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/numpy.d.ts +5 -4
- package/dist/src/utils/numpy.d.ts.map +1 -0
- package/dist/src/utils/numpy.js +22 -16
- package/dist/src/utils/numpy.js.map +1 -1
- package/dist/src/utils/params.d.ts +2 -2
- package/dist/src/utils/params.d.ts.map +1 -0
- package/dist/src/utils/params.js +0 -1
- package/dist/src/utils/params.js.map +1 -1
- package/dist/src/utils/random.d.ts +18 -0
- package/dist/src/utils/random.d.ts.map +1 -0
- package/dist/src/utils/random.js +18 -1
- package/dist/src/utils/random.js.map +1 -1
- package/dist/src/utils/rescale.d.ts +2 -3
- package/dist/src/utils/rescale.d.ts.map +1 -0
- package/dist/src/utils/rescale.js +12 -10
- package/dist/src/utils/rescale.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +35 -34
- package/src/algorithms/index.ts +2 -2
- package/src/algorithms/optimization/index.ts +4 -8
- package/src/algorithms/optimization/kamada-kawai-solver.ts +170 -179
- package/src/algorithms/optimization/lbfgs.ts +42 -49
- package/src/algorithms/optimization/line-search.ts +27 -28
- package/src/algorithms/optimization/types.ts +2 -2
- package/src/algorithms/planarity/check.ts +23 -23
- package/src/algorithms/planarity/embedding.ts +160 -171
- package/src/algorithms/planarity/index.ts +4 -8
- package/src/algorithms/planarity/lr-test.ts +46 -46
- package/src/algorithms/planarity/special-graphs.ts +73 -83
- package/src/generators/basic.ts +57 -57
- package/src/generators/bipartite.ts +37 -31
- package/src/generators/grid.ts +28 -28
- package/src/generators/index.ts +5 -11
- package/src/generators/random.ts +26 -25
- package/src/generators/scale-free.ts +56 -55
- package/src/index.ts +5 -5
- package/src/layouts/basic/index.ts +1 -1
- package/src/layouts/basic/random.ts +20 -16
- package/src/layouts/force-directed/arf.ts +107 -105
- package/src/layouts/force-directed/forceatlas2.ts +374 -352
- package/src/layouts/force-directed/fruchterman-reingold.ts +133 -134
- package/src/layouts/force-directed/index.ts +5 -5
- package/src/layouts/force-directed/kamada-kawai.ts +77 -80
- package/src/layouts/force-directed/spring.ts +24 -25
- package/src/layouts/geometric/circular.ts +63 -57
- package/src/layouts/geometric/index.ts +3 -3
- package/src/layouts/geometric/shell.ts +58 -53
- package/src/layouts/geometric/spiral.ts +60 -64
- package/src/layouts/hierarchical/bfs.ts +58 -59
- package/src/layouts/hierarchical/bipartite.ts +62 -63
- package/src/layouts/hierarchical/index.ts +3 -3
- package/src/layouts/hierarchical/multipartite.ts +62 -63
- package/src/layouts/index.ts +5 -5
- package/src/layouts/specialized/index.ts +2 -2
- package/src/layouts/specialized/planar.ts +41 -42
- package/src/layouts/specialized/spectral.ts +110 -99
- package/src/types/embedding.ts +5 -5
- package/src/types/graph.ts +4 -4
- package/src/types/index.ts +3 -3
- package/src/types/layout.ts +2 -2
- package/src/utils/graph.ts +31 -35
- package/src/utils/index.ts +5 -5
- package/src/utils/numpy.ts +96 -92
- package/src/utils/params.ts +14 -11
- package/src/utils/random.ts +57 -40
- package/src/utils/rescale.ts +169 -174
- package/dist/vitest.config.d.ts +0 -2
- package/dist/vitest.config.js +0 -30
- package/dist/vitest.config.js.map +0 -1
package/dist/layout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","sources":["../src/utils/rescale.ts","../src/utils/params.ts","../src/utils/graph.ts","../src/utils/random.ts","../src/layouts/basic/random.ts","../src/utils/numpy.ts","../src/layouts/geometric/circular.ts","../src/layouts/geometric/shell.ts","../src/layouts/geometric/spiral.ts","../src/layouts/force-directed/fruchterman-reingold.ts","../src/layouts/force-directed/spring.ts","../src/algorithms/optimization/lbfgs.ts","../src/algorithms/optimization/line-search.ts","../src/algorithms/optimization/kamada-kawai-solver.ts","../src/layouts/force-directed/kamada-kawai.ts","../src/layouts/force-directed/forceatlas2.ts","../src/layouts/force-directed/arf.ts","../src/layouts/hierarchical/bipartite.ts","../src/layouts/hierarchical/multipartite.ts","../src/layouts/hierarchical/bfs.ts","../src/layouts/specialized/spectral.ts","../src/algorithms/planarity/special-graphs.ts","../src/algorithms/planarity/embedding.ts","../src/algorithms/planarity/lr-test.ts","../src/algorithms/planarity/check.ts","../src/layouts/specialized/planar.ts","../src/generators/basic.ts","../src/generators/grid.ts","../src/generators/random.ts","../src/generators/bipartite.ts","../src/generators/scale-free.ts"],"sourcesContent":["/**\n * Layout rescaling utilities\n */\n\nimport { PositionMap } from '../types';\n\n/**\n * Returns scaled position array/dict to (-scale, scale) in all axes.\n * \n * @param pos - Position dictionary or array\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @returns Rescaled positions dictionary\n */\nexport function rescaleLayout(\n pos: PositionMap | number[][],\n scale: number = 1,\n center: number[] | null = null\n): PositionMap | number[][] {\n // Check if pos is empty\n if (Array.isArray(pos)) {\n if (pos.length === 0) return [];\n } else {\n if (Object.keys(pos).length === 0) return {};\n }\n\n // Extract position values\n const posValues: number[][] = Array.isArray(pos) ? pos : Object.values(pos);\n const dim = posValues[0].length;\n\n // Fix Bug #1: Default center should match dimensionality\n if (!center) {\n center = Array(dim).fill(0);\n }\n \n // Use the maximum dimension between positions and center\n const targetDim = Math.max(dim, center.length);\n\n // Calculate center of positions, handling NaN values (Bug #3)\n const posCenter = Array(dim).fill(0);\n const counts = Array(dim).fill(0);\n \n for (const p of posValues) {\n for (let i = 0; i < dim; i++) {\n if (!isNaN(p[i])) {\n posCenter[i] += p[i];\n counts[i]++;\n }\n }\n }\n \n // Average by actual count, not total length\n for (let i = 0; i < dim; i++) {\n posCenter[i] = counts[i] > 0 ? posCenter[i] / counts[i] : 0;\n }\n\n // Center positions\n let centeredPos: PositionMap | number[][] = {};\n if (Array.isArray(pos)) {\n centeredPos = pos.map(p => {\n const centered = Array(targetDim).fill(0);\n for (let i = 0; i < targetDim; i++) {\n centered[i] = (i < p.length ? p[i] : 0) - (i < posCenter.length ? posCenter[i] : 0);\n }\n return centered;\n });\n } else {\n for (const [node, p] of Object.entries(pos)) {\n const centered = Array(targetDim).fill(0);\n for (let i = 0; i < targetDim; i++) {\n centered[i] = (i < p.length ? p[i] : 0) - (i < posCenter.length ? posCenter[i] : 0);\n }\n (centeredPos as PositionMap)[node] = centered;\n }\n }\n\n // Find maximum distance from center, handling NaN values (Bug #3)\n let maxDistance = 0;\n const centeredValues = Array.isArray(centeredPos) ? centeredPos : Object.values(centeredPos);\n for (const p of centeredValues) {\n // Calculate distance, treating NaN as 0 for distance calculation\n let sumSquares = 0;\n for (const val of p) {\n if (!isNaN(val)) {\n sumSquares += val * val;\n }\n }\n const distance = Math.sqrt(sumSquares);\n if (!isNaN(distance)) {\n maxDistance = Math.max(maxDistance, distance);\n }\n }\n\n // Rescale\n let scaledPos: PositionMap | number[][] = Array.isArray(pos) ? [] : {};\n\n if (maxDistance > 0) {\n const scaleFactor = scale / maxDistance;\n\n if (Array.isArray(pos)) {\n (scaledPos as number[][]) = (centeredPos as number[][]).map((p, idx) =>\n p.map((val, i) => {\n // Check if this dimension existed in the original position\n const origPos = pos[idx];\n if (i >= origPos.length) {\n // This dimension was added, use center value\n return center![i];\n }\n // Preserve NaN values (Bug #3)\n if (isNaN(val)) return NaN;\n return val * scaleFactor + center![i];\n })\n );\n } else {\n for (const [node, p] of Object.entries(centeredPos as PositionMap)) {\n const origPos = pos[node];\n (scaledPos as PositionMap)[node] = p.map((val, i) => {\n // Check if this dimension existed in the original position\n if (i >= origPos.length) {\n // This dimension was added, use center value\n return center![i];\n }\n // Preserve NaN values (Bug #3)\n if (isNaN(val)) return NaN;\n return val * scaleFactor + center![i];\n });\n }\n }\n } else {\n // All nodes at the same position - extend to target dimensionality\n if (Array.isArray(pos)) {\n (scaledPos as number[][]) = pos.map(p => {\n const result = Array(targetDim);\n for (let i = 0; i < targetDim; i++) {\n if (i < p.length) {\n result[i] = isNaN(p[i]) ? NaN : center![i];\n } else {\n result[i] = center![i];\n }\n }\n return result;\n });\n } else {\n for (const [node, p] of Object.entries(pos)) {\n const result = Array(targetDim);\n for (let i = 0; i < targetDim; i++) {\n if (i < p.length) {\n result[i] = isNaN(p[i]) ? NaN : center![i];\n } else {\n result[i] = center![i];\n }\n }\n (scaledPos as PositionMap)[node] = result;\n }\n }\n }\n\n return scaledPos;\n}\n\n/**\n * Return a dictionary of scaled positions centered at (0, 0).\n * \n * @param pos - Dictionary of positions\n * @param scale - Scale factor for positions\n * @returns Dictionary of scaled positions\n */\nexport function rescaleLayoutDict(\n pos: PositionMap,\n scale: number = 1\n): PositionMap {\n if (Object.keys(pos).length === 0) {\n return {};\n }\n\n // Extract positions as array\n const posArray = Object.values(pos);\n\n // Find center of positions\n const center: number[] = [];\n for (let d = 0; d < posArray[0].length; d++) {\n center[d] = posArray.reduce((sum, p) => sum + p[d], 0) / posArray.length;\n }\n\n // Center positions\n const centeredPos: PositionMap = {};\n for (const [node, p] of Object.entries(pos)) {\n centeredPos[node] = p.map((val, d) => val - center[d]);\n }\n\n // Find maximum distance from center\n let maxDist = 0;\n for (const p of Object.values(centeredPos)) {\n const dist = Math.sqrt(p.reduce((sum, val) => sum + val * val, 0));\n maxDist = Math.max(maxDist, dist);\n }\n\n // Scale positions\n const scaledPos: PositionMap = {};\n if (maxDist > 0) {\n for (const [node, p] of Object.entries(centeredPos)) {\n scaledPos[node] = p.map(val => val * scale / maxDist);\n }\n } else {\n // All points at the center\n for (const node of Object.keys(centeredPos)) {\n scaledPos[node] = Array(centeredPos[node].length).fill(0);\n }\n }\n\n return scaledPos;\n}","/**\n * Parameter processing utilities\n */\n\nimport { Graph, Node } from '../types';\n\n/**\n * Process and validate layout parameters\n * Helper function similar to _process_params in Python version\n * \n * @param G - Graph object or array of nodes\n * @param center - Center coordinates or null\n * @param dim - Dimension of layout\n * @returns Processed parameters\n */\nexport function _processParams(G: Graph | Node[], center: number[] | null, dim: number): { G: Graph | Node[]; center: number[] } {\n if (!center) {\n center = Array(dim).fill(0);\n }\n\n if (center.length !== dim) {\n throw new Error(\"length of center coordinates must match dimension of layout\");\n }\n\n return { G, center };\n}","/**\n * Graph utility functions\n */\n\nimport { Graph, Node, Edge } from '../types';\n\n/**\n * Extract nodes from a graph object\n * \n * @param G - Graph or list of nodes\n * @returns Array of nodes\n */\nexport function getNodesFromGraph(G: Graph | Node[]): Node[] {\n if (Array.isArray(G)) {\n return G;\n }\n return G.nodes();\n}\n\n/**\n * Extract edges from a graph object\n * \n * @param G - Graph or list of nodes\n * @returns Array of edges\n */\nexport function getEdgesFromGraph(G: Graph | Node[]): Edge[] {\n if (Array.isArray(G)) {\n return [];\n }\n return G.edges();\n}\n\n/**\n * Get the degree of a node in the graph\n * \n * @param graph - Graph object\n * @param node - Node to get degree for\n * @returns Degree of the node\n */\nexport function getNodeDegree(graph: Graph, node: Node): number {\n if (!graph.edges) return 0;\n \n const edges = graph.edges();\n let degree = 0;\n \n for (const [source, target] of edges) {\n if (source === node || target === node) {\n degree++;\n }\n }\n \n return degree;\n}\n\n/**\n * Get the neighbors of a node in the graph\n * \n * @param graph - Graph object\n * @param node - Node to get neighbors for\n * @returns Array of neighbor nodes\n */\nexport function getNeighbors(graph: Graph, node: Node): Node[] {\n if (!graph.edges) return [];\n\n const neighbors = new Set<Node>();\n const edges = graph.edges();\n\n for (const [source, target] of edges) {\n if (source === node) {\n neighbors.add(target);\n } else if (target === node) {\n neighbors.add(source);\n }\n }\n\n return Array.from(neighbors);\n}","/**\n * Random number generator for seed-based randomization\n * Maintains exact same functionality as original implementation\n */\n\nexport class RandomNumberGenerator {\n private seed: number;\n private m: number;\n private a: number;\n private c: number;\n private _state: number;\n\n constructor(seed?: number) {\n this.seed = seed || Math.floor(Math.random() * 1000000);\n this.m = 2 ** 35 - 31;\n this.a = 185852;\n this.c = 1;\n this._state = this.seed % this.m;\n }\n\n _next(): number {\n this._state = (this.a * this._state + this.c) % this.m;\n return this._state / this.m;\n }\n\n rand(shape: number | number[] | null = null): number | number[] | number[][] {\n if (shape === null) {\n return this._next();\n }\n\n if (typeof shape === 'number') {\n const result: number[] = [];\n for (let i = 0; i < shape; i++) {\n result.push(this._next());\n }\n return result;\n }\n\n if (shape.length === 1) {\n const result: number[] = [];\n for (let i = 0; i < shape[0]; i++) {\n result.push(this._next());\n }\n return result;\n }\n\n const result: any[] = [];\n for (let i = 0; i < shape[0]; i++) {\n result.push(this.rand(shape.slice(1)));\n }\n return result;\n }\n}","/**\n * Random layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from '../../types';\nimport { _processParams } from '../../utils/params';\nimport { getNodesFromGraph } from '../../utils/graph';\nimport { RandomNumberGenerator } from '../../utils/random';\n\n/**\n * Position nodes uniformly at random in the unit square.\n * \n * @param G - Graph or list of nodes\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @param seed - Random seed for reproducible layouts\n * @returns Positions dictionary keyed by node\n */\nexport function randomLayout(G: Graph | Node[], center: number[] | null = null, dim: number = 2, seed: number | null = null): PositionMap {\n const processed = _processParams(G, center, dim);\n const nodes = getNodesFromGraph(processed.G);\n center = processed.center;\n\n const rng = new RandomNumberGenerator(seed ?? undefined);\n const pos: PositionMap = {};\n\n nodes.forEach((node: Node) => {\n pos[node] = (rng.rand(dim) as number[]).map((val: number, i: number) => val + center[i]);\n });\n\n return pos;\n}","/**\n * NumPy-like array manipulation functions\n * Maintains exact same functionality as original implementation\n */\n\nexport const np = {\n zeros: function (shape: number | number[]): number | number[] | number[][] | any[] {\n if (typeof shape === 'number') {\n return Array(shape).fill(0);\n }\n if (shape.length === 1) {\n return Array(shape[0]).fill(0);\n }\n return Array(shape[0]).fill(0).map(() => this.zeros(shape.slice(1)));\n },\n\n ones: function (shape: number | number[]): number | any[] {\n if (typeof shape === 'number') {\n return Array(shape).fill(1);\n }\n if (shape.length === 1) {\n return Array(shape[0]).fill(1);\n }\n return Array(shape[0]).fill(1).map(() => this.ones(shape.slice(1)));\n },\n\n linspace: function (start: number, stop: number, num: number): number[] {\n if (num === 1) {\n return [start];\n }\n const step = (stop - start) / (num - 1);\n return Array.from({ length: num }, (_, i) => start + i * step);\n },\n\n array: function (arr: any): any[] {\n return Array.isArray(arr) ? [...arr] : [arr];\n },\n\n repeat: function (a: any, repeats: number): any[] {\n const result: any[] = [];\n for (let i = 0; i < repeats; i++) {\n result.push(...np.array(a));\n }\n return result;\n },\n\n mean: function (arr: number[] | number[][], axis: number | null = null): number | number[] {\n if (axis === null) {\n const flatArr = Array.isArray(arr[0])\n ? (arr as number[][]).flat(Infinity) as number[]\n : arr as number[];\n const sum = flatArr.reduce((a, b) => a + b, 0);\n return sum / flatArr.length;\n }\n\n if (axis === 0) {\n const result: number[] = [];\n const matrix = arr as number[][];\n for (let i = 0; i < matrix[0].length; i++) {\n let sum = 0;\n for (let j = 0; j < matrix.length; j++) {\n sum += matrix[j][i];\n }\n result.push(sum / matrix.length);\n }\n return result;\n }\n\n return (arr as number[][]).map(row => np.mean(row) as number);\n },\n\n add: function (a: number | number[], b: number | number[]): number | number[] {\n if (!Array.isArray(a) && !Array.isArray(b)) {\n return a + b;\n }\n if (!Array.isArray(a)) {\n return (b as number[]).map(val => a + val);\n }\n if (!Array.isArray(b)) {\n return (a as number[]).map(val => val + b);\n }\n return (a as number[]).map((val, i) => val + (b as number[])[i]);\n },\n\n subtract: function (a: number | number[], b: number | number[]): number | number[] {\n if (!Array.isArray(a) && !Array.isArray(b)) {\n return a - b;\n }\n if (!Array.isArray(a)) {\n return (b as number[]).map(val => a - val);\n }\n if (!Array.isArray(b)) {\n return (a as number[]).map(val => val - b);\n }\n return (a as number[]).map((val, i) => val - (b as number[])[i]);\n },\n\n max: function (arr: number | number[]): number {\n if (!Array.isArray(arr)) return arr;\n return Math.max(...(arr as number[]).flat(Infinity) as number[]);\n },\n\n min: function (arr: number | number[]): number {\n if (!Array.isArray(arr)) return arr;\n return Math.min(...(arr as number[]).flat(Infinity) as number[]);\n },\n\n norm: function (arr: number[]): number {\n return Math.sqrt(arr.reduce((sum, val) => sum + val * val, 0));\n }\n};","/**\n * Circular layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from '../../types';\nimport { _processParams } from '../../utils/params';\nimport { getNodesFromGraph } from '../../utils/graph';\nimport { RandomNumberGenerator } from '../../utils/random';\nimport { np } from '../../utils/numpy';\n\n/**\n * Position nodes on a circle (2D) or sphere (3D).\n * \n * @param G - Graph or list of nodes\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout (supports 2D circle or 3D sphere)\n * @returns Positions dictionary keyed by node\n */\nexport function circularLayout(G: Graph, scale: number = 1, center: number[] | null = null, dim: number = 2): PositionMap {\n if (dim < 2) {\n throw new Error(\"cannot handle dimensions < 2\");\n }\n\n const processed = _processParams(G, center, dim);\n const nodes = getNodesFromGraph(processed.G);\n center = processed.center;\n\n const pos: PositionMap = {};\n\n if (nodes.length === 0) {\n return pos;\n }\n\n if (nodes.length === 1) {\n pos[nodes[0]] = center;\n return pos;\n }\n\n if (dim === 2) {\n // 2D circle layout\n const theta = np.linspace(0, 2 * Math.PI, nodes.length + 1).slice(0, -1);\n\n nodes.forEach((node: Node, i: number) => {\n const x: number = Math.cos(theta[i]) * scale + center[0];\n const y: number = Math.sin(theta[i]) * scale + center[1];\n pos[node] = [x, y];\n });\n } else if (dim === 3) {\n // 3D sphere layout using Fibonacci spiral\n const n = nodes.length;\n const goldenRatio = (1 + Math.sqrt(5)) / 2;\n \n nodes.forEach((node: Node, i: number) => {\n // Use Fibonacci spiral for even distribution on sphere\n const theta = 2 * Math.PI * i / goldenRatio;\n const phi = Math.acos(1 - 2 * (i + 0.5) / n);\n \n const x = Math.sin(phi) * Math.cos(theta) * scale + center[0];\n const y = Math.sin(phi) * Math.sin(theta) * scale + center[1];\n const z = Math.cos(phi) * scale + center[2];\n \n pos[node] = [x, y, z];\n });\n } else {\n // For higher dimensions, fall back to random on hypersphere\n const rng = new RandomNumberGenerator();\n nodes.forEach((node: Node) => {\n // Generate random point on unit hypersphere\n const coords = Array(dim).fill(0).map(() => rng.rand() as number * 2 - 1);\n const norm = Math.sqrt(coords.reduce((sum, c) => sum + c * c, 0));\n pos[node] = coords.map((c, j) => c / norm * scale + center[j]);\n });\n }\n\n return pos;\n}","/**\n * Shell layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from '../../types';\nimport { _processParams } from '../../utils/params';\nimport { getNodesFromGraph } from '../../utils/graph';\nimport { np } from '../../utils/numpy';\n\n/**\n * Position nodes in concentric circles.\n * \n * @param G - Graph or list of nodes\n * @param nlist - List of node lists for each shell\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout (currently only supports dim=2)\n * @returns Positions dictionary keyed by node\n */\nexport function shellLayout(G: Graph, nlist: Node[][] | null = null, scale: number = 1, center: number[] | null = null, dim: number = 2): PositionMap {\n if (dim !== 2) {\n throw new Error(\"can only handle 2 dimensions\");\n }\n\n const processed = _processParams(G, center, dim);\n const nodes = getNodesFromGraph(processed.G);\n center = processed.center;\n\n const pos: PositionMap = {};\n\n if (nodes.length === 0) {\n return pos;\n }\n\n if (nodes.length === 1) {\n pos[nodes[0]] = center;\n return pos;\n }\n\n // If no nlist is specified, put all nodes in a single shell\n if (!nlist) {\n nlist = [nodes];\n }\n\n const radiusBump = scale / nlist.length;\n let radius: number;\n\n if (nlist[0].length === 1) {\n // Single node at center\n radius = 0;\n pos[nlist[0][0]] = [...center];\n radius += radiusBump;\n } else {\n // Start at radius 1\n radius = radiusBump;\n }\n\n for (let i = 0; i < nlist.length; i++) {\n const shell = nlist[i];\n if (shell.length === 0) continue;\n\n if (shell.length === 1 && i === 0) {\n // Already handled the case of a single center node\n continue;\n }\n\n // Calculate positions on a circle\n const theta = np.linspace(0, 2 * Math.PI, shell.length + 1).slice(0, -1);\n\n shell.forEach((node: Node, j) => {\n const x = Math.cos(theta[j]) * radius + center[0];\n const y = Math.sin(theta[j]) * radius + center[1];\n pos[node] = [x, y];\n });\n\n radius += radiusBump;\n }\n\n return pos;\n}","/**\n * Spiral layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from '../../types';\nimport { _processParams } from '../../utils/params';\nimport { getNodesFromGraph } from '../../utils/graph';\nimport { rescaleLayout } from '../../utils/rescale';\n\n/**\n * Position nodes in a spiral layout.\n * \n * @param G - Graph or list of nodes\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @param resolution - Controls the spacing between spiral elements\n * @param equidistant - Whether to place nodes equidistant from each other\n * @returns Positions dictionary keyed by node\n */\nexport function spiralLayout(\n G: Graph,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n resolution: number = 0.35,\n equidistant: boolean = false\n): PositionMap {\n if (dim !== 2) {\n throw new Error(\"can only handle 2 dimensions\");\n }\n\n const processed = _processParams(G, center || [0, 0], dim);\n const nodes = getNodesFromGraph(processed.G);\n center = processed.center;\n\n const pos: PositionMap = {};\n\n if (nodes.length === 0) {\n return pos;\n }\n\n if (nodes.length === 1) {\n pos[nodes[0]] = [...center];\n return pos;\n }\n\n let positions: number[][] = [];\n\n if (equidistant) {\n // Create equidistant points along the spiral\n // This matches the Python implementation logic\n const chord = 1;\n const step = 0.5;\n let theta = resolution;\n theta += chord / (step * theta);\n\n for (let i = 0; i < nodes.length; i++) {\n const r = step * theta;\n theta += chord / r;\n positions.push([Math.cos(theta) * r, Math.sin(theta) * r]);\n }\n } else {\n // Create points with equal angle but increasing distance\n const dist = Array.from({ length: nodes.length }, (_, i) => parseFloat(String(i)));\n const angle = dist.map(d => resolution * d);\n\n positions = dist.map((d, i) => [\n Math.cos(angle[i]) * d,\n Math.sin(angle[i]) * d\n ]);\n }\n\n // Convert position array to position matrix for rescaling\n const posArray: number[][] = [];\n for (let i = 0; i < positions.length; i++) {\n posArray.push(positions[i]);\n }\n\n // Rescale positions and add center offset\n const scaledPositions = rescaleLayout(posArray as any, scale) as any;\n for (let i = 0; i < scaledPositions.length; i++) {\n scaledPositions[i][0] += center[0];\n scaledPositions[i][1] += center[1];\n }\n\n // Create position dictionary\n for (let i = 0; i < nodes.length; i++) {\n pos[nodes[i]] = scaledPositions[i];\n }\n\n return pos;\n}","/**\n * Fruchterman-Reingold force-directed layout algorithm\n */\n\nimport { Graph, Node, Edge, PositionMap } from '../../types';\nimport { _processParams } from '../../utils/params';\nimport { getNodesFromGraph, getEdgesFromGraph } from '../../utils/graph';\nimport { RandomNumberGenerator } from '../../utils/random';\nimport { rescaleLayout } from '../../utils/rescale';\n\n/**\n * Position nodes using Fruchterman-Reingold force-directed algorithm.\n *\n * @param {Object} G - Graph or list of nodes\n * @param {number} k - Optimal distance between nodes\n * @param {Object} pos - Initial positions for nodes\n * @param {Array} fixed - Nodes to keep fixed at initial position\n * @param {number} iterations - Maximum number of iterations\n * @param {number} scale - Scale factor for positions\n * @param {Array|null} center - Coordinate pair around which to center the layout\n * @param {number} dim - Dimension of layout\n * @param {number} seed - Random seed for initial positions\n * @returns {Object} Positions dictionary keyed by node\n */\nexport function fruchtermanReingoldLayout(\n G: Graph,\n k: number | null = null,\n pos: PositionMap | null = null,\n fixed: Node[] | null = null,\n iterations: number = 50,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n seed: number | null = null\n): PositionMap {\n const processed = _processParams(G, center, dim);\n let graph = processed.G;\n center = processed.center;\n\n const nodes = getNodesFromGraph(graph);\n const edges = getEdgesFromGraph(graph);\n\n if (nodes.length === 0) {\n return {};\n }\n\n if (nodes.length === 1) {\n const singlePos: PositionMap = {};\n singlePos[nodes[0]] = center;\n return singlePos;\n }\n\n // Set up initial positions\n let positions: PositionMap = {};\n if (pos) {\n // Use provided positions\n for (const node of nodes) {\n if (pos[node]) {\n positions[node] = [...pos[node]];\n } else {\n const rng = new RandomNumberGenerator(seed ?? undefined);\n positions[node] = rng.rand(dim) as number[];\n }\n }\n } else {\n // Random initial positions\n const rng = new RandomNumberGenerator(seed ?? undefined);\n for (const node of nodes) {\n positions[node] = rng.rand(dim) as number[];\n }\n }\n\n // Set up fixed nodes\n const fixedNodes = new Set(fixed || []);\n\n // Optimal distance between nodes\n if (!k) {\n k = 1.0 / Math.sqrt(nodes.length);\n }\n\n // Initialize temperature\n let t = 0.1;\n // Calculate temperature reduction\n const dt = t / (iterations + 1);\n\n // Simple cooling schedule\n for (let i = 0; i < iterations; i++) {\n // Calculate repulsive forces\n const displacement: Record<Node, number[]> = {};\n for (const node of nodes) {\n displacement[node] = Array(dim).fill(0);\n }\n\n // Repulsive forces between nodes\n for (let v1i = 0; v1i < nodes.length; v1i++) {\n const v1 = nodes[v1i];\n for (let v2i = v1i + 1; v2i < nodes.length; v2i++) {\n const v2 = nodes[v2i];\n\n // Difference vector\n const delta = positions[v1].map((p, i) => p - positions[v2][i]);\n\n // Distance\n const distance = Math.sqrt(delta.reduce((sum, d) => sum + d * d, 0)) || 0.1;\n\n // Force\n const force = (k * k) / distance;\n\n // Add force to displacement\n for (let j = 0; j < dim; j++) {\n const direction = delta[j] / distance;\n displacement[v1][j] += direction * force;\n displacement[v2][j] -= direction * force;\n }\n }\n }\n\n // Attractive forces between connected nodes\n for (const [source, target] of edges) {\n // Difference vector\n const delta = positions[source].map((p, i) => p - positions[target][i]);\n\n // Distance\n const distance = Math.sqrt(delta.reduce((sum, d) => sum + d * d, 0)) || 0.1;\n\n // Force\n const force = (distance * distance) / k;\n\n // Add force to displacement\n for (let j = 0; j < dim; j++) {\n const direction = delta[j] / distance;\n displacement[source][j] -= direction * force;\n displacement[target][j] += direction * force;\n }\n }\n\n // Update positions\n for (const node of nodes) {\n if (fixedNodes.has(node)) continue;\n\n // Calculate displacement magnitude\n const magnitude = Math.sqrt(displacement[node].reduce((sum, d) => sum + d * d, 0));\n\n // Limit maximum displacement by temperature\n const limitedMagnitude = Math.min(magnitude, t);\n\n // Update position\n for (let j = 0; j < dim; j++) {\n const direction = magnitude === 0 ? 0 : displacement[node][j] / magnitude;\n positions[node][j] += direction * limitedMagnitude;\n }\n }\n\n // Cool temperature\n t -= dt;\n }\n\n // Rescale positions\n if (!fixed) {\n positions = rescaleLayout(positions, scale, center) as PositionMap;\n }\n\n return positions;\n}","/**\n * Spring layout algorithm (Fruchterman-Reingold variant)\n */\n\nimport { Graph, Node, PositionMap } from '../../types';\nimport { fruchtermanReingoldLayout } from './fruchterman-reingold';\n\n/**\n * Position nodes using Fruchterman-Reingold force-directed algorithm.\n * \n * @param {Object} G - Graph or list of nodes\n * @param {number} k - Optimal distance between nodes\n * @param {Object} pos - Initial positions for nodes\n * @param {Array} fixed - Nodes to keep fixed at initial position\n * @param {number} iterations - Maximum number of iterations\n * @param {number} scale - Scale factor for positions\n * @param {Array|null} center - Coordinate pair around which to center the layout\n * @param {number} dim - Dimension of layout\n * @param {number} seed - Random seed for initial positions\n * @returns {Object} Positions dictionary keyed by node\n */\nexport function springLayout(\n G: Graph,\n k: number | null = null,\n pos: PositionMap | null = null,\n fixed: Node[] | null = null,\n iterations: number = 50,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n seed: number | null = null\n): PositionMap {\n // Legacy compatibility alias\n return fruchtermanReingoldLayout(G, k, pos, fixed, iterations, scale, center, dim, seed);\n}","/**\n * L-BFGS optimization utilities\n */\n\n/**\n * Compute the search direction using L-BFGS approximation\n * \n * @param grad - Current gradient\n * @param sList - List of position differences (s_k)\n * @param yList - List of gradient differences (y_k)\n * @param m - Memory size\n * @returns Direction vector\n */\nexport function _lbfgsDirection(\n grad: number[],\n sList: number[][],\n yList: number[][],\n m: number\n): number[] {\n if (sList.length === 0) {\n // First iteration - use negative gradient\n return grad.map(g => -g);\n }\n\n const q = grad.slice();\n const alpha = Array(sList.length).fill(0);\n const rho: number[] = [];\n\n // Compute rho values\n for (let i = 0; i < sList.length; i++) {\n const s = sList[i];\n const y = yList[i];\n rho.push(1 / y.reduce((sum, val, j) => sum + val * s[j], 0));\n }\n\n // Forward pass\n for (let i = sList.length - 1; i >= 0; i--) {\n const s = sList[i];\n alpha[i] = rho[i] * s.reduce((sum, val, j) => sum + val * q[j], 0);\n for (let j = 0; j < q.length; j++) {\n q[j] -= alpha[i] * yList[i][j];\n }\n }\n\n // Scale initial Hessian approximation\n let gamma = 1;\n if (sList.length > 0 && yList.length > 0) {\n const y = yList[yList.length - 1];\n const s = sList[sList.length - 1];\n gamma = s.reduce((sum, val, i) => sum + val * y[i], 0) /\n y.reduce((sum, val) => sum + val * val, 0);\n }\n\n // Initialize direction with scaled negative gradient\n const direction = q.map(val => -gamma * val);\n\n // Backward pass\n for (let i = 0; i < sList.length; i++) {\n const s = sList[i];\n const y = yList[i];\n const beta = rho[i] * y.reduce((sum, val, j) => sum + val * direction[j], 0);\n for (let j = 0; j < direction.length; j++) {\n direction[j] += s[j] * (alpha[i] - beta);\n }\n }\n\n return direction;\n}","/**\n * Line search optimization utilities\n */\n\n/**\n * Backtracking line search to find step size\n * \n * @param x - Current position\n * @param direction - Search direction\n * @param f - Function value at current position\n * @param grad - Gradient at current position\n * @param func - Function to evaluate cost\n * @param alpha0 - Initial step size\n * @returns Optimal step size\n */\nexport function _backtrackingLineSearch(\n x: number[],\n direction: number[],\n f: number,\n grad: number[],\n func: (x: number[]) => number,\n alpha0: number\n): number {\n const c1 = 1e-4;\n const c2 = 0.9;\n const initialSlope = grad.reduce((sum, g, i) => sum + g * direction[i], 0);\n\n if (initialSlope >= 0) {\n return 1e-8; // Direction is not a descent direction\n }\n\n let alpha = alpha0;\n const maxIter = 20;\n\n for (let i = 0; i < maxIter; i++) {\n // Try step\n const newX = x.map((val, i) => val + alpha * direction[i]);\n const newF = func(newX);\n\n // Check sufficient decrease condition (Armijo condition)\n if (newF <= f + c1 * alpha * initialSlope) {\n return alpha;\n }\n\n // Reduce step size\n alpha *= c2;\n }\n\n return alpha; // Return last alpha even if not optimal\n}","/**\n * Kamada-Kawai layout algorithm optimization functions\n */\n\nimport { Graph, Node, Edge } from '../../types';\nimport { DistanceMap } from './types';\nimport { _lbfgsDirection } from './lbfgs';\nimport { _backtrackingLineSearch } from './line-search';\nimport { getNodesFromGraph, getEdgesFromGraph } from '../../utils/graph';\n\n/**\n * Compute all-pairs shortest path distances for the graph\n * \n * @param G - NetworkX graph\n * @param weight - Edge attribute for weight\n * @returns Dictionary of dictionaries of shortest path distances\n */\nexport function _computeShortestPathDistances(\n G: Graph,\n weight: string\n): DistanceMap {\n const distances: DistanceMap = {};\n const nodes = getNodesFromGraph(G);\n const edges = getEdgesFromGraph(G);\n\n // Initialize distances with direct edges\n for (const node of nodes) {\n distances[node] = {};\n distances[node][node] = 0;\n\n for (const other of nodes) {\n if (node !== other) {\n distances[node][other] = Infinity;\n }\n }\n }\n\n // Add direct edges\n for (const [source, target] of edges) {\n // In a real implementation, we would get the weight from the graph\n // For now, assume weight = 1 or use weight attribute if available\n let edgeWeight = 1;\n if (G.getEdgeData) {\n edgeWeight = G.getEdgeData(source, target, weight) || 1;\n }\n\n distances[source][target] = edgeWeight;\n distances[target][source] = edgeWeight; // Assuming undirected graph\n }\n\n // Floyd-Warshall algorithm for all-pairs shortest paths\n for (const k of nodes) {\n for (const i of nodes) {\n for (const j of nodes) {\n if (distances[i][k] + distances[k][j] < distances[i][j]) {\n distances[i][j] = distances[i][k] + distances[k][j];\n }\n }\n }\n }\n\n return distances;\n}\n\n/**\n * Solve the Kamada-Kawai layout optimization problem\n * \n * @param distMatrix - Matrix of desired distances between nodes\n * @param positions - Initial node positions\n * @param dim - Dimension of layout\n * @returns Optimized node positions\n */\nexport function _kamadaKawaiSolve(\n distMatrix: number[][],\n positions: number[][],\n dim: number\n): number[][] {\n // Implementation of L-BFGS optimization for Kamada-Kawai\n const nNodes = positions.length;\n const meanWeight = 1e-3;\n\n // Convert distances to inverse distances (with protection against division by zero)\n const invDistMatrix = distMatrix.map(row =>\n row.map(d => d === 0 ? 0 : 1 / (d + 1e-3))\n );\n\n // Flatten positions for optimization\n let posVec = positions.flat();\n\n // Optimization parameters\n const maxIter = 500;\n const gtol = 1e-5;\n const m = 10; // L-BFGS memory size\n\n // Implement a simplified L-BFGS-B algorithm\n let alpha = 1.0;\n const oldValues: number[][] = [];\n const oldGrads: number[][] = [];\n\n for (let iter = 0; iter < maxIter; iter++) {\n // Calculate cost and gradient\n const [cost, grad] = _kamadaKawaiCostfn(posVec, invDistMatrix, meanWeight, dim);\n\n // Compute search direction using L-BFGS approximation\n const direction = _lbfgsDirection(grad, oldValues, oldGrads, m);\n\n // Simple line search for step size\n alpha = _backtrackingLineSearch(\n posVec, direction, cost, grad,\n (x: number[]) => _kamadaKawaiCostfn(x, invDistMatrix, meanWeight, dim)[0],\n alpha\n );\n\n // Save current position and gradient for next iteration\n const oldPos = [...posVec];\n\n // Update position\n for (let i = 0; i < posVec.length; i++) {\n posVec[i] += alpha * direction[i];\n }\n\n // Calculate new gradient\n const [, newGrad] = _kamadaKawaiCostfn(posVec, invDistMatrix, meanWeight, dim);\n\n // Update L-BFGS memory\n oldValues.push(posVec.map((val, i) => val - oldPos[i]));\n oldGrads.push(newGrad.map((val, i) => val - grad[i]));\n\n // Keep only m most recent updates\n if (oldValues.length > m) {\n oldValues.shift();\n oldGrads.shift();\n }\n\n // Check convergence\n const gradNorm = Math.sqrt(newGrad.reduce((sum, g) => sum + g * g, 0));\n if (gradNorm < gtol) {\n break;\n }\n }\n\n // Reshape result back into positions array\n const result: number[][] = [];\n for (let i = 0; i < nNodes; i++) {\n result.push(posVec.slice(i * dim, (i + 1) * dim));\n }\n\n return result;\n}\n\n/**\n * Cost function and gradient for Kamada-Kawai layout algorithm\n * \n * @param posVec - Flattened position array\n * @param invDist - Inverse distance matrix\n * @param meanWeight - Weight for centering positions\n * @param dim - Dimension of layout\n * @returns Array with [cost, gradient]\n */\nexport function _kamadaKawaiCostfn(\n posVec: number[],\n invDist: number[][],\n meanWeight: number,\n dim: number\n): [number, number[]] {\n const nNodes = invDist.length;\n const positions: number[][] = [];\n\n // Reshape flat vector into positions array\n for (let i = 0; i < nNodes; i++) {\n positions.push(posVec.slice(i * dim, (i + 1) * dim));\n }\n\n // Calculate cost\n let cost = 0;\n\n // Add mean position penalty term\n const sumPos = Array(dim).fill(0);\n for (let i = 0; i < nNodes; i++) {\n for (let d = 0; d < dim; d++) {\n sumPos[d] += positions[i][d];\n }\n }\n cost += 0.5 * meanWeight * sumPos.reduce((sum, val) => sum + val * val, 0);\n\n // Add distance penalty terms\n for (let i = 0; i < nNodes; i++) {\n for (let j = i + 1; j < nNodes; j++) {\n // Calculate actual distance\n const diff = positions[i].map((val, d) => val - positions[j][d]);\n const distance = Math.sqrt(diff.reduce((sum, d) => sum + d * d, 0));\n\n // Add penalty for difference between actual and ideal distance\n const idealInvDist = invDist[i][j];\n const offset = distance * idealInvDist - 1.0;\n cost += 0.5 * offset * offset;\n }\n }\n\n // Calculate gradient\n const grad = new Array(posVec.length).fill(0);\n\n // Add gradient of mean position penalty\n for (let i = 0; i < nNodes; i++) {\n for (let d = 0; d < dim; d++) {\n grad[i * dim + d] += meanWeight * sumPos[d];\n }\n }\n\n // Add gradient of distance penalties\n for (let i = 0; i < nNodes; i++) {\n for (let j = i + 1; j < nNodes; j++) {\n // Calculate actual distance and direction\n const diff = positions[i].map((val, d) => val - positions[j][d]);\n const distance = Math.sqrt(diff.reduce((sum, d) => sum + d * d, 0)) || 1e-10;\n const direction = diff.map(d => d / distance);\n\n // Calculate contribution to gradient\n const idealInvDist = invDist[i][j];\n const offset = distance * idealInvDist - 1.0;\n\n for (let d = 0; d < dim; d++) {\n const force = idealInvDist * offset * direction[d];\n grad[i * dim + d] += force;\n grad[j * dim + d] -= force;\n }\n }\n }\n\n return [cost, grad];\n}","import type { Graph, Node, PositionMap } from '../../types';\nimport type { DistanceMap } from '../../algorithms/optimization';\nimport { getNodesFromGraph } from '../../utils/graph';\nimport { _processParams } from '../../utils/params';\nimport { rescaleLayout } from '../../utils/rescale';\nimport { circularLayout } from '../geometric/circular';\nimport { \n _computeShortestPathDistances,\n _kamadaKawaiSolve\n} from '../../algorithms/optimization';\n\n/**\n * Position nodes using Kamada-Kawai path-length cost-function.\n * \n * @param G - NetworkX graph or list of nodes\n * @param dist - A two-level dictionary of optimal distances between nodes\n * @param pos - Initial positions for nodes\n * @param weight - The edge attribute used for edge weights\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @returns Positions dictionary keyed by node\n */\nexport function kamadaKawaiLayout(\n G: Graph,\n dist: DistanceMap | null = null,\n pos: PositionMap | null = null,\n weight: string = 'weight',\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2\n): PositionMap {\n const processed = _processParams(G, center, dim);\n const graph = processed.G;\n center = processed.center;\n\n const nodes = getNodesFromGraph(graph);\n\n if (nodes.length === 0) {\n return {};\n }\n\n if (nodes.length === 1) {\n return { [nodes[0]]: center };\n }\n\n // Initialize distance matrix\n if (!dist) {\n // Kamada-Kawai requires a proper Graph, not just a list of nodes\n if (Array.isArray(graph)) {\n throw new Error('Kamada-Kawai layout requires a Graph with edges, not just a list of nodes');\n }\n dist = _computeShortestPathDistances(graph, weight);\n }\n\n // Convert distances to a matrix\n const nodesArray: Node[] = Array.from(nodes);\n const nNodes = nodesArray.length;\n const distMatrix: number[][] = Array(nNodes).fill(0).map(() => Array(nNodes).fill(1e6));\n\n for (let i = 0; i < nNodes; i++) {\n const nodeI = nodesArray[i];\n distMatrix[i][i] = 0;\n\n if (!dist[nodeI]) continue;\n\n for (let j = 0; j < nNodes; j++) {\n const nodeJ = nodesArray[j];\n if (dist[nodeI][nodeJ] !== undefined) {\n distMatrix[i][j] = dist[nodeI][nodeJ];\n }\n }\n }\n\n // Initialize positions if not provided\n if (!pos) {\n if (dim >= 2) {\n // Use circular/spherical layout for 2D and 3D\n pos = circularLayout(G, 1, center, dim);\n } else {\n // For 1D, use a linear layout\n const posArray: PositionMap = {};\n nodesArray.forEach((node, i) => {\n posArray[node] = [i / (nNodes - 1 || 1)];\n });\n pos = posArray;\n }\n }\n\n // Convert positions to array for computation\n const posArray: number[][] = new Array(nNodes);\n for (let i = 0; i < nNodes; i++) {\n const node = nodesArray[i];\n posArray[i] = pos[node] ? [...pos[node]] : Array(dim).fill(0);\n\n // Ensure correct dimensionality\n while (posArray[i].length < dim) {\n posArray[i].push(0);\n }\n }\n\n // Run the Kamada-Kawai algorithm\n const newPositions = _kamadaKawaiSolve(distMatrix, posArray, dim);\n\n // Convert positions array back to dictionary and rescale\n const finalPos: PositionMap = {};\n for (let i = 0; i < nNodes; i++) {\n finalPos[nodesArray[i]] = newPositions[i];\n }\n\n return rescaleLayout(finalPos, scale, center) as PositionMap;\n}","import type { Graph, Node, Edge, PositionMap } from '../../types';\nimport { getNodesFromGraph, getEdgesFromGraph } from '../../utils/graph';\nimport { _processParams } from '../../utils/params';\nimport { rescaleLayout } from '../../utils/rescale';\nimport { RandomNumberGenerator } from '../../utils/random';\n\n/**\n * Position nodes using the ForceAtlas2 force-directed algorithm.\n * \n * @param G - Graph\n * @param pos - Initial positions for nodes\n * @param maxIter - Maximum number of iterations\n * @param jitterTolerance - Controls tolerance for node speed adjustments\n * @param scalingRatio - Scaling of attraction and repulsion forces\n * @param gravity - Attraction to center to prevent disconnected components from drifting\n * @param distributedAction - Distributes attraction force among nodes\n * @param strongGravity - Uses a stronger gravity model\n * @param nodeMass - Dictionary mapping nodes to their masses\n * @param nodeSize - Dictionary mapping nodes to their sizes\n * @param weight - Edge attribute for weight\n * @param dissuadeHubs - Whether to prevent hub nodes from clustering\n * @param linlog - Whether to use logarithmic attraction\n * @param seed - Random seed for initial positions\n * @param dim - Dimension of layout\n * @returns Positions dictionary keyed by node\n */\nexport function forceatlas2Layout(\n G: Graph,\n pos: PositionMap | null = null,\n maxIter: number = 100,\n jitterTolerance: number = 1.0,\n scalingRatio: number = 2.0,\n gravity: number = 1.0,\n distributedAction: boolean = false,\n strongGravity: boolean = false,\n nodeMass: Record<Node, number> | null = null,\n nodeSize: Record<Node, number> | null = null,\n weight: string | null = null,\n dissuadeHubs: boolean = false,\n linlog: boolean = false,\n seed: number | null = null,\n dim: number = 2\n): PositionMap {\n const processed = _processParams(G, null, dim);\n const graph = processed.G;\n\n const nodes = getNodesFromGraph(graph);\n\n if (nodes.length === 0) {\n return {};\n }\n\n // Initialize random number generator\n const rng = new RandomNumberGenerator(seed ?? undefined);\n\n // Initialize positions if not provided\n let posArray: number[][];\n if (pos === null) {\n pos = {};\n posArray = new Array(nodes.length);\n for (let i = 0; i < nodes.length; i++) {\n posArray[i] = Array(dim).fill(0).map(() => rng.rand() as number * 2 - 1);\n pos[nodes[i]] = posArray[i];\n }\n } else if (Object.keys(pos).length === nodes.length) {\n // Use provided positions\n posArray = new Array(nodes.length);\n for (let i = 0; i < nodes.length; i++) {\n const nodePos = pos[nodes[i]];\n posArray[i] = new Array(dim);\n for (let d = 0; d < dim; d++) {\n posArray[i][d] = d < nodePos.length ? nodePos[d] : (rng.rand() as number * 2 - 1);\n }\n }\n } else {\n // Some nodes don't have positions, initialize within the range of existing positions\n let minPos = Array(dim).fill(Number.POSITIVE_INFINITY);\n let maxPos = Array(dim).fill(Number.NEGATIVE_INFINITY);\n\n // Find min and max of existing positions\n for (const node in pos) {\n const nodePos = pos[node];\n for (let d = 0; d < dim; d++) {\n if (d < nodePos.length) {\n minPos[d] = Math.min(minPos[d], nodePos[d]);\n maxPos[d] = Math.max(maxPos[d], nodePos[d]);\n }\n }\n }\n\n // If min/max are still infinity for some dimensions, use default range\n for (let d = 0; d < dim; d++) {\n if (!isFinite(minPos[d]) || !isFinite(maxPos[d])) {\n minPos[d] = -1;\n maxPos[d] = 1;\n }\n }\n\n posArray = new Array(nodes.length);\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (pos[node]) {\n const nodePos = pos[node];\n posArray[i] = new Array(dim);\n for (let d = 0; d < dim; d++) {\n posArray[i][d] = d < nodePos.length ? nodePos[d] : (rng.rand() as number * 2 - 1);\n }\n } else {\n posArray[i] = Array(dim).fill(0).map((_, d) =>\n minPos[d] + (rng.rand() as number) * (maxPos[d] - minPos[d])\n );\n pos[node] = posArray[i];\n }\n }\n }\n\n // Initialize mass and size arrays\n const mass = new Array(nodes.length).fill(0);\n const size = new Array(nodes.length).fill(0);\n\n // Flag to track whether to adjust for node sizes\n const adjustSizes = nodeSize !== null;\n\n // Set node masses and sizes\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n mass[i] = nodeMass && nodeMass[node] ?\n nodeMass[node] :\n (Array.isArray(graph) ? 1 : getNodeDegree(graph, node) + 1);\n\n size[i] = nodeSize && nodeSize[node] ? nodeSize[node] : 1;\n }\n\n // Create adjacency matrix\n const n = nodes.length;\n const A = Array(n).fill(0).map(() => Array(n).fill(0));\n\n // Populate adjacency matrix with edge weights\n const edges = Array.isArray(graph) ? [] as Edge[] : graph.edges();\n const nodeIndices: Record<Node, number> = {};\n nodes.forEach((node, i) => { nodeIndices[node] = i; });\n\n for (const [source, target] of edges) {\n const i = nodeIndices[source];\n const j = nodeIndices[target];\n\n // Use edge weight if provided, otherwise default to 1\n let edgeWeight = 1;\n if (weight && !Array.isArray(graph) && graph.getEdgeData) {\n edgeWeight = graph.getEdgeData(source, target, weight) || 1;\n }\n\n A[i][j] = edgeWeight;\n A[j][i] = edgeWeight; // For undirected graphs\n }\n\n // Initialize force arrays\n const gravities = Array(n).fill(0).map(() => Array(dim).fill(0));\n const attraction = Array(n).fill(0).map(() => Array(dim).fill(0));\n const repulsion = Array(n).fill(0).map(() => Array(dim).fill(0));\n\n // Simulation parameters\n let speed = 1;\n let speedEfficiency = 1;\n let swing = 1;\n let traction = 1;\n\n // Helper function to estimate factor for force scaling\n function estimateFactor(\n n: number,\n swing: number,\n traction: number,\n speed: number,\n speedEfficiency: number,\n jitterTolerance: number\n ): [number, number] {\n // Optimal jitter parameters\n const optJitter = 0.05 * Math.sqrt(n);\n const minJitter = Math.sqrt(optJitter);\n const maxJitter = 10;\n const minSpeedEfficiency = 0.05;\n\n // Estimate jitter based on current state\n const other = Math.min(maxJitter, optJitter * traction / (n * n));\n let jitter = jitterTolerance * Math.max(minJitter, other);\n\n // Adjust speed efficiency based on swing/traction ratio\n if (swing / traction > 2.0) {\n if (speedEfficiency > minSpeedEfficiency) {\n speedEfficiency *= 0.5;\n }\n jitter = Math.max(jitter, jitterTolerance);\n }\n\n // Calculate target speed\n let targetSpeed = swing === 0 ?\n Number.POSITIVE_INFINITY :\n jitter * speedEfficiency * traction / swing;\n\n // Further adjust speed efficiency\n if (swing > jitter * traction) {\n if (speedEfficiency > minSpeedEfficiency) {\n speedEfficiency *= 0.7;\n }\n } else if (speed < 1000) {\n speedEfficiency *= 1.3;\n }\n\n // Limit the speed increase\n const maxRise = 0.5;\n speed = speed + Math.min(targetSpeed - speed, maxRise * speed);\n\n return [speed, speedEfficiency];\n }\n\n // Main simulation loop\n for (let iter = 0; iter < maxIter; iter++) {\n // Reset forces for this iteration\n for (let i = 0; i < n; i++) {\n for (let d = 0; d < dim; d++) {\n attraction[i][d] = 0;\n repulsion[i][d] = 0;\n gravities[i][d] = 0;\n }\n }\n\n // Compute pairwise differences and distances\n const diff = Array(n).fill(0).map(() =>\n Array(n).fill(0).map(() => Array(dim).fill(0))\n );\n\n const distance = Array(n).fill(0).map(() => Array(n).fill(0));\n\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (i === j) continue;\n\n for (let d = 0; d < dim; d++) {\n diff[i][j][d] = posArray[i][d] - posArray[j][d];\n }\n\n distance[i][j] = Math.sqrt(diff[i][j].reduce((sum, d) => sum + d * d, 0));\n // Prevent division by zero\n if (distance[i][j] < 0.01) distance[i][j] = 0.01;\n }\n }\n\n // Calculate attraction forces\n if (linlog) {\n // Logarithmic attraction model\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (i === j || A[i][j] === 0) continue;\n\n const dist = distance[i][j];\n const factor = -Math.log(1 + dist) / dist * A[i][j];\n\n for (let d = 0; d < dim; d++) {\n const force = factor * diff[i][j][d];\n attraction[i][d] += force;\n }\n }\n }\n } else {\n // Linear attraction model\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (i === j || A[i][j] === 0) continue;\n\n for (let d = 0; d < dim; d++) {\n const force = -diff[i][j][d] * A[i][j];\n attraction[i][d] += force;\n }\n }\n }\n }\n\n // Apply distributed attraction if enabled\n if (distributedAction) {\n for (let i = 0; i < n; i++) {\n for (let d = 0; d < dim; d++) {\n attraction[i][d] /= mass[i];\n }\n }\n }\n\n // Calculate repulsion forces\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (i === j) continue;\n\n let dist = distance[i][j];\n\n // Adjust distance for node sizes if needed\n if (adjustSizes) {\n dist -= size[i] - size[j];\n dist = Math.max(dist, 0.01); // Prevent negative or zero distances\n }\n\n const distSquared = dist * dist;\n const massProduct = mass[i] * mass[j];\n const factor = (massProduct / distSquared) * scalingRatio;\n\n for (let d = 0; d < dim; d++) {\n const direction = diff[i][j][d] / dist;\n repulsion[i][d] += direction * factor;\n }\n }\n }\n\n // Calculate gravity forces\n // First find the center of mass\n const centerOfMass = Array(dim).fill(0);\n for (let i = 0; i < n; i++) {\n for (let d = 0; d < dim; d++) {\n centerOfMass[d] += posArray[i][d] / n;\n }\n }\n\n for (let i = 0; i < n; i++) {\n const posCentered = Array(dim);\n for (let d = 0; d < dim; d++) {\n posCentered[d] = posArray[i][d] - centerOfMass[d];\n }\n\n if (strongGravity) {\n // Strong gravity model\n for (let d = 0; d < dim; d++) {\n gravities[i][d] = -gravity * mass[i] * posCentered[d];\n }\n } else {\n // Regular gravity model\n const dist = Math.sqrt(posCentered.reduce((sum, val) => sum + val * val, 0));\n\n if (dist > 0.01) {\n for (let d = 0; d < dim; d++) {\n const direction = posCentered[d] / dist;\n gravities[i][d] = -gravity * mass[i] * direction;\n }\n }\n }\n }\n\n // Calculate total forces and update positions\n const update = Array(n).fill(0).map(() => Array(dim).fill(0));\n let totalSwing = 0;\n let totalTraction = 0;\n\n for (let i = 0; i < n; i++) {\n for (let d = 0; d < dim; d++) {\n update[i][d] = attraction[i][d] + repulsion[i][d] + gravities[i][d];\n }\n\n // Calculate swing and traction for this node\n const oldPos = [...posArray[i]];\n const newPos = oldPos.map((p, d) => p + update[i][d]);\n\n const swingVector = oldPos.map((p, d) => p - newPos[d]);\n const tractionVector = oldPos.map((p, d) => p + newPos[d]);\n\n const swingMagnitude = Math.sqrt(swingVector.reduce((sum, val) => sum + val * val, 0));\n const tractionMagnitude = Math.sqrt(tractionVector.reduce((sum, val) => sum + val * val, 0));\n\n totalSwing += mass[i] * swingMagnitude;\n totalTraction += 0.5 * mass[i] * tractionMagnitude;\n }\n\n // Update speed and efficiency\n [speed, speedEfficiency] = estimateFactor(\n n,\n totalSwing,\n totalTraction,\n speed,\n speedEfficiency,\n jitterTolerance\n );\n\n // Apply forces to update positions\n let totalMovement = 0;\n\n for (let i = 0; i < n; i++) {\n let factor;\n\n if (adjustSizes) {\n // Calculate displacement magnitude\n const df = Math.sqrt(update[i].reduce((sum, val) => sum + val * val, 0));\n const swinging = mass[i] * df;\n\n // Determine scaling factor with size adjustments\n factor = 0.1 * speed / (1 + Math.sqrt(speed * swinging));\n factor = Math.min(factor * df, 10) / df;\n } else {\n // Standard scaling factor\n const swinging = mass[i] * Math.sqrt(update[i].reduce((sum, val) => sum + val * val, 0));\n factor = speed / (1 + Math.sqrt(speed * swinging));\n }\n\n // Apply factor to update position\n for (let d = 0; d < dim; d++) {\n const movement = update[i][d] * factor;\n posArray[i][d] += movement;\n totalMovement += Math.abs(movement);\n }\n }\n\n // Check for convergence\n if (totalMovement < 1e-10) {\n break;\n }\n }\n\n // Create position dictionary\n const positions: PositionMap = {};\n for (let i = 0; i < n; i++) {\n positions[nodes[i]] = posArray[i];\n }\n\n return rescaleLayout(positions) as PositionMap;\n}\n\n// Helper function to get node degree\nfunction getNodeDegree(graph: Graph, node: Node): number {\n return graph.edges().filter((edge: Edge) =>\n edge[0] === node || edge[1] === node\n ).length;\n}","import type { Graph, Node, PositionMap } from '../../types';\nimport { getNodesFromGraph, getEdgesFromGraph } from '../../utils/graph';\nimport { RandomNumberGenerator } from '../../utils/random';\nimport { randomLayout } from '../basic/random';\n\n/**\n * Layout algorithm with attractive and repulsive forces (ARF).\n * \n * @param G - Graph\n * @param pos - Initial positions for nodes\n * @param scaling - Scale factor for positions\n * @param a - Strength of springs between connected nodes (should be > 1)\n * @param maxIter - Maximum number of iterations\n * @param seed - Random seed for initial positions\n * @returns Positions dictionary keyed by node\n */\nexport function arfLayout(\n G: Graph,\n pos: PositionMap | null = null,\n scaling: number = 1,\n a: number = 1.1,\n maxIter: number = 1000,\n seed: number | null = null\n): PositionMap {\n if (a <= 1) {\n throw new Error(\"The parameter a should be larger than 1\");\n }\n\n const nodes = getNodesFromGraph(G);\n const edges = getEdgesFromGraph(G);\n\n if (nodes.length === 0) {\n return {};\n }\n\n // Initialize positions if not provided\n if (!pos) {\n pos = randomLayout(G, null, 2, seed);\n } else {\n // Make sure all nodes have positions\n const rng = new RandomNumberGenerator(seed ?? undefined);\n const defaultPos: PositionMap = {};\n nodes.forEach((node: Node) => {\n if (!pos![node]) {\n defaultPos[node] = [(rng.rand() as number), (rng.rand() as number)];\n }\n });\n pos = { ...pos, ...defaultPos };\n }\n\n // Create node index mapping\n const nodeIndex: Record<Node, number> = {};\n nodes.forEach((node: Node, i: number) => {\n nodeIndex[node] = i;\n });\n\n // Create positions array\n const positions: number[][] = nodes.map((node: Node) => [...pos![node]]);\n\n // Initialize spring constant matrix\n const N = nodes.length;\n const K = Array(N).fill(0).map(() => Array(N).fill(1));\n\n // Set diagonal to zero (no self-attraction)\n for (let i = 0; i < N; i++) {\n K[i][i] = 0;\n }\n\n // Set stronger attraction between connected nodes\n for (const [source, target] of edges) {\n if (source === target) continue;\n\n const i = nodeIndex[source];\n const j = nodeIndex[target];\n K[i][j] = a;\n K[j][i] = a;\n }\n\n // Calculate rho (scale factor)\n const rho = scaling * Math.sqrt(N);\n\n // Optimization loop\n const dt = 1e-3; // Time step\n const etol = 1e-6; // Error tolerance\n let error = etol + 1;\n let nIter = 0;\n\n while (error > etol && nIter < maxIter) {\n // Calculate changes for each node\n const change = Array(N).fill(0).map(() => [0, 0]);\n\n for (let i = 0; i < N; i++) {\n for (let j = 0; j < N; j++) {\n if (i === j) continue;\n\n // Calculate difference vector\n const diff = positions[i].map((coord, dim) => coord - positions[j][dim]);\n\n // Calculate distance (with minimum to avoid division by zero)\n const dist = Math.sqrt(diff.reduce((sum, d) => sum + d * d, 0)) || 0.01;\n\n // Calculate attractive and repulsive forces\n for (let d = 0; d < diff.length; d++) {\n change[i][d] += K[i][j] * diff[d] - (rho / dist) * diff[d];\n }\n }\n }\n\n // Update positions\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < positions[i].length; d++) {\n positions[i][d] += change[i][d] * dt;\n }\n }\n\n // Calculate error (sum of force magnitudes)\n error = change.reduce((sum, c) =>\n sum + Math.sqrt(c.reduce((s, v) => s + v * v, 0)), 0);\n\n nIter++;\n }\n\n // Convert positions array back to object\n const finalPos: PositionMap = {};\n nodes.forEach((node: Node, i: number) => {\n finalPos[node] = positions[i];\n });\n\n return finalPos;\n}","/**\n * Bipartite layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from '../../types';\nimport { _processParams } from '../../utils/params';\nimport { getNodesFromGraph } from '../../utils/graph';\nimport { rescaleLayout } from '../../utils/rescale';\n\n/**\n * Position nodes in two straight lines (bipartite layout).\n * \n * @param G - Graph or list of nodes\n * @param nodes - Nodes in one node set of the graph\n * @param align - The alignment of nodes: 'vertical' or 'horizontal'\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param aspectRatio - The ratio of the width to the height of the layout\n * @returns Positions dictionary keyed by node\n */\nexport function bipartiteLayout(\n G: Graph,\n nodes: Node[] | null = null,\n align: 'vertical' | 'horizontal' = 'vertical',\n scale: number = 1,\n center: number[] | null = null,\n aspectRatio: number = 4 / 3\n): PositionMap {\n if (align !== 'vertical' && align !== 'horizontal') {\n throw new Error(\"align must be either vertical or horizontal\");\n }\n\n const processed = _processParams(G, center || [0, 0], 2);\n const graph = processed.G;\n center = processed.center;\n\n const allNodes = getNodesFromGraph(graph);\n\n if (allNodes.length === 0) {\n return {};\n }\n\n // If nodes not provided, try to determine bipartite sets\n if (!nodes) {\n // A simple heuristic for bipartite detection: use nodes with even/odd indices\n // This is a simplification, in Python NetworkX has bipartite.sets()\n nodes = allNodes.filter((_: Node, i: number): boolean => i % 2 === 0);\n }\n\n const left = new Set(nodes);\n const right: Set<Node> = new Set(allNodes.filter((n: Node) => !left.has(n)));\n\n const height = 1;\n const width = aspectRatio * height;\n const offset = [width / 2, height / 2];\n\n const pos: PositionMap = {};\n\n // Position nodes in the left set\n const leftNodes = [...left];\n leftNodes.forEach((node, i) => {\n const x = 0;\n const y = i * height / (leftNodes.length || 1);\n pos[node] = [x, y];\n });\n\n // Position nodes in the right set\n const rightNodes = [...right];\n rightNodes.forEach((node, i) => {\n const x = width;\n const y = i * height / (rightNodes.length || 1);\n pos[node] = [x, y];\n });\n\n // Center positions around the origin and apply offset\n for (const node in pos) {\n pos[node][0] -= offset[0];\n pos[node][1] -= offset[1];\n }\n\n // Rescale positions\n const scaledPos = rescaleLayout(pos, scale, center) as PositionMap;\n\n // Handle horizontal alignment\n if (align === 'horizontal') {\n for (const node in scaledPos) {\n const temp = scaledPos[node][0];\n scaledPos[node][0] = scaledPos[node][1];\n scaledPos[node][1] = temp;\n }\n }\n\n return scaledPos;\n}","import type { Graph, Node, PositionMap } from '../../types';\nimport { getNodesFromGraph, getNeighbors } from '../../utils/graph';\nimport { _processParams } from '../../utils/params';\nimport { rescaleLayout } from '../../utils/rescale';\n\n/**\n * Position nodes in layers of straight lines (multipartite layout).\n * \n * @param G - Graph or list of nodes\n * @param subsetKey - Object mapping layers to node sets, or node attribute name\n * @param align - The alignment of nodes: 'vertical' or 'horizontal'\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @returns Positions dictionary keyed by node\n */\nexport function multipartiteLayout(\n G: Graph,\n subsetKey: Record<number | string, Node | Node[]> | string = 'subset',\n align: 'vertical' | 'horizontal' = 'vertical',\n scale: number = 1,\n center: number[] | null = null\n): PositionMap {\n if (align !== 'vertical' && align !== 'horizontal') {\n throw new Error(\"align must be either vertical or horizontal\");\n }\n\n const processed = _processParams(G, center || [0, 0], 2);\n const graph = processed.G;\n center = processed.center;\n\n const allNodes = getNodesFromGraph(graph);\n\n if (allNodes.length === 0) {\n return {};\n }\n\n // Convert subsetKey to a layer mapping if it's a string\n let layers: Record<number | string, Node[]> = {};\n if (typeof subsetKey === 'string') {\n // In JS we don't have access to node attributes directly\n // This is a simplification - in a real implementation we would need\n // to access node attributes from the graph\n console.warn(\"Using string subsetKey requires node attributes, using default partitioning\");\n // Create a simple partitioning as fallback\n layers = { 0: allNodes };\n } else {\n // subsetKey is already a mapping of layers to nodes\n // Convert single nodes to arrays\n for (const [key, value] of Object.entries(subsetKey)) {\n if (Array.isArray(value)) {\n layers[key] = value;\n } else {\n layers[key] = [value];\n }\n }\n }\n\n const layerCount = Object.keys(layers).length;\n let pos: PositionMap = {};\n\n // Process each layer\n Object.entries(layers).forEach(([layer, nodes], layerIdx) => {\n const layerNodes = Array.isArray(nodes) ? nodes : [nodes];\n const layerSize = layerNodes.length;\n\n layerNodes.forEach((node, nodeIdx) => {\n // Place nodes in a grid: layerIdx determines x-coordinate (column)\n // nodeIdx determines y-coordinate (row position within column)\n const x = layerIdx - (layerCount - 1) / 2;\n const y = nodeIdx - (layerSize - 1) / 2;\n pos[node] = [x, y];\n });\n });\n\n // Rescale positions\n pos = rescaleLayout(pos, scale, center) as PositionMap;\n\n // Handle horizontal alignment\n if (align === 'horizontal') {\n for (const node in pos) {\n const temp = pos[node][0];\n pos[node][0] = pos[node][1];\n pos[node][1] = temp;\n }\n }\n\n return pos;\n}","import type { Graph, Node, Edge, PositionMap } from '../../types';\nimport { getNodesFromGraph, getNeighbors } from '../../utils/graph';\nimport { _processParams } from '../../utils/params';\nimport { multipartiteLayout } from './multipartite';\n\n/**\n * Position nodes according to breadth-first search algorithm.\n * \n * @param G - Graph \n * @param start - Starting node for bfs\n * @param align - The alignment of layers: 'vertical' or 'horizontal'\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @returns Positions dictionary keyed by node\n */\nexport function bfsLayout(\n G: Graph,\n start: Node,\n align: 'vertical' | 'horizontal' = 'vertical',\n scale: number = 1,\n center: number[] | null = null\n): PositionMap {\n const processed = _processParams(G, center || [0, 0], 2);\n \n // BFS layout requires a proper Graph, not just a list of nodes\n if (Array.isArray(processed.G)) {\n throw new Error('BFS layout requires a Graph with edges, not just a list of nodes');\n }\n \n const graph = processed.G;\n center = processed.center;\n\n const allNodes = getNodesFromGraph(graph);\n\n if (allNodes.length === 0) {\n return {};\n }\n\n // Compute BFS layers\n const layers: Record<number, Node[]> = {};\n const visited = new Set<Node>();\n let currentLayer = 0;\n\n // Starting layer\n layers[currentLayer] = [start];\n visited.add(start);\n\n // BFS traversal\n while (Object.values(layers).flat().length < allNodes.length) {\n const nextLayer: Node[] = [];\n const currentNodes = layers[currentLayer];\n\n for (const node of currentNodes) {\n // Get neighbors - this is a simplified approach\n // In a real implementation, we would get neighbors from the graph\n const neighbors = getNeighbors(graph, node);\n\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n nextLayer.push(neighbor);\n visited.add(neighbor);\n }\n }\n }\n\n if (nextLayer.length === 0) {\n // No more connected nodes\n const unvisited: Node[] = allNodes.filter((node: Node) => !visited.has(node));\n if (unvisited.length > 0) {\n throw new Error(\"bfs_layout didn't include all nodes. Graph may be disconnected.\");\n }\n break;\n }\n\n currentLayer++;\n layers[currentLayer] = nextLayer;\n }\n\n // Use multipartite_layout to position the layers\n return multipartiteLayout(graph, layers, align, scale, center);\n}","/**\n * Spectral layout algorithm using eigenvectors of the graph Laplacian\n */\n\nimport { Graph, Node, Edge, PositionMap } from '../../types';\nimport { _processParams } from '../../utils/params';\nimport { getNodesFromGraph, getEdgesFromGraph } from '../../utils/graph';\nimport { rescaleLayout } from '../../utils/rescale';\n\n/**\n * Position nodes in a spectral layout using eigenvectors of the graph Laplacian.\n * \n * @param G - Graph\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @returns Positions dictionary keyed by node\n */\nexport function spectralLayout(\n G: Graph,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2\n): PositionMap {\n const processed = _processParams(G, center, dim);\n const graph = processed.G;\n center = processed.center;\n\n const nodes = getNodesFromGraph(graph);\n\n if (nodes.length <= 2) {\n if (nodes.length === 0) {\n return {};\n } else if (nodes.length === 1) {\n return { [nodes[0]]: center };\n } else {\n return {\n [nodes[0]]: center.map(v => v - scale),\n [nodes[1]]: center.map(v => v + scale)\n };\n }\n }\n\n // Create adjacency matrix\n const N = nodes.length;\n const nodeIndices: Record<Node, number> = {};\n nodes.forEach((node: Node, i: number) => { nodeIndices[node] = i; });\n\n const A = Array(N).fill(0).map(() => Array(N).fill(0));\n const edges = getEdgesFromGraph(graph);\n\n for (const [source, target] of edges) {\n const i = nodeIndices[source];\n const j = nodeIndices[target];\n A[i][j] = 1;\n A[j][i] = 1; // Make symmetric for undirected graphs\n }\n\n // Create Laplacian matrix: L = D - A where D is degree matrix\n const L = Array(N).fill(0).map(() => Array(N).fill(0));\n for (let i = 0; i < N; i++) {\n // Compute degree (sum of row)\n L[i][i] = A[i].reduce((sum, val) => sum + val, 0);\n for (let j = 0; j < N; j++) {\n L[i][j] -= A[i][j];\n }\n }\n\n // Compute eigenvectors using power iteration method\n // We need the smallest non-zero eigenvectors of L\n const eigenvectors: number[][] = [];\n\n // For each dimension, find an eigenvector\n for (let d = 0; d < dim; d++) {\n let vector = Array(N).fill(0).map(() => Math.random() - 0.5);\n\n // Orthogonalize against previous eigenvectors\n for (const ev of eigenvectors) {\n const dot = vector.reduce((acc, val, idx) => acc + val * ev[idx], 0);\n vector = vector.map((val, idx) => val - dot * ev[idx]);\n }\n\n // Normalize\n const norm = Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0));\n vector = vector.map(val => val / norm);\n\n // Apply shifted inverse iteration to find smallest non-zero eigenvector\n // This is a simplification of the actual algorithm\n for (let iter = 0; iter < 100; iter++) {\n // Apply Laplacian\n const newVec = Array(N).fill(0);\n for (let i = 0; i < N; i++) {\n for (let j = 0; j < N; j++) {\n newVec[i] += L[i][j] * vector[j];\n }\n }\n\n // Orthogonalize against the constant vector (eigenvector with eigenvalue 0)\n const mean = newVec.reduce((acc, val) => acc + val, 0) / N;\n newVec.forEach((val, idx, arr) => { arr[idx] = val - mean; });\n\n // Normalize\n const newNorm = Math.sqrt(newVec.reduce((acc, val) => acc + val * val, 0));\n if (newNorm < 1e-10) continue; // Skip if vector is close to zero\n\n vector = newVec.map(val => val / newNorm);\n }\n\n eigenvectors.push(vector);\n }\n\n // Create position array from eigenvectors\n const positions: number[][] = Array(N).fill(0).map(() => Array(dim).fill(0));\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < dim; d++) {\n positions[i][d] = eigenvectors[d][i];\n }\n }\n\n // Rescale and create position dictionary\n const scaledPositions = rescaleLayout(positions as any, scale);\n const pos: PositionMap = {};\n nodes.forEach((node: Node, i: number) => {\n pos[node] = (scaledPositions as number[][])[i].map((val: number, j: number) => val + center[j]);\n });\n\n return pos;\n}","/**\n * Special graph detection functions for planarity testing\n */\n\nimport { Node, Edge } from '../../types';\n\n/**\n * Check if graph is K5 (complete graph with 5 nodes)\n * \n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns True if graph is K5\n */\nexport function isK5(nodes: Node[], edges: Edge[]): boolean {\n if (nodes.length !== 5) return false;\n\n // K5 has exactly 10 edges\n if (edges.length !== 10) return false;\n\n // Check if every pair of distinct nodes is connected\n for (let i = 0; i < nodes.length; i++) {\n for (let j = i + 1; j < nodes.length; j++) {\n const hasEdge = edges.some(\n e => (e[0] === nodes[i] && e[1] === nodes[j]) ||\n (e[0] === nodes[j] && e[1] === nodes[i])\n );\n if (!hasEdge) return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check if graph is K3,3 (complete bipartite with 3,3 nodes)\n * \n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns True if graph is K3,3\n */\nexport function isK33(nodes: Node[], edges: Edge[]): boolean {\n if (nodes.length !== 6) return false;\n\n // K3,3 has exactly 9 edges\n if (edges.length !== 9) return false;\n\n // Try to find a bipartite partition\n const nodePartitions = tryFindBipartitePartition(nodes, edges);\n if (!nodePartitions) return false;\n\n const [part1, part2] = nodePartitions;\n\n // Check if both partitions have size 3\n if (part1.length !== 3 || part2.length !== 3) return false;\n\n // Check if every node in part1 is connected to every node in part2\n for (const n1 of part1) {\n for (const n2 of part2) {\n const hasEdge = edges.some(\n e => (e[0] === n1 && e[1] === n2) ||\n (e[0] === n2 && e[1] === n1)\n );\n if (!hasEdge) return false;\n }\n }\n\n return true;\n}\n\n/**\n * Try to find a bipartite partition of the nodes\n * \n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns Array of two partitions, or null if not bipartite\n */\nexport function tryFindBipartitePartition(\n nodes: Node[],\n edges: Edge[]\n): [Node[], Node[]] | null {\n const colorMap: Record<Node, number> = {};\n const adjList: Record<Node, Node[]> = {};\n\n // Create adjacency list\n for (const node of nodes) {\n adjList[node] = [];\n }\n\n for (const [u, v] of edges) {\n adjList[u].push(v);\n adjList[v].push(u);\n }\n\n // BFS to color nodes\n const queue: Node[] = [nodes[0]];\n colorMap[nodes[0]] = 0;\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n const nodeColor = colorMap[node];\n\n for (const neighbor of adjList[node]) {\n if (colorMap[neighbor] === undefined) {\n colorMap[neighbor] = 1 - nodeColor; // Toggle color (0/1)\n queue.push(neighbor);\n } else if (colorMap[neighbor] === nodeColor) {\n // Conflict: not bipartite\n return null;\n }\n }\n }\n\n // Create partitions\n const part0: Node[] = [];\n const part1: Node[] = [];\n\n for (const node of nodes) {\n if (colorMap[node] === 0) {\n part0.push(node);\n } else {\n part1.push(node);\n }\n }\n\n return [part0, part1];\n}","/**\n * Embedding functions for planar graphs\n */\n\nimport { Node, Edge, Embedding, PositionMap } from '../../types';\nimport { RandomNumberGenerator } from '../../utils/random';\n\n/**\n * Create a triangulation-based embedding for a planar graph\n * \n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns Embedding object\n */\nexport function createTriangulationEmbedding(\n nodes: Node[],\n edges: Edge[],\n seed: number | null = null\n): Embedding {\n // Create RNG instance for deterministic randomness\n const rng = new RandomNumberGenerator(seed ?? undefined);\n \n // Create a simple embedding using the incremental approach\n const embedding: Embedding = {\n nodeOrder: [...nodes],\n faceList: [],\n nodePositions: {}\n };\n\n // Create a map of adjacent nodes\n const adjMap: Record<Node, Set<Node>> = {};\n for (const node of nodes) {\n adjMap[node] = new Set<Node>();\n }\n\n for (const [u, v] of edges) {\n adjMap[u].add(v);\n adjMap[v].add(u);\n }\n\n // Create outer face as a cycle (if possible)\n const outerFace = findCycle(nodes, edges, adjMap) || nodes;\n embedding.faceList.push(outerFace);\n\n // Position nodes on a convex polygon (outer face)\n const n = outerFace.length;\n for (let i = 0; i < n; i++) {\n const angle = 2 * Math.PI * i / n;\n embedding.nodePositions[outerFace[i]] = [Math.cos(angle), Math.sin(angle)];\n }\n\n // Position interior nodes using barycentric coordinates\n const interiorNodes = nodes.filter(node => !embedding.nodePositions[node]);\n\n for (const node of interiorNodes) {\n const neighbors = Array.from(adjMap[node]);\n\n if (neighbors.length === 0) {\n // Isolated node, place at center\n embedding.nodePositions[node] = [0, 0];\n } else {\n // Average position of neighbors that have positions\n let xSum = 0, ySum = 0, count = 0;\n\n for (const neighbor of neighbors) {\n if (embedding.nodePositions[neighbor]) {\n xSum += embedding.nodePositions[neighbor][0];\n ySum += embedding.nodePositions[neighbor][1];\n count++;\n }\n }\n\n if (count > 0) {\n // Place slightly away from center to avoid overlaps\n const jitter = 0.1 * (rng.rand() as number);\n embedding.nodePositions[node] = [\n xSum / count + jitter * ((rng.rand() as number) - 0.5),\n ySum / count + jitter * ((rng.rand() as number) - 0.5)\n ];\n } else {\n // No neighbors have positions yet, place randomly inside unit circle\n const r = 0.5 * (rng.rand() as number);\n const angle = 2 * Math.PI * (rng.rand() as number);\n embedding.nodePositions[node] = [r * Math.cos(angle), r * Math.sin(angle)];\n }\n }\n }\n\n return embedding;\n}\n\n/**\n * Find a simple cycle in the graph (for outer face)\n * \n * @param nodes - List of nodes\n * @param edges - List of edges\n * @param adjMap - Adjacency map\n * @returns Cycle as array of nodes, or null if none found\n */\nexport function findCycle(\n nodes: Node[],\n edges: Edge[],\n adjMap: Record<Node, Set<Node>>\n): Node[] | null {\n if (nodes.length === 0) return null;\n if (nodes.length <= 2) return nodes; // Not a real cycle but handle it\n\n // Try to find a Hamiltonian cycle for simplicity (for small graphs)\n if (nodes.length <= 8) {\n const visited = new Set<Node>();\n const path: Node[] = [];\n\n function hamiltonianCycleDFS(node: Node): boolean {\n path.push(node);\n visited.add(node);\n\n if (path.length === nodes.length) {\n // Check if it's a cycle (last node connects to first)\n if (adjMap[node].has(path[0])) {\n return true;\n }\n // Not a cycle\n visited.delete(node);\n path.pop();\n return false;\n }\n\n for (const neighbor of adjMap[node]) {\n if (!visited.has(neighbor)) {\n if (hamiltonianCycleDFS(neighbor)) {\n return true;\n }\n }\n }\n\n visited.delete(node);\n path.pop();\n return false;\n }\n\n if (hamiltonianCycleDFS(nodes[0])) {\n return path;\n }\n }\n\n // Fallback: try to find any cycle using DFS\n const visited = new Set<Node>();\n const parent: Record<Node, Node | null> = {};\n let cycleFound: Node[] | null = null;\n\n function findCycleDFS(node: Node, parentNode: Node | null): boolean {\n visited.add(node);\n\n for (const neighbor of adjMap[node]) {\n if (neighbor === parentNode) continue;\n\n if (visited.has(neighbor)) {\n // Found a cycle\n cycleFound = constructCycle(node, neighbor, parent);\n return true;\n }\n\n parent[neighbor] = node;\n if (findCycleDFS(neighbor, node)) {\n return true;\n }\n }\n\n return false;\n }\n\n function constructCycle(u: Node, v: Node, parent: Record<Node, Node | null>): Node[] {\n const cycle: Node[] = [v, u];\n let current = u;\n\n while (parent[current] !== undefined && parent[current] !== v) {\n current = parent[current]!;\n cycle.push(current);\n }\n\n return cycle;\n }\n\n // Try to find a cycle\n for (const node of nodes) {\n if (!visited.has(node)) {\n parent[node] = null;\n if (findCycleDFS(node, null)) {\n break;\n }\n }\n }\n\n return cycleFound || nodes; // Fallback to all nodes if no cycle found\n}\n\n/**\n * Convert a combinatorial embedding to node positions\n * \n * @param embedding - The embedding object\n * @param nodes - List of nodes\n * @returns Dictionary mapping nodes to positions\n */\nexport function combinatorialEmbeddingToPos(\n embedding: Embedding,\n nodes: Node[]\n): PositionMap {\n const pos: PositionMap = {};\n\n // Use the positions from the embedding\n for (const node of nodes) {\n if (embedding.nodePositions[node]) {\n pos[node] = embedding.nodePositions[node];\n } else {\n // Fallback for any nodes without positions\n pos[node] = [0, 0];\n }\n }\n\n return pos;\n}","/**\n * Left-Right Planarity Test implementation\n */\n\nimport { Node, Edge, Embedding } from '../../types';\nimport { createTriangulationEmbedding } from './embedding';\n\n/**\n * Left-Right Planarity Test for general graphs\n *\n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns Object containing isPlanar flag and embedding\n */\nexport function lrPlanarityTest(\n nodes: Node[],\n edges: Edge[],\n seed: number | null = null\n): { isPlanar: boolean; embedding: Embedding | null } {\n // Create adjacency list for the graph\n const adjList: Record<Node, Node[]> = {};\n for (const node of nodes) {\n adjList[node] = [];\n }\n\n for (const [u, v] of edges) {\n adjList[u].push(v);\n adjList[v].push(u);\n }\n\n // Step 1: Perform DFS to get an st-numbering (ordering of nodes)\n const visited = new Set<Node>();\n const ordering: Node[] = [];\n\n function dfs(node: Node): void {\n visited.add(node);\n ordering.push(node);\n\n for (const neighbor of adjList[node]) {\n if (!visited.has(neighbor)) {\n dfs(neighbor);\n }\n }\n }\n\n // Start DFS from first node\n dfs(nodes[0]);\n\n // If the graph is disconnected, it's still planar but we need to handle each component\n if (ordering.length < nodes.length) {\n // Create a simple triangulation embedding for disconnected graphs\n return { isPlanar: true, embedding: createTriangulationEmbedding(nodes, edges, seed) };\n }\n\n // Step 2: For a general implementation, we'll use a simplified approach\n // since this would normally require implementing the entire LR algorithm\n\n // For this implementation, since we can't fully implement Boyer-Myrvold,\n // we'll create a reasonable planar embedding for most planar graphs\n\n // We assume the graph is planar if it's sparse enough (|E| <= 3|V| - 6)\n // This is a necessary but not sufficient condition for planar graphs\n if (edges.length > 3 * nodes.length - 6) {\n return { isPlanar: false, embedding: null };\n }\n\n // Create a planar embedding using a triangulation approach\n const embedding = createTriangulationEmbedding(nodes, edges, seed);\n\n return { isPlanar: true, embedding };\n}","/**\n * Main planarity checking function\n */\n\nimport { Graph, Node, Edge, Embedding } from '../../types';\nimport { isK5, isK33 } from './special-graphs';\nimport { lrPlanarityTest } from './lr-test';\nimport { createTriangulationEmbedding } from './embedding';\n\n/**\n * Check if graph is planar using a simplified version of Boyer-Myrvold algorithm.\n * Returns planarity and embedding information.\n * \n * @param G - Graph\n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns Object containing isPlanar flag and embedding\n */\nexport function checkPlanarity(\n G: Graph,\n nodes: Node[],\n edges: Edge[],\n seed: number | null = null\n): { isPlanar: boolean; embedding: Embedding | null } {\n // For small graphs (n <= 4), all are planar\n if (nodes.length <= 4) {\n return { isPlanar: true, embedding: createTriangulationEmbedding(nodes, edges, seed) };\n }\n\n // For K5 (complete graph with 5 nodes) and K3,3 (complete bipartite with 3,3 nodes)\n // these are not planar by Kuratowski's theorem\n if (isK5(nodes, edges) || isK33(nodes, edges)) {\n return { isPlanar: false, embedding: null };\n }\n\n // For other graphs, use LR algorithm (Left-Right Planarity Test)\n const result = lrPlanarityTest(nodes, edges, seed);\n return result;\n}","/**\n * Planar layout algorithm\n */\n\nimport { Graph, Node, Edge, PositionMap } from '../../types';\nimport { _processParams } from '../../utils/params';\nimport { getNodesFromGraph, getEdgesFromGraph } from '../../utils/graph';\nimport { rescaleLayout } from '../../utils/rescale';\nimport { checkPlanarity, combinatorialEmbeddingToPos } from '../../algorithms/planarity';\n\n/**\n * Position nodes without edge intersections (planar layout).\n * \n * @param G - Graph\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout (must be 2)\n * @param seed - Random seed for reproducible layouts\n * @returns Positions dictionary keyed by node\n */\nexport function planarLayout(\n G: Graph,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n seed: number | null = null\n): PositionMap {\n if (dim !== 2) {\n throw new Error(\"can only handle 2 dimensions\");\n }\n\n const processed = _processParams(G, center || [0, 0], dim);\n \n // Planar layout requires a proper Graph, not just a list of nodes\n if (Array.isArray(processed.G)) {\n throw new Error('Planar layout requires a Graph with edges, not just a list of nodes');\n }\n \n const graph = processed.G;\n center = processed.center;\n\n const nodes = getNodesFromGraph(graph);\n const edges = getEdgesFromGraph(graph);\n\n if (nodes.length === 0) {\n return {};\n }\n\n // Check if graph is planar and get embedding\n const { isPlanar, embedding } = checkPlanarity(graph, nodes, edges, seed);\n\n if (!isPlanar) {\n throw new Error(\"G is not planar.\");\n }\n\n if (!embedding) {\n throw new Error(\"Failed to generate planar embedding.\");\n }\n\n // Convert embedding to positions\n let pos = combinatorialEmbeddingToPos(embedding, nodes);\n\n // Rescale the positions\n pos = rescaleLayout(pos, scale, center) as PositionMap;\n\n return pos;\n}","/**\n * Basic graph generation functions\n */\n\nimport { Graph, Node, Edge } from '../types';\n\n/**\n * Create a complete graph with n nodes\n * @param n - Number of nodes\n * @returns Graph object with all nodes connected to all other nodes\n */\nexport function completeGraph(n: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n \n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n edges.push([i, j]);\n }\n }\n \n return {\n nodes: () => nodes,\n edges: () => edges\n };\n}\n\n/**\n * Create a cycle graph with n nodes\n * @param n - Number of nodes\n * @returns Graph object with nodes connected in a cycle\n */\nexport function cycleGraph(n: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n \n for (let i = 0; i < n; i++) {\n edges.push([i, (i + 1) % n]);\n }\n \n return {\n nodes: () => nodes,\n edges: () => edges\n };\n}\n\n/**\n * Create a star graph with n nodes (1 center + n-1 leaves)\n * @param n - Total number of nodes\n * @returns Graph object with star topology\n */\nexport function starGraph(n: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n \n // Connect all nodes to node 0 (center)\n for (let i = 1; i < n; i++) {\n edges.push([0, i]);\n }\n \n return {\n nodes: () => nodes,\n edges: () => edges\n };\n}\n\n/**\n * Create a wheel graph with n nodes (1 center + n-1 rim nodes)\n * @param n - Total number of nodes\n * @returns Graph object with wheel topology\n */\nexport function wheelGraph(n: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n \n // Connect all rim nodes to center (node 0)\n for (let i = 1; i < n; i++) {\n edges.push([0, i]);\n }\n \n // Connect rim nodes in a cycle\n for (let i = 1; i < n - 1; i++) {\n edges.push([i, i + 1]);\n }\n if (n > 2) {\n edges.push([n - 1, 1]);\n }\n \n return {\n nodes: () => nodes,\n edges: () => edges\n };\n}","/**\n * Grid graph generation function\n */\n\nimport { Graph, Node, Edge } from '../types';\n\n/**\n * Create a grid graph with rows x cols nodes\n * @param rows - Number of rows\n * @param cols - Number of columns\n * @returns Graph object with grid topology\n */\nexport function gridGraph(rows: number, cols: number): Graph {\n const nodes: Node[] = [];\n const edges: Edge[] = [];\n \n // Create nodes\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n nodes.push(`${i},${j}`);\n }\n }\n \n // Create edges\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n // Connect to right neighbor\n if (j < cols - 1) {\n edges.push([`${i},${j}`, `${i},${j + 1}`]);\n }\n // Connect to bottom neighbor\n if (i < rows - 1) {\n edges.push([`${i},${j}`, `${i + 1},${j}`]);\n }\n }\n }\n \n return {\n nodes: () => nodes,\n edges: () => edges\n };\n}","/**\n * Random graph generation function\n */\n\nimport { Graph, Node, Edge } from '../types';\n\n/**\n * Create a random graph with n nodes and given edge probability\n * @param n - Number of nodes\n * @param p - Probability of edge between any two nodes (0-1)\n * @param seed - Random seed for reproducibility\n * @returns Graph object with random edges\n */\nexport function randomGraph(n: number, p: number, seed?: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n \n // Simple deterministic pseudo-random if seed provided\n let currentSeed = seed;\n let random = seed !== undefined \n ? () => {\n currentSeed = (currentSeed! * 9301 + 49297) % 233280;\n return currentSeed / 233280;\n }\n : Math.random;\n \n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n if (random() < p) {\n edges.push([i, j]);\n }\n }\n }\n \n return {\n nodes: () => nodes,\n edges: () => edges\n };\n}","/**\n * Bipartite graph generation function\n */\n\nimport { Graph, Node, Edge } from '../types';\n\n/**\n * Create a bipartite graph with two sets of nodes\n * @param n1 - Number of nodes in first set\n * @param n2 - Number of nodes in second set\n * @param p - Probability of edge between nodes in different sets\n * @param seed - Random seed for reproducibility\n * @returns Graph object with bipartite structure and setA/setB properties\n */\nexport function bipartiteGraph(n1: number, n2: number, p: number, seed?: number): Graph & { setA: Node[], setB: Node[] } {\n const setA: Node[] = Array.from({ length: n1 }, (_, i) => `A${i}`);\n const setB: Node[] = Array.from({ length: n2 }, (_, i) => `B${i}`);\n const nodes = [...setA, ...setB];\n const edges: Edge[] = [];\n \n // Simple deterministic pseudo-random if seed provided\n let currentSeed = seed;\n let random = seed !== undefined \n ? () => {\n currentSeed = (currentSeed! * 9301 + 49297) % 233280;\n return currentSeed / 233280;\n }\n : Math.random;\n \n // Only connect nodes between sets\n for (const a of setA) {\n for (const b of setB) {\n if (random() < p) {\n edges.push([a, b]);\n }\n }\n }\n \n return {\n nodes: () => nodes,\n edges: () => edges,\n setA,\n setB\n };\n}","/**\n * Scale-free graph generation function\n */\n\nimport { Graph, Node, Edge } from '../types';\n\n/**\n * Create a scale-free graph using Barabási-Albert model\n * @param n - Total number of nodes\n * @param m - Number of edges to attach from new node\n * @param seed - Random seed for reproducibility\n * @returns Graph object with scale-free properties\n */\nexport function scaleFreeGraph(n: number, m: number, seed?: number): Graph {\n if (m >= n) {\n throw new Error('m must be less than n');\n }\n \n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n const degrees = new Array(n).fill(0);\n \n // Simple deterministic pseudo-random if seed provided\n let currentSeed = seed;\n let random = seed !== undefined \n ? () => {\n currentSeed = (currentSeed! * 9301 + 49297) % 233280;\n return currentSeed / 233280;\n }\n : Math.random;\n \n // Start with complete graph of m+1 nodes\n for (let i = 0; i <= m; i++) {\n for (let j = i + 1; j <= m; j++) {\n edges.push([i, j]);\n degrees[i]++;\n degrees[j]++;\n }\n }\n \n // Add remaining nodes\n for (let i = m + 1; i < n; i++) {\n const targets = new Set<number>();\n const totalDegree = degrees.reduce((sum, d) => sum + d, 0);\n \n // Choose m targets based on preferential attachment\n while (targets.size < m) {\n let r = random() * totalDegree;\n let cumSum = 0;\n \n for (let j = 0; j < i; j++) {\n cumSum += degrees[j];\n if (r <= cumSum && !targets.has(j)) {\n targets.add(j);\n break;\n }\n }\n }\n \n // Add edges to targets\n for (const target of targets) {\n edges.push([i, target]);\n degrees[i]++;\n degrees[target]++;\n }\n }\n \n return {\n nodes: () => nodes,\n edges: () => edges\n };\n}"],"names":["result","i","posArray","n","swing","traction","speed","speedEfficiency","jitterTolerance","visited","parent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"layout.js","sources":["../src/utils/rescale.ts","../src/utils/graph.ts","../src/utils/params.ts","../src/utils/random.ts","../src/layouts/basic/random.ts","../src/layouts/force-directed/arf.ts","../src/layouts/force-directed/forceatlas2.ts","../src/layouts/force-directed/fruchterman-reingold.ts","../src/algorithms/optimization/lbfgs.ts","../src/algorithms/optimization/line-search.ts","../src/algorithms/optimization/kamada-kawai-solver.ts","../src/utils/numpy.ts","../src/layouts/geometric/circular.ts","../src/layouts/force-directed/kamada-kawai.ts","../src/layouts/force-directed/spring.ts","../src/layouts/geometric/shell.ts","../src/layouts/geometric/spiral.ts","../src/layouts/hierarchical/multipartite.ts","../src/layouts/hierarchical/bfs.ts","../src/layouts/hierarchical/bipartite.ts","../src/algorithms/planarity/embedding.ts","../src/algorithms/planarity/lr-test.ts","../src/algorithms/planarity/special-graphs.ts","../src/algorithms/planarity/check.ts","../src/layouts/specialized/planar.ts","../src/layouts/specialized/spectral.ts","../src/generators/basic.ts","../src/generators/bipartite.ts","../src/generators/grid.ts","../src/generators/random.ts","../src/generators/scale-free.ts"],"sourcesContent":["/**\n * Layout rescaling utilities\n */\n\nimport { PositionMap } from \"../types\";\n\n/**\n * Returns scaled position array/dict to (-scale, scale) in all axes.\n * @param pos - Position dictionary or array\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @returns Rescaled positions dictionary\n */\nexport function rescaleLayout(\n pos: PositionMap | number[][],\n scale: number = 1,\n center: number[] | null = null,\n): PositionMap | number[][] {\n // Check if pos is empty\n if (Array.isArray(pos)) {\n if (pos.length === 0) {return [];}\n } else {\n if (Object.keys(pos).length === 0) {return {};}\n }\n\n // Extract position values\n const posValues: number[][] = Array.isArray(pos) ? pos : Object.values(pos);\n const dim = posValues[0].length;\n\n // Fix Bug #1: Default center should match dimensionality\n if (!center) {\n center = Array(dim).fill(0);\n }\n\n // Use the maximum dimension between positions and center\n const targetDim = Math.max(dim, center.length);\n\n // Calculate center of positions, handling NaN values (Bug #3)\n const posCenter: number[] = Array(dim).fill(0);\n const counts: number[] = Array(dim).fill(0);\n\n for (const p of posValues) {\n for (let i = 0; i < dim; i++) {\n if (!isNaN(p[i])) {\n posCenter[i] += p[i];\n counts[i]++;\n }\n }\n }\n\n // Average by actual count, not total length\n for (let i = 0; i < dim; i++) {\n posCenter[i] = counts[i] > 0 ? posCenter[i] / counts[i] : 0;\n }\n\n // Center positions\n let centeredPos: PositionMap | number[][] = {};\n if (Array.isArray(pos)) {\n centeredPos = pos.map((p) => {\n const centered = Array(targetDim).fill(0);\n for (let i = 0; i < targetDim; i++) {\n centered[i] = (i < p.length ? p[i] : 0) - (i < posCenter.length ? posCenter[i] : 0);\n }\n return centered;\n });\n } else {\n for (const [node, p] of Object.entries(pos)) {\n const centered = Array(targetDim).fill(0);\n for (let i = 0; i < targetDim; i++) {\n centered[i] = (i < p.length ? p[i] : 0) - (i < posCenter.length ? posCenter[i] : 0);\n }\n (centeredPos)[node] = centered;\n }\n }\n\n // Find maximum distance from center, handling NaN values (Bug #3)\n let maxDistance = 0;\n const centeredValues = Array.isArray(centeredPos) ? centeredPos : Object.values(centeredPos);\n for (const p of centeredValues) {\n // Calculate distance, treating NaN as 0 for distance calculation\n let sumSquares = 0;\n for (const val of p) {\n if (!isNaN(val)) {\n sumSquares += val * val;\n }\n }\n const distance = Math.sqrt(sumSquares);\n if (!isNaN(distance)) {\n maxDistance = Math.max(maxDistance, distance);\n }\n }\n\n // Rescale\n let scaledPos: PositionMap | number[][] = Array.isArray(pos) ? [] : {};\n\n if (maxDistance > 0) {\n const scaleFactor = scale / maxDistance;\n\n if (Array.isArray(pos)) {\n (scaledPos as number[][]) = (centeredPos as number[][]).map((p, idx) =>\n p.map((val, i) => {\n // Check if this dimension existed in the original position\n const origPos = pos[idx];\n if (i >= origPos.length) {\n // This dimension was added, use center value\n return center[i];\n }\n // Preserve NaN values (Bug #3)\n if (isNaN(val)) {return NaN;}\n return val * scaleFactor + center[i];\n }),\n );\n } else {\n for (const [node, p] of Object.entries(centeredPos as PositionMap)) {\n const origPos = pos[node];\n (scaledPos as PositionMap)[node] = p.map((val, i) => {\n // Check if this dimension existed in the original position\n if (i >= origPos.length) {\n // This dimension was added, use center value\n return center[i];\n }\n // Preserve NaN values (Bug #3)\n if (isNaN(val)) {return NaN;}\n return val * scaleFactor + center[i];\n });\n }\n }\n } else {\n // All nodes at the same position - extend to target dimensionality\n if (Array.isArray(pos)) {\n (scaledPos as number[][]) = pos.map((p) => {\n const result = Array(targetDim);\n for (let i = 0; i < targetDim; i++) {\n if (i < p.length) {\n result[i] = isNaN(p[i]) ? NaN : center[i];\n } else {\n result[i] = center[i];\n }\n }\n return result;\n });\n } else {\n for (const [node, p] of Object.entries(pos)) {\n const result = Array(targetDim);\n for (let i = 0; i < targetDim; i++) {\n if (i < p.length) {\n result[i] = isNaN(p[i]) ? NaN : center[i];\n } else {\n result[i] = center[i];\n }\n }\n (scaledPos as PositionMap)[node] = result;\n }\n }\n }\n\n return scaledPos;\n}\n\n/**\n * Return a dictionary of scaled positions centered at (0, 0).\n * @param pos - Dictionary of positions\n * @param scale - Scale factor for positions\n * @returns Dictionary of scaled positions\n */\nexport function rescaleLayoutDict(pos: PositionMap, scale: number = 1): PositionMap {\n if (Object.keys(pos).length === 0) {\n return {};\n }\n\n // Extract positions as array\n const posArray = Object.values(pos);\n\n // Find center of positions\n const center: number[] = [];\n for (let d = 0; d < posArray[0].length; d++) {\n center[d] = posArray.reduce((sum, p) => sum + p[d], 0) / posArray.length;\n }\n\n // Center positions\n const centeredPos: PositionMap = {};\n for (const [node, p] of Object.entries(pos)) {\n centeredPos[node] = p.map((val, d) => val - center[d]);\n }\n\n // Find maximum distance from center\n let maxDist = 0;\n for (const p of Object.values(centeredPos)) {\n const dist = Math.sqrt(p.reduce((sum, val) => sum + val * val, 0));\n maxDist = Math.max(maxDist, dist);\n }\n\n // Scale positions\n const scaledPos: PositionMap = {};\n if (maxDist > 0) {\n for (const [node, p] of Object.entries(centeredPos)) {\n scaledPos[node] = p.map((val) => (val * scale) / maxDist);\n }\n } else {\n // All points at the center\n for (const node of Object.keys(centeredPos)) {\n scaledPos[node] = Array(centeredPos[node].length).fill(0);\n }\n }\n\n return scaledPos;\n}\n","/**\n * Graph utility functions\n */\n\nimport { Edge,Graph, Node } from \"../types\";\n\n/**\n * Extract nodes from a graph object\n * @param G - Graph or list of nodes\n * @returns Array of nodes\n */\nexport function getNodesFromGraph(G: Graph | Node[]): Node[] {\n if (Array.isArray(G)) {\n return G;\n }\n return G.nodes();\n}\n\n/**\n * Extract edges from a graph object\n * @param G - Graph or list of nodes\n * @returns Array of edges\n */\nexport function getEdgesFromGraph(G: Graph | Node[]): Edge[] {\n if (Array.isArray(G)) {\n return [];\n }\n return G.edges();\n}\n\n/**\n * Get the degree of a node in the graph\n * @param graph - Graph object\n * @param node - Node to get degree for\n * @returns Degree of the node\n */\nexport function getNodeDegree(graph: Graph, node: Node): number {\n if (!graph.edges) {return 0;}\n\n const edges = graph.edges();\n let degree = 0;\n\n for (const [source, target] of edges) {\n if (source === node || target === node) {\n degree++;\n }\n }\n\n return degree;\n}\n\n/**\n * Get the neighbors of a node in the graph\n * @param graph - Graph object\n * @param node - Node to get neighbors for\n * @returns Array of neighbor nodes\n */\nexport function getNeighbors(graph: Graph, node: Node): Node[] {\n if (!graph.edges) {return [];}\n\n const neighbors = new Set<Node>();\n const edges = graph.edges();\n\n for (const [source, target] of edges) {\n if (source === node) {\n neighbors.add(target);\n } else if (target === node) {\n neighbors.add(source);\n }\n }\n\n return Array.from(neighbors);\n}\n","/**\n * Parameter processing utilities\n */\n\nimport { Graph, Node } from \"../types\";\n\n/**\n * Process and validate layout parameters\n * Helper function similar to _process_params in Python version\n * @param G - Graph object or array of nodes\n * @param center - Center coordinates or null\n * @param dim - Dimension of layout\n * @returns Processed parameters\n */\nexport function _processParams(\n G: Graph | Node[],\n center: number[] | null,\n dim: number,\n): { G: Graph | Node[]; center: number[] } {\n if (!center) {\n center = Array(dim).fill(0);\n }\n\n if (center.length !== dim) {\n throw new Error(\"length of center coordinates must match dimension of layout\");\n }\n\n return { G, center };\n}\n","/**\n * Random number generator for seed-based randomization\n * Maintains exact same functionality as original implementation\n */\n\n/**\n * A deterministic random number generator based on a linear congruential generator (LCG) algorithm.\n * Provides consistent random sequences when initialized with the same seed.\n */\nexport class RandomNumberGenerator {\n private seed: number;\n private m: number;\n private a: number;\n private c: number;\n private _state: number;\n\n /**\n * Creates a new random number generator instance.\n * @param seed - Initial seed value for the generator. If not provided, uses a random seed.\n */\n constructor(seed?: number) {\n this.seed = seed || Math.floor(Math.random() * 1000000);\n this.m = 2 ** 35 - 31;\n this.a = 185852;\n this.c = 1;\n this._state = this.seed % this.m;\n }\n\n /**\n * Generates the next random number in the sequence.\n * @returns A random number between 0 and 1.\n */\n _next(): number {\n this._state = (this.a * this._state + this.c) % this.m;\n return this._state / this.m;\n }\n\n /**\n * Generates random numbers according to the specified shape.\n * @param shape - Determines the output format: null for single number, number for 1D array, array for multi-dimensional array.\n * @returns A random number, 1D array, or multi-dimensional array depending on the shape parameter.\n */\n rand(shape: number | number[] | null = null): number | number[] | number[][] {\n if (shape === null) {\n return this._next();\n }\n\n if (typeof shape === \"number\") {\n const result: number[] = [];\n for (let i = 0; i < shape; i++) {\n result.push(this._next());\n }\n return result;\n }\n\n if (shape.length === 1) {\n const result: number[] = [];\n for (let i = 0; i < shape[0]; i++) {\n result.push(this._next());\n }\n return result;\n }\n\n const result: (number | number[] | number[][])[] = [];\n for (let i = 0; i < shape[0]; i++) {\n result.push(this.rand(shape.slice(1)));\n }\n return result as number[][];\n }\n}\n","/**\n * Random layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from \"../../types\";\nimport { getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { RandomNumberGenerator } from \"../../utils/random\";\n\n/**\n * Position nodes uniformly at random in the unit square.\n * @param G - Graph or list of nodes\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @param seed - Random seed for reproducible layouts\n * @returns Positions dictionary keyed by node\n */\nexport function randomLayout(\n G: Graph | Node[],\n center: number[] | null = null,\n dim: number = 2,\n seed: number | null = null,\n): PositionMap {\n const processed = _processParams(G, center, dim);\n const nodes = getNodesFromGraph(processed.G);\n ({ center } = processed);\n\n const rng = new RandomNumberGenerator(seed ?? undefined);\n const pos: PositionMap = {};\n\n nodes.forEach((node: Node) => {\n pos[node] = (rng.rand(dim) as number[]).map((val: number, i: number) => val + center[i]);\n });\n\n return pos;\n}\n","import type { Graph, Node, PositionMap } from \"../../types\";\nimport { getEdgesFromGraph,getNodesFromGraph } from \"../../utils/graph\";\nimport { RandomNumberGenerator } from \"../../utils/random\";\nimport { randomLayout } from \"../basic/random\";\n\n/**\n * Layout algorithm with attractive and repulsive forces (ARF).\n * @param G - Graph\n * @param pos - Initial positions for nodes\n * @param scaling - Scale factor for positions\n * @param a - Strength of springs between connected nodes (should be > 1)\n * @param maxIter - Maximum number of iterations\n * @param seed - Random seed for initial positions\n * @returns Positions dictionary keyed by node\n */\nexport function arfLayout(\n G: Graph,\n pos: PositionMap | null = null,\n scaling: number = 1,\n a: number = 1.1,\n maxIter: number = 1000,\n seed: number | null = null,\n): PositionMap {\n if (a <= 1) {\n throw new Error(\"The parameter a should be larger than 1\");\n }\n\n const nodes = getNodesFromGraph(G);\n const edges = getEdgesFromGraph(G);\n\n if (nodes.length === 0) {\n return {};\n }\n\n // Initialize positions if not provided\n if (!pos) {\n pos = randomLayout(G, null, 2, seed);\n } else {\n // Make sure all nodes have positions\n const rng = new RandomNumberGenerator(seed ?? undefined);\n const defaultPos: PositionMap = {};\n nodes.forEach((node: Node) => {\n if (!(pos as PositionMap)[node]) {\n defaultPos[node] = [rng.rand() as number, rng.rand() as number];\n }\n });\n pos = { ...pos, ...defaultPos };\n }\n\n // Create node index mapping\n const nodeIndex: Record<Node, number> = {};\n nodes.forEach((node: Node, i: number) => {\n nodeIndex[node] = i;\n });\n\n // Create positions array\n const positions: number[][] = nodes.map((node: Node) => [...pos[node]]);\n\n // Initialize spring constant matrix\n const N = nodes.length;\n const K = Array(N)\n .fill(0)\n .map(() => Array(N).fill(1));\n\n // Set diagonal to zero (no self-attraction)\n for (let i = 0; i < N; i++) {\n K[i][i] = 0;\n }\n\n // Set stronger attraction between connected nodes\n for (const [source, target] of edges) {\n if (source === target) {continue;}\n\n const i = nodeIndex[source];\n const j = nodeIndex[target];\n K[i][j] = a;\n K[j][i] = a;\n }\n\n // Calculate rho (scale factor)\n const rho = scaling * Math.sqrt(N);\n\n // Optimization loop\n const dt = 1e-3; // Time step\n const etol = 1e-6; // Error tolerance\n let error = etol + 1;\n let nIter = 0;\n\n while (error > etol && nIter < maxIter) {\n // Calculate changes for each node\n const change = Array(N)\n .fill(0)\n .map(() => [0, 0]);\n\n for (let i = 0; i < N; i++) {\n for (let j = 0; j < N; j++) {\n if (i === j) {continue;}\n\n // Calculate difference vector\n const diff = positions[i].map((coord, dim) => coord - positions[j][dim]);\n\n // Calculate distance (with minimum to avoid division by zero)\n const dist = Math.sqrt(diff.reduce((sum, d) => sum + d * d, 0)) || 0.01;\n\n // Calculate attractive and repulsive forces\n for (let d = 0; d < diff.length; d++) {\n change[i][d] += K[i][j] * diff[d] - (rho / dist) * diff[d];\n }\n }\n }\n\n // Update positions\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < positions[i].length; d++) {\n positions[i][d] += change[i][d] * dt;\n }\n }\n\n // Calculate error (sum of force magnitudes)\n error = change.reduce((sum, c) => sum + Math.sqrt(c.reduce((s, v) => s + v * v, 0)), 0);\n\n nIter++;\n }\n\n // Convert positions array back to object\n const finalPos: PositionMap = {};\n nodes.forEach((node: Node, i: number) => {\n finalPos[node] = positions[i];\n });\n\n return finalPos;\n}\n","import type { Edge, Graph, Node, PositionMap } from \"../../types\";\nimport { getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { RandomNumberGenerator } from \"../../utils/random\";\nimport { rescaleLayout } from \"../../utils/rescale\";\n\n/**\n * Position nodes using the ForceAtlas2 force-directed algorithm.\n * @param G - Graph\n * @param pos - Initial positions for nodes\n * @param maxIter - Maximum number of iterations\n * @param jitterTolerance - Controls tolerance for node speed adjustments\n * @param scalingRatio - Scaling of attraction and repulsion forces\n * @param gravity - Attraction to center to prevent disconnected components from drifting\n * @param distributedAction - Distributes attraction force among nodes\n * @param strongGravity - Uses a stronger gravity model\n * @param nodeMass - Dictionary mapping nodes to their masses\n * @param nodeSize - Dictionary mapping nodes to their sizes\n * @param weight - Edge attribute for weight\n * @param _dissuadeHubs - Whether to prevent hub nodes from clustering (unused)\n * @param linlog - Whether to use logarithmic attraction\n * @param seed - Random seed for initial positions\n * @param dim - Dimension of layout\n * @returns Positions dictionary keyed by node\n */\nexport function forceatlas2Layout(\n G: Graph,\n pos: PositionMap | null = null,\n maxIter: number = 100,\n jitterTolerance: number = 1.0,\n scalingRatio: number = 2.0,\n gravity: number = 1.0,\n distributedAction: boolean = false,\n strongGravity: boolean = false,\n nodeMass: Record<Node, number> | null = null,\n nodeSize: Record<Node, number> | null = null,\n weight: string | null = null,\n _dissuadeHubs: boolean = false,\n linlog: boolean = false,\n seed: number | null = null,\n dim: number = 2,\n): PositionMap {\n const processed = _processParams(G, null, dim);\n const graph = processed.G;\n\n const nodes = getNodesFromGraph(graph);\n\n if (nodes.length === 0) {\n return {};\n }\n\n // Initialize random number generator\n const rng = new RandomNumberGenerator(seed ?? undefined);\n\n // Initialize positions if not provided\n let posArray: number[][];\n if (pos === null) {\n pos = {};\n posArray = new Array(nodes.length);\n for (let i = 0; i < nodes.length; i++) {\n posArray[i] = Array(dim)\n .fill(0)\n .map(() => (rng.rand() as number) * 2 - 1);\n pos[nodes[i]] = posArray[i];\n }\n } else if (Object.keys(pos).length === nodes.length) {\n // Use provided positions\n posArray = new Array(nodes.length);\n for (let i = 0; i < nodes.length; i++) {\n const nodePos = pos[nodes[i]];\n posArray[i] = new Array(dim);\n for (let d = 0; d < dim; d++) {\n posArray[i][d] = d < nodePos.length ? nodePos[d] : (rng.rand() as number) * 2 - 1;\n }\n }\n } else {\n // Some nodes don't have positions, initialize within the range of existing positions\n const minPos: number[] = Array(dim).fill(Number.POSITIVE_INFINITY);\n const maxPos: number[] = Array(dim).fill(Number.NEGATIVE_INFINITY);\n\n // Find min and max of existing positions\n for (const node in pos) {\n const nodePos = pos[node];\n for (let d = 0; d < dim; d++) {\n if (d < nodePos.length) {\n minPos[d] = Math.min(minPos[d], nodePos[d]);\n maxPos[d] = Math.max(maxPos[d], nodePos[d]);\n }\n }\n }\n\n // If min/max are still infinity for some dimensions, use default range\n for (let d = 0; d < dim; d++) {\n if (!isFinite(minPos[d]) || !isFinite(maxPos[d])) {\n minPos[d] = -1;\n maxPos[d] = 1;\n }\n }\n\n posArray = new Array(nodes.length);\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (pos[node]) {\n const nodePos = pos[node];\n posArray[i] = new Array(dim);\n for (let d = 0; d < dim; d++) {\n posArray[i][d] = d < nodePos.length ? nodePos[d] : (rng.rand() as number) * 2 - 1;\n }\n } else {\n posArray[i] = Array(dim)\n .fill(0)\n .map((_, d) => minPos[d] + (rng.rand() as number) * (maxPos[d] - minPos[d]));\n pos[node] = posArray[i];\n }\n }\n }\n\n // Initialize mass and size arrays\n const mass = new Array(nodes.length).fill(0);\n const size = new Array(nodes.length).fill(0);\n\n // Flag to track whether to adjust for node sizes\n const adjustSizes = nodeSize !== null;\n\n // Set node masses and sizes\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (nodeMass && nodeMass[node]) {\n mass[i] = nodeMass[node];\n } else if (Array.isArray(graph)) {\n mass[i] = 1;\n } else {\n mass[i] = getNodeDegree(graph, node) + 1;\n }\n\n size[i] = nodeSize && nodeSize[node] ? nodeSize[node] : 1;\n }\n\n // Create adjacency matrix\n const n = nodes.length;\n const A: number[][] = Array(n)\n .fill(0)\n .map(() => Array(n).fill(0) as number[]);\n\n // Populate adjacency matrix with edge weights\n const edges = Array.isArray(graph) ? ([] as Edge[]) : graph.edges();\n const nodeIndices: Record<Node, number> = {};\n nodes.forEach((node, i) => {\n nodeIndices[node] = i;\n });\n\n for (const [source, target] of edges) {\n const i = nodeIndices[source];\n const j = nodeIndices[target];\n\n // Use edge weight if provided, otherwise default to 1\n let edgeWeight = 1;\n if (weight && !Array.isArray(graph) && graph.getEdgeData) {\n edgeWeight = graph.getEdgeData(source, target, weight) || 1;\n }\n\n A[i][j] = edgeWeight;\n A[j][i] = edgeWeight; // For undirected graphs\n }\n\n // Initialize force arrays\n const gravities: number[][] = Array(n)\n .fill(0)\n .map(() => Array(dim).fill(0) as number[]);\n const attraction: number[][] = Array(n)\n .fill(0)\n .map(() => Array(dim).fill(0) as number[]);\n const repulsion: number[][] = Array(n)\n .fill(0)\n .map(() => Array(dim).fill(0) as number[]);\n\n // Simulation parameters\n let speed = 1;\n let speedEfficiency = 1;\n const _swing = 1; // Reserved for adaptive speed control\n const _traction = 1; // Reserved for adaptive speed control\n\n // Helper function to estimate factor for force scaling\n function estimateFactor(\n nodeCount: number,\n swingValue: number,\n tractionValue: number,\n currentSpeed: number,\n currentSpeedEfficiency: number,\n jitterToleranceParam: number,\n ): [number, number] {\n let resultSpeed = currentSpeed;\n let resultSpeedEfficiency = currentSpeedEfficiency;\n\n // Optimal jitter parameters\n const optJitter = 0.05 * Math.sqrt(nodeCount);\n const minJitter = Math.sqrt(optJitter);\n const maxJitter = 10;\n const minSpeedEfficiency = 0.05;\n\n // Estimate jitter based on current state\n const other = Math.min(maxJitter, (optJitter * tractionValue) / (nodeCount * nodeCount));\n let jitter = jitterToleranceParam * Math.max(minJitter, other);\n\n // Adjust speed efficiency based on swing/traction ratio\n if (swingValue / tractionValue > 2.0) {\n if (resultSpeedEfficiency > minSpeedEfficiency) {\n resultSpeedEfficiency *= 0.5;\n }\n jitter = Math.max(jitter, jitterToleranceParam);\n }\n\n // Calculate target speed\n const targetSpeed = swingValue === 0 ? Number.POSITIVE_INFINITY : (jitter * resultSpeedEfficiency * tractionValue) / swingValue;\n\n // Further adjust speed efficiency\n if (swingValue > jitter * tractionValue) {\n if (resultSpeedEfficiency > minSpeedEfficiency) {\n resultSpeedEfficiency *= 0.7;\n }\n } else if (resultSpeed < 1000) {\n resultSpeedEfficiency *= 1.3;\n }\n\n // Limit the speed increase\n const maxRise = 0.5;\n resultSpeed = resultSpeed + Math.min(targetSpeed - resultSpeed, maxRise * resultSpeed);\n\n return [resultSpeed, resultSpeedEfficiency];\n }\n\n // Main simulation loop\n for (let iter = 0; iter < maxIter; iter++) {\n // Reset forces for this iteration\n for (let i = 0; i < n; i++) {\n for (let d = 0; d < dim; d++) {\n attraction[i][d] = 0;\n repulsion[i][d] = 0;\n gravities[i][d] = 0;\n }\n }\n\n // Compute pairwise differences and distances\n const diff: number[][][] = Array(n)\n .fill(0)\n .map(() =>\n Array(n)\n .fill(0)\n .map(() => Array(dim).fill(0) as number[]),\n );\n\n const distance: number[][] = Array(n)\n .fill(0)\n .map(() => Array(n).fill(0) as number[]);\n\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (i === j) {continue;}\n\n for (let d = 0; d < dim; d++) {\n diff[i][j][d] = posArray[i][d] - posArray[j][d];\n }\n\n distance[i][j] = Math.sqrt(diff[i][j].reduce((sum: number, d: number) => sum + d * d, 0));\n // Prevent division by zero\n if (distance[i][j] < 0.01) {distance[i][j] = 0.01;}\n }\n }\n\n // Calculate attraction forces\n if (linlog) {\n // Logarithmic attraction model\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (i === j || A[i][j] === 0) {continue;}\n\n const dist = distance[i][j];\n const factor = (-Math.log(1 + dist) / dist) * A[i][j];\n\n for (let d = 0; d < dim; d++) {\n const force = factor * diff[i][j][d];\n attraction[i][d] += force;\n }\n }\n }\n } else {\n // Linear attraction model\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (i === j || A[i][j] === 0) {continue;}\n\n for (let d = 0; d < dim; d++) {\n const force = -diff[i][j][d] * A[i][j];\n attraction[i][d] += force;\n }\n }\n }\n }\n\n // Apply distributed attraction if enabled\n if (distributedAction) {\n for (let i = 0; i < n; i++) {\n for (let d = 0; d < dim; d++) {\n attraction[i][d] /= mass[i];\n }\n }\n }\n\n // Calculate repulsion forces\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (i === j) {continue;}\n\n let dist = distance[i][j];\n\n // Adjust distance for node sizes if needed\n if (adjustSizes) {\n dist -= size[i] - size[j];\n dist = Math.max(dist, 0.01); // Prevent negative or zero distances\n }\n\n const distSquared = dist * dist;\n const massProduct = mass[i] * mass[j];\n const factor = (massProduct / distSquared) * scalingRatio;\n\n for (let d = 0; d < dim; d++) {\n const direction = diff[i][j][d] / dist;\n repulsion[i][d] += direction * factor;\n }\n }\n }\n\n // Calculate gravity forces\n // First find the center of mass\n const centerOfMass: number[] = Array(dim).fill(0);\n for (let i = 0; i < n; i++) {\n for (let d = 0; d < dim; d++) {\n centerOfMass[d] += posArray[i][d] / n;\n }\n }\n\n for (let i = 0; i < n; i++) {\n const posCentered = Array(dim);\n for (let d = 0; d < dim; d++) {\n posCentered[d] = posArray[i][d] - centerOfMass[d];\n }\n\n if (strongGravity) {\n // Strong gravity model\n for (let d = 0; d < dim; d++) {\n gravities[i][d] = -gravity * mass[i] * posCentered[d];\n }\n } else {\n // Regular gravity model\n const dist = Math.sqrt(posCentered.reduce((sum: number, val: number) => sum + val * val, 0));\n\n if (dist > 0.01) {\n for (let d = 0; d < dim; d++) {\n const direction = posCentered[d] / dist;\n gravities[i][d] = -gravity * mass[i] * direction;\n }\n }\n }\n }\n\n // Calculate total forces and update positions\n const update = Array(n)\n .fill(0)\n .map(() => Array(dim).fill(0));\n let totalSwing = 0;\n let totalTraction = 0;\n\n for (let i = 0; i < n; i++) {\n for (let d = 0; d < dim; d++) {\n update[i][d] = attraction[i][d] + repulsion[i][d] + gravities[i][d];\n }\n\n // Calculate swing and traction for this node\n const oldPos = [...posArray[i]];\n const newPos = oldPos.map((p, d) => p + (update[i][d] as number));\n\n const swingVector = oldPos.map((p, d) => p - newPos[d]);\n const tractionVector = oldPos.map((p, d) => p + newPos[d]);\n\n const swingMagnitude = Math.sqrt(swingVector.reduce((sum: number, val: number) => sum + val * val, 0));\n const tractionMagnitude = Math.sqrt(tractionVector.reduce((sum: number, val: number) => sum + val * val, 0));\n\n totalSwing += mass[i] * swingMagnitude;\n totalTraction += 0.5 * mass[i] * tractionMagnitude;\n }\n\n // Update speed and efficiency\n [speed, speedEfficiency] = estimateFactor(\n n,\n totalSwing,\n totalTraction,\n speed,\n speedEfficiency,\n jitterTolerance,\n );\n\n // Apply forces to update positions\n let totalMovement = 0;\n\n for (let i = 0; i < n; i++) {\n let factor;\n\n if (adjustSizes) {\n // Calculate displacement magnitude\n const df = Math.sqrt(update[i].reduce((sum: number, val: number) => sum + val * val, 0));\n const swinging = mass[i] * df;\n\n // Determine scaling factor with size adjustments\n factor = (0.1 * speed) / (1 + Math.sqrt(speed * swinging));\n factor = Math.min(factor * df, 10) / df;\n } else {\n // Standard scaling factor\n const swinging = (mass[i] as number) * Math.sqrt(update[i].reduce((sum: number, val: number) => sum + val * val, 0));\n factor = speed / (1 + Math.sqrt(speed * swinging));\n }\n\n // Apply factor to update position\n for (let d = 0; d < dim; d++) {\n const movement = update[i][d] * factor;\n posArray[i][d] += movement;\n totalMovement += Math.abs(movement);\n }\n }\n\n // Check for convergence\n if (totalMovement < 1e-10) {\n break;\n }\n }\n\n // Create position dictionary\n const positions: PositionMap = {};\n for (let i = 0; i < n; i++) {\n positions[nodes[i]] = posArray[i];\n }\n\n return rescaleLayout(positions) as PositionMap;\n}\n\n// Helper function to get node degree\nfunction getNodeDegree(graph: Graph, node: Node): number {\n return graph.edges().filter((edge: Edge) => edge[0] === node || edge[1] === node).length;\n}\n","/**\n * Fruchterman-Reingold force-directed layout algorithm\n */\n\nimport type { Graph, Node, PositionMap } from \"../../types\";\nimport { getEdgesFromGraph,getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { RandomNumberGenerator } from \"../../utils/random\";\nimport { rescaleLayout } from \"../../utils/rescale\";\n\n/**\n * Position nodes using Fruchterman-Reingold force-directed algorithm.\n * @param G - Graph or list of nodes\n * @param k - Optimal distance between nodes\n * @param pos - Initial positions for nodes\n * @param fixed - Nodes to keep fixed at initial position\n * @param iterations - Maximum number of iterations\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @param seed - Random seed for initial positions\n * @returns Positions dictionary keyed by node\n */\nexport function fruchtermanReingoldLayout(\n G: Graph,\n k: number | null = null,\n pos: PositionMap | null = null,\n fixed: Node[] | null = null,\n iterations: number = 50,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n seed: number | null = null,\n): PositionMap {\n const processed = _processParams(G, center, dim);\n const graph = processed.G;\n ({ center } = processed);\n\n const nodes = getNodesFromGraph(graph);\n const edges = getEdgesFromGraph(graph);\n\n if (nodes.length === 0) {\n return {};\n }\n\n if (nodes.length === 1) {\n const singlePos: PositionMap = {};\n singlePos[nodes[0]] = center;\n return singlePos;\n }\n\n // Set up initial positions\n let positions: PositionMap = {};\n if (pos) {\n // Use provided positions\n for (const node of nodes) {\n if (pos[node]) {\n positions[node] = [...pos[node]];\n } else {\n const rng = new RandomNumberGenerator(seed ?? undefined);\n positions[node] = rng.rand(dim) as number[];\n }\n }\n } else {\n // Random initial positions\n const rng = new RandomNumberGenerator(seed ?? undefined);\n for (const node of nodes) {\n positions[node] = rng.rand(dim) as number[];\n }\n }\n\n // Set up fixed nodes\n const fixedNodes = new Set(fixed || []);\n\n // Optimal distance between nodes\n if (!k) {\n k = 1.0 / Math.sqrt(nodes.length);\n }\n\n // Initialize temperature\n let t = 0.1;\n // Calculate temperature reduction\n const dt = t / (iterations + 1);\n\n // Simple cooling schedule\n for (let i = 0; i < iterations; i++) {\n // Calculate repulsive forces\n const displacement: Record<Node, number[]> = {};\n for (const node of nodes) {\n displacement[node] = Array(dim).fill(0);\n }\n\n // Repulsive forces between nodes\n for (let v1i = 0; v1i < nodes.length; v1i++) {\n const v1 = nodes[v1i];\n for (let v2i = v1i + 1; v2i < nodes.length; v2i++) {\n const v2 = nodes[v2i];\n\n // Difference vector\n const delta = positions[v1].map((p, i) => p - positions[v2][i]);\n\n // Distance\n const distance = Math.sqrt(delta.reduce((sum, d) => sum + d * d, 0)) || 0.1;\n\n // Force\n const force = (k * k) / distance;\n\n // Add force to displacement\n for (let j = 0; j < dim; j++) {\n const direction = delta[j] / distance;\n displacement[v1][j] += direction * force;\n displacement[v2][j] -= direction * force;\n }\n }\n }\n\n // Attractive forces between connected nodes\n for (const [source, target] of edges) {\n // Difference vector\n const delta = positions[source].map((p, i) => p - positions[target][i]);\n\n // Distance\n const distance = Math.sqrt(delta.reduce((sum, d) => sum + d * d, 0)) || 0.1;\n\n // Force\n const force = (distance * distance) / k;\n\n // Add force to displacement\n for (let j = 0; j < dim; j++) {\n const direction = delta[j] / distance;\n displacement[source][j] -= direction * force;\n displacement[target][j] += direction * force;\n }\n }\n\n // Update positions\n for (const node of nodes) {\n if (fixedNodes.has(node)) {continue;}\n\n // Calculate displacement magnitude\n const magnitude = Math.sqrt(displacement[node].reduce((sum, d) => sum + d * d, 0));\n\n // Limit maximum displacement by temperature\n const limitedMagnitude = Math.min(magnitude, t);\n\n // Update position\n for (let j = 0; j < dim; j++) {\n const direction = magnitude === 0 ? 0 : displacement[node][j] / magnitude;\n positions[node][j] += direction * limitedMagnitude;\n }\n }\n\n // Cool temperature\n t -= dt;\n }\n\n // Rescale positions\n if (!fixed) {\n positions = rescaleLayout(positions, scale, center) as PositionMap;\n }\n\n return positions;\n}\n","/**\n * L-BFGS optimization utilities\n */\n\n/**\n * Compute the search direction using L-BFGS approximation\n * @param grad - Current gradient\n * @param sList - List of position differences (s_k)\n * @param yList - List of gradient differences (y_k)\n * @param _m - Memory size (unused, kept for API compatibility)\n * @returns Direction vector\n */\nexport function _lbfgsDirection(grad: number[], sList: number[][], yList: number[][], _m: number): number[] {\n if (sList.length === 0) {\n // First iteration - use negative gradient\n return grad.map((g) => -g);\n }\n\n const q = grad.slice();\n const alpha = Array(sList.length).fill(0);\n const rho: number[] = [];\n\n // Compute rho values\n for (let i = 0; i < sList.length; i++) {\n const s = sList[i];\n const y = yList[i];\n rho.push(1 / y.reduce((sum, val, j) => sum + val * s[j], 0));\n }\n\n // Forward pass\n for (let i = sList.length - 1; i >= 0; i--) {\n const s = sList[i];\n alpha[i] = rho[i] * s.reduce((sum, val, j) => sum + val * q[j], 0);\n for (let j = 0; j < q.length; j++) {\n q[j] -= alpha[i] * yList[i][j];\n }\n }\n\n // Scale initial Hessian approximation\n let gamma = 1;\n if (sList.length > 0 && yList.length > 0) {\n const y = yList[yList.length - 1];\n const s = sList[sList.length - 1];\n gamma = s.reduce((sum, val, i) => sum + val * y[i], 0) / y.reduce((sum, val) => sum + val * val, 0);\n }\n\n // Initialize direction with scaled negative gradient\n const direction = q.map((val) => -gamma * val);\n\n // Backward pass\n for (let i = 0; i < sList.length; i++) {\n const s = sList[i];\n const y = yList[i];\n const beta = rho[i] * y.reduce((sum, val, j) => sum + val * direction[j], 0);\n for (let j = 0; j < direction.length; j++) {\n direction[j] += s[j] * (alpha[i] - beta);\n }\n }\n\n return direction;\n}\n","/**\n * Line search optimization utilities\n */\n\n/**\n * Backtracking line search to find step size\n * @param x - Current position\n * @param direction - Search direction\n * @param f - Function value at current position\n * @param grad - Gradient at current position\n * @param func - Function to evaluate cost\n * @param alpha0 - Initial step size\n * @returns Optimal step size\n */\nexport function _backtrackingLineSearch(\n x: number[],\n direction: number[],\n f: number,\n grad: number[],\n func: (x: number[]) => number,\n alpha0: number,\n): number {\n const c1 = 1e-4;\n const c2 = 0.9;\n const initialSlope = grad.reduce((sum, g, i) => sum + g * direction[i], 0);\n\n if (initialSlope >= 0) {\n return 1e-8; // Direction is not a descent direction\n }\n\n let alpha = alpha0;\n const maxIter = 20;\n\n for (let i = 0; i < maxIter; i++) {\n // Try step\n const newX = x.map((val, i) => val + alpha * direction[i]);\n const newF = func(newX);\n\n // Check sufficient decrease condition (Armijo condition)\n if (newF <= f + c1 * alpha * initialSlope) {\n return alpha;\n }\n\n // Reduce step size\n alpha *= c2;\n }\n\n return alpha; // Return last alpha even if not optimal\n}\n","/**\n * Kamada-Kawai layout algorithm optimization functions\n */\n\nimport type { Graph } from \"../../types\";\nimport { getEdgesFromGraph,getNodesFromGraph } from \"../../utils/graph\";\nimport { _lbfgsDirection } from \"./lbfgs\";\nimport { _backtrackingLineSearch } from \"./line-search\";\nimport { DistanceMap } from \"./types\";\n\n/**\n * Compute all-pairs shortest path distances for the graph\n * @param G - NetworkX graph\n * @param weight - Edge attribute for weight\n * @returns Dictionary of dictionaries of shortest path distances\n */\nexport function _computeShortestPathDistances(G: Graph, weight: string): DistanceMap {\n const distances: DistanceMap = {};\n const nodes = getNodesFromGraph(G);\n const edges = getEdgesFromGraph(G);\n\n // Initialize distances with direct edges\n for (const node of nodes) {\n distances[node] = {};\n distances[node][node] = 0;\n\n for (const other of nodes) {\n if (node !== other) {\n distances[node][other] = Infinity;\n }\n }\n }\n\n // Add direct edges\n for (const [source, target] of edges) {\n // In a real implementation, we would get the weight from the graph\n // For now, assume weight = 1 or use weight attribute if available\n let edgeWeight = 1;\n if (G.getEdgeData) {\n edgeWeight = G.getEdgeData(source, target, weight) || 1;\n }\n\n distances[source][target] = edgeWeight;\n distances[target][source] = edgeWeight; // Assuming undirected graph\n }\n\n // Floyd-Warshall algorithm for all-pairs shortest paths\n for (const k of nodes) {\n for (const i of nodes) {\n for (const j of nodes) {\n if (distances[i][k] + distances[k][j] < distances[i][j]) {\n distances[i][j] = distances[i][k] + distances[k][j];\n }\n }\n }\n }\n\n return distances;\n}\n\n/**\n * Solve the Kamada-Kawai layout optimization problem\n * @param distMatrix - Matrix of desired distances between nodes\n * @param positions - Initial node positions\n * @param dim - Dimension of layout\n * @returns Optimized node positions\n */\nexport function _kamadaKawaiSolve(distMatrix: number[][], positions: number[][], dim: number): number[][] {\n // Implementation of L-BFGS optimization for Kamada-Kawai\n const nNodes = positions.length;\n const meanWeight = 1e-3;\n\n // Convert distances to inverse distances (with protection against division by zero)\n const invDistMatrix = distMatrix.map((row) => row.map((d) => (d === 0 ? 0 : 1 / (d + 1e-3))));\n\n // Flatten positions for optimization\n const posVec = positions.flat();\n\n // Optimization parameters\n const maxIter = 500;\n const gtol = 1e-5;\n const m = 10; // L-BFGS memory size\n\n // Implement a simplified L-BFGS-B algorithm\n let alpha = 1.0;\n const oldValues: number[][] = [];\n const oldGrads: number[][] = [];\n\n for (let iter = 0; iter < maxIter; iter++) {\n // Calculate cost and gradient\n const [cost, grad] = _kamadaKawaiCostfn(posVec, invDistMatrix, meanWeight, dim);\n\n // Compute search direction using L-BFGS approximation\n const direction = _lbfgsDirection(grad, oldValues, oldGrads, m);\n\n // Simple line search for step size\n alpha = _backtrackingLineSearch(\n posVec,\n direction,\n cost,\n grad,\n (x: number[]) => _kamadaKawaiCostfn(x, invDistMatrix, meanWeight, dim)[0],\n alpha,\n );\n\n // Save current position and gradient for next iteration\n const oldPos = [...posVec];\n\n // Update position\n for (let i = 0; i < posVec.length; i++) {\n posVec[i] += alpha * direction[i];\n }\n\n // Calculate new gradient\n const [, newGrad] = _kamadaKawaiCostfn(posVec, invDistMatrix, meanWeight, dim);\n\n // Update L-BFGS memory\n oldValues.push(posVec.map((val, i) => val - oldPos[i]));\n oldGrads.push(newGrad.map((val, i) => val - grad[i]));\n\n // Keep only m most recent updates\n if (oldValues.length > m) {\n oldValues.shift();\n oldGrads.shift();\n }\n\n // Check convergence\n const gradNorm = Math.sqrt(newGrad.reduce((sum, g) => sum + g * g, 0));\n if (gradNorm < gtol) {\n break;\n }\n }\n\n // Reshape result back into positions array\n const result: number[][] = [];\n for (let i = 0; i < nNodes; i++) {\n result.push(posVec.slice(i * dim, (i + 1) * dim));\n }\n\n return result;\n}\n\n/**\n * Cost function and gradient for Kamada-Kawai layout algorithm\n * @param posVec - Flattened position array\n * @param invDist - Inverse distance matrix\n * @param meanWeight - Weight for centering positions\n * @param dim - Dimension of layout\n * @returns Array with [cost, gradient]\n */\nexport function _kamadaKawaiCostfn(\n posVec: number[],\n invDist: number[][],\n meanWeight: number,\n dim: number,\n): [number, number[]] {\n const nNodes = invDist.length;\n const positions: number[][] = [];\n\n // Reshape flat vector into positions array\n for (let i = 0; i < nNodes; i++) {\n positions.push(posVec.slice(i * dim, (i + 1) * dim));\n }\n\n // Calculate cost\n let cost = 0;\n\n // Add mean position penalty term\n const sumPos: number[] = Array(dim).fill(0);\n for (let i = 0; i < nNodes; i++) {\n for (let d = 0; d < dim; d++) {\n sumPos[d] += positions[i][d];\n }\n }\n cost += 0.5 * meanWeight * sumPos.reduce((sum: number, val: number) => sum + val * val, 0);\n\n // Add distance penalty terms\n for (let i = 0; i < nNodes; i++) {\n for (let j = i + 1; j < nNodes; j++) {\n // Calculate actual distance\n const diff = positions[i].map((val, d) => val - positions[j][d]);\n const distance = Math.sqrt(diff.reduce((sum, d) => sum + d * d, 0));\n\n // Add penalty for difference between actual and ideal distance\n const idealInvDist = invDist[i][j];\n const offset = distance * idealInvDist - 1.0;\n cost += 0.5 * offset * offset;\n }\n }\n\n // Calculate gradient\n const grad = new Array(posVec.length).fill(0);\n\n // Add gradient of mean position penalty\n for (let i = 0; i < nNodes; i++) {\n for (let d = 0; d < dim; d++) {\n (grad[i * dim + d] as number) += meanWeight * sumPos[d];\n }\n }\n\n // Add gradient of distance penalties\n for (let i = 0; i < nNodes; i++) {\n for (let j = i + 1; j < nNodes; j++) {\n // Calculate actual distance and direction\n const diff = positions[i].map((val, d) => val - positions[j][d]);\n const distance = Math.sqrt(diff.reduce((sum, d) => sum + d * d, 0)) || 1e-10;\n const direction = diff.map((d) => d / distance);\n\n // Calculate contribution to gradient\n const idealInvDist = invDist[i][j];\n const offset = distance * idealInvDist - 1.0;\n\n for (let d = 0; d < dim; d++) {\n const force = idealInvDist * offset * direction[d];\n (grad[i * dim + d] as number) += force;\n (grad[j * dim + d] as number) -= force;\n }\n }\n }\n\n return [cost, grad];\n}\n","/**\n * NumPy-like array manipulation functions\n * Maintains exact same functionality as original implementation\n */\n\nexport const np = {\n zeros: function (shape: number | number[]): number[] | number[][] {\n if (typeof shape === \"number\") {\n return Array(shape).fill(0) as number[];\n }\n if (shape.length === 1) {\n return Array(shape[0]).fill(0) as number[];\n }\n return Array(shape[0])\n .fill(0)\n .map(() => this.zeros(shape.slice(1))) as number[][];\n },\n\n ones: function (shape: number | number[]): number[] | number[][] {\n if (typeof shape === \"number\") {\n return Array(shape).fill(1) as number[];\n }\n if (shape.length === 1) {\n return Array(shape[0]).fill(1) as number[];\n }\n return Array(shape[0])\n .fill(1)\n .map(() => this.ones(shape.slice(1))) as number[][];\n },\n\n linspace: function (start: number, stop: number, num: number): number[] {\n if (num === 1) {\n return [start];\n }\n const step = (stop - start) / (num - 1);\n return Array.from({ length: num }, (_, i) => start + i * step);\n },\n\n array: function (arr: number | number[]): number[] {\n return Array.isArray(arr) ? [...arr] : [arr];\n },\n\n repeat: function (a: number | number[], repeats: number): number[] {\n const result: number[] = [];\n for (let i = 0; i < repeats; i++) {\n result.push(...np.array(a));\n }\n return result;\n },\n\n mean: function (arr: number[] | number[][], axis: number | null = null): number | number[] {\n if (axis === null) {\n const flatArr = Array.isArray(arr[0])\n ? ((arr as number[][]).flat(Infinity) as number[])\n : (arr as number[]);\n const sum = flatArr.reduce((a, b) => a + b, 0);\n return sum / flatArr.length;\n }\n\n if (axis === 0) {\n const result: number[] = [];\n const matrix = arr as number[][];\n for (let i = 0; i < matrix[0].length; i++) {\n let sum = 0;\n for (let j = 0; j < matrix.length; j++) {\n sum += matrix[j][i];\n }\n result.push(sum / matrix.length);\n }\n return result;\n }\n\n return (arr as number[][]).map((row) => np.mean(row) as number);\n },\n\n add: function (a: number | number[], b: number | number[]): number | number[] {\n if (!Array.isArray(a) && !Array.isArray(b)) {\n return a + b;\n }\n if (!Array.isArray(a)) {\n return (b as number[]).map((val) => a + val);\n }\n if (!Array.isArray(b)) {\n return (a).map((val) => val + b);\n }\n return (a).map((val, i) => val + (b)[i]);\n },\n\n subtract: function (a: number | number[], b: number | number[]): number | number[] {\n if (!Array.isArray(a) && !Array.isArray(b)) {\n return a - b;\n }\n if (!Array.isArray(a)) {\n return (b as number[]).map((val) => a - val);\n }\n if (!Array.isArray(b)) {\n return (a).map((val) => val - b);\n }\n return (a).map((val, i) => val - (b)[i]);\n },\n\n max: function (arr: number | number[]): number {\n if (!Array.isArray(arr)) {return arr;}\n return Math.max(...((arr).flat(Infinity)));\n },\n\n min: function (arr: number | number[]): number {\n if (!Array.isArray(arr)) {return arr;}\n return Math.min(...((arr).flat(Infinity)));\n },\n\n norm: function (arr: number[]): number {\n return Math.sqrt(arr.reduce((sum, val) => sum + val * val, 0));\n },\n};\n","/**\n * Circular layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from \"../../types\";\nimport { getNodesFromGraph } from \"../../utils/graph\";\nimport { np } from \"../../utils/numpy\";\nimport { _processParams } from \"../../utils/params\";\nimport { RandomNumberGenerator } from \"../../utils/random\";\n\n/**\n * Position nodes on a circle (2D) or sphere (3D).\n * @param G - Graph or list of nodes\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout (supports 2D circle or 3D sphere)\n * @returns Positions dictionary keyed by node\n */\nexport function circularLayout(\n G: Graph,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n): PositionMap {\n if (dim < 2) {\n throw new Error(\"cannot handle dimensions < 2\");\n }\n\n const processed = _processParams(G, center, dim);\n const nodes = getNodesFromGraph(processed.G);\n ({ center } = processed);\n\n const pos: PositionMap = {};\n\n if (nodes.length === 0) {\n return pos;\n }\n\n if (nodes.length === 1) {\n pos[nodes[0]] = center;\n return pos;\n }\n\n if (dim === 2) {\n // 2D circle layout\n const theta = np.linspace(0, 2 * Math.PI, nodes.length + 1).slice(0, -1);\n\n nodes.forEach((node: Node, i: number) => {\n const x: number = Math.cos(theta[i]) * scale + center[0];\n const y: number = Math.sin(theta[i]) * scale + center[1];\n pos[node] = [x, y];\n });\n } else if (dim === 3) {\n // 3D sphere layout using Fibonacci spiral\n const n = nodes.length;\n const goldenRatio = (1 + Math.sqrt(5)) / 2;\n\n nodes.forEach((node: Node, i: number) => {\n // Use Fibonacci spiral for even distribution on sphere\n const theta = (2 * Math.PI * i) / goldenRatio;\n const phi = Math.acos(1 - (2 * (i + 0.5)) / n);\n\n const x = Math.sin(phi) * Math.cos(theta) * scale + center[0];\n const y = Math.sin(phi) * Math.sin(theta) * scale + center[1];\n const z = Math.cos(phi) * scale + center[2];\n\n pos[node] = [x, y, z];\n });\n } else {\n // For higher dimensions, fall back to random on hypersphere\n const rng = new RandomNumberGenerator();\n nodes.forEach((node: Node) => {\n // Generate random point on unit hypersphere\n const coords = Array(dim)\n .fill(0)\n .map(() => (rng.rand() as number) * 2 - 1);\n const norm = Math.sqrt(coords.reduce((sum, c) => sum + c * c, 0));\n pos[node] = coords.map((c, j) => (c / norm) * scale + center[j]);\n });\n }\n\n return pos;\n}\n","import { _computeShortestPathDistances, _kamadaKawaiSolve, type DistanceMap } from \"../../algorithms/optimization\";\nimport type { Graph, Node, PositionMap } from \"../../types\";\nimport { getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { rescaleLayout } from \"../../utils/rescale\";\nimport { circularLayout } from \"../geometric/circular\";\n\n/**\n * Position nodes using Kamada-Kawai path-length cost-function.\n * @param G - NetworkX graph or list of nodes\n * @param dist - A two-level dictionary of optimal distances between nodes\n * @param pos - Initial positions for nodes\n * @param weight - The edge attribute used for edge weights\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @returns Positions dictionary keyed by node\n */\nexport function kamadaKawaiLayout(\n G: Graph,\n dist: DistanceMap | null = null,\n pos: PositionMap | null = null,\n weight: string = \"weight\",\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n): PositionMap {\n const processed = _processParams(G, center, dim);\n const graph = processed.G;\n ({ center } = processed);\n\n const nodes = getNodesFromGraph(graph);\n\n if (nodes.length === 0) {\n return {};\n }\n\n if (nodes.length === 1) {\n return { [nodes[0]]: center };\n }\n\n // Initialize distance matrix\n if (!dist) {\n // Kamada-Kawai requires a proper Graph, not just a list of nodes\n if (Array.isArray(graph)) {\n throw new Error(\"Kamada-Kawai layout requires a Graph with edges, not just a list of nodes\");\n }\n dist = _computeShortestPathDistances(graph, weight);\n }\n\n // Convert distances to a matrix\n const nodesArray: Node[] = Array.from(nodes);\n const nNodes = nodesArray.length;\n const distMatrix: number[][] = Array(nNodes)\n .fill(0)\n .map(() => Array(nNodes).fill(1e6));\n\n for (let i = 0; i < nNodes; i++) {\n const nodeI = nodesArray[i];\n distMatrix[i][i] = 0;\n\n if (!dist[nodeI]) {continue;}\n\n for (let j = 0; j < nNodes; j++) {\n const nodeJ = nodesArray[j];\n if (dist[nodeI][nodeJ] !== undefined) {\n distMatrix[i][j] = dist[nodeI][nodeJ];\n }\n }\n }\n\n // Initialize positions if not provided\n if (!pos) {\n if (dim >= 2) {\n // Use circular/spherical layout for 2D and 3D\n pos = circularLayout(G, 1, center, dim);\n } else {\n // For 1D, use a linear layout\n const posArray: PositionMap = {};\n nodesArray.forEach((node, i) => {\n posArray[node] = [i / (nNodes - 1 || 1)];\n });\n pos = posArray;\n }\n }\n\n // Convert positions to array for computation\n const posArray: number[][] = new Array(nNodes);\n for (let i = 0; i < nNodes; i++) {\n const node = nodesArray[i];\n posArray[i] = pos[node] ? [...pos[node]] : Array(dim).fill(0);\n\n // Ensure correct dimensionality\n while (posArray[i].length < dim) {\n posArray[i].push(0);\n }\n }\n\n // Run the Kamada-Kawai algorithm\n const newPositions = _kamadaKawaiSolve(distMatrix, posArray, dim);\n\n // Convert positions array back to dictionary and rescale\n const finalPos: PositionMap = {};\n for (let i = 0; i < nNodes; i++) {\n finalPos[nodesArray[i]] = newPositions[i];\n }\n\n return rescaleLayout(finalPos, scale, center) as PositionMap;\n}\n","/**\n * Spring layout algorithm (Fruchterman-Reingold variant)\n */\n\nimport { Graph, Node, PositionMap } from \"../../types\";\nimport { fruchtermanReingoldLayout } from \"./fruchterman-reingold\";\n\n/**\n * Position nodes using Fruchterman-Reingold force-directed algorithm.\n * @param G - Graph or list of nodes\n * @param k - Optimal distance between nodes\n * @param pos - Initial positions for nodes\n * @param fixed - Nodes to keep fixed at initial position\n * @param iterations - Maximum number of iterations\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @param seed - Random seed for initial positions\n * @returns Positions dictionary keyed by node\n */\nexport function springLayout(\n G: Graph,\n k: number | null = null,\n pos: PositionMap | null = null,\n fixed: Node[] | null = null,\n iterations: number = 50,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n seed: number | null = null,\n): PositionMap {\n // Legacy compatibility alias\n return fruchtermanReingoldLayout(G, k, pos, fixed, iterations, scale, center, dim, seed);\n}\n","/**\n * Shell layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from \"../../types\";\nimport { getNodesFromGraph } from \"../../utils/graph\";\nimport { np } from \"../../utils/numpy\";\nimport { _processParams } from \"../../utils/params\";\n\n/**\n * Position nodes in concentric circles.\n * @param G - Graph or list of nodes\n * @param nlist - List of node lists for each shell\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout (currently only supports dim=2)\n * @returns Positions dictionary keyed by node\n */\nexport function shellLayout(\n G: Graph,\n nlist: Node[][] | null = null,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n): PositionMap {\n if (dim !== 2) {\n throw new Error(\"can only handle 2 dimensions\");\n }\n\n const processed = _processParams(G, center, dim);\n const nodes = getNodesFromGraph(processed.G);\n ({ center } = processed);\n\n const pos: PositionMap = {};\n\n if (nodes.length === 0) {\n return pos;\n }\n\n if (nodes.length === 1) {\n pos[nodes[0]] = center;\n return pos;\n }\n\n // If no nlist is specified, put all nodes in a single shell\n if (!nlist) {\n nlist = [nodes];\n }\n\n const radiusBump = scale / nlist.length;\n let radius: number;\n\n if (nlist[0].length === 1) {\n // Single node at center\n radius = 0;\n pos[nlist[0][0]] = [...center];\n radius += radiusBump;\n } else {\n // Start at radius 1\n radius = radiusBump;\n }\n\n for (let i = 0; i < nlist.length; i++) {\n const shell = nlist[i];\n if (shell.length === 0) {continue;}\n\n if (shell.length === 1 && i === 0) {\n // Already handled the case of a single center node\n continue;\n }\n\n // Calculate positions on a circle\n const theta = np.linspace(0, 2 * Math.PI, shell.length + 1).slice(0, -1);\n\n shell.forEach((node: Node, j) => {\n const x = Math.cos(theta[j]) * radius + center[0];\n const y = Math.sin(theta[j]) * radius + center[1];\n pos[node] = [x, y];\n });\n\n radius += radiusBump;\n }\n\n return pos;\n}\n","/**\n * Spiral layout algorithm\n */\n\nimport type { Graph, PositionMap } from \"../../types\";\nimport { getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { rescaleLayout } from \"../../utils/rescale\";\n\n/**\n * Position nodes in a spiral layout.\n * @param G - Graph or list of nodes\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @param resolution - Controls the spacing between spiral elements\n * @param equidistant - Whether to place nodes equidistant from each other\n * @returns Positions dictionary keyed by node\n */\nexport function spiralLayout(\n G: Graph,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n resolution: number = 0.35,\n equidistant: boolean = false,\n): PositionMap {\n if (dim !== 2) {\n throw new Error(\"can only handle 2 dimensions\");\n }\n\n const processed = _processParams(G, center || [0, 0], dim);\n const nodes = getNodesFromGraph(processed.G);\n ({ center } = processed);\n\n const pos: PositionMap = {};\n\n if (nodes.length === 0) {\n return pos;\n }\n\n if (nodes.length === 1) {\n pos[nodes[0]] = [...center];\n return pos;\n }\n\n let positions: number[][] = [];\n\n if (equidistant) {\n // Create equidistant points along the spiral\n // This matches the Python implementation logic\n const chord = 1;\n const step = 0.5;\n let theta = resolution;\n theta += chord / (step * theta);\n\n for (let i = 0; i < nodes.length; i++) {\n const r = step * theta;\n theta += chord / r;\n positions.push([Math.cos(theta) * r, Math.sin(theta) * r]);\n }\n } else {\n // Create points with equal angle but increasing distance\n const dist = Array.from({ length: nodes.length }, (_, i) => parseFloat(String(i)));\n const angle = dist.map((d) => resolution * d);\n\n positions = dist.map((d, i) => [Math.cos(angle[i]) * d, Math.sin(angle[i]) * d]);\n }\n\n // Convert position array to position matrix for rescaling\n const posArray: number[][] = [];\n for (let i = 0; i < positions.length; i++) {\n posArray.push(positions[i]);\n }\n\n // Rescale positions and add center offset\n const scaledPositions = rescaleLayout(posArray, scale) as number[][];\n for (let i = 0; i < scaledPositions.length; i++) {\n scaledPositions[i][0] += center[0];\n scaledPositions[i][1] += center[1];\n }\n\n // Create position dictionary\n for (let i = 0; i < nodes.length; i++) {\n pos[nodes[i]] = scaledPositions[i];\n }\n\n return pos;\n}\n","import type { Graph, Node, PositionMap } from \"../../types\";\nimport { getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { rescaleLayout } from \"../../utils/rescale\";\n\n/**\n * Position nodes in layers of straight lines (multipartite layout).\n * @param G - Graph or list of nodes\n * @param subsetKey - Object mapping layers to node sets, or node attribute name\n * @param align - The alignment of nodes: 'vertical' or 'horizontal'\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @returns Positions dictionary keyed by node\n */\nexport function multipartiteLayout(\n G: Graph,\n subsetKey: Record<number | string, Node | Node[]> | string = \"subset\",\n align: \"vertical\" | \"horizontal\" = \"vertical\",\n scale: number = 1,\n center: number[] | null = null,\n): PositionMap {\n if (align !== \"vertical\" && align !== \"horizontal\") {\n throw new Error(\"align must be either vertical or horizontal\");\n }\n\n const processed = _processParams(G, center || [0, 0], 2);\n const graph = processed.G;\n ({ center } = processed);\n\n const allNodes = getNodesFromGraph(graph);\n\n if (allNodes.length === 0) {\n return {};\n }\n\n // Convert subsetKey to a layer mapping if it's a string\n let layers: Record<number | string, Node[]> = {};\n if (typeof subsetKey === \"string\") {\n // In JS we don't have access to node attributes directly\n // This is a simplification - in a real implementation we would need\n // to access node attributes from the graph\n console.warn(\"Using string subsetKey requires node attributes, using default partitioning\");\n // Create a simple partitioning as fallback\n layers = { 0: allNodes };\n } else {\n // subsetKey is already a mapping of layers to nodes\n // Convert single nodes to arrays\n for (const [key, value] of Object.entries(subsetKey)) {\n if (Array.isArray(value)) {\n layers[key] = value;\n } else {\n layers[key] = [value];\n }\n }\n }\n\n const layerCount = Object.keys(layers).length;\n let pos: PositionMap = {};\n\n // Process each layer\n Object.entries(layers).forEach(([_layer, nodes], layerIdx) => {\n const layerNodes = Array.isArray(nodes) ? nodes : [nodes];\n const layerSize = layerNodes.length;\n\n layerNodes.forEach((node, nodeIdx) => {\n // Place nodes in a grid: layerIdx determines x-coordinate (column)\n // nodeIdx determines y-coordinate (row position within column)\n const x = layerIdx - (layerCount - 1) / 2;\n const y = nodeIdx - (layerSize - 1) / 2;\n pos[node] = [x, y];\n });\n });\n\n // Rescale positions\n pos = rescaleLayout(pos, scale, center) as PositionMap;\n\n // Handle horizontal alignment\n if (align === \"horizontal\") {\n for (const node in pos) {\n const temp = pos[node][0];\n pos[node][0] = pos[node][1];\n pos[node][1] = temp;\n }\n }\n\n return pos;\n}\n","import type { Graph, Node, PositionMap } from \"../../types\";\nimport { getNeighbors,getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { multipartiteLayout } from \"./multipartite\";\n\n/**\n * Position nodes according to breadth-first search algorithm.\n * @param G - Graph\n * @param start - Starting node for bfs\n * @param align - The alignment of layers: 'vertical' or 'horizontal'\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @returns Positions dictionary keyed by node\n */\nexport function bfsLayout(\n G: Graph,\n start: Node,\n align: \"vertical\" | \"horizontal\" = \"vertical\",\n scale: number = 1,\n center: number[] | null = null,\n): PositionMap {\n const processed = _processParams(G, center || [0, 0], 2);\n\n // BFS layout requires a proper Graph, not just a list of nodes\n if (Array.isArray(processed.G)) {\n throw new Error(\"BFS layout requires a Graph with edges, not just a list of nodes\");\n }\n\n const graph = processed.G;\n ({ center } = processed);\n\n const allNodes = getNodesFromGraph(graph);\n\n if (allNodes.length === 0) {\n return {};\n }\n\n // Compute BFS layers\n const layers: Record<number, Node[]> = {};\n const visited = new Set<Node>();\n let currentLayer = 0;\n\n // Starting layer\n layers[currentLayer] = [start];\n visited.add(start);\n\n // BFS traversal\n while (Object.values(layers).flat().length < allNodes.length) {\n const nextLayer: Node[] = [];\n const currentNodes = layers[currentLayer];\n\n for (const node of currentNodes) {\n // Get neighbors - this is a simplified approach\n // In a real implementation, we would get neighbors from the graph\n const neighbors = getNeighbors(graph, node);\n\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n nextLayer.push(neighbor);\n visited.add(neighbor);\n }\n }\n }\n\n if (nextLayer.length === 0) {\n // No more connected nodes\n const unvisited: Node[] = allNodes.filter((node: Node) => !visited.has(node));\n if (unvisited.length > 0) {\n throw new Error(\"bfs_layout didn't include all nodes. Graph may be disconnected.\");\n }\n break;\n }\n\n currentLayer++;\n layers[currentLayer] = nextLayer;\n }\n\n // Use multipartite_layout to position the layers\n return multipartiteLayout(graph, layers, align, scale, center);\n}\n","/**\n * Bipartite layout algorithm\n */\n\nimport { Graph, Node, PositionMap } from \"../../types\";\nimport { getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { rescaleLayout } from \"../../utils/rescale\";\n\n/**\n * Position nodes in two straight lines (bipartite layout).\n * @param G - Graph or list of nodes\n * @param nodes - Nodes in one node set of the graph\n * @param align - The alignment of nodes: 'vertical' or 'horizontal'\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param aspectRatio - The ratio of the width to the height of the layout\n * @returns Positions dictionary keyed by node\n */\nexport function bipartiteLayout(\n G: Graph,\n nodes: Node[] | null = null,\n align: \"vertical\" | \"horizontal\" = \"vertical\",\n scale: number = 1,\n center: number[] | null = null,\n aspectRatio: number = 4 / 3,\n): PositionMap {\n if (align !== \"vertical\" && align !== \"horizontal\") {\n throw new Error(\"align must be either vertical or horizontal\");\n }\n\n const processed = _processParams(G, center || [0, 0], 2);\n const graph = processed.G;\n ({ center } = processed);\n\n const allNodes = getNodesFromGraph(graph);\n\n if (allNodes.length === 0) {\n return {};\n }\n\n // If nodes not provided, try to determine bipartite sets\n if (!nodes) {\n // A simple heuristic for bipartite detection: use nodes with even/odd indices\n // This is a simplification, in Python NetworkX has bipartite.sets()\n nodes = allNodes.filter((_: Node, i: number): boolean => i % 2 === 0);\n }\n\n const left = new Set(nodes);\n const right: Set<Node> = new Set(allNodes.filter((n: Node) => !left.has(n)));\n\n const height = 1;\n const width = aspectRatio * height;\n const offset = [width / 2, height / 2];\n\n const pos: PositionMap = {};\n\n // Position nodes in the left set\n const leftNodes = [...left];\n leftNodes.forEach((node, i) => {\n const x = 0;\n const y = (i * height) / (leftNodes.length || 1);\n pos[node] = [x, y];\n });\n\n // Position nodes in the right set\n const rightNodes = [...right];\n rightNodes.forEach((node, i) => {\n const x = width;\n const y = (i * height) / (rightNodes.length || 1);\n pos[node] = [x, y];\n });\n\n // Center positions around the origin and apply offset\n for (const node in pos) {\n pos[node][0] -= offset[0];\n pos[node][1] -= offset[1];\n }\n\n // Rescale positions\n const scaledPos = rescaleLayout(pos, scale, center) as PositionMap;\n\n // Handle horizontal alignment\n if (align === \"horizontal\") {\n for (const node in scaledPos) {\n const temp = scaledPos[node][0];\n scaledPos[node][0] = scaledPos[node][1];\n scaledPos[node][1] = temp;\n }\n }\n\n return scaledPos;\n}\n","/**\n * Embedding functions for planar graphs\n */\n\nimport { Edge, Embedding, Node, PositionMap } from \"../../types\";\nimport { RandomNumberGenerator } from \"../../utils/random\";\n\n/**\n * Create a triangulation-based embedding for a planar graph\n * @param nodes - List of nodes\n * @param edges - List of edges\n * @param seed - Random seed for deterministic embedding generation\n * @returns Embedding object\n */\nexport function createTriangulationEmbedding(nodes: Node[], edges: Edge[], seed: number | null = null): Embedding {\n // Create RNG instance for deterministic randomness\n const rng = new RandomNumberGenerator(seed ?? undefined);\n\n // Create a simple embedding using the incremental approach\n const embedding: Embedding = {\n nodeOrder: [...nodes],\n faceList: [],\n nodePositions: {},\n };\n\n // Create a map of adjacent nodes\n const adjMap: Record<Node, Set<Node>> = {};\n for (const node of nodes) {\n adjMap[node] = new Set<Node>();\n }\n\n for (const [u, v] of edges) {\n adjMap[u].add(v);\n adjMap[v].add(u);\n }\n\n // Create outer face as a cycle (if possible)\n const outerFace = findCycle(nodes, edges, adjMap) || nodes;\n embedding.faceList.push(outerFace);\n\n // Position nodes on a convex polygon (outer face)\n const n = outerFace.length;\n for (let i = 0; i < n; i++) {\n const angle = (2 * Math.PI * i) / n;\n embedding.nodePositions[outerFace[i]] = [Math.cos(angle), Math.sin(angle)];\n }\n\n // Position interior nodes using barycentric coordinates\n const interiorNodes = nodes.filter((node) => !embedding.nodePositions[node]);\n\n for (const node of interiorNodes) {\n const neighbors = Array.from(adjMap[node]);\n\n if (neighbors.length === 0) {\n // Isolated node, place at center\n embedding.nodePositions[node] = [0, 0];\n } else {\n // Average position of neighbors that have positions\n let xSum = 0,\n ySum = 0,\n count = 0;\n\n for (const neighbor of neighbors) {\n if (embedding.nodePositions[neighbor]) {\n xSum += embedding.nodePositions[neighbor][0];\n ySum += embedding.nodePositions[neighbor][1];\n count++;\n }\n }\n\n if (count > 0) {\n // Place slightly away from center to avoid overlaps\n const jitter = 0.1 * (rng.rand() as number);\n embedding.nodePositions[node] = [\n xSum / count + jitter * ((rng.rand() as number) - 0.5),\n ySum / count + jitter * ((rng.rand() as number) - 0.5),\n ];\n } else {\n // No neighbors have positions yet, place randomly inside unit circle\n const r = 0.5 * (rng.rand() as number);\n const angle = 2 * Math.PI * (rng.rand() as number);\n embedding.nodePositions[node] = [r * Math.cos(angle), r * Math.sin(angle)];\n }\n }\n }\n\n return embedding;\n}\n\n/**\n * Find a simple cycle in the graph (for outer face)\n * @param nodes - List of nodes\n * @param _edges - List of edges (reserved for future use)\n * @param adjMap - Adjacency map\n * @returns Cycle as array of nodes, or null if none found\n */\nexport function findCycle(nodes: Node[], _edges: Edge[], adjMap: Record<Node, Set<Node>>): Node[] | null {\n if (nodes.length === 0) {return null;}\n if (nodes.length <= 2) {return nodes;} // Not a real cycle but handle it\n\n // Try to find a Hamiltonian cycle for simplicity (for small graphs)\n if (nodes.length <= 8) {\n const visited = new Set<Node>();\n const path: Node[] = [];\n\n function hamiltonianCycleDFS(node: Node): boolean {\n path.push(node);\n visited.add(node);\n\n if (path.length === nodes.length) {\n // Check if it's a cycle (last node connects to first)\n if (adjMap[node].has(path[0])) {\n return true;\n }\n // Not a cycle\n visited.delete(node);\n path.pop();\n return false;\n }\n\n for (const neighbor of adjMap[node]) {\n if (!visited.has(neighbor)) {\n if (hamiltonianCycleDFS(neighbor)) {\n return true;\n }\n }\n }\n\n visited.delete(node);\n path.pop();\n return false;\n }\n\n if (hamiltonianCycleDFS(nodes[0])) {\n return path;\n }\n }\n\n // Fallback: try to find any cycle using DFS\n const visited = new Set<Node>();\n const parent: Record<Node, Node | null> = {};\n let cycleFound: Node[] | null = null;\n\n function findCycleDFS(node: Node, parentNode: Node | null): boolean {\n visited.add(node);\n\n for (const neighbor of adjMap[node]) {\n if (neighbor === parentNode) {continue;}\n\n if (visited.has(neighbor)) {\n // Found a cycle\n cycleFound = constructCycle(node, neighbor, parent);\n return true;\n }\n\n parent[neighbor] = node;\n if (findCycleDFS(neighbor, node)) {\n return true;\n }\n }\n\n return false;\n }\n\n function constructCycle(u: Node, v: Node, parent: Record<Node, Node | null>): Node[] {\n const cycle: Node[] = [v, u];\n let current = u;\n\n while (parent[current] !== undefined && parent[current] !== v) {\n current = parent[current] as Node;\n cycle.push(current);\n }\n\n return cycle;\n }\n\n // Try to find a cycle\n for (const node of nodes) {\n if (!visited.has(node)) {\n parent[node] = null;\n if (findCycleDFS(node, null)) {\n break;\n }\n }\n }\n\n return cycleFound || nodes; // Fallback to all nodes if no cycle found\n}\n\n/**\n * Convert a combinatorial embedding to node positions\n * @param embedding - The embedding object\n * @param nodes - List of nodes\n * @returns Dictionary mapping nodes to positions\n */\nexport function combinatorialEmbeddingToPos(embedding: Embedding, nodes: Node[]): PositionMap {\n const pos: PositionMap = {};\n\n // Use the positions from the embedding\n for (const node of nodes) {\n if (embedding.nodePositions[node]) {\n pos[node] = embedding.nodePositions[node];\n } else {\n // Fallback for any nodes without positions\n pos[node] = [0, 0];\n }\n }\n\n return pos;\n}\n","/**\n * Left-Right Planarity Test implementation\n */\n\nimport { Edge, Embedding,Node } from \"../../types\";\nimport { createTriangulationEmbedding } from \"./embedding\";\n\n/**\n * Left-Right Planarity Test for general graphs\n * @param nodes - List of nodes\n * @param edges - List of edges\n * @param seed - Random seed for deterministic embedding generation\n * @returns Object containing isPlanar flag and embedding\n */\nexport function lrPlanarityTest(\n nodes: Node[],\n edges: Edge[],\n seed: number | null = null,\n): { isPlanar: boolean; embedding: Embedding | null } {\n // Create adjacency list for the graph\n const adjList: Record<Node, Node[]> = {};\n for (const node of nodes) {\n adjList[node] = [];\n }\n\n for (const [u, v] of edges) {\n adjList[u].push(v);\n adjList[v].push(u);\n }\n\n // Step 1: Perform DFS to get an st-numbering (ordering of nodes)\n const visited = new Set<Node>();\n const ordering: Node[] = [];\n\n function dfs(node: Node): void {\n visited.add(node);\n ordering.push(node);\n\n for (const neighbor of adjList[node]) {\n if (!visited.has(neighbor)) {\n dfs(neighbor);\n }\n }\n }\n\n // Start DFS from first node\n dfs(nodes[0]);\n\n // If the graph is disconnected, it's still planar but we need to handle each component\n if (ordering.length < nodes.length) {\n // Create a simple triangulation embedding for disconnected graphs\n return { isPlanar: true, embedding: createTriangulationEmbedding(nodes, edges, seed) };\n }\n\n // Step 2: For a general implementation, we'll use a simplified approach\n // since this would normally require implementing the entire LR algorithm\n\n // For this implementation, since we can't fully implement Boyer-Myrvold,\n // we'll create a reasonable planar embedding for most planar graphs\n\n // We assume the graph is planar if it's sparse enough (|E| <= 3|V| - 6)\n // This is a necessary but not sufficient condition for planar graphs\n if (edges.length > 3 * nodes.length - 6) {\n return { isPlanar: false, embedding: null };\n }\n\n // Create a planar embedding using a triangulation approach\n const embedding = createTriangulationEmbedding(nodes, edges, seed);\n\n return { isPlanar: true, embedding };\n}\n","/**\n * Special graph detection functions for planarity testing\n */\n\nimport { Edge,Node } from \"../../types\";\n\n/**\n * Check if graph is K5 (complete graph with 5 nodes)\n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns True if graph is K5\n */\nexport function isK5(nodes: Node[], edges: Edge[]): boolean {\n if (nodes.length !== 5) {return false;}\n\n // K5 has exactly 10 edges\n if (edges.length !== 10) {return false;}\n\n // Check if every pair of distinct nodes is connected\n for (let i = 0; i < nodes.length; i++) {\n for (let j = i + 1; j < nodes.length; j++) {\n const hasEdge = edges.some(\n (e) => (e[0] === nodes[i] && e[1] === nodes[j]) || (e[0] === nodes[j] && e[1] === nodes[i]),\n );\n if (!hasEdge) {return false;}\n }\n }\n\n return true;\n}\n\n/**\n * Check if graph is K3,3 (complete bipartite with 3,3 nodes)\n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns True if graph is K3,3\n */\nexport function isK33(nodes: Node[], edges: Edge[]): boolean {\n if (nodes.length !== 6) {return false;}\n\n // K3,3 has exactly 9 edges\n if (edges.length !== 9) {return false;}\n\n // Try to find a bipartite partition\n const nodePartitions = tryFindBipartitePartition(nodes, edges);\n if (!nodePartitions) {return false;}\n\n const [part1, part2] = nodePartitions;\n\n // Check if both partitions have size 3\n if (part1.length !== 3 || part2.length !== 3) {return false;}\n\n // Check if every node in part1 is connected to every node in part2\n for (const n1 of part1) {\n for (const n2 of part2) {\n const hasEdge = edges.some((e) => (e[0] === n1 && e[1] === n2) || (e[0] === n2 && e[1] === n1));\n if (!hasEdge) {return false;}\n }\n }\n\n return true;\n}\n\n/**\n * Try to find a bipartite partition of the nodes\n * @param nodes - List of nodes\n * @param edges - List of edges\n * @returns Array of two partitions, or null if not bipartite\n */\nexport function tryFindBipartitePartition(nodes: Node[], edges: Edge[]): [Node[], Node[]] | null {\n const colorMap: Record<Node, number> = {};\n const adjList: Record<Node, Node[]> = {};\n\n // Create adjacency list\n for (const node of nodes) {\n adjList[node] = [];\n }\n\n for (const [u, v] of edges) {\n adjList[u].push(v);\n adjList[v].push(u);\n }\n\n // BFS to color nodes\n const queue: Node[] = [nodes[0]];\n colorMap[nodes[0]] = 0;\n\n while (queue.length > 0) {\n const node = queue.shift() as Node;\n const nodeColor = colorMap[node];\n\n for (const neighbor of adjList[node]) {\n if (colorMap[neighbor] === undefined) {\n colorMap[neighbor] = 1 - nodeColor; // Toggle color (0/1)\n queue.push(neighbor);\n } else if (colorMap[neighbor] === nodeColor) {\n // Conflict: not bipartite\n return null;\n }\n }\n }\n\n // Create partitions\n const part0: Node[] = [];\n const part1: Node[] = [];\n\n for (const node of nodes) {\n if (colorMap[node] === 0) {\n part0.push(node);\n } else {\n part1.push(node);\n }\n }\n\n return [part0, part1];\n}\n","/**\n * Main planarity checking function\n */\n\nimport { Edge, Embedding,Graph, Node } from \"../../types\";\nimport { createTriangulationEmbedding } from \"./embedding\";\nimport { lrPlanarityTest } from \"./lr-test\";\nimport { isK5, isK33 } from \"./special-graphs\";\n\n/**\n * Check if graph is planar using a simplified version of Boyer-Myrvold algorithm.\n * Returns planarity and embedding information.\n * @param _G - Graph (reserved for future use)\n * @param nodes - List of nodes\n * @param edges - List of edges\n * @param seed - Random seed for deterministic embedding generation\n * @returns Object containing isPlanar flag and embedding\n */\nexport function checkPlanarity(\n _G: Graph,\n nodes: Node[],\n edges: Edge[],\n seed: number | null = null,\n): { isPlanar: boolean; embedding: Embedding | null } {\n // For small graphs (n <= 4), all are planar\n if (nodes.length <= 4) {\n return { isPlanar: true, embedding: createTriangulationEmbedding(nodes, edges, seed) };\n }\n\n // For K5 (complete graph with 5 nodes) and K3,3 (complete bipartite with 3,3 nodes)\n // these are not planar by Kuratowski's theorem\n if (isK5(nodes, edges) || isK33(nodes, edges)) {\n return { isPlanar: false, embedding: null };\n }\n\n // For other graphs, use LR algorithm (Left-Right Planarity Test)\n const result = lrPlanarityTest(nodes, edges, seed);\n return result;\n}\n","/**\n * Planar layout algorithm\n */\n\nimport { checkPlanarity, combinatorialEmbeddingToPos } from \"../../algorithms/planarity\";\nimport type { Graph, PositionMap } from \"../../types\";\nimport { getEdgesFromGraph,getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { rescaleLayout } from \"../../utils/rescale\";\n\n/**\n * Position nodes without edge intersections (planar layout).\n * @param G - Graph\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout (must be 2)\n * @param seed - Random seed for reproducible layouts\n * @returns Positions dictionary keyed by node\n */\nexport function planarLayout(\n G: Graph,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n seed: number | null = null,\n): PositionMap {\n if (dim !== 2) {\n throw new Error(\"can only handle 2 dimensions\");\n }\n\n const processed = _processParams(G, center || [0, 0], dim);\n\n // Planar layout requires a proper Graph, not just a list of nodes\n if (Array.isArray(processed.G)) {\n throw new Error(\"Planar layout requires a Graph with edges, not just a list of nodes\");\n }\n\n const graph = processed.G;\n ({ center } = processed);\n\n const nodes = getNodesFromGraph(graph);\n const edges = getEdgesFromGraph(graph);\n\n if (nodes.length === 0) {\n return {};\n }\n\n // Check if graph is planar and get embedding\n const { isPlanar, embedding } = checkPlanarity(graph, nodes, edges, seed);\n\n if (!isPlanar) {\n throw new Error(\"G is not planar.\");\n }\n\n if (!embedding) {\n throw new Error(\"Failed to generate planar embedding.\");\n }\n\n // Convert embedding to positions\n let pos = combinatorialEmbeddingToPos(embedding, nodes);\n\n // Rescale the positions\n pos = rescaleLayout(pos, scale, center) as PositionMap;\n\n return pos;\n}\n","/**\n * Spectral layout algorithm using eigenvectors of the graph Laplacian\n */\n\nimport type { Graph, Node, PositionMap } from \"../../types\";\nimport { getEdgesFromGraph,getNodesFromGraph } from \"../../utils/graph\";\nimport { _processParams } from \"../../utils/params\";\nimport { rescaleLayout } from \"../../utils/rescale\";\n\n/**\n * Position nodes in a spectral layout using eigenvectors of the graph Laplacian.\n * @param G - Graph\n * @param scale - Scale factor for positions\n * @param center - Coordinate pair around which to center the layout\n * @param dim - Dimension of layout\n * @returns Positions dictionary keyed by node\n */\nexport function spectralLayout(\n G: Graph,\n scale: number = 1,\n center: number[] | null = null,\n dim: number = 2,\n): PositionMap {\n const processed = _processParams(G, center, dim);\n const graph = processed.G;\n ({ center } = processed);\n\n const nodes = getNodesFromGraph(graph);\n\n if (nodes.length <= 2) {\n if (nodes.length === 0) {\n return {};\n } else if (nodes.length === 1) {\n return { [nodes[0]]: center };\n } \n return {\n [nodes[0]]: center.map((v) => v - scale),\n [nodes[1]]: center.map((v) => v + scale),\n };\n \n }\n\n // Create adjacency matrix\n const N = nodes.length;\n const nodeIndices: Record<Node, number> = {};\n nodes.forEach((node: Node, i: number) => {\n nodeIndices[node] = i;\n });\n\n const A: number[][] = Array(N)\n .fill(0)\n .map(() => Array(N).fill(0) as number[]);\n const edges = getEdgesFromGraph(graph);\n\n for (const [source, target] of edges) {\n const i = nodeIndices[source];\n const j = nodeIndices[target];\n A[i][j] = 1;\n A[j][i] = 1; // Make symmetric for undirected graphs\n }\n\n // Create Laplacian matrix: L = D - A where D is degree matrix\n const L: number[][] = Array(N)\n .fill(0)\n .map(() => Array(N).fill(0) as number[]);\n for (let i = 0; i < N; i++) {\n // Compute degree (sum of row)\n L[i][i] = A[i].reduce((sum: number, val: number) => sum + val, 0);\n for (let j = 0; j < N; j++) {\n L[i][j] -= A[i][j];\n }\n }\n\n // Compute eigenvectors using power iteration method\n // We need the smallest non-zero eigenvectors of L\n const eigenvectors: number[][] = [];\n\n // For each dimension, find an eigenvector\n for (let d = 0; d < dim; d++) {\n let vector = Array(N)\n .fill(0)\n .map(() => Math.random() - 0.5);\n\n // Orthogonalize against previous eigenvectors\n for (const ev of eigenvectors) {\n const dot = vector.reduce((acc, val, idx) => acc + val * ev[idx], 0);\n vector = vector.map((val, idx) => val - dot * ev[idx]);\n }\n\n // Normalize\n const norm = Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0));\n vector = vector.map((val) => val / norm);\n\n // Apply shifted inverse iteration to find smallest non-zero eigenvector\n // This is a simplification of the actual algorithm\n for (let iter = 0; iter < 100; iter++) {\n // Apply Laplacian\n const newVec: number[] = Array(N).fill(0);\n for (let i = 0; i < N; i++) {\n for (let j = 0; j < N; j++) {\n newVec[i] += L[i][j] * vector[j];\n }\n }\n\n // Orthogonalize against the constant vector (eigenvector with eigenvalue 0)\n const mean = newVec.reduce((acc: number, val: number) => acc + val, 0) / N;\n newVec.forEach((val, idx, arr) => {\n arr[idx] = val - mean;\n });\n\n // Normalize\n const newNorm = Math.sqrt(newVec.reduce((acc: number, val: number) => acc + val * val, 0));\n if (newNorm < 1e-10) {continue;} // Skip if vector is close to zero\n\n vector = newVec.map((val) => val / newNorm);\n }\n\n eigenvectors.push(vector);\n }\n\n // Create position array from eigenvectors\n const positions: number[][] = Array(N)\n .fill(0)\n .map(() => Array(dim).fill(0));\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < dim; d++) {\n positions[i][d] = eigenvectors[d][i];\n }\n }\n\n // Rescale and create position dictionary\n const scaledPositions = rescaleLayout(positions, scale);\n const pos: PositionMap = {};\n nodes.forEach((node: Node, i: number) => {\n pos[node] = (scaledPositions as number[][])[i].map((val: number, j: number) => val + center[j]);\n });\n\n return pos;\n}\n","/**\n * Basic graph generation functions\n */\n\nimport { Edge,Graph, Node } from \"../types\";\n\n/**\n * Create a complete graph with n nodes\n * @param n - Number of nodes\n * @returns Graph object with all nodes connected to all other nodes\n */\nexport function completeGraph(n: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n edges.push([i, j]);\n }\n }\n\n return {\n nodes: () => nodes,\n edges: () => edges,\n };\n}\n\n/**\n * Create a cycle graph with n nodes\n * @param n - Number of nodes\n * @returns Graph object with nodes connected in a cycle\n */\nexport function cycleGraph(n: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n\n for (let i = 0; i < n; i++) {\n edges.push([i, (i + 1) % n]);\n }\n\n return {\n nodes: () => nodes,\n edges: () => edges,\n };\n}\n\n/**\n * Create a star graph with n nodes (1 center + n-1 leaves)\n * @param n - Total number of nodes\n * @returns Graph object with star topology\n */\nexport function starGraph(n: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n\n // Connect all nodes to node 0 (center)\n for (let i = 1; i < n; i++) {\n edges.push([0, i]);\n }\n\n return {\n nodes: () => nodes,\n edges: () => edges,\n };\n}\n\n/**\n * Create a wheel graph with n nodes (1 center + n-1 rim nodes)\n * @param n - Total number of nodes\n * @returns Graph object with wheel topology\n */\nexport function wheelGraph(n: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n\n // Connect all rim nodes to center (node 0)\n for (let i = 1; i < n; i++) {\n edges.push([0, i]);\n }\n\n // Connect rim nodes in a cycle\n for (let i = 1; i < n - 1; i++) {\n edges.push([i, i + 1]);\n }\n if (n > 2) {\n edges.push([n - 1, 1]);\n }\n\n return {\n nodes: () => nodes,\n edges: () => edges,\n };\n}\n","/**\n * Bipartite graph generation function\n */\n\nimport { Edge,Graph, Node } from \"../types\";\n\n/**\n * Create a bipartite graph with two sets of nodes\n * @param n1 - Number of nodes in first set\n * @param n2 - Number of nodes in second set\n * @param p - Probability of edge between nodes in different sets\n * @param seed - Random seed for reproducibility\n * @returns Graph object with bipartite structure and setA/setB properties\n */\nexport function bipartiteGraph(\n n1: number,\n n2: number,\n p: number,\n seed?: number,\n): Graph & { setA: Node[]; setB: Node[] } {\n const setA: Node[] = Array.from({ length: n1 }, (_, i) => `A${i}`);\n const setB: Node[] = Array.from({ length: n2 }, (_, i) => `B${i}`);\n const nodes = [...setA, ...setB];\n const edges: Edge[] = [];\n\n // Simple deterministic pseudo-random if seed provided\n let currentSeed = seed;\n const random =\n seed !== undefined\n ? () => {\n currentSeed = ((currentSeed as number) * 9301 + 49297) % 233280;\n return currentSeed / 233280;\n }\n : Math.random;\n\n // Only connect nodes between sets\n for (const a of setA) {\n for (const b of setB) {\n if (random() < p) {\n edges.push([a, b]);\n }\n }\n }\n\n return {\n nodes: () => nodes,\n edges: () => edges,\n setA,\n setB,\n };\n}\n","/**\n * Grid graph generation function\n */\n\nimport { Edge,Graph, Node } from \"../types\";\n\n/**\n * Create a grid graph with rows x cols nodes\n * @param rows - Number of rows\n * @param cols - Number of columns\n * @returns Graph object with grid topology\n */\nexport function gridGraph(rows: number, cols: number): Graph {\n const nodes: Node[] = [];\n const edges: Edge[] = [];\n\n // Create nodes\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n nodes.push(`${i},${j}`);\n }\n }\n\n // Create edges\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n // Connect to right neighbor\n if (j < cols - 1) {\n edges.push([`${i},${j}`, `${i},${j + 1}`]);\n }\n // Connect to bottom neighbor\n if (i < rows - 1) {\n edges.push([`${i},${j}`, `${i + 1},${j}`]);\n }\n }\n }\n\n return {\n nodes: () => nodes,\n edges: () => edges,\n };\n}\n","/**\n * Random graph generation function\n */\n\nimport { Edge,Graph, Node } from \"../types\";\n\n/**\n * Create a random graph with n nodes and given edge probability\n * @param n - Number of nodes\n * @param p - Probability of edge between any two nodes (0-1)\n * @param seed - Random seed for reproducibility\n * @returns Graph object with random edges\n */\nexport function randomGraph(n: number, p: number, seed?: number): Graph {\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n\n // Simple deterministic pseudo-random if seed provided\n let currentSeed = seed;\n const random =\n seed !== undefined\n ? () => {\n currentSeed = ((currentSeed as number) * 9301 + 49297) % 233280;\n return currentSeed / 233280;\n }\n : Math.random;\n\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n if (random() < p) {\n edges.push([i, j]);\n }\n }\n }\n\n return {\n nodes: () => nodes,\n edges: () => edges,\n };\n}\n","/**\n * Scale-free graph generation function\n */\n\nimport { Edge,Graph, Node } from \"../types\";\n\n/**\n * Create a scale-free graph using Barabási-Albert model\n * @param n - Total number of nodes\n * @param m - Number of edges to attach from new node\n * @param seed - Random seed for reproducibility\n * @returns Graph object with scale-free properties\n */\nexport function scaleFreeGraph(n: number, m: number, seed?: number): Graph {\n if (m >= n) {\n throw new Error(\"m must be less than n\");\n }\n\n const nodes: Node[] = Array.from({ length: n }, (_, i) => i);\n const edges: Edge[] = [];\n const degrees = new Array(n).fill(0);\n\n // Simple deterministic pseudo-random if seed provided\n let currentSeed = seed;\n const random =\n seed !== undefined\n ? () => {\n currentSeed = ((currentSeed as number) * 9301 + 49297) % 233280;\n return currentSeed / 233280;\n }\n : Math.random;\n\n // Start with complete graph of m+1 nodes\n for (let i = 0; i <= m; i++) {\n for (let j = i + 1; j <= m; j++) {\n edges.push([i, j]);\n degrees[i]++;\n degrees[j]++;\n }\n }\n\n // Add remaining nodes\n for (let i = m + 1; i < n; i++) {\n const targets = new Set<number>();\n const totalDegree = degrees.reduce((sum: number, d: number) => sum + d, 0);\n\n // Choose m targets based on preferential attachment\n while (targets.size < m) {\n const r = random() * totalDegree;\n let cumSum = 0;\n\n for (let j = 0; j < i; j++) {\n cumSum += degrees[j] as number;\n if (r <= cumSum && !targets.has(j)) {\n targets.add(j);\n break;\n }\n }\n }\n\n // Add edges to targets\n for (const target of targets) {\n edges.push([i, target]);\n degrees[i]++;\n degrees[target]++;\n }\n }\n\n return {\n nodes: () => nodes,\n edges: () => edges,\n };\n}\n"],"names":["result","i","posArray","visited","parent"],"mappings":"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"}
|