@mark1russell7/highways 0.1.0 → 0.1.2
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/build/index.d.ts +17 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +359 -28
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/bench/properties.ts +27 -2
- package/src/levels.ts +243 -0
- package/src/routers/sections.ts +17 -37
- package/src/segments.ts +26 -3
- package/src/visibility.ts +25 -3
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["turn","dedupe"],"sources":["../src/geom.ts","../src/grid.ts","../src/model.ts","../src/fixtures.ts","../src/plugs.ts","../src/curves.ts","../src/visibility.ts","../src/ways.ts","../src/segments.ts","../src/sections.ts","../src/routers/corners.ts","../src/routers/plugs.ts","../src/routers/sections.ts","../src/routers/shared.ts","../src/routers/straight.ts","../src/routers/trunks.ts","../src/routers/index.ts","../src/bench/properties.ts","../src/bench/quality.ts","../src/bench/run.ts"],"sourcesContent":["/** A point in the plane. */\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** A box with its top-left corner at (`x`, `y`). */\nexport interface Box {\n readonly x: number;\n readonly y: number;\n readonly w: number;\n readonly h: number;\n}\n\n/** This function gives the distance between two points. */\nexport function dist(a: Point, b: Point): number {\n const dx = a.x - b.x;\n const dy = a.y - b.y;\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/** This function gives the center of a box. */\nexport function center(b: Box): Point {\n return { x: b.x + b.w / 2, y: b.y + b.h / 2 };\n}\n\n/** This function gives a box that is larger by `m` on each side. A negative `m` makes the box smaller. */\nexport function inflate(b: Box, m: number): Box {\n return { x: b.x - m, y: b.y - m, w: Math.max(0, b.w + 2 * m), h: Math.max(0, b.h + 2 * m) };\n}\n\n/** This function gives the sum of the lengths of the segments of a polyline. */\nexport function polylineLength(p: readonly Point[]): number {\n let s = 0;\n for (let i = 1; i < p.length; i++) s += dist(p[i - 1]!, p[i]!);\n return s;\n}\n\nconst orient = (a: Point, b: Point, c: Point): number => (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n\n/**\n * This function tells if the segments `ab` and `cd` cross at one point inside both of them.\n * Segments that only touch at an end, or that are collinear, do not cross.\n */\nexport function segmentsCross(a: Point, b: Point, c: Point, d: Point): boolean {\n const d1 = orient(c, d, a);\n const d2 = orient(c, d, b);\n const d3 = orient(a, b, c);\n const d4 = orient(a, b, d);\n return d1 * d2 < 0 && d3 * d4 < 0;\n}\n\n/**\n * This function tells if the segment `ab` goes through the inside of the box.\n * The function clips the segment to the box (Liang-Barsky) and asks for a part longer than `eps`.\n */\nexport function segmentHitsBox(a: Point, b: Point, box: Box, eps = 1e-6): boolean {\n return segmentHitsRect(a, b, box.x, box.y, box.x + box.w, box.y + box.h, eps);\n}\n\n/** This function tells if the segment `ab` goes through the inside of the box from (`x0`, `y0`) to (`x1`, `y1`). */\nexport function segmentHitsRect(a: Point, b: Point, x0: number, y0: number, x1: number, y1: number, eps = 1e-6): boolean {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n let t0 = 0;\n let t1 = 1;\n if (dx === 0) {\n if (a.x <= x0 || a.x >= x1) return false;\n } else {\n const ta = (x0 - a.x) / dx;\n const tb = (x1 - a.x) / dx;\n t0 = Math.max(t0, Math.min(ta, tb));\n t1 = Math.min(t1, Math.max(ta, tb));\n if (t0 > t1) return false;\n }\n if (dy === 0) {\n if (a.y <= y0 || a.y >= y1) return false;\n } else {\n const ta = (y0 - a.y) / dy;\n const tb = (y1 - a.y) / dy;\n t0 = Math.max(t0, Math.min(ta, tb));\n t1 = Math.min(t1, Math.max(ta, tb));\n if (t0 > t1) return false;\n }\n return (t1 - t0) * Math.sqrt(dx * dx + dy * dy) > eps;\n}\n\n/** This function gives the distance from a point to a box. The distance is 0 when the point is in the box. */\nexport function pointBoxDistance(p: Point, b: Box): number {\n const qx = Math.max(b.x, Math.min(b.x + b.w, p.x));\n const qy = Math.max(b.y, Math.min(b.y + b.h, p.y));\n return Math.hypot(p.x - qx, p.y - qy);\n}\n\n/** This function gives the distance from a point to the segment `ab`. */\nexport function pointSegmentDistance(p: Point, a: Point, b: Point): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const l2 = dx * dx + dy * dy;\n const t = l2 === 0 ? 0 : Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / l2));\n return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy));\n}\n\n/** This function gives the distance from the segment `ab` to a box. The distance is 0 when they touch. */\nexport function segmentBoxDistance(a: Point, b: Point, box: Box): number {\n if (segmentHitsBox(a, b, box, 0) || pointBoxDistance(a, box) === 0 || pointBoxDistance(b, box) === 0) return 0;\n const corners: Point[] = [\n { x: box.x, y: box.y },\n { x: box.x + box.w, y: box.y },\n { x: box.x, y: box.y + box.h },\n { x: box.x + box.w, y: box.y + box.h },\n ];\n let d = Math.min(pointBoxDistance(a, box), pointBoxDistance(b, box));\n for (const c of corners) d = Math.min(d, pointSegmentDistance(c, a, b));\n return d;\n}\n\n/**\n * This function gives the turn at each inner vertex of a polyline, in radians, from -π to π.\n * A positive turn is counterclockwise in a frame with the y axis up. The function skips segments shorter than `eps`.\n */\nexport function turns(p: readonly Point[], eps = 1e-9): number[] {\n const q: Point[] = [];\n for (const v of p) if (q.length === 0 || dist(q[q.length - 1]!, v) > eps) q.push(v);\n const out: number[] = [];\n for (let i = 1; i + 1 < q.length; i++) {\n const a = q[i - 1]!;\n const b = q[i]!;\n const c = q[i + 1]!;\n const cr = (b.x - a.x) * (c.y - b.y) - (b.y - a.y) * (c.x - b.x);\n const dt = (b.x - a.x) * (c.x - b.x) + (b.y - a.y) * (c.y - b.y);\n out.push(Math.atan2(cr, dt));\n }\n return out;\n}\n\n/** This function counts the vertices of a polyline where the direction changes by more than `minTurn` radians. */\nexport function bendCount(p: readonly Point[], minTurn = 0.05): number {\n return turns(p).filter((t) => Math.abs(t) > minTurn).length;\n}\n\n/**\n * This function counts the inflections of a polyline: the changes of the sign of the turn.\n * A turn smaller than `minTurn` radians does not count. Thus a straight part between two turns keeps their signs.\n */\nexport function inflectionCount(p: readonly Point[], minTurn = 1e-3): number {\n let n = 0;\n let last = 0;\n for (const t of turns(p)) {\n if (Math.abs(t) <= minTurn) continue;\n const s = Math.sign(t);\n if (last !== 0 && s !== last) n++;\n last = s;\n }\n return n;\n}\n\n/**\n * This function gives the discrete Fréchet distance between two polylines (Eiter and Mannila, 1994).\n * The cost is O(|p|·|q|) in time and O(|q|) in memory.\n */\nexport function frechet(p: readonly Point[], q: readonly Point[]): number {\n if (p.length === 0 || q.length === 0) return p.length === q.length ? 0 : Infinity;\n let prev = new Float64Array(q.length);\n let cur = new Float64Array(q.length);\n for (let i = 0; i < p.length; i++) {\n for (let j = 0; j < q.length; j++) {\n const d = dist(p[i]!, q[j]!);\n if (i === 0 && j === 0) cur[j] = d;\n else if (i === 0) cur[j] = Math.max(cur[j - 1]!, d);\n else if (j === 0) cur[j] = Math.max(prev[j]!, d);\n else cur[j] = Math.max(Math.min(prev[j]!, prev[j - 1]!, cur[j - 1]!), d);\n }\n [prev, cur] = [cur, prev];\n }\n return prev[q.length - 1]!;\n}\n","import type { Box, Point } from \"./geom.ts\";\n\n/**\n * A uniform grid of buckets over the plane. A box item goes into each bucket that the box touches.\n * A segment item goes only into the buckets along the segment, so a long diagonal segment stays cheap.\n * A query gives each item in the buckets that it touches, one time each.\n */\nexport class Grid<T> {\n readonly #cell: number;\n readonly #buckets = new Map<number, number[]>();\n readonly #items: T[] = [];\n readonly #ids = new Map<T, number>();\n // The stamp of the last query that gave each item, by the index of the item.\n #seen = new Int32Array(16);\n #stamp = 0;\n\n /** This constructor makes an empty grid with square buckets of side `cell`. */\n constructor(cell: number) {\n this.#cell = Math.max(1e-9, cell);\n }\n\n #key(i: number, j: number): number {\n // The key packs the two bucket indices into one number. Each index stays within ±2^20.\n return (i + 1_048_576) * 2_097_152 + (j + 1_048_576);\n }\n\n #id(item: T): number {\n let id = this.#ids.get(item);\n if (id === undefined) {\n id = this.#items.length;\n this.#ids.set(item, id);\n this.#items.push(item);\n if (id >= this.#seen.length) {\n const seen = new Int32Array(this.#seen.length * 2);\n seen.set(this.#seen);\n this.#seen = seen;\n }\n }\n return id;\n }\n\n #put(id: number, x0: number, y0: number, x1: number, y1: number): void {\n const c = this.#cell;\n const i1 = Math.floor(x1 / c);\n const j1 = Math.floor(y1 / c);\n for (let i = Math.floor(x0 / c); i <= i1; i++) {\n for (let j = Math.floor(y0 / c); j <= j1; j++) {\n const key = this.#key(i, j);\n const list = this.#buckets.get(key);\n if (list === undefined) this.#buckets.set(key, [id]);\n else if (list[list.length - 1] !== id) list.push(id);\n }\n }\n }\n\n #take(stamp: number, x0: number, y0: number, x1: number, y1: number, visit: (item: T) => void): void {\n const c = this.#cell;\n const i1 = Math.floor(x1 / c);\n const j1 = Math.floor(y1 / c);\n const seen = this.#seen;\n for (let i = Math.floor(x0 / c); i <= i1; i++) {\n for (let j = Math.floor(y0 / c); j <= j1; j++) {\n const list = this.#buckets.get(this.#key(i, j));\n if (list === undefined) continue;\n for (const id of list) {\n if (seen[id] === stamp) continue;\n seen[id] = stamp;\n visit(this.#items[id]!);\n }\n }\n }\n }\n\n // The buckets along a segment, widened by `margin`: the boxes of steps of at most half a bucket.\n #segment(a: Point, b: Point, margin: number, each: (x0: number, y0: number, x1: number, y1: number) => void): void {\n const n = Math.max(1, Math.ceil(Math.hypot(b.x - a.x, b.y - a.y) / (this.#cell / 2)));\n let px = a.x;\n let py = a.y;\n for (let k = 1; k <= n; k++) {\n const qx = k === n ? b.x : a.x + ((b.x - a.x) * k) / n;\n const qy = k === n ? b.y : a.y + ((b.y - a.y) * k) / n;\n each(Math.min(px, qx) - margin, Math.min(py, qy) - margin, Math.max(px, qx) + margin, Math.max(py, qy) + margin);\n px = qx;\n py = qy;\n }\n }\n\n /** This method adds an item with its bounding box. */\n add(item: T, b: Box): void {\n this.#put(this.#id(item), b.x, b.y, b.x + b.w, b.y + b.h);\n }\n\n /** This method adds the segment `ab` as an item. */\n addSegment(item: T, a: Point, b: Point): void {\n const id = this.#id(item);\n this.#segment(a, b, 0, (x0, y0, x1, y1) => this.#put(id, x0, y0, x1, y1));\n }\n\n /** This method gives each item whose buckets touch the box to `visit`, one time each. */\n query(b: Box, visit: (item: T) => void): void {\n this.#take(++this.#stamp, b.x, b.y, b.x + b.w, b.y + b.h, visit);\n }\n\n /** This method gives each item whose buckets come within `margin` of the segment `ab` to `visit`, one time each. */\n querySegment(a: Point, b: Point, margin: number, visit: (item: T) => void): void {\n const stamp = ++this.#stamp;\n this.#segment(a, b, margin, (x0, y0, x1, y1) => this.#take(stamp, x0, y0, x1, y1, visit));\n }\n}\n\n/** This function gives the bounding box of the segment `ab`. */\nexport function segmentBounds(a: Point, b: Point): Box {\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n return { x, y, w: Math.abs(a.x - b.x), h: Math.abs(a.y - b.y) };\n}\n","import type { Box, Point } from \"./geom.ts\";\n\n/** A side of a node box. */\nexport type Side = \"north\" | \"east\" | \"south\" | \"west\";\n\n/**\n * A plug of a node: a place where edges go into the node.\n * A plug with `at` is fixed. The router does not move it. A plug without `at` is free: the router places it.\n */\nexport interface Port {\n readonly id: string;\n /** This point is the fixed place of the plug, relative to the top-left corner of the node box. */\n readonly at?: Point;\n /** This side is where a free plug goes. Without it, the router picks the side. */\n readonly side?: Side;\n}\n\n/** A node: a box that routes must not go through. */\nexport interface Node {\n readonly id: string;\n readonly box: Box;\n readonly ports?: readonly Port[];\n}\n\n/** One end of an edge: a node, and optionally one plug of that node. */\nexport interface End {\n readonly node: string;\n readonly port?: string;\n}\n\n/** An edge between two nodes. `data` is free for the grouping rules. */\nexport interface Edge {\n readonly id: string;\n readonly source: End;\n readonly target: End;\n readonly data?: Readonly<Record<string, unknown>>;\n}\n\n/** The input of a router. */\nexport interface Graph {\n readonly nodes: readonly Node[];\n readonly edges: readonly Edge[];\n}\n\n/** The route of one edge: a polyline from the source plug to the target plug, in absolute coordinates. */\nexport interface Route {\n readonly edge: string;\n readonly points: readonly Point[];\n}\n\n/**\n * One zoom level of a result. Each shown item is a node or a group of nodes.\n * Each link joins two shown items and carries the count of the edges that it stands for.\n */\nexport interface Level {\n readonly depth: number;\n readonly items: readonly LevelItem[];\n readonly links: readonly LevelLink[];\n}\n\n/** A shown item of a level: one node, or a group that stands for its nodes. */\nexport interface LevelItem {\n readonly id: string;\n readonly box: Box;\n readonly nodes: readonly string[];\n}\n\n/** A link of a level: the edges between two shown items, drawn as one path. */\nexport interface LevelLink {\n readonly source: string;\n readonly target: string;\n readonly count: number;\n readonly points: readonly Point[];\n}\n\n/** The output of a router. `levels` is present when the router makes zoom levels. */\nexport interface Result {\n readonly routes: readonly Route[];\n readonly levels?: readonly Level[];\n readonly bundles?: readonly Bundle[];\n /** The stretches of way that several routes share, if the router gives them. */\n readonly runs?: readonly SharedRun[];\n}\n\n/**\n * A bundle: edges from one node that share one plug and one trunk. Then the edges fan out to their targets.\n * A renderer draws a bundle as one fat edge with a count, or as one lane for each edge.\n */\nexport interface Bundle {\n readonly id: string;\n /** The key that the grouping rule gave each edge of the bundle. */\n readonly key: string;\n /** The node where the edges share their plug. */\n readonly node: string;\n /** The edges in lane order. Lane 0 turns most to the left of the trunk, in a frame with the y axis down. */\n readonly edges: readonly string[];\n /** The shared start of each route of the bundle, from the plug to the split point. */\n readonly trunk: readonly Point[];\n}\n\n/**\n * A stretch of way that several routes share, with the same points. Each route of `edges` has `points` in it,\n * in this order or in the reverse order. A renderer draws a run as one fat line, or as one lane for each edge.\n */\nexport interface SharedRun {\n readonly id: string;\n /** The key of the grouping rule of the edges. */\n readonly key: string;\n readonly points: readonly Point[];\n /** The edges in lane order. Lane 0 is on the left of the run, from its first point to its last. The y axis points down. */\n readonly edges: readonly string[];\n}\n\n/** A grouping rule gives each edge a key. The edges from one plug with one key make a bundle. An edge without a key stays alone. */\nexport type GroupRule = (edge: Edge) => string | undefined;\n\n/** A router: a strategy with a name. The same input must give the same result. */\nexport interface Router {\n readonly name: string;\n /** The benchmark skips a fixture with more nodes than this. Without it, the router takes each fixture. */\n readonly maxNodes?: number;\n route(graph: Graph): Result;\n}\n\n/** This function gives a map from the id of each node to the node. */\nexport function nodeIndex(g: Graph): Map<string, Node> {\n const m = new Map<string, Node>();\n for (const n of g.nodes) m.set(n.id, n);\n return m;\n}\n\n/** This function gives the absolute place of a fixed plug, or `undefined` for a free plug or no plug. */\nexport function fixedPortPoint(node: Node, end: End): Point | undefined {\n if (end.port === undefined) return undefined;\n const p = node.ports?.find((q) => q.id === end.port);\n if (p?.at === undefined) return undefined;\n return { x: node.box.x + p.at.x, y: node.box.y + p.at.y };\n}\n","import type { Box, Point } from \"./geom.ts\";\nimport { Grid } from \"./grid.ts\";\nimport type { Edge, Graph, Node, Port, Side } from \"./model.ts\";\n\n/** This function gives a seeded random source with values in [0, 1) (mulberry32). */\nexport function rng(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = a;\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/**\n * The ways a fixture puts its nodes and picks its edges. In `collections`, each cluster is one collection,\n * and some nodes link to many nodes of one other collection (a fan-out).\n */\nexport type FixtureKind = \"uniform\" | \"clustered\" | \"grid\" | \"hubs\" | \"collections\";\n\n/** The parameters of a generated graph. */\nexport interface FixtureSpec {\n readonly name: string;\n readonly kind: FixtureKind;\n readonly nodes: number;\n /** The number of edges is about `nodes × edgesPerNode`. */\n readonly edgesPerNode: number;\n readonly seed: number;\n /** This share of the edges, from 0 to 1, joins a node near the source. */\n readonly locality?: number;\n /** This share of the nodes, from 0 to 1, has one fixed plug that its outgoing edges use. */\n readonly fixedPorts?: number;\n}\n\n/** The fixtures of the benchmark, from 10 to 100 000 nodes. */\nexport const FIXTURES: readonly FixtureSpec[] = [\n { name: \"tiny-uniform\", kind: \"uniform\", nodes: 10, edgesPerNode: 1.5, seed: 1 },\n { name: \"small-clustered\", kind: \"clustered\", nodes: 100, edgesPerNode: 2, seed: 2, fixedPorts: 0.2 },\n { name: \"grid-400\", kind: \"grid\", nodes: 400, edgesPerNode: 2, seed: 3 },\n { name: \"mid-uniform\", kind: \"uniform\", nodes: 1000, edgesPerNode: 2, seed: 4 },\n { name: \"mid-clustered\", kind: \"clustered\", nodes: 1000, edgesPerNode: 3, seed: 5, fixedPorts: 0.2 },\n { name: \"mid-hubs\", kind: \"hubs\", nodes: 1000, edgesPerNode: 2, seed: 6 },\n { name: \"mid-fanout\", kind: \"collections\", nodes: 1000, edgesPerNode: 2, seed: 9 },\n { name: \"large-clustered\", kind: \"clustered\", nodes: 10_000, edgesPerNode: 3, seed: 7 },\n { name: \"huge-clustered\", kind: \"clustered\", nodes: 100_000, edgesPerNode: 2, seed: 8 },\n];\n\nconst COLLECTIONS = [\"users\", \"modes\", \"speeds\", \"scores\", \"teams\"] as const;\nconst SIDES: readonly Side[] = [\"north\", \"east\", \"south\", \"west\"];\nconst GAP = 12;\nconst SPACING = 90;\n\n/**\n * This function makes the graph of a fixture. The same spec always gives the same graph.\n * Node boxes do not overlap, and a gap of 12 units stays between them.\n */\nexport function makeFixture(spec: FixtureSpec): Graph {\n const R = rng(spec.seed * 2654435761 + spec.nodes);\n const gauss = (): number => Math.sqrt(-2 * Math.log(R() + 1e-12)) * Math.cos(2 * Math.PI * R());\n const side = Math.sqrt(spec.nodes) * SPACING;\n const grid = new Grid<Box>(SPACING);\n const nodes: Node[] = [];\n const clusterOf: number[] = [];\n const free = (b: Box): boolean => {\n let ok = true;\n const g: Box = { x: b.x - GAP, y: b.y - GAP, w: b.w + 2 * GAP, h: b.h + 2 * GAP };\n grid.query(g, (o) => {\n if (ok && o.x < g.x + g.w && g.x < o.x + o.w && o.y < g.y + g.h && g.y < o.y + o.h) ok = false;\n });\n return ok;\n };\n const centers: Point[] = Array.from({ length: Math.max(3, Math.round(Math.sqrt(spec.nodes) / 3)) }, () => ({\n x: side * (0.1 + 0.8 * R()),\n y: side * (0.1 + 0.8 * R()),\n }));\n const spread = side / (2.5 * Math.sqrt(centers.length));\n const cols = Math.ceil(Math.sqrt(spec.nodes));\n let tries = 0;\n while (nodes.length < spec.nodes && tries++ < spec.nodes * 200) {\n const w = 30 + Math.floor(R() * 30);\n const h = 18 + Math.floor(R() * 12);\n let cx: number;\n let cy: number;\n let cluster = -1;\n if (spec.kind === \"grid\") {\n const i = nodes.length;\n cx = ((i % cols) + 0.5) * SPACING;\n cy = (Math.floor(i / cols) + 0.5) * SPACING;\n } else if (spec.kind === \"clustered\" || spec.kind === \"collections\") {\n cluster = Math.floor(R() * centers.length);\n const c = centers[cluster]!;\n cx = c.x + gauss() * spread;\n cy = c.y + gauss() * spread;\n } else {\n cx = R() * side;\n cy = R() * side;\n }\n const box: Box = { x: Math.round(cx - w / 2), y: Math.round(cy - h / 2), w, h };\n if (spec.kind !== \"grid\" && !free(box)) continue;\n grid.add(box, box);\n clusterOf.push(cluster);\n const id = `n${nodes.length}`;\n if (R() < (spec.fixedPorts ?? 0)) {\n const s = SIDES[Math.floor(R() * 4)]!;\n const t = 0.2 + 0.6 * R();\n const at: Point =\n s === \"north\" ? { x: w * t, y: 0 } : s === \"south\" ? { x: w * t, y: h } : s === \"west\" ? { x: 0, y: h * t } : { x: w, y: h * t };\n const ports: Port[] = [{ id: \"out\", at: { x: Math.round(at.x), y: Math.round(at.y) } }];\n nodes.push({ id, box, ports });\n } else nodes.push({ id, box });\n }\n return { nodes, edges: makeEdges(spec, nodes, clusterOf, R) };\n}\n\nfunction makeEdges(spec: FixtureSpec, nodes: readonly Node[], clusterOf: readonly number[], R: () => number): Edge[] {\n const n = nodes.length;\n if (n < 2) return [];\n const locality = spec.locality ?? 0.65;\n const near = new Grid<number>(SPACING * 2);\n nodes.forEach((v, i) => near.add(i, v.box));\n const kindOf =\n spec.kind === \"collections\"\n ? clusterOf.map((c) => `${COLLECTIONS[c % COLLECTIONS.length]!}-${c}`)\n : nodes.map(() => COLLECTIONS[Math.floor(R() * COLLECTIONS.length)]!);\n // Hubs: a few nodes get most of the far edges (preferential attachment by a power law).\n const pickFar = (): number => (spec.kind === \"hubs\" ? Math.floor(n * R() ** 3) : Math.floor(R() * n));\n const target = Math.round(n * spec.edgesPerNode);\n const seen = new Set<string>();\n const edges: Edge[] = [];\n const add = (u: number, v: number): void => {\n const key = u < v ? `${u}-${v}` : `${v}-${u}`;\n if (u === v || seen.has(key)) return;\n seen.add(key);\n const src = nodes[u]!;\n edges.push({\n id: `e${edges.length}`,\n source: src.ports ? { node: src.id, port: \"out\" } : { node: src.id },\n target: { node: nodes[v]!.id },\n data: { collection: kindOf[v]! },\n });\n };\n if (spec.kind === \"collections\") {\n // Six of ten edges are fan-outs: a node links to 4 to 15 nodes of one other cluster.\n const members = new Map<number, number[]>();\n clusterOf.forEach((c, i) => {\n const list = members.get(c);\n if (list) list.push(i);\n else members.set(c, [i]);\n });\n const clusters = [...members.keys()].sort((a, c) => a - c);\n let rounds = 0;\n while (edges.length < target * 0.6 && clusters.length > 1 && rounds++ < target) {\n const u = Math.floor(R() * n);\n const others = clusters.filter((c) => c !== clusterOf[u]);\n const pool = members.get(others[Math.floor(R() * others.length)]!)!;\n const fan = 4 + Math.floor(R() * 12);\n for (let i = 0; i < fan; i++) add(u, pool[Math.floor(R() * pool.length)]!);\n }\n }\n let tries = 0;\n while (edges.length < target && tries++ < target * 30) {\n const u = Math.floor(R() * n);\n let v = -1;\n if (R() < locality) {\n const b = nodes[u]!.box;\n const cand: number[] = [];\n for (let r = SPACING; cand.length < 8 && r < SPACING * 64; r *= 2) {\n cand.length = 0;\n near.query({ x: b.x - r, y: b.y - r, w: b.w + 2 * r, h: b.h + 2 * r }, (i) => {\n if (i !== u) cand.push(i);\n });\n }\n cand.sort((a, c) => a - c);\n if (cand.length) v = cand[Math.floor(R() * cand.length)]!;\n } else v = pickFar();\n if (v >= 0) add(u, v);\n }\n return edges;\n}\n","import { center, type Box, type Point } from \"./geom.ts\";\nimport { fixedPortPoint, type End, type Node, type Side } from \"./model.ts\";\n\n/** A plug: the point where a route leaves or enters a node, and the outward normal of its side. */\nexport interface Plug {\n readonly point: Point;\n readonly normal: Point;\n}\n\n/** The outward normal of each side, in a frame with the y axis down. */\nexport const SIDE_NORMAL: Readonly<Record<Side, Point>> = {\n north: { x: 0, y: -1 },\n east: { x: 1, y: 0 },\n south: { x: 0, y: 1 },\n west: { x: -1, y: 0 },\n};\n\n/** This function gives the side of the box that is nearest to the point. */\nexport function nearestSide(box: Box, p: Point): Side {\n const d: [Side, number][] = [\n [\"north\", Math.abs(p.y - box.y)],\n [\"east\", Math.abs(box.x + box.w - p.x)],\n [\"south\", Math.abs(box.y + box.h - p.y)],\n [\"west\", Math.abs(p.x - box.x)],\n ];\n let best = d[0]!;\n for (const x of d) if (x[1] < best[1]) best = x;\n return best[0];\n}\n\n/**\n * This function gives the side that faces `toward`: the side of the larger component of the direction from the center.\n * Thus the angle between the normal of the side and that direction is 45° or less.\n */\nexport function sideToward(box: Box, toward: Point): Side {\n const c = center(box);\n const dx = toward.x - c.x;\n const dy = toward.y - c.y;\n if (Math.abs(dx) >= Math.abs(dy)) return dx >= 0 ? \"east\" : \"west\";\n return dy >= 0 ? \"south\" : \"north\";\n}\n\n/**\n * This function gives the point on a side of the box that is nearest to the line from the center to `toward`.\n * The point stays away from the corners by `inset`, or by a quarter of the side when the side is short.\n */\nexport function pointOnSide(box: Box, side: Side, toward: Point, inset = 6): Point {\n const c = center(box);\n const dx = toward.x - c.x;\n const dy = toward.y - c.y;\n const clamp = (v: number, lo: number, len: number): number => {\n const m = Math.min(inset, len / 4);\n return Math.max(lo + m, Math.min(lo + len - m, v));\n };\n if (side === \"east\" || side === \"west\") {\n const x = side === \"east\" ? box.x + box.w : box.x;\n const y = dx === 0 ? c.y : c.y + (dy * (x - c.x)) / dx;\n return { x, y: clamp(y, box.y, box.h) };\n }\n const y = side === \"south\" ? box.y + box.h : box.y;\n const x = dy === 0 ? c.x : c.x + (dx * (y - c.y)) / dy;\n return { x: clamp(x, box.x, box.w), y };\n}\n\n/**\n * This function places the plug of one end of an edge. A fixed plug stays at its point. A plug with a side stays on that side.\n * The router places a free plug on the side that faces `toward`.\n */\nexport function placePlug(node: Node, end: End, toward: Point): Plug {\n const fixed = fixedPortPoint(node, end);\n const port = end.port === undefined ? undefined : node.ports?.find((p) => p.id === end.port);\n if (fixed) return { point: fixed, normal: SIDE_NORMAL[port?.side ?? nearestSide(node.box, fixed)] };\n const side = port?.side ?? sideToward(node.box, toward);\n return { point: pointOnSide(node.box, side, toward), normal: SIDE_NORMAL[side] };\n}\n","import { dist, type Point } from \"./geom.ts\";\n\n/** The options of the inflection rule. */\nexport interface InflectionOptions {\n /** The half width of the axis and diagonal bands, in radians. The default is 7°. */\n readonly tol?: number;\n /** The number of segments of the curve. The default is 24. */\n readonly samples?: number;\n /** The largest angle between the tangent and the chord, in radians. The default is 1.35 (approximately 77°). */\n readonly maxAngle?: number;\n}\n\n/**\n * This function gives the number of inflections that the rule asks for a chord at the angle `angle` (radians).\n * It gives 0 near an axis, 1 near a diagonal and 2 between them. The bands are `tol` wide on each side.\n */\nexport function inflectionSector(angle: number, tol: number = (7 * Math.PI) / 180): 0 | 1 | 2 {\n const q = Math.PI / 2;\n const mod = ((angle % q) + q) % q;\n if (mod < tol || q - mod < tol) return 0;\n if (Math.abs(mod - q / 2) < tol) return 1;\n return 2;\n}\n\n/**\n * This function draws the curve of the inflection rule from the plug `p0` to `target`.\n * The curve leaves `p0` along `normal`. In the frame of the chord, its side offset f has f(0) = f(L) = 0 and f'(0) = tan θ.\n * Here θ is the angle from the chord to the normal. A polynomial of degree 2, 3 or 4 gives 0, 1 or 2 inflections,\n * at 1/2, or at 1/3 and 2/3, of the chord.\n */\nexport function inflectionCurve(p0: Point, normal: Point, target: Point, options: InflectionOptions = {}): Point[] {\n const L = dist(p0, target);\n if (L === 0) return [p0, target];\n const ux = (target.x - p0.x) / L;\n const uy = (target.y - p0.y) / L;\n const k = inflectionSector(Math.atan2(uy, ux), options.tol);\n const maxAngle = options.maxAngle ?? 1.35;\n const th = -Math.atan2(normal.x * uy - normal.y * ux, normal.x * ux + normal.y * uy);\n const d = Math.tan(Math.max(-maxAngle, Math.min(maxAngle, th)));\n const f =\n k === 0\n ? (s: number): number => (-d / L) * s * s + d * s\n : k === 1\n ? (s: number): number => ((12 * d) / (L * L)) * (s ** 3 / 6 - (L * s * s) / 4) + d * s\n : (s: number): number => ((-36 * d) / L ** 3) * (s ** 4 / 12 - (L * s ** 3) / 6 + (L * L * s * s) / 9) + d * s;\n const n = Math.max(2, options.samples ?? 24);\n const out: Point[] = [];\n for (let i = 0; i <= n; i++) {\n if (i === n) {\n out.push(target);\n break;\n }\n const s = (L * i) / n;\n const o = f(s);\n out.push({ x: p0.x + ux * s - uy * o, y: p0.y + uy * s + ux * o });\n }\n out[0] = p0;\n return out;\n}\n\n/**\n * This function rounds each inner vertex of a polyline with a quadratic Bézier curve.\n * The curve starts and ends at most `radius` from the vertex, and at most half of each segment. The ends of the polyline stay.\n */\nexport function roundCorners(p: readonly Point[], radius: number, steps = 4): Point[] {\n if (p.length < 3 || radius <= 0) return [...p];\n const out: Point[] = [p[0]!];\n for (let i = 1; i + 1 < p.length; i++) {\n const a = p[i - 1]!;\n const v = p[i]!;\n const b = p[i + 1]!;\n const la = dist(a, v);\n const lb = dist(v, b);\n const r = Math.min(radius, la / 2, lb / 2);\n if (r <= 0) {\n out.push(v);\n continue;\n }\n const p1 = { x: v.x + ((a.x - v.x) * r) / la, y: v.y + ((a.y - v.y) * r) / la };\n const p2 = { x: v.x + ((b.x - v.x) * r) / lb, y: v.y + ((b.y - v.y) * r) / lb };\n for (let k = 0; k <= steps; k++) {\n const t = k / steps;\n const u = 1 - t;\n out.push({ x: u * u * p1.x + 2 * u * t * v.x + t * t * p2.x, y: u * u * p1.y + 2 * u * t * v.y + t * t * p2.y });\n }\n }\n out.push(p[p.length - 1]!);\n return out;\n}\n","import { dist, inflate, segmentHitsRect, type Point } from \"./geom.ts\";\nimport { Grid } from \"./grid.ts\";\nimport type { Node } from \"./model.ts\";\n\n/** The nodes as obstacles, with a grid for fast tests. */\nexport class Obstacles {\n readonly #grid: Grid<Node>;\n\n /** This constructor indexes the boxes of the nodes. */\n constructor(nodes: readonly Node[], cell: number) {\n this.#grid = new Grid<Node>(cell);\n for (const n of nodes) this.#grid.add(n, n.box);\n }\n\n /** This method tells if the segment `ab` stays out of each box, made larger by `pad`. The nodes in `skip` do not count. */\n clear(a: Point, b: Point, pad: number, skip?: ReadonlySet<Node>): boolean {\n let ok = true;\n this.#grid.querySegment(a, b, pad, (n) => {\n if (ok && !skip?.has(n)) {\n const x = n.box;\n if (segmentHitsRect(a, b, x.x - pad, x.y - pad, x.x + x.w + pad, x.y + x.h + pad)) ok = false;\n }\n });\n return ok;\n }\n\n /** This method tells if the polyline stays out of each box, made larger by `pad`. The nodes in `skip` do not count. */\n clearPath(p: readonly Point[], pad: number, skip?: ReadonlySet<Node>): boolean {\n for (let i = 1; i < p.length; i++) if (!this.clear(p[i - 1]!, p[i]!, pad, skip)) return false;\n return true;\n }\n\n /** This method tells if the point is inside a box, made larger by `pad`. The node `skip` does not count. */\n inside(p: Point, pad: number, skip?: Node): boolean {\n let hit = false;\n this.#grid.query({ x: p.x, y: p.y, w: 0, h: 0 }, (n) => {\n if (!hit && n !== skip) {\n const b = n.box;\n hit = p.x > b.x - pad && p.x < b.x + b.w + pad && p.y > b.y - pad && p.y < b.y + b.h + pad;\n }\n });\n return hit;\n }\n}\n\n/** The options of the corner graph. */\nexport interface CornerGraphOptions {\n /** The distance from a box to its corners. */\n readonly margin: number;\n /** The number of visible neighbours of each corner. */\n readonly k: number;\n /**\n * The spacing of a lattice of free points over the plane, in units of the mean node size. The default is 3, and 0 turns it off.\n * The lattice links groups of nodes across empty space. Without it, the nearest corners of a group are all in that group.\n */\n readonly lattice?: number;\n}\n\n/**\n * A sparse visibility graph. Its vertices are the corners of the boxes, made larger by `margin`.\n * Each corner links to its `k` nearest corners that it can see. A lattice of free points links the groups of nodes.\n * A path goes from corner to corner around the boxes.\n * The obstacle test uses half of the margin, so a path keeps a clearance of at least half of the margin.\n */\nexport class CornerGraph {\n readonly points: Point[] = [];\n readonly #adj: number[][] = [];\n // The length of each link, in the order of #adj.\n readonly #len: number[][] = [];\n readonly #obstacles: Obstacles;\n readonly #pointGrid: Grid<number>;\n readonly #cell: number;\n readonly #pad: number;\n readonly #k: number;\n // The work arrays of A*, made once and cleared by a stamp.\n #g = new Float64Array(0);\n #parent = new Int32Array(0);\n #open = new Int32Array(0);\n #closed = new Int32Array(0);\n #stamp = 0;\n // The stamp of the last call of nearestVisible that tested each corner.\n #tested = new Int32Array(0);\n #testStamp = 0;\n\n /** This constructor makes the graph of the nodes. */\n constructor(nodes: readonly Node[], obstacles: Obstacles, options: CornerGraphOptions) {\n this.#obstacles = obstacles;\n this.#pad = options.margin / 2;\n this.#k = options.k;\n let size = 0;\n for (const n of nodes) size += (n.box.w + n.box.h) / 2;\n this.#cell = Math.max(1, size / Math.max(1, nodes.length) + 2 * options.margin);\n this.#pointGrid = new Grid<number>(this.#cell);\n for (const n of nodes) {\n const b = inflate(n.box, options.margin);\n for (const c of [\n { x: b.x, y: b.y },\n { x: b.x + b.w, y: b.y },\n { x: b.x + b.w, y: b.y + b.h },\n { x: b.x, y: b.y + b.h },\n ]) {\n if (!obstacles.inside(c, this.#pad)) this.#addPoint(c);\n }\n }\n const spacing = (options.lattice ?? 3) * this.#cell;\n if (spacing > 0 && nodes.length > 0) {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const n of nodes) {\n x0 = Math.min(x0, n.box.x);\n y0 = Math.min(y0, n.box.y);\n x1 = Math.max(x1, n.box.x + n.box.w);\n y1 = Math.max(y1, n.box.y + n.box.h);\n }\n for (let x = x0 - spacing / 2; x <= x1 + spacing; x += spacing) {\n for (let y = y0 - spacing / 2; y <= y1 + spacing; y += spacing) {\n const c = { x, y };\n if (!obstacles.inside(c, options.margin)) this.#addPoint(c);\n }\n }\n }\n const links: Set<number>[] = this.points.map(() => new Set<number>());\n for (let i = 0; i < this.points.length; i++) {\n for (const j of this.nearestVisible(this.points[i]!, this.#k, i)) {\n links[i]!.add(j);\n links[j]!.add(i);\n }\n }\n links.forEach((s, i) => {\n const adj = [...s].sort((a, b) => a - b);\n this.#adj.push(adj);\n this.#len.push(adj.map((j) => dist(this.points[i]!, this.points[j]!)));\n });\n }\n\n #addPoint(c: Point): void {\n this.#pointGrid.add(this.points.length, { x: c.x, y: c.y, w: 0, h: 0 });\n this.points.push(c);\n }\n\n /** This method gives the number of links of the graph. */\n get linkCount(): number {\n let n = 0;\n for (const a of this.#adj) n += a.length;\n return n / 2;\n }\n\n /** This method gives the index of the corner nearest to `p`, seen or not, or -1 when the graph has no corner near it. */\n nearest(p: Point): number {\n for (let r = this.#cell; r <= this.#cell * 64; r *= 2) {\n let best = -1;\n let bestD = Infinity;\n this.#pointGrid.query({ x: p.x - r, y: p.y - r, w: 2 * r, h: 2 * r }, (j) => {\n const d = dist(p, this.points[j]!);\n if (d < bestD || (d === bestD && j < best)) {\n bestD = d;\n best = j;\n }\n });\n // A corner beyond r can be nearer than a corner in a corner of the square. Within r, none is.\n if (best >= 0 && bestD <= r) return best;\n }\n return -1;\n }\n\n /** This method gives at most `k` corners that `p` can see, nearest first. The corner `self` does not count. */\n nearestVisible(p: Point, k: number, self = -1): number[] {\n const out: number[] = [];\n if (this.#tested.length < this.points.length) this.#tested = new Int32Array(this.points.length);\n const tested = this.#tested;\n const stamp = ++this.#testStamp;\n for (let r = this.#cell; r <= this.#cell * 8; r *= 2) {\n const cands: [number, number][] = [];\n this.#pointGrid.query({ x: p.x - r, y: p.y - r, w: 2 * r, h: 2 * r }, (j) => {\n if (j !== self && tested[j] !== stamp) cands.push([dist(p, this.points[j]!), j]);\n });\n cands.sort((a, b) => a[0] - b[0] || a[1] - b[1]);\n for (const [d, j] of cands) {\n // A corner beyond r can be nearer than a corner of the next ring, so it waits for that ring.\n if (d > r) break;\n tested[j] = stamp;\n if (this.#obstacles.clear(p, this.points[j]!, this.#pad)) out.push(j);\n if (out.length >= k) return out;\n }\n }\n return out;\n }\n\n /**\n * This method gives a shortest path from `from` to `to` in the graph (A*), with the two points as its ends.\n * It gives `undefined` when the graph links no corner near `from` to a corner near `to`.\n * The function `cost` can change the cost of the link from corner `i` to corner `j`, of length `d`.\n * It must give at least `floor` × `d`, so that the estimate of A* stays below the true cost.\n */\n path(from: Point, to: Point, cost?: (i: number, j: number, d: number) => number, floor: number = 1): Point[] | undefined {\n if (this.#obstacles.clear(from, to, this.#pad)) return [from, to];\n const n = this.points.length;\n if (this.#g.length < n) {\n this.#g = new Float64Array(n);\n this.#parent = new Int32Array(n);\n this.#open = new Int32Array(n);\n this.#closed = new Int32Array(n);\n }\n const stamp = ++this.#stamp;\n const goal = new Map<number, number>();\n for (const j of this.nearestVisible(to, this.#k * 2)) goal.set(j, dist(this.points[j]!, to));\n if (goal.size === 0) return undefined;\n const heap = new MinHeap();\n const h = (i: number): number => floor * dist(this.points[i]!, to);\n const relax = (j: number, g: number, parent: number): void => {\n if (this.#closed[j] === stamp) return;\n if (this.#open[j] === stamp && this.#g[j]! <= g) return;\n this.#open[j] = stamp;\n this.#g[j] = g;\n this.#parent[j] = parent;\n heap.push(g + h(j), j);\n };\n for (const j of this.nearestVisible(from, this.#k * 2)) relax(j, dist(from, this.points[j]!), -1);\n let best = Infinity;\n let bestEnd = -1;\n while (heap.size > 0) {\n if (heap.topKey >= best) break;\n const i = heap.pop();\n if (this.#closed[i] === stamp) continue;\n this.#closed[i] = stamp;\n const gi = this.#g[i]!;\n const tail = goal.get(i);\n if (tail !== undefined && gi + tail < best) {\n best = gi + tail;\n bestEnd = i;\n }\n const adj = this.#adj[i]!;\n const len = this.#len[i]!;\n for (let m = 0; m < adj.length; m++) {\n const j = adj[m]!;\n const d = len[m]!;\n relax(j, gi + (cost ? cost(i, j, d) : d), i);\n }\n }\n if (bestEnd < 0) return undefined;\n const out: Point[] = [to];\n for (let i = bestEnd; i >= 0; i = this.#parent[i]!) out.push(this.points[i]!);\n out.push(from);\n return out.reverse();\n }\n\n /** This method removes the vertices that a later vertex makes needless: from each vertex, it goes to the farthest vertex in view. */\n pull(p: readonly Point[], lookahead = 16): Point[] {\n if (p.length < 3) return [...p];\n const out: Point[] = [p[0]!];\n let i = 0;\n while (i < p.length - 1) {\n let j = Math.min(p.length - 1, i + lookahead);\n while (j > i + 1 && !this.#obstacles.clear(p[i]!, p[j]!, this.#pad)) j--;\n out.push(p[j]!);\n i = j;\n }\n return out;\n }\n}\n\n/** A binary min-heap of (key, value) pairs. Equal keys come out by the smaller value, so the order is deterministic. */\nclass MinHeap {\n readonly #k: number[] = [];\n readonly #v: number[] = [];\n\n get size(): number {\n return this.#k.length;\n }\n\n #less(a: number, b: number): boolean {\n return this.#k[a]! < this.#k[b]! || (this.#k[a] === this.#k[b] && this.#v[a]! < this.#v[b]!);\n }\n\n #swap(a: number, b: number): void {\n const k = this.#k[a]!;\n this.#k[a] = this.#k[b]!;\n this.#k[b] = k;\n const v = this.#v[a]!;\n this.#v[a] = this.#v[b]!;\n this.#v[b] = v;\n }\n\n /** The smallest key. */\n get topKey(): number {\n return this.#k[0]!;\n }\n\n push(key: number, value: number): void {\n this.#k.push(key);\n this.#v.push(value);\n let i = this.#k.length - 1;\n while (i > 0) {\n const p = (i - 1) >> 1;\n if (!this.#less(i, p)) break;\n this.#swap(i, p);\n i = p;\n }\n }\n\n /** This method removes the pair with the smallest key and gives its value. */\n pop(): number {\n const top = this.#v[0]!;\n const k = this.#k.pop()!;\n const v = this.#v.pop()!;\n if (this.#k.length > 0) {\n this.#k[0] = k;\n this.#v[0] = v;\n let i = 0;\n for (;;) {\n const l = 2 * i + 1;\n const r = l + 1;\n let m = i;\n if (l < this.#k.length && this.#less(l, m)) m = l;\n if (r < this.#k.length && this.#less(r, m)) m = r;\n if (m === i) break;\n this.#swap(i, m);\n i = m;\n }\n }\n return top;\n }\n}\n","import { inflectionCurve, roundCorners } from \"./curves.ts\";\nimport type { Point } from \"./geom.ts\";\nimport type { Node } from \"./model.ts\";\nimport type { Plug } from \"./plugs.ts\";\nimport { CornerGraph, Obstacles } from \"./visibility.ts\";\n\n/** The options of a way finder. */\nexport interface WayOptions {\n /** The distance from a box to the corners of the graph. The default is 5. */\n readonly margin?: number;\n /** The number of visible neighbours of each corner. The default is 8. */\n readonly k?: number;\n /** With `smooth`, a way in clear view uses the inflection rule, and the other ways get round corners. */\n readonly smooth?: boolean;\n}\n\n/**\n * The ways around the nodes of one graph. A way leaves a plug along its normal.\n * It goes a shortest way (A*) through the corner graph, without the needless corners. It enters the other plug along its normal.\n */\nexport class WayFinder {\n readonly obstacles: Obstacles;\n readonly corners: CornerGraph;\n readonly margin: number;\n readonly #smooth: boolean;\n\n /** This constructor makes the obstacles and the corner graph of the nodes. */\n constructor(nodes: readonly Node[], options: WayOptions = {}) {\n this.margin = options.margin ?? 5;\n this.#smooth = options.smooth ?? false;\n this.obstacles = new Obstacles(nodes, 180);\n this.corners = new CornerGraph(nodes, this.obstacles, { margin: this.margin, k: options.k ?? 8 });\n }\n\n /** This method gives the point at `margin` from the plug, along its normal. */\n out(p: Plug): Point {\n return { x: p.point.x + p.normal.x * this.margin, y: p.point.y + p.normal.y * this.margin };\n }\n\n /** This method gives a way from plug to plug. Without a way in the graph, it gives the straight line. */\n between(ps: Plug, pt: Plug, ends: ReadonlySet<Node>): Point[] {\n if (this.#smooth) {\n const curve = inflectionCurve(ps.point, ps.normal, pt.point);\n if (this.obstacles.clearPath(curve, this.margin / 2, ends)) return curve;\n }\n const way = this.corners.path(this.out(ps), this.out(pt));\n if (!way) return [ps.point, pt.point];\n const poly = [ps.point, ...this.corners.pull(way), pt.point];\n if (this.#smooth) {\n const round = roundCorners(poly, this.margin);\n if (this.obstacles.clearPath(round, 0, ends)) return round;\n }\n return poly;\n }\n\n /** This method gives a way from a plug to a free point, or `undefined` when the graph has none. */\n fromPlug(ps: Plug, to: Point): Point[] | undefined {\n const way = this.corners.path(this.out(ps), to);\n return way && [ps.point, ...this.corners.pull(way)];\n }\n\n /** This method gives a way from a free point to a plug, or `undefined` when the graph has none. */\n toPlug(from: Point, pt: Plug): Point[] | undefined {\n const way = this.corners.path(from, this.out(pt));\n return way && [...this.corners.pull(way), pt.point];\n }\n}\n","import { dist, type Point } from \"./geom.ts\";\nimport type { Result, Route } from \"./model.ts\";\n\n/** A piece of drawn way. A shared segment carries several edges, in lane order. A private segment carries one edge. */\nexport interface Segment {\n readonly id: string;\n readonly points: readonly Point[];\n /** The edges in lane order. Lane 0 is on the left of the segment, from its first point to its last. The y axis points down. */\n readonly edges: readonly string[];\n /** The number of edges. A renderer shows it on a fat edge. */\n readonly count: number;\n}\n\n/** One step of a path: a segment, the way through it, and the lane of the edge in it. */\nexport interface SegmentRef {\n readonly segment: string;\n /** This value is true when the edge goes from the last point of the segment to its first point. */\n readonly reverse: boolean;\n readonly lane: number;\n}\n\n/** The route of one edge as a list of segments. */\nexport interface Path {\n readonly edge: string;\n readonly segments: readonly SegmentRef[];\n}\n\n/** The routes of a result as shared geometry. A renderer can draw each segment one time, with a count. */\nexport interface SegmentGraph {\n readonly segments: readonly Segment[];\n readonly paths: readonly Path[];\n}\n\nconst SAME = 1e-6;\n\n/** This function gives the index where `p` holds the points of `part` in a row, from `from` on, or -1. */\nfunction indexOf(p: readonly Point[], part: readonly Point[], from: number): number {\n for (let i = from; i + part.length <= p.length; i++) {\n let ok = true;\n for (let j = 0; ok && j < part.length; j++) ok = dist(p[i + j]!, part[j]!) <= SAME;\n if (ok) return i;\n }\n return -1;\n}\n\n/**\n * This function breaks each route into segments. The runs and the trunks of the bundles become shared segments.\n * The other parts of each route become private segments. The segments of a path, in order, give the points of its route again.\n */\nexport function segmentsOf(result: Result): SegmentGraph {\n const shared = [\n ...(result.runs ?? []).map((r) => ({ id: r.id, points: r.points, edges: r.edges })),\n ...(result.bundles ?? []).map((b) => ({ id: b.id, points: b.trunk, edges: b.edges })),\n ].filter((s) => s.points.length >= 2);\n const onEdge = new Map<string, { id: string; points: readonly Point[]; lane: number }[]>();\n for (const s of shared) {\n s.edges.forEach((edge, lane) => {\n const list = onEdge.get(edge);\n if (list) list.push({ id: s.id, points: s.points, lane });\n else onEdge.set(edge, [{ id: s.id, points: s.points, lane }]);\n });\n }\n const segments: Segment[] = shared.map((s) => ({ id: s.id, points: s.points, edges: s.edges, count: s.edges.length }));\n const paths: Path[] = [];\n for (const route of result.routes) {\n const p = route.points;\n // The place of each shared segment in the route, in the order of the route.\n const found: { at: number; end: number; ref: SegmentRef }[] = [];\n for (const s of onEdge.get(route.edge) ?? []) {\n let at = indexOf(p, s.points, 0);\n let reverse = false;\n if (at < 0) {\n at = indexOf(p, [...s.points].reverse(), 0);\n reverse = true;\n }\n if (at >= 0) found.push({ at, end: at + s.points.length - 1, ref: { segment: s.id, reverse, lane: s.lane } });\n }\n found.sort((a, b) => a.at - b.at);\n const refs: SegmentRef[] = [];\n let i = 0;\n const own = (to: number): void => {\n if (to <= i) return;\n const id = `${route.edge}/${refs.length}`;\n segments.push({ id, points: p.slice(i, to + 1), edges: [route.edge], count: 1 });\n refs.push({ segment: id, reverse: false, lane: 0 });\n };\n for (const f of found) {\n if (f.at < i) continue;\n own(f.at);\n refs.push(f.ref);\n i = f.end;\n }\n own(p.length - 1);\n paths.push({ edge: route.edge, segments: refs });\n }\n return { segments, paths };\n}\n\n/** This function gives the points of a path, with the segments in the order and the way of the path. */\nexport function pathPoints(graph: SegmentGraph, path: Path): Point[] {\n const byId = new Map(graph.segments.map((s) => [s.id, s]));\n const out: Point[] = [];\n for (const ref of path.segments) {\n const s = byId.get(ref.segment);\n if (!s) continue;\n const pts = ref.reverse ? [...s.points].reverse() : s.points;\n for (const q of pts) if (out.length === 0 || dist(q, out[out.length - 1]!) > SAME) out.push(q);\n }\n return out;\n}\n\n/**\n * This function moves each point of a polyline by `d` to the left, in a frame with the y axis down.\n * At an inner point, it moves along the bisector, at most 2 × `d` far.\n */\nexport function offsetPolyline(p: readonly Point[], d: number): Point[] {\n if (d === 0 || p.length < 2) return [...p];\n const normals: Point[] = [];\n for (let i = 1; i < p.length; i++) {\n const dx = p[i]!.x - p[i - 1]!.x;\n const dy = p[i]!.y - p[i - 1]!.y;\n const l = Math.hypot(dx, dy);\n normals.push(l > 0 ? { x: dy / l, y: -dx / l } : (normals[normals.length - 1] ?? { x: 0, y: 0 }));\n }\n return p.map((q, i) => {\n const a = normals[Math.max(0, i - 1)]!;\n const b = normals[Math.min(normals.length - 1, i)]!;\n const mx = a.x + b.x;\n const my = a.y + b.y;\n const ml = Math.hypot(mx, my);\n if (ml < 1e-9) return { x: q.x + a.x * d, y: q.y + a.y * d };\n const cos = (mx * a.x + my * a.y) / ml;\n const k = Math.min(2, 1 / Math.max(cos, 1e-9)) * d;\n return { x: q.x + (mx / ml) * k, y: q.y + (my / ml) * k };\n });\n}\n\n/** The options of `pullApart`. */\nexport interface PullApartOptions {\n /** The distance between two lanes. */\n readonly spacing: number;\n /** The largest width of a segment, from its outer lane on the left to its outer lane on the right. */\n readonly maxWidth: number;\n}\n\n/**\n * This function pulls the lanes of each shared segment apart, and gives a route for each edge.\n * The lanes keep the lane order, so they do not cross in a segment. The two ends of each route stay at their plugs.\n */\nexport function pullApart(graph: SegmentGraph, options: PullApartOptions): Route[] {\n const byId = new Map(graph.segments.map((s) => [s.id, s]));\n const routes: Route[] = [];\n for (const path of graph.paths) {\n const ends = pathPoints(graph, path);\n const out: Point[] = [];\n for (const ref of path.segments) {\n const s = byId.get(ref.segment);\n if (!s) continue;\n const n = s.count;\n const spacing = n > 1 ? Math.min(options.spacing, options.maxWidth / (n - 1)) : 0;\n const moved = offsetPolyline(s.points, ((n - 1) / 2 - ref.lane) * spacing);\n for (const q of ref.reverse ? moved.reverse() : moved) if (out.length === 0 || dist(q, out[out.length - 1]!) > SAME) out.push(q);\n }\n if (out.length >= 2 && ends.length >= 2) {\n out[0] = ends[0]!;\n out[out.length - 1] = ends[ends.length - 1]!;\n }\n routes.push({ edge: path.edge, points: out });\n }\n return routes;\n}\n\n/** The angle, from -π to π, of the turn at `base` from the direction `from` → `base` to the point `to`. */\nfunction turn(from: Point, base: Point, to: Point): number {\n const dx = base.x - from.x;\n const dy = base.y - from.y;\n const vx = to.x - base.x;\n const vy = to.y - base.y;\n return Math.atan2(dx * vy - dy * vx, dx * vx + dy * vy);\n}\n\n/**\n * This function gives the lane order of the edges on a shared way `run` (metro-line order). Two routes go on together\n * past the last point of the run until they part. The route that turns more to the left there gets the lane more to the left.\n * Two routes can part only before the first point. Then the route that comes from more to the left gets the lane more to the left.\n * A route that does not hold the run goes last.\n */\nexport function orderLanes(run: readonly Point[], routes: readonly Route[]): string[] {\n const placed: { edge: string; p: readonly Point[]; s: number; e: number }[] = [];\n const lost: string[] = [];\n for (const r of routes) {\n let at = indexOf(r.points, run, 0);\n if (at >= 0) placed.push({ edge: r.edge, p: r.points, s: at, e: at + run.length - 1 });\n else {\n const p = [...r.points].reverse();\n at = indexOf(p, run, 0);\n if (at >= 0) placed.push({ edge: r.edge, p, s: at, e: at + run.length - 1 });\n else lost.push(r.edge);\n }\n }\n const same = (a: Point, b: Point): boolean => dist(a, b) <= SAME;\n placed.sort((P, Q) => {\n for (let j = 1; ; j++) {\n const a = P.p[P.e + j];\n const b = Q.p[Q.e + j];\n if (a === undefined || b === undefined) break;\n if (!same(a, b)) {\n const d = turn(P.p[P.e + j - 2]!, P.p[P.e + j - 1]!, a) - turn(P.p[P.e + j - 2]!, P.p[P.e + j - 1]!, b);\n if (d !== 0) return d;\n break;\n }\n }\n for (let j = 1; ; j++) {\n const a = P.p[P.s - j];\n const b = Q.p[Q.s - j];\n if (a === undefined || b === undefined) break;\n if (!same(a, b)) {\n // Seen backward, the left side is the right side. Thus the order turns around.\n const d = turn(P.p[P.s - j + 2]!, P.p[P.s - j + 1]!, b) - turn(P.p[P.s - j + 2]!, P.p[P.s - j + 1]!, a);\n if (d !== 0) return d;\n break;\n }\n }\n return P.edge < Q.edge ? -1 : P.edge > Q.edge ? 1 : 0;\n });\n return [...placed.map((x) => x.edge), ...lost.sort()];\n}\n","import { center, type Box } from \"./geom.ts\";\nimport type { Node } from \"./model.ts\";\n\n/** A section of the plane: a cell of a quadtree, with the nodes whose centers are in it. */\nexport interface Section {\n /** The path from the root: \"s\", then one digit from 0 to 3 for each step down. */\n readonly id: string;\n readonly depth: number;\n readonly cell: Box;\n /** The indices of the nodes, in the order of the graph. */\n readonly nodes: readonly number[];\n readonly children: readonly Section[];\n}\n\n/** The options of the tree of sections. */\nexport interface SectionOptions {\n /** A section with more nodes splits. The default is 8. */\n readonly cap?: number;\n /** The tree stops at this depth. The default is 16. */\n readonly maxDepth?: number;\n}\n\n/**\n * This function makes the tree of sections of the nodes. A cell with more than `cap` nodes splits in four.\n * When the nodes of a cell are all in one quarter, the cell becomes that quarter and does not make a level.\n */\nexport function buildSections(nodes: readonly Node[], options: SectionOptions = {}): Section {\n const cap = Math.max(1, options.cap ?? 8);\n const maxDepth = options.maxDepth ?? 16;\n const centers = nodes.map((n) => center(n.box));\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const n of nodes) {\n x0 = Math.min(x0, n.box.x);\n y0 = Math.min(y0, n.box.y);\n x1 = Math.max(x1, n.box.x + n.box.w);\n y1 = Math.max(y1, n.box.y + n.box.h);\n }\n const root: Box = nodes.length ? { x: x0, y: y0, w: x1 - x0, h: y1 - y0 } : { x: 0, y: 0, w: 0, h: 0 };\n const make = (id: string, depth: number, cell: Box, list: readonly number[]): Section => {\n let box = cell;\n for (let guard = 0; list.length > cap && depth < maxDepth && guard < 32; guard++) {\n const mx = box.x + box.w / 2;\n const my = box.y + box.h / 2;\n const parts: number[][] = [[], [], [], []];\n for (const i of list) parts[(centers[i]!.x < mx ? 0 : 1) + (centers[i]!.y < my ? 0 : 2)]!.push(i);\n const quarter = (q: number): Box => ({\n x: q % 2 === 0 ? box.x : mx,\n y: q < 2 ? box.y : my,\n w: box.w / 2,\n h: box.h / 2,\n });\n const full = parts.map((p, q) => [p, q] as const).filter(([p]) => p.length > 0);\n if (full.length === 1) {\n box = quarter(full[0]![1]);\n continue;\n }\n const children = full.map(([p, q]) => make(`${id}${q}`, depth + 1, quarter(q), p));\n return { id, depth, cell: box, nodes: list, children };\n }\n return { id, depth, cell: box, nodes: list, children: [] };\n };\n return make(\"s\", 0, root, nodes.map((_, i) => i));\n}\n\n/** This function gives the sections of the tree, parents before children. */\nexport function allSections(root: Section): Section[] {\n const out: Section[] = [];\n const walk = (s: Section): void => {\n out.push(s);\n for (const c of s.children) walk(c);\n };\n walk(root);\n return out;\n}\n\n/** This function gives the depth of the deepest section. */\nexport function treeDepth(root: Section): number {\n return root.children.reduce((d, c) => Math.max(d, treeDepth(c)), root.depth);\n}\n","import { center } from \"../geom.ts\";\nimport { nodeIndex, type Graph, type Node, type Result, type Route, type Router } from \"../model.ts\";\nimport { placePlug } from \"../plugs.ts\";\nimport { WayFinder, type WayOptions } from \"../ways.ts\";\n\n/** The options of the corner router. */\nexport interface CornersOptions extends WayOptions {\n /** The name in the benchmark. */\n readonly name: string;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\n/**\n * This function makes a router that goes around the nodes.\n * Each edge leaves its plug along the normal of the side. It goes a shortest way (A*) through a sparse visibility graph\n * of the box corners, without the needless corners. It enters the target plug along its normal.\n */\nexport function cornersRouter(options: CornersOptions): Router {\n const router: Router = {\n name: options.name,\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const ways = new WayFinder(graph.nodes, options);\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n }\n return { routes };\n },\n };\n return options.maxNodes === undefined ? router : { ...router, maxNodes: options.maxNodes };\n}\n","import { inflectionCurve } from \"../curves.ts\";\nimport { center } from \"../geom.ts\";\nimport { nodeIndex, type Graph, type Result, type Route, type Router } from \"../model.ts\";\nimport { placePlug } from \"../plugs.ts\";\n\n/**\n * Plugs and the inflection rule, with no obstacles. Each edge leaves its source plug at the tangent of the side.\n * It goes to the target plug on the curve of the rule. This router measures the rule alone.\n */\nexport const plugsRouter: Router = {\n name: \"plugs\",\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n routes.push({ edge: e.id, points: inflectionCurve(ps.point, ps.normal, pt.point) });\n }\n return { routes };\n },\n};\n","import { center, dist, polylineLength, type Box, type Point } from \"../geom.ts\";\nimport {\n nodeIndex,\n type Graph,\n type Level,\n type LevelItem,\n type LevelLink,\n type Node,\n type Result,\n type Route,\n type Router,\n type SharedRun,\n} from \"../model.ts\";\nimport { placePlug } from \"../plugs.ts\";\nimport { allSections, buildSections, treeDepth, type Section, type SectionOptions } from \"../sections.ts\";\nimport { orderLanes } from \"../segments.ts\";\nimport { WayFinder, type WayOptions } from \"../ways.ts\";\n\n/** The options of the router with sections. */\nexport interface SectionsOptions extends WayOptions, SectionOptions {\n /** The name in the benchmark. */\n readonly name: string;\n /**\n * The number of hubs on each side of the lowest common section that a way passes. A smaller number gives shorter ways\n * and fewer shared ways. Without it, a way passes each hub from its node up.\n */\n readonly hubs?: number;\n /** A way through the hubs can be at most this many times as long as the line between its plugs. Else the edge goes directly. The default is 2. */\n readonly stretch?: number;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\nconst dedupe = (p: readonly Point[]): Point[] => p.filter((q, i) => i === 0 || dist(q, p[i - 1]!) > 1e-9);\n\n/**\n * This function makes a router with a tree of sections. Each section has a hub: the free corner nearest to the center of its nodes.\n * An edge goes from its node up the hubs of its sections to the lowest common section, across, and down to the other node.\n * Each way from hub to hub is found one time, so all the edges on it share its points.\n * The edges in one section of the lowest level go straight around the nodes. The result gives one zoom level for each depth of the tree.\n */\nexport function sectionsRouter(options: SectionsOptions): Router {\n const router: Router = {\n name: options.name,\n route(graph: Graph): Result {\n const stretch = options.stretch ?? 2;\n const byId = nodeIndex(graph);\n const indexOfNode = new Map(graph.nodes.map((n, i) => [n.id, i]));\n const ways = new WayFinder(graph.nodes, options);\n const corners = ways.corners;\n const root = buildSections(graph.nodes, options);\n const parent = new Map<Section, Section>();\n const leafOf: Section[] = [];\n for (const s of allSections(root)) {\n for (const c of s.children) parent.set(c, s);\n if (s.children.length === 0) for (const i of s.nodes) leafOf[i] = s;\n }\n const hubs = new Map<Section, Point>();\n const hub = (s: Section): Point => {\n let h = hubs.get(s);\n if (!h) {\n let x = 0;\n let y = 0;\n for (const i of s.nodes) {\n const c = center(graph.nodes[i]!.box);\n x += c.x;\n y += c.y;\n }\n const c = { x: x / Math.max(1, s.nodes.length), y: y / Math.max(1, s.nodes.length) };\n const j = corners.nearest(c);\n h = j >= 0 ? corners.points[j]! : c;\n hubs.set(s, h);\n }\n return h;\n };\n const up = (s: Section): Section[] => {\n const out: Section[] = [];\n for (let x: Section | undefined = s; x; x = parent.get(x)) out.push(x);\n return out;\n };\n\n // The ways between two places, found one time. A place is a hub or a free point.\n const pieces = new Map<string, Point[]>();\n const users = new Map<string, string[]>();\n const piece = (ka: string, a: Point, kb: string, b: Point, used: string[]): Point[] => {\n const forward = ka <= kb;\n const key = forward ? `${ka}>${kb}` : `${kb}>${ka}`;\n let p = pieces.get(key);\n if (!p) {\n const [from, to] = forward ? [a, b] : [b, a];\n const way = corners.path(from, to);\n p = dedupe(way ? corners.pull(way) : [from, to]);\n pieces.set(key, p);\n }\n if (!used.includes(key)) used.push(key);\n return forward ? p : [...p].reverse();\n };\n const at = (p: Point): string => `${p.x},${p.y}`;\n\n const routes: Route[] = [];\n // The index in the route of each hub that the route passes, by section.\n const marks = new Map<string, Map<Section, number>>();\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n const iu = indexOfNode.get(e.source.node);\n const iv = indexOfNode.get(e.target.node);\n if (!s || !t || iu === undefined || iv === undefined) continue;\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n const lu = leafOf[iu]!;\n const lv = leafOf[iv]!;\n if (lu === lv) {\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n continue;\n }\n const a = up(lu);\n const b = up(lv);\n const common = new Set(b);\n const lca = a.find((x) => common.has(x))!;\n const keep = options.hubs ?? Infinity;\n const side = (list: Section[]): Section[] => list.slice(Math.max(0, list.indexOf(lca) - keep), list.indexOf(lca));\n const chain = [...side(a), ...side(b).reverse()];\n const out: Point[] = [ps.point];\n const mark = new Map<Section, number>();\n const append = (p: readonly Point[]): void => {\n for (const q of p) if (dist(q, out[out.length - 1]!) > 1e-9) out.push(q);\n };\n const used: string[] = [];\n const start = ways.out(ps);\n append(piece(at(start), start, chain[0]!.id, hub(chain[0]!), used));\n mark.set(chain[0]!, out.length - 1);\n for (let i = 1; i < chain.length; i++) {\n append(piece(chain[i - 1]!.id, hub(chain[i - 1]!), chain[i]!.id, hub(chain[i]!), used));\n mark.set(chain[i]!, out.length - 1);\n }\n const end = ways.out(pt);\n append(piece(chain[chain.length - 1]!.id, hub(chain[chain.length - 1]!), at(end), end, used));\n append([pt.point]);\n // A way through the hubs that is too long gives way to the direct way.\n if (polylineLength(out) > stretch * dist(ps.point, pt.point) + 4 * ways.margin) {\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n continue;\n }\n for (const key of used) {\n const list = users.get(key);\n if (list) list.push(e.id);\n else users.set(key, [e.id]);\n }\n routes.push({ edge: e.id, points: out });\n marks.set(e.id, mark);\n }\n\n const routeOf = new Map(routes.map((r) => [r.edge, r]));\n const runs: SharedRun[] = [];\n for (const [key, p] of pieces) {\n const list = users.get(key) ?? [];\n if (list.length < 2 || p.length < 2) continue;\n runs.push({ id: `r${runs.length}`, key, points: p, edges: orderLanes(p, list.map((id) => routeOf.get(id)!)) });\n }\n return { routes, runs, levels: makeLevels(graph, root, routeOf, marks) };\n },\n };\n return options.maxNodes === undefined ? router : { ...router, maxNodes: options.maxNodes };\n}\n\n/**\n * This function gives one zoom level for each depth of the tree, and a last level with each node alone.\n * At depth d, a section of depth d is one item. A link joins two items and counts the edges between them.\n * Its points are the part of the route of its first edge between the two items.\n */\nfunction makeLevels(\n graph: Graph,\n root: Section,\n routeOf: ReadonlyMap<string, Route>,\n marks: ReadonlyMap<string, ReadonlyMap<Section, number>>,\n): Level[] {\n const indexOfNode = new Map(graph.nodes.map((n, i) => [n.id, i]));\n const levels: Level[] = [];\n const deepest = treeDepth(root);\n for (let d = 0; d <= deepest + 1; d++) {\n const items: LevelItem[] = [];\n const itemOf: (Section | number)[] = [];\n const boxOf = (list: readonly number[]): Box => {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const i of list) {\n const b = graph.nodes[i]!.box;\n x0 = Math.min(x0, b.x);\n y0 = Math.min(y0, b.y);\n x1 = Math.max(x1, b.x + b.w);\n y1 = Math.max(y1, b.y + b.h);\n }\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 };\n };\n const visit = (s: Section): void => {\n if (s.depth >= d) {\n items.push({ id: s.id, box: boxOf(s.nodes), nodes: s.nodes.map((i) => graph.nodes[i]!.id) });\n for (const i of s.nodes) itemOf[i] = s;\n } else if (s.children.length > 0) for (const c of s.children) visit(c);\n else\n for (const i of s.nodes) {\n const n = graph.nodes[i]!;\n items.push({ id: n.id, box: n.box, nodes: [n.id] });\n itemOf[i] = i;\n }\n };\n if (graph.nodes.length > 0) visit(root);\n const links = new Map<string, { source: string; target: string; count: number; points: readonly Point[] }>();\n for (const e of graph.edges) {\n const iu = indexOfNode.get(e.source.node);\n const iv = indexOfNode.get(e.target.node);\n if (iu === undefined || iv === undefined) continue;\n const a = itemOf[iu]!;\n const b = itemOf[iv]!;\n if (a === b) continue;\n const ida = typeof a === \"number\" ? graph.nodes[a]!.id : a.id;\n const idb = typeof b === \"number\" ? graph.nodes[b]!.id : b.id;\n const key = `${ida}\\u0000${idb}`;\n const link = links.get(key);\n if (link) {\n link.count++;\n continue;\n }\n const route = routeOf.get(e.id)?.points ?? [];\n const mark = marks.get(e.id);\n const from = typeof a === \"number\" ? 0 : (mark?.get(a) ?? 0);\n const to = typeof b === \"number\" ? route.length - 1 : (mark?.get(b) ?? route.length - 1);\n links.set(key, { source: ida, target: idb, count: 1, points: route.slice(from, to + 1) });\n }\n levels.push({ depth: d, items, links: [...links.values()] as LevelLink[] });\n }\n return levels;\n}\n","import { center, dist, type Point } from \"../geom.ts\";\nimport { nodeIndex, type Edge, type Graph, type GroupRule, type Result, type Route, type Router, type SharedRun } from \"../model.ts\";\nimport { placePlug, type Plug } from \"../plugs.ts\";\nimport { WayFinder, type WayOptions } from \"../ways.ts\";\n\n/** The options of the router with shared ways. */\nexport interface SharedOptions extends WayOptions {\n /** The name in the benchmark. */\n readonly name: string;\n /** The edges with one key share their ways. Without a rule, all edges share. An edge without a key shares with no edge. */\n readonly rule?: GroupRule;\n /** The cost of a link that an edge with the same key uses already, as a share of its length. The default is 0.5. */\n readonly discount?: number;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\ninterface Way {\n readonly edge: Edge;\n readonly key: string;\n readonly ps: Plug;\n readonly pt: Plug;\n /** The way through the corner graph, from the point out of the source plug to the point out of the target plug. */\n seq: Point[];\n /** The index of each point of `seq` in the corner graph. The two ends get an index after the corners, one for each place. */\n ids: number[];\n found: boolean;\n}\n\ninterface Run {\n readonly key: string;\n readonly first: number;\n readonly last: number;\n /** The points from the corner `first` to the corner `last`, without the needless corners. */\n readonly points: Point[];\n readonly ways: Way[];\n}\n\nconst byText = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);\n\n/** The angle, from -π to π, of the turn at `base` from the direction `from` → `base` to the point `to`. */\nfunction turn(from: Point, base: Point, to: Point): number {\n const dx = base.x - from.x;\n const dy = base.y - from.y;\n const vx = to.x - base.x;\n const vy = to.y - base.y;\n return Math.atan2(dx * vy - dy * vx, dx * vx + dy * vy);\n}\n\n/**\n * This function makes a router where edges share their ways (after Pupyrev, Nachmanson, Bereg and Holroyd, \"Edge routing with ordered bundles\").\n * The edges go one by one through the corner graph. A link that an edge with the same key uses already costs less.\n * Thus the edges of a key come together on common ways. Each stretch that several edges share has the same points in each route.\n * The result gives each stretch as a run, with the order of its lanes.\n */\nexport function sharedRouter(options: SharedOptions): Router {\n const discount = Math.min(1, Math.max(0.05, options.discount ?? 0.5));\n const keyOf = (e: Edge): string => {\n if (!options.rule) return \"*\";\n return options.rule(e) ?? `\\u0000${e.id}`;\n };\n const router: Router = {\n name: options.name,\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const ways = new WayFinder(graph.nodes, options);\n const corners = ways.corners;\n const index = new Map<Point, number>();\n corners.points.forEach((p, i) => index.set(p, i));\n const M = corners.points.length + 1;\n const link = (i: number, j: number): number => (i < j ? i * M + j : j * M + i);\n const ends = new Map<string, number>();\n const endId = (p: Point): number => {\n const k = `${p.x},${p.y}`;\n let id = ends.get(k);\n if (id === undefined) ends.set(k, (id = corners.points.length + ends.size));\n return id;\n };\n\n const all: Way[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n all.push({ edge: e, key: keyOf(e), ps, pt, seq: [], ids: [], found: false });\n }\n\n // The edges of one key go one after the other, the longest first, so that the short edges join the long ways.\n const discounted = new Map<string, Map<number, string[]>>();\n const order = [...all].sort(\n (p, q) => byText(p.key, q.key) || dist(q.ps.point, q.pt.point) - dist(p.ps.point, p.pt.point) || byText(p.edge.id, q.edge.id),\n );\n for (const w of order) {\n let used = discounted.get(w.key);\n if (!used) discounted.set(w.key, (used = new Map()));\n const mine = used;\n const way = corners.path(ways.out(w.ps), ways.out(w.pt), (i, j, d) => (mine.has(link(i, j)) ? d * discount : d), discount);\n if (!way) continue;\n w.found = true;\n w.seq = way;\n w.ids = way.map((p, i) => (i === 0 || i === way.length - 1 ? endId(p) : index.get(p)!));\n for (let i = 1; i < w.ids.length; i++) {\n const a = w.ids[i - 1]!;\n const b = w.ids[i]!;\n if (a >= corners.points.length || b >= corners.points.length) continue;\n const list = mine.get(link(a, b));\n if (list) list.push(w.edge.id);\n else mine.set(link(a, b), [w.edge.id]);\n }\n }\n\n // The users of each link, with the links to the ends. Two edges from one plug share the link from it.\n const users = new Map<string, Map<string, string[]>>();\n for (const w of order) {\n if (!w.found) continue;\n let mine = users.get(w.key);\n if (!mine) users.set(w.key, (mine = new Map()));\n for (let i = 1; i < w.ids.length; i++) {\n const a = w.ids[i - 1]!;\n const b = w.ids[i]!;\n const k = a < b ? `${a}:${b}` : `${b}:${a}`;\n const list = mine.get(k);\n if (list) list.push(w.edge.id);\n else mine.set(k, [w.edge.id]);\n }\n }\n\n // Each way breaks into stretches where the set of edges on the links stays the same.\n // A shared stretch loses its needless corners one time, so it has the same points in each of its routes.\n const runs = new Map<string, Run>();\n const points = new Map<string, Point[]>();\n for (const w of all) {\n if (!w.found) continue;\n const used = users.get(w.key)!;\n const sig = (i: number): string => {\n const a = w.ids[i]!;\n const b = w.ids[i + 1]!;\n const list = used.get(a < b ? `${a}:${b}` : `${b}:${a}`)!;\n return list.length < 2 ? \"\" : [...list].sort(byText).join(\"\\u0001\");\n };\n const out: Point[] = [w.ps.point];\n const append = (piece: readonly Point[]): void => {\n for (const p of piece) if (dist(p, out[out.length - 1]!) > 1e-9) out.push(p);\n };\n let start = 0;\n for (let i = 0; i < w.seq.length - 1; i++) {\n const s = sig(i);\n if (i + 1 < w.seq.length - 1 && sig(i + 1) === s) continue;\n const raw = w.seq.slice(start, i + 2);\n if (s === \"\") append(corners.pull(raw));\n else {\n const a = w.ids[start]!;\n const b = w.ids[i + 1]!;\n const id = `${s}\\u0002${Math.min(a, b)}\\u0002${Math.max(a, b)}`;\n let run = runs.get(id);\n if (!run) {\n run = { key: w.key, first: Math.min(a, b), last: Math.max(a, b), points: corners.pull(a < b ? raw : [...raw].reverse()), ways: [] };\n runs.set(id, run);\n }\n run.ways.push(w);\n append(a < b ? run.points : [...run.points].reverse());\n }\n start = i + 1;\n }\n append([w.pt.point]);\n points.set(w.edge.id, out);\n }\n\n const routes: Route[] = [];\n for (const w of all) routes.push({ edge: w.edge.id, points: points.get(w.edge.id) ?? [w.ps.point, w.pt.point] });\n const shared: SharedRun[] = [];\n for (const run of runs.values()) {\n shared.push({ id: `r${shared.length}`, key: run.key, points: run.points, edges: laneOrderOfRun(run) });\n }\n return { routes, runs: shared };\n },\n };\n return options.maxNodes === undefined ? router : { ...router, maxNodes: options.maxNodes };\n}\n\n/**\n * This function gives the lane order of a run (metro-line order). Two edges of the run go together past its last corner\n * until they part. The edge that turns more to the left there gets the lane more to the left.\n * Two edges can part only before the first corner. Then the edge that comes from more to the left gets the lane more to the left.\n */\nfunction laneOrderOfRun(run: Run): string[] {\n const oriented = new Map<Way, { seq: Point[]; ids: number[]; s: number; e: number }>();\n for (const w of run.ways) {\n const s0 = w.ids.indexOf(run.first);\n const e0 = w.ids.indexOf(run.last);\n if (s0 < e0) oriented.set(w, { seq: w.seq, ids: w.ids, s: s0, e: e0 });\n else oriented.set(w, { seq: [...w.seq].reverse(), ids: [...w.ids].reverse(), s: w.seq.length - 1 - s0, e: w.seq.length - 1 - e0 });\n }\n const compare = (p: Way, q: Way): number => {\n const P = oriented.get(p)!;\n const Q = oriented.get(q)!;\n for (let j = 1; ; j++) {\n const a = P.seq[P.e + j];\n const b = Q.seq[Q.e + j];\n if (a === undefined || b === undefined) break;\n if (P.ids[P.e + j] !== Q.ids[Q.e + j]) {\n const d = turn(P.seq[P.e + j - 2]!, P.seq[P.e + j - 1]!, a) - turn(P.seq[P.e + j - 2]!, P.seq[P.e + j - 1]!, b);\n if (d !== 0) return d;\n break;\n }\n }\n for (let j = 1; ; j++) {\n const a = P.seq[P.s - j];\n const b = Q.seq[Q.s - j];\n if (a === undefined || b === undefined) break;\n if (P.ids[P.s - j] !== Q.ids[Q.s - j]) {\n // Seen backward, the left side is the right side. Thus the order turns around.\n const d = turn(P.seq[P.s - j + 2]!, P.seq[P.s - j + 1]!, b) - turn(P.seq[P.s - j + 2]!, P.seq[P.s - j + 1]!, a);\n if (d !== 0) return d;\n break;\n }\n }\n return byText(p.edge.id, q.edge.id);\n };\n return [...run.ways].sort(compare).map((w) => w.edge.id);\n}\n","import { center, type Box, type Point } from \"../geom.ts\";\nimport { fixedPortPoint, nodeIndex, type Graph, type Result, type Route, type Router } from \"../model.ts\";\n\n/** This function gives the point where the ray from the center of the box to `toward` leaves the box. */\nexport function boxExit(box: Box, toward: Point): Point {\n const c = center(box);\n const dx = toward.x - c.x;\n const dy = toward.y - c.y;\n if (dx === 0 && dy === 0) return c;\n const tx = dx === 0 ? Infinity : box.w / 2 / Math.abs(dx);\n const ty = dy === 0 ? Infinity : box.h / 2 / Math.abs(dy);\n const t = Math.min(tx, ty);\n return { x: c.x + dx * t, y: c.y + dy * t };\n}\n\n/**\n * The control of the benchmark: each edge is one straight line between its plugs.\n * A free plug goes where the line between the two centers leaves the box.\n */\nexport const straightRouter: Router = {\n name: \"straight\",\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const fs = fixedPortPoint(s, e.source);\n const ft = fixedPortPoint(t, e.target);\n const a = fs ?? boxExit(s.box, ft ?? center(t.box));\n const b = ft ?? boxExit(t.box, fs ?? center(s.box));\n routes.push({ edge: e.id, points: [a, b] });\n }\n return { routes };\n },\n};\n","import { center, dist, type Point } from \"../geom.ts\";\nimport { nodeIndex, type Bundle, type Edge, type Graph, type GroupRule, type Node, type Result, type Route, type Router } from \"../model.ts\";\nimport { placePlug, type Plug } from \"../plugs.ts\";\nimport { WayFinder, type WayOptions } from \"../ways.ts\";\n\n/** The options of the trunk router. */\nexport interface TrunksOptions extends WayOptions {\n /** The name in the benchmark. */\n readonly name: string;\n /** The grouping rule. The edges from one plug with one key share a trunk. */\n readonly rule: GroupRule;\n /** The split point is at this share of the way to the center of the targets. The default is 0.5. */\n readonly split?: number;\n /** A group with fewer edges stays unbundled. The default is 2. */\n readonly minSize?: number;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\n/** The rule that groups the edges by the collection of their target, in `data.collection`. */\nexport const byCollection: GroupRule = (e) => {\n const c = e.data?.[\"collection\"];\n return typeof c === \"string\" ? c : undefined;\n};\n\n/**\n * This function groups the edges by their source plug and their key. Each group keeps the order of the edges.\n * A group with fewer than `minSize` edges does not appear.\n */\nexport function groupEdges(edges: readonly Edge[], rule: GroupRule, minSize = 2): Map<string, Edge[]> {\n const all = new Map<string, Edge[]>();\n for (const e of edges) {\n const key = rule(e);\n if (key === undefined) continue;\n const id = `${e.source.node}\\u0000${e.source.port ?? \"\"}\\u0000${key}`;\n const list = all.get(id);\n if (list) list.push(e);\n else all.set(id, [e]);\n }\n for (const [id, list] of all) if (list.length < minSize) all.delete(id);\n return all;\n}\n\n/**\n * This function gives the lane order of the branches that leave the split point `from`, with the trunk along `dir`.\n * Lane 0 turns most to the left, in a frame with the y axis down. Thus two lanes do not cross at the split.\n */\nexport function laneOrder(dir: Point, from: Point, branches: readonly { readonly edge: string; readonly next: Point }[]): string[] {\n const angle = (p: Point): number => {\n const vx = p.x - from.x;\n const vy = p.y - from.y;\n return Math.atan2(dir.x * vy - dir.y * vx, dir.x * vx + dir.y * vy);\n };\n return branches\n .map((b) => ({ edge: b.edge, a: angle(b.next) }))\n .sort((p, q) => p.a - q.a || (p.edge < q.edge ? -1 : p.edge > q.edge ? 1 : 0))\n .map((x) => x.edge);\n}\n\n/**\n * This function gives the split point of a bundle, on the line from `start` to the center of the targets.\n * The point is at `split` of the way, but at most half of the way to the nearest target. It moves back toward `start` out of the boxes.\n */\nexport function splitPoint(start: Point, targets: readonly Point[], split: number, free: (p: Point) => boolean, step: number): Point {\n if (targets.length === 0) return start;\n const c = { x: targets.reduce((s, p) => s + p.x, 0) / targets.length, y: targets.reduce((s, p) => s + p.y, 0) / targets.length };\n const L = dist(start, c);\n if (L === 0) return start;\n let d = Math.min(split * L, 0.5 * Math.min(...targets.map((p) => dist(start, p))));\n const at = (t: number): Point => ({ x: start.x + ((c.x - start.x) * t) / L, y: start.y + ((c.y - start.y) * t) / L });\n while (d > 0 && !free(at(d))) d -= step;\n return d > 0 ? at(d) : start;\n}\n\nconst dedupe = (p: readonly Point[]): Point[] => p.filter((q, i) => i === 0 || dist(q, p[i - 1]!) > 1e-9);\n\n/**\n * This function makes a router that bundles the edges by a rule. The edges of a group share one plug and one trunk\n * to a split point. From there, each edge goes its own way. The router gives the bundles with their lane order.\n * The edges outside the groups go as in the corner router.\n */\nexport function trunksRouter(options: TrunksOptions): Router {\n const router: Router = {\n name: options.name,\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const ways = new WayFinder(graph.nodes, options);\n const points = new Map<string, Point[]>();\n const bundles: Bundle[] = [];\n for (const [id, group] of groupEdges(graph.edges, options.rule, options.minSize ?? 2)) {\n const first = group[0]!;\n const s = byId.get(first.source.node);\n const targets = group.map((e) => byId.get(e.target.node));\n if (!s || targets.some((t) => !t)) continue;\n const centers = targets.map((t) => center(t!.box));\n const c = { x: centers.reduce((a, p) => a + p.x, 0) / centers.length, y: centers.reduce((a, p) => a + p.y, 0) / centers.length };\n const plug: Plug = placePlug(s, first.source, c);\n const start = ways.out(plug);\n const split = splitPoint(start, centers, options.split ?? 0.5, (p) => !ways.obstacles.inside(p, ways.margin), ways.margin);\n const way = ways.fromPlug(plug, split);\n if (!way) continue;\n const trunk = dedupe(way);\n const end = trunk[trunk.length - 1]!;\n const prev = trunk.length >= 2 ? trunk[trunk.length - 2]! : plug.point;\n const len = dist(prev, end);\n const dir = len > 0 ? { x: (end.x - prev.x) / len, y: (end.y - prev.y) / len } : plug.normal;\n const branches: { edge: string; next: Point }[] = [];\n group.forEach((e, i) => {\n const pt = placePlug(targets[i]!, e.target, end);\n const branch = dedupe(ways.toPlug(end, pt) ?? [end, pt.point]);\n points.set(e.id, dedupe([...trunk, ...branch.slice(1)]));\n branches.push({ edge: e.id, next: branch[1] ?? pt.point });\n });\n bundles.push({ id: `b${bundles.length}`, key: id.split(\"\\u0000\")[2]!, node: s.id, edges: laneOrder(dir, end, branches), trunk });\n }\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const known = points.get(e.id);\n if (known) {\n routes.push({ edge: e.id, points: known });\n continue;\n }\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n }\n return { routes, bundles };\n },\n };\n return options.maxNodes === undefined ? router : { ...router, maxNodes: options.maxNodes };\n}\n","import type { Router } from \"../model.ts\";\nimport { cornersRouter } from \"./corners.ts\";\nimport { plugsRouter } from \"./plugs.ts\";\nimport { sectionsRouter } from \"./sections.ts\";\nimport { sharedRouter } from \"./shared.ts\";\nimport { straightRouter } from \"./straight.ts\";\nimport { byCollection, trunksRouter } from \"./trunks.ts\";\n\nexport { boxExit, straightRouter } from \"./straight.ts\";\nexport { plugsRouter } from \"./plugs.ts\";\nexport { cornersRouter, type CornersOptions } from \"./corners.ts\";\nexport { sharedRouter, type SharedOptions } from \"./shared.ts\";\nexport { sectionsRouter, type SectionsOptions } from \"./sections.ts\";\nexport { byCollection, groupEdges, laneOrder, splitPoint, trunksRouter, type TrunksOptions } from \"./trunks.ts\";\n\n/** The routers that the benchmark races. */\nexport const ROUTERS: readonly Router[] = [\n straightRouter,\n plugsRouter,\n cornersRouter({ name: \"corners\", maxNodes: 10_000 }),\n cornersRouter({ name: \"corners-smooth\", smooth: true, maxNodes: 10_000 }),\n trunksRouter({ name: \"trunks\", rule: byCollection, maxNodes: 10_000 }),\n sharedRouter({ name: \"shared\", rule: byCollection, maxNodes: 10_000 }),\n sharedRouter({ name: \"shared-all\", maxNodes: 10_000 }),\n sectionsRouter({ name: \"sections\", maxNodes: 100_000 }),\n sectionsRouter({ name: \"sections-tree\", stretch: Infinity, maxNodes: 100_000 }),\n];\n","import { dist, inflate, pointBoxDistance, segmentHitsBox, type Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport { fixedPortPoint, nodeIndex, type Graph, type Node, type Result } from \"../model.ts\";\n\n/** A broken hard rule. A correct router has none. */\nexport interface Violation {\n readonly rule: \"complete\" | \"ends-at-plugs\" | \"fixed-plugs\" | \"no-pass-through\" | \"counts-sum\" | \"bundle-trunk\" | \"run-shared\";\n readonly edge?: string;\n readonly detail: string;\n}\n\n/** The tolerance of the hard rules, in units of the plane. */\nexport const TOLERANCE = 0.5;\n\n/**\n * This function checks the hard rules of a result. Each edge has one route, and each route starts and ends at its nodes.\n * Fixed plugs stay in place. No route goes through a node that is not one of its ends. The counts of each level add up.\n *\n * Each route of a bundle starts with its trunk, and an edge is in one bundle at most.\n * Each run has two edges or more, and the route of each edge holds the points of the run in a row.\n * The function gives at most `limit` violations.\n */\nexport function checkProperties(graph: Graph, result: Result, limit = 100): Violation[] {\n const out: Violation[] = [];\n const add = (v: Violation): boolean => {\n out.push(v);\n return out.length >= limit;\n };\n const byId = nodeIndex(graph);\n const grid = new Grid<Node>(180);\n for (const n of graph.nodes) grid.add(n, n.box);\n const routes = new Map<string, (typeof result.routes)[number]>();\n for (const r of result.routes) routes.set(r.edge, r);\n for (const e of graph.edges) {\n const r = routes.get(e.id);\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n if (!r || r.points.length < 2) {\n if (add({ rule: \"complete\", edge: e.id, detail: \"no route\" })) return out;\n continue;\n }\n const a = r.points[0]!;\n const b = r.points[r.points.length - 1]!;\n if (pointBoxDistance(a, s.box) > TOLERANCE || pointBoxDistance(b, t.box) > TOLERANCE)\n if (add({ rule: \"ends-at-plugs\", edge: e.id, detail: \"an end of the route is away from its node\" })) return out;\n const fs = fixedPortPoint(s, e.source);\n const ft = fixedPortPoint(t, e.target);\n if ((fs && dist(fs, a) > TOLERANCE) || (ft && dist(ft, b) > TOLERANCE))\n if (add({ rule: \"fixed-plugs\", edge: e.id, detail: \"the route does not start or end at its fixed plug\" })) return out;\n for (let i = 1; i < r.points.length; i++) {\n const p = r.points[i - 1]!;\n const q = r.points[i]!;\n let hit: Node | undefined;\n grid.querySegment(p, q, 0, (n) => {\n if (!hit && n !== s && n !== t && segmentHitsBox(p, q, inflate(n.box, -TOLERANCE))) hit = n;\n });\n if (hit) {\n if (add({ rule: \"no-pass-through\", edge: e.id, detail: `segment ${i} goes through ${hit.id}` })) return out;\n break;\n }\n }\n }\n const bundled = new Set<string>();\n for (const b of result.bundles ?? []) {\n for (const id of b.edges) {\n const r = routes.get(id);\n const shares = r !== undefined && r.points.length >= b.trunk.length && b.trunk.every((p, i) => dist(p, r.points[i]!) <= TOLERANCE);\n if (bundled.has(id) || !shares)\n if (add({ rule: \"bundle-trunk\", edge: id, detail: `bundle ${b.id}: the route is in two bundles or does not start with the trunk` })) return out;\n bundled.add(id);\n }\n }\n for (const run of result.runs ?? []) {\n if (run.edges.length < 2)\n if (add({ rule: \"run-shared\", detail: `run ${run.id} has fewer than two edges` })) return out;\n for (const id of run.edges) {\n const r = routes.get(id);\n if (!r || !(holds(r.points, run.points) || holds(r.points, [...run.points].reverse())))\n if (add({ rule: \"run-shared\", edge: id, detail: `run ${run.id}: the route does not hold the points of the run in a row` })) return out;\n }\n }\n for (const level of result.levels ?? []) {\n const itemOf = new Map<string, string>();\n for (const it of level.items) for (const n of it.nodes) itemOf.set(n, it.id);\n if (itemOf.size !== graph.nodes.length)\n if (add({ rule: \"counts-sum\", detail: `level ${level.depth}: the items hold ${itemOf.size} of ${graph.nodes.length} nodes` }))\n return out;\n let between = 0;\n for (const e of graph.edges) if (itemOf.get(e.source.node) !== itemOf.get(e.target.node)) between++;\n const sum = level.links.reduce((s, l) => s + l.count, 0);\n if (sum !== between)\n if (add({ rule: \"counts-sum\", detail: `level ${level.depth}: the links count ${sum} edges, not ${between}` })) return out;\n }\n return out;\n}\n\n/** This function tells if the polyline `p` holds the points of `part` in a row. */\nfunction holds(p: readonly Point[], part: readonly Point[]): boolean {\n if (part.length === 0) return true;\n for (let i = 0; i + part.length <= p.length; i++) if (part.every((q, j) => dist(q, p[i + j]!) <= TOLERANCE)) return true;\n return false;\n}\n","import {\n bendCount,\n dist,\n frechet,\n inflectionCount,\n polylineLength,\n segmentBoxDistance,\n segmentsCross,\n type Box,\n type Point,\n} from \"../geom.ts\";\nimport { rng } from \"../fixtures.ts\";\nimport { Grid } from \"../grid.ts\";\nimport { nodeIndex, type Graph, type Node, type Result } from \"../model.ts\";\n\n/** The quality of a result. Lower is better for each value except `clearance`. */\nexport interface Quality {\n /** The length of all drawn lines. A segment that several routes share counts one time. */\n readonly ink: number;\n /** The number of points where two drawn segments cross. */\n readonly crossings: number;\n /** This value is true when `crossings` is an estimate from a sample of the segments. */\n readonly crossingsEstimated: boolean;\n /** The mean number of bends of a route. */\n readonly bends: number;\n /** The mean number of inflections of a route. */\n readonly inflections: number;\n /** The mean distance from a route to the nearest node that is not one of its ends, up to `CLEARANCE_CAP`. */\n readonly clearance: number;\n /** The share of the routes that come closer than 4 units to a node that is not one of their ends. */\n readonly tight: number;\n /** The mean ratio of the length of a route to the distance between its ends. */\n readonly detour: number;\n /** The mean angle, in degrees, between the first or last segment of a route and the normal of the side of its node. */\n readonly plugAngle: number;\n}\n\n/** The clearance stops at this distance. */\nexport const CLEARANCE_CAP = 40;\nconst TIGHT = 4;\nconst EXACT_CROSSINGS = 20_000;\nconst SAMPLE = 2_000;\n\nconst key = (p: Point): string => `${Math.round(p.x * 8)},${Math.round(p.y * 8)}`;\n\n/** This function measures the quality of a result. */\nexport function measureQuality(graph: Graph, result: Result): Quality {\n const byId = nodeIndex(graph);\n const nodes = new Grid<Node>(180);\n for (const n of graph.nodes) nodes.add(n, n.box);\n\n // The drawn segments: one for each distinct pair of ends.\n const segs: [Point, Point][] = [];\n const seen = new Set<string>();\n let bends = 0;\n let infl = 0;\n let clear = 0;\n let tight = 0;\n let detour = 0;\n let detourN = 0;\n let angle = 0;\n let angleN = 0;\n for (const r of result.routes) {\n const p = r.points;\n for (let i = 1; i < p.length; i++) {\n const ka = key(p[i - 1]!);\n const kb = key(p[i]!);\n if (ka === kb) continue;\n const k = ka < kb ? `${ka}|${kb}` : `${kb}|${ka}`;\n if (seen.has(k)) continue;\n seen.add(k);\n segs.push([p[i - 1]!, p[i]!]);\n }\n bends += bendCount(p);\n infl += inflectionCount(p);\n const ends = endNodes(graph, byId, r.edge);\n let c = CLEARANCE_CAP;\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n nodes.querySegment(a, b, c, (n) => {\n if (n !== ends.source && n !== ends.target) c = Math.min(c, segmentBoxDistance(a, b, n.box));\n });\n }\n clear += c;\n if (c < TIGHT) tight++;\n if (p.length >= 2) {\n const d = dist(p[0]!, p[p.length - 1]!);\n if (d > 1) {\n detour += polylineLength(p) / d;\n detourN++;\n }\n for (const [at, next, node] of [\n [p[0]!, p[1]!, ends.source],\n [p[p.length - 1]!, p[p.length - 2]!, ends.target],\n ] as const) {\n if (!node) continue;\n const a = sideAngle(node.box, at, next);\n if (a !== undefined) {\n angle += a;\n angleN++;\n }\n }\n }\n }\n const n = Math.max(1, result.routes.length);\n let ink = 0;\n for (const [a, b] of segs) ink += dist(a, b);\n const [crossings, crossingsEstimated] = countCrossings(segs);\n return {\n ink,\n crossings,\n crossingsEstimated,\n bends: bends / n,\n inflections: infl / n,\n clearance: clear / n,\n tight: tight / n,\n detour: detourN ? detour / detourN : 1,\n plugAngle: angleN ? angle / angleN : 0,\n };\n}\n\ninterface Ends {\n readonly source: Node | undefined;\n readonly target: Node | undefined;\n}\n\nfunction endNodes(graph: Graph, byId: Map<string, Node>, edgeId: string): Ends {\n const e = edgeIndex(graph).get(edgeId);\n return { source: e && byId.get(e.source.node), target: e && byId.get(e.target.node) };\n}\n\nconst edgeIndexes = new WeakMap<Graph, Map<string, Graph[\"edges\"][number]>>();\nfunction edgeIndex(graph: Graph): Map<string, Graph[\"edges\"][number]> {\n let m = edgeIndexes.get(graph);\n if (!m) {\n m = new Map();\n for (const e of graph.edges) m.set(e.id, e);\n edgeIndexes.set(graph, m);\n }\n return m;\n}\n\n/**\n * This function gives an angle in degrees: the angle between the segment from `at` to `next` and the outward normal.\n * The normal is the normal of the side of the box nearest to `at`. A route that starts inside the box (an interior route) gives no angle.\n */\nexport function sideAngle(box: Box, at: Point, next: Point): number | undefined {\n const d = [\n [Math.abs(at.y - box.y), 0, -1],\n [Math.abs(at.x - (box.x + box.w)), 1, 0],\n [Math.abs(at.y - (box.y + box.h)), 0, 1],\n [Math.abs(at.x - box.x), -1, 0],\n ].sort((a, b) => a[0]! - b[0]!)[0]!;\n if (d[0]! > 1) return undefined;\n const vx = next.x - at.x;\n const vy = next.y - at.y;\n const l = Math.hypot(vx, vy);\n if (l === 0) return undefined;\n const cos = Math.max(-1, Math.min(1, (vx * d[1]! + vy * d[2]!) / l));\n return (Math.acos(cos) * 180) / Math.PI;\n}\n\n/**\n * This function counts the crossings of a set of segments with a grid of buckets.\n * Above 20 000 segments, it counts the crossings of a seeded sample of 2 000 segments and scales the count.\n */\nexport function countCrossings(segs: readonly (readonly [Point, Point])[]): [number, boolean] {\n if (segs.length < 2) return [0, false];\n const len = segs.reduce((s, [a, b]) => s + dist(a, b), 0) / segs.length;\n const grid = new Grid<number>(Math.max(20, len));\n segs.forEach(([a, b], i) => grid.addSegment(i, a, b));\n const exact = segs.length <= EXACT_CROSSINGS;\n const R = rng(segs.length);\n const pick = exact ? segs.map((_, i) => i) : Array.from({ length: SAMPLE }, () => Math.floor(R() * segs.length));\n let count = 0;\n for (const i of pick) {\n const [a, b] = segs[i]!;\n grid.querySegment(a, b, 0, (j) => {\n if (exact && j <= i) return;\n if (j === i) return;\n const [c, d] = segs[j]!;\n if (segmentsCross(a, b, c, d)) count++;\n });\n }\n return exact ? [count, false] : [Math.round((count * segs.length) / (2 * pick.length)), true];\n}\n\n/** The change between two results of the same graph: the Fréchet distance between the two routes of each edge. */\nexport interface Stability {\n readonly mean: number;\n readonly max: number;\n /** The share of the routes that moved more than 1 unit. */\n readonly moved: number;\n}\n\n/** This function measures how much the routes changed between two results. */\nexport function measureStability(before: Result, after: Result): Stability {\n const prev = new Map(before.routes.map((r) => [r.edge, r.points] as const));\n let sum = 0;\n let max = 0;\n let moved = 0;\n let n = 0;\n for (const r of after.routes) {\n const p = prev.get(r.edge);\n if (!p) continue;\n const f = frechet(p, r.points);\n sum += f;\n max = Math.max(max, f);\n if (f > 1) moved++;\n n++;\n }\n return { mean: n ? sum / n : 0, max, moved: n ? moved / n : 0 };\n}\n","import { makeFixture, type FixtureSpec } from \"../fixtures.ts\";\nimport type { Graph, Result, Router } from \"../model.ts\";\nimport { checkProperties, type Violation } from \"./properties.ts\";\nimport { measureQuality, type Quality } from \"./quality.ts\";\n\n// The core runs in any host, so it reads the clock without the types of Node or the browser.\nconst now = (): number => (globalThis as { performance?: { now(): number } }).performance?.now() ?? Date.now();\n\n/** One row of the benchmark: one router on one fixture. */\nexport interface BenchRow {\n readonly router: string;\n readonly fixture: string;\n readonly nodes: number;\n readonly edges: number;\n /** The median time of one run, in milliseconds. */\n readonly ms: number;\n /** This value is false when two runs on the same input gave different results. */\n readonly deterministic: boolean;\n readonly violations: number;\n /** The first violations, for the report. */\n readonly sample: readonly Violation[];\n readonly quality: Quality;\n}\n\n/** The options of a benchmark run. */\nexport interface BenchOptions {\n /** The number of timed routes of each fixture by each router. The default is 3. */\n readonly repeat?: number;\n}\n\n/** This function routes each fixture with each router, checks the hard rules and measures the quality. */\nexport function runBenchmark(routers: readonly Router[], fixtures: readonly FixtureSpec[], options: BenchOptions = {}): BenchRow[] {\n const rows: BenchRow[] = [];\n for (const spec of fixtures) {\n const graph = makeFixture(spec);\n for (const router of routers) if (graph.nodes.length <= (router.maxNodes ?? Infinity)) rows.push(benchOne(router, spec.name, graph, options.repeat ?? 3));\n }\n return rows;\n}\n\n/**\n * This function tells if two values hold the same data, as JSON sees it. It does not make a string,\n * because the result of a large graph can be longer than the longest string.\n */\nexport function sameData(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a === \"number\" && typeof b === \"number\") return Number.isNaN(a) && Number.isNaN(b);\n if (typeof a !== \"object\" || typeof b !== \"object\" || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a)) {\n const y = b as unknown[];\n if (a.length !== y.length) return false;\n for (let i = 0; i < a.length; i++) if (!sameData(a[i], y[i])) return false;\n return true;\n }\n const x = a as Record<string, unknown>;\n const y = b as Record<string, unknown>;\n const kx = Object.keys(x).filter((k) => x[k] !== undefined);\n const ky = Object.keys(y).filter((k) => y[k] !== undefined);\n if (kx.length !== ky.length) return false;\n for (const k of kx) if (!sameData(x[k], y[k])) return false;\n return true;\n}\n\n/** This function routes one graph with one router and measures the result. */\nexport function benchOne(router: Router, fixture: string, graph: Graph, repeat = 3): BenchRow {\n const times: number[] = [];\n let first: Result | undefined;\n let deterministic = true;\n for (let i = 0; i < Math.max(2, repeat); i++) {\n const t0 = now();\n const r = router.route(graph);\n times.push(now() - t0);\n if (!first) first = r;\n else if (i === 1 && !sameData(r, first)) deterministic = false;\n }\n times.sort((a, b) => a - b);\n const result = first!;\n const all = checkProperties(graph, result, 1_000_000);\n return {\n router: router.name,\n fixture,\n nodes: graph.nodes.length,\n edges: graph.edges.length,\n ms: times[Math.floor(times.length / 2)]!,\n deterministic,\n violations: all.length,\n sample: all.slice(0, 5),\n quality: measureQuality(graph, result),\n };\n}\n\n/** This function writes the rows as a Markdown table. */\nexport function formatTable(rows: readonly BenchRow[]): string {\n const head = \"| router | fixture | nodes | edges | ms | same twice | violations | ink | crossings | bends | inflections | clearance | tight | detour | plug angle |\";\n const line = \"|---|---|---:|---:|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const f = (v: number, d = 2): string => (Number.isInteger(v) ? String(v) : v.toFixed(d));\n const body = rows.map((r) => {\n const q = r.quality;\n return `| ${r.router} | ${r.fixture} | ${r.nodes} | ${r.edges} | ${f(r.ms, 1)} | ${r.deterministic ? \"yes\" : \"NO\"} | ${r.violations} | ${Math.round(q.ink)} | ${q.crossingsEstimated ? \"≈\" : \"\"}${q.crossings} | ${f(q.bends)} | ${f(q.inflections)} | ${f(q.clearance, 1)} | ${f(q.tight)} | ${f(q.detour)} | ${f(q.plugAngle, 1)} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["SIDES","turn","dedupe"],"sources":["../src/geom.ts","../src/grid.ts","../src/model.ts","../src/fixtures.ts","../src/plugs.ts","../src/curves.ts","../src/visibility.ts","../src/ways.ts","../src/segments.ts","../src/sections.ts","../src/routers/corners.ts","../src/routers/plugs.ts","../src/levels.ts","../src/routers/sections.ts","../src/routers/shared.ts","../src/routers/straight.ts","../src/routers/trunks.ts","../src/routers/index.ts","../src/bench/properties.ts","../src/bench/quality.ts","../src/bench/run.ts"],"sourcesContent":["/** A point in the plane. */\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** A box with its top-left corner at (`x`, `y`). */\nexport interface Box {\n readonly x: number;\n readonly y: number;\n readonly w: number;\n readonly h: number;\n}\n\n/** This function gives the distance between two points. */\nexport function dist(a: Point, b: Point): number {\n const dx = a.x - b.x;\n const dy = a.y - b.y;\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/** This function gives the center of a box. */\nexport function center(b: Box): Point {\n return { x: b.x + b.w / 2, y: b.y + b.h / 2 };\n}\n\n/** This function gives a box that is larger by `m` on each side. A negative `m` makes the box smaller. */\nexport function inflate(b: Box, m: number): Box {\n return { x: b.x - m, y: b.y - m, w: Math.max(0, b.w + 2 * m), h: Math.max(0, b.h + 2 * m) };\n}\n\n/** This function gives the sum of the lengths of the segments of a polyline. */\nexport function polylineLength(p: readonly Point[]): number {\n let s = 0;\n for (let i = 1; i < p.length; i++) s += dist(p[i - 1]!, p[i]!);\n return s;\n}\n\nconst orient = (a: Point, b: Point, c: Point): number => (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n\n/**\n * This function tells if the segments `ab` and `cd` cross at one point inside both of them.\n * Segments that only touch at an end, or that are collinear, do not cross.\n */\nexport function segmentsCross(a: Point, b: Point, c: Point, d: Point): boolean {\n const d1 = orient(c, d, a);\n const d2 = orient(c, d, b);\n const d3 = orient(a, b, c);\n const d4 = orient(a, b, d);\n return d1 * d2 < 0 && d3 * d4 < 0;\n}\n\n/**\n * This function tells if the segment `ab` goes through the inside of the box.\n * The function clips the segment to the box (Liang-Barsky) and asks for a part longer than `eps`.\n */\nexport function segmentHitsBox(a: Point, b: Point, box: Box, eps = 1e-6): boolean {\n return segmentHitsRect(a, b, box.x, box.y, box.x + box.w, box.y + box.h, eps);\n}\n\n/** This function tells if the segment `ab` goes through the inside of the box from (`x0`, `y0`) to (`x1`, `y1`). */\nexport function segmentHitsRect(a: Point, b: Point, x0: number, y0: number, x1: number, y1: number, eps = 1e-6): boolean {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n let t0 = 0;\n let t1 = 1;\n if (dx === 0) {\n if (a.x <= x0 || a.x >= x1) return false;\n } else {\n const ta = (x0 - a.x) / dx;\n const tb = (x1 - a.x) / dx;\n t0 = Math.max(t0, Math.min(ta, tb));\n t1 = Math.min(t1, Math.max(ta, tb));\n if (t0 > t1) return false;\n }\n if (dy === 0) {\n if (a.y <= y0 || a.y >= y1) return false;\n } else {\n const ta = (y0 - a.y) / dy;\n const tb = (y1 - a.y) / dy;\n t0 = Math.max(t0, Math.min(ta, tb));\n t1 = Math.min(t1, Math.max(ta, tb));\n if (t0 > t1) return false;\n }\n return (t1 - t0) * Math.sqrt(dx * dx + dy * dy) > eps;\n}\n\n/** This function gives the distance from a point to a box. The distance is 0 when the point is in the box. */\nexport function pointBoxDistance(p: Point, b: Box): number {\n const qx = Math.max(b.x, Math.min(b.x + b.w, p.x));\n const qy = Math.max(b.y, Math.min(b.y + b.h, p.y));\n return Math.hypot(p.x - qx, p.y - qy);\n}\n\n/** This function gives the distance from a point to the segment `ab`. */\nexport function pointSegmentDistance(p: Point, a: Point, b: Point): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const l2 = dx * dx + dy * dy;\n const t = l2 === 0 ? 0 : Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / l2));\n return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy));\n}\n\n/** This function gives the distance from the segment `ab` to a box. The distance is 0 when they touch. */\nexport function segmentBoxDistance(a: Point, b: Point, box: Box): number {\n if (segmentHitsBox(a, b, box, 0) || pointBoxDistance(a, box) === 0 || pointBoxDistance(b, box) === 0) return 0;\n const corners: Point[] = [\n { x: box.x, y: box.y },\n { x: box.x + box.w, y: box.y },\n { x: box.x, y: box.y + box.h },\n { x: box.x + box.w, y: box.y + box.h },\n ];\n let d = Math.min(pointBoxDistance(a, box), pointBoxDistance(b, box));\n for (const c of corners) d = Math.min(d, pointSegmentDistance(c, a, b));\n return d;\n}\n\n/**\n * This function gives the turn at each inner vertex of a polyline, in radians, from -π to π.\n * A positive turn is counterclockwise in a frame with the y axis up. The function skips segments shorter than `eps`.\n */\nexport function turns(p: readonly Point[], eps = 1e-9): number[] {\n const q: Point[] = [];\n for (const v of p) if (q.length === 0 || dist(q[q.length - 1]!, v) > eps) q.push(v);\n const out: number[] = [];\n for (let i = 1; i + 1 < q.length; i++) {\n const a = q[i - 1]!;\n const b = q[i]!;\n const c = q[i + 1]!;\n const cr = (b.x - a.x) * (c.y - b.y) - (b.y - a.y) * (c.x - b.x);\n const dt = (b.x - a.x) * (c.x - b.x) + (b.y - a.y) * (c.y - b.y);\n out.push(Math.atan2(cr, dt));\n }\n return out;\n}\n\n/** This function counts the vertices of a polyline where the direction changes by more than `minTurn` radians. */\nexport function bendCount(p: readonly Point[], minTurn = 0.05): number {\n return turns(p).filter((t) => Math.abs(t) > minTurn).length;\n}\n\n/**\n * This function counts the inflections of a polyline: the changes of the sign of the turn.\n * A turn smaller than `minTurn` radians does not count. Thus a straight part between two turns keeps their signs.\n */\nexport function inflectionCount(p: readonly Point[], minTurn = 1e-3): number {\n let n = 0;\n let last = 0;\n for (const t of turns(p)) {\n if (Math.abs(t) <= minTurn) continue;\n const s = Math.sign(t);\n if (last !== 0 && s !== last) n++;\n last = s;\n }\n return n;\n}\n\n/**\n * This function gives the discrete Fréchet distance between two polylines (Eiter and Mannila, 1994).\n * The cost is O(|p|·|q|) in time and O(|q|) in memory.\n */\nexport function frechet(p: readonly Point[], q: readonly Point[]): number {\n if (p.length === 0 || q.length === 0) return p.length === q.length ? 0 : Infinity;\n let prev = new Float64Array(q.length);\n let cur = new Float64Array(q.length);\n for (let i = 0; i < p.length; i++) {\n for (let j = 0; j < q.length; j++) {\n const d = dist(p[i]!, q[j]!);\n if (i === 0 && j === 0) cur[j] = d;\n else if (i === 0) cur[j] = Math.max(cur[j - 1]!, d);\n else if (j === 0) cur[j] = Math.max(prev[j]!, d);\n else cur[j] = Math.max(Math.min(prev[j]!, prev[j - 1]!, cur[j - 1]!), d);\n }\n [prev, cur] = [cur, prev];\n }\n return prev[q.length - 1]!;\n}\n","import type { Box, Point } from \"./geom.ts\";\n\n/**\n * A uniform grid of buckets over the plane. A box item goes into each bucket that the box touches.\n * A segment item goes only into the buckets along the segment, so a long diagonal segment stays cheap.\n * A query gives each item in the buckets that it touches, one time each.\n */\nexport class Grid<T> {\n readonly #cell: number;\n readonly #buckets = new Map<number, number[]>();\n readonly #items: T[] = [];\n readonly #ids = new Map<T, number>();\n // The stamp of the last query that gave each item, by the index of the item.\n #seen = new Int32Array(16);\n #stamp = 0;\n\n /** This constructor makes an empty grid with square buckets of side `cell`. */\n constructor(cell: number) {\n this.#cell = Math.max(1e-9, cell);\n }\n\n #key(i: number, j: number): number {\n // The key packs the two bucket indices into one number. Each index stays within ±2^20.\n return (i + 1_048_576) * 2_097_152 + (j + 1_048_576);\n }\n\n #id(item: T): number {\n let id = this.#ids.get(item);\n if (id === undefined) {\n id = this.#items.length;\n this.#ids.set(item, id);\n this.#items.push(item);\n if (id >= this.#seen.length) {\n const seen = new Int32Array(this.#seen.length * 2);\n seen.set(this.#seen);\n this.#seen = seen;\n }\n }\n return id;\n }\n\n #put(id: number, x0: number, y0: number, x1: number, y1: number): void {\n const c = this.#cell;\n const i1 = Math.floor(x1 / c);\n const j1 = Math.floor(y1 / c);\n for (let i = Math.floor(x0 / c); i <= i1; i++) {\n for (let j = Math.floor(y0 / c); j <= j1; j++) {\n const key = this.#key(i, j);\n const list = this.#buckets.get(key);\n if (list === undefined) this.#buckets.set(key, [id]);\n else if (list[list.length - 1] !== id) list.push(id);\n }\n }\n }\n\n #take(stamp: number, x0: number, y0: number, x1: number, y1: number, visit: (item: T) => void): void {\n const c = this.#cell;\n const i1 = Math.floor(x1 / c);\n const j1 = Math.floor(y1 / c);\n const seen = this.#seen;\n for (let i = Math.floor(x0 / c); i <= i1; i++) {\n for (let j = Math.floor(y0 / c); j <= j1; j++) {\n const list = this.#buckets.get(this.#key(i, j));\n if (list === undefined) continue;\n for (const id of list) {\n if (seen[id] === stamp) continue;\n seen[id] = stamp;\n visit(this.#items[id]!);\n }\n }\n }\n }\n\n // The buckets along a segment, widened by `margin`: the boxes of steps of at most half a bucket.\n #segment(a: Point, b: Point, margin: number, each: (x0: number, y0: number, x1: number, y1: number) => void): void {\n const n = Math.max(1, Math.ceil(Math.hypot(b.x - a.x, b.y - a.y) / (this.#cell / 2)));\n let px = a.x;\n let py = a.y;\n for (let k = 1; k <= n; k++) {\n const qx = k === n ? b.x : a.x + ((b.x - a.x) * k) / n;\n const qy = k === n ? b.y : a.y + ((b.y - a.y) * k) / n;\n each(Math.min(px, qx) - margin, Math.min(py, qy) - margin, Math.max(px, qx) + margin, Math.max(py, qy) + margin);\n px = qx;\n py = qy;\n }\n }\n\n /** This method adds an item with its bounding box. */\n add(item: T, b: Box): void {\n this.#put(this.#id(item), b.x, b.y, b.x + b.w, b.y + b.h);\n }\n\n /** This method adds the segment `ab` as an item. */\n addSegment(item: T, a: Point, b: Point): void {\n const id = this.#id(item);\n this.#segment(a, b, 0, (x0, y0, x1, y1) => this.#put(id, x0, y0, x1, y1));\n }\n\n /** This method gives each item whose buckets touch the box to `visit`, one time each. */\n query(b: Box, visit: (item: T) => void): void {\n this.#take(++this.#stamp, b.x, b.y, b.x + b.w, b.y + b.h, visit);\n }\n\n /** This method gives each item whose buckets come within `margin` of the segment `ab` to `visit`, one time each. */\n querySegment(a: Point, b: Point, margin: number, visit: (item: T) => void): void {\n const stamp = ++this.#stamp;\n this.#segment(a, b, margin, (x0, y0, x1, y1) => this.#take(stamp, x0, y0, x1, y1, visit));\n }\n}\n\n/** This function gives the bounding box of the segment `ab`. */\nexport function segmentBounds(a: Point, b: Point): Box {\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n return { x, y, w: Math.abs(a.x - b.x), h: Math.abs(a.y - b.y) };\n}\n","import type { Box, Point } from \"./geom.ts\";\n\n/** A side of a node box. */\nexport type Side = \"north\" | \"east\" | \"south\" | \"west\";\n\n/**\n * A plug of a node: a place where edges go into the node.\n * A plug with `at` is fixed. The router does not move it. A plug without `at` is free: the router places it.\n */\nexport interface Port {\n readonly id: string;\n /** This point is the fixed place of the plug, relative to the top-left corner of the node box. */\n readonly at?: Point;\n /** This side is where a free plug goes. Without it, the router picks the side. */\n readonly side?: Side;\n}\n\n/** A node: a box that routes must not go through. */\nexport interface Node {\n readonly id: string;\n readonly box: Box;\n readonly ports?: readonly Port[];\n}\n\n/** One end of an edge: a node, and optionally one plug of that node. */\nexport interface End {\n readonly node: string;\n readonly port?: string;\n}\n\n/** An edge between two nodes. `data` is free for the grouping rules. */\nexport interface Edge {\n readonly id: string;\n readonly source: End;\n readonly target: End;\n readonly data?: Readonly<Record<string, unknown>>;\n}\n\n/** The input of a router. */\nexport interface Graph {\n readonly nodes: readonly Node[];\n readonly edges: readonly Edge[];\n}\n\n/** The route of one edge: a polyline from the source plug to the target plug, in absolute coordinates. */\nexport interface Route {\n readonly edge: string;\n readonly points: readonly Point[];\n}\n\n/**\n * One zoom level of a result. Each shown item is a node or a group of nodes.\n * Each link joins two shown items and carries the count of the edges that it stands for.\n */\nexport interface Level {\n readonly depth: number;\n readonly items: readonly LevelItem[];\n readonly links: readonly LevelLink[];\n}\n\n/** A shown item of a level: one node, or a group that stands for its nodes. */\nexport interface LevelItem {\n readonly id: string;\n readonly box: Box;\n readonly nodes: readonly string[];\n}\n\n/** A link of a level: the edges between two shown items, drawn as one path. */\nexport interface LevelLink {\n readonly source: string;\n readonly target: string;\n readonly count: number;\n readonly points: readonly Point[];\n}\n\n/** The output of a router. `levels` is present when the router makes zoom levels. */\nexport interface Result {\n readonly routes: readonly Route[];\n readonly levels?: readonly Level[];\n readonly bundles?: readonly Bundle[];\n /** The stretches of way that several routes share, if the router gives them. */\n readonly runs?: readonly SharedRun[];\n}\n\n/**\n * A bundle: edges from one node that share one plug and one trunk. Then the edges fan out to their targets.\n * A renderer draws a bundle as one fat edge with a count, or as one lane for each edge.\n */\nexport interface Bundle {\n readonly id: string;\n /** The key that the grouping rule gave each edge of the bundle. */\n readonly key: string;\n /** The node where the edges share their plug. */\n readonly node: string;\n /** The edges in lane order. Lane 0 turns most to the left of the trunk, in a frame with the y axis down. */\n readonly edges: readonly string[];\n /** The shared start of each route of the bundle, from the plug to the split point. */\n readonly trunk: readonly Point[];\n}\n\n/**\n * A stretch of way that several routes share, with the same points. Each route of `edges` has `points` in it,\n * in this order or in the reverse order. A renderer draws a run as one fat line, or as one lane for each edge.\n */\nexport interface SharedRun {\n readonly id: string;\n /** The key of the grouping rule of the edges. */\n readonly key: string;\n readonly points: readonly Point[];\n /** The edges in lane order. Lane 0 is on the left of the run, from its first point to its last. The y axis points down. */\n readonly edges: readonly string[];\n}\n\n/** A grouping rule gives each edge a key. The edges from one plug with one key make a bundle. An edge without a key stays alone. */\nexport type GroupRule = (edge: Edge) => string | undefined;\n\n/** A router: a strategy with a name. The same input must give the same result. */\nexport interface Router {\n readonly name: string;\n /** The benchmark skips a fixture with more nodes than this. Without it, the router takes each fixture. */\n readonly maxNodes?: number;\n route(graph: Graph): Result;\n}\n\n/** This function gives a map from the id of each node to the node. */\nexport function nodeIndex(g: Graph): Map<string, Node> {\n const m = new Map<string, Node>();\n for (const n of g.nodes) m.set(n.id, n);\n return m;\n}\n\n/** This function gives the absolute place of a fixed plug, or `undefined` for a free plug or no plug. */\nexport function fixedPortPoint(node: Node, end: End): Point | undefined {\n if (end.port === undefined) return undefined;\n const p = node.ports?.find((q) => q.id === end.port);\n if (p?.at === undefined) return undefined;\n return { x: node.box.x + p.at.x, y: node.box.y + p.at.y };\n}\n","import type { Box, Point } from \"./geom.ts\";\nimport { Grid } from \"./grid.ts\";\nimport type { Edge, Graph, Node, Port, Side } from \"./model.ts\";\n\n/** This function gives a seeded random source with values in [0, 1) (mulberry32). */\nexport function rng(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = a;\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/**\n * The ways a fixture puts its nodes and picks its edges. In `collections`, each cluster is one collection,\n * and some nodes link to many nodes of one other collection (a fan-out).\n */\nexport type FixtureKind = \"uniform\" | \"clustered\" | \"grid\" | \"hubs\" | \"collections\";\n\n/** The parameters of a generated graph. */\nexport interface FixtureSpec {\n readonly name: string;\n readonly kind: FixtureKind;\n readonly nodes: number;\n /** The number of edges is about `nodes × edgesPerNode`. */\n readonly edgesPerNode: number;\n readonly seed: number;\n /** This share of the edges, from 0 to 1, joins a node near the source. */\n readonly locality?: number;\n /** This share of the nodes, from 0 to 1, has one fixed plug that its outgoing edges use. */\n readonly fixedPorts?: number;\n}\n\n/** The fixtures of the benchmark, from 10 to 100 000 nodes. */\nexport const FIXTURES: readonly FixtureSpec[] = [\n { name: \"tiny-uniform\", kind: \"uniform\", nodes: 10, edgesPerNode: 1.5, seed: 1 },\n { name: \"small-clustered\", kind: \"clustered\", nodes: 100, edgesPerNode: 2, seed: 2, fixedPorts: 0.2 },\n { name: \"grid-400\", kind: \"grid\", nodes: 400, edgesPerNode: 2, seed: 3 },\n { name: \"mid-uniform\", kind: \"uniform\", nodes: 1000, edgesPerNode: 2, seed: 4 },\n { name: \"mid-clustered\", kind: \"clustered\", nodes: 1000, edgesPerNode: 3, seed: 5, fixedPorts: 0.2 },\n { name: \"mid-hubs\", kind: \"hubs\", nodes: 1000, edgesPerNode: 2, seed: 6 },\n { name: \"mid-fanout\", kind: \"collections\", nodes: 1000, edgesPerNode: 2, seed: 9 },\n { name: \"large-clustered\", kind: \"clustered\", nodes: 10_000, edgesPerNode: 3, seed: 7 },\n { name: \"huge-clustered\", kind: \"clustered\", nodes: 100_000, edgesPerNode: 2, seed: 8 },\n];\n\nconst COLLECTIONS = [\"users\", \"modes\", \"speeds\", \"scores\", \"teams\"] as const;\nconst SIDES: readonly Side[] = [\"north\", \"east\", \"south\", \"west\"];\nconst GAP = 12;\nconst SPACING = 90;\n\n/**\n * This function makes the graph of a fixture. The same spec always gives the same graph.\n * Node boxes do not overlap, and a gap of 12 units stays between them.\n */\nexport function makeFixture(spec: FixtureSpec): Graph {\n const R = rng(spec.seed * 2654435761 + spec.nodes);\n const gauss = (): number => Math.sqrt(-2 * Math.log(R() + 1e-12)) * Math.cos(2 * Math.PI * R());\n const side = Math.sqrt(spec.nodes) * SPACING;\n const grid = new Grid<Box>(SPACING);\n const nodes: Node[] = [];\n const clusterOf: number[] = [];\n const free = (b: Box): boolean => {\n let ok = true;\n const g: Box = { x: b.x - GAP, y: b.y - GAP, w: b.w + 2 * GAP, h: b.h + 2 * GAP };\n grid.query(g, (o) => {\n if (ok && o.x < g.x + g.w && g.x < o.x + o.w && o.y < g.y + g.h && g.y < o.y + o.h) ok = false;\n });\n return ok;\n };\n const centers: Point[] = Array.from({ length: Math.max(3, Math.round(Math.sqrt(spec.nodes) / 3)) }, () => ({\n x: side * (0.1 + 0.8 * R()),\n y: side * (0.1 + 0.8 * R()),\n }));\n const spread = side / (2.5 * Math.sqrt(centers.length));\n const cols = Math.ceil(Math.sqrt(spec.nodes));\n let tries = 0;\n while (nodes.length < spec.nodes && tries++ < spec.nodes * 200) {\n const w = 30 + Math.floor(R() * 30);\n const h = 18 + Math.floor(R() * 12);\n let cx: number;\n let cy: number;\n let cluster = -1;\n if (spec.kind === \"grid\") {\n const i = nodes.length;\n cx = ((i % cols) + 0.5) * SPACING;\n cy = (Math.floor(i / cols) + 0.5) * SPACING;\n } else if (spec.kind === \"clustered\" || spec.kind === \"collections\") {\n cluster = Math.floor(R() * centers.length);\n const c = centers[cluster]!;\n cx = c.x + gauss() * spread;\n cy = c.y + gauss() * spread;\n } else {\n cx = R() * side;\n cy = R() * side;\n }\n const box: Box = { x: Math.round(cx - w / 2), y: Math.round(cy - h / 2), w, h };\n if (spec.kind !== \"grid\" && !free(box)) continue;\n grid.add(box, box);\n clusterOf.push(cluster);\n const id = `n${nodes.length}`;\n if (R() < (spec.fixedPorts ?? 0)) {\n const s = SIDES[Math.floor(R() * 4)]!;\n const t = 0.2 + 0.6 * R();\n const at: Point =\n s === \"north\" ? { x: w * t, y: 0 } : s === \"south\" ? { x: w * t, y: h } : s === \"west\" ? { x: 0, y: h * t } : { x: w, y: h * t };\n const ports: Port[] = [{ id: \"out\", at: { x: Math.round(at.x), y: Math.round(at.y) } }];\n nodes.push({ id, box, ports });\n } else nodes.push({ id, box });\n }\n return { nodes, edges: makeEdges(spec, nodes, clusterOf, R) };\n}\n\nfunction makeEdges(spec: FixtureSpec, nodes: readonly Node[], clusterOf: readonly number[], R: () => number): Edge[] {\n const n = nodes.length;\n if (n < 2) return [];\n const locality = spec.locality ?? 0.65;\n const near = new Grid<number>(SPACING * 2);\n nodes.forEach((v, i) => near.add(i, v.box));\n const kindOf =\n spec.kind === \"collections\"\n ? clusterOf.map((c) => `${COLLECTIONS[c % COLLECTIONS.length]!}-${c}`)\n : nodes.map(() => COLLECTIONS[Math.floor(R() * COLLECTIONS.length)]!);\n // Hubs: a few nodes get most of the far edges (preferential attachment by a power law).\n const pickFar = (): number => (spec.kind === \"hubs\" ? Math.floor(n * R() ** 3) : Math.floor(R() * n));\n const target = Math.round(n * spec.edgesPerNode);\n const seen = new Set<string>();\n const edges: Edge[] = [];\n const add = (u: number, v: number): void => {\n const key = u < v ? `${u}-${v}` : `${v}-${u}`;\n if (u === v || seen.has(key)) return;\n seen.add(key);\n const src = nodes[u]!;\n edges.push({\n id: `e${edges.length}`,\n source: src.ports ? { node: src.id, port: \"out\" } : { node: src.id },\n target: { node: nodes[v]!.id },\n data: { collection: kindOf[v]! },\n });\n };\n if (spec.kind === \"collections\") {\n // Six of ten edges are fan-outs: a node links to 4 to 15 nodes of one other cluster.\n const members = new Map<number, number[]>();\n clusterOf.forEach((c, i) => {\n const list = members.get(c);\n if (list) list.push(i);\n else members.set(c, [i]);\n });\n const clusters = [...members.keys()].sort((a, c) => a - c);\n let rounds = 0;\n while (edges.length < target * 0.6 && clusters.length > 1 && rounds++ < target) {\n const u = Math.floor(R() * n);\n const others = clusters.filter((c) => c !== clusterOf[u]);\n const pool = members.get(others[Math.floor(R() * others.length)]!)!;\n const fan = 4 + Math.floor(R() * 12);\n for (let i = 0; i < fan; i++) add(u, pool[Math.floor(R() * pool.length)]!);\n }\n }\n let tries = 0;\n while (edges.length < target && tries++ < target * 30) {\n const u = Math.floor(R() * n);\n let v = -1;\n if (R() < locality) {\n const b = nodes[u]!.box;\n const cand: number[] = [];\n for (let r = SPACING; cand.length < 8 && r < SPACING * 64; r *= 2) {\n cand.length = 0;\n near.query({ x: b.x - r, y: b.y - r, w: b.w + 2 * r, h: b.h + 2 * r }, (i) => {\n if (i !== u) cand.push(i);\n });\n }\n cand.sort((a, c) => a - c);\n if (cand.length) v = cand[Math.floor(R() * cand.length)]!;\n } else v = pickFar();\n if (v >= 0) add(u, v);\n }\n return edges;\n}\n","import { center, type Box, type Point } from \"./geom.ts\";\nimport { fixedPortPoint, type End, type Node, type Side } from \"./model.ts\";\n\n/** A plug: the point where a route leaves or enters a node, and the outward normal of its side. */\nexport interface Plug {\n readonly point: Point;\n readonly normal: Point;\n}\n\n/** The outward normal of each side, in a frame with the y axis down. */\nexport const SIDE_NORMAL: Readonly<Record<Side, Point>> = {\n north: { x: 0, y: -1 },\n east: { x: 1, y: 0 },\n south: { x: 0, y: 1 },\n west: { x: -1, y: 0 },\n};\n\n/** This function gives the side of the box that is nearest to the point. */\nexport function nearestSide(box: Box, p: Point): Side {\n const d: [Side, number][] = [\n [\"north\", Math.abs(p.y - box.y)],\n [\"east\", Math.abs(box.x + box.w - p.x)],\n [\"south\", Math.abs(box.y + box.h - p.y)],\n [\"west\", Math.abs(p.x - box.x)],\n ];\n let best = d[0]!;\n for (const x of d) if (x[1] < best[1]) best = x;\n return best[0];\n}\n\n/**\n * This function gives the side that faces `toward`: the side of the larger component of the direction from the center.\n * Thus the angle between the normal of the side and that direction is 45° or less.\n */\nexport function sideToward(box: Box, toward: Point): Side {\n const c = center(box);\n const dx = toward.x - c.x;\n const dy = toward.y - c.y;\n if (Math.abs(dx) >= Math.abs(dy)) return dx >= 0 ? \"east\" : \"west\";\n return dy >= 0 ? \"south\" : \"north\";\n}\n\n/**\n * This function gives the point on a side of the box that is nearest to the line from the center to `toward`.\n * The point stays away from the corners by `inset`, or by a quarter of the side when the side is short.\n */\nexport function pointOnSide(box: Box, side: Side, toward: Point, inset = 6): Point {\n const c = center(box);\n const dx = toward.x - c.x;\n const dy = toward.y - c.y;\n const clamp = (v: number, lo: number, len: number): number => {\n const m = Math.min(inset, len / 4);\n return Math.max(lo + m, Math.min(lo + len - m, v));\n };\n if (side === \"east\" || side === \"west\") {\n const x = side === \"east\" ? box.x + box.w : box.x;\n const y = dx === 0 ? c.y : c.y + (dy * (x - c.x)) / dx;\n return { x, y: clamp(y, box.y, box.h) };\n }\n const y = side === \"south\" ? box.y + box.h : box.y;\n const x = dy === 0 ? c.x : c.x + (dx * (y - c.y)) / dy;\n return { x: clamp(x, box.x, box.w), y };\n}\n\n/**\n * This function places the plug of one end of an edge. A fixed plug stays at its point. A plug with a side stays on that side.\n * The router places a free plug on the side that faces `toward`.\n */\nexport function placePlug(node: Node, end: End, toward: Point): Plug {\n const fixed = fixedPortPoint(node, end);\n const port = end.port === undefined ? undefined : node.ports?.find((p) => p.id === end.port);\n if (fixed) return { point: fixed, normal: SIDE_NORMAL[port?.side ?? nearestSide(node.box, fixed)] };\n const side = port?.side ?? sideToward(node.box, toward);\n return { point: pointOnSide(node.box, side, toward), normal: SIDE_NORMAL[side] };\n}\n","import { dist, type Point } from \"./geom.ts\";\n\n/** The options of the inflection rule. */\nexport interface InflectionOptions {\n /** The half width of the axis and diagonal bands, in radians. The default is 7°. */\n readonly tol?: number;\n /** The number of segments of the curve. The default is 24. */\n readonly samples?: number;\n /** The largest angle between the tangent and the chord, in radians. The default is 1.35 (approximately 77°). */\n readonly maxAngle?: number;\n}\n\n/**\n * This function gives the number of inflections that the rule asks for a chord at the angle `angle` (radians).\n * It gives 0 near an axis, 1 near a diagonal and 2 between them. The bands are `tol` wide on each side.\n */\nexport function inflectionSector(angle: number, tol: number = (7 * Math.PI) / 180): 0 | 1 | 2 {\n const q = Math.PI / 2;\n const mod = ((angle % q) + q) % q;\n if (mod < tol || q - mod < tol) return 0;\n if (Math.abs(mod - q / 2) < tol) return 1;\n return 2;\n}\n\n/**\n * This function draws the curve of the inflection rule from the plug `p0` to `target`.\n * The curve leaves `p0` along `normal`. In the frame of the chord, its side offset f has f(0) = f(L) = 0 and f'(0) = tan θ.\n * Here θ is the angle from the chord to the normal. A polynomial of degree 2, 3 or 4 gives 0, 1 or 2 inflections,\n * at 1/2, or at 1/3 and 2/3, of the chord.\n */\nexport function inflectionCurve(p0: Point, normal: Point, target: Point, options: InflectionOptions = {}): Point[] {\n const L = dist(p0, target);\n if (L === 0) return [p0, target];\n const ux = (target.x - p0.x) / L;\n const uy = (target.y - p0.y) / L;\n const k = inflectionSector(Math.atan2(uy, ux), options.tol);\n const maxAngle = options.maxAngle ?? 1.35;\n const th = -Math.atan2(normal.x * uy - normal.y * ux, normal.x * ux + normal.y * uy);\n const d = Math.tan(Math.max(-maxAngle, Math.min(maxAngle, th)));\n const f =\n k === 0\n ? (s: number): number => (-d / L) * s * s + d * s\n : k === 1\n ? (s: number): number => ((12 * d) / (L * L)) * (s ** 3 / 6 - (L * s * s) / 4) + d * s\n : (s: number): number => ((-36 * d) / L ** 3) * (s ** 4 / 12 - (L * s ** 3) / 6 + (L * L * s * s) / 9) + d * s;\n const n = Math.max(2, options.samples ?? 24);\n const out: Point[] = [];\n for (let i = 0; i <= n; i++) {\n if (i === n) {\n out.push(target);\n break;\n }\n const s = (L * i) / n;\n const o = f(s);\n out.push({ x: p0.x + ux * s - uy * o, y: p0.y + uy * s + ux * o });\n }\n out[0] = p0;\n return out;\n}\n\n/**\n * This function rounds each inner vertex of a polyline with a quadratic Bézier curve.\n * The curve starts and ends at most `radius` from the vertex, and at most half of each segment. The ends of the polyline stay.\n */\nexport function roundCorners(p: readonly Point[], radius: number, steps = 4): Point[] {\n if (p.length < 3 || radius <= 0) return [...p];\n const out: Point[] = [p[0]!];\n for (let i = 1; i + 1 < p.length; i++) {\n const a = p[i - 1]!;\n const v = p[i]!;\n const b = p[i + 1]!;\n const la = dist(a, v);\n const lb = dist(v, b);\n const r = Math.min(radius, la / 2, lb / 2);\n if (r <= 0) {\n out.push(v);\n continue;\n }\n const p1 = { x: v.x + ((a.x - v.x) * r) / la, y: v.y + ((a.y - v.y) * r) / la };\n const p2 = { x: v.x + ((b.x - v.x) * r) / lb, y: v.y + ((b.y - v.y) * r) / lb };\n for (let k = 0; k <= steps; k++) {\n const t = k / steps;\n const u = 1 - t;\n out.push({ x: u * u * p1.x + 2 * u * t * v.x + t * t * p2.x, y: u * u * p1.y + 2 * u * t * v.y + t * t * p2.y });\n }\n }\n out.push(p[p.length - 1]!);\n return out;\n}\n","import { dist, inflate, segmentHitsRect, type Point } from \"./geom.ts\";\nimport { Grid } from \"./grid.ts\";\nimport type { Node } from \"./model.ts\";\n\n/** The nodes as obstacles, with a grid for fast tests. */\nexport class Obstacles {\n readonly #grid: Grid<Node>;\n\n /** This constructor indexes the boxes of the nodes. */\n constructor(nodes: readonly Node[], cell: number) {\n this.#grid = new Grid<Node>(cell);\n for (const n of nodes) this.#grid.add(n, n.box);\n }\n\n /** This method tells if the segment `ab` stays out of each box, made larger by `pad`. The nodes in `skip` do not count. */\n clear(a: Point, b: Point, pad: number, skip?: ReadonlySet<Node>): boolean {\n let ok = true;\n this.#grid.querySegment(a, b, pad, (n) => {\n if (ok && !skip?.has(n)) {\n const x = n.box;\n if (segmentHitsRect(a, b, x.x - pad, x.y - pad, x.x + x.w + pad, x.y + x.h + pad)) ok = false;\n }\n });\n return ok;\n }\n\n /** This method tells if the polyline stays out of each box, made larger by `pad`. The nodes in `skip` do not count. */\n clearPath(p: readonly Point[], pad: number, skip?: ReadonlySet<Node>): boolean {\n for (let i = 1; i < p.length; i++) if (!this.clear(p[i - 1]!, p[i]!, pad, skip)) return false;\n return true;\n }\n\n /** This method tells if the point is inside a box, made larger by `pad`. The node `skip` does not count. */\n inside(p: Point, pad: number, skip?: Node): boolean {\n let hit = false;\n this.#grid.query({ x: p.x, y: p.y, w: 0, h: 0 }, (n) => {\n if (!hit && n !== skip) {\n const b = n.box;\n hit = p.x > b.x - pad && p.x < b.x + b.w + pad && p.y > b.y - pad && p.y < b.y + b.h + pad;\n }\n });\n return hit;\n }\n}\n\n/** The options of the corner graph. */\nexport interface CornerGraphOptions {\n /** The distance from a box to its corners. */\n readonly margin: number;\n /** The number of visible neighbours of each corner. */\n readonly k: number;\n /**\n * The spacing of a lattice of free points over the plane, in units of the mean node size. The default is 3, and 0 turns it off.\n * The lattice links groups of nodes across empty space. Without it, the nearest corners of a group are all in that group.\n */\n readonly lattice?: number;\n}\n\n/**\n * A sparse visibility graph. Its vertices are the corners of the boxes, made larger by `margin`.\n * Each corner links to its `k` nearest corners that it can see. A lattice of free points links the groups of nodes.\n * A path goes from corner to corner around the boxes.\n * The obstacle test uses half of the margin, so a path keeps a clearance of at least half of the margin.\n */\nexport class CornerGraph {\n readonly points: Point[] = [];\n readonly #adj: number[][] = [];\n // The length of each link, in the order of #adj.\n readonly #len: number[][] = [];\n readonly #obstacles: Obstacles;\n readonly #pointGrid: Grid<number>;\n readonly #cell: number;\n readonly #pad: number;\n readonly #k: number;\n // The work arrays of A*, made once and cleared by a stamp.\n #g = new Float64Array(0);\n #parent = new Int32Array(0);\n #open = new Int32Array(0);\n #closed = new Int32Array(0);\n #stamp = 0;\n // The stamp of the last call of nearestVisible that tested each corner.\n #tested = new Int32Array(0);\n #testStamp = 0;\n // The corners that each end of a path sees, by the coordinates of the end.\n readonly #endCache = new Map<string, number[]>();\n\n /** This constructor makes the graph of the nodes. */\n constructor(nodes: readonly Node[], obstacles: Obstacles, options: CornerGraphOptions) {\n this.#obstacles = obstacles;\n this.#pad = options.margin / 2;\n this.#k = options.k;\n let size = 0;\n for (const n of nodes) size += (n.box.w + n.box.h) / 2;\n this.#cell = Math.max(1, size / Math.max(1, nodes.length) + 2 * options.margin);\n this.#pointGrid = new Grid<number>(this.#cell);\n for (const n of nodes) {\n const b = inflate(n.box, options.margin);\n for (const c of [\n { x: b.x, y: b.y },\n { x: b.x + b.w, y: b.y },\n { x: b.x + b.w, y: b.y + b.h },\n { x: b.x, y: b.y + b.h },\n ]) {\n if (!obstacles.inside(c, this.#pad)) this.#addPoint(c);\n }\n }\n const spacing = (options.lattice ?? 3) * this.#cell;\n if (spacing > 0 && nodes.length > 0) {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const n of nodes) {\n x0 = Math.min(x0, n.box.x);\n y0 = Math.min(y0, n.box.y);\n x1 = Math.max(x1, n.box.x + n.box.w);\n y1 = Math.max(y1, n.box.y + n.box.h);\n }\n for (let x = x0 - spacing / 2; x <= x1 + spacing; x += spacing) {\n for (let y = y0 - spacing / 2; y <= y1 + spacing; y += spacing) {\n const c = { x, y };\n if (!obstacles.inside(c, options.margin)) this.#addPoint(c);\n }\n }\n }\n const links: Set<number>[] = this.points.map(() => new Set<number>());\n for (let i = 0; i < this.points.length; i++) {\n for (const j of this.nearestVisible(this.points[i]!, this.#k, i)) {\n links[i]!.add(j);\n links[j]!.add(i);\n }\n }\n links.forEach((s, i) => {\n const adj = [...s].sort((a, b) => a - b);\n this.#adj.push(adj);\n this.#len.push(adj.map((j) => dist(this.points[i]!, this.points[j]!)));\n });\n }\n\n #addPoint(c: Point): void {\n this.#pointGrid.add(this.points.length, { x: c.x, y: c.y, w: 0, h: 0 });\n this.points.push(c);\n }\n\n /** This method gives the number of links of the graph. */\n get linkCount(): number {\n let n = 0;\n for (const a of this.#adj) n += a.length;\n return n / 2;\n }\n\n /** This method gives the index of the corner nearest to `p`, seen or not, or -1 when the graph has no corner near it. */\n nearest(p: Point): number {\n for (let r = this.#cell; r <= this.#cell * 64; r *= 2) {\n let best = -1;\n let bestD = Infinity;\n this.#pointGrid.query({ x: p.x - r, y: p.y - r, w: 2 * r, h: 2 * r }, (j) => {\n const d = dist(p, this.points[j]!);\n if (d < bestD || (d === bestD && j < best)) {\n bestD = d;\n best = j;\n }\n });\n // A corner beyond r can be nearer than a corner in a corner of the square. Within r, none is.\n if (best >= 0 && bestD <= r) return best;\n }\n return -1;\n }\n\n /** This method gives at most `k` corners that `p` can see, nearest first. The corner `self` does not count. */\n nearestVisible(p: Point, k: number, self = -1): number[] {\n return this.#nearestVisible(p, k, self, this.#pad);\n }\n\n #nearestVisible(p: Point, k: number, self: number, pad: number): number[] {\n const out: number[] = [];\n if (this.#tested.length < this.points.length) this.#tested = new Int32Array(this.points.length);\n const tested = this.#tested;\n const stamp = ++this.#testStamp;\n for (let r = this.#cell; r <= this.#cell * 8; r *= 2) {\n const cands: [number, number][] = [];\n this.#pointGrid.query({ x: p.x - r, y: p.y - r, w: 2 * r, h: 2 * r }, (j) => {\n if (j !== self && tested[j] !== stamp) cands.push([dist(p, this.points[j]!), j]);\n });\n cands.sort((a, b) => a[0] - b[0] || a[1] - b[1]);\n for (const [d, j] of cands) {\n // A corner beyond r can be nearer than a corner of the next ring, so it waits for that ring.\n if (d > r) break;\n tested[j] = stamp;\n if (this.#obstacles.clear(p, this.points[j]!, pad)) out.push(j);\n if (out.length >= k) return out;\n }\n }\n return out;\n }\n\n /**\n * This method gives a shortest path from `from` to `to` in the graph (A*), with the two points as its ends.\n * It gives `undefined` when the graph links no corner near `from` to a corner near `to`.\n * The function `cost` can change the cost of the link from corner `i` to corner `j`, of length `d`.\n * It must give at least `floor` × `d`, so that the estimate of A* stays below the true cost.\n */\n path(from: Point, to: Point, cost?: (i: number, j: number, d: number) => number, floor: number = 1): Point[] | undefined {\n if (this.#obstacles.clear(from, to, this.#pad)) return [from, to];\n const n = this.points.length;\n if (this.#g.length < n) {\n this.#g = new Float64Array(n);\n this.#parent = new Int32Array(n);\n this.#open = new Int32Array(n);\n this.#closed = new Int32Array(n);\n }\n const stamp = ++this.#stamp;\n const goal = new Map<number, number>();\n for (const j of this.#ends(to)) goal.set(j, dist(this.points[j]!, to));\n if (goal.size === 0) return undefined;\n const heap = new MinHeap();\n const h = (i: number): number => floor * dist(this.points[i]!, to);\n const relax = (j: number, g: number, parent: number): void => {\n if (this.#closed[j] === stamp) return;\n if (this.#open[j] === stamp && this.#g[j]! <= g) return;\n this.#open[j] = stamp;\n this.#g[j] = g;\n this.#parent[j] = parent;\n heap.push(g + h(j), j);\n };\n for (const j of this.#ends(from)) relax(j, dist(from, this.points[j]!), -1);\n let best = Infinity;\n let bestEnd = -1;\n while (heap.size > 0) {\n if (heap.topKey >= best) break;\n const i = heap.pop();\n if (this.#closed[i] === stamp) continue;\n this.#closed[i] = stamp;\n const gi = this.#g[i]!;\n const tail = goal.get(i);\n if (tail !== undefined && gi + tail < best) {\n best = gi + tail;\n bestEnd = i;\n }\n const adj = this.#adj[i]!;\n const len = this.#len[i]!;\n for (let m = 0; m < adj.length; m++) {\n const j = adj[m]!;\n const d = len[m]!;\n relax(j, gi + (cost ? cost(i, j, d) : d), i);\n }\n }\n if (bestEnd < 0) return undefined;\n const out: Point[] = [to];\n for (let i = bestEnd; i >= 0; i = this.#parent[i]!) out.push(this.points[i]!);\n out.push(from);\n return out.reverse();\n }\n\n /**\n * This method gives the corners that an end of a path can see. An end near a box sees no corner with the clearance.\n * Then the end takes the corners that it sees without the clearance, so the path does not cut through the boxes.\n * The graph does not change, so the method keeps the corners of each end.\n */\n #ends(p: Point): number[] {\n const key = `${p.x},${p.y}`;\n let out = this.#endCache.get(key);\n if (!out) {\n out = this.nearestVisible(p, this.#k * 2);\n if (out.length === 0) out = this.#nearestVisible(p, this.#k * 2, -1, 0);\n this.#endCache.set(key, out);\n }\n return out;\n }\n\n /** This method removes the vertices that a later vertex makes needless: from each vertex, it goes to the farthest vertex in view. */\n pull(p: readonly Point[], lookahead = 16): Point[] {\n if (p.length < 3) return [...p];\n const out: Point[] = [p[0]!];\n let i = 0;\n while (i < p.length - 1) {\n let j = Math.min(p.length - 1, i + lookahead);\n while (j > i + 1 && !this.#obstacles.clear(p[i]!, p[j]!, this.#pad)) j--;\n out.push(p[j]!);\n i = j;\n }\n return out;\n }\n}\n\n/** A binary min-heap of (key, value) pairs. Equal keys come out by the smaller value, so the order is deterministic. */\nclass MinHeap {\n readonly #k: number[] = [];\n readonly #v: number[] = [];\n\n get size(): number {\n return this.#k.length;\n }\n\n #less(a: number, b: number): boolean {\n return this.#k[a]! < this.#k[b]! || (this.#k[a] === this.#k[b] && this.#v[a]! < this.#v[b]!);\n }\n\n #swap(a: number, b: number): void {\n const k = this.#k[a]!;\n this.#k[a] = this.#k[b]!;\n this.#k[b] = k;\n const v = this.#v[a]!;\n this.#v[a] = this.#v[b]!;\n this.#v[b] = v;\n }\n\n /** The smallest key. */\n get topKey(): number {\n return this.#k[0]!;\n }\n\n push(key: number, value: number): void {\n this.#k.push(key);\n this.#v.push(value);\n let i = this.#k.length - 1;\n while (i > 0) {\n const p = (i - 1) >> 1;\n if (!this.#less(i, p)) break;\n this.#swap(i, p);\n i = p;\n }\n }\n\n /** This method removes the pair with the smallest key and gives its value. */\n pop(): number {\n const top = this.#v[0]!;\n const k = this.#k.pop()!;\n const v = this.#v.pop()!;\n if (this.#k.length > 0) {\n this.#k[0] = k;\n this.#v[0] = v;\n let i = 0;\n for (;;) {\n const l = 2 * i + 1;\n const r = l + 1;\n let m = i;\n if (l < this.#k.length && this.#less(l, m)) m = l;\n if (r < this.#k.length && this.#less(r, m)) m = r;\n if (m === i) break;\n this.#swap(i, m);\n i = m;\n }\n }\n return top;\n }\n}\n","import { inflectionCurve, roundCorners } from \"./curves.ts\";\nimport type { Point } from \"./geom.ts\";\nimport type { Node } from \"./model.ts\";\nimport type { Plug } from \"./plugs.ts\";\nimport { CornerGraph, Obstacles } from \"./visibility.ts\";\n\n/** The options of a way finder. */\nexport interface WayOptions {\n /** The distance from a box to the corners of the graph. The default is 5. */\n readonly margin?: number;\n /** The number of visible neighbours of each corner. The default is 8. */\n readonly k?: number;\n /** With `smooth`, a way in clear view uses the inflection rule, and the other ways get round corners. */\n readonly smooth?: boolean;\n}\n\n/**\n * The ways around the nodes of one graph. A way leaves a plug along its normal.\n * It goes a shortest way (A*) through the corner graph, without the needless corners. It enters the other plug along its normal.\n */\nexport class WayFinder {\n readonly obstacles: Obstacles;\n readonly corners: CornerGraph;\n readonly margin: number;\n readonly #smooth: boolean;\n\n /** This constructor makes the obstacles and the corner graph of the nodes. */\n constructor(nodes: readonly Node[], options: WayOptions = {}) {\n this.margin = options.margin ?? 5;\n this.#smooth = options.smooth ?? false;\n this.obstacles = new Obstacles(nodes, 180);\n this.corners = new CornerGraph(nodes, this.obstacles, { margin: this.margin, k: options.k ?? 8 });\n }\n\n /** This method gives the point at `margin` from the plug, along its normal. */\n out(p: Plug): Point {\n return { x: p.point.x + p.normal.x * this.margin, y: p.point.y + p.normal.y * this.margin };\n }\n\n /** This method gives a way from plug to plug. Without a way in the graph, it gives the straight line. */\n between(ps: Plug, pt: Plug, ends: ReadonlySet<Node>): Point[] {\n if (this.#smooth) {\n const curve = inflectionCurve(ps.point, ps.normal, pt.point);\n if (this.obstacles.clearPath(curve, this.margin / 2, ends)) return curve;\n }\n const way = this.corners.path(this.out(ps), this.out(pt));\n if (!way) return [ps.point, pt.point];\n const poly = [ps.point, ...this.corners.pull(way), pt.point];\n if (this.#smooth) {\n const round = roundCorners(poly, this.margin);\n if (this.obstacles.clearPath(round, 0, ends)) return round;\n }\n return poly;\n }\n\n /** This method gives a way from a plug to a free point, or `undefined` when the graph has none. */\n fromPlug(ps: Plug, to: Point): Point[] | undefined {\n const way = this.corners.path(this.out(ps), to);\n return way && [ps.point, ...this.corners.pull(way)];\n }\n\n /** This method gives a way from a free point to a plug, or `undefined` when the graph has none. */\n toPlug(from: Point, pt: Plug): Point[] | undefined {\n const way = this.corners.path(from, this.out(pt));\n return way && [...this.corners.pull(way), pt.point];\n }\n}\n","import { dist, type Point } from \"./geom.ts\";\nimport type { Result, Route } from \"./model.ts\";\n\n/** A piece of drawn way. A shared segment carries several edges, in lane order. A private segment carries one edge. */\nexport interface Segment {\n readonly id: string;\n readonly points: readonly Point[];\n /** The edges in lane order. Lane 0 is on the left of the segment, from its first point to its last. The y axis points down. */\n readonly edges: readonly string[];\n /** The number of edges. A renderer shows it on a fat edge. */\n readonly count: number;\n}\n\n/** One step of a path: a segment, the way through it, and the lane of the edge in it. */\nexport interface SegmentRef {\n readonly segment: string;\n /** This value is true when the edge goes from the last point of the segment to its first point. */\n readonly reverse: boolean;\n readonly lane: number;\n}\n\n/** The route of one edge as a list of segments. */\nexport interface Path {\n readonly edge: string;\n readonly segments: readonly SegmentRef[];\n}\n\n/** The routes of a result as shared geometry. A renderer can draw each segment one time, with a count. */\nexport interface SegmentGraph {\n readonly segments: readonly Segment[];\n readonly paths: readonly Path[];\n}\n\nconst SAME = 1e-6;\n\n/** This function gives the index where `p` holds the points of `part` in a row, from `from` on, or -1. */\nfunction indexOf(p: readonly Point[], part: readonly Point[], from: number): number {\n for (let i = from; i + part.length <= p.length; i++) {\n let ok = true;\n for (let j = 0; ok && j < part.length; j++) ok = dist(p[i + j]!, part[j]!) <= SAME;\n if (ok) return i;\n }\n return -1;\n}\n\n/**\n * This function breaks each route into segments. The runs and the trunks of the bundles become shared segments.\n * The other parts of each route become private segments. The segments of a path, in order, give the points of its route again.\n */\nexport function segmentsOf(result: Result): SegmentGraph {\n const shared = [\n ...(result.runs ?? []).map((r) => ({ id: r.id, points: r.points, edges: r.edges })),\n ...(result.bundles ?? []).map((b) => ({ id: b.id, points: b.trunk, edges: b.edges })),\n ].filter((s) => s.points.length >= 2);\n const onEdge = new Map<string, { id: string; points: readonly Point[]; lane: number }[]>();\n for (const s of shared) {\n s.edges.forEach((edge, lane) => {\n const list = onEdge.get(edge);\n if (list) list.push({ id: s.id, points: s.points, lane });\n else onEdge.set(edge, [{ id: s.id, points: s.points, lane }]);\n });\n }\n const segments: Segment[] = shared.map((s) => ({ id: s.id, points: s.points, edges: s.edges, count: s.edges.length }));\n const paths: Path[] = [];\n for (const route of result.routes) {\n const p = route.points;\n // The place of each shared segment in the route, in the order of the route.\n const found: { at: number; end: number; ref: SegmentRef }[] = [];\n for (const s of onEdge.get(route.edge) ?? []) {\n let at = indexOf(p, s.points, 0);\n let reverse = false;\n if (at < 0) {\n at = indexOf(p, [...s.points].reverse(), 0);\n reverse = true;\n }\n if (at >= 0) found.push({ at, end: at + s.points.length - 1, ref: { segment: s.id, reverse, lane: s.lane } });\n }\n found.sort((a, b) => a.at - b.at);\n const refs: SegmentRef[] = [];\n let i = 0;\n const own = (to: number): void => {\n if (to <= i) return;\n const id = `${route.edge}/${refs.length}`;\n segments.push({ id, points: p.slice(i, to + 1), edges: [route.edge], count: 1 });\n refs.push({ segment: id, reverse: false, lane: 0 });\n };\n for (const f of found) {\n if (f.at < i) continue;\n own(f.at);\n refs.push(f.ref);\n i = f.end;\n }\n own(p.length - 1);\n paths.push({ edge: route.edge, segments: refs });\n }\n return { segments, paths };\n}\n\n/** This function gives the points of a path, with the segments in the order and the way of the path. */\nexport function pathPoints(graph: SegmentGraph, path: Path): Point[] {\n const byId = new Map(graph.segments.map((s) => [s.id, s]));\n const out: Point[] = [];\n for (const ref of path.segments) {\n const s = byId.get(ref.segment);\n if (!s) continue;\n const pts = ref.reverse ? [...s.points].reverse() : s.points;\n for (const q of pts) if (out.length === 0 || dist(q, out[out.length - 1]!) > SAME) out.push(q);\n }\n return out;\n}\n\n/**\n * This function moves each point of a polyline by `d` to the left, in a frame with the y axis down.\n * At an inner point, it moves along the bisector, at most 2 × `d` far.\n */\nexport function offsetPolyline(p: readonly Point[], d: number): Point[] {\n if (d === 0 || p.length < 2) return [...p];\n const normals: Point[] = [];\n for (let i = 1; i < p.length; i++) {\n const dx = p[i]!.x - p[i - 1]!.x;\n const dy = p[i]!.y - p[i - 1]!.y;\n const l = Math.hypot(dx, dy);\n normals.push(l > 0 ? { x: dy / l, y: -dx / l } : (normals[normals.length - 1] ?? { x: 0, y: 0 }));\n }\n return p.map((q, i) => {\n const a = normals[Math.max(0, i - 1)]!;\n const b = normals[Math.min(normals.length - 1, i)]!;\n const mx = a.x + b.x;\n const my = a.y + b.y;\n const ml = Math.hypot(mx, my);\n if (ml < 1e-9) return { x: q.x + a.x * d, y: q.y + a.y * d };\n const cos = (mx * a.x + my * a.y) / ml;\n const k = Math.min(2, 1 / Math.max(cos, 1e-9)) * d;\n return { x: q.x + (mx / ml) * k, y: q.y + (my / ml) * k };\n });\n}\n\n/** The options of `pullApart`. */\nexport interface PullApartOptions {\n /** The distance between two lanes. */\n readonly spacing: number;\n /** The largest width of a segment, from its outer lane on the left to its outer lane on the right. */\n readonly maxWidth: number;\n}\n\n/**\n * This function pulls the lanes of each shared segment apart, and gives a route for each edge.\n * The lanes keep the lane order, so they do not cross in a segment. The two ends of each route stay at their plugs.\n */\nexport function pullApart(graph: SegmentGraph, options: PullApartOptions): Route[] {\n return lanePaths(graph, (s) => (s.count > 1 ? Math.min(options.spacing, options.maxWidth / (s.count - 1)) : 0));\n}\n\n/** This function gives the key of a shared run: the ids of its edges, sorted and joined with commas. */\nexport function runKey(edges: readonly string[]): string {\n return [...edges].sort().join(\",\");\n}\n\n/**\n * This function opens the shared segments whose key is in `open`: each edge of an open segment gets its own lane.\n * The lanes are `laneWidth` apart, and an open segment is at most `maxWidth` wide. The other segments stay as one way.\n *\n * Lane 0 is on the left of the segment, from its first point to its last, with the y axis down.\n * The function takes a result or its segments. It gives a route for each edge, with the ends at their plugs.\n * The key of a segment is `runKey` of its edges.\n */\nexport function laneRoutes(source: Result | SegmentGraph, open: ReadonlySet<string>, laneWidth: number, maxWidth: number = Infinity): Route[] {\n const graph = \"paths\" in source ? source : segmentsOf(source);\n if (open.size === 0) return graph.paths.map((path) => ({ edge: path.edge, points: pathPoints(graph, path) }));\n return lanePaths(graph, (s) => (s.count > 1 && open.has(runKey(s.edges)) ? Math.min(laneWidth, maxWidth / (s.count - 1)) : 0));\n}\n\n/** This function gives the route of each path, with the lanes of each segment at the spacing that `spacingOf` gives. */\nfunction lanePaths(graph: SegmentGraph, spacingOf: (s: Segment) => number): Route[] {\n const byId = new Map(graph.segments.map((s) => [s.id, s]));\n const routes: Route[] = [];\n for (const path of graph.paths) {\n const ends = pathPoints(graph, path);\n const out: Point[] = [];\n for (const ref of path.segments) {\n const s = byId.get(ref.segment);\n if (!s) continue;\n const spacing = spacingOf(s);\n const moved = offsetPolyline(s.points, ((s.count - 1) / 2 - ref.lane) * spacing);\n for (const q of ref.reverse ? moved.reverse() : moved) if (out.length === 0 || dist(q, out[out.length - 1]!) > SAME) out.push(q);\n }\n if (out.length >= 2 && ends.length >= 2) {\n out[0] = ends[0]!;\n out[out.length - 1] = ends[ends.length - 1]!;\n }\n routes.push({ edge: path.edge, points: out });\n }\n return routes;\n}\n\n/** The angle, from -π to π, of the turn at `base` from the direction `from` → `base` to the point `to`. */\nfunction turn(from: Point, base: Point, to: Point): number {\n const dx = base.x - from.x;\n const dy = base.y - from.y;\n const vx = to.x - base.x;\n const vy = to.y - base.y;\n return Math.atan2(dx * vy - dy * vx, dx * vx + dy * vy);\n}\n\n/**\n * This function gives the lane order of the edges on a shared way `run` (metro-line order). Two routes go on together\n * past the last point of the run until they part. The route that turns more to the left there gets the lane more to the left.\n * Two routes can part only before the first point. Then the route that comes from more to the left gets the lane more to the left.\n * A route that does not hold the run goes last.\n */\nexport function orderLanes(run: readonly Point[], routes: readonly Route[]): string[] {\n const placed: { edge: string; p: readonly Point[]; s: number; e: number }[] = [];\n const lost: string[] = [];\n for (const r of routes) {\n let at = indexOf(r.points, run, 0);\n if (at >= 0) placed.push({ edge: r.edge, p: r.points, s: at, e: at + run.length - 1 });\n else {\n const p = [...r.points].reverse();\n at = indexOf(p, run, 0);\n if (at >= 0) placed.push({ edge: r.edge, p, s: at, e: at + run.length - 1 });\n else lost.push(r.edge);\n }\n }\n const same = (a: Point, b: Point): boolean => dist(a, b) <= SAME;\n placed.sort((P, Q) => {\n for (let j = 1; ; j++) {\n const a = P.p[P.e + j];\n const b = Q.p[Q.e + j];\n if (a === undefined || b === undefined) break;\n if (!same(a, b)) {\n const d = turn(P.p[P.e + j - 2]!, P.p[P.e + j - 1]!, a) - turn(P.p[P.e + j - 2]!, P.p[P.e + j - 1]!, b);\n if (d !== 0) return d;\n break;\n }\n }\n for (let j = 1; ; j++) {\n const a = P.p[P.s - j];\n const b = Q.p[Q.s - j];\n if (a === undefined || b === undefined) break;\n if (!same(a, b)) {\n // Seen backward, the left side is the right side. Thus the order turns around.\n const d = turn(P.p[P.s - j + 2]!, P.p[P.s - j + 1]!, b) - turn(P.p[P.s - j + 2]!, P.p[P.s - j + 1]!, a);\n if (d !== 0) return d;\n break;\n }\n }\n return P.edge < Q.edge ? -1 : P.edge > Q.edge ? 1 : 0;\n });\n return [...placed.map((x) => x.edge), ...lost.sort()];\n}\n","import { center, type Box } from \"./geom.ts\";\nimport type { Node } from \"./model.ts\";\n\n/** A section of the plane: a cell of a quadtree, with the nodes whose centers are in it. */\nexport interface Section {\n /** The path from the root: \"s\", then one digit from 0 to 3 for each step down. */\n readonly id: string;\n readonly depth: number;\n readonly cell: Box;\n /** The indices of the nodes, in the order of the graph. */\n readonly nodes: readonly number[];\n readonly children: readonly Section[];\n}\n\n/** The options of the tree of sections. */\nexport interface SectionOptions {\n /** A section with more nodes splits. The default is 8. */\n readonly cap?: number;\n /** The tree stops at this depth. The default is 16. */\n readonly maxDepth?: number;\n}\n\n/**\n * This function makes the tree of sections of the nodes. A cell with more than `cap` nodes splits in four.\n * When the nodes of a cell are all in one quarter, the cell becomes that quarter and does not make a level.\n */\nexport function buildSections(nodes: readonly Node[], options: SectionOptions = {}): Section {\n const cap = Math.max(1, options.cap ?? 8);\n const maxDepth = options.maxDepth ?? 16;\n const centers = nodes.map((n) => center(n.box));\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const n of nodes) {\n x0 = Math.min(x0, n.box.x);\n y0 = Math.min(y0, n.box.y);\n x1 = Math.max(x1, n.box.x + n.box.w);\n y1 = Math.max(y1, n.box.y + n.box.h);\n }\n const root: Box = nodes.length ? { x: x0, y: y0, w: x1 - x0, h: y1 - y0 } : { x: 0, y: 0, w: 0, h: 0 };\n const make = (id: string, depth: number, cell: Box, list: readonly number[]): Section => {\n let box = cell;\n for (let guard = 0; list.length > cap && depth < maxDepth && guard < 32; guard++) {\n const mx = box.x + box.w / 2;\n const my = box.y + box.h / 2;\n const parts: number[][] = [[], [], [], []];\n for (const i of list) parts[(centers[i]!.x < mx ? 0 : 1) + (centers[i]!.y < my ? 0 : 2)]!.push(i);\n const quarter = (q: number): Box => ({\n x: q % 2 === 0 ? box.x : mx,\n y: q < 2 ? box.y : my,\n w: box.w / 2,\n h: box.h / 2,\n });\n const full = parts.map((p, q) => [p, q] as const).filter(([p]) => p.length > 0);\n if (full.length === 1) {\n box = quarter(full[0]![1]);\n continue;\n }\n const children = full.map(([p, q]) => make(`${id}${q}`, depth + 1, quarter(q), p));\n return { id, depth, cell: box, nodes: list, children };\n }\n return { id, depth, cell: box, nodes: list, children: [] };\n };\n return make(\"s\", 0, root, nodes.map((_, i) => i));\n}\n\n/** This function gives the sections of the tree, parents before children. */\nexport function allSections(root: Section): Section[] {\n const out: Section[] = [];\n const walk = (s: Section): void => {\n out.push(s);\n for (const c of s.children) walk(c);\n };\n walk(root);\n return out;\n}\n\n/** This function gives the depth of the deepest section. */\nexport function treeDepth(root: Section): number {\n return root.children.reduce((d, c) => Math.max(d, treeDepth(c)), root.depth);\n}\n","import { center } from \"../geom.ts\";\nimport { nodeIndex, type Graph, type Node, type Result, type Route, type Router } from \"../model.ts\";\nimport { placePlug } from \"../plugs.ts\";\nimport { WayFinder, type WayOptions } from \"../ways.ts\";\n\n/** The options of the corner router. */\nexport interface CornersOptions extends WayOptions {\n /** The name in the benchmark. */\n readonly name: string;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\n/**\n * This function makes a router that goes around the nodes.\n * Each edge leaves its plug along the normal of the side. It goes a shortest way (A*) through a sparse visibility graph\n * of the box corners, without the needless corners. It enters the target plug along its normal.\n */\nexport function cornersRouter(options: CornersOptions): Router {\n const router: Router = {\n name: options.name,\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const ways = new WayFinder(graph.nodes, options);\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n }\n return { routes };\n },\n };\n return options.maxNodes === undefined ? router : { ...router, maxNodes: options.maxNodes };\n}\n","import { inflectionCurve } from \"../curves.ts\";\nimport { center } from \"../geom.ts\";\nimport { nodeIndex, type Graph, type Result, type Route, type Router } from \"../model.ts\";\nimport { placePlug } from \"../plugs.ts\";\n\n/**\n * Plugs and the inflection rule, with no obstacles. Each edge leaves its source plug at the tangent of the side.\n * It goes to the target plug on the curve of the rule. This router measures the rule alone.\n */\nexport const plugsRouter: Router = {\n name: \"plugs\",\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n routes.push({ edge: e.id, points: inflectionCurve(ps.point, ps.normal, pt.point) });\n }\n return { routes };\n },\n};\n","import { center, dist, type Box, type Point } from \"./geom.ts\";\nimport type { LevelItem, LevelLink, Node, Side } from \"./model.ts\";\nimport { pointOnSide, SIDE_NORMAL, sideToward, type Plug } from \"./plugs.ts\";\nimport { CornerGraph, Obstacles } from \"./visibility.ts\";\nimport type { WayFinder, WayOptions } from \"./ways.ts\";\n\n/** Two items of a level that a link joins, and the count of the edges between them. */\nexport interface ItemPair {\n readonly source: string;\n readonly target: string;\n readonly count: number;\n}\n\n/** The parts of a way finder that a link uses. */\ntype Ways = Pick<WayFinder, \"obstacles\" | \"corners\" | \"margin\" | \"out\">;\n\nconst EPS = 1e-6;\n\n/**\n * This function removes the repeated points, the points in the middle of a straight run,\n * and the points where the way turns back on itself.\n */\nfunction tidy(p: readonly Point[]): Point[] {\n const out: Point[] = [];\n for (const q of p) {\n if (out.length > 0 && dist(q, out[out.length - 1]!) <= EPS) continue;\n while (out.length >= 2) {\n const a = out[out.length - 2]!;\n const b = out[out.length - 1]!;\n const cross = (b.x - a.x) * (q.y - b.y) - (b.y - a.y) * (q.x - b.x);\n if (Math.abs(cross) > EPS * (1 + dist(a, b) * dist(b, q))) break;\n // The point b is on the line through a and q: in the middle of a straight run, or at the tip of a turn back.\n out.pop();\n }\n if (out.length > 0 && dist(q, out[out.length - 1]!) <= EPS) continue;\n out.push(q);\n }\n return out;\n}\n\n/**\n * This function gives the links of one level. The items of the level are the obstacles.\n * A link starts on the boundary of the box of its source and ends on the boundary of the box of its target.\n * It goes around the boxes of the other items. Where there is space, its legs are parallel to the axes.\n */\nexport function levelLinks(items: readonly LevelItem[], pairs: readonly ItemPair[], options: WayOptions = {}): LevelLink[] {\n if (pairs.length === 0) return [];\n const nodes: Node[] = items.map((i) => ({ id: i.id, box: i.box }));\n const byId = new Map(nodes.map((n) => [n.id, n]));\n const ways = levelWays(nodes, options);\n const inset = Math.min(6, ways.margin);\n const out: LevelLink[] = [];\n for (const p of pairs) {\n const s = byId.get(p.source);\n const t = byId.get(p.target);\n if (!s || !t) continue;\n // Two items with a clear way between their facing sides get the short way.\n const [fs, ft] = facingPlugs(s.box, t.box, inset);\n let points = isFree(ways, s, fs) && isFree(ways, t, ft) ? quickWay(ways, ends(ways, s, fs, t, ft)) : undefined;\n // Else the link goes from the middle of a side. Each item has at most four such plugs, so the corner graph finds their ends one time.\n points ??= squareWay(ways, ends(ways, s, sidePlug(ways, s, center(t.box)), t, sidePlug(ways, t, center(s.box))));\n out.push({ source: p.source, target: p.target, count: p.count, points });\n }\n return out;\n}\n\n/**\n * This function makes the obstacles and the corner graph of the items of a level.\n * The buckets of the obstacles grow with the items, so a long link visits few buckets.\n */\nfunction levelWays(nodes: readonly Node[], options: WayOptions): Ways {\n const margin = options.margin ?? 5;\n let size = 0;\n for (const n of nodes) size += Math.max(n.box.w, n.box.h);\n const obstacles = new Obstacles(nodes, Math.max(180, (2 * size) / Math.max(1, nodes.length)));\n const corners = new CornerGraph(nodes, obstacles, { margin, k: options.k ?? 8 });\n return { obstacles, corners, margin, out: (p) => ({ x: p.point.x + p.normal.x * margin, y: p.point.y + p.normal.y * margin }) };\n}\n\n/**\n * This function gives the plugs of a link between two boxes. Each plug is on the side that faces the other box.\n * When the two sides face each other and their spans overlap, both plugs are at the middle of the overlap, so the link is straight.\n */\nexport function facingPlugs(a: Box, b: Box, inset: number): [Plug, Plug] {\n const sa = sideToward(a, center(b));\n const sb = sideToward(b, center(a));\n const plug = (box: Box, side: Side, toward: Point): Plug => ({ point: pointOnSide(box, side, toward, inset), normal: SIDE_NORMAL[side] });\n const across = (sa === \"east\" && sb === \"west\") || (sa === \"west\" && sb === \"east\");\n const down = (sa === \"south\" && sb === \"north\") || (sa === \"north\" && sb === \"south\");\n if (across || down) {\n const lo = across ? Math.max(a.y, b.y) + inset : Math.max(a.x, b.x) + inset;\n const hi = across ? Math.min(a.y + a.h, b.y + b.h) - inset : Math.min(a.x + a.w, b.x + b.w) - inset;\n if (lo <= hi) {\n const ca = center(a);\n const cb = center(b);\n const m = Math.max(lo, Math.min(hi, across ? (ca.y + cb.y) / 2 : (ca.x + cb.x) / 2));\n const at = (box: Box, side: Side): Point =>\n across\n ? { x: side === \"east\" ? box.x + box.w : box.x, y: m }\n : { x: m, y: side === \"south\" ? box.y + box.h : box.y };\n return [\n { point: at(a, sa), normal: SIDE_NORMAL[sa] },\n { point: at(b, sb), normal: SIDE_NORMAL[sb] },\n ];\n }\n }\n return [plug(a, sa, center(b)), plug(b, sb, center(a))];\n}\n\nconst SIDES: readonly Side[] = [\"north\", \"east\", \"south\", \"west\"];\n\n/** This function tells if the way out of a plug is free. The plug and the point at `margin` from it are in no other box. */\nfunction isFree(ways: Ways, node: Node, plug: Plug): boolean {\n return !ways.obstacles.inside(ways.out(plug), 0, node) && !ways.obstacles.inside(plug.point, 0, node);\n}\n\n/** This function gives the plug at the middle of a side of the node: the side with a free way out that faces `toward` most. */\nfunction sidePlug(ways: Ways, node: Node, toward: Point): Plug {\n const b = node.box;\n const c = center(b);\n const d = { x: toward.x - c.x, y: toward.y - c.y };\n const facing = (s: Side): number => SIDE_NORMAL[s].x * d.x + SIDE_NORMAL[s].y * d.y;\n const order = [...SIDES].sort((u, v) => facing(v) - facing(u));\n const plug = (s: Side): Plug => {\n const n = SIDE_NORMAL[s];\n return { point: { x: c.x + (n.x * b.w) / 2, y: c.y + (n.y * b.h) / 2 }, normal: n };\n };\n for (const s of order) if (isFree(ways, node, plug(s))) return plug(s);\n return plug(order[0]!);\n}\n\n/** The two ends of a link: each plug, and the point where the link turns away from the normal of the plug. */\ninterface Ends {\n readonly ps: Plug;\n readonly pt: Plug;\n readonly a: Point;\n readonly b: Point;\n}\n\n/**\n * This function gives the ends of a link. The link leaves each plug along its normal for the margin.\n * A box can be nearer than twice the margin in front of a plug. Then the link turns in the middle of the space before that box.\n * Two plugs that face each other across a narrow space make the link turn in the middle of that space.\n */\nfunction ends(ways: Ways, s: Node, ps: Plug, t: Node, pt: Plug): Ends {\n let ra = reach(ways, s, ps);\n let rb = reach(ways, t, pt);\n // Two plugs that face each other turn at the same distance, so the link does not go past itself.\n if (ps.normal.x === -pt.normal.x && ps.normal.y === -pt.normal.y) {\n const d = (pt.point.x - ps.point.x) * ps.normal.x + (pt.point.y - ps.point.y) * ps.normal.y;\n if (d > 0 && ra + rb > d) ra = rb = d / 2;\n }\n return { ps, pt, a: along(ps, ra), b: along(pt, rb) };\n}\n\nconst along = (p: Plug, d: number): Point => ({ x: p.point.x + p.normal.x * d, y: p.point.y + p.normal.y * d });\n\n/** This function gives the distance that a link goes along the normal of a plug before it turns. */\nfunction reach(ways: Ways, node: Node, plug: Plug): number {\n const skip = new Set([node]);\n const far = 2 * ways.margin;\n if (ways.obstacles.clear(plug.point, along(plug, far), 0, skip)) return ways.margin;\n let lo = 0;\n let hi = far;\n for (let i = 0; i < 10; i++) {\n const m = (lo + hi) / 2;\n if (ways.obstacles.clear(plug.point, along(plug, m), 0, skip)) lo = m;\n else hi = m;\n }\n return lo / 2;\n}\n\n/**\n * This function gives the way between the ends when one or two legs parallel to the axes are clear, or `undefined`.\n * The legs keep half the margin from the boxes, or less when an end turns nearer to a box.\n */\nfunction quickWay(ways: Ways, e: Ends): Point[] | undefined {\n const near = Math.min(dist(e.ps.point, e.a), dist(e.pt.point, e.b));\n const pad = Math.max(0, Math.min(ways.margin / 2, near - 1));\n const legs = square(e.a, e.b, ways.obstacles, pad, axisOf(e.ps.normal), axisOf(e.pt.normal));\n return legs && tidy([e.ps.point, e.a, ...legs, e.pt.point]);\n}\n\n/**\n * This function gives a way from plug to plug through the corner graph. The way leaves and enters each plug along its normal.\n * Then it pulls the corners tight with legs that are parallel to the axes, where the obstacles let it.\n */\nfunction squareWay(ways: Ways, e: Ends): Point[] {\n const quick = quickWay(ways, e);\n if (quick) return quick;\n const legs = squarePull(ways.corners.path(e.a, e.b) ?? [e.a, e.b], ways.obstacles, ways.margin / 2, axisOf(e.ps.normal), axisOf(e.pt.normal));\n return tidy([e.ps.point, ...legs, e.pt.point]);\n}\n\ntype Axis = \"x\" | \"y\";\n\nconst axisOf = (n: Point): Axis => (Math.abs(n.x) > Math.abs(n.y) ? \"x\" : \"y\");\n\n/**\n * This function pulls a path tight. From each vertex, it goes to the farthest vertex that one or two legs can reach.\n * These legs are parallel to the axes and clear of the obstacles by `pad`. It keeps a diagonal leg only where no such legs are clear.\n * `first` is the axis of the way into the first vertex, and `last` is the axis of the way out of the last vertex.\n */\nfunction squarePull(p: readonly Point[], obstacles: Obstacles, pad: number, first: Axis, last: Axis, lookahead = 16): Point[] {\n if (p.length === 0) return [];\n const out: Point[] = [p[0]!];\n let axis: Axis | undefined = first;\n let i = 0;\n while (i < p.length - 1) {\n let step: { j: number; legs: Point[] } | undefined;\n for (let j = Math.min(p.length - 1, i + lookahead); j > i && !step; j--) {\n const legs = square(p[i]!, p[j]!, obstacles, pad, axis, j === p.length - 1 ? last : undefined);\n if (legs) step = { j, legs };\n }\n // With no clear legs to the next vertex, the legs may touch a box, but they do not go through it.\n step ??= {\n j: i + 1,\n legs: square(p[i]!, p[i + 1]!, obstacles, 0, axis, i + 1 === p.length - 1 ? last : undefined) ?? [p[i + 1]!],\n };\n out.push(...step.legs);\n const end = out[out.length - 1]!;\n const before = out[out.length - 2]!;\n axis = Math.abs(end.y - before.y) < EPS ? \"x\" : Math.abs(end.x - before.x) < EPS ? \"y\" : undefined;\n i = step.j;\n }\n return out;\n}\n\n/**\n * This function gives one or two legs parallel to the axes from `a` to `b`, clear of the obstacles by `pad`, or `undefined`.\n * Of two clear corners, it picks the corner that continues the axis `from` and arrives along the axis `to`.\n */\nfunction square(a: Point, b: Point, obstacles: Obstacles, pad: number, from: Axis | undefined, to: Axis | undefined): Point[] | undefined {\n if (Math.abs(a.x - b.x) < EPS || Math.abs(a.y - b.y) < EPS) return obstacles.clear(a, b, pad) ? [b] : undefined;\n // The corner of `x` goes along the x axis first, and the corner of `y` along the y axis first.\n const options: { c: Point; bends: number }[] = [\n { c: { x: b.x, y: a.y }, bends: (from === \"y\" ? 1 : 0) + (to === \"x\" ? 1 : 0) },\n { c: { x: a.x, y: b.y }, bends: (from === \"x\" ? 1 : 0) + (to === \"y\" ? 1 : 0) },\n ];\n options.sort((u, v) => u.bends - v.bends);\n for (const { c } of options) if (obstacles.clear(a, c, pad) && obstacles.clear(c, b, pad)) return [c, b];\n return undefined;\n}\n","import { center, dist, polylineLength, type Box, type Point } from \"../geom.ts\";\nimport { levelLinks, type ItemPair } from \"../levels.ts\";\nimport { nodeIndex, type Graph, type Level, type LevelItem, type Node, type Result, type Route, type Router, type SharedRun } from \"../model.ts\";\nimport { placePlug } from \"../plugs.ts\";\nimport { allSections, buildSections, treeDepth, type Section, type SectionOptions } from \"../sections.ts\";\nimport { orderLanes } from \"../segments.ts\";\nimport { WayFinder, type WayOptions } from \"../ways.ts\";\n\n/** The options of the router with sections. */\nexport interface SectionsOptions extends WayOptions, SectionOptions {\n /** The name in the benchmark. */\n readonly name: string;\n /**\n * The number of hubs on each side of the lowest common section that a way passes. A smaller number gives shorter ways\n * and fewer shared ways. Without it, a way passes each hub from its node up.\n */\n readonly hubs?: number;\n /** A way through the hubs can be at most this many times as long as the line between its plugs. Else the edge goes directly. The default is 2. */\n readonly stretch?: number;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\nconst dedupe = (p: readonly Point[]): Point[] => p.filter((q, i) => i === 0 || dist(q, p[i - 1]!) > 1e-9);\n\n/**\n * This function makes a router with a tree of sections. Each section has a hub: the free corner nearest to the center of its nodes.\n * An edge goes from its node up the hubs of its sections to the lowest common section, across, and down to the other node.\n * Each way from hub to hub is found one time, so all the edges on it share its points.\n * The edges in one section of the lowest level go straight around the nodes.\n *\n * The result gives one zoom level for each depth of the tree.\n * A link of a level goes from the boundary of one item to the boundary of the other, around the other items.\n */\nexport function sectionsRouter(options: SectionsOptions): Router {\n const router: Router = {\n name: options.name,\n route(graph: Graph): Result {\n const stretch = options.stretch ?? 2;\n const byId = nodeIndex(graph);\n const indexOfNode = new Map(graph.nodes.map((n, i) => [n.id, i]));\n const ways = new WayFinder(graph.nodes, options);\n const corners = ways.corners;\n const root = buildSections(graph.nodes, options);\n const parent = new Map<Section, Section>();\n const leafOf: Section[] = [];\n for (const s of allSections(root)) {\n for (const c of s.children) parent.set(c, s);\n if (s.children.length === 0) for (const i of s.nodes) leafOf[i] = s;\n }\n const hubs = new Map<Section, Point>();\n const hub = (s: Section): Point => {\n let h = hubs.get(s);\n if (!h) {\n let x = 0;\n let y = 0;\n for (const i of s.nodes) {\n const c = center(graph.nodes[i]!.box);\n x += c.x;\n y += c.y;\n }\n const c = { x: x / Math.max(1, s.nodes.length), y: y / Math.max(1, s.nodes.length) };\n const j = corners.nearest(c);\n h = j >= 0 ? corners.points[j]! : c;\n hubs.set(s, h);\n }\n return h;\n };\n const up = (s: Section): Section[] => {\n const out: Section[] = [];\n for (let x: Section | undefined = s; x; x = parent.get(x)) out.push(x);\n return out;\n };\n\n // The ways between two places, found one time. A place is a hub or a free point.\n const pieces = new Map<string, Point[]>();\n const users = new Map<string, string[]>();\n const piece = (ka: string, a: Point, kb: string, b: Point, used: string[]): Point[] => {\n const forward = ka <= kb;\n const key = forward ? `${ka}>${kb}` : `${kb}>${ka}`;\n let p = pieces.get(key);\n if (!p) {\n const [from, to] = forward ? [a, b] : [b, a];\n const way = corners.path(from, to);\n p = dedupe(way ? corners.pull(way) : [from, to]);\n pieces.set(key, p);\n }\n if (!used.includes(key)) used.push(key);\n return forward ? p : [...p].reverse();\n };\n const at = (p: Point): string => `${p.x},${p.y}`;\n\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n const iu = indexOfNode.get(e.source.node);\n const iv = indexOfNode.get(e.target.node);\n if (!s || !t || iu === undefined || iv === undefined) continue;\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n const lu = leafOf[iu]!;\n const lv = leafOf[iv]!;\n if (lu === lv) {\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n continue;\n }\n const a = up(lu);\n const b = up(lv);\n const common = new Set(b);\n const lca = a.find((x) => common.has(x))!;\n const keep = options.hubs ?? Infinity;\n const side = (list: Section[]): Section[] => list.slice(Math.max(0, list.indexOf(lca) - keep), list.indexOf(lca));\n const chain = [...side(a), ...side(b).reverse()];\n const out: Point[] = [ps.point];\n const append = (p: readonly Point[]): void => {\n for (const q of p) if (dist(q, out[out.length - 1]!) > 1e-9) out.push(q);\n };\n const used: string[] = [];\n const start = ways.out(ps);\n append(piece(at(start), start, chain[0]!.id, hub(chain[0]!), used));\n for (let i = 1; i < chain.length; i++) append(piece(chain[i - 1]!.id, hub(chain[i - 1]!), chain[i]!.id, hub(chain[i]!), used));\n const end = ways.out(pt);\n append(piece(chain[chain.length - 1]!.id, hub(chain[chain.length - 1]!), at(end), end, used));\n append([pt.point]);\n // A way through the hubs that is too long gives way to the direct way.\n if (polylineLength(out) > stretch * dist(ps.point, pt.point) + 4 * ways.margin) {\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n continue;\n }\n for (const key of used) {\n const list = users.get(key);\n if (list) list.push(e.id);\n else users.set(key, [e.id]);\n }\n routes.push({ edge: e.id, points: out });\n }\n\n const routeOf = new Map(routes.map((r) => [r.edge, r]));\n const runs: SharedRun[] = [];\n for (const [key, p] of pieces) {\n const list = users.get(key) ?? [];\n if (list.length < 2 || p.length < 2) continue;\n runs.push({ id: `r${runs.length}`, key, points: p, edges: orderLanes(p, list.map((id) => routeOf.get(id)!)) });\n }\n return { routes, runs, levels: makeLevels(graph, root, routeOf, options) };\n },\n };\n return options.maxNodes === undefined ? router : { ...router, maxNodes: options.maxNodes };\n}\n\n/**\n * This function gives one zoom level for each depth of the tree, and a last level with each node alone.\n * At depth d, a section of depth d is one item. A link joins two items and counts the edges between them.\n * In a level with groups, a link goes around the boxes of the other items (`levelLinks`).\n * In the last level, the points of a link are the route of its first edge.\n */\nfunction makeLevels(graph: Graph, root: Section, routeOf: ReadonlyMap<string, Route>, options: WayOptions): Level[] {\n const indexOfNode = new Map(graph.nodes.map((n, i) => [n.id, i]));\n const levels: Level[] = [];\n const deepest = treeDepth(root);\n for (let d = 0; d <= deepest + 1; d++) {\n const items: LevelItem[] = [];\n const itemOf: (Section | number)[] = [];\n const boxOf = (list: readonly number[]): Box => {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const i of list) {\n const b = graph.nodes[i]!.box;\n x0 = Math.min(x0, b.x);\n y0 = Math.min(y0, b.y);\n x1 = Math.max(x1, b.x + b.w);\n y1 = Math.max(y1, b.y + b.h);\n }\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 };\n };\n const visit = (s: Section): void => {\n if (s.depth >= d) {\n items.push({ id: s.id, box: boxOf(s.nodes), nodes: s.nodes.map((i) => graph.nodes[i]!.id) });\n for (const i of s.nodes) itemOf[i] = s;\n } else if (s.children.length > 0) for (const c of s.children) visit(c);\n else\n for (const i of s.nodes) {\n const n = graph.nodes[i]!;\n items.push({ id: n.id, box: n.box, nodes: [n.id] });\n itemOf[i] = i;\n }\n };\n if (graph.nodes.length > 0) visit(root);\n const links = new Map<string, { source: string; target: string; count: number; edge: string }>();\n for (const e of graph.edges) {\n const iu = indexOfNode.get(e.source.node);\n const iv = indexOfNode.get(e.target.node);\n if (iu === undefined || iv === undefined) continue;\n const a = itemOf[iu]!;\n const b = itemOf[iv]!;\n if (a === b) continue;\n const ida = typeof a === \"number\" ? graph.nodes[a]!.id : a.id;\n const idb = typeof b === \"number\" ? graph.nodes[b]!.id : b.id;\n const key = `${ida}\\u0000${idb}`;\n const link = links.get(key);\n if (link) {\n link.count++;\n continue;\n }\n links.set(key, { source: ida, target: idb, count: 1, edge: e.id });\n }\n const pairs: ItemPair[] = [...links.values()].map(({ source, target, count }) => ({ source, target, count }));\n if (d > deepest)\n levels.push({ depth: d, items, links: [...links.values()].map(({ edge, ...l }) => ({ ...l, points: routeOf.get(edge)?.points ?? [] })) });\n else levels.push({ depth: d, items, links: levelLinks(items, pairs, options) });\n }\n return levels;\n}\n","import { center, dist, type Point } from \"../geom.ts\";\nimport { nodeIndex, type Edge, type Graph, type GroupRule, type Result, type Route, type Router, type SharedRun } from \"../model.ts\";\nimport { placePlug, type Plug } from \"../plugs.ts\";\nimport { WayFinder, type WayOptions } from \"../ways.ts\";\n\n/** The options of the router with shared ways. */\nexport interface SharedOptions extends WayOptions {\n /** The name in the benchmark. */\n readonly name: string;\n /** The edges with one key share their ways. Without a rule, all edges share. An edge without a key shares with no edge. */\n readonly rule?: GroupRule;\n /** The cost of a link that an edge with the same key uses already, as a share of its length. The default is 0.5. */\n readonly discount?: number;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\ninterface Way {\n readonly edge: Edge;\n readonly key: string;\n readonly ps: Plug;\n readonly pt: Plug;\n /** The way through the corner graph, from the point out of the source plug to the point out of the target plug. */\n seq: Point[];\n /** The index of each point of `seq` in the corner graph. The two ends get an index after the corners, one for each place. */\n ids: number[];\n found: boolean;\n}\n\ninterface Run {\n readonly key: string;\n readonly first: number;\n readonly last: number;\n /** The points from the corner `first` to the corner `last`, without the needless corners. */\n readonly points: Point[];\n readonly ways: Way[];\n}\n\nconst byText = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);\n\n/** The angle, from -π to π, of the turn at `base` from the direction `from` → `base` to the point `to`. */\nfunction turn(from: Point, base: Point, to: Point): number {\n const dx = base.x - from.x;\n const dy = base.y - from.y;\n const vx = to.x - base.x;\n const vy = to.y - base.y;\n return Math.atan2(dx * vy - dy * vx, dx * vx + dy * vy);\n}\n\n/**\n * This function makes a router where edges share their ways (after Pupyrev, Nachmanson, Bereg and Holroyd, \"Edge routing with ordered bundles\").\n * The edges go one by one through the corner graph. A link that an edge with the same key uses already costs less.\n * Thus the edges of a key come together on common ways. Each stretch that several edges share has the same points in each route.\n * The result gives each stretch as a run, with the order of its lanes.\n */\nexport function sharedRouter(options: SharedOptions): Router {\n const discount = Math.min(1, Math.max(0.05, options.discount ?? 0.5));\n const keyOf = (e: Edge): string => {\n if (!options.rule) return \"*\";\n return options.rule(e) ?? `\\u0000${e.id}`;\n };\n const router: Router = {\n name: options.name,\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const ways = new WayFinder(graph.nodes, options);\n const corners = ways.corners;\n const index = new Map<Point, number>();\n corners.points.forEach((p, i) => index.set(p, i));\n const M = corners.points.length + 1;\n const link = (i: number, j: number): number => (i < j ? i * M + j : j * M + i);\n const ends = new Map<string, number>();\n const endId = (p: Point): number => {\n const k = `${p.x},${p.y}`;\n let id = ends.get(k);\n if (id === undefined) ends.set(k, (id = corners.points.length + ends.size));\n return id;\n };\n\n const all: Way[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n all.push({ edge: e, key: keyOf(e), ps, pt, seq: [], ids: [], found: false });\n }\n\n // The edges of one key go one after the other, the longest first, so that the short edges join the long ways.\n const discounted = new Map<string, Map<number, string[]>>();\n const order = [...all].sort(\n (p, q) => byText(p.key, q.key) || dist(q.ps.point, q.pt.point) - dist(p.ps.point, p.pt.point) || byText(p.edge.id, q.edge.id),\n );\n for (const w of order) {\n let used = discounted.get(w.key);\n if (!used) discounted.set(w.key, (used = new Map()));\n const mine = used;\n const way = corners.path(ways.out(w.ps), ways.out(w.pt), (i, j, d) => (mine.has(link(i, j)) ? d * discount : d), discount);\n if (!way) continue;\n w.found = true;\n w.seq = way;\n w.ids = way.map((p, i) => (i === 0 || i === way.length - 1 ? endId(p) : index.get(p)!));\n for (let i = 1; i < w.ids.length; i++) {\n const a = w.ids[i - 1]!;\n const b = w.ids[i]!;\n if (a >= corners.points.length || b >= corners.points.length) continue;\n const list = mine.get(link(a, b));\n if (list) list.push(w.edge.id);\n else mine.set(link(a, b), [w.edge.id]);\n }\n }\n\n // The users of each link, with the links to the ends. Two edges from one plug share the link from it.\n const users = new Map<string, Map<string, string[]>>();\n for (const w of order) {\n if (!w.found) continue;\n let mine = users.get(w.key);\n if (!mine) users.set(w.key, (mine = new Map()));\n for (let i = 1; i < w.ids.length; i++) {\n const a = w.ids[i - 1]!;\n const b = w.ids[i]!;\n const k = a < b ? `${a}:${b}` : `${b}:${a}`;\n const list = mine.get(k);\n if (list) list.push(w.edge.id);\n else mine.set(k, [w.edge.id]);\n }\n }\n\n // Each way breaks into stretches where the set of edges on the links stays the same.\n // A shared stretch loses its needless corners one time, so it has the same points in each of its routes.\n const runs = new Map<string, Run>();\n const points = new Map<string, Point[]>();\n for (const w of all) {\n if (!w.found) continue;\n const used = users.get(w.key)!;\n const sig = (i: number): string => {\n const a = w.ids[i]!;\n const b = w.ids[i + 1]!;\n const list = used.get(a < b ? `${a}:${b}` : `${b}:${a}`)!;\n return list.length < 2 ? \"\" : [...list].sort(byText).join(\"\\u0001\");\n };\n const out: Point[] = [w.ps.point];\n const append = (piece: readonly Point[]): void => {\n for (const p of piece) if (dist(p, out[out.length - 1]!) > 1e-9) out.push(p);\n };\n let start = 0;\n for (let i = 0; i < w.seq.length - 1; i++) {\n const s = sig(i);\n if (i + 1 < w.seq.length - 1 && sig(i + 1) === s) continue;\n const raw = w.seq.slice(start, i + 2);\n if (s === \"\") append(corners.pull(raw));\n else {\n const a = w.ids[start]!;\n const b = w.ids[i + 1]!;\n const id = `${s}\\u0002${Math.min(a, b)}\\u0002${Math.max(a, b)}`;\n let run = runs.get(id);\n if (!run) {\n run = { key: w.key, first: Math.min(a, b), last: Math.max(a, b), points: corners.pull(a < b ? raw : [...raw].reverse()), ways: [] };\n runs.set(id, run);\n }\n run.ways.push(w);\n append(a < b ? run.points : [...run.points].reverse());\n }\n start = i + 1;\n }\n append([w.pt.point]);\n points.set(w.edge.id, out);\n }\n\n const routes: Route[] = [];\n for (const w of all) routes.push({ edge: w.edge.id, points: points.get(w.edge.id) ?? [w.ps.point, w.pt.point] });\n const shared: SharedRun[] = [];\n for (const run of runs.values()) {\n shared.push({ id: `r${shared.length}`, key: run.key, points: run.points, edges: laneOrderOfRun(run) });\n }\n return { routes, runs: shared };\n },\n };\n return options.maxNodes === undefined ? router : { ...router, maxNodes: options.maxNodes };\n}\n\n/**\n * This function gives the lane order of a run (metro-line order). Two edges of the run go together past its last corner\n * until they part. The edge that turns more to the left there gets the lane more to the left.\n * Two edges can part only before the first corner. Then the edge that comes from more to the left gets the lane more to the left.\n */\nfunction laneOrderOfRun(run: Run): string[] {\n const oriented = new Map<Way, { seq: Point[]; ids: number[]; s: number; e: number }>();\n for (const w of run.ways) {\n const s0 = w.ids.indexOf(run.first);\n const e0 = w.ids.indexOf(run.last);\n if (s0 < e0) oriented.set(w, { seq: w.seq, ids: w.ids, s: s0, e: e0 });\n else oriented.set(w, { seq: [...w.seq].reverse(), ids: [...w.ids].reverse(), s: w.seq.length - 1 - s0, e: w.seq.length - 1 - e0 });\n }\n const compare = (p: Way, q: Way): number => {\n const P = oriented.get(p)!;\n const Q = oriented.get(q)!;\n for (let j = 1; ; j++) {\n const a = P.seq[P.e + j];\n const b = Q.seq[Q.e + j];\n if (a === undefined || b === undefined) break;\n if (P.ids[P.e + j] !== Q.ids[Q.e + j]) {\n const d = turn(P.seq[P.e + j - 2]!, P.seq[P.e + j - 1]!, a) - turn(P.seq[P.e + j - 2]!, P.seq[P.e + j - 1]!, b);\n if (d !== 0) return d;\n break;\n }\n }\n for (let j = 1; ; j++) {\n const a = P.seq[P.s - j];\n const b = Q.seq[Q.s - j];\n if (a === undefined || b === undefined) break;\n if (P.ids[P.s - j] !== Q.ids[Q.s - j]) {\n // Seen backward, the left side is the right side. Thus the order turns around.\n const d = turn(P.seq[P.s - j + 2]!, P.seq[P.s - j + 1]!, b) - turn(P.seq[P.s - j + 2]!, P.seq[P.s - j + 1]!, a);\n if (d !== 0) return d;\n break;\n }\n }\n return byText(p.edge.id, q.edge.id);\n };\n return [...run.ways].sort(compare).map((w) => w.edge.id);\n}\n","import { center, type Box, type Point } from \"../geom.ts\";\nimport { fixedPortPoint, nodeIndex, type Graph, type Result, type Route, type Router } from \"../model.ts\";\n\n/** This function gives the point where the ray from the center of the box to `toward` leaves the box. */\nexport function boxExit(box: Box, toward: Point): Point {\n const c = center(box);\n const dx = toward.x - c.x;\n const dy = toward.y - c.y;\n if (dx === 0 && dy === 0) return c;\n const tx = dx === 0 ? Infinity : box.w / 2 / Math.abs(dx);\n const ty = dy === 0 ? Infinity : box.h / 2 / Math.abs(dy);\n const t = Math.min(tx, ty);\n return { x: c.x + dx * t, y: c.y + dy * t };\n}\n\n/**\n * The control of the benchmark: each edge is one straight line between its plugs.\n * A free plug goes where the line between the two centers leaves the box.\n */\nexport const straightRouter: Router = {\n name: \"straight\",\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const fs = fixedPortPoint(s, e.source);\n const ft = fixedPortPoint(t, e.target);\n const a = fs ?? boxExit(s.box, ft ?? center(t.box));\n const b = ft ?? boxExit(t.box, fs ?? center(s.box));\n routes.push({ edge: e.id, points: [a, b] });\n }\n return { routes };\n },\n};\n","import { center, dist, type Point } from \"../geom.ts\";\nimport { nodeIndex, type Bundle, type Edge, type Graph, type GroupRule, type Node, type Result, type Route, type Router } from \"../model.ts\";\nimport { placePlug, type Plug } from \"../plugs.ts\";\nimport { WayFinder, type WayOptions } from \"../ways.ts\";\n\n/** The options of the trunk router. */\nexport interface TrunksOptions extends WayOptions {\n /** The name in the benchmark. */\n readonly name: string;\n /** The grouping rule. The edges from one plug with one key share a trunk. */\n readonly rule: GroupRule;\n /** The split point is at this share of the way to the center of the targets. The default is 0.5. */\n readonly split?: number;\n /** A group with fewer edges stays unbundled. The default is 2. */\n readonly minSize?: number;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\n/** The rule that groups the edges by the collection of their target, in `data.collection`. */\nexport const byCollection: GroupRule = (e) => {\n const c = e.data?.[\"collection\"];\n return typeof c === \"string\" ? c : undefined;\n};\n\n/**\n * This function groups the edges by their source plug and their key. Each group keeps the order of the edges.\n * A group with fewer than `minSize` edges does not appear.\n */\nexport function groupEdges(edges: readonly Edge[], rule: GroupRule, minSize = 2): Map<string, Edge[]> {\n const all = new Map<string, Edge[]>();\n for (const e of edges) {\n const key = rule(e);\n if (key === undefined) continue;\n const id = `${e.source.node}\\u0000${e.source.port ?? \"\"}\\u0000${key}`;\n const list = all.get(id);\n if (list) list.push(e);\n else all.set(id, [e]);\n }\n for (const [id, list] of all) if (list.length < minSize) all.delete(id);\n return all;\n}\n\n/**\n * This function gives the lane order of the branches that leave the split point `from`, with the trunk along `dir`.\n * Lane 0 turns most to the left, in a frame with the y axis down. Thus two lanes do not cross at the split.\n */\nexport function laneOrder(dir: Point, from: Point, branches: readonly { readonly edge: string; readonly next: Point }[]): string[] {\n const angle = (p: Point): number => {\n const vx = p.x - from.x;\n const vy = p.y - from.y;\n return Math.atan2(dir.x * vy - dir.y * vx, dir.x * vx + dir.y * vy);\n };\n return branches\n .map((b) => ({ edge: b.edge, a: angle(b.next) }))\n .sort((p, q) => p.a - q.a || (p.edge < q.edge ? -1 : p.edge > q.edge ? 1 : 0))\n .map((x) => x.edge);\n}\n\n/**\n * This function gives the split point of a bundle, on the line from `start` to the center of the targets.\n * The point is at `split` of the way, but at most half of the way to the nearest target. It moves back toward `start` out of the boxes.\n */\nexport function splitPoint(start: Point, targets: readonly Point[], split: number, free: (p: Point) => boolean, step: number): Point {\n if (targets.length === 0) return start;\n const c = { x: targets.reduce((s, p) => s + p.x, 0) / targets.length, y: targets.reduce((s, p) => s + p.y, 0) / targets.length };\n const L = dist(start, c);\n if (L === 0) return start;\n let d = Math.min(split * L, 0.5 * Math.min(...targets.map((p) => dist(start, p))));\n const at = (t: number): Point => ({ x: start.x + ((c.x - start.x) * t) / L, y: start.y + ((c.y - start.y) * t) / L });\n while (d > 0 && !free(at(d))) d -= step;\n return d > 0 ? at(d) : start;\n}\n\nconst dedupe = (p: readonly Point[]): Point[] => p.filter((q, i) => i === 0 || dist(q, p[i - 1]!) > 1e-9);\n\n/**\n * This function makes a router that bundles the edges by a rule. The edges of a group share one plug and one trunk\n * to a split point. From there, each edge goes its own way. The router gives the bundles with their lane order.\n * The edges outside the groups go as in the corner router.\n */\nexport function trunksRouter(options: TrunksOptions): Router {\n const router: Router = {\n name: options.name,\n route(graph: Graph): Result {\n const byId = nodeIndex(graph);\n const ways = new WayFinder(graph.nodes, options);\n const points = new Map<string, Point[]>();\n const bundles: Bundle[] = [];\n for (const [id, group] of groupEdges(graph.edges, options.rule, options.minSize ?? 2)) {\n const first = group[0]!;\n const s = byId.get(first.source.node);\n const targets = group.map((e) => byId.get(e.target.node));\n if (!s || targets.some((t) => !t)) continue;\n const centers = targets.map((t) => center(t!.box));\n const c = { x: centers.reduce((a, p) => a + p.x, 0) / centers.length, y: centers.reduce((a, p) => a + p.y, 0) / centers.length };\n const plug: Plug = placePlug(s, first.source, c);\n const start = ways.out(plug);\n const split = splitPoint(start, centers, options.split ?? 0.5, (p) => !ways.obstacles.inside(p, ways.margin), ways.margin);\n const way = ways.fromPlug(plug, split);\n if (!way) continue;\n const trunk = dedupe(way);\n const end = trunk[trunk.length - 1]!;\n const prev = trunk.length >= 2 ? trunk[trunk.length - 2]! : plug.point;\n const len = dist(prev, end);\n const dir = len > 0 ? { x: (end.x - prev.x) / len, y: (end.y - prev.y) / len } : plug.normal;\n const branches: { edge: string; next: Point }[] = [];\n group.forEach((e, i) => {\n const pt = placePlug(targets[i]!, e.target, end);\n const branch = dedupe(ways.toPlug(end, pt) ?? [end, pt.point]);\n points.set(e.id, dedupe([...trunk, ...branch.slice(1)]));\n branches.push({ edge: e.id, next: branch[1] ?? pt.point });\n });\n bundles.push({ id: `b${bundles.length}`, key: id.split(\"\\u0000\")[2]!, node: s.id, edges: laneOrder(dir, end, branches), trunk });\n }\n const routes: Route[] = [];\n for (const e of graph.edges) {\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n const known = points.get(e.id);\n if (known) {\n routes.push({ edge: e.id, points: known });\n continue;\n }\n const ps = placePlug(s, e.source, center(t.box));\n const pt = placePlug(t, e.target, center(s.box));\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n }\n return { routes, bundles };\n },\n };\n return options.maxNodes === undefined ? router : { ...router, maxNodes: options.maxNodes };\n}\n","import type { Router } from \"../model.ts\";\nimport { cornersRouter } from \"./corners.ts\";\nimport { plugsRouter } from \"./plugs.ts\";\nimport { sectionsRouter } from \"./sections.ts\";\nimport { sharedRouter } from \"./shared.ts\";\nimport { straightRouter } from \"./straight.ts\";\nimport { byCollection, trunksRouter } from \"./trunks.ts\";\n\nexport { boxExit, straightRouter } from \"./straight.ts\";\nexport { plugsRouter } from \"./plugs.ts\";\nexport { cornersRouter, type CornersOptions } from \"./corners.ts\";\nexport { sharedRouter, type SharedOptions } from \"./shared.ts\";\nexport { sectionsRouter, type SectionsOptions } from \"./sections.ts\";\nexport { byCollection, groupEdges, laneOrder, splitPoint, trunksRouter, type TrunksOptions } from \"./trunks.ts\";\n\n/** The routers that the benchmark races. */\nexport const ROUTERS: readonly Router[] = [\n straightRouter,\n plugsRouter,\n cornersRouter({ name: \"corners\", maxNodes: 10_000 }),\n cornersRouter({ name: \"corners-smooth\", smooth: true, maxNodes: 10_000 }),\n trunksRouter({ name: \"trunks\", rule: byCollection, maxNodes: 10_000 }),\n sharedRouter({ name: \"shared\", rule: byCollection, maxNodes: 10_000 }),\n sharedRouter({ name: \"shared-all\", maxNodes: 10_000 }),\n sectionsRouter({ name: \"sections\", maxNodes: 100_000 }),\n sectionsRouter({ name: \"sections-tree\", stretch: Infinity, maxNodes: 100_000 }),\n];\n","import { dist, inflate, pointBoxDistance, segmentHitsBox, type Box, type Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport { fixedPortPoint, nodeIndex, type Graph, type Node, type Result } from \"../model.ts\";\n\n/** A broken hard rule. A correct router has none. */\nexport interface Violation {\n readonly rule:\n | \"complete\"\n | \"ends-at-plugs\"\n | \"fixed-plugs\"\n | \"no-pass-through\"\n | \"counts-sum\"\n | \"link-ends\"\n | \"bundle-trunk\"\n | \"run-shared\";\n readonly edge?: string;\n readonly detail: string;\n}\n\n/** The tolerance of the hard rules, in units of the plane. */\nexport const TOLERANCE = 0.5;\n\n/**\n * This function checks the hard rules of a result. Each edge has one route, and each route starts and ends at its nodes.\n * Fixed plugs stay in place. No route goes through a node that is not one of its ends. The counts of each level add up.\n * Each link of a level starts on the box of its source and ends on the box of its target.\n *\n * Each route of a bundle starts with its trunk, and an edge is in one bundle at most.\n * Each run has two edges or more, and the route of each edge holds the points of the run in a row.\n * The function gives at most `limit` violations.\n */\nexport function checkProperties(graph: Graph, result: Result, limit = 100): Violation[] {\n const out: Violation[] = [];\n const add = (v: Violation): boolean => {\n out.push(v);\n return out.length >= limit;\n };\n const byId = nodeIndex(graph);\n const grid = new Grid<Node>(180);\n for (const n of graph.nodes) grid.add(n, n.box);\n const routes = new Map<string, (typeof result.routes)[number]>();\n for (const r of result.routes) routes.set(r.edge, r);\n for (const e of graph.edges) {\n const r = routes.get(e.id);\n const s = byId.get(e.source.node);\n const t = byId.get(e.target.node);\n if (!s || !t) continue;\n if (!r || r.points.length < 2) {\n if (add({ rule: \"complete\", edge: e.id, detail: \"no route\" })) return out;\n continue;\n }\n const a = r.points[0]!;\n const b = r.points[r.points.length - 1]!;\n if (pointBoxDistance(a, s.box) > TOLERANCE || pointBoxDistance(b, t.box) > TOLERANCE)\n if (add({ rule: \"ends-at-plugs\", edge: e.id, detail: \"an end of the route is away from its node\" })) return out;\n const fs = fixedPortPoint(s, e.source);\n const ft = fixedPortPoint(t, e.target);\n if ((fs && dist(fs, a) > TOLERANCE) || (ft && dist(ft, b) > TOLERANCE))\n if (add({ rule: \"fixed-plugs\", edge: e.id, detail: \"the route does not start or end at its fixed plug\" })) return out;\n for (let i = 1; i < r.points.length; i++) {\n const p = r.points[i - 1]!;\n const q = r.points[i]!;\n let hit: Node | undefined;\n grid.querySegment(p, q, 0, (n) => {\n if (!hit && n !== s && n !== t && segmentHitsBox(p, q, inflate(n.box, -TOLERANCE))) hit = n;\n });\n if (hit) {\n if (add({ rule: \"no-pass-through\", edge: e.id, detail: `segment ${i} goes through ${hit.id}` })) return out;\n break;\n }\n }\n }\n const bundled = new Set<string>();\n for (const b of result.bundles ?? []) {\n for (const id of b.edges) {\n const r = routes.get(id);\n const shares = r !== undefined && r.points.length >= b.trunk.length && b.trunk.every((p, i) => dist(p, r.points[i]!) <= TOLERANCE);\n if (bundled.has(id) || !shares)\n if (add({ rule: \"bundle-trunk\", edge: id, detail: `bundle ${b.id}: the route is in two bundles or does not start with the trunk` })) return out;\n bundled.add(id);\n }\n }\n for (const run of result.runs ?? []) {\n if (run.edges.length < 2)\n if (add({ rule: \"run-shared\", detail: `run ${run.id} has fewer than two edges` })) return out;\n for (const id of run.edges) {\n const r = routes.get(id);\n if (!r || !(holds(r.points, run.points) || holds(r.points, [...run.points].reverse())))\n if (add({ rule: \"run-shared\", edge: id, detail: `run ${run.id}: the route does not hold the points of the run in a row` })) return out;\n }\n }\n for (const level of result.levels ?? []) {\n const itemOf = new Map<string, string>();\n for (const it of level.items) for (const n of it.nodes) itemOf.set(n, it.id);\n if (itemOf.size !== graph.nodes.length)\n if (add({ rule: \"counts-sum\", detail: `level ${level.depth}: the items hold ${itemOf.size} of ${graph.nodes.length} nodes` }))\n return out;\n let between = 0;\n for (const e of graph.edges) if (itemOf.get(e.source.node) !== itemOf.get(e.target.node)) between++;\n const sum = level.links.reduce((s, l) => s + l.count, 0);\n if (sum !== between)\n if (add({ rule: \"counts-sum\", detail: `level ${level.depth}: the links count ${sum} edges, not ${between}` })) return out;\n const boxOf = new Map(level.items.map((it) => [it.id, it.box]));\n for (const l of level.links) {\n const s = boxOf.get(l.source);\n const t = boxOf.get(l.target);\n const p = l.points;\n if (!s || !t || p.length < 2 || !onBoundary(p[0]!, s) || !onBoundary(p[p.length - 1]!, t))\n if (add({ rule: \"link-ends\", detail: `level ${level.depth}: the link ${l.source} to ${l.target} does not start and end on the boundaries of its items` }))\n return out;\n }\n }\n return out;\n}\n\n/** This function tells if the point is on the boundary of the box, within `TOLERANCE`. */\nfunction onBoundary(p: Point, b: Box): boolean {\n const inner = inflate(b, -TOLERANCE);\n const deep = p.x > inner.x && p.x < inner.x + inner.w && p.y > inner.y && p.y < inner.y + inner.h;\n return !deep && pointBoxDistance(p, b) <= TOLERANCE;\n}\n\n/** This function tells if the polyline `p` holds the points of `part` in a row. */\nfunction holds(p: readonly Point[], part: readonly Point[]): boolean {\n if (part.length === 0) return true;\n for (let i = 0; i + part.length <= p.length; i++) if (part.every((q, j) => dist(q, p[i + j]!) <= TOLERANCE)) return true;\n return false;\n}\n","import {\n bendCount,\n dist,\n frechet,\n inflectionCount,\n polylineLength,\n segmentBoxDistance,\n segmentsCross,\n type Box,\n type Point,\n} from \"../geom.ts\";\nimport { rng } from \"../fixtures.ts\";\nimport { Grid } from \"../grid.ts\";\nimport { nodeIndex, type Graph, type Node, type Result } from \"../model.ts\";\n\n/** The quality of a result. Lower is better for each value except `clearance`. */\nexport interface Quality {\n /** The length of all drawn lines. A segment that several routes share counts one time. */\n readonly ink: number;\n /** The number of points where two drawn segments cross. */\n readonly crossings: number;\n /** This value is true when `crossings` is an estimate from a sample of the segments. */\n readonly crossingsEstimated: boolean;\n /** The mean number of bends of a route. */\n readonly bends: number;\n /** The mean number of inflections of a route. */\n readonly inflections: number;\n /** The mean distance from a route to the nearest node that is not one of its ends, up to `CLEARANCE_CAP`. */\n readonly clearance: number;\n /** The share of the routes that come closer than 4 units to a node that is not one of their ends. */\n readonly tight: number;\n /** The mean ratio of the length of a route to the distance between its ends. */\n readonly detour: number;\n /** The mean angle, in degrees, between the first or last segment of a route and the normal of the side of its node. */\n readonly plugAngle: number;\n}\n\n/** The clearance stops at this distance. */\nexport const CLEARANCE_CAP = 40;\nconst TIGHT = 4;\nconst EXACT_CROSSINGS = 20_000;\nconst SAMPLE = 2_000;\n\nconst key = (p: Point): string => `${Math.round(p.x * 8)},${Math.round(p.y * 8)}`;\n\n/** This function measures the quality of a result. */\nexport function measureQuality(graph: Graph, result: Result): Quality {\n const byId = nodeIndex(graph);\n const nodes = new Grid<Node>(180);\n for (const n of graph.nodes) nodes.add(n, n.box);\n\n // The drawn segments: one for each distinct pair of ends.\n const segs: [Point, Point][] = [];\n const seen = new Set<string>();\n let bends = 0;\n let infl = 0;\n let clear = 0;\n let tight = 0;\n let detour = 0;\n let detourN = 0;\n let angle = 0;\n let angleN = 0;\n for (const r of result.routes) {\n const p = r.points;\n for (let i = 1; i < p.length; i++) {\n const ka = key(p[i - 1]!);\n const kb = key(p[i]!);\n if (ka === kb) continue;\n const k = ka < kb ? `${ka}|${kb}` : `${kb}|${ka}`;\n if (seen.has(k)) continue;\n seen.add(k);\n segs.push([p[i - 1]!, p[i]!]);\n }\n bends += bendCount(p);\n infl += inflectionCount(p);\n const ends = endNodes(graph, byId, r.edge);\n let c = CLEARANCE_CAP;\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n nodes.querySegment(a, b, c, (n) => {\n if (n !== ends.source && n !== ends.target) c = Math.min(c, segmentBoxDistance(a, b, n.box));\n });\n }\n clear += c;\n if (c < TIGHT) tight++;\n if (p.length >= 2) {\n const d = dist(p[0]!, p[p.length - 1]!);\n if (d > 1) {\n detour += polylineLength(p) / d;\n detourN++;\n }\n for (const [at, next, node] of [\n [p[0]!, p[1]!, ends.source],\n [p[p.length - 1]!, p[p.length - 2]!, ends.target],\n ] as const) {\n if (!node) continue;\n const a = sideAngle(node.box, at, next);\n if (a !== undefined) {\n angle += a;\n angleN++;\n }\n }\n }\n }\n const n = Math.max(1, result.routes.length);\n let ink = 0;\n for (const [a, b] of segs) ink += dist(a, b);\n const [crossings, crossingsEstimated] = countCrossings(segs);\n return {\n ink,\n crossings,\n crossingsEstimated,\n bends: bends / n,\n inflections: infl / n,\n clearance: clear / n,\n tight: tight / n,\n detour: detourN ? detour / detourN : 1,\n plugAngle: angleN ? angle / angleN : 0,\n };\n}\n\ninterface Ends {\n readonly source: Node | undefined;\n readonly target: Node | undefined;\n}\n\nfunction endNodes(graph: Graph, byId: Map<string, Node>, edgeId: string): Ends {\n const e = edgeIndex(graph).get(edgeId);\n return { source: e && byId.get(e.source.node), target: e && byId.get(e.target.node) };\n}\n\nconst edgeIndexes = new WeakMap<Graph, Map<string, Graph[\"edges\"][number]>>();\nfunction edgeIndex(graph: Graph): Map<string, Graph[\"edges\"][number]> {\n let m = edgeIndexes.get(graph);\n if (!m) {\n m = new Map();\n for (const e of graph.edges) m.set(e.id, e);\n edgeIndexes.set(graph, m);\n }\n return m;\n}\n\n/**\n * This function gives an angle in degrees: the angle between the segment from `at` to `next` and the outward normal.\n * The normal is the normal of the side of the box nearest to `at`. A route that starts inside the box (an interior route) gives no angle.\n */\nexport function sideAngle(box: Box, at: Point, next: Point): number | undefined {\n const d = [\n [Math.abs(at.y - box.y), 0, -1],\n [Math.abs(at.x - (box.x + box.w)), 1, 0],\n [Math.abs(at.y - (box.y + box.h)), 0, 1],\n [Math.abs(at.x - box.x), -1, 0],\n ].sort((a, b) => a[0]! - b[0]!)[0]!;\n if (d[0]! > 1) return undefined;\n const vx = next.x - at.x;\n const vy = next.y - at.y;\n const l = Math.hypot(vx, vy);\n if (l === 0) return undefined;\n const cos = Math.max(-1, Math.min(1, (vx * d[1]! + vy * d[2]!) / l));\n return (Math.acos(cos) * 180) / Math.PI;\n}\n\n/**\n * This function counts the crossings of a set of segments with a grid of buckets.\n * Above 20 000 segments, it counts the crossings of a seeded sample of 2 000 segments and scales the count.\n */\nexport function countCrossings(segs: readonly (readonly [Point, Point])[]): [number, boolean] {\n if (segs.length < 2) return [0, false];\n const len = segs.reduce((s, [a, b]) => s + dist(a, b), 0) / segs.length;\n const grid = new Grid<number>(Math.max(20, len));\n segs.forEach(([a, b], i) => grid.addSegment(i, a, b));\n const exact = segs.length <= EXACT_CROSSINGS;\n const R = rng(segs.length);\n const pick = exact ? segs.map((_, i) => i) : Array.from({ length: SAMPLE }, () => Math.floor(R() * segs.length));\n let count = 0;\n for (const i of pick) {\n const [a, b] = segs[i]!;\n grid.querySegment(a, b, 0, (j) => {\n if (exact && j <= i) return;\n if (j === i) return;\n const [c, d] = segs[j]!;\n if (segmentsCross(a, b, c, d)) count++;\n });\n }\n return exact ? [count, false] : [Math.round((count * segs.length) / (2 * pick.length)), true];\n}\n\n/** The change between two results of the same graph: the Fréchet distance between the two routes of each edge. */\nexport interface Stability {\n readonly mean: number;\n readonly max: number;\n /** The share of the routes that moved more than 1 unit. */\n readonly moved: number;\n}\n\n/** This function measures how much the routes changed between two results. */\nexport function measureStability(before: Result, after: Result): Stability {\n const prev = new Map(before.routes.map((r) => [r.edge, r.points] as const));\n let sum = 0;\n let max = 0;\n let moved = 0;\n let n = 0;\n for (const r of after.routes) {\n const p = prev.get(r.edge);\n if (!p) continue;\n const f = frechet(p, r.points);\n sum += f;\n max = Math.max(max, f);\n if (f > 1) moved++;\n n++;\n }\n return { mean: n ? sum / n : 0, max, moved: n ? moved / n : 0 };\n}\n","import { makeFixture, type FixtureSpec } from \"../fixtures.ts\";\nimport type { Graph, Result, Router } from \"../model.ts\";\nimport { checkProperties, type Violation } from \"./properties.ts\";\nimport { measureQuality, type Quality } from \"./quality.ts\";\n\n// The core runs in any host, so it reads the clock without the types of Node or the browser.\nconst now = (): number => (globalThis as { performance?: { now(): number } }).performance?.now() ?? Date.now();\n\n/** One row of the benchmark: one router on one fixture. */\nexport interface BenchRow {\n readonly router: string;\n readonly fixture: string;\n readonly nodes: number;\n readonly edges: number;\n /** The median time of one run, in milliseconds. */\n readonly ms: number;\n /** This value is false when two runs on the same input gave different results. */\n readonly deterministic: boolean;\n readonly violations: number;\n /** The first violations, for the report. */\n readonly sample: readonly Violation[];\n readonly quality: Quality;\n}\n\n/** The options of a benchmark run. */\nexport interface BenchOptions {\n /** The number of timed routes of each fixture by each router. The default is 3. */\n readonly repeat?: number;\n}\n\n/** This function routes each fixture with each router, checks the hard rules and measures the quality. */\nexport function runBenchmark(routers: readonly Router[], fixtures: readonly FixtureSpec[], options: BenchOptions = {}): BenchRow[] {\n const rows: BenchRow[] = [];\n for (const spec of fixtures) {\n const graph = makeFixture(spec);\n for (const router of routers) if (graph.nodes.length <= (router.maxNodes ?? Infinity)) rows.push(benchOne(router, spec.name, graph, options.repeat ?? 3));\n }\n return rows;\n}\n\n/**\n * This function tells if two values hold the same data, as JSON sees it. It does not make a string,\n * because the result of a large graph can be longer than the longest string.\n */\nexport function sameData(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a === \"number\" && typeof b === \"number\") return Number.isNaN(a) && Number.isNaN(b);\n if (typeof a !== \"object\" || typeof b !== \"object\" || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a)) {\n const y = b as unknown[];\n if (a.length !== y.length) return false;\n for (let i = 0; i < a.length; i++) if (!sameData(a[i], y[i])) return false;\n return true;\n }\n const x = a as Record<string, unknown>;\n const y = b as Record<string, unknown>;\n const kx = Object.keys(x).filter((k) => x[k] !== undefined);\n const ky = Object.keys(y).filter((k) => y[k] !== undefined);\n if (kx.length !== ky.length) return false;\n for (const k of kx) if (!sameData(x[k], y[k])) return false;\n return true;\n}\n\n/** This function routes one graph with one router and measures the result. */\nexport function benchOne(router: Router, fixture: string, graph: Graph, repeat = 3): BenchRow {\n const times: number[] = [];\n let first: Result | undefined;\n let deterministic = true;\n for (let i = 0; i < Math.max(2, repeat); i++) {\n const t0 = now();\n const r = router.route(graph);\n times.push(now() - t0);\n if (!first) first = r;\n else if (i === 1 && !sameData(r, first)) deterministic = false;\n }\n times.sort((a, b) => a - b);\n const result = first!;\n const all = checkProperties(graph, result, 1_000_000);\n return {\n router: router.name,\n fixture,\n nodes: graph.nodes.length,\n edges: graph.edges.length,\n ms: times[Math.floor(times.length / 2)]!,\n deterministic,\n violations: all.length,\n sample: all.slice(0, 5),\n quality: measureQuality(graph, result),\n };\n}\n\n/** This function writes the rows as a Markdown table. */\nexport function formatTable(rows: readonly BenchRow[]): string {\n const head = \"| router | fixture | nodes | edges | ms | same twice | violations | ink | crossings | bends | inflections | clearance | tight | detour | plug angle |\";\n const line = \"|---|---|---:|---:|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const f = (v: number, d = 2): string => (Number.isInteger(v) ? String(v) : v.toFixed(d));\n const body = rows.map((r) => {\n const q = r.quality;\n return `| ${r.router} | ${r.fixture} | ${r.nodes} | ${r.edges} | ${f(r.ms, 1)} | ${r.deterministic ? \"yes\" : \"NO\"} | ${r.violations} | ${Math.round(q.ink)} | ${q.crossingsEstimated ? \"≈\" : \"\"}${q.crossings} | ${f(q.bends)} | ${f(q.inflections)} | ${f(q.clearance, 1)} | ${f(q.tight)} | ${f(q.detour)} | ${f(q.plugAngle, 1)} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n"],"mappings":"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"}
|