{
  "version": 3,
  "sources": ["../../src/clustering/mst.ts"],
  "sourcesContent": ["import type { LeafInput, MstEdge } from './types'\n\n/**\n * Return the Euclidean MST over the leaves, ordered by the canonical edge key:\n * distance, then normalized endpoint ids.\n */\nexport function mstEdges(leaves: readonly LeafInput[]): MstEdge[] {\n\tconst n = leaves.length\n\tconst ids = new Array<string>(n)\n\tconst xs = new Float64Array(n)\n\tconst ys = new Float64Array(n)\n\tconst seen = new Set<string>()\n\n\tlet root = 0\n\tfor (let i = 0; i < n; i++) {\n\t\tconst leaf = leaves[i]\n\t\tif (seen.has(leaf.id)) {\n\t\t\tthrow new Error(`Duplicate leaf id: ${leaf.id}`)\n\t\t}\n\t\tseen.add(leaf.id)\n\t\tif (!Number.isFinite(leaf.point.x) || !Number.isFinite(leaf.point.y)) {\n\t\t\tthrow new Error(`Non-finite coordinate for leaf id: ${leaf.id}`)\n\t\t}\n\t\tids[i] = leaf.id\n\t\txs[i] = leaf.point.x\n\t\tys[i] = leaf.point.y\n\t\tif (i > 0 && leaf.id < ids[root]) root = i\n\t}\n\n\tif (n < 2) return []\n\n\tconst inTree = new Uint8Array(n)\n\tconst bestD2 = new Float64Array(n)\n\tconst bestFrom = new Int32Array(n)\n\n\tinTree[root] = 1\n\tbestD2.fill(Number.POSITIVE_INFINITY)\n\tbestFrom.fill(-1)\n\n\tfor (let i = 0; i < n; i++) {\n\t\tif (i === root) continue\n\t\tbestD2[i] = squaredDistance(xs, ys, root, i)\n\t\tbestFrom[i] = root\n\t}\n\n\tconst edges: MstEdge[] = []\n\n\tfor (let edgeCount = 0; edgeCount < n - 1; edgeCount++) {\n\t\tlet next = -1\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tif (inTree[i]) continue\n\t\t\tif (\n\t\t\t\tnext === -1 ||\n\t\t\t\tedgeKeyLess(bestD2[i], bestFrom[i], i, bestD2[next], bestFrom[next], next, ids)\n\t\t\t) {\n\t\t\t\tnext = i\n\t\t\t}\n\t\t}\n\n\t\tconst from = bestFrom[next]\n\t\tedges.push(createOutputEdge(xs, ys, ids, from, next))\n\t\tinTree[next] = 1\n\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tif (inTree[i]) continue\n\t\t\tconst d2 = squaredDistance(xs, ys, next, i)\n\t\t\tif (edgeKeyLess(d2, next, i, bestD2[i], bestFrom[i], i, ids)) {\n\t\t\t\tbestD2[i] = d2\n\t\t\t\tbestFrom[i] = next\n\t\t\t}\n\t\t}\n\t}\n\n\tedges.sort((a, b) => outputEdgeCompare(a, b, leaves))\n\treturn edges\n}\n\nfunction squaredDistance(xs: Float64Array, ys: Float64Array, a: number, b: number): number {\n\tconst dx = xs[a] - xs[b]\n\tconst dy = ys[a] - ys[b]\n\treturn dx * dx + dy * dy\n}\n\nfunction edgeKeyLess(\n\td2A: number,\n\ta0: number,\n\ta1: number,\n\td2B: number,\n\tb0: number,\n\tb1: number,\n\tids: readonly string[]\n): boolean {\n\tif (d2A !== d2B) return d2A < d2B\n\n\tconst aLo = ids[a0] < ids[a1] ? ids[a0] : ids[a1]\n\tconst aHi = ids[a0] < ids[a1] ? ids[a1] : ids[a0]\n\tconst bLo = ids[b0] < ids[b1] ? ids[b0] : ids[b1]\n\tconst bHi = ids[b0] < ids[b1] ? ids[b1] : ids[b0]\n\n\tif (aLo !== bLo) return aLo < bLo\n\treturn aHi < bHi\n}\n\nfunction createOutputEdge(\n\txs: Float64Array,\n\tys: Float64Array,\n\tids: readonly string[],\n\ti: number,\n\tj: number\n): MstEdge {\n\tconst a = ids[i] < ids[j] ? i : j\n\tconst b = ids[i] < ids[j] ? j : i\n\treturn {\n\t\ta,\n\t\tb,\n\t\td: Math.hypot(xs[a] - xs[b], ys[a] - ys[b]),\n\t}\n}\n\nfunction outputEdgeCompare(a: MstEdge, b: MstEdge, leaves: readonly LeafInput[]): number {\n\tif (a.d < b.d) return -1\n\tif (a.d > b.d) return 1\n\n\tconst aLo = leaves[a.a].id\n\tconst aHi = leaves[a.b].id\n\tconst bLo = leaves[b.a].id\n\tconst bHi = leaves[b.b].id\n\n\tif (aLo < bLo) return -1\n\tif (aLo > bLo) return 1\n\tif (aHi < bHi) return -1\n\tif (aHi > bHi) return 1\n\treturn 0\n}\n"],
  "mappings": "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",
  "names": []
}
