{
  "version": 3,
  "sources": ["../../src/clustering/schedule.ts"],
  "sourcesContent": ["import type { ClusterNode, ContractedEvent, MergeEvent, RawMergeEvent } from './types'\n\nexport function contract(raw: readonly RawMergeEvent[], eps: number): ContractedEvent[] {\n\tif (!Number.isFinite(eps) || eps < 0) {\n\t\tthrow new Error('eps must be finite and greater than or equal to 0')\n\t}\n\n\tconst out: ContractedEvent[] = []\n\tlet i = 0\n\twhile (i < raw.length) {\n\t\tconst anchor = raw[i].z\n\t\tlet j = i\n\t\twhile (j + 1 < raw.length && raw[j + 1].z >= anchor / (1 + eps)) {\n\t\t\tj++\n\t\t}\n\n\t\tconst chains = contractWindow(raw.slice(i, j + 1), anchor)\n\t\tout.push(...chains)\n\t\ti = j + 1\n\t}\n\n\treturn out\n}\n\nexport function finalize(\n\tevents: readonly ContractedEvent[],\n\topts: { Tc: number; Tu: number; minZoom: number; maxZoom: number; maxSplitZoom: number }\n): MergeEvent[] {\n\tvalidateFinalizeOptions(opts)\n\n\tconst r = opts.Tu / opts.Tc\n\t// Every cluster must have split by maxSplitZoom, however close (or coincident) its members.\n\t// Capping zMerge at maxSplitZoom / r keeps the whole band below the cap, preserving\n\t// zSplit > zMerge and the table's sort order (min with a constant is order-preserving).\n\tconst zMergeCap = opts.maxSplitZoom / r\n\tconst out: MergeEvent[] = []\n\tfor (const event of events) {\n\t\tconst zMerge = Math.min(event.zMerge, zMergeCap)\n\t\tif (zMerge < opts.minZoom) break\n\t\tlet zSplit = zMerge * r\n\t\tif (zMerge < opts.maxZoom) {\n\t\t\tzSplit = Math.min(zSplit, opts.maxZoom)\n\t\t}\n\t\tout.push({\n\t\t\tzMerge,\n\t\t\tzSplit,\n\t\t\tchildren: event.children,\n\t\t\tresult: event.result,\n\t\t})\n\t}\n\treturn out\n}\n\nfunction contractWindow(events: readonly RawMergeEvent[], zMerge: number): ContractedEvent[] {\n\tconst uf = new ComponentUnionFind(events.length)\n\tconst resultToIndex = new Map<string, number>()\n\tfor (let i = 0; i < events.length; i++) {\n\t\tresultToIndex.set(events[i].result.id, i)\n\t}\n\n\tfor (let i = 0; i < events.length; i++) {\n\t\tfor (const child of events[i].children) {\n\t\t\tconst producer = resultToIndex.get(child.id)\n\t\t\tif (producer !== undefined) {\n\t\t\t\tuf.union(i, producer)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst byRoot = new Map<number, number[]>()\n\tfor (let i = 0; i < events.length; i++) {\n\t\tconst root = uf.find(i)\n\t\tconst list = byRoot.get(root)\n\t\tif (list) {\n\t\t\tlist.push(i)\n\t\t} else {\n\t\t\tbyRoot.set(root, [i])\n\t\t}\n\t}\n\n\treturn Array.from(byRoot.values())\n\t\t.map((indices) => contractChain(events, indices, zMerge))\n\t\t.sort((a, b) => compareNodesByMinMember(a.result, b.result))\n}\n\nfunction contractChain(\n\tevents: readonly RawMergeEvent[],\n\tindices: readonly number[],\n\tzMerge: number\n): ContractedEvent {\n\tconst produced = new Set<string>()\n\tconst consumedProduced = new Set<string>()\n\tfor (const index of indices) {\n\t\tproduced.add(events[index].result.id)\n\t}\n\tfor (const index of indices) {\n\t\tfor (const child of events[index].children) {\n\t\t\tif (produced.has(child.id)) consumedProduced.add(child.id)\n\t\t}\n\t}\n\n\tconst childrenById = new Map<string, ClusterNode>()\n\tfor (const index of indices) {\n\t\tfor (const child of events[index].children) {\n\t\t\tif (!produced.has(child.id)) childrenById.set(child.id, child)\n\t\t}\n\t}\n\n\tlet result: ClusterNode | undefined\n\tfor (const index of indices) {\n\t\tconst candidate = events[index].result\n\t\tif (!consumedProduced.has(candidate.id)) {\n\t\t\tif (!result || compareNodesByMinMember(candidate, result) < 0) result = candidate\n\t\t}\n\t}\n\n\treturn {\n\t\tzMerge,\n\t\tchildren: Array.from(childrenById.values()).sort(compareNodesByMinMember),\n\t\tresult: result!,\n\t}\n}\n\nfunction validateFinalizeOptions(opts: {\n\tTc: number\n\tTu: number\n\tminZoom: number\n\tmaxZoom: number\n\tmaxSplitZoom: number\n}) {\n\tif (!Number.isFinite(opts.maxSplitZoom) || opts.maxSplitZoom <= 0) {\n\t\tthrow new Error('maxSplitZoom must be finite and greater than 0')\n\t}\n\tif (!Number.isFinite(opts.Tc) || opts.Tc <= 0) {\n\t\tthrow new Error('Tc must be finite and greater than 0')\n\t}\n\tif (!Number.isFinite(opts.Tu) || opts.Tu <= opts.Tc) {\n\t\tthrow new Error('Tu must be finite and greater than Tc')\n\t}\n\tif (!Number.isFinite(opts.minZoom) || opts.minZoom <= 0) {\n\t\tthrow new Error('minZoom must be finite and greater than 0')\n\t}\n\tif (!Number.isFinite(opts.maxZoom) || opts.maxZoom <= opts.minZoom) {\n\t\tthrow new Error('maxZoom must be finite and greater than minZoom')\n\t}\n}\n\nfunction compareNodesByMinMember(a: ClusterNode, b: ClusterNode): number {\n\tconst aMin = a.members[0]\n\tconst bMin = b.members[0]\n\tif (aMin < bMin) return -1\n\tif (aMin > bMin) return 1\n\treturn 0\n}\n\nclass ComponentUnionFind {\n\tprivate readonly parent: Int32Array\n\n\tconstructor(n: number) {\n\t\tthis.parent = new Int32Array(n)\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tthis.parent[i] = i\n\t\t}\n\t}\n\n\tfind(index: number): number {\n\t\tlet root = index\n\t\twhile (this.parent[root] !== root) {\n\t\t\troot = this.parent[root]\n\t\t}\n\t\twhile (this.parent[index] !== index) {\n\t\t\tconst next = this.parent[index]\n\t\t\tthis.parent[index] = root\n\t\t\tindex = next\n\t\t}\n\t\treturn root\n\t}\n\n\tunion(a: number, b: number) {\n\t\tconst rootA = this.find(a)\n\t\tconst rootB = this.find(b)\n\t\tif (rootA !== rootB) this.parent[rootB] = rootA\n\t}\n}\n"],
  "mappings": "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",
  "names": []
}
