{
  "version": 3,
  "sources": ["../../src/clustering/runtime.ts"],
  "sourcesContent": ["import type { ClusterNode, ClusterTable, MergeEvent } from './types'\n\n/** @internal */\nexport interface ClusterRuntime {\n\t/** Events[0..k) are in the cursor (applied unless suppressed). Exposed for tests/debugging. */\n\treadonly k: number\n\t/**\n\t * Increments whenever the displayed partition changes. Subscribe to this, not `k`: detaches\n\t * and suppressed-event healing change the partition without moving the cursor.\n\t */\n\treadonly version: number\n\t/** Number of suppressed band events currently inside the cursor. Exposed for tests. */\n\tgetSuppressedCount(): number\n\t/** Number of leaves currently detached from the displayed partition. Exposed for tests. */\n\tgetDetachedCount(): number\n\t/** Reset state from scratch for the given zoom (cold start / after rebuild). Clears detaches. */\n\tseed(zoom: number): void\n\t/**\n\t * Reset state for the given zoom, carrying hysteresis state over from a previous partition.\n\t * Threshold-forced events ignore history: zoom \\<= zMerge is always merged, zoom \\>= zSplit always\n\t * split. An event inside its band keeps its previous state; one that was unmerged (or has no\n\t * history) stays suppressed inside the cursor until a zoom-out crosses its own zMerge. Carryover is\n\t * exact \u2014 no group changes state because of the swap alone. Clears detaches.\n\t */\n\tseedFrom(zoom: number, previous: ReadonlyMap<string, ClusterNode>): void\n\t/** Advance/retreat the cursor for a camera change. No-op if zoom sits inside all bands. */\n\tonCamera(zoom: number): void\n\t/**\n\t * Remove one leaf from the displayed partition without touching the event table. Local by\n\t * construction: only the nodes containing the leaf change, so a deletion, pop-out, or thread-open\n\t * never re-flows the rest of the document. The table's thresholds around the detached leaf go\n\t * stale; the caller is expected to adopt a corrected rebuild (with seedFrom) at the next zoom-out.\n\t * Unknown or already-detached ids are no-ops.\n\t */\n\tdetachLeaf(leafId: string): void\n\t/**\n\t * Batch form of {@link ClusterRuntime.detachLeaf}: detach every given leaf with a single\n\t * patch rebuild and a single version bump. Ids that are unknown or already detached are\n\t * skipped; if nothing new detaches, nothing changes.\n\t */\n\tdetachLeaves(leafIds: Iterable<string>): void\n\t/** The displayed partition: cluster id \u2192 node, with detaches applied. Do not mutate. */\n\tgetVisible(): ReadonlyMap<string, ClusterNode>\n}\n\n/** @internal */\nexport function createClusterRuntime(table: ClusterTable): ClusterRuntime {\n\treturn new ClusterRuntimeImpl(table)\n}\n\nclass ClusterRuntimeImpl implements ClusterRuntime {\n\t// mutable internally; readonly through the ClusterRuntime interface\n\tk = 0\n\tversion = 0\n\t// Structural partition: exactly leaves + applied events, never patched. The cursor invariants\n\t// live here, untouched by detaches \u2014 resolution to the displayed partition happens at read\n\t// time in getVisible().\n\tprivate visible = new Map<string, ClusterNode>()\n\tprivate seeded = false\n\t// Indices (< k) of band events held unmerged by seedFrom carryover. The single cursor can only\n\t// express \"merged up to here\", but a carried-over partition can be \"merged except these\". Self-\n\t// draining: an entry leaves via onCamera when the zoom crosses its zMerge or its zSplit.\n\tprivate suppressed = new Set<number>()\n\t// Leaves removed from the displayed partition (deleted / popped out / opened). Patches map\n\t// each structural node containing a detached leaf to its displayed replacement (or null to\n\t// drop it). Rebuilt from the detached set; cleared by seed/seedFrom.\n\tprivate detached = new Set<string>()\n\tprivate patched = new Map<string, ClusterNode | null>()\n\tprivate leafById: Map<string, ClusterNode> | null = null\n\tprivate resolvedCache: { version: number; map: Map<string, ClusterNode> } | null = null\n\n\tconstructor(private readonly table: ClusterTable) {\n\t\tthis.resetVisible()\n\t}\n\n\tgetSuppressedCount(): number {\n\t\treturn this.suppressed.size\n\t}\n\n\tgetDetachedCount(): number {\n\t\treturn this.detached.size\n\t}\n\n\tseed(zoom: number): void {\n\t\tvalidateZoom(zoom)\n\t\tthis.k = seedCount(this.table.events, zoom)\n\t\tthis.suppressed.clear()\n\t\tthis.detached.clear()\n\t\tthis.patched.clear()\n\t\tthis.resetVisible()\n\t\tfor (let i = 0; i < this.k; i++) {\n\t\t\tapplyEvent(this.visible, this.table.events[i])\n\t\t}\n\t\tthis.seeded = true\n\t\tthis.version++\n\t}\n\n\tseedFrom(zoom: number, previous: ReadonlyMap<string, ClusterNode>): void {\n\t\tvalidateZoom(zoom)\n\t\tconst ownerByMember = new Map<string, string>()\n\t\tfor (const node of previous.values()) {\n\t\t\tfor (const member of node.members) {\n\t\t\t\townerByMember.set(member, node.id)\n\t\t\t}\n\t\t}\n\n\t\t// Cut the cursor purely on split thresholds. zSplit is non-increasing down the table, so\n\t\t// everything past the first mandatory split (zoom >= zSplit) is also mandatorily split \u2014\n\t\t// this cut can never conflict with an event that should be merged.\n\t\tconst events = this.table.events\n\t\tlet k = 0\n\t\twhile (k < events.length && zoom < events[k].zSplit) {\n\t\t\tk++\n\t\t}\n\n\t\tthis.k = k\n\t\tthis.suppressed.clear()\n\t\tthis.detached.clear()\n\t\tthis.patched.clear()\n\t\tthis.resetVisible()\n\t\tfor (let i = 0; i < k; i++) {\n\t\t\tconst event = events[i]\n\t\t\tif (zoom > event.zMerge && !wasMergedTogether(event.result.members, ownerByMember)) {\n\t\t\t\t// In its band and previously unmerged: keep it unmerged, as an exception inside the cursor.\n\t\t\t\t// Dependency-safe, since an applied event can never consume a suppressed result.\n\t\t\t\tthis.suppressed.add(i)\n\t\t\t} else {\n\t\t\t\tapplyEvent(this.visible, event)\n\t\t\t}\n\t\t}\n\t\tthis.seeded = true\n\t\tthis.version++\n\t}\n\n\tonCamera(zoom: number): void {\n\t\tvalidateZoom(zoom)\n\t\tif (!this.seeded) {\n\t\t\tthrow new Error('Cluster runtime must be seeded before onCamera')\n\t\t}\n\n\t\tlet changed = false\n\t\t// Heal suppressed events at their own merge threshold BEFORE the merge walk, so a zoom-out past\n\t\t// zMerge merges a held-out band event as if it had still been ahead of the cursor. Healing must come\n\t\t// first: one zoom jump can cross both a suppressed event and an event consuming its result, and\n\t\t// applying the consumer first would double-count the producer's leaves. Iterated live \u2014 deleting only\n\t\t// the entry being visited is safe, and Set iteration still yields the rest in insertion order.\n\t\tif (this.suppressed.size > 0) {\n\t\t\tfor (const i of this.suppressed) {\n\t\t\t\tif (zoom <= this.table.events[i].zMerge) {\n\t\t\t\t\tthis.suppressed.delete(i)\n\t\t\t\t\tapplyEvent(this.visible, this.table.events[i])\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\twhile (this.k < this.table.events.length && zoom <= this.table.events[this.k].zMerge) {\n\t\t\tapplyEvent(this.visible, this.table.events[this.k])\n\t\t\tthis.k++\n\t\t\tchanged = true\n\t\t}\n\t\twhile (this.k > 0 && zoom >= this.table.events[this.k - 1].zSplit) {\n\t\t\tthis.k--\n\t\t\t// A suppressed event was never applied \u2014 retreating past it is bookkeeping only.\n\t\t\tif (!this.suppressed.delete(this.k)) {\n\t\t\t\tunapplyEvent(this.visible, this.table.events[this.k])\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t}\n\t\tif (changed) this.version++\n\t}\n\n\tdetachLeaf(leafId: string): void {\n\t\tthis.detachLeaves([leafId])\n\t}\n\n\tdetachLeaves(leafIds: Iterable<string>): void {\n\t\tconst leafById = this.getLeafById()\n\t\tlet changed = false\n\t\tfor (const leafId of leafIds) {\n\t\t\tif (this.detached.has(leafId)) continue\n\t\t\tif (!leafById.has(leafId)) continue\n\t\t\tthis.detached.add(leafId)\n\t\t\tchanged = true\n\t\t}\n\t\tif (!changed) return\n\t\tthis.rebuildPatches()\n\t\tthis.version++\n\t}\n\n\tgetVisible(): ReadonlyMap<string, ClusterNode> {\n\t\tif (this.resolvedCache && this.resolvedCache.version === this.version) {\n\t\t\treturn this.resolvedCache.map\n\t\t}\n\t\tlet map: Map<string, ClusterNode>\n\t\tif (this.patched.size === 0) {\n\t\t\tmap = this.visible\n\t\t} else {\n\t\t\tmap = new Map()\n\t\t\tfor (const node of this.visible.values()) {\n\t\t\t\tconst resolved = this.patched.has(node.id) ? this.patched.get(node.id)! : node\n\t\t\t\tif (resolved) map.set(resolved.id, resolved)\n\t\t\t}\n\t\t}\n\t\tthis.resolvedCache = { version: this.version, map }\n\t\treturn map\n\t}\n\n\tprivate getLeafById(): Map<string, ClusterNode> {\n\t\tif (!this.leafById) {\n\t\t\tthis.leafById = new Map(this.table.leaves.map((leaf) => [leaf.id, leaf]))\n\t\t}\n\t\treturn this.leafById\n\t}\n\n\t/** Recompute the patch map from the detached set. A node is patched iff it contains a detached\n\t *  member; the patch drops those members and recomputes count/centroid, collapsing to the surviving\n\t *  leaf at count 1 and to nothing at count 0. Patched nodes keep their structural id. */\n\tprivate rebuildPatches() {\n\t\tthis.patched.clear()\n\t\tconst leafById = this.getLeafById()\n\t\tfor (const id of this.detached) {\n\t\t\tthis.patched.set(id, null)\n\t\t}\n\t\tconst patch = (node: ClusterNode) => {\n\t\t\tif (node.members.length === 1 || !node.members.some((m) => this.detached.has(m))) return\n\t\t\tconst members = node.members.filter((m) => !this.detached.has(m))\n\t\t\tif (members.length === 0) {\n\t\t\t\tthis.patched.set(node.id, null)\n\t\t\t} else if (members.length === 1) {\n\t\t\t\tthis.patched.set(node.id, leafById.get(members[0])!)\n\t\t\t} else {\n\t\t\t\tlet x = 0\n\t\t\t\tlet y = 0\n\t\t\t\tfor (const m of members) {\n\t\t\t\t\tconst leaf = leafById.get(m)!\n\t\t\t\t\tx += leaf.centroid.x\n\t\t\t\t\ty += leaf.centroid.y\n\t\t\t\t}\n\t\t\t\tthis.patched.set(node.id, {\n\t\t\t\t\tid: node.id,\n\t\t\t\t\tcentroid: { x: x / members.length, y: y / members.length },\n\t\t\t\t\tcount: members.length,\n\t\t\t\t\tmembers,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tfor (const event of this.table.events) {\n\t\t\tpatch(event.result)\n\t\t\tfor (const child of event.children) patch(child)\n\t\t}\n\t}\n\n\tprivate resetVisible() {\n\t\tthis.visible = new Map()\n\t\tfor (const leaf of this.table.leaves) {\n\t\t\tthis.visible.set(leaf.id, leaf)\n\t\t}\n\t}\n}\n\n/** True iff every member id belonged to the same node of the previous partition. */\nfunction wasMergedTogether(\n\tmembers: readonly string[],\n\townerByMember: ReadonlyMap<string, string>\n): boolean {\n\tconst owner = ownerByMember.get(members[0])\n\tif (owner === undefined) return false\n\tfor (let i = 1; i < members.length; i++) {\n\t\tif (ownerByMember.get(members[i]) !== owner) return false\n\t}\n\treturn true\n}\n\nfunction seedCount(events: readonly MergeEvent[], zoom: number): number {\n\tlet lo = 0\n\tlet hi = events.length\n\twhile (lo < hi) {\n\t\tconst mid = (lo + hi) >> 1\n\t\tif (zoom <= seedThreshold(events[mid])) {\n\t\t\tlo = mid + 1\n\t\t} else {\n\t\t\thi = mid\n\t\t}\n\t}\n\treturn lo\n}\n\nfunction seedThreshold(event: MergeEvent): number {\n\treturn Math.sqrt(event.zMerge * event.zSplit)\n}\n\nfunction applyEvent(visible: Map<string, ClusterNode>, event: MergeEvent) {\n\tfor (const child of event.children) {\n\t\tvisible.delete(child.id)\n\t}\n\tvisible.set(event.result.id, event.result)\n}\n\nfunction unapplyEvent(visible: Map<string, ClusterNode>, event: MergeEvent) {\n\tvisible.delete(event.result.id)\n\tfor (const child of event.children) {\n\t\tvisible.set(child.id, child)\n\t}\n}\n\nfunction validateZoom(zoom: number) {\n\tif (!Number.isFinite(zoom) || zoom <= 0) {\n\t\tthrow new Error('zoom must be finite and greater than 0')\n\t}\n}\n"],
  "mappings": "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",
  "names": []
}
