@mark1russell7/highways 0.1.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +293 -8
  2. package/build/index.d.ts +1774 -236
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +9307 -3090
  5. package/build/index.js.map +1 -1
  6. package/package.json +2 -1
  7. package/src/bench/compare.ts +145 -0
  8. package/src/bench/curves.ts +514 -2
  9. package/src/bench/links.ts +28 -6
  10. package/src/bench/measures/bundles.ts +119 -0
  11. package/src/bench/measures/curves.ts +211 -0
  12. package/src/bench/measures/groups.ts +122 -0
  13. package/src/bench/measures/index.ts +9 -0
  14. package/src/bench/measures/levels.ts +103 -0
  15. package/src/bench/measures/pareto.ts +37 -0
  16. package/src/bench/measures/room.ts +43 -0
  17. package/src/bench/measures/routes.ts +226 -0
  18. package/src/bench/measures/stability.ts +104 -0
  19. package/src/bench/measures/stats.ts +114 -0
  20. package/src/bench/properties.ts +18 -2
  21. package/src/bench/room.ts +209 -2
  22. package/src/bench/run.ts +86 -11
  23. package/src/bench/sections.ts +121 -0
  24. package/src/bench/suite.ts +781 -0
  25. package/src/cases.ts +41 -5
  26. package/src/curves/clothoid/index.ts +150 -0
  27. package/src/curves/corner.ts +116 -0
  28. package/src/curves/fit.ts +79 -0
  29. package/src/curves/highway/index.ts +636 -0
  30. package/src/curves/index.ts +16 -1
  31. package/src/curves/model.ts +4 -2
  32. package/src/curves/smooth/index.ts +50 -0
  33. package/src/curves/space.ts +76 -0
  34. package/src/groups/cut/index.ts +292 -0
  35. package/src/groups/index.ts +4 -0
  36. package/src/groups/kd/index.ts +207 -0
  37. package/src/groups/keys/index.ts +81 -0
  38. package/src/groups/quadtree/index.ts +10 -0
  39. package/src/index.ts +7 -0
  40. package/src/levels.ts +178 -9
  41. package/src/model.ts +2 -0
  42. package/src/pick.ts +36 -0
  43. package/src/room/bends.ts +203 -0
  44. package/src/room/index.ts +28 -0
  45. package/src/room/levels/index.ts +155 -0
  46. package/src/routers/sections.ts +78 -55
  47. package/src/routers/shared.ts +7 -2
  48. package/src/routers/trunks.ts +131 -6
  49. package/src/sections.ts +93 -4
  50. package/src/segments.ts +81 -31
  51. package/src/strategies/builtins.ts +153 -7
  52. package/src/strategies/index.ts +1 -0
  53. package/src/strategies/model.ts +29 -7
  54. package/src/strategies/options.ts +296 -0
  55. package/src/strategies/schemas.ts +221 -0
  56. package/src/visibility.ts +190 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["SIDES","hits","turn","EPS","dedupe","now","now"],"sources":["../src/geom.ts","../src/grid.ts","../src/model.ts","../src/fixtures.ts","../src/cases.ts","../src/plugs.ts","../src/curves.ts","../src/curves/model.ts","../src/bench/properties.ts","../src/curves/sample.ts","../src/curves/space.ts","../src/curves/arc/index.ts","../src/curves/rounded/index.ts","../src/curves/spline/index.ts","../src/curves/straight/index.ts","../src/curves/index.ts","../src/visibility.ts","../src/ways.ts","../src/segments.ts","../src/sections.ts","../src/routers/corners.ts","../src/routers/plugs.ts","../src/bench/links.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/room/index.ts","../src/room/lanes.ts","../src/bench/quality.ts","../src/bench/run.ts","../src/strategies/model.ts","../src/strategies/builtins.ts","../src/bench/curves.ts","../src/bench/room.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 /**\n * This method gives each item in the buckets along the segment `ab`, widened by `margin`, to `visit`, one time each.\n * The buckets are those of `#segment`, in the same order, so the items come in the same order.\n * A bucket in the range of the step before has no new item, so the walk skips it.\n * The walk stops when `visit` gives true, and then the method gives true.\n */\n #walk(a: Point, b: Point, margin: number, visit: (item: T) => boolean | void): boolean {\n const stamp = ++this.#stamp;\n const c = this.#cell;\n const items = this.#items;\n const n = Math.max(1, Math.ceil(Math.hypot(b.x - a.x, b.y - a.y) / (c / 2)));\n let px = a.x;\n let py = a.y;\n // The bucket range of the step before. The first step has none.\n let pi0 = 1;\n let pi1 = 0;\n let pj0 = 1;\n let pj1 = 0;\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 const i0 = Math.floor((Math.min(px, qx) - margin) / c);\n const j0 = Math.floor((Math.min(py, qy) - margin) / c);\n const i1 = Math.floor((Math.max(px, qx) + margin) / c);\n const j1 = Math.floor((Math.max(py, qy) + margin) / c);\n // A visit can add an item and so replace the array of stamps. Each step reads it again, as `#take` does.\n const seen = this.#seen;\n for (let i = i0; i <= i1; i++) {\n const before = i >= pi0 && i <= pi1;\n for (let j = j0; j <= j1; j++) {\n if (before && j >= pj0 && j <= pj1) continue;\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 if (visit(items[id]!) === true) return true;\n }\n }\n }\n pi0 = i0;\n pi1 = i1;\n pj0 = j0;\n pj1 = j1;\n px = qx;\n py = qy;\n }\n return false;\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 this.#walk(a, b, margin, (item) => {\n visit(item);\n });\n }\n\n /**\n * This method tells if `test` gives true for an item whose buckets come within `margin` of the segment `ab`.\n * It gives the items in the order of `querySegment`, and it stops at the first item that passes the test.\n */\n someSegment(a: Point, b: Point, margin: number, test: (item: T) => boolean): boolean {\n return this.#walk(a, b, margin, test);\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 { makeFixture, rng } from \"./fixtures.ts\";\nimport type { Edge, Graph, Node } from \"./model.ts\";\n\n/**\n * A board of made-up data that shows one known defect of the routes or of the zoom levels.\n * The benchmark races the routers on each case, and the measures of `measureLinks` give a number for the defect.\n */\nexport interface CaseBoard {\n readonly name: string;\n /** The defect that the board shows, in a few words. */\n readonly defect: string;\n /** This function makes the graph. The same function always gives the same graph. */\n readonly make: () => Graph;\n}\n\n/** A board while it grows: the functions add nodes and edges in order. */\nclass Board {\n readonly nodes: Node[] = [];\n readonly edges: Edge[] = [];\n readonly #pairs = new Set<string>();\n\n node(id: string, x: number, y: number, w: number, h: number): string {\n this.nodes.push({ id, box: { x, y, w, h } });\n return id;\n }\n\n /** This method adds an edge. It adds nothing for a loop or for a second edge between the same two nodes. */\n link(source: string, target: string): void {\n const key = source < target ? `${source}|${target}` : `${target}|${source}`;\n if (source === target || this.#pairs.has(key)) return;\n this.#pairs.add(key);\n this.edges.push({ id: `e${this.edges.length}`, source: { node: source }, target: { node: target } });\n }\n\n graph(): Graph {\n return { nodes: this.nodes, edges: this.edges };\n }\n}\n\n/**\n * This function makes a dense board: 150 nodes in tight clusters. At the far view, the boxes of the groups overlap.\n * Then a level link starts or ends in a group that another group covers.\n */\nexport function denseGroupsBoard(): Graph {\n return makeFixture({ name: \"dense-groups\", kind: \"clustered\", nodes: 150, edgesPerNode: 2, seed: 3 });\n}\n\n/**\n * This function makes a board of three rows of 32 cards. Each card links to the next card of its row.\n * Forty long links join cards far apart. The hub of a section is near the middle of its cards.\n * So a long link climbs to hubs behind its source or past its target, and comes back.\n */\nexport function hubChainBoard(): Graph {\n const R = rng(3);\n const b = new Board();\n const rows = 3;\n const cols = 32;\n const gap = 48;\n const id = (r: number, c: number): string => `c${r}-${c}`;\n for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) b.node(id(r, c), c * (80 + gap), r * (36 + gap), 80, 36);\n for (let r = 0; r < rows; r++) for (let c = 0; c + 1 < cols; c++) b.link(id(r, c), id(r, c + 1));\n for (let n = 0; n < 40; n++) {\n const r = Math.floor(R() * rows);\n const c = Math.floor(R() * cols);\n const span = Math.floor(cols / 8 + (R() * cols) / 2);\n if (c + span < cols) b.link(id(r, c), id((r + 1) % rows, c + span));\n }\n return b.graph();\n}\n\n/**\n * This function makes a board of 32 groups in 8 columns and 4 rows. Each group has 4 cards in a square.\n * The cards of a group link in a chain, and 96 random links join cards of two groups.\n * On a level with many groups, some level links go around the outer edge of the board.\n */\nexport function manyGroupsBoard(): Graph {\n const R = rng(7);\n const b = new Board();\n const cols = 8;\n const rows = 4;\n const per = 4;\n const w = 60;\n const h = 30;\n const cardGap = 12;\n const groupGap = 60;\n const side = Math.ceil(Math.sqrt(per));\n const gw = side * w + (side - 1) * cardGap;\n const gh = Math.ceil(per / side) * h + (Math.ceil(per / side) - 1) * cardGap;\n const groups: string[][] = [];\n for (let r = 0; r < rows; r++)\n for (let c = 0; c < cols; c++) {\n const list: string[] = [];\n for (let i = 0; i < per; i++) {\n const x = c * (gw + groupGap) + (i % side) * (w + cardGap);\n const y = r * (gh + groupGap) + Math.floor(i / side) * (h + cardGap);\n list.push(b.node(`g${r}-${c}-${i}`, x, y, w, h));\n }\n groups.push(list);\n }\n for (const list of groups) for (let i = 1; i < list.length; i++) b.link(list[i - 1]!, list[i]!);\n const pick = (list: readonly string[]): string => list[Math.floor(R() * list.length)]!;\n for (let n = 0; n < groups.length * 3; n++) b.link(pick(groups[Math.floor(R() * groups.length)]!), pick(groups[Math.floor(R() * groups.length)]!));\n return b.graph();\n}\n\n/**\n * This function makes the far view of a board after a host layout packs it.\n * The board has 96 boxes of one size in a grid of 12 columns and 8 rows.\n * The boxes touch, with no gap between them. Each box links to a box near it, and 48 long links join boxes far apart.\n * The links have no channel between the boxes. The roadmap item ROOM measures this board before and after `makeRoom`.\n *\n * The board is not in `CASES`, because the digests of the router fix the output on each board of `CASES`.\n */\nexport function packedGridBoard(): Graph {\n const R = rng(11);\n const b = new Board();\n const cols = 12;\n const rows = 8;\n const w = 140;\n const h = 90;\n const id = (r: number, c: number): string => `p${r}-${c}`;\n for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) b.node(id(r, c), c * w, r * h, w, h);\n const step = (): number => Math.floor(R() * 5) - 2;\n for (let r = 0; r < rows; r++)\n for (let c = 0; c < cols; c++) {\n const rr = Math.max(0, Math.min(rows - 1, r + step()));\n const cc = Math.max(0, Math.min(cols - 1, c + step()));\n b.link(id(r, c), id(rr, cc));\n }\n for (let n = 0; n < 48; n++) b.link(id(Math.floor(R() * rows), Math.floor(R() * cols)), id(Math.floor(R() * rows), Math.floor(R() * cols)));\n return b.graph();\n}\n\n/** The case boards of the benchmark. Each board has a few hundred nodes at most, so the benchmark races them on each run. */\nexport const CASES: readonly CaseBoard[] = [\n { name: \"case-dense-groups\", defect: \"Groups overlap at the far view, and level links go through other groups.\", make: denseGroupsBoard },\n { name: \"case-hub-chain\", defect: \"A route climbs a chain of hubs away from its target and comes back.\", make: hubChainBoard },\n { name: \"case-many-groups\", defect: \"On a level with many groups, links go around the outer edge of the board.\", make: manyGroupsBoard },\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 type { Point } from \"../geom.ts\";\n\n/**\n * A type of curve for a route.\n *\n * - `straight`: the polyline as it is.\n * - `rounded`: a quadratic Bezier curve at each corner, as `roundCorners` draws it.\n * - `spline`: a centripetal Catmull-Rom spline through the points. It does not overshoot or make loops.\n * - `arc`: a circular arc at each corner, tangent to the two legs.\n */\nexport type CurveType = \"straight\" | \"rounded\" | \"spline\" | \"arc\";\n\n/** The curve types, in the order of the benchmark. */\nexport const CURVE_TYPES: readonly CurveType[] = [\"straight\", \"rounded\", \"spline\", \"arc\"];\n\n/** The start of a curve: the pen goes to `to` and draws nothing. */\nexport interface MoveSegment {\n readonly kind: \"move\";\n readonly to: Point;\n}\n\n/** A straight line from the end of the segment before to `to`. */\nexport interface LineSegment {\n readonly kind: \"line\";\n readonly to: Point;\n}\n\n/** A cubic Bezier curve from the end of the segment before to `to`, with the control points `c1` and `c2`. */\nexport interface CubicSegment {\n readonly kind: \"cubic\";\n readonly c1: Point;\n readonly c2: Point;\n readonly to: Point;\n}\n\n/**\n * A circular arc from the end of the segment before to `to`. The arc has its center at `center` and the radius `radius`.\n * It starts at the angle `start` and turns by `sweep` radians. A positive `sweep` turns from the x axis to the y axis.\n * On a canvas, `ctx.arc(center.x, center.y, radius, start, start + sweep, sweep < 0)` draws it.\n */\nexport interface ArcSegment {\n readonly kind: \"arc\";\n readonly center: Point;\n readonly radius: number;\n readonly start: number;\n readonly sweep: number;\n readonly to: Point;\n}\n\n/**\n * A segment of a curve. A curve is a list of segments: one `move` first, then lines, cubic curves and arcs.\n * A renderer maps the list to SVG path data, to canvas calls or to the vertices of a mesh.\n */\nexport type CurveSegment = MoveSegment | LineSegment | CubicSegment | ArcSegment;\n\n/** This function gives the points of a polyline without the points that are nearer than `eps` to the point before them. */\nexport function distinctPoints(points: readonly Point[], eps = 1e-9): Point[] {\n const out: Point[] = [];\n for (const p of points) {\n const q = out[out.length - 1];\n if (q === undefined || Math.hypot(p.x - q.x, p.y - q.y) > eps) out.push(p);\n }\n return out;\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 type { Point } from \"../geom.ts\";\nimport type { CurveSegment } from \"./model.ts\";\n\n/** The largest number of points that `sampleCurve` gives for one segment. */\nconst MAX_STEPS = 1024;\n\n/**\n * This function gives a polyline that follows the curve. The distance from each part of the curve to the polyline is `tolerance` or less.\n * The polyline starts at the point of the `move` and goes through the end of each segment.\n * Hit tests, measures and renderers that draw only lines use this polyline.\n */\nexport function sampleCurve(segments: readonly CurveSegment[], tolerance = 0.5): Point[] {\n const tol = Math.max(1e-6, tolerance);\n const out: Point[] = [];\n let at: Point | undefined;\n for (const s of segments) {\n if (s.kind === \"move\" || at === undefined) {\n out.push(s.to);\n at = s.to;\n continue;\n }\n if (s.kind === \"cubic\") {\n // The chord of a step of 1/n of the parameter is within 3·D/(4·n²) of the curve. D is the largest second difference of the control points.\n const d = Math.max(\n Math.hypot(at.x - 2 * s.c1.x + s.c2.x, at.y - 2 * s.c1.y + s.c2.y),\n Math.hypot(s.c1.x - 2 * s.c2.x + s.to.x, s.c1.y - 2 * s.c2.y + s.to.y),\n );\n const n = Math.min(MAX_STEPS, Math.max(1, Math.ceil(Math.sqrt((3 * d) / (4 * tol)))));\n for (let k = 1; k < n; k++) out.push(cubicAt(at, s.c1, s.c2, s.to, k / n));\n } else if (s.kind === \"arc\") {\n // The chord of an angle φ is within r·(1 - cos(φ/2)) of the arc.\n const step = s.radius <= tol ? Math.PI : 2 * Math.acos(1 - tol / s.radius);\n const n = Math.min(MAX_STEPS, Math.max(1, Math.ceil(Math.abs(s.sweep) / step)));\n for (let k = 1; k < n; k++) {\n const a = s.start + (s.sweep * k) / n;\n out.push({ x: s.center.x + s.radius * Math.cos(a), y: s.center.y + s.radius * Math.sin(a) });\n }\n }\n out.push(s.to);\n at = s.to;\n }\n return out;\n}\n\n/** This function gives the point at the parameter `t` of the cubic Bezier curve with the control points `p0`, `p1`, `p2` and `p3`. */\nexport function cubicAt(p0: Point, p1: Point, p2: Point, p3: Point, t: number): Point {\n const u = 1 - t;\n const a = u * u * u;\n const b = 3 * u * u * t;\n const c = 3 * u * t * t;\n const d = t * t * t;\n return { x: a * p0.x + b * p1.x + c * p2.x + d * p3.x, y: a * p0.y + b * p1.y + c * p2.y + d * p3.y };\n}\n\n/**\n * This function writes the segments as the data of an SVG path: the commands `M`, `L`, `C` and `A`.\n * Each number has at most `digits` digits after the point.\n */\nexport function toSvgPath(segments: readonly CurveSegment[], digits = 2): string {\n const n = (v: number): string => {\n const s = String(Number(v.toFixed(digits)));\n return s === \"-0\" ? \"0\" : s;\n };\n const p = (q: Point): string => `${n(q.x)} ${n(q.y)}`;\n const parts: string[] = [];\n for (const s of segments) {\n if (s.kind === \"move\") parts.push(`M ${p(s.to)}`);\n else if (s.kind === \"line\") parts.push(`L ${p(s.to)}`);\n else if (s.kind === \"cubic\") parts.push(`C ${p(s.c1)} ${p(s.c2)} ${p(s.to)}`);\n else parts.push(`A ${n(s.radius)} ${n(s.radius)} 0 ${Math.abs(s.sweep) > Math.PI ? 1 : 0} ${s.sweep > 0 ? 1 : 0} ${p(s.to)}`);\n }\n return parts.join(\" \");\n}\n","import { TOLERANCE } from \"../bench/properties.ts\";\nimport { inflate, segmentHitsBox, type Box, type Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport type { CurveSegment } from \"./model.ts\";\nimport { sampleCurve } from \"./sample.ts\";\n\n/**\n * The free space of a board: the boxes that a curve must not go through.\n * Make it one time for a board with `curveSpace`, and give it to each call of `curveOf`.\n */\nexport interface CurveSpace {\n /** The boxes of the board. */\n readonly boxes: readonly Box[];\n /** The tolerance of the samples of a curve, in units of the plane. */\n readonly tolerance: number;\n /**\n * This method tells if the polyline `q` goes through a box that the polyline `p` does not go through.\n * A polyline goes through a box when a part of it longer than `TOLERANCE` is inside the box made smaller by `TOLERANCE`.\n */\n addsHit(q: readonly Point[], p: readonly Point[]): boolean;\n}\n\n/**\n * This function makes the free space of a board from its boxes. The boxes are the nodes, or the items of a zoom level.\n * The curves sample each piece within `tolerance` of the curve for the test.\n */\nexport function curveSpace(boxes: readonly Box[], tolerance = 0.25): CurveSpace {\n const inner = boxes.map((b) => inflate(b, -TOLERANCE));\n let size = 0;\n for (const b of boxes) size += Math.max(b.w, b.h);\n // The buckets grow with the boxes, as the buckets of `measureLinks` do.\n const grid = new Grid<number>(Math.max(180, (2 * size) / Math.max(1, boxes.length)));\n inner.forEach((b, i) => grid.add(i, b));\n const hits = (p: readonly Point[]): Set<number> => {\n const out = new Set<number>();\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n grid.querySegment(a, b, 0, (id) => {\n if (!out.has(id) && segmentHitsBox(a, b, inner[id]!, TOLERANCE)) out.add(id);\n });\n }\n return out;\n };\n return {\n boxes,\n tolerance,\n addsHit(q: readonly Point[], p: readonly Point[]): boolean {\n let before: Set<number> | undefined;\n for (let i = 1; i < q.length; i++) {\n const a = q[i - 1]!;\n const b = q[i]!;\n const hit = grid.someSegment(a, b, 0, (id) => {\n if (!segmentHitsBox(a, b, inner[id]!, TOLERANCE)) return false;\n before ??= hits(p);\n return !before.has(id);\n });\n if (hit) return true;\n }\n return false;\n },\n };\n}\n\n/**\n * This function finds the largest size from `max` down to 0 that keeps a piece of a curve clear.\n * A clear piece goes through no box that its polyline avoids.\n *\n * The function `piece` gives the segments of the piece at a size. They start with a `move`.\n * The polyline `chord` is the part of the original polyline that the piece replaces.\n * The function tries `max` first, then it halves the interval `steps` times. The result is 0 when no size of the search is clear.\n */\nexport function fitSize(\n space: CurveSpace | undefined,\n max: number,\n chord: (size: number) => readonly Point[],\n piece: (size: number) => readonly CurveSegment[],\n steps = 8,\n): number {\n if (space === undefined || max <= 0) return Math.max(0, max);\n const clear = (size: number): boolean => !space.addsHit(sampleCurve(piece(size), space.tolerance), chord(size));\n if (clear(max)) return max;\n let lo = 0;\n let hi = max;\n for (let i = 0; i < steps; i++) {\n const mid = (lo + hi) / 2;\n if (clear(mid)) lo = mid;\n else hi = mid;\n }\n return lo;\n}\n","import { dist, type Point } from \"../../geom.ts\";\nimport { distinctPoints, type CurveSegment } from \"../model.ts\";\nimport { fitSize, type CurveSpace } from \"../space.ts\";\n\n/** The options of `arcCurve`. */\nexport interface ArcOptions {\n /** The largest radius of the arc at a corner. The default is 12. */\n readonly radius?: number;\n /** The boxes that the curve must not go through. Without it, each corner gets the largest radius that fits on its legs. */\n readonly space?: CurveSpace;\n}\n\n/** A turn smaller than this angle, in radians, is no corner. A turn nearer to a half turn than this angle stays sharp. */\nconst FLAT = 1e-6;\n\n/**\n * This function puts a circular arc at each inner vertex of a polyline. The arc is tangent to the two legs of its corner.\n * The tangent points stay on the first half of each leg, so the ends of the polyline stay.\n * With `space`, the function makes the radius of a corner smaller until the arc goes through no box that the polyline avoids.\n * On a polyline with only horizontal and vertical legs, each arc is a quarter circle.\n */\nexport function arcCurve(points: readonly Point[], options: ArcOptions = {}): CurveSegment[] {\n const p = distinctPoints(points);\n if (p.length === 0) return [];\n const radius = options.radius ?? 12;\n const out: CurveSegment[] = [{ kind: \"move\", to: 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 ux = (v.x - a.x) / la;\n const uy = (v.y - a.y) / la;\n const wx = (b.x - v.x) / lb;\n const wy = (b.y - v.y) / lb;\n const turn = Math.atan2(ux * wy - uy * wx, ux * wx + uy * wy);\n if (Math.abs(turn) < FLAT || Math.PI - Math.abs(turn) < FLAT) {\n out.push({ kind: \"line\", to: v });\n continue;\n }\n // The tangent points are r·tan(|turn|/2) from the vertex.\n const k = Math.tan(Math.abs(turn) / 2);\n const side = Math.sign(turn);\n const ends = (r: number): [Point, Point] => [\n { x: v.x - ux * r * k, y: v.y - uy * r * k },\n { x: v.x + wx * r * k, y: v.y + wy * r * k },\n ];\n const piece = (r: number): CurveSegment[] => {\n const [p1, p2] = ends(r);\n // The center is on the side of the turn, at the distance r from the first leg.\n const center = { x: p1.x - side * uy * r, y: p1.y + side * ux * r };\n return [{ kind: \"arc\", center, radius: r, start: Math.atan2(p1.y - center.y, p1.x - center.x), sweep: turn, to: p2 }];\n };\n const r = fitSize(\n options.space,\n Math.min(radius, Math.min(la, lb) / (2 * k)),\n (s) => [ends(s)[0], v, ends(s)[1]],\n (s) => [{ kind: \"move\", to: ends(s)[0] }, ...piece(s)],\n );\n if (r <= 0) {\n out.push({ kind: \"line\", to: v });\n continue;\n }\n const [p1] = ends(r);\n if (dist(p1, out[out.length - 1]!.to) > 1e-9) out.push({ kind: \"line\", to: p1 });\n out.push(...piece(r));\n }\n if (p.length > 1) out.push({ kind: \"line\", to: p[p.length - 1]! });\n return out;\n}\n","import { dist, type Point } from \"../../geom.ts\";\nimport { distinctPoints, type CurveSegment } from \"../model.ts\";\nimport { fitSize, type CurveSpace } from \"../space.ts\";\n\n/** The options of `roundedCurve`. */\nexport interface RoundedOptions {\n /** The largest distance from a corner to the start and to the end of its curve. The default is 12. */\n readonly radius?: number;\n /** The boxes that the curve must not go through. Without it, each corner gets the full radius. */\n readonly space?: CurveSpace;\n}\n\n/**\n * This function rounds each inner vertex of a polyline with a quadratic Bezier curve, as `roundCorners` does.\n * The curve of a corner starts and ends at most `radius` from the vertex, and at most half of each leg. The ends of the polyline stay.\n * The function gives each quadratic curve as the same cubic curve. With `space`, it makes the radius of a corner smaller until the curve\n * goes through no box that the polyline avoids.\n */\nexport function roundedCurve(points: readonly Point[], options: RoundedOptions = {}): CurveSegment[] {\n const p = distinctPoints(points);\n if (p.length === 0) return [];\n const radius = options.radius ?? 12;\n const out: CurveSegment[] = [{ kind: \"move\", to: 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 ends = (r: number): [Point, Point] => [\n { x: v.x + ((a.x - v.x) * r) / la, y: v.y + ((a.y - v.y) * r) / la },\n { x: v.x + ((b.x - v.x) * r) / lb, y: v.y + ((b.y - v.y) * r) / lb },\n ];\n const piece = (r: number): CurveSegment[] => {\n const [p1, p2] = ends(r);\n // A quadratic curve with the control point v is the cubic curve with the control points 2/3 of the way to v.\n return [{ kind: \"cubic\", c1: { x: p1.x + (2 * (v.x - p1.x)) / 3, y: p1.y + (2 * (v.y - p1.y)) / 3 }, c2: { x: p2.x + (2 * (v.x - p2.x)) / 3, y: p2.y + (2 * (v.y - p2.y)) / 3 }, to: p2 }];\n };\n const r = fitSize(\n options.space,\n Math.min(radius, la / 2, lb / 2),\n (s) => [ends(s)[0], v, ends(s)[1]],\n (s) => [{ kind: \"move\", to: ends(s)[0] }, ...piece(s)],\n );\n if (r <= 0) {\n out.push({ kind: \"line\", to: v });\n continue;\n }\n const [p1] = ends(r);\n if (dist(p1, at(out)) > 1e-9) out.push({ kind: \"line\", to: p1 });\n out.push(...piece(r));\n }\n if (p.length > 1) out.push({ kind: \"line\", to: p[p.length - 1]! });\n return out;\n}\n\n/** This function gives the end of the last segment. */\nfunction at(segments: readonly CurveSegment[]): Point {\n return segments[segments.length - 1]!.to;\n}\n","import { dist, type Point } from \"../../geom.ts\";\nimport { distinctPoints, type CurveSegment } from \"../model.ts\";\nimport { fitSize, type CurveSpace } from \"../space.ts\";\n\n/** The options of `splineCurve`. */\nexport interface SplineOptions {\n /**\n * The tension of the spline, from 0 to 1. The value 0 gives the centripetal Catmull-Rom spline, and 1 gives the polyline.\n * The default is 0.\n */\n readonly tension?: number;\n /** The outward normal of the plug at the first point. With it, the curve leaves the first point along this normal. */\n readonly startNormal?: Point;\n /** The outward normal of the plug at the last point. With it, the curve comes into the last point against this normal. */\n readonly endNormal?: Point;\n /** The boxes that the curve must not go through. Without it, each piece gets the full tangents. */\n readonly space?: CurveSpace;\n}\n\n/**\n * This function draws a centripetal Catmull-Rom spline through the points of a polyline (Yuksel, Schaefer and Keyser, 2011).\n * Each piece between two points is one cubic Bezier curve. The centripetal knots keep the curve free of cusps and loops in a piece.\n * The curve goes through each point. Its tangent at a point keeps one direction on the two sides of the point.\n *\n * With `space`, the function makes the tangents of a piece shorter until the piece goes through no box that its leg avoids.\n * A piece with no tangent is the straight leg.\n */\nexport function splineCurve(points: readonly Point[], options: SplineOptions = {}): CurveSegment[] {\n const p = distinctPoints(points);\n if (p.length === 0) return [];\n const out: CurveSegment[] = [{ kind: \"move\", to: p[0]! }];\n const n = p.length;\n if (n === 1) return out;\n const scale = 1 - Math.max(0, Math.min(1, options.tension ?? 0));\n // The knot interval of each leg is the square root of its length.\n const dt = Array.from({ length: n - 1 }, (_, i) => Math.sqrt(dist(p[i]!, p[i + 1]!)));\n const unit = (q: Point): Point => {\n const l = Math.hypot(q.x, q.y);\n return l === 0 ? { x: 0, y: 0 } : { x: q.x / l, y: q.y / l };\n };\n // The tangent at each point, as a speed in the parameter of the knots.\n const m: Point[] = p.map((v, i) => {\n if (i === 0) {\n const leg = { x: p[1]!.x - v.x, y: p[1]!.y - v.y };\n if (!options.startNormal) return { x: leg.x / dt[0]!, y: leg.y / dt[0]! };\n const u = unit(options.startNormal);\n return { x: u.x * dt[0]!, y: u.y * dt[0]! };\n }\n if (i === n - 1) {\n const a = p[i - 1]!;\n const leg = { x: v.x - a.x, y: v.y - a.y };\n if (!options.endNormal) return { x: leg.x / dt[i - 1]!, y: leg.y / dt[i - 1]! };\n const u = unit(options.endNormal);\n return { x: -u.x * dt[i - 1]!, y: -u.y * dt[i - 1]! };\n }\n const a = p[i - 1]!;\n const b = p[i + 1]!;\n const t0 = dt[i - 1]!;\n const t1 = dt[i]!;\n return {\n x: (v.x - a.x) / t0 - (b.x - a.x) / (t0 + t1) + (b.x - v.x) / t1,\n y: (v.y - a.y) / t0 - (b.y - a.y) / (t0 + t1) + (b.y - v.y) / t1,\n };\n });\n for (let i = 0; i + 1 < n; i++) {\n const a = p[i]!;\n const b = p[i + 1]!;\n const h = dt[i]! / 3;\n const piece = (s: number): CurveSegment[] => [\n { kind: \"move\", to: a },\n { kind: \"cubic\", c1: { x: a.x + m[i]!.x * h * s, y: a.y + m[i]!.y * h * s }, c2: { x: b.x - m[i + 1]!.x * h * s, y: b.y - m[i + 1]!.y * h * s }, to: b },\n ];\n const s = fitSize(options.space, scale, () => [a, b], piece);\n out.push(s > 0 ? piece(s)[1]! : { kind: \"line\", to: b });\n }\n return out;\n}\n","import type { Point } from \"../../geom.ts\";\nimport type { CurveSegment } from \"../model.ts\";\n\n/** This function gives the polyline as it is: one `move` to the first point and one `line` to each other point. */\nexport function straightCurve(points: readonly Point[]): CurveSegment[] {\n return points.map((to, i): CurveSegment => (i === 0 ? { kind: \"move\", to } : { kind: \"line\", to }));\n}\n","import type { Point } from \"../geom.ts\";\nimport { arcCurve } from \"./arc/index.ts\";\nimport type { CurveSegment, CurveType } from \"./model.ts\";\nimport { roundedCurve } from \"./rounded/index.ts\";\nimport type { CurveSpace } from \"./space.ts\";\nimport { splineCurve } from \"./spline/index.ts\";\nimport { straightCurve } from \"./straight/index.ts\";\n\nexport * from \"./model.ts\";\nexport { cubicAt, sampleCurve, toSvgPath } from \"./sample.ts\";\nexport { curveSpace, type CurveSpace } from \"./space.ts\";\nexport { straightCurve } from \"./straight/index.ts\";\nexport { roundedCurve, type RoundedOptions } from \"./rounded/index.ts\";\nexport { splineCurve, type SplineOptions } from \"./spline/index.ts\";\nexport { arcCurve, type ArcOptions } from \"./arc/index.ts\";\n\n/** The options of `curveOf`. Each type reads only the options that it uses. */\nexport interface CurveOptions {\n readonly type: CurveType;\n /** The types `rounded` and `arc` read this radius of the corners. The default is 12. */\n readonly radius?: number;\n /** The type `spline` reads this tension, from 0 to 1. The default is 0. */\n readonly tension?: number;\n /** The type `spline` leaves the first point along this outward normal of its plug. */\n readonly startNormal?: Point;\n /** The type `spline` comes into the last point against this outward normal of its plug. */\n readonly endNormal?: Point;\n /** The boxes that the curve must not go through, from `curveSpace`. The type `straight` does not read it. */\n readonly space?: CurveSpace;\n}\n\n/**\n * This function gives the curve of a route: a polyline of a router, a lane of `laneRoutes` or a link of a zoom level.\n * The curve starts at the first point and ends at the last point of the polyline.\n * The output is a list of segments for any renderer. `toSvgPath` writes it as SVG path data, and `sampleCurve` gives points.\n */\nexport function curveOf(points: readonly Point[], options: CurveOptions): CurveSegment[] {\n switch (options.type) {\n case \"straight\":\n return straightCurve(points);\n case \"rounded\":\n return roundedCurve(points, options);\n case \"spline\":\n return splineCurve(points, options);\n case \"arc\":\n return arcCurve(points, options);\n }\n}\n","import { dist, inflate, segmentHitsRect, type Box, 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 return this.hit(a, b, pad, skip) === undefined;\n }\n\n /**\n * This method gives a node whose box, made larger by `pad`, the segment `ab` goes into, or `undefined` when the segment is clear.\n * The nodes in `skip` do not count. The test stops at the first such node.\n */\n hit(a: Point, b: Point, pad: number, skip?: ReadonlySet<Node>): Node | undefined {\n let found: Node | undefined;\n this.#grid.someSegment(a, b, pad, (n) => {\n if (skip?.has(n) || !hits(a, b, n, pad)) return false;\n found = n;\n return true;\n });\n return found;\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 gives each node whose bucket the box touches to `visit`. A node can be outside the box. */\n query(box: Box, visit: (n: Node) => void): void {\n this.#grid.query(box, visit);\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/** This function tells if the segment `ab` goes into the box of the node, made larger by `pad`. */\nfunction hits(a: Point, b: Point, n: Node, pad: number): boolean {\n const x = n.box;\n return segmentHitsRect(a, b, x.x - pad, x.y - pad, x.x + x.w + pad, x.y + x.h + pad);\n}\n\n/** A free point at an end of a search of `CornerGraph.pathAmong`, and the cost to reach it. */\nexport interface Terminal {\n readonly point: Point;\n readonly cost: number;\n}\n\n/** A path of `CornerGraph.pathAmong`: its points, the index of its first point in `from`, the index of its last point in `to`, and its cost. */\nexport interface Among {\n readonly points: Point[];\n readonly from: number;\n readonly to: number;\n readonly cost: number;\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 * With `cones`, each corner also links to the nearest corner that it can see in each of four cones around the axes.\n * Then a path can go along a long corridor between rows or columns of boxes. The default is false.\n */\n readonly cones?: boolean;\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 corners in each bucket of the point grid, by the key of the bucket. A corner is in one bucket: the bucket of its point.\n readonly #buckets = new Map<number, number[]>();\n // The distance from the point of the last call of nearestVisible to each corner that the call found.\n #dist = new Float64Array(0);\n // The corners of one ring of nearestVisible, nearest first.\n readonly #near = new MinHeap();\n // The corners that each end of a path sees, by the coordinates of the end.\n readonly #endCache = new Map<string, number[]>();\n // The corners that each end of a path of `pathAmong` sees. Such a path has several ends, so each end takes fewer corners.\n readonly #fewCache = new Map<string, number[]>();\n // The connected part of the graph of each corner. The first call of `path` makes it.\n #part: Int32Array | undefined;\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 // The k nearest corners of a corner in a long corridor are often all on one side. The cones add a link along the corridor.\n for (const j of this.#nearestVisible(this.points[i]!, this.#k, i, this.#pad, options.cones ?? false)) {\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 const j = this.points.length;\n this.#pointGrid.add(j, { x: c.x, y: c.y, w: 0, h: 0 });\n const key = bucketKey(Math.floor(c.x / this.#cell), Math.floor(c.y / this.#cell));\n const list = this.#buckets.get(key);\n if (list === undefined) this.#buckets.set(key, [j]);\n else list.push(j);\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 /**\n * This method tests the corners in rings of radius `r` = 1, 2, 4 and 8 cells. In each ring, it tests the corners\n * within `r` that an earlier ring did not test, nearest first, and equal distances by index.\n * The ring of `r` takes the corners of the buckets that the square of side `2r` around `p` touches.\n * A corner of these buckets beyond `r` waits for the next ring. So the method visits each bucket one time.\n * With `cones`, the method also gives the nearest visible corner of each of four cones around the axes that the `k` nearest corners leave empty.\n */\n #nearestVisible(p: Point, k: number, self: number, pad: number, cones = false): number[] {\n const out: number[] = [];\n // The bits of the full cones: 1 is +x, 2 is +y, 4 is -x and 8 is -y.\n let full = 0;\n if (this.#dist.length < this.points.length) this.#dist = new Float64Array(this.points.length);\n const dd = this.#dist;\n const points = this.points;\n const cell = this.#cell;\n const reach = CONE_CELLS * cell;\n const blockers: Node[] = [];\n const now = this.#near;\n // The corners that the rings found beyond their radius. The next ring takes them.\n let wait: number[] = [];\n // The bucket range of the ring before. The first ring has none.\n let pi0 = 1;\n let pi1 = 0;\n let pj0 = 1;\n let pj1 = 0;\n for (let r = cell; r <= cell * 8; r *= 2) {\n // The ring of `r` holds the corners beyond `r / 2`. With the k nearest corners, the cones take no corner beyond `reach`.\n if (out.length >= k && r / 2 >= reach) return out;\n // These bounds are the bounds of a query of the box at (p.x - r, p.y - r) with the side 2r.\n const x0 = p.x - r;\n const y0 = p.y - r;\n const i0 = Math.floor(x0 / cell);\n const j0 = Math.floor(y0 / cell);\n const i1 = Math.floor((x0 + 2 * r) / cell);\n const j1 = Math.floor((y0 + 2 * r) / cell);\n const later: number[] = [];\n now.clear();\n for (const j of wait) {\n if (dd[j]! > r) later.push(j);\n else now.add(dd[j]!, j);\n }\n for (let bi = i0; bi <= i1; bi++) {\n const before = bi >= pi0 && bi <= pi1;\n for (let bj = j0; bj <= j1; bj++) {\n if (before && bj >= pj0 && bj <= pj1) continue;\n const list = this.#buckets.get(bucketKey(bi, bj));\n if (list === undefined) continue;\n for (const j of list) {\n if (j === self) continue;\n const d = dist(p, points[j]!);\n dd[j] = d;\n if (d > r) later.push(j);\n else now.add(d, j);\n }\n }\n }\n // The heap gives the corners nearest first, and equal distances by index. A call often stops after a few corners.\n now.build();\n while (now.size > 0) {\n const j = now.pop();\n // A node that stopped an earlier segment often stops this segment too, so the test takes these nodes first.\n // The order of the nodes does not change the result.\n const q = points[j]!;\n const cone = cones ? coneOf(q.x - p.x, q.y - p.y) : 0;\n if (out.length >= k) {\n // After the k nearest corners, only a corner of an empty cone counts, up to `CONE_CELLS` cells from `p`.\n if (dd[j]! > reach) return out;\n if ((full & cone) !== 0) continue;\n }\n let blocked = false;\n for (let b = 0; b < blockers.length && !blocked; b++) blocked = hits(p, q, blockers[b]!, pad);\n if (blocked) continue;\n const hit = this.#obstacles.hit(p, q, pad);\n if (hit !== undefined) blockers.push(hit);\n else {\n out.push(j);\n full |= cone;\n if (out.length >= k && (!cones || full === 15)) return out;\n }\n }\n wait = later;\n pi0 = i0;\n pi1 = i1;\n pj0 = j0;\n pj1 = j1;\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 return this.#search([{ point: from, cost: 0 }], [{ point: to, cost: 0 }], cost, floor, this.#k * 2)?.points;\n }\n\n /**\n * This method gives the shortest path from a point of `from` to a point of `to`, or `undefined` when the graph has none.\n * The cost of a path includes the costs of its two points. One search finds the path, so this method is faster than a call of `path` for each pair.\n */\n pathAmong(from: readonly Terminal[], to: readonly Terminal[]): Among | undefined {\n const found = this.#search(from, to, undefined, 1, this.#k);\n // A straight line between two points that costs less than the found path is better. The test takes the lines in order of cost.\n const lines: Among[] = [];\n from.forEach((a, i) =>\n to.forEach((b, k) => {\n const c = a.cost + dist(a.point, b.point) + b.cost;\n if (!found || c < found.cost) lines.push({ points: [a.point, b.point], from: i, to: k, cost: c });\n }),\n );\n lines.sort((u, v) => u.cost - v.cost);\n return lines.find((l) => this.#obstacles.clear(l.points[0]!, l.points[1]!, this.#pad)) ?? found;\n }\n\n /** This method is the search (A*) of `path` and `pathAmong`. */\n #search(\n from: readonly Terminal[],\n to: readonly Terminal[],\n cost: ((i: number, j: number, d: number) => number) | undefined,\n floor: number,\n count: number,\n ): Among | undefined {\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 points = this.points;\n // The cost from each corner near a point of `to` to that point, and the index of that point.\n const goal = new Map<number, number>();\n const goalOf = new Map<number, number>();\n to.forEach((b, k) => {\n for (const j of this.#ends(b.point, count)) {\n const tail = dist(points[j]!, b.point) + b.cost;\n const now = goal.get(j);\n if (now === undefined || tail < now) {\n goal.set(j, tail);\n goalOf.set(j, k);\n }\n }\n });\n if (goal.size === 0) return undefined;\n const starts = from.map((a) => this.#ends(a.point, count));\n // Without a start and a goal in one connected part, A* finds no path. This test stops it before it visits the whole part.\n if (!starts.some((list) => this.#joined(list, goal))) return undefined;\n const heap = new MinHeap();\n const G = this.#g;\n const parentOf = this.#parent;\n const open = this.#open;\n const closed = this.#closed;\n const estimate = (p: Point): number => {\n let h = Infinity;\n for (const b of to) h = Math.min(h, dist(p, b.point));\n return floor * h;\n };\n const relax = (j: number, g: number, parent: number): void => {\n if (closed[j] === stamp) return;\n if (open[j] === stamp && G[j]! <= g) return;\n open[j] = stamp;\n G[j] = g;\n parentOf[j] = parent;\n heap.push(g + estimate(points[j]!), j);\n };\n // The parent of a first corner is -1 - i, where i is the index of its point in `from`.\n from.forEach((a, i) => {\n for (const j of starts[i]!) relax(j, a.cost + dist(a.point, points[j]!), -1 - i);\n });\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 (closed[i] === stamp) continue;\n closed[i] = stamp;\n const gi = 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 if (closed[j] === stamp) continue;\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 k = goalOf.get(bestEnd)!;\n const out: Point[] = [to[k]!.point];\n for (let i = bestEnd; ; i = parentOf[i]!) {\n out.push(points[i]!);\n if (parentOf[i]! < 0) {\n const f = -1 - parentOf[i]!;\n out.push(from[f]!.point);\n return { points: out.reverse(), from: f, to: k, cost: best };\n }\n }\n }\n\n /** This method tells if a corner of `starts` and a corner of `goal` are in one connected part of the graph. */\n #joined(starts: readonly number[], goal: ReadonlyMap<number, number>): boolean {\n const part = (this.#part ??= this.#parts());\n const goals = new Set<number>();\n for (const j of goal.keys()) goals.add(part[j]!);\n for (const j of starts) if (goals.has(part[j]!)) return true;\n return false;\n }\n\n /** This method gives the number of the connected part of each corner. */\n #parts(): Int32Array {\n const part = new Int32Array(this.points.length).fill(-1);\n const stack: number[] = [];\n let count = 0;\n for (let i = 0; i < part.length; i++) {\n if (part[i] !== -1) continue;\n part[i] = count;\n stack.push(i);\n while (stack.length > 0) {\n for (const j of this.#adj[stack.pop()!]!) {\n if (part[j] !== -1) continue;\n part[j] = count;\n stack.push(j);\n }\n }\n count++;\n }\n return part;\n }\n\n /**\n * This method gives at most `count` 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, count: number): number[] {\n const cache = count === this.#k * 2 ? this.#endCache : this.#fewCache;\n const key = `${p.x},${p.y}`;\n let out = cache.get(key);\n if (!out) {\n out = this.nearestVisible(p, count);\n if (out.length === 0) out = this.#nearestVisible(p, count, -1, 0);\n cache.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 link of a cone is at most this number of cells long. A longer search costs time on a dense level and finds few new links. */\nconst CONE_CELLS = 3;\n\n/** This function gives the bit of the cone of the offset (`dx`, `dy`): 1 is +x, 2 is +y, 4 is -x and 8 is -y. A diagonal offset is in a cone of the x axis. */\nconst coneOf = (dx: number, dy: number): number => (Math.abs(dx) >= Math.abs(dy) ? (dx > 0 ? 1 : 4) : dy > 0 ? 2 : 8);\n\n/** This function packs the two indices of a bucket into one number. Each index stays within ±2^20. */\nconst bucketKey = (i: number, j: number): number => (i + 1_048_576) * 2_097_152 + (j + 1_048_576);\n\n/**\n * A binary min-heap of (key, value) pairs in typed arrays. The pairs come out by key, and equal keys by value, so the order is deterministic.\n * The method `push` adds a pair to the heap. The method `add` only appends a pair, and the method `build` then makes the heap of all the pairs.\n */\nclass MinHeap {\n #d = new Float64Array(64);\n #j = new Int32Array(64);\n size = 0;\n\n /** The smallest key. */\n get topKey(): number {\n return this.#d[0]!;\n }\n\n push(key: number, value: number): void {\n this.add(key, value);\n const d = this.#d;\n const jj = this.#j;\n let i = this.size - 1;\n while (i > 0) {\n const p = (i - 1) >> 1;\n if (!(key < d[p]! || (key === d[p] && value < jj[p]!))) break;\n d[i] = d[p]!;\n jj[i] = jj[p]!;\n i = p;\n }\n d[i] = key;\n jj[i] = value;\n }\n\n clear(): void {\n this.size = 0;\n }\n\n add(d: number, j: number): void {\n if (this.size === this.#d.length) {\n const dd = new Float64Array(2 * this.size);\n dd.set(this.#d);\n this.#d = dd;\n const jj = new Int32Array(2 * this.size);\n jj.set(this.#j);\n this.#j = jj;\n }\n this.#d[this.size] = d;\n this.#j[this.size] = j;\n this.size++;\n }\n\n build(): void {\n for (let i = (this.size >> 1) - 1; i >= 0; i--) this.#down(i);\n }\n\n /** This method removes the pair with the smallest key and gives its value. */\n pop(): number {\n const top = this.#j[0]!;\n this.size--;\n if (this.size > 0) {\n this.#d[0] = this.#d[this.size]!;\n this.#j[0] = this.#j[this.size]!;\n this.#down(0);\n }\n return top;\n }\n\n #down(i: number): void {\n const d = this.#d;\n const jj = this.#j;\n const n = this.size;\n const di = d[i]!;\n const ji = jj[i]!;\n for (;;) {\n const l = 2 * i + 1;\n if (l >= n) break;\n const r = l + 1;\n let m = l;\n if (r < n && (d[r]! < d[l]! || (d[r] === d[l] && jj[r]! < jj[l]!))) m = r;\n if (!(d[m]! < di || (d[m] === di && jj[m]! < ji))) break;\n d[i] = d[m]!;\n jj[i] = jj[m]!;\n i = m;\n }\n d[i] = di;\n jj[i] = ji;\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 { dist, inflate, pointSegmentDistance, polylineLength, segmentHitsBox, type Box, type Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport type { Graph, Level, Result } from \"../model.ts\";\nimport { TOLERANCE } from \"./properties.ts\";\n\n/**\n * The faults of a set of links: the routes of the edges, or the links of one zoom level.\n * Each value counts links, except `worstDetour`. Lower is better for each value.\n */\nexport interface LinkFaults {\n /** The number of links that the measure examined. */\n readonly links: number;\n /**\n * The number of links that go through the inside of a box that is not one of their two ends.\n * A segment goes through a box when a part of it longer than `TOLERANCE` is inside the box made smaller by `TOLERANCE`.\n */\n readonly through: number;\n /**\n * The number of links that go out and back. The distance from a point of the link to its last point grows after the nearest approach.\n * A link goes out and back when this growth is more than `BACKTRACK_SHARE` of the distance between its ends, and more than `BACKTRACK_MIN` units.\n */\n readonly backtrack: number;\n /** The largest ratio of the length of a link to the distance between its ends. Links with ends nearer than 1 unit do not count. */\n readonly worstDetour: number;\n /**\n * The number of links with a point outside the bounding box of all the boxes, made larger by `slack`.\n * Both ends of a link are always in that bounding box, so such a link goes around the outer edge of the board.\n */\n readonly outside: number;\n}\n\n/** The faults of the links of one zoom level. */\nexport interface LevelFaults extends LinkFaults {\n readonly depth: number;\n /** The number of items of the level. */\n readonly items: number;\n /** The number of items that hold more than one node. */\n readonly groups: number;\n /** The number of pairs of items whose boxes overlap by more than `TOLERANCE` on each axis. */\n readonly overlaps: number;\n}\n\n/** The options of the link measures. */\nexport interface LinkFaultOptions {\n /** A link that goes farther than this distance outside the bounding box of all the boxes counts in `outside`. The default is 24. */\n readonly slack?: number;\n}\n\n/** A link goes out and back when its distance to its target grows by more than this share of the distance between its ends. */\nexport const BACKTRACK_SHARE = 0.25;\n/** A link goes out and back only when its distance to its target grows by more than this number of units. */\nexport const BACKTRACK_MIN = 40;\n/** The default `slack` of `LinkFaultOptions`. */\nexport const OUTSIDE_SLACK = 24;\n\n/** A link from one box to another box, as `measureLinks` sees it. */\nexport interface MeasuredLink {\n readonly source: string;\n readonly target: string;\n readonly points: readonly Point[];\n}\n\n/**\n * This function gives the largest growth of the distance to the last point of a polyline.\n * The growth at a vertex is its distance to the last point, less the nearest approach of the polyline before that vertex.\n */\nexport function backtrackOf(p: readonly Point[]): number {\n if (p.length < 3) return 0;\n const end = p[p.length - 1]!;\n let near = dist(p[0]!, end);\n let worst = 0;\n for (let i = 1; i < p.length; i++) {\n worst = Math.max(worst, dist(p[i]!, end) - near);\n near = Math.min(near, pointSegmentDistance(end, p[i - 1]!, p[i]!));\n }\n return worst;\n}\n\n/** This function tells if the polyline `p` goes out and back: `backtrackOf(p)` is more than `BACKTRACK_MIN` and more than `BACKTRACK_SHARE` of the span. */\nexport function goesOutAndBack(p: readonly Point[]): boolean {\n if (p.length < 3) return false;\n const span = dist(p[0]!, p[p.length - 1]!);\n return backtrackOf(p) > Math.max(BACKTRACK_MIN, BACKTRACK_SHARE * span);\n}\n\n/**\n * This function measures the faults of links between boxes. The map `boxes` gives the box of each end.\n * The bounding box of `outside` is the bounding box of all the boxes of the map.\n */\nexport function measureLinks(boxes: ReadonlyMap<string, Box>, links: readonly MeasuredLink[], options: LinkFaultOptions = {}): LinkFaults {\n const slack = options.slack ?? OUTSIDE_SLACK;\n let size = 0;\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const b of boxes.values()) {\n size += Math.max(b.w, b.h);\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 // Large items cover many buckets of a small grid, so the buckets grow with the items.\n const grid = new Grid<string>(Math.max(180, (2 * size) / Math.max(1, boxes.size)));\n for (const [id, b] of boxes) grid.add(id, b);\n let through = 0;\n let backtrack = 0;\n let worstDetour = 0;\n let outside = 0;\n for (const l of links) {\n const p = l.points;\n if (p.length === 0) continue;\n let hit = false;\n for (let i = 1; i < p.length && !hit; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n grid.querySegment(a, b, 0, (id) => {\n if (!hit && id !== l.source && id !== l.target && segmentHitsBox(a, b, inflate(boxes.get(id)!, -TOLERANCE), TOLERANCE)) hit = true;\n });\n }\n if (hit) through++;\n if (goesOutAndBack(p)) backtrack++;\n const span = dist(p[0]!, p[p.length - 1]!);\n if (span > 1) worstDetour = Math.max(worstDetour, polylineLength(p) / span);\n if (p.some((q) => q.x < x0 - slack || q.x > x1 + slack || q.y < y0 - slack || q.y > y1 + slack)) outside++;\n }\n return { links: links.length, through, backtrack, worstDetour, outside };\n}\n\n/** This function measures the faults of the routes of a result. The ends of a route are the nodes of its edge. */\nexport function measureRouteFaults(graph: Graph, result: Result, options: LinkFaultOptions = {}): LinkFaults {\n const boxes = new Map(graph.nodes.map((n) => [n.id, n.box]));\n const edges = new Map(graph.edges.map((e) => [e.id, e]));\n const links: MeasuredLink[] = [];\n for (const r of result.routes) {\n const e = edges.get(r.edge);\n if (e) links.push({ source: e.source.node, target: e.target.node, points: r.points });\n }\n return measureLinks(boxes, links, options);\n}\n\n/** This function counts the pairs of boxes that overlap by more than `TOLERANCE` on each axis. */\nexport function countOverlaps(boxes: readonly Box[]): number {\n let size = 0;\n for (const b of boxes) size += Math.max(b.w, b.h);\n const grid = new Grid<number>(Math.max(180, (2 * size) / Math.max(1, boxes.length)));\n boxes.forEach((b, i) => grid.add(i, b));\n let n = 0;\n boxes.forEach((a, i) => {\n grid.query(a, (j) => {\n const b = boxes[j]!;\n if (j > i && Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x) > TOLERANCE && Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y) > TOLERANCE) n++;\n });\n });\n return n;\n}\n\n/** This function measures the faults of the links of one zoom level. The items of the level are the boxes. */\nexport function measureLevel(level: Level, options: LinkFaultOptions = {}): LevelFaults {\n const boxes = new Map(level.items.map((i) => [i.id, i.box]));\n return {\n depth: level.depth,\n items: level.items.length,\n groups: level.items.filter((i) => i.nodes.length > 1).length,\n overlaps: countOverlaps(level.items.map((i) => i.box)),\n ...measureLinks(boxes, level.links, options),\n };\n}\n\n/**\n * This function measures the faults of each zoom level of a result that has groups: the levels of the far view.\n * A level of single nodes only is the near view. Its links are routes, and `measureRouteFaults` measures them.\n */\nexport function measureLevelFaults(result: Result, options: LinkFaultOptions = {}): LevelFaults[] {\n return (result.levels ?? []).filter((l) => l.items.some((i) => i.nodes.length > 1)).map((l) => measureLevel(l, options));\n}\n\n/** This function adds the faults of several levels: it sums the counts and keeps the largest `worstDetour`. */\nexport function sumFaults(list: readonly LinkFaults[]): LinkFaults {\n return list.reduce<LinkFaults>(\n (s, f) => ({\n links: s.links + f.links,\n through: s.through + f.through,\n backtrack: s.backtrack + f.backtrack,\n worstDetour: Math.max(s.worstDetour, f.worstDetour),\n outside: s.outside + f.outside,\n }),\n { links: 0, through: 0, backtrack: 0, worstDetour: 0, outside: 0 },\n );\n}\n","import { center, dist, polylineLength, 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\n/** The free plugs of a node, and the reach of each plug. */\ninterface FreePlugs {\n readonly plugs: readonly Plug[];\n readonly reach: readonly number[];\n}\n\n/** The ways of a level, with a second corner graph and the free plugs of the nodes. */\ninterface LevelWays extends Ways {\n /** This function gives a second corner graph with a small margin. The first link that needs it makes it. */\n readonly tight: () => CornerGraph;\n /** The free plugs of each node that a link needed. */\n readonly free: Map<Node, FreePlugs>;\n}\n\n/** The margin of the second corner graph. A gap between two boxes wider than approximately 1.5 times this margin lets a link through. */\nconst TIGHT_MARGIN = 1;\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 ??= sideWay(ways, s, t, inset);\n out.push({ source: p.source, target: p.target, count: p.count, points });\n }\n return out;\n}\n\n/**\n * This function gives a way from plug to plug between the plugs at the middle of a side of the two nodes.\n * Without a way in the corner graph, the link goes straight between the ends, with legs parallel to the axes where they are clear.\n * When that line goes through another box, the link goes between the free plugs of the two nodes (`freeWay`) instead.\n */\nfunction sideWay(ways: LevelWays, s: Node, t: Node, inset: number): Point[] {\n const e = ends(ways, s, sidePlug(ways, s, center(t.box)), t, sidePlug(ways, t, center(s.box)));\n const quick = quickWay(ways, e);\n if (quick) return quick;\n const path = ways.corners.path(e.a, e.b);\n const way = pulled(ways, e.ps, path ?? [e.a, e.b], e.pt);\n if (path || ways.obstacles.clearPath(way, 0, new Set([s, t]))) return way;\n return freeWay(ways, s, t, inset) ?? way;\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 * The corner graphs use `cones`, so a link goes along the corridors between the groups, not around the outer edge of the board.\n */\nfunction levelWays(nodes: readonly Node[], options: WayOptions): LevelWays {\n const margin = options.margin ?? 5;\n const k = options.k ?? 8;\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, cones: true });\n const out = (p: Plug): Point => ({ x: p.point.x + p.normal.x * margin, y: p.point.y + p.normal.y * margin });\n let tight: CornerGraph | undefined;\n const tightGraph = (): CornerGraph => (tight ??= new CornerGraph(nodes, obstacles, { margin: Math.min(margin, TIGHT_MARGIN), k, cones: true }));\n return { obstacles, corners, margin, out, tight: tightGraph, free: new Map() };\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/**\n * This function gives the free plugs of a node: on each side, the free point nearest to the middle of the side.\n * A point is free when it and the point at `margin` from it are in no other box. The function keeps the plugs of each node.\n */\nfunction freePlugs(ways: LevelWays, node: Node, inset: number): FreePlugs {\n const known = ways.free.get(node);\n if (known) return known;\n const b = node.box;\n const out: Plug[] = [];\n for (const side of SIDES) {\n const n = SIDE_NORMAL[side];\n const across = n.x === 0;\n // The side goes from `lo` to `hi` along its axis, at the coordinate `at` of the other axis.\n const lo = across ? b.x : b.y;\n const hi = across ? b.x + b.w : b.y + b.h;\n const at = across ? (n.y > 0 ? b.y + b.h : b.y) : n.x > 0 ? b.x + b.w : b.x;\n const far = at + (across ? n.y : n.x) * ways.margin;\n // A box covers a point of the side when the point or its way out is inside the box, as in `isFree`.\n const covered: [number, number][] = [];\n const strip = across\n ? { x: lo, y: Math.min(at, far), w: hi - lo, h: Math.abs(far - at) }\n : { x: Math.min(at, far), y: lo, w: Math.abs(far - at), h: hi - lo };\n ways.obstacles.query(strip, (m) => {\n if (m === node) return;\n const o = m.box;\n const [o0, o1, p0, p1] = across ? [o.x, o.x + o.w, o.y, o.y + o.h] : [o.y, o.y + o.h, o.x, o.x + o.w];\n if ((at > p0 && at < p1) || (far > p0 && far < p1)) covered.push([o0, o1]);\n });\n const mid = (lo + hi) / 2;\n let best: number | undefined;\n for (const [f0, f1] of freeSpans(lo, hi, covered)) {\n const room = Math.min(inset, (f1 - f0) / 2);\n const u = Math.max(f0 + room, Math.min(f1 - room, mid));\n if (best === undefined || Math.abs(u - mid) < Math.abs(best - mid)) best = u;\n }\n if (best !== undefined) out.push({ point: across ? { x: best, y: at } : { x: at, y: best }, normal: n });\n }\n const free = { plugs: out, reach: out.map((p) => reach(ways, node, p)) };\n ways.free.set(node, free);\n return free;\n}\n\n/** This function gives the indices of the plugs, and the plugs that face `toward` most come first. */\nfunction facingOrder(plugs: readonly Plug[], from: Point, toward: Point): number[] {\n const facing = (p: Plug): number => p.normal.x * (toward.x - from.x) + p.normal.y * (toward.y - from.y);\n return plugs.map((_, i) => i).sort((u, v) => facing(plugs[v]!) - facing(plugs[u]!) || u - v);\n}\n\n/** This function gives the parts of the span from `lo` to `hi` outside each open interval of `covered`. A part of zero length does not count. */\nfunction freeSpans(lo: number, hi: number, covered: [number, number][]): [number, number][] {\n covered.sort((u, v) => u[0] - v[0]);\n const out: [number, number][] = [];\n let x = lo;\n for (const [c0, c1] of covered) {\n if (c0 > x) out.push([x, Math.min(c0, hi)]);\n x = Math.max(x, c1);\n if (x >= hi) break;\n }\n if (x < hi) out.push([x, hi]);\n return out.filter(([a, b]) => b - a > EPS);\n}\n\n/**\n * This function gives the shortest way between the free plugs of the two nodes, or `undefined` when the second corner graph has none.\n * A link uses it when its plugs at the middle of a side find no way. Other boxes can cover such a plug, or close the space in front of it.\n */\nfunction freeWay(ways: LevelWays, s: Node, t: Node, inset: number): Point[] | undefined {\n const fs = freePlugs(ways, s, inset);\n const ft = freePlugs(ways, t, inset);\n const cs = center(s.box);\n const ct = center(t.box);\n const is = facingOrder(fs.plugs, cs, ct);\n const it = facingOrder(ft.plugs, ct, cs);\n const from = is.map((i) => fs.plugs[i]!);\n const to = it.map((k) => ft.plugs[k]!);\n const ra = is.map((i) => fs.reach[i]!);\n const rb = it.map((k) => ft.reach[k]!);\n // A pair of plugs with one or two clear legs between them gives the short way.\n let best: Point[] | undefined;\n let bestLength = Infinity;\n from.forEach((ps, i) =>\n to.forEach((pt, k) => {\n const way = quickWay(ways, endsAt(ps, ra[i]!, pt, rb[k]!));\n const length = way ? polylineLength(way) : Infinity;\n if (length < bestLength) {\n best = way;\n bestLength = length;\n }\n }),\n );\n if (best) return best;\n // Else one search of the second corner graph finds the shortest way from a plug of `s` to a plug of `t`.\n // The corners of the second graph are near the boxes, so the way can go through a gap that is narrower than the margin.\n const a = from.map((ps, i) => ({ point: along(ps, ra[i]!), cost: ra[i]! }));\n const b = to.map((pt, k) => ({ point: along(pt, rb[k]!), cost: rb[k]! }));\n const found = ways.tight().pathAmong(a, b);\n return found && pulled(ways, from[found.from]!, found.points, to[found.to]!);\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 return endsAt(ps, reach(ways, s, ps), pt, reach(ways, t, pt));\n}\n\n/** This function gives the ends of a link from the plug `ps` to the plug `pt`, with the reach of each plug. */\nfunction endsAt(ps: Plug, ra: number, pt: Plug, rb: number): Ends {\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 the plug `ps` through the points of `path` to the plug `pt`.\n * The way leaves and enters each plug along its normal. Then it pulls the corners tight with legs that are parallel to the axes, where the obstacles let it.\n */\nfunction pulled(ways: Ways, ps: Plug, path: readonly Point[], pt: Plug): Point[] {\n const legs = squarePull(path, ways.obstacles, ways.margin / 2, axisOf(ps.normal), axisOf(pt.normal));\n return tidy([ps.point, ...legs, 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 { BACKTRACK_MIN, goesOutAndBack } from \"../bench/links.ts\";\nimport { center, dist, pointSegmentDistance, 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 * A hub can be this many units farther from the target than the nearest approach of the way before it.\n * A hub farther away goes out and back, so the way skips it.\n */\nconst HUB_SLACK = 2 * BACKTRACK_MIN;\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 * An edge skips a hub that takes it away from its target. A way that still goes out and back gives way to the direct way.\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 // The sections of the chain whose hubs do not take the way away from its target. The test uses the straight lines from hub to hub.\n const forward = (list: readonly Section[], from: Point, to: Point): Section[] => {\n const kept: Section[] = [];\n let near = dist(from, to);\n let last = from;\n for (const c of list) {\n const h = hub(c);\n if (dist(h, to) > near + HUB_SLACK) continue;\n near = Math.min(near, pointSegmentDistance(to, last, h));\n last = h;\n kept.push(c);\n }\n return kept;\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 end = ways.out(pt);\n const start = ways.out(ps);\n const chain = forward([...side(a), ...side(b).reverse()], start, pt.point);\n if (chain.length === 0) {\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n continue;\n }\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 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 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, or that goes out and back, gives way to the direct way.\n if (polylineLength(out) > stretch * dist(ps.point, pt.point) + 4 * ways.margin || goesOutAndBack(out)) {\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 built-in routers. The registry `STRATEGIES` holds the same routers as strategies, and the benchmark races the routers of the registry. */\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 { center, type Box, type Point } from \"../geom.ts\";\nimport { levelLinks } from \"../levels.ts\";\nimport type { Edge, Graph, Router } from \"../model.ts\";\n\n/** An item with a box: a node of a graph, an item of a level or a box of a host layout. */\nexport interface Boxed {\n readonly id: string;\n readonly box: Box;\n}\n\n/** A link between two boxes. For a bundled link, `count` is the number of its edges. The default count is 1. */\nexport interface RoomLink {\n readonly source: string;\n readonly target: string;\n readonly count?: number;\n}\n\n/**\n * A gap of a board: a boundary of the sweep over the left or top edges of the boxes.\n * On the axis `x`, the gap is a vertical channel between two columns. On the axis `y`, it is a horizontal channel between two rows.\n */\nexport interface Gap {\n readonly axis: \"x\" | \"y\";\n /** The place of the gap in the order of the gaps on its axis, from 0. */\n readonly index: number;\n /** The coordinate where the boxes after the gap start, on the axis of the gap. */\n readonly at: number;\n /** The ids of the boxes that end at the near side of the gap. */\n readonly before: readonly string[];\n /** The ids of the boxes that start at the far side of the gap, at `at`. */\n readonly after: readonly string[];\n /** The current width of the gap: the distance from the nearest box edge before the gap to `at`. */\n readonly width: number;\n /** The number of lanes that the links need in the gap. */\n readonly lanes: number;\n /** The width that the gap needs: at least the current width, and at least `gutter + lanes × spacing`. */\n readonly need: number;\n}\n\n/** The ways that `roomDemand` finds the lanes of each gap. */\nexport type RoomMethod = \"routes\" | \"lines\";\n\n/** The options of `roomDemand` and `makeRoom`. */\nexport interface RoomOptions {\n /** The smallest width of each gap. The default is 8. */\n readonly gutter?: number;\n /** The width of one lane: the distance between two lines that run side by side. The default is 4. */\n readonly spacing?: number;\n /**\n * The largest growth of the board on each axis, as a share of its size. The default is `Infinity`.\n * When the lanes need more, each gap gets its gutter, and the lanes share the rest in proportion.\n */\n readonly maxGrowth?: number;\n /**\n * The way to find the lanes. The default is `routes`.\n * With `routes`, the function routes the links one time on the board with each gap open to the gutter.\n * The lanes of a gap are the most routes that run along the gap side by side.\n * With `lines`, the lanes of a gap are the straight lines between the centers of the boxes that cross the gap.\n */\n readonly method?: RoomMethod;\n /** The router of the method `routes`. Without it, the links go as the links of a zoom level (`levelLinks`), with the margin `gutter / 2`. */\n readonly router?: Router;\n /** With `count`, a link takes one lane for each of its edges. With `link`, the default, a link takes one lane. */\n readonly lanes?: \"link\" | \"count\";\n /** Two box edges nearer than this distance make one boundary of the sweep. The default is 0.5. */\n readonly snap?: number;\n /**\n * The number of passes of the demand. The default is 1.\n * Each pass after the first finds the lanes again on the board that the passes before it opened, and adds the growth that it needs.\n * The limit `maxGrowth` applies to the sum of the passes.\n */\n readonly passes?: number;\n}\n\n/** The demand of a board and the board with its gaps open. */\nexport interface Room<T extends Boxed> {\n readonly gaps: readonly Gap[];\n readonly items: T[];\n}\n\nconst DEFAULT_GUTTER = 8;\nconst DEFAULT_SPACING = 4;\nconst DEFAULT_SNAP = 0.5;\n\ntype Axis = \"x\" | \"y\";\n\nconst lo = (b: Box, a: Axis): number => (a === \"x\" ? b.x : b.y);\nconst len = (b: Box, a: Axis): number => (a === \"x\" ? b.w : b.h);\nconst other = (a: Axis): Axis => (a === \"x\" ? \"y\" : \"x\");\n\n/**\n * This function gives the gaps of a board. A sweep over each axis sorts the left (or top) edges of the boxes.\n * Each distinct edge after the first is a gap. The `lanes` of each gap are 0, and its `need` is its current width.\n */\nexport function boardGaps(items: readonly Boxed[], snap: number = DEFAULT_SNAP): Gap[] {\n return [...axisGaps(items, \"x\", snap), ...axisGaps(items, \"y\", snap)];\n}\n\nfunction axisGaps(items: readonly Boxed[], axis: Axis, snap: number): Gap[] {\n const starts = [...new Set(items.map((i) => lo(i.box, axis)))].sort((u, v) => u - v);\n const bounds: number[] = [];\n for (const s of starts) if (bounds.length === 0 || s - bounds[bounds.length - 1]! > snap) bounds.push(s);\n const after: string[][] = bounds.map(() => []);\n for (const i of items) after[lastAtOrBefore(bounds, lo(i.box, axis) + snap)]!.push(i.id);\n const ends = items.map((i) => ({ id: i.id, end: lo(i.box, axis) + len(i.box, axis) })).sort((u, v) => u.end - v.end);\n const gaps: Gap[] = [];\n let k = 0;\n for (let n = 1; n < bounds.length; n++) {\n const at = bounds[n]!;\n // The nearest box edge before the gap is the largest end at or before the boundary.\n while (k < ends.length && ends[k]!.end <= at + snap) k++;\n const near = k > 0 ? ends[k - 1]!.end : at;\n const before: string[] = [];\n for (let j = k - 1; j >= 0 && ends[j]!.end >= near - snap; j--) before.push(ends[j]!.id);\n gaps.push({ axis, index: n - 1, at, before: before.reverse(), after: after[n]!, width: Math.max(0, at - near), lanes: 0, need: Math.max(0, at - near) });\n }\n return gaps;\n}\n\n/** This function gives the index of the last value of the sorted list `v` that is at or before `x`, or 0. */\nfunction lastAtOrBefore(v: readonly number[], x: number): number {\n let a = 0;\n let b = v.length - 1;\n while (a < b) {\n const m = (a + b + 1) >> 1;\n if (v[m]! <= x) a = m;\n else b = m - 1;\n }\n return a;\n}\n\n/**\n * This function moves the boxes apart, so that each gap gets the width `need`. The boxes keep their size, their order and their alignment.\n * A box moves by the sum of the growth of each gap at or before its left (or top) edge. Thus a grid stays a grid.\n * The function moves no box nearer to another box, so it makes no overlap.\n */\nexport function openGaps<T extends Boxed>(items: readonly T[], gaps: readonly Gap[], snap: number = DEFAULT_SNAP): T[] {\n const shift = (axis: Axis): ((v: number) => number) => {\n const list = gaps.filter((g) => g.axis === axis).sort((u, v) => u.at - v.at);\n const at = list.map((g) => g.at);\n const sum: number[] = [];\n let s = 0;\n for (const g of list) sum.push((s += Math.max(0, g.need - g.width)));\n return (v) => (list.length === 0 || at[0]! > v + snap ? 0 : sum[lastAtOrBefore(at, v + snap)]!);\n };\n const sx = shift(\"x\");\n const sy = shift(\"y\");\n return items.map((i) => ({ ...i, box: { ...i.box, x: i.box.x + sx(i.box.x), y: i.box.y + sy(i.box.y) } }));\n}\n\n/**\n * This function gives the room that the links need in each gap of the board.\n * The lanes of a gap come from the `method` of the options. The need of a gap is `gutter + lanes × spacing`, and not less than its current width.\n */\nexport function roomDemand(items: readonly Boxed[], links: readonly RoomLink[], options: RoomOptions = {}): Gap[] {\n const gutter = options.gutter ?? DEFAULT_GUTTER;\n const snap = options.snap ?? DEFAULT_SNAP;\n const passes = Math.max(1, Math.floor(options.passes ?? 1));\n let total = demandOnce(items, links, options);\n for (let p = 1; p < passes; p++) {\n // The next pass measures the board that the passes before it opened. Its gaps are the same gaps, in the same order.\n const next = demandOnce(openGaps(items, total, snap), links, options);\n if (next.length !== total.length || next.some((g, i) => g.axis !== total[i]!.axis)) break;\n total = total.map((g, i) => ({ ...g, lanes: Math.max(g.lanes, next[i]!.lanes), need: g.need + Math.max(0, next[i]!.need - next[i]!.width) }));\n }\n return capGrowth(items, total, gutter, options.maxGrowth ?? Infinity);\n}\n\n/** This function gives the demand of one pass, without the limit `maxGrowth`. */\nfunction demandOnce(items: readonly Boxed[], links: readonly RoomLink[], options: RoomOptions): Gap[] {\n const gutter = options.gutter ?? DEFAULT_GUTTER;\n const spacing = options.spacing ?? DEFAULT_SPACING;\n const snap = options.snap ?? DEFAULT_SNAP;\n const weight = (l: RoomLink): number => (options.lanes === \"count\" ? Math.max(1, l.count ?? 1) : 1);\n const gaps = boardGaps(items, snap);\n const lanes = (options.method ?? \"routes\") === \"lines\" ? lineLanes(items, links, gaps, weight) : routeLanes(items, links, gaps, gutter, snap, weight, options.router);\n return gaps.map((g, i) => ({ ...g, lanes: lanes[i]!, need: Math.max(g.width, gutter + lanes[i]! * spacing) }));\n}\n\n/** This function gives the demand of the board and the board with each gap open to its need. */\nexport function makeRoom<T extends Boxed>(items: readonly T[], links: readonly RoomLink[], options: RoomOptions = {}): Room<T> {\n const gaps = roomDemand(items, links, options);\n return { gaps, items: openGaps(items, gaps, options.snap ?? DEFAULT_SNAP) };\n}\n\n/** This function gives the links between the nodes of a graph, with the count of the edges of each pair. A loop does not count. */\nexport function roomLinks(graph: Graph): RoomLink[] {\n const byPair = new Map<string, { source: string; target: string; count: number }>();\n for (const e of graph.edges) {\n const [s, t] = [e.source.node, e.target.node];\n if (s === t) continue;\n const key = s < t ? `${s}\\u0000${t}` : `${t}\\u0000${s}`;\n const known = byPair.get(key);\n if (known) known.count++;\n else byPair.set(key, { source: s, target: t, count: 1 });\n }\n return [...byPair.values()];\n}\n\n/** This function counts, for each gap, the straight lines between the centers of the boxes of a link that cross the gap. */\nfunction lineLanes(items: readonly Boxed[], links: readonly RoomLink[], gaps: readonly Gap[], weight: (l: RoomLink) => number): number[] {\n const byId = new Map(items.map((i) => [i.id, center(i.box)]));\n return gaps.map((g) => {\n let n = 0;\n for (const l of links) {\n const a = byId.get(l.source);\n const b = byId.get(l.target);\n if (a && b && Math.min(a[g.axis], b[g.axis]) < g.at && Math.max(a[g.axis], b[g.axis]) > g.at) n += weight(l);\n }\n return n;\n });\n}\n\n/**\n * This function routes the links one time on the board with each gap open to the gutter.\n * The lanes of a gap are the largest number of routes that run along the gap at one place.\n * A piece of a route goes along a gap when it is in the channel of the gap.\n * It must also go farther along the gap than across it.\n */\nfunction routeLanes(\n items: readonly Boxed[],\n links: readonly RoomLink[],\n gaps: readonly Gap[],\n gutter: number,\n snap: number,\n weight: (l: RoomLink) => number,\n router: Router | undefined,\n): number[] {\n const probeGaps = gaps.map((g) => ({ ...g, need: Math.max(g.width, gutter) }));\n const probe = openGaps(items, probeGaps, snap);\n const ways = probeWays(probe, links, gutter, router);\n return probeGaps.map((g) => {\n // The channel of the gap on the probe board: its far side moves with the growth of each gap up to this one.\n let grow = 0;\n for (const h of probeGaps) if (h.axis === g.axis && h.at <= g.at + snap) grow += h.need - h.width;\n const hi = g.at + grow;\n const lo = hi - g.need;\n const spans: { from: number; to: number; w: number }[] = [];\n ways.forEach((points, i) => {\n const along = alongSpans(points, g.axis, lo, hi);\n for (const [from, to] of merge(along)) spans.push({ from, to, w: weight(links[i]!) });\n });\n return density(spans);\n });\n}\n\n/** This function gives the points of the way of each link on the probe board, in the order of the links. */\nfunction probeWays(items: readonly Boxed[], links: readonly RoomLink[], gutter: number, router: Router | undefined): (readonly Point[])[] {\n if (router) {\n const edges: Edge[] = links.map((l, i) => ({ id: `l${i}`, source: { node: l.source }, target: { node: l.target } }));\n const routes = new Map(router.route({ nodes: items, edges }).routes.map((r) => [r.edge, r.points]));\n return edges.map((e) => routes.get(e.id) ?? []);\n }\n const level = items.map((i) => ({ id: i.id, box: i.box, nodes: [i.id] }));\n const pairs = links.map((l) => ({ source: l.source, target: l.target, count: l.count ?? 1 }));\n // The margin puts the corners of the two sides of a gap on its middle line.\n const out = levelLinks(level, pairs, { margin: Math.max(1, gutter / 2) });\n const byPair = new Map(out.map((l) => [`${l.source}\\u0000${l.target}`, l.points]));\n return links.map((l) => byPair.get(`${l.source}\\u0000${l.target}`) ?? []);\n}\n\n/**\n * This function gives the spans along the axis of a gap where the polyline goes along the channel from `lo` to `hi`.\n * The axis `x` gap is a vertical channel, so its spans are on the y axis.\n */\nfunction alongSpans(p: readonly Point[], axis: Axis, lo: number, hi: number): [number, number][] {\n const across = axis;\n const along = other(axis);\n const out: [number, number][] = [];\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n const da = b[across] - a[across];\n // The part of the segment inside the channel, as the parameters t0 and t1 of the segment.\n let t0 = 0;\n let t1 = 1;\n if (Math.abs(da) < 1e-9) {\n if (a[across] < lo - 1e-6 || a[across] > hi + 1e-6) continue;\n } else {\n const u = (lo - a[across]) / da;\n const v = (hi - a[across]) / da;\n t0 = Math.max(0, Math.min(u, v));\n t1 = Math.min(1, Math.max(u, v));\n if (t1 <= t0) continue;\n }\n const s = a[along] + (b[along] - a[along]) * t0;\n const e = a[along] + (b[along] - a[along]) * t1;\n const run = Math.abs(e - s);\n const cross = Math.abs(da) * (t1 - t0);\n if (run > cross && run > 1e-6) out.push([Math.min(s, e), Math.max(s, e)]);\n }\n return out;\n}\n\n/** This function joins the spans that overlap, so that one link counts one time at each place. */\nfunction merge(spans: [number, number][]): [number, number][] {\n spans.sort((u, v) => u[0] - v[0]);\n const out: [number, number][] = [];\n for (const s of spans) {\n const last = out[out.length - 1];\n if (last && s[0] <= last[1]) last[1] = Math.max(last[1], s[1]);\n else out.push([s[0], s[1]]);\n }\n return out;\n}\n\n/** This function gives the largest sum of the weights of the spans that overlap at one place. Spans that only touch do not overlap. */\nfunction density(spans: readonly { from: number; to: number; w: number }[]): number {\n const events: [number, number][] = [];\n for (const s of spans) events.push([s.from, s.w], [s.to, -s.w]);\n // At one coordinate, the ends come before the starts.\n events.sort((u, v) => u[0] - v[0] || u[1] - v[1]);\n let n = 0;\n let best = 0;\n for (const [, w] of events) {\n n += w;\n best = Math.max(best, n);\n }\n return best;\n}\n\n/**\n * This function keeps the growth of the board on each axis at most `maxGrowth` times its size.\n * Each gap keeps its gutter. The lanes of all gaps of the axis share the rest of the growth in proportion.\n */\nfunction capGrowth(items: readonly Boxed[], gaps: Gap[], gutter: number, maxGrowth: number): Gap[] {\n if (!Number.isFinite(maxGrowth)) return gaps;\n const out = [...gaps];\n for (const axis of [\"x\", \"y\"] as const) {\n let x0 = Infinity;\n let x1 = -Infinity;\n for (const i of items) {\n x0 = Math.min(x0, lo(i.box, axis));\n x1 = Math.max(x1, lo(i.box, axis) + len(i.box, axis));\n }\n const budget = Math.max(0, maxGrowth) * Math.max(0, x1 - x0);\n let base = 0;\n let spare = 0;\n for (const g of gaps) {\n if (g.axis !== axis) continue;\n const b = Math.max(0, gutter - g.width);\n base += b;\n spare += Math.max(0, g.need - g.width - b);\n }\n if (base + spare <= budget || spare === 0) continue;\n const f = Math.max(0, (budget - base) / spare);\n gaps.forEach((g, i) => {\n if (g.axis !== axis) return;\n const b = Math.max(0, gutter - g.width);\n out[i] = { ...g, need: g.width + b + f * Math.max(0, g.need - g.width - b) };\n });\n }\n return out;\n}\n","import { segmentHitsBox, type Box, type Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport type { LevelLink } from \"../model.ts\";\nimport { boardGaps, type Boxed } from \"./index.ts\";\n\n/**\n * The lane order of the pieces of the links in one gap.\n *\n * - `links`: the order of the list of links. This order reads nothing of the board.\n * - `ends`: the pieces that turn to the near side at their two ends come first. The pieces that turn to the far side come last.\n * - `crossings`: the order with the fewest crossings between the pieces of the gap and the legs at their ends. A local search finds it.\n */\nexport type LaneOrder = \"links\" | \"ends\" | \"crossings\";\n\n/** The lane orders of `gapLanes`, in the order of the benchmark. */\nexport const LANE_ORDERS: readonly LaneOrder[] = [\"links\", \"ends\", \"crossings\"];\n\n/** The options of `gapLanes`. */\nexport interface GapLaneOptions {\n /** The largest distance between two lanes. A narrow gap puts its lanes nearer. The default is 4. */\n readonly spacing?: number;\n /** The lane order in each gap. The default is `crossings`. */\n readonly order?: LaneOrder;\n /** Two box edges nearer than this distance make one boundary of the sweep, as in `boardGaps`. The default is 0.5. */\n readonly snap?: number;\n}\n\n/** A piece of a link: a leg of the link that runs along a gap. */\ninterface Piece {\n /** The index of the link. */\n readonly link: number;\n /** The index of the last point of the leg. The leg goes from the point `seg - 1` to the point `seg`. */\n readonly seg: number;\n /** The span of the leg along the gap. */\n readonly lo: number;\n readonly hi: number;\n /** For each end of the leg: its place along the gap, and the side (-1 or 1) across the gap where the link turns. */\n readonly turns: readonly (readonly [number, number])[];\n}\n\nconst EPS = 1e-6;\nconst ROUNDS = 8;\n\n/**\n * This function gives each link that runs along a gap its own lane in the gap. The lanes of a gap are `spacing` apart, around its middle line.\n * A leg of a link moves across its gap only, so the link keeps its plugs and the axes of its legs.\n * When a move puts a link through more boxes than before, the link keeps its points.\n */\nexport function gapLanes(items: readonly Boxed[], links: readonly LevelLink[], options: GapLaneOptions = {}): LevelLink[] {\n const spacing = Math.max(0, options.spacing ?? 4);\n const order = options.order ?? \"crossings\";\n const moved = links.map((l) => l.points.map((p) => ({ x: p.x, y: p.y })));\n for (const g of boardGaps(items, options.snap)) {\n if (g.width <= EPS) continue;\n const across = g.axis;\n const along = g.axis === \"x\" ? \"y\" : \"x\";\n const lo = g.at - g.width;\n const hi = g.at;\n const pieces: Piece[] = [];\n links.forEach((l, li) => {\n const p = l.points;\n // The first and the last legs hold the plugs, so they do not move.\n for (let i = 2; i <= p.length - 2; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n if (Math.abs(a[across] - b[across]) > EPS || a[across] <= lo + EPS || a[across] >= hi - EPS) continue;\n if (Math.abs(a[along] - b[along]) <= EPS) continue;\n const side = (q: Point, r: Point): number => Math.sign(r[across] - q[across]);\n pieces.push({\n link: li,\n seg: i,\n lo: Math.min(a[along], b[along]),\n hi: Math.max(a[along], b[along]),\n turns: [\n [a[along], side(a, p[i - 2]!)],\n [b[along], side(b, p[i + 1]!)],\n ],\n });\n }\n });\n if (pieces.length === 0) continue;\n const list = orderPieces(pieces, order);\n // A piece goes one lane past each piece before it in the order that it overlaps. Thus two pieces that overlap keep their order.\n const lane: number[] = [];\n let n = 0;\n list.forEach((P, i) => {\n let k = 0;\n for (let j = 0; j < i; j++) if (overlaps(list[j]!, P)) k = Math.max(k, lane[j]! + 1);\n lane.push(k);\n n = Math.max(n, k + 1);\n });\n const step = Math.min(spacing, g.width / (n + 1));\n const mid = (lo + hi) / 2;\n list.forEach((P, i) => {\n const v = mid + (lane[i]! - (n - 1) / 2) * step;\n moved[P.link]![P.seg - 1]![across] = v;\n moved[P.link]![P.seg]![across] = v;\n });\n }\n const boxes = new Grid<Box>(Math.max(20, meanSide(items)));\n for (const i of items) boxes.add(i.box, i.box);\n return links.map((l, i) => (hits(boxes, moved[i]!) > hits(boxes, l.points) ? l : { ...l, points: moved[i]! }));\n}\n\nconst overlaps = (P: Piece, Q: Piece): boolean => Math.min(P.hi, Q.hi) - Math.max(P.lo, Q.lo) > EPS;\n\n/**\n * This function counts the crossings when the piece `P` is on the near side of the piece `Q`.\n * A turn of `P` to the far side crosses `Q` when it is inside the span of `Q`. A turn of `Q` to the near side crosses `P` in the same way.\n */\nfunction cost(P: Piece, Q: Piece): number {\n let c = 0;\n for (const [y, s] of P.turns) if (s > 0 && y > Q.lo + EPS && y < Q.hi - EPS) c++;\n for (const [y, s] of Q.turns) if (s < 0 && y > P.lo + EPS && y < P.hi - EPS) c++;\n return c;\n}\n\n/** This function gives the pieces of one gap in lane order, from the near side to the far side. */\nfunction orderPieces(pieces: readonly Piece[], order: LaneOrder): Piece[] {\n if (order === \"links\") return [...pieces];\n const sum = (P: Piece): number => P.turns.reduce((s, [, side]) => s + side, 0);\n const list = [...pieces].sort((P, Q) => sum(P) - sum(Q) || P.link - Q.link || P.seg - Q.seg);\n if (order === \"ends\") return list;\n // The local search moves one piece to the place that removes the most crossings, until no move removes one.\n const n = list.length;\n const index = new Map(list.map((P, i) => [P, i]));\n const c: number[][] = list.map((P) => list.map((Q) => (P !== Q && overlaps(P, Q) ? cost(P, Q) : 0)));\n const at = (P: Piece, Q: Piece): number => c[index.get(P)!]![index.get(Q)!]!;\n for (let round = 0; round < ROUNDS; round++) {\n let better = false;\n for (let i = 0; i < n; i++) {\n const x = list[i]!;\n // The change of the crossings when `x` moves to the place `k`, for each `k`.\n let best = 0;\n let to = i;\n let d = 0;\n for (let k = i - 1; k >= 0; k--) {\n d += at(x, list[k]!) - at(list[k]!, x);\n if (d < best) [best, to] = [d, k];\n }\n d = 0;\n for (let k = i + 1; k < n; k++) {\n d += at(list[k]!, x) - at(x, list[k]!);\n if (d < best) [best, to] = [d, k];\n }\n if (to !== i) {\n list.splice(i, 1);\n list.splice(to, 0, x);\n better = true;\n }\n }\n if (!better) break;\n }\n return list;\n}\n\n/** This function gives the mean of the longer side of the boxes. */\nfunction meanSide(items: readonly Boxed[]): number {\n let s = 0;\n for (const i of items) s += Math.max(i.box.w, i.box.h);\n return items.length ? s / items.length : 1;\n}\n\n/** This function counts the legs of a polyline that go through a box, for each box. */\nfunction hits(boxes: Grid<Box>, p: readonly Point[]): number {\n let n = 0;\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n boxes.querySegment(a, b, 0, (box) => {\n if (segmentHitsBox(a, b, box)) n++;\n });\n }\n return n;\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 { measureLevelFaults, measureRouteFaults, sumFaults, type LevelFaults, type LinkFaults } from \"./links.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 /** The faults of the routes of the edges (`measureRouteFaults`). */\n readonly faults: LinkFaults;\n /** The faults of each zoom level with groups (`measureLevelFaults`). The list is empty for a router without levels. */\n readonly levelFaults: readonly LevelFaults[];\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 faults: measureRouteFaults(graph, result),\n levelFaults: measureLevelFaults(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\n/**\n * This function writes the faults of the rows as a Markdown table: the routes first, then the sum of the levels with groups.\n * A router without such levels gets a dash in the columns of the levels.\n */\nexport function formatFaults(rows: readonly BenchRow[]): string {\n const head =\n \"| router | fixture | through | out and back | worst detour | outside | level links | level overlaps | level through | level out and back | level worst detour | level outside |\";\n const line = \"|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map((r) => {\n const f = r.faults;\n const cells = [r.router, r.fixture, f.through, f.backtrack, f.worstDetour.toFixed(2), f.outside];\n if (r.levelFaults.length === 0) cells.push(\"-\", \"-\", \"-\", \"-\", \"-\", \"-\");\n else {\n const l = sumFaults(r.levelFaults);\n cells.push(l.links, r.levelFaults.reduce((s, x) => s + x.overlaps, 0), l.through, l.backtrack, l.worstDetour.toFixed(2), l.outside);\n }\n return `| ${cells.join(\" | \")} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n","import type { CurveSegment } from \"../curves/model.ts\";\nimport type { CurveSpace } from \"../curves/space.ts\";\nimport type { Point } from \"../geom.ts\";\nimport type { Graph, Result, Router } from \"../model.ts\";\nimport type { Boxed, Gap, RoomLink } from \"../room/index.ts\";\n\n/** The input of a curve strategy: one polyline and the context of its route. */\nexport interface CurveInput {\n /** These points are the polyline: a route of a router, a lane of `laneRoutes` or a link of a zoom level. */\n readonly points: readonly Point[];\n /** The curve leaves the first point along this outward normal of its plug, if the strategy reads it. */\n readonly startNormal?: Point;\n /** The curve comes into the last point against this outward normal of its plug, if the strategy reads it. */\n readonly endNormal?: Point;\n /** The boxes that the curve must not go through, from `curveSpace`. */\n readonly space?: CurveSpace;\n}\n\n/** The input of a room strategy: the boxes of a board and the links between them. */\nexport interface RoomInput {\n readonly items: readonly Boxed[];\n readonly links: readonly RoomLink[];\n}\n\n/**\n * The steps that have strategies, with the fixed input and output type of each step.\n *\n * - `router`: a graph in, the routes (and the `levels`, `bundles` and `runs`) out.\n * - `curve`: a polyline in, the segments of a curve out.\n * - `room`: the boxes and links of a board in, the gaps of the board with their need out.\n */\nexport interface StepTypes {\n readonly router: { readonly input: Graph; readonly output: Result };\n readonly curve: { readonly input: CurveInput; readonly output: CurveSegment[] };\n readonly room: { readonly input: RoomInput; readonly output: Gap[] };\n}\n\n/** The name of a step that has strategies. */\nexport type Step = keyof StepTypes;\n\n/** The input type of a step. */\nexport type StepInput<S extends Step> = StepTypes[S][\"input\"];\n\n/** The output type of a step. */\nexport type StepOutput<S extends Step> = StepTypes[S][\"output\"];\n\n/** The steps that have strategies, in the order of the pipeline. */\nexport const STEPS: readonly Step[] = [\"router\", \"curve\", \"room\"];\n\n/**\n * A strategy: one way to do one step, with a name and a description.\n * The same input and the same options must give the same output.\n */\nexport interface Strategy<S extends Step = Step, O extends object = object> {\n /** The step of the strategy. It fixes the input and the output type. */\n readonly step: S;\n /** The name of the strategy. Each name is unique in its step of a registry. */\n readonly name: string;\n /** One or two sentences that tell what the strategy does. The site and the documents show them. */\n readonly describe: string;\n /** The values of the options when the caller gives no value. */\n readonly defaults: Readonly<O>;\n /** The benchmark skips an input with more nodes than this. Without it, the strategy takes each input. */\n readonly maxNodes?: number;\n /** This method does the step. Each option that `options` does not give gets its value from `defaults`. */\n run(input: StepInput<S>, options?: Partial<O>): StepOutput<S>;\n}\n\n/** A strategy of any step. A registry holds a list of these. */\nexport type AnyStrategy = { [S in Step]: Strategy<S> }[Step];\n\n/** The definition of a strategy, for `defineStrategy`. */\nexport interface StrategyDefinition<S extends Step, O extends object> {\n readonly step: S;\n readonly name: string;\n readonly describe: string;\n /** These values are the options when the caller gives no value. Give `{}` for a strategy without options. */\n readonly defaults: O;\n readonly maxNodes?: number;\n /** This function does the step. It gets each option, from the caller or from `defaults`. */\n run(input: StepInput<S>, options: Readonly<O>): StepOutput<S>;\n}\n\n/**\n * This function makes a strategy from its definition. The strategy fills the missing options from `defaults`.\n * When the caller gives no option, the definition gets the `defaults` object itself.\n */\nexport function defineStrategy<S extends Step, O extends object>(definition: StrategyDefinition<S, O>): Strategy<S, O> {\n const { step, name, describe, defaults, maxNodes } = definition;\n if (name.length === 0) throw new Error(`A strategy of the step \"${step}\" has no name.`);\n const strategy: Strategy<S, O> = {\n step,\n name,\n describe,\n defaults: Object.freeze({ ...defaults }),\n ...(maxNodes === undefined ? {} : { maxNodes }),\n run(input: StepInput<S>, options?: Partial<O>): StepOutput<S> {\n const all = options === undefined || Object.keys(options).length === 0 ? strategy.defaults : { ...strategy.defaults, ...options };\n return definition.run(input, all as Readonly<O>);\n },\n };\n return Object.freeze(strategy);\n}\n\n/**\n * A registry: the strategies of each step, in order. A registry is data. No import changes it.\n * A consumer makes its own registry with `createRegistry`, and adds a strategy with `register`.\n */\nexport type Registry = { readonly [S in Step]: readonly Strategy<S>[] };\n\n/** This function makes a registry from a list of strategies. It keeps their order. Two strategies with one step and one name are an error. */\nexport function createRegistry(strategies: readonly AnyStrategy[]): Registry {\n const out: { [S in Step]: Strategy<S>[] } = { router: [], curve: [], room: [] };\n for (const s of strategies) {\n const list = out[s.step] as AnyStrategy[] | undefined;\n if (!list) throw new Error(`There is no step \"${String(s.step)}\". The steps are ${STEPS.join(\", \")}.`);\n if (list.some((t) => t.name === s.name)) throw new Error(`The step \"${s.step}\" has two strategies with the name \"${s.name}\".`);\n list.push(s);\n }\n return Object.freeze({ router: Object.freeze(out.router), curve: Object.freeze(out.curve), room: Object.freeze(out.room) });\n}\n\n/** This function gives a new registry with the strategies of `registry` and then `strategies`. It does not change `registry`. */\nexport function register(registry: Registry, ...strategies: readonly AnyStrategy[]): Registry {\n return createRegistry([...registry.router, ...registry.curve, ...registry.room, ...strategies]);\n}\n\n/** This function gives the strategies of one step of a registry, in order. */\nexport function listStrategies<S extends Step>(registry: Registry, step: S): readonly Strategy<S>[] {\n return registry[step];\n}\n\n/** This function gives the strategy of one step with a name, or `undefined` when the registry has no such strategy. */\nexport function findStrategy<S extends Step>(registry: Registry, step: S, name: string): Strategy<S> | undefined {\n return listStrategies(registry, step).find((s) => s.name === name);\n}\n\n/** This function gives the strategy of one step with a name. When the registry has no such strategy, the function throws an error. */\nexport function getStrategy<S extends Step>(registry: Registry, step: S, name: string): Strategy<S> {\n const s = findStrategy(registry, step, name);\n if (!s) throw new Error(`There is no ${step} \"${name}\". The registry has ${listStrategies(registry, step).map((t) => t.name).join(\", \")}.`);\n return s;\n}\n\n/** This function gives a `Router` that runs a router strategy with the options. The router keeps the name and the `maxNodes` of the strategy. */\nexport function asRouter<O extends object>(strategy: Strategy<\"router\", O>, options?: Partial<O>): Router {\n return {\n name: strategy.name,\n ...(strategy.maxNodes === undefined ? {} : { maxNodes: strategy.maxNodes }),\n route: (graph: Graph): Result => strategy.run(graph, options),\n };\n}\n\n/** This function gives the router strategies of a registry as `Router` objects, in order. The benchmark races them. */\nexport function routersOf(registry: Registry): Router[] {\n return listStrategies(registry, \"router\").map((s) => asRouter(s));\n}\n","import { arcCurve, type ArcOptions } from \"../curves/arc/index.ts\";\nimport { roundedCurve, type RoundedOptions } from \"../curves/rounded/index.ts\";\nimport { splineCurve, type SplineOptions } from \"../curves/spline/index.ts\";\nimport { straightCurve } from \"../curves/straight/index.ts\";\nimport type { Graph, Result, Router } from \"../model.ts\";\nimport { roomDemand, type RoomMethod, type RoomOptions } from \"../room/index.ts\";\nimport { cornersRouter, type CornersOptions } from \"../routers/corners.ts\";\nimport { plugsRouter } from \"../routers/plugs.ts\";\nimport { sectionsRouter, type SectionsOptions } from \"../routers/sections.ts\";\nimport { sharedRouter, type SharedOptions } from \"../routers/shared.ts\";\nimport { straightRouter } from \"../routers/straight.ts\";\nimport { byCollection, trunksRouter, type TrunksOptions } from \"../routers/trunks.ts\";\nimport { createRegistry, defineStrategy, type AnyStrategy, type CurveInput, type Registry, type Strategy } from \"./model.ts\";\n\n/** The options of a router strategy: the options of its router, without the name and the limit of the benchmark. */\nexport type RouterPreset<O> = Omit<O, \"name\" | \"maxNodes\">;\n\n/** This function makes a router strategy from a router factory and a preset of its options. Each call makes the router of its options. */\nfunction routerStrategy<O extends object>(\n name: string,\n describe: string,\n maxNodes: number,\n defaults: O,\n make: (options: O & { readonly name: string }) => Router,\n): Strategy<\"router\", O> {\n return defineStrategy({ step: \"router\", name, describe, defaults, maxNodes, run: (graph: Graph, options: Readonly<O>): Result => make({ ...options, name }).route(graph) });\n}\n\n/** This function makes a router strategy for a router without options. */\nfunction fixedRouter(router: Router, describe: string): Strategy<\"router\", object> {\n return defineStrategy({ step: \"router\", name: router.name, describe, defaults: {}, run: (graph: Graph): Result => router.route(graph) });\n}\n\n/** The built-in router strategies, in the order of the benchmark. They route as the routers of `ROUTERS`. */\nexport const routerStrategies: {\n readonly straight: Strategy<\"router\", object>;\n readonly plugs: Strategy<\"router\", object>;\n readonly corners: Strategy<\"router\", RouterPreset<CornersOptions>>;\n readonly \"corners-smooth\": Strategy<\"router\", RouterPreset<CornersOptions>>;\n readonly trunks: Strategy<\"router\", RouterPreset<TrunksOptions>>;\n readonly shared: Strategy<\"router\", RouterPreset<SharedOptions>>;\n readonly \"shared-all\": Strategy<\"router\", RouterPreset<SharedOptions>>;\n readonly sections: Strategy<\"router\", RouterPreset<SectionsOptions>>;\n readonly \"sections-tree\": Strategy<\"router\", RouterPreset<SectionsOptions>>;\n} = Object.freeze({\n straight: fixedRouter(straightRouter, \"The control. Each edge is one straight line between its plugs.\"),\n plugs: fixedRouter(\n plugsRouter,\n \"Each edge leaves its plug along the normal of the side and follows the curve of the inflection rule. It does not go around the nodes.\",\n ),\n corners: routerStrategy<RouterPreset<CornersOptions>>(\n \"corners\",\n \"Each edge goes around the nodes on a shortest path (A*) through a sparse visibility graph of the box corners.\",\n 10_000,\n {},\n cornersRouter,\n ),\n \"corners-smooth\": routerStrategy<RouterPreset<CornersOptions>>(\n \"corners-smooth\",\n \"The same paths as `corners`. A route in clear view follows the inflection rule, and the other routes get round corners.\",\n 10_000,\n { smooth: true },\n cornersRouter,\n ),\n trunks: routerStrategy<RouterPreset<TrunksOptions>>(\n \"trunks\",\n \"A rule puts edges in groups. The edges of a group leave one plug of one node on one trunk. At a split point, each edge goes on to its target.\",\n 10_000,\n { rule: byCollection },\n trunksRouter,\n ),\n shared: routerStrategy<RouterPreset<SharedOptions>>(\n \"shared\",\n \"The edges of one collection share their ways through the corner graph. A link that the group uses already costs half.\",\n 10_000,\n { rule: byCollection },\n sharedRouter,\n ),\n \"shared-all\": routerStrategy<RouterPreset<SharedOptions>>(\"shared-all\", \"The same as `shared`, but all edges share their ways.\", 10_000, {}, sharedRouter),\n sections: routerStrategy<RouterPreset<SectionsOptions>>(\n \"sections\",\n \"A tree of sections, with a hub in each section. A long edge goes through the hubs, and a short edge goes directly.\",\n 100_000,\n {},\n sectionsRouter,\n ),\n \"sections-tree\": routerStrategy<RouterPreset<SectionsOptions>>(\n \"sections-tree\",\n \"The same as `sections`, but without the limit of the stretch.\",\n 100_000,\n { stretch: Infinity },\n sectionsRouter,\n ),\n});\n\n/** The context of a curve input, without the keys that have no value. */\nconst contextOf = (input: CurveInput): Omit<CurveInput, \"points\"> => ({\n ...(input.startNormal ? { startNormal: input.startNormal } : {}),\n ...(input.endNormal ? { endNormal: input.endNormal } : {}),\n ...(input.space ? { space: input.space } : {}),\n});\n\n/** The options of the curve strategies `rounded` and `arc`. */\nexport interface RadiusOptions {\n /** The radius of the corners. The default is 12. */\n readonly radius: number;\n}\n\n/** The options of the curve strategy `spline`. */\nexport interface TensionOptions {\n /** The tension of the spline, from 0 (the spline) to 1 (the polyline). The default is 0. */\n readonly tension: number;\n}\n\n/** The built-in curve strategies, in the order of `CURVE_TYPES`. Each one gives the same segments as `curveOf` with its type. */\nexport const curveStrategies: {\n readonly straight: Strategy<\"curve\", object>;\n readonly rounded: Strategy<\"curve\", RadiusOptions>;\n readonly spline: Strategy<\"curve\", TensionOptions>;\n readonly arc: Strategy<\"curve\", RadiusOptions>;\n} = Object.freeze({\n straight: defineStrategy({ step: \"curve\", name: \"straight\", describe: \"The polyline as it is.\", defaults: {}, run: (input: CurveInput) => straightCurve(input.points) }),\n rounded: defineStrategy({\n step: \"curve\",\n name: \"rounded\",\n describe: \"A quadratic Bezier curve at each corner, as `roundCorners` draws it. The first and the last legs stay.\",\n defaults: { radius: 12 },\n run: (input: CurveInput, o: Readonly<RadiusOptions>) => roundedCurve(input.points, { ...contextOf(input), radius: o.radius } satisfies RoundedOptions),\n }),\n spline: defineStrategy({\n step: \"curve\",\n name: \"spline\",\n describe: \"A centripetal Catmull-Rom spline through each point. It does not overshoot or make loops in a piece.\",\n defaults: { tension: 0 },\n run: (input: CurveInput, o: Readonly<TensionOptions>) => splineCurve(input.points, { ...contextOf(input), tension: o.tension } satisfies SplineOptions),\n }),\n arc: defineStrategy({\n step: \"curve\",\n name: \"arc\",\n describe: \"A circular arc at each corner, tangent to the two legs. The first and the last legs stay.\",\n defaults: { radius: 12 },\n run: (input: CurveInput, o: Readonly<RadiusOptions>) => arcCurve(input.points, { ...contextOf(input), radius: o.radius } satisfies ArcOptions),\n }),\n});\n\n/** The options of a room strategy: the options of `roomDemand`, without the method. */\nexport type RoomPreset = Omit<RoomOptions, \"method\">;\n\nconst roomStrategy = (method: RoomMethod, describe: string): Strategy<\"room\", RoomPreset> =>\n defineStrategy<\"room\", RoomPreset>({ step: \"room\", name: method, describe, defaults: {}, run: (input, o) => roomDemand(input.items, input.links, { ...o, method }) });\n\n/** The built-in room strategies: the methods of `roomDemand`. */\nexport const roomStrategies: {\n readonly routes: Strategy<\"room\", RoomPreset>;\n readonly lines: Strategy<\"room\", RoomPreset>;\n} = Object.freeze({\n routes: roomStrategy(\"routes\", \"The lanes of a gap are the most routes that run along it side by side, with each gap open to the gutter.\"),\n lines: roomStrategy(\"lines\", \"The lanes of a gap are the straight lines between the centers of the boxes that cross the gap.\"),\n});\n\n/** The built-in strategies of each step, in order. A consumer adds its own: `createRegistry([...BUILT_IN_STRATEGIES, mine])`. */\nexport const BUILT_IN_STRATEGIES: readonly AnyStrategy[] = Object.freeze([\n ...Object.values(routerStrategies),\n ...Object.values(curveStrategies),\n ...Object.values(roomStrategies),\n]);\n\n/** The registry of the built-in strategies. The benchmark and the site take their lists from it. */\nexport const STRATEGIES: Registry = createRegistry(BUILT_IN_STRATEGIES);\n","import { CURVE_TYPES, curveSpace, sampleCurve, type CurveType } from \"../curves/index.ts\";\nimport { polylineLength } from \"../geom.ts\";\nimport { nodeIndex, type Graph, type Router } from \"../model.ts\";\nimport { nearestSide, SIDE_NORMAL } from \"../plugs.ts\";\nimport { curveStrategies } from \"../strategies/builtins.ts\";\nimport type { Strategy } from \"../strategies/model.ts\";\nimport { measureLinks, type MeasuredLink } from \"./links.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/**\n * One row of the benchmark of the curves: one curve type on the routes of one router on one fixture.\n * The type `T` of the name of the curve is `CurveType` for `benchCurves`, and `string` for `benchCurveStrategies`.\n */\nexport interface CurveBenchRow<T extends string = CurveType> {\n readonly router: string;\n readonly fixture: string;\n readonly type: T;\n /** The number of routes. */\n readonly links: number;\n /** The number of polylines that go through a box that is not one of their ends (`measureLinks`). */\n readonly through: number;\n /** The number of curves without a free space that go through such a box. */\n readonly free: number;\n /** The number of curves with the free space of the nodes (`curveSpace`) that go through such a box. */\n readonly clamped: number;\n /** The ratio of the length of all curves with the free space to the length of all polylines. */\n readonly length: number;\n /** The time to make all curves with the free space, in milliseconds. */\n readonly ms: number;\n}\n\n/** The options of `benchCurves`. */\nexport interface CurveBenchOptions {\n /** The radius of the types `rounded` and `arc`. The default is 12. */\n readonly radius?: number;\n /** The tolerance of the samples of the curves. The default is 0.25. */\n readonly tolerance?: number;\n}\n\n/**\n * This function routes a graph with a router and makes each curve type of each route.\n * It counts the curves that go through a box, with and without the free space, and it compares their length to the polylines.\n * The type `spline` leaves each plug along the normal of the nearest side of its node.\n */\nexport function benchCurves(router: Router, fixture: string, graph: Graph, options: CurveBenchOptions = {}): CurveBenchRow[] {\n // Each built-in curve strategy has the name of its curve type, so each row has a `CurveType`.\n return benchCurveStrategies(\n router,\n fixture,\n graph,\n CURVE_TYPES.map((t) => curveStrategies[t]),\n options,\n ) as CurveBenchRow[];\n}\n\n/**\n * This function does the work of `benchCurves` with a list of curve strategies, in place of the curve types.\n * The option `radius` goes to each strategy. A strategy without such an option does not read it.\n */\nexport function benchCurveStrategies(\n router: Router,\n fixture: string,\n graph: Graph,\n curves: readonly Strategy<\"curve\">[],\n options: CurveBenchOptions = {},\n): CurveBenchRow<string>[] {\n const tolerance = options.tolerance ?? 0.25;\n const result = router.route(graph);\n const byId = nodeIndex(graph);\n const boxes = new Map(graph.nodes.map((n) => [n.id, n.box]));\n const edges = new Map(graph.edges.map((e) => [e.id, e]));\n const space = curveSpace(\n graph.nodes.map((n) => n.box),\n tolerance,\n );\n const routes = result.routes.flatMap((r) => {\n const e = edges.get(r.edge);\n const s = e && byId.get(e.source.node);\n const t = e && byId.get(e.target.node);\n if (!e || !s || !t || r.points.length < 2) return [];\n const first = r.points[0]!;\n const last = r.points[r.points.length - 1]!;\n return [{ source: s.id, target: t.id, points: r.points, startNormal: SIDE_NORMAL[nearestSide(s.box, first)], endNormal: SIDE_NORMAL[nearestSide(t.box, last)] }];\n });\n const base = measureLinks(boxes, routes);\n const ink = routes.reduce((sum, r) => sum + polylineLength(r.points), 0);\n const radius = { radius: options.radius ?? 12 };\n return curves.map((curve): CurveBenchRow<string> => {\n const make = (withSpace: boolean): MeasuredLink[] =>\n routes.map((r) => ({\n source: r.source,\n target: r.target,\n points: sampleCurve(\n curve.run({ points: r.points, startNormal: r.startNormal, endNormal: r.endNormal, ...(withSpace ? { space } : {}) }, radius),\n tolerance,\n ),\n }));\n const free = measureLinks(boxes, make(false));\n const t0 = now();\n const clamped = make(true);\n const ms = now() - t0;\n const length = clamped.reduce((sum, l) => sum + polylineLength(l.points), 0);\n return {\n router: router.name,\n fixture,\n type: curve.name,\n links: routes.length,\n through: base.through,\n free: free.through,\n clamped: measureLinks(boxes, clamped).through,\n length: ink > 0 ? length / ink : 1,\n ms,\n };\n });\n}\n\n/** This function writes the rows of `benchCurves` as a Markdown table. */\nexport function formatCurves(rows: readonly CurveBenchRow<string>[]): string {\n const head = \"| router | fixture | curve | routes | through, polyline | through, free | through, clamped | length | ms |\";\n const line = \"|---|---|---|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map((r) => `| ${r.router} | ${r.fixture} | ${r.type} | ${r.links} | ${r.through} | ${r.free} | ${r.clamped} | ${r.length.toFixed(3)} | ${r.ms.toFixed(1)} |`);\n return [head, line, ...body].join(\"\\n\");\n}\n","import { levelLinks } from \"../levels.ts\";\nimport type { Graph, Node, Result } from \"../model.ts\";\nimport { makeRoom, openGaps, roomLinks, type RoomOptions } from \"../room/index.ts\";\nimport { gapLanes, LANE_ORDERS, type LaneOrder } from \"../room/lanes.ts\";\nimport { sectionsRouter } from \"../routers/sections.ts\";\nimport { laneRoutes, runKey, segmentsOf } from \"../segments.ts\";\nimport { roomStrategies } from \"../strategies/builtins.ts\";\nimport type { Strategy } from \"../strategies/model.ts\";\nimport { measureLinks, measureRouteFaults, type LinkFaults } from \"./links.ts\";\nimport { measureQuality } 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 of the room: one state of a board, packed or open, and the measures of its links. */\nexport interface RoomBenchRow {\n readonly fixture: string;\n /** The state of the board: `packed`, `gutter` (each gap open to the gutter only), or a method of `roomDemand`. */\n readonly board: string;\n /** The area of the bounding box of the boxes, as a share of the area of the packed board. */\n readonly area: number;\n /** The faults of the links of the far view (`levelLinks` with each box as one item). */\n readonly faults: LinkFaults;\n /** The crossings of the links of the far view (`measureQuality`). */\n readonly crossings: number;\n /** The ink of the links of the far view. */\n readonly ink: number;\n /** The mean detour of the links of the far view. */\n readonly detour: number;\n /**\n * The number of lane routes of the router `sections` that go through a box. Each shared segment opens to one lane for each edge,\n * at the spacing of the options (`laneRoutes`).\n */\n readonly laneThrough: number;\n /** The time of `makeRoom`, in milliseconds. It is 0 for the packed board. */\n readonly ms: number;\n}\n\n/** This function gives the area of the bounding box of the nodes. */\nfunction areaOf(nodes: readonly Node[]): number {\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 return nodes.length ? (x1 - x0) * (y1 - y0) : 0;\n}\n\n/**\n * This function measures the links of one board. It measures the links of the far view, with each node of the graph as one item of a level.\n * With a lane order, each link of the far view gets its own lane in each gap (`gapLanes` at the lane width `spacing`).\n * Without it, the links of a gap share the lines of the level links.\n * The function also measures the lane routes of the router `sections` at the lane width `spacing`.\n */\nexport function measureBoard(graph: Graph, spacing: number, order?: LaneOrder): Omit<RoomBenchRow, \"fixture\" | \"board\" | \"area\" | \"ms\"> {\n const links = roomLinks(graph);\n const items = graph.nodes.map((n) => ({ id: n.id, box: n.box, nodes: [n.id] }));\n const level = levelLinks(\n items,\n links.map((l) => ({ source: l.source, target: l.target, count: l.count ?? 1 })),\n );\n const drawn = order ? gapLanes(graph.nodes, level, { spacing, order }) : level;\n const boxes = new Map(graph.nodes.map((n) => [n.id, n.box]));\n // `measureQuality` reads routes of edges, so each link of the far view stands for the first edge of its pair.\n const edgeOf = new Map<string, string>();\n for (const e of graph.edges) {\n const key = `${e.source.node}\\u0000${e.target.node}`;\n if (!edgeOf.has(key)) edgeOf.set(key, e.id);\n }\n const asRoutes: Result = { routes: drawn.map((l) => ({ edge: edgeOf.get(`${l.source}\\u0000${l.target}`)!, points: l.points })) };\n const q = measureQuality(graph, asRoutes);\n const routed = sectionsRouter({ name: \"sections\" }).route(graph);\n const segments = segmentsOf(routed);\n const open = new Set(segments.segments.filter((s) => s.count > 1).map((s) => runKey(s.edges)));\n const lanes = laneRoutes(segments, open, spacing);\n return {\n faults: measureLinks(boxes, drawn),\n crossings: q.crossings,\n ink: q.ink,\n detour: q.detour,\n laneThrough: measureRouteFaults(graph, { routes: lanes }).through,\n };\n}\n\n/**\n * This function measures a packed board, the board with each gap open to the gutter only, and the board that each room strategy opens.\n * The options are the same for each strategy, except `method`. The default strategies are the methods `routes` and `lines` of `roomDemand`.\n */\nexport function benchRoom(\n fixture: string,\n graph: Graph,\n options: RoomOptions = {},\n methods: readonly Strategy<\"room\">[] = [roomStrategies.routes, roomStrategies.lines],\n): RoomBenchRow[] {\n const spacing = options.spacing ?? 4;\n const area0 = areaOf(graph.nodes);\n const links = roomLinks(graph);\n const row = (board: string, nodes: readonly Node[], ms: number): RoomBenchRow => ({\n fixture,\n board,\n area: area0 > 0 ? areaOf(nodes) / area0 : 1,\n ms,\n ...measureBoard({ nodes, edges: graph.edges }, spacing),\n });\n const rows = [row(\"packed\", graph.nodes, 0)];\n const t0 = now();\n const gutter = makeRoom(graph.nodes, links, { ...options, spacing: 0, method: \"routes\" });\n rows.push(row(\"gutter\", gutter.items, now() - t0));\n const { method: _method, ...preset } = options;\n for (const s of methods) {\n const t1 = now();\n const gaps = s.run({ items: graph.nodes, links }, preset);\n const nodes = openGaps(graph.nodes, gaps, options.snap);\n rows.push(row(s.name, nodes, now() - t1));\n }\n return rows;\n}\n\n/** One setting of a sweep of the room: the options of `makeRoom` and the lane order of the far view. */\nexport interface RoomSetting {\n /** The name of the setting in the column `board`. */\n readonly name: string;\n readonly options: RoomOptions;\n /** The lane order of the far view. Without it, the links of a gap share the lines of the level links. */\n readonly lanes?: LaneOrder;\n}\n\n/**\n * This function measures the board that `makeRoom` opens with each setting, with the method `routes`.\n * The first row is the fair baseline: the board with each gap open to the gutter of `baseline` only, measured at the spacing of `baseline`.\n */\nexport function sweepRoom(fixture: string, graph: Graph, settings: readonly RoomSetting[], baseline: RoomOptions = { gutter: 8, spacing: 4 }): RoomBenchRow[] {\n const area0 = areaOf(graph.nodes);\n const links = roomLinks(graph);\n const row = (board: string, nodes: readonly Node[], ms: number, spacing: number, lanes?: LaneOrder): RoomBenchRow => ({\n fixture,\n board,\n area: area0 > 0 ? areaOf(nodes) / area0 : 1,\n ms,\n ...measureBoard({ nodes, edges: graph.edges }, spacing, lanes),\n });\n const fair = makeRoom(graph.nodes, links, { ...baseline, spacing: 0, method: \"routes\", maxGrowth: Infinity, passes: 1 });\n const rows = [row(\"gutter\", fair.items, 0, baseline.spacing ?? 4)];\n for (const s of settings) {\n const t0 = now();\n const open = makeRoom(graph.nodes, links, { ...s.options, method: \"routes\" });\n rows.push(row(s.name, open.items, now() - t0, s.options.spacing ?? 4, s.lanes));\n }\n return rows;\n}\n\n/** The values of `maxGrowth` of the sweep of ROOM-A. */\nexport const GROWTH_SWEEP: readonly number[] = [0, 0.06, 0.09, 0.12, 0.15, 0.18, 0.21, 0.25, 0.3, 0.35, 0.5, Infinity];\n\n/** This function gives the settings of ROOM-A: the area and the faults for each `maxGrowth`, at gutter 8 and spacing 4. */\nexport function growthSettings(values: readonly number[] = GROWTH_SWEEP): RoomSetting[] {\n return values.map((m) => ({ name: `maxGrowth ${m}`, options: { gutter: 8, spacing: 4, maxGrowth: m } }));\n}\n\n/**\n * This function gives the settings of ROOM-C: each lane order of the far view at each spacing, at gutter 8.\n * The order `shared` is the far view without lanes, as before ROOM-C.\n */\nexport function laneSettings(spacings: readonly number[] = [2, 4, 6, 8], orders: readonly LaneOrder[] = LANE_ORDERS): RoomSetting[] {\n return spacings.flatMap((spacing) => [\n { name: `shared spacing ${spacing}`, options: { gutter: 8, spacing } },\n ...orders.map((lanes) => ({ name: `${lanes} spacing ${spacing}`, options: { gutter: 8, spacing }, lanes })),\n ]);\n}\n\n/** This function gives the settings of ROOM-D: each gutter with each number of passes, at spacing 4. */\nexport function passSettings(gutters: readonly number[] = [4, 8, 12, 16], passes: readonly number[] = [1, 2]): RoomSetting[] {\n return gutters.flatMap((gutter) => passes.map((p) => ({ name: `gutter ${gutter} passes ${p}`, options: { gutter, spacing: 4, passes: p } })));\n}\n\n/** This function writes the rows of `benchRoom` as a Markdown table. */\nexport function formatRoom(rows: readonly RoomBenchRow[]): string {\n const head = \"| fixture | board | area | links | through | outside | out and back | worst detour | crossings | ink | detour | lane through | ms |\";\n const line = \"|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map((r) => {\n const f = r.faults;\n return `| ${r.fixture} | ${r.board} | ${r.area.toFixed(3)} | ${f.links} | ${f.through} | ${f.outside} | ${f.backtrack} | ${f.worstDetour.toFixed(2)} | ${r.crossings} | ${Math.round(r.ink)} | ${r.detour.toFixed(3)} | ${r.laneThrough} | ${r.ms.toFixed(1)} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["orient","SIDES","FLAT","FLAT","cross","SAME","turn","FLAT","SAME","SPIKE","STEPS","along","turnOf","hits","SHRINK","EPS","dedupe","meanSide","DEFAULT_SNAP","EPS","cost","EXACT_CROSSINGS","SAMPLE","key","now","now","medianOf","now","areaOf","now"],"sources":["../src/geom.ts","../src/grid.ts","../src/model.ts","../src/fixtures.ts","../src/cases.ts","../src/plugs.ts","../src/curves.ts","../src/curves/model.ts","../src/bench/properties.ts","../src/curves/sample.ts","../src/curves/space.ts","../src/curves/arc/index.ts","../src/curves/corner.ts","../src/curves/fit.ts","../src/curves/clothoid/index.ts","../src/curves/rounded/index.ts","../src/curves/smooth/index.ts","../src/curves/spline/index.ts","../src/curves/straight/index.ts","../src/segments.ts","../src/curves/highway/index.ts","../src/curves/index.ts","../src/visibility.ts","../src/ways.ts","../src/sections.ts","../src/groups/quadtree/index.ts","../src/groups/keys/index.ts","../src/groups/kd/index.ts","../src/groups/cut/index.ts","../src/pick.ts","../src/routers/corners.ts","../src/routers/plugs.ts","../src/bench/links.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/room/bends.ts","../src/room/index.ts","../src/room/lanes.ts","../src/room/levels/index.ts","../src/bench/quality.ts","../src/bench/run.ts","../src/strategies/model.ts","../src/strategies/schemas.ts","../src/strategies/builtins.ts","../src/bench/measures/curves.ts","../src/bench/curves.ts","../src/bench/room.ts","../src/bench/sections.ts","../src/bench/measures/stats.ts","../src/bench/measures/routes.ts","../src/bench/measures/bundles.ts","../src/bench/measures/levels.ts","../src/bench/measures/groups.ts","../src/bench/measures/stability.ts","../src/bench/measures/room.ts","../src/bench/measures/pareto.ts","../src/bench/suite.ts","../src/strategies/options.ts","../src/bench/compare.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 /**\n * This method gives each item in the buckets along the segment `ab`, widened by `margin`, to `visit`, one time each.\n * The buckets are those of `#segment`, in the same order, so the items come in the same order.\n * A bucket in the range of the step before has no new item, so the walk skips it.\n * The walk stops when `visit` gives true, and then the method gives true.\n */\n #walk(a: Point, b: Point, margin: number, visit: (item: T) => boolean | void): boolean {\n const stamp = ++this.#stamp;\n const c = this.#cell;\n const items = this.#items;\n const n = Math.max(1, Math.ceil(Math.hypot(b.x - a.x, b.y - a.y) / (c / 2)));\n let px = a.x;\n let py = a.y;\n // The bucket range of the step before. The first step has none.\n let pi0 = 1;\n let pi1 = 0;\n let pj0 = 1;\n let pj1 = 0;\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 const i0 = Math.floor((Math.min(px, qx) - margin) / c);\n const j0 = Math.floor((Math.min(py, qy) - margin) / c);\n const i1 = Math.floor((Math.max(px, qx) + margin) / c);\n const j1 = Math.floor((Math.max(py, qy) + margin) / c);\n // A visit can add an item and so replace the array of stamps. Each step reads it again, as `#take` does.\n const seen = this.#seen;\n for (let i = i0; i <= i1; i++) {\n const before = i >= pi0 && i <= pi1;\n for (let j = j0; j <= j1; j++) {\n if (before && j >= pj0 && j <= pj1) continue;\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 if (visit(items[id]!) === true) return true;\n }\n }\n }\n pi0 = i0;\n pi1 = i1;\n pj0 = j0;\n pj1 = j1;\n px = qx;\n py = qy;\n }\n return false;\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 this.#walk(a, b, margin, (item) => {\n visit(item);\n });\n }\n\n /**\n * This method tells if `test` gives true for an item whose buckets come within `margin` of the segment `ab`.\n * It gives the items in the order of `querySegment`, and it stops at the first item that passes the test.\n */\n someSegment(a: Point, b: Point, margin: number, test: (item: T) => boolean): boolean {\n return this.#walk(a, b, margin, test);\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 /** This data is free for the grouping rules of the nodes. The rule `keys` reads the string `data.group` by default. */\n readonly data?: Readonly<Record<string, unknown>>;\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 { makeFixture, rng } from \"./fixtures.ts\";\nimport type { Edge, Graph, Node } from \"./model.ts\";\n\n/**\n * A board of made-up data that shows one known defect of the routes or of the zoom levels.\n * The benchmark races the routers on each case, and the measures of `measureLinks` give a number for the defect.\n */\nexport interface CaseBoard {\n readonly name: string;\n /** The defect that the board shows, in a few words. */\n readonly defect: string;\n /** This function makes the graph. The same function always gives the same graph. */\n readonly make: () => Graph;\n}\n\n/** A board while it grows: the functions add nodes and edges in order. */\nclass Board {\n readonly nodes: Node[] = [];\n readonly edges: Edge[] = [];\n readonly #pairs = new Set<string>();\n\n node(id: string, x: number, y: number, w: number, h: number): string {\n this.nodes.push({ id, box: { x, y, w, h } });\n return id;\n }\n\n /** This method adds an edge. It adds nothing for a loop or for a second edge between the same two nodes. */\n link(source: string, target: string): void {\n const key = source < target ? `${source}|${target}` : `${target}|${source}`;\n if (source === target || this.#pairs.has(key)) return;\n this.#pairs.add(key);\n this.edges.push({ id: `e${this.edges.length}`, source: { node: source }, target: { node: target } });\n }\n\n graph(): Graph {\n return { nodes: this.nodes, edges: this.edges };\n }\n}\n\n/**\n * This function makes a dense board: 150 nodes in tight clusters. At the far view, the boxes of the groups overlap.\n * Then a level link starts or ends in a group that another group covers.\n */\nexport function denseGroupsBoard(): Graph {\n return makeFixture({ name: \"dense-groups\", kind: \"clustered\", nodes: 150, edgesPerNode: 2, seed: 3 });\n}\n\n/**\n * This function makes a board of three rows of 32 cards. Each card links to the next card of its row.\n * Forty long links join cards far apart. The hub of a section is near the middle of its cards.\n * So a long link climbs to hubs behind its source or past its target, and comes back.\n */\nexport function hubChainBoard(): Graph {\n const R = rng(3);\n const b = new Board();\n const rows = 3;\n const cols = 32;\n const gap = 48;\n const id = (r: number, c: number): string => `c${r}-${c}`;\n for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) b.node(id(r, c), c * (80 + gap), r * (36 + gap), 80, 36);\n for (let r = 0; r < rows; r++) for (let c = 0; c + 1 < cols; c++) b.link(id(r, c), id(r, c + 1));\n for (let n = 0; n < 40; n++) {\n const r = Math.floor(R() * rows);\n const c = Math.floor(R() * cols);\n const span = Math.floor(cols / 8 + (R() * cols) / 2);\n if (c + span < cols) b.link(id(r, c), id((r + 1) % rows, c + span));\n }\n return b.graph();\n}\n\n/**\n * This function makes a board of 32 groups in 8 columns and 4 rows. Each group has 4 cards in a square.\n * The cards of a group link in a chain, and 96 random links join cards of two groups.\n * On a level with many groups, some level links go around the outer edge of the board.\n */\nexport function manyGroupsBoard(): Graph {\n const R = rng(7);\n const b = new Board();\n const cols = 8;\n const rows = 4;\n const per = 4;\n const w = 60;\n const h = 30;\n const cardGap = 12;\n const groupGap = 60;\n const side = Math.ceil(Math.sqrt(per));\n const gw = side * w + (side - 1) * cardGap;\n const gh = Math.ceil(per / side) * h + (Math.ceil(per / side) - 1) * cardGap;\n const groups: string[][] = [];\n for (let r = 0; r < rows; r++)\n for (let c = 0; c < cols; c++) {\n const list: string[] = [];\n for (let i = 0; i < per; i++) {\n const x = c * (gw + groupGap) + (i % side) * (w + cardGap);\n const y = r * (gh + groupGap) + Math.floor(i / side) * (h + cardGap);\n list.push(b.node(`g${r}-${c}-${i}`, x, y, w, h));\n }\n groups.push(list);\n }\n for (const list of groups) for (let i = 1; i < list.length; i++) b.link(list[i - 1]!, list[i]!);\n const pick = (list: readonly string[]): string => list[Math.floor(R() * list.length)]!;\n for (let n = 0; n < groups.length * 3; n++) b.link(pick(groups[Math.floor(R() * groups.length)]!), pick(groups[Math.floor(R() * groups.length)]!));\n return b.graph();\n}\n\n/** The options of `packedGridBoard`. */\nexport interface PackedGridOptions {\n /** The seed of the links. The default is 11. */\n readonly seed?: number;\n /** The number of columns. The default is 12. */\n readonly cols?: number;\n /** The number of rows. The default is 8. */\n readonly rows?: number;\n /** The number of long links between boxes far apart. The default is 48. */\n readonly long?: number;\n}\n\n/**\n * This function makes the far view of a board after a host layout packs it.\n * The board has 96 boxes of one size in a grid of 12 columns and 8 rows.\n * The boxes touch, with no gap between them. Each box links to a box near it, and 48 long links join boxes far apart.\n * The links have no channel between the boxes. The roadmap item ROOM measures this board before and after `makeRoom`.\n *\n * The board is not in `CASES`, because the digests of the router fix the output on each board of `CASES`.\n * The options make a family of such boards for the measure suite. Without options, the board does not change.\n */\nexport function packedGridBoard(options: PackedGridOptions = {}): Graph {\n const R = rng(options.seed ?? 11);\n const b = new Board();\n const cols = options.cols ?? 12;\n const rows = options.rows ?? 8;\n const long = options.long ?? 48;\n const w = 140;\n const h = 90;\n const id = (r: number, c: number): string => `p${r}-${c}`;\n for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) b.node(id(r, c), c * w, r * h, w, h);\n const step = (): number => Math.floor(R() * 5) - 2;\n for (let r = 0; r < rows; r++)\n for (let c = 0; c < cols; c++) {\n const rr = Math.max(0, Math.min(rows - 1, r + step()));\n const cc = Math.max(0, Math.min(cols - 1, c + step()));\n b.link(id(r, c), id(rr, cc));\n }\n for (let n = 0; n < long; n++) b.link(id(Math.floor(R() * rows), Math.floor(R() * cols)), id(Math.floor(R() * rows), Math.floor(R() * cols)));\n return b.graph();\n}\n\n/**\n * This function makes a packed board with three zoom levels of groups. The board has 256 touching boxes in a grid of 16 columns and 16 rows.\n * The quadtree of `buildSections` splits it into 4, 16 and 64 groups. Each box links to a box near it, and 64 long links join boxes far apart.\n * At each level, the boxes of the groups touch, so the level links have no channel. The roadmap item ROOM2 measures this board.\n *\n * The board is not in `CASES`, because the digests of the router fix the output on each board of `CASES`.\n */\nexport function nestedGridBoard(): Graph {\n const R = rng(13);\n const b = new Board();\n const side = 16;\n const w = 120;\n const h = 80;\n const id = (r: number, c: number): string => `n${r}-${c}`;\n for (let r = 0; r < side; r++) for (let c = 0; c < side; c++) b.node(id(r, c), c * w, r * h, w, h);\n const step = (): number => Math.floor(R() * 5) - 2;\n const clamp = (v: number): number => Math.max(0, Math.min(side - 1, v));\n for (let r = 0; r < side; r++) for (let c = 0; c < side; c++) b.link(id(r, c), id(clamp(r + step()), clamp(c + step())));\n for (let n = 0; n < 64; n++) b.link(id(Math.floor(R() * side), Math.floor(R() * side)), id(Math.floor(R() * side), Math.floor(R() * side)));\n return b.graph();\n}\n\n/** The case boards of the benchmark. Each board has a few hundred nodes at most, so the benchmark races them on each run. */\nexport const CASES: readonly CaseBoard[] = [\n { name: \"case-dense-groups\", defect: \"Groups overlap at the far view, and level links go through other groups.\", make: denseGroupsBoard },\n { name: \"case-hub-chain\", defect: \"A route climbs a chain of hubs away from its target and comes back.\", make: hubChainBoard },\n { name: \"case-many-groups\", defect: \"On a level with many groups, links go around the outer edge of the board.\", make: manyGroupsBoard },\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 type { Point } from \"../geom.ts\";\n\n/**\n * A type of curve for a route.\n *\n * - `straight`: the polyline as it is.\n * - `rounded`: a quadratic Bezier curve at each corner, as `roundCorners` draws it.\n * - `spline`: a centripetal Catmull-Rom spline through the points. It does not overshoot or make loops.\n * - `arc`: a circular arc at each corner, tangent to the two legs.\n * - `smooth`: a cubic spiral, an arc and a second cubic spiral at each corner, as the corner smoothing of Figma.\n * - `clothoid`: a clothoid, an arc and a second clothoid at each corner, as a transition curve of a road.\n */\nexport type CurveType = \"straight\" | \"rounded\" | \"spline\" | \"arc\" | \"smooth\" | \"clothoid\";\n\n/** The curve types, in the order of the benchmark. */\nexport const CURVE_TYPES: readonly CurveType[] = [\"straight\", \"rounded\", \"spline\", \"arc\", \"smooth\", \"clothoid\"];\n\n/** The start of a curve: the pen goes to `to` and draws nothing. */\nexport interface MoveSegment {\n readonly kind: \"move\";\n readonly to: Point;\n}\n\n/** A straight line from the end of the segment before to `to`. */\nexport interface LineSegment {\n readonly kind: \"line\";\n readonly to: Point;\n}\n\n/** A cubic Bezier curve from the end of the segment before to `to`, with the control points `c1` and `c2`. */\nexport interface CubicSegment {\n readonly kind: \"cubic\";\n readonly c1: Point;\n readonly c2: Point;\n readonly to: Point;\n}\n\n/**\n * A circular arc from the end of the segment before to `to`. The arc has its center at `center` and the radius `radius`.\n * It starts at the angle `start` and turns by `sweep` radians. A positive `sweep` turns from the x axis to the y axis.\n * On a canvas, `ctx.arc(center.x, center.y, radius, start, start + sweep, sweep < 0)` draws it.\n */\nexport interface ArcSegment {\n readonly kind: \"arc\";\n readonly center: Point;\n readonly radius: number;\n readonly start: number;\n readonly sweep: number;\n readonly to: Point;\n}\n\n/**\n * A segment of a curve. A curve is a list of segments: one `move` first, then lines, cubic curves and arcs.\n * A renderer maps the list to SVG path data, to canvas calls or to the vertices of a mesh.\n */\nexport type CurveSegment = MoveSegment | LineSegment | CubicSegment | ArcSegment;\n\n/** This function gives the points of a polyline without the points that are nearer than `eps` to the point before them. */\nexport function distinctPoints(points: readonly Point[], eps = 1e-9): Point[] {\n const out: Point[] = [];\n for (const p of points) {\n const q = out[out.length - 1];\n if (q === undefined || Math.hypot(p.x - q.x, p.y - q.y) > eps) out.push(p);\n }\n return out;\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 Level, 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 out.push(...checkLevels(graph, result.levels ?? [], limit - out.length));\n return out;\n}\n\n/**\n * This function checks the hard rules of the zoom levels. The counts of each level add up (`counts-sum`).\n * Each link of a level starts on the box of its source and ends on the box of its target (`link-ends`).\n * The function gives at most `limit` violations.\n */\nexport function checkLevels(graph: Graph, levels: readonly Level[], limit = 100): Violation[] {\n const out: Violation[] = [];\n const add = (v: Violation): boolean => {\n out.push(v);\n return out.length >= limit;\n };\n if (limit <= 0) return out;\n for (const level of 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 type { Point } from \"../geom.ts\";\nimport type { CurveSegment } from \"./model.ts\";\n\n/** The largest number of points that `sampleCurve` gives for one segment. */\nconst MAX_STEPS = 1024;\n\n/**\n * This function gives a polyline that follows the curve. The distance from each part of the curve to the polyline is `tolerance` or less.\n * The polyline starts at the point of the `move` and goes through the end of each segment.\n * Hit tests, measures and renderers that draw only lines use this polyline.\n */\nexport function sampleCurve(segments: readonly CurveSegment[], tolerance = 0.5): Point[] {\n const tol = Math.max(1e-6, tolerance);\n const out: Point[] = [];\n let at: Point | undefined;\n for (const s of segments) {\n if (s.kind === \"move\" || at === undefined) {\n out.push(s.to);\n at = s.to;\n continue;\n }\n if (s.kind === \"cubic\") {\n // The chord of a step of 1/n of the parameter is within 3·D/(4·n²) of the curve. D is the largest second difference of the control points.\n const d = Math.max(\n Math.hypot(at.x - 2 * s.c1.x + s.c2.x, at.y - 2 * s.c1.y + s.c2.y),\n Math.hypot(s.c1.x - 2 * s.c2.x + s.to.x, s.c1.y - 2 * s.c2.y + s.to.y),\n );\n const n = Math.min(MAX_STEPS, Math.max(1, Math.ceil(Math.sqrt((3 * d) / (4 * tol)))));\n for (let k = 1; k < n; k++) out.push(cubicAt(at, s.c1, s.c2, s.to, k / n));\n } else if (s.kind === \"arc\") {\n // The chord of an angle φ is within r·(1 - cos(φ/2)) of the arc.\n const step = s.radius <= tol ? Math.PI : 2 * Math.acos(1 - tol / s.radius);\n const n = Math.min(MAX_STEPS, Math.max(1, Math.ceil(Math.abs(s.sweep) / step)));\n for (let k = 1; k < n; k++) {\n const a = s.start + (s.sweep * k) / n;\n out.push({ x: s.center.x + s.radius * Math.cos(a), y: s.center.y + s.radius * Math.sin(a) });\n }\n }\n out.push(s.to);\n at = s.to;\n }\n return out;\n}\n\n/** This function gives the point at the parameter `t` of the cubic Bezier curve with the control points `p0`, `p1`, `p2` and `p3`. */\nexport function cubicAt(p0: Point, p1: Point, p2: Point, p3: Point, t: number): Point {\n const u = 1 - t;\n const a = u * u * u;\n const b = 3 * u * u * t;\n const c = 3 * u * t * t;\n const d = t * t * t;\n return { x: a * p0.x + b * p1.x + c * p2.x + d * p3.x, y: a * p0.y + b * p1.y + c * p2.y + d * p3.y };\n}\n\n/**\n * This function writes the segments as the data of an SVG path: the commands `M`, `L`, `C` and `A`.\n * Each number has at most `digits` digits after the point.\n */\nexport function toSvgPath(segments: readonly CurveSegment[], digits = 2): string {\n const n = (v: number): string => {\n const s = String(Number(v.toFixed(digits)));\n return s === \"-0\" ? \"0\" : s;\n };\n const p = (q: Point): string => `${n(q.x)} ${n(q.y)}`;\n const parts: string[] = [];\n for (const s of segments) {\n if (s.kind === \"move\") parts.push(`M ${p(s.to)}`);\n else if (s.kind === \"line\") parts.push(`L ${p(s.to)}`);\n else if (s.kind === \"cubic\") parts.push(`C ${p(s.c1)} ${p(s.c2)} ${p(s.to)}`);\n else parts.push(`A ${n(s.radius)} ${n(s.radius)} 0 ${Math.abs(s.sweep) > Math.PI ? 1 : 0} ${s.sweep > 0 ? 1 : 0} ${p(s.to)}`);\n }\n return parts.join(\" \");\n}\n","import { TOLERANCE } from \"../bench/properties.ts\";\nimport { inflate, segmentHitsBox, type Box, type Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport type { CurveSegment } from \"./model.ts\";\nimport { sampleCurve } from \"./sample.ts\";\n\n/**\n * The free space of a board: the boxes that a curve must not go through.\n * Make it one time for a board with `curveSpace`, and give it to each call of `curveOf`.\n */\nexport interface CurveSpace {\n /** The boxes of the board. */\n readonly boxes: readonly Box[];\n /** The tolerance of the samples of a curve, in units of the plane. */\n readonly tolerance: number;\n /**\n * This method tells if the polyline `q` goes through a box that the polyline `p` does not go through.\n * A polyline goes through a box when a part of it longer than `TOLERANCE` is inside the box made smaller by `TOLERANCE`.\n */\n addsHit(q: readonly Point[], p: readonly Point[]): boolean;\n /**\n * This method tells if the triangle `(a, v, b)` overlaps a box that the polyline `(a, v, b)` does not go through.\n * A convex corner from `a` to `b` stays in this triangle, so a clear triangle proves a clear corner with no samples.\n * The method is optional. Without it, a corner samples its curve.\n */\n addsHitTriangle?(a: Point, v: Point, b: Point): boolean;\n}\n\n/**\n * This function makes the free space of a board from its boxes. The boxes are the nodes, or the items of a zoom level.\n * The curves sample each piece within `tolerance` of the curve for the test.\n */\nexport function curveSpace(boxes: readonly Box[], tolerance = 0.25): CurveSpace {\n const inner = boxes.map((b) => inflate(b, -TOLERANCE));\n let size = 0;\n for (const b of boxes) size += Math.max(b.w, b.h);\n // The buckets grow with the boxes, as the buckets of `measureLinks` do.\n const grid = new Grid<number>(Math.max(180, (2 * size) / Math.max(1, boxes.length)));\n inner.forEach((b, i) => grid.add(i, b));\n const hits = (p: readonly Point[]): Set<number> => {\n const out = new Set<number>();\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n grid.querySegment(a, b, 0, (id) => {\n if (!out.has(id) && segmentHitsBox(a, b, inner[id]!, TOLERANCE)) out.add(id);\n });\n }\n return out;\n };\n return {\n boxes,\n tolerance,\n addsHit(q: readonly Point[], p: readonly Point[]): boolean {\n let before: Set<number> | undefined;\n for (let i = 1; i < q.length; i++) {\n const a = q[i - 1]!;\n const b = q[i]!;\n const hit = grid.someSegment(a, b, 0, (id) => {\n if (!segmentHitsBox(a, b, inner[id]!, TOLERANCE)) return false;\n before ??= hits(p);\n return !before.has(id);\n });\n if (hit) return true;\n }\n return false;\n },\n addsHitTriangle(a: Point, v: Point, b: Point): boolean {\n const x0 = Math.min(a.x, v.x, b.x);\n const y0 = Math.min(a.y, v.y, b.y);\n let before: Set<number> | undefined;\n let hit = false;\n grid.query({ x: x0, y: y0, w: Math.max(a.x, v.x, b.x) - x0, h: Math.max(a.y, v.y, b.y) - y0 }, (id) => {\n if (hit || !triangleOverlapsBox(a, v, b, inner[id]!)) return;\n before ??= hits([a, v, b]);\n if (!before.has(id)) hit = true;\n });\n return hit;\n },\n };\n}\n\n/**\n * This function tells if the triangle `(a, b, c)` and the box overlap by more than `eps`. It is the test of the separating axes:\n * the two axes of the box and the normal of each side of the triangle.\n */\nexport function triangleOverlapsBox(a: Point, b: Point, c: Point, box: Box, eps = 1e-9): boolean {\n if (Math.max(a.x, b.x, c.x) <= box.x + eps || Math.min(a.x, b.x, c.x) >= box.x + box.w - eps) return false;\n if (Math.max(a.y, b.y, c.y) <= box.y + eps || Math.min(a.y, b.y, c.y) >= box.y + box.h - eps) return false;\n const corners: readonly 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 const tri = [a, b, c];\n for (let i = 0; i < 3; i++) {\n const p = tri[i]!;\n const q = tri[(i + 1) % 3]!;\n const n = { x: q.y - p.y, y: p.x - q.x };\n const len = Math.hypot(n.x, n.y);\n if (len < 1e-12) continue;\n const proj = (r: Point): number => ((r.x - p.x) * n.x + (r.y - p.y) * n.y) / len;\n // The triangle is on one side of its side pq: the side of the third vertex.\n const side = proj(tri[(i + 2) % 3]!);\n if (Math.abs(side) < 1e-12) continue;\n const toward = corners.map(proj).map((x) => (side > 0 ? x : -x));\n if (Math.max(...toward) <= eps) return false;\n }\n return true;\n}\n\n/**\n * This function finds the largest size from `max` down to 0 that keeps a convex corner clear, with the test of its triangle.\n * The function `triangle` gives the start of the corner, the vertex and the end of the corner at a size.\n * Without `addsHitTriangle` in the space, the function samples the segments of `piece`, as `fitSize` does.\n * The function tries `max` first, then it halves the interval `steps` times.\n */\nexport function fitCorner(\n space: CurveSpace | undefined,\n max: number,\n triangle: (size: number) => readonly [Point, Point, Point],\n piece: (size: number) => readonly CurveSegment[],\n steps = 8,\n): number {\n if (space === undefined || max <= 0) return Math.max(0, max);\n const test = space.addsHitTriangle?.bind(space);\n if (!test) return fitSize(space, max, triangle, piece, steps);\n const clear = (size: number): boolean => !test(...triangle(size));\n if (clear(max)) return max;\n let lo = 0;\n let hi = max;\n for (let i = 0; i < steps; i++) {\n const mid = (lo + hi) / 2;\n if (clear(mid)) lo = mid;\n else hi = mid;\n }\n return lo;\n}\n\n/**\n * This function finds the largest size from `max` down to 0 that keeps a piece of a curve clear.\n * A clear piece goes through no box that its polyline avoids.\n *\n * The function `piece` gives the segments of the piece at a size. They start with a `move`.\n * The polyline `chord` is the part of the original polyline that the piece replaces.\n * The function tries `max` first, then it halves the interval `steps` times. The result is 0 when no size of the search is clear.\n */\nexport function fitSize(\n space: CurveSpace | undefined,\n max: number,\n chord: (size: number) => readonly Point[],\n piece: (size: number) => readonly CurveSegment[],\n steps = 8,\n): number {\n if (space === undefined || max <= 0) return Math.max(0, max);\n const clear = (size: number): boolean => !space.addsHit(sampleCurve(piece(size), space.tolerance), chord(size));\n if (clear(max)) return max;\n let lo = 0;\n let hi = max;\n for (let i = 0; i < steps; i++) {\n const mid = (lo + hi) / 2;\n if (clear(mid)) lo = mid;\n else hi = mid;\n }\n return lo;\n}\n","import { dist, type Point } from \"../../geom.ts\";\nimport { distinctPoints, type CurveSegment } from \"../model.ts\";\nimport { fitSize, type CurveSpace } from \"../space.ts\";\n\n/** The options of `arcCurve`. */\nexport interface ArcOptions {\n /** The largest radius of the arc at a corner. The default is 12. */\n readonly radius?: number;\n /** The boxes that the curve must not go through. Without it, each corner gets the largest radius that fits on its legs. */\n readonly space?: CurveSpace;\n}\n\n/** A turn smaller than this angle, in radians, is no corner. A turn nearer to a half turn than this angle stays sharp. */\nconst FLAT = 1e-6;\n\n/**\n * This function puts a circular arc at each inner vertex of a polyline. The arc is tangent to the two legs of its corner.\n * The tangent points stay on the first half of each leg, so the ends of the polyline stay.\n * With `space`, the function makes the radius of a corner smaller until the arc goes through no box that the polyline avoids.\n * On a polyline with only horizontal and vertical legs, each arc is a quarter circle.\n */\nexport function arcCurve(points: readonly Point[], options: ArcOptions = {}): CurveSegment[] {\n const p = distinctPoints(points);\n if (p.length === 0) return [];\n const radius = options.radius ?? 12;\n const out: CurveSegment[] = [{ kind: \"move\", to: 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 ux = (v.x - a.x) / la;\n const uy = (v.y - a.y) / la;\n const wx = (b.x - v.x) / lb;\n const wy = (b.y - v.y) / lb;\n const turn = Math.atan2(ux * wy - uy * wx, ux * wx + uy * wy);\n if (Math.abs(turn) < FLAT || Math.PI - Math.abs(turn) < FLAT) {\n out.push({ kind: \"line\", to: v });\n continue;\n }\n // The tangent points are r·tan(|turn|/2) from the vertex.\n const k = Math.tan(Math.abs(turn) / 2);\n const side = Math.sign(turn);\n const ends = (r: number): [Point, Point] => [\n { x: v.x - ux * r * k, y: v.y - uy * r * k },\n { x: v.x + wx * r * k, y: v.y + wy * r * k },\n ];\n const piece = (r: number): CurveSegment[] => {\n const [p1, p2] = ends(r);\n // The center is on the side of the turn, at the distance r from the first leg.\n const center = { x: p1.x - side * uy * r, y: p1.y + side * ux * r };\n return [{ kind: \"arc\", center, radius: r, start: Math.atan2(p1.y - center.y, p1.x - center.x), sweep: turn, to: p2 }];\n };\n const r = fitSize(\n options.space,\n Math.min(radius, Math.min(la, lb) / (2 * k)),\n (s) => [ends(s)[0], v, ends(s)[1]],\n (s) => [{ kind: \"move\", to: ends(s)[0] }, ...piece(s)],\n );\n if (r <= 0) {\n out.push({ kind: \"line\", to: v });\n continue;\n }\n const [p1] = ends(r);\n if (dist(p1, out[out.length - 1]!.to) > 1e-9) out.push({ kind: \"line\", to: p1 });\n out.push(...piece(r));\n }\n if (p.length > 1) out.push({ kind: \"line\", to: p[p.length - 1]! });\n return out;\n}\n","import { dist, type Point } from \"../geom.ts\";\nimport type { CubicPiece } from \"./fit.ts\";\nimport { distinctPoints, type CurveSegment } from \"./model.ts\";\nimport { fitCorner, type CurveSpace } from \"./space.ts\";\n\n/**\n * The shape of a symmetric corner with a spiral, an arc and a second spiral, at the smallest radius 1.\n * The local frame of the first spiral starts at the tangent point on the leg in. Its x axis goes along the leg, and its y axis goes to the side of the turn.\n */\nexport interface SpiralShape {\n /** The tangent length of the corner at the radius 1: the distance from the vertex to each end of the corner. */\n readonly tangent: number;\n /** The turn of each spiral, in radians. The arc turns by the rest of the corner. */\n readonly theta: number;\n /** The cubic pieces of the first spiral at the radius 1, from the origin of the local frame to the start of the arc. */\n readonly pieces: (radius: number) => readonly CubicPiece[];\n /** The end of the first spiral at the radius 1: the start of the arc. */\n readonly end: Point;\n}\n\n/** A turn smaller than this angle, in radians, is no corner. A turn nearer to a half turn than this angle stays sharp. */\nconst FLAT = 1e-6;\n\n/** The options of `spiralCorners`. */\nexport interface SpiralCornerOptions {\n /** The largest smallest radius of a corner. */\n readonly radius: number;\n /** The boxes that the curve must not go through. Without it, each corner gets the largest radius that fits on its legs. */\n readonly space?: CurveSpace;\n}\n\n/**\n * This function puts a symmetric corner at each inner vertex of a polyline: a spiral, an arc and a second spiral.\n * The function `shapeOf` gives the shape of a corner from its turn, at the radius 1. A larger radius scales the shape.\n * The ends of each corner stay on the first half of each leg, so the ends of the polyline stay.\n * With `space`, the radius of a corner shrinks until its corner triangle overlaps no box that the polyline avoids.\n */\nexport function spiralCorners(points: readonly Point[], options: SpiralCornerOptions, shapeOf: (turn: number) => SpiralShape): CurveSegment[] {\n const p = distinctPoints(points);\n if (p.length === 0) return [];\n const out: CurveSegment[] = [{ kind: \"move\", to: 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 u = { x: (v.x - a.x) / la, y: (v.y - a.y) / la };\n const w = { x: (b.x - v.x) / lb, y: (b.y - v.y) / lb };\n const turn = Math.atan2(u.x * w.y - u.y * w.x, u.x * w.x + u.y * w.y);\n if (Math.abs(turn) < FLAT || Math.PI - Math.abs(turn) < FLAT) {\n out.push({ kind: \"line\", to: v });\n continue;\n }\n const shape = shapeOf(Math.abs(turn));\n const side = Math.sign(turn);\n const ends = (r: number): [Point, Point] => [\n { x: v.x - u.x * r * shape.tangent, y: v.y - u.y * r * shape.tangent },\n { x: v.x + w.x * r * shape.tangent, y: v.y + w.y * r * shape.tangent },\n ];\n const piece = (r: number): CurveSegment[] => cornerSegments(shape, r, ends(r), u, w, side, Math.abs(turn));\n const r = fitCorner(\n options.space,\n Math.min(Math.max(0, options.radius), Math.min(la, lb) / (2 * shape.tangent)),\n (s) => [ends(s)[0], v, ends(s)[1]],\n (s) => [{ kind: \"move\", to: ends(s)[0] }, ...piece(s)],\n );\n if (r <= 0) {\n out.push({ kind: \"line\", to: v });\n continue;\n }\n const [p1] = ends(r);\n if (dist(p1, out[out.length - 1]!.to) > 1e-9) out.push({ kind: \"line\", to: p1 });\n out.push(...piece(r));\n }\n if (p.length > 1) out.push({ kind: \"line\", to: p[p.length - 1]! });\n return out;\n}\n\n/**\n * This function gives the segments of one corner at the radius `r`, from the tangent point `p1` to the tangent point `p2`.\n * The first spiral is in the frame of the leg in. The second spiral is the mirror image of the first, in the frame of the leg out, in the reverse order.\n */\nfunction cornerSegments(shape: SpiralShape, r: number, [p1, p2]: [Point, Point], u: Point, w: Point, side: number, turn: number): CurveSegment[] {\n // The y axis of each frame goes to the side of the turn: the left normal of the leg, times the sign of the turn.\n const n1 = { x: -u.y * side, y: u.x * side };\n const n2 = { x: -w.y * side, y: w.x * side };\n const map1 = (q: Point): Point => ({ x: p1.x + (u.x * q.x + n1.x * q.y) * r, y: p1.y + (u.y * q.x + n1.y * q.y) * r });\n const map2 = (q: Point): Point => ({ x: p2.x + (-w.x * q.x + n2.x * q.y) * r, y: p2.y + (-w.y * q.x + n2.y * q.y) * r });\n const out: CurveSegment[] = [];\n const pieces = shape.theta > 0 ? shape.pieces(r) : [];\n for (const q of pieces) out.push({ kind: \"cubic\", c1: map1(q.c1), c2: map1(q.c2), to: map1(q.to) });\n const sweep = turn - 2 * shape.theta;\n if (sweep > 1e-9) {\n const from = map1(shape.end);\n // The center of the arc is at the distance r from the end of the spiral, to the side of the turn.\n const center = map1({ x: shape.end.x - Math.sin(shape.theta), y: shape.end.y + Math.cos(shape.theta) });\n out.push({ kind: \"arc\", center, radius: r, start: Math.atan2(from.y - center.y, from.x - center.x), sweep: side * sweep, to: map2(shape.end) });\n }\n for (let k = pieces.length - 1; k >= 0; k--) {\n const q = pieces[k]!;\n const start = k === 0 ? { x: 0, y: 0 } : pieces[k - 1]!.to;\n out.push({ kind: \"cubic\", c1: map2(q.c2), c2: map2(q.c1), to: k === 0 ? p2 : map2(start) });\n }\n return out;\n}\n\n/**\n * This function gives the tangent length of a symmetric corner at the radius 1. The spiral of the corner turns by `theta` and ends at `end`.\n * The center of the arc is on the bisector of the corner: `T = k + (1 + p) tan(turn / 2)`, with the shift `p` and the offset `k` of the arc.\n */\nexport function cornerTangent(turn: number, theta: number, end: Point): number {\n const k = end.x - Math.sin(theta);\n const p = end.y - (1 - Math.cos(theta));\n return k + (1 + p) * Math.tan(turn / 2);\n}\n","import type { Point } from \"../geom.ts\";\n\n/** One end of a piece of a smooth curve: the point, the unit tangent and the signed curvature. */\nexport interface CurveEnd {\n readonly p: Point;\n readonly t: Point;\n readonly k: number;\n}\n\n/** The control points of a cubic Bezier piece after its start point. */\nexport interface CubicPiece {\n readonly c1: Point;\n readonly c2: Point;\n readonly to: Point;\n}\n\nconst cross = (a: Point, b: Point): number => a.x * b.y - a.y * b.x;\n\n/**\n * This function fits one cubic Bezier piece to two ends of a curve with G2 Hermite data.\n * The piece starts at `a.p` along `a.t` with the curvature `a.k`, and it ends at `b.p` along `b.t` with the curvature `b.k`.\n *\n * The handles have the lengths `h0` and `h1`. The curvature at the start is `(2/3) (cross(t0, D) - h1 cross(t0, t1)) / h0^2`,\n * and at the end `(2/3) (cross(D, t1) - h0 cross(t0, t1)) / h1^2`, with `D = b.p - a.p`.\n * Newton steps solve these two equations, from the handles `guess`.\n * The function gives `undefined` when the steps do not converge to two positive handles. The caller then uses the C1 handles.\n */\nexport function fitG2(a: CurveEnd, b: CurveEnd, guess: readonly [number, number]): CubicPiece | undefined {\n const D = { x: b.p.x - a.p.x, y: b.p.y - a.p.y };\n const s = cross(a.t, b.t);\n const c0 = cross(a.t, D);\n const c1 = cross(D, b.t);\n let [h0, h1] = guess;\n const scale = Math.max(1e-12, Math.hypot(D.x, D.y));\n for (let i = 0; i < 30; i++) {\n const f1 = a.k * h0 * h0 - (2 / 3) * (c0 - h1 * s);\n const f2 = b.k * h1 * h1 - (2 / 3) * (c1 - h0 * s);\n if (Math.abs(f1) < 1e-13 * scale && Math.abs(f2) < 1e-13 * scale) break;\n // The Jacobian of (f1, f2) by (h0, h1).\n const j11 = 2 * a.k * h0;\n const j12 = (2 / 3) * s;\n const j21 = (2 / 3) * s;\n const j22 = 2 * b.k * h1;\n const det = j11 * j22 - j12 * j21;\n if (Math.abs(det) < 1e-18) return undefined;\n h0 -= (f1 * j22 - f2 * j12) / det;\n h1 -= (j11 * f2 - j21 * f1) / det;\n if (!Number.isFinite(h0) || !Number.isFinite(h1)) return undefined;\n }\n const f1 = a.k * h0 * h0 - (2 / 3) * (c0 - h1 * s);\n const f2 = b.k * h1 * h1 - (2 / 3) * (c1 - h0 * s);\n if (!(h0 > 0 && h1 > 0) || Math.abs(f1) > 1e-9 * scale || Math.abs(f2) > 1e-9 * scale) return undefined;\n // A handle longer than the chord gives a loop or a bulge. The C1 handles are better then.\n if (h0 > 1.5 * scale || h1 > 1.5 * scale) return undefined;\n return { c1: { x: a.p.x + a.t.x * h0, y: a.p.y + a.t.y * h0 }, c2: { x: b.p.x - b.t.x * h1, y: b.p.y - b.t.y * h1 }, to: b.p };\n}\n\n/**\n * This function gives `n` cubic Bezier pieces of a smooth curve `at(t)`, with `t` from 0 to 1. The pieces have equal steps of `t`.\n * The function `at` gives the point, the first derivative and the second derivative.\n * Each piece is G2 with its neighbours where `fitG2` finds handles. Elsewhere it has the C1 handles of the derivatives.\n */\nexport function fitPieces(at: (t: number) => { p: Point; d: Point; dd: Point }, n: number): CubicPiece[] {\n const end = (t: number): CurveEnd & { speed: number } => {\n const { p, d, dd } = at(t);\n const speed = Math.hypot(d.x, d.y);\n return { p, t: { x: d.x / speed, y: d.y / speed }, k: cross(d, dd) / speed ** 3, speed };\n };\n const out: CubicPiece[] = [];\n let a = end(0);\n for (let i = 1; i <= n; i++) {\n const b = end(i / n);\n const h0 = a.speed / (3 * n);\n const h1 = b.speed / (3 * n);\n out.push(fitG2(a, b, [h0, h1]) ?? { c1: { x: a.p.x + a.t.x * h0, y: a.p.y + a.t.y * h0 }, c2: { x: b.p.x - b.t.x * h1, y: b.p.y - b.t.y * h1 }, to: b.p });\n a = b;\n }\n return out;\n}\n","import type { Point } from \"../../geom.ts\";\nimport { cornerTangent, spiralCorners, type SpiralShape } from \"../corner.ts\";\nimport { fitPieces, type CubicPiece } from \"../fit.ts\";\nimport type { CurveSegment } from \"../model.ts\";\nimport { cubicAt } from \"../sample.ts\";\nimport type { CurveSpace } from \"../space.ts\";\n\n/** The options of `clothoidCurve`. */\nexport interface ClothoidOptions {\n /** The radius of the arc in the middle of each corner: the smallest radius of the corner. The default is 12. */\n readonly radius?: number;\n /** The share of the turn of a corner in its two clothoids, from 0 (a circular arc) to 1 (no arc). The default is 0.5. */\n readonly spiral?: number;\n /** The largest distance from the cubic pieces to the true clothoid, in units of the plane. The default is 0.25. */\n readonly tolerance?: number;\n /** The boxes that the curve must not go through. Without it, each corner gets the largest radius that fits on its legs. */\n readonly space?: CurveSpace;\n}\n\n/** The largest number of cubic pieces of one clothoid. */\nexport const MAX_CLOTHOID_PIECES = 8;\n\n/**\n * This function gives the point at the arc length `s` of the clothoid that starts at the origin along the x axis.\n * The tangent angle is `θ(s) = s² / (2 a2)`, so the curvature `s / a2` grows linearly with the length.\n * The Fresnel integrals give the point. Their power series converge fast for the turns of a corner.\n */\nexport function clothoidPoint(s: number, a2: number): Point {\n const theta = (s * s) / (2 * a2);\n const t2 = theta * theta;\n let x = 0;\n let y = 0;\n // The term of x is (-1)^n θ^(2n) / ((2n)! (4n + 1)). The term of y is (-1)^n θ^(2n+1) / ((2n+1)! (4n + 3)).\n let px = 1;\n let py = theta;\n for (let n = 0; n < 40; n++) {\n const tx = px / (4 * n + 1);\n const ty = py / (4 * n + 3);\n x += tx;\n y += ty;\n if (Math.abs(tx) < 1e-17 && Math.abs(ty) < 1e-17) break;\n px *= -t2 / ((2 * n + 1) * (2 * n + 2));\n py *= -t2 / ((2 * n + 2) * (2 * n + 3));\n }\n return { x: s * x, y: s * y };\n}\n\n/** The cubic pieces of one clothoid at the radius 1, and their largest distance to the clothoid. */\ninterface ClothoidFit {\n readonly pieces: readonly CubicPiece[];\n readonly error: number;\n}\n\n/** The fits of the clothoids of recent corners, by the turn and the spiral share. Each fit comes when a corner first needs it. The cache empties when it gets large. */\nconst fits = new Map<string, (n: number) => ClothoidFit>();\n\n/** The number of points of the dense polyline that measures the error of a fit. */\nconst DENSE = 256;\n\n/** This function gives the distance from the point `q` to the part of the polyline `p` from the index `from` to the index `to`. */\nfunction distanceTo(q: Point, p: readonly Point[], from: number, to: number): number {\n let best = Infinity;\n for (let i = Math.max(1, from); i <= Math.min(p.length - 1, to); i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\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 ? Math.max(0, Math.min(1, ((q.x - a.x) * dx + (q.y - a.y) * dy) / l2)) : 0;\n best = Math.min(best, Math.hypot(a.x + t * dx - q.x, a.y + t * dy - q.y));\n }\n return best;\n}\n\n/**\n * This function gives the fits of the clothoid that turns by `theta` and ends with the curvature 1, with 1 to `MAX_CLOTHOID_PIECES` pieces.\n * Each piece is G2 with its neighbours. The error of a fit is the largest distance from 16 samples of each piece to a dense polyline of the clothoid.\n * A sample looks only at the part of the polyline near its arc length. A smaller part gives a larger distance, so the error does not get smaller.\n */\nfunction clothoidFits(theta: number): (n: number) => ClothoidFit {\n const length = 2 * theta;\n const a2 = length;\n const at = (t: number): { p: Point; d: Point; dd: Point } => {\n const s = t * length;\n const angle = (s * s) / (2 * a2);\n const k = s / a2;\n const d = { x: length * Math.cos(angle), y: length * Math.sin(angle) };\n return { p: clothoidPoint(s, a2), d, dd: { x: -d.y * length * k, y: d.x * length * k } };\n };\n const dense: Point[] = [];\n for (let i = 0; i <= DENSE; i++) dense.push(clothoidPoint((i / DENSE) * length, a2));\n const done: ClothoidFit[] = [];\n return (n) => {\n const known = done[n];\n if (known) return known;\n const pieces = fitPieces(at, n);\n const window = Math.ceil(DENSE / n / 2) + 8;\n let error = 0;\n let from: Point = { x: 0, y: 0 };\n pieces.forEach((q, k) => {\n for (let i = 1; i < 16; i++) {\n const mid = Math.round(((k + i / 16) / n) * DENSE);\n error = Math.max(error, distanceTo(cubicAt(from, q.c1, q.c2, q.to, i / 16), dense, mid - window, mid + window));\n }\n from = q.to;\n });\n const fit = { pieces, error };\n done[n] = fit;\n return fit;\n };\n}\n\n/** This function gives the shape of a corner of `clothoidCurve` with the turn `turn` at the radius 1. */\nexport function clothoidShape(turn: number, spiral: number, tolerance: number): SpiralShape {\n const theta = (Math.max(0, Math.min(1, spiral)) * turn) / 2;\n if (theta < 1e-9) return { tangent: Math.tan(turn / 2), theta: 0, pieces: () => [], end: { x: 0, y: 0 } };\n const key = `${turn}|${spiral}`;\n let all = fits.get(key);\n if (all === undefined) {\n if (fits.size >= 256) fits.clear();\n all = clothoidFits(theta);\n fits.set(key, all);\n }\n const fit = all;\n const end = clothoidPoint(2 * theta, 2 * theta);\n return {\n tangent: cornerTangent(turn, theta, end),\n theta,\n end,\n // The error of a fit scales with the radius. The corner takes the fewest pieces that keep the error within the tolerance.\n pieces: (radius) => {\n for (let n = 1; n < MAX_CLOTHOID_PIECES; n++) if (fit(n).error * radius <= tolerance) return fit(n).pieces;\n return fit(MAX_CLOTHOID_PIECES).pieces;\n },\n };\n}\n\n/**\n * This function rounds each inner vertex of a polyline with a clothoid, a circular arc and a second clothoid (F6 of the note CURVES).\n * The curvature of a clothoid grows linearly with its length, from 0 on the leg to `1 / radius` on the arc. This is the transition curve of roads and railways.\n * Each clothoid turns by `spiral` times half of the turn. G2 cubic pieces draw it within `tolerance` of the true clothoid.\n *\n * The ends of each corner stay on the first half of each leg, so the ends of the polyline stay.\n * With `space`, the radius of a corner shrinks until its corner triangle overlaps no box that the polyline avoids.\n */\nexport function clothoidCurve(points: readonly Point[], options: ClothoidOptions = {}): CurveSegment[] {\n const spiral = options.spiral ?? 0.5;\n const tolerance = Math.max(1e-3, options.tolerance ?? 0.25);\n return spiralCorners(points, { radius: options.radius ?? 12, ...(options.space ? { space: options.space } : {}) }, (turn) => clothoidShape(turn, spiral, tolerance));\n}\n","import { dist, type Point } from \"../../geom.ts\";\nimport { distinctPoints, type CurveSegment } from \"../model.ts\";\nimport { fitSize, type CurveSpace } from \"../space.ts\";\n\n/** The options of `roundedCurve`. */\nexport interface RoundedOptions {\n /** The largest distance from a corner to the start and to the end of its curve. The default is 12. */\n readonly radius?: number;\n /** The boxes that the curve must not go through. Without it, each corner gets the full radius. */\n readonly space?: CurveSpace;\n}\n\n/**\n * This function rounds each inner vertex of a polyline with a quadratic Bezier curve, as `roundCorners` does.\n * The curve of a corner starts and ends at most `radius` from the vertex, and at most half of each leg. The ends of the polyline stay.\n * The function gives each quadratic curve as the same cubic curve. With `space`, it makes the radius of a corner smaller until the curve\n * goes through no box that the polyline avoids.\n */\nexport function roundedCurve(points: readonly Point[], options: RoundedOptions = {}): CurveSegment[] {\n const p = distinctPoints(points);\n if (p.length === 0) return [];\n const radius = options.radius ?? 12;\n const out: CurveSegment[] = [{ kind: \"move\", to: 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 ends = (r: number): [Point, Point] => [\n { x: v.x + ((a.x - v.x) * r) / la, y: v.y + ((a.y - v.y) * r) / la },\n { x: v.x + ((b.x - v.x) * r) / lb, y: v.y + ((b.y - v.y) * r) / lb },\n ];\n const piece = (r: number): CurveSegment[] => {\n const [p1, p2] = ends(r);\n // A quadratic curve with the control point v is the cubic curve with the control points 2/3 of the way to v.\n return [{ kind: \"cubic\", c1: { x: p1.x + (2 * (v.x - p1.x)) / 3, y: p1.y + (2 * (v.y - p1.y)) / 3 }, c2: { x: p2.x + (2 * (v.x - p2.x)) / 3, y: p2.y + (2 * (v.y - p2.y)) / 3 }, to: p2 }];\n };\n const r = fitSize(\n options.space,\n Math.min(radius, la / 2, lb / 2),\n (s) => [ends(s)[0], v, ends(s)[1]],\n (s) => [{ kind: \"move\", to: ends(s)[0] }, ...piece(s)],\n );\n if (r <= 0) {\n out.push({ kind: \"line\", to: v });\n continue;\n }\n const [p1] = ends(r);\n if (dist(p1, at(out)) > 1e-9) out.push({ kind: \"line\", to: p1 });\n out.push(...piece(r));\n }\n if (p.length > 1) out.push({ kind: \"line\", to: p[p.length - 1]! });\n return out;\n}\n\n/** This function gives the end of the last segment. */\nfunction at(segments: readonly CurveSegment[]): Point {\n return segments[segments.length - 1]!.to;\n}\n","import type { Point } from \"../../geom.ts\";\nimport { cornerTangent, spiralCorners, type SpiralShape } from \"../corner.ts\";\nimport type { CurveSegment } from \"../model.ts\";\nimport type { CurveSpace } from \"../space.ts\";\n\n/** The options of `smoothCurve`. */\nexport interface SmoothOptions {\n /** The radius of the arc in the middle of each corner: the smallest radius of the corner. The default is 12. */\n readonly radius?: number;\n /** The share of the turn of a corner in its two spirals, from 0 (a circular arc) to 1 (no arc). The default is 0.6. */\n readonly smoothing?: number;\n /** The boxes that the curve must not go through. Without it, each corner gets the largest radius that fits on its legs. */\n readonly space?: CurveSpace;\n}\n\n/** The largest turn of one spiral, in radians. A cubic spiral with a larger turn has a curvature that is not monotone. */\nexport const MAX_SPIRAL_TURN = 1;\n\n/**\n * This function gives the cubic Bezier spiral at the radius 1 with the turn `theta` (F7 of the note CURVES).\n * The first three control points are on the x axis, so the curvature is 0 at the start. The end has the curvature 1 and the tangent angle `theta`.\n * The handles are `a = (2/3) θ (1 - θ²/2)` and `b = (2/3) θ (1 + θ²/5)`, and the middle leg is `g = 1.5 b² / sin θ`.\n * With these handles, the curvature rises monotonically from 0 to 1 for each turn up to `MAX_SPIRAL_TURN`.\n */\nexport function bezierSpiral(theta: number): { readonly c1: Point; readonly c2: Point; readonly to: Point } {\n const a = (2 / 3) * theta * (1 - (theta * theta) / 2);\n const b = (2 / 3) * theta * (1 + (theta * theta) / 5);\n const g = (1.5 * b * b) / Math.sin(theta);\n return { c1: { x: a, y: 0 }, c2: { x: a + g, y: 0 }, to: { x: a + g + b * Math.cos(theta), y: b * Math.sin(theta) } };\n}\n\n/** This function gives the shape of a corner of `smoothCurve` with the turn `turn` at the radius 1. */\nexport function smoothShape(turn: number, smoothing: number): SpiralShape {\n const theta = Math.min((Math.max(0, Math.min(1, smoothing)) * turn) / 2, MAX_SPIRAL_TURN);\n if (theta < 1e-9) return { tangent: Math.tan(turn / 2), theta: 0, pieces: () => [], end: { x: 0, y: 0 } };\n const spiral = bezierSpiral(theta);\n return { tangent: cornerTangent(turn, theta, spiral.to), theta, pieces: () => [spiral], end: spiral.to };\n}\n\n/**\n * This function rounds each inner vertex of a polyline with a cubic spiral, a circular arc and a second cubic spiral.\n * It is the shape of the corner smoothing of Figma (F7 of the note CURVES). The curvature rises from 0 on the leg to `1 / radius` on the arc,\n * so the curve is G2: it has no jump of the curvature. Each spiral turns by `smoothing` times half of the turn, up to `MAX_SPIRAL_TURN`.\n * The ends of each corner stay on the first half of each leg, so the ends of the polyline stay.\n * With `space`, the radius of a corner shrinks until its corner triangle overlaps no box that the polyline avoids.\n */\nexport function smoothCurve(points: readonly Point[], options: SmoothOptions = {}): CurveSegment[] {\n const smoothing = options.smoothing ?? 0.6;\n return spiralCorners(points, { radius: options.radius ?? 12, ...(options.space ? { space: options.space } : {}) }, (turn) => smoothShape(turn, smoothing));\n}\n","import { dist, type Point } from \"../../geom.ts\";\nimport { distinctPoints, type CurveSegment } from \"../model.ts\";\nimport { fitSize, type CurveSpace } from \"../space.ts\";\n\n/** The options of `splineCurve`. */\nexport interface SplineOptions {\n /**\n * The tension of the spline, from 0 to 1. The value 0 gives the centripetal Catmull-Rom spline, and 1 gives the polyline.\n * The default is 0.\n */\n readonly tension?: number;\n /** The outward normal of the plug at the first point. With it, the curve leaves the first point along this normal. */\n readonly startNormal?: Point;\n /** The outward normal of the plug at the last point. With it, the curve comes into the last point against this normal. */\n readonly endNormal?: Point;\n /** The boxes that the curve must not go through. Without it, each piece gets the full tangents. */\n readonly space?: CurveSpace;\n}\n\n/**\n * This function draws a centripetal Catmull-Rom spline through the points of a polyline (Yuksel, Schaefer and Keyser, 2011).\n * Each piece between two points is one cubic Bezier curve. The centripetal knots keep the curve free of cusps and loops in a piece.\n * The curve goes through each point. Its tangent at a point keeps one direction on the two sides of the point.\n *\n * With `space`, the function makes the tangents of a piece shorter until the piece goes through no box that its leg avoids.\n * A piece with no tangent is the straight leg.\n */\nexport function splineCurve(points: readonly Point[], options: SplineOptions = {}): CurveSegment[] {\n const p = distinctPoints(points);\n if (p.length === 0) return [];\n const out: CurveSegment[] = [{ kind: \"move\", to: p[0]! }];\n const n = p.length;\n if (n === 1) return out;\n const scale = 1 - Math.max(0, Math.min(1, options.tension ?? 0));\n // The knot interval of each leg is the square root of its length.\n const dt = Array.from({ length: n - 1 }, (_, i) => Math.sqrt(dist(p[i]!, p[i + 1]!)));\n const unit = (q: Point): Point => {\n const l = Math.hypot(q.x, q.y);\n return l === 0 ? { x: 0, y: 0 } : { x: q.x / l, y: q.y / l };\n };\n // The tangent at each point, as a speed in the parameter of the knots.\n const m: Point[] = p.map((v, i) => {\n if (i === 0) {\n const leg = { x: p[1]!.x - v.x, y: p[1]!.y - v.y };\n if (!options.startNormal) return { x: leg.x / dt[0]!, y: leg.y / dt[0]! };\n const u = unit(options.startNormal);\n return { x: u.x * dt[0]!, y: u.y * dt[0]! };\n }\n if (i === n - 1) {\n const a = p[i - 1]!;\n const leg = { x: v.x - a.x, y: v.y - a.y };\n if (!options.endNormal) return { x: leg.x / dt[i - 1]!, y: leg.y / dt[i - 1]! };\n const u = unit(options.endNormal);\n return { x: -u.x * dt[i - 1]!, y: -u.y * dt[i - 1]! };\n }\n const a = p[i - 1]!;\n const b = p[i + 1]!;\n const t0 = dt[i - 1]!;\n const t1 = dt[i]!;\n return {\n x: (v.x - a.x) / t0 - (b.x - a.x) / (t0 + t1) + (b.x - v.x) / t1,\n y: (v.y - a.y) / t0 - (b.y - a.y) / (t0 + t1) + (b.y - v.y) / t1,\n };\n });\n for (let i = 0; i + 1 < n; i++) {\n const a = p[i]!;\n const b = p[i + 1]!;\n const h = dt[i]! / 3;\n const piece = (s: number): CurveSegment[] => [\n { kind: \"move\", to: a },\n { kind: \"cubic\", c1: { x: a.x + m[i]!.x * h * s, y: a.y + m[i]!.y * h * s }, c2: { x: b.x - m[i + 1]!.x * h * s, y: b.y - m[i + 1]!.y * h * s }, to: b },\n ];\n const s = fitSize(options.space, scale, () => [a, b], piece);\n out.push(s > 0 ? piece(s)[1]! : { kind: \"line\", to: b });\n }\n return out;\n}\n","import type { Point } from \"../../geom.ts\";\nimport type { CurveSegment } from \"../model.ts\";\n\n/** This function gives the polyline as it is: one `move` to the first point and one `line` to each other point. */\nexport function straightCurve(points: readonly Point[]): CurveSegment[] {\n return points.map((to, i): CurveSegment => (i === 0 ? { kind: \"move\", to } : { kind: \"line\", to }));\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 * The lane order of the shared ways of a router.\n * With `bundle`, two edges keep one order on all the shared ways of their common stretch.\n * With `run`, each shared way gets its order alone. Two edges can change sides from one shared way to the next.\n */\nexport type RunOrder = \"bundle\" | \"run\";\n\n/** The place of a route on a run. The points go in the direction of the run. `s` and `e` are the indexes of the ends of the run. */\ninterface Placed {\n readonly edge: string;\n readonly p: readonly Point[];\n readonly s: number;\n readonly e: number;\n}\n\n/** The place where two routes part past one end of their common stretch, and the side of the first route there. */\ninterface Parting {\n /** The last common point. */\n readonly at: Point;\n /** This value is below 0 when the first route goes to the left of the second route. It is above 0 when it goes to the right. */\n readonly side: number;\n}\n\n/** This function gives the place where the routes `P` and `Q` part after the last point of the run, or nothing. */\nfunction partAfter(P: Placed, Q: Placed): Parting | undefined {\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) return undefined;\n if (dist(a, b) > SAME) {\n const from = P.p[P.e + j - 2]!;\n const at = P.p[P.e + j - 1]!;\n const side = turn(from, at, a) - turn(from, at, b);\n return side === 0 ? undefined : { at, side };\n }\n }\n}\n\n/** This function gives the place where the routes `P` and `Q` part before the first point of the run, or nothing. */\nfunction partBefore(P: Placed, Q: Placed): Parting | undefined {\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) return undefined;\n if (dist(a, b) > SAME) {\n const from = P.p[P.s - j + 2]!;\n const at = P.p[P.s - j + 1]!;\n // Seen backward, the left side is the right side. Thus the order turns around.\n const side = turn(from, at, b) - turn(from, at, a);\n return side === 0 ? undefined : { at, side };\n }\n }\n}\n\nconst byEdge = (P: Placed, Q: Placed): number => (P.edge < Q.edge ? -1 : P.edge > Q.edge ? 1 : 0);\n\n/** This function puts the point `a` before the point `b`: the smaller x first, then the smaller y. */\nconst firstPoint = (a: Point, b: Point): boolean => a.x < b.x - SAME || (Math.abs(a.x - b.x) <= SAME && a.y < b.y);\n\n/**\n * This function gives the lane order of the edges on a shared way `run` (metro-line order).\n * The routes are polylines that hold the points of the run in a row, in either direction. A route that does not hold the run goes last.\n *\n * Two routes go on together past each end of the run until they part. The route that turns more to the left there gets the lane more to the left.\n *\n * With the order `run`, the default, the end after the last point of the run tells the side first.\n * With the order `bundle`, two routes that part on one side at both ends keep that side.\n * When the two ends disagree, the two routes must cross. The end with the smaller x, then the smaller y, tells the side.\n * Thus each shared way of a common stretch gives two routes the same order, and the crossing is where they part.\n */\nexport function orderLanes(run: readonly Point[], routes: readonly Route[], order: RunOrder = \"run\"): string[] {\n const placed: Placed[] = [];\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 if (order === \"run\") placed.sort((P, Q) => partAfter(P, Q)?.side ?? partBefore(P, Q)?.side ?? byEdge(P, Q));\n else {\n // The sort starts from the order of the edges, so that each run sorts the same edges the same way.\n placed.sort(byEdge);\n placed.sort((P, Q) => {\n const after = partAfter(P, Q);\n const before = partBefore(P, Q);\n if (after && before && Math.sign(after.side) !== Math.sign(before.side)) return firstPoint(after.at, before.at) ? after.side : before.side;\n return after?.side ?? before?.side ?? byEdge(P, Q);\n });\n }\n return [...placed.map((x) => x.edge), ...lost.sort()];\n}\n","import type { Point } from \"../../geom.ts\";\nimport type { Result } from \"../../model.ts\";\nimport { laneRoutes, runKey, segmentsOf, type Segment, type SegmentGraph } from \"../../segments.ts\";\nimport { arcCurve } from \"../arc/index.ts\";\nimport { fitPieces } from \"../fit.ts\";\nimport { distinctPoints, type CurveSegment } from \"../model.ts\";\nimport { sampleCurve } from \"../sample.ts\";\nimport type { CurveSpace } from \"../space.ts\";\n\n/** The options of `highwayCurves`. */\nexport interface HighwayOptions {\n /** The radius at a bend of the center line of a bundle, at a lone corner, and at a merge or a split. The default is 12. */\n readonly radius?: number;\n /** The smallest radius of each lane at a bend, a merge or a split. A bend of a bundle grows to keep its inner lane at this radius. The default is 4. */\n readonly minRadius?: number;\n /** The largest width of an open segment, from its outer lane on the left to its outer lane on the right, as in `laneRoutes`. The default is `Infinity`. */\n readonly maxWidth?: number;\n /** The boxes that the lanes must not go through, from `curveSpace`. With it, no lane goes through a box that its lane of `laneRoutes` avoids. */\n readonly space?: CurveSpace;\n /** The shape of the S curve where a lane joins or leaves a bundle. The default is `biarc`. */\n readonly jog?: JogStyle;\n /** The number of cubic pieces of a `quintic` S curve, from 1 to 8. The default is 4. */\n readonly jogPieces?: number;\n}\n\n/**\n * The shape of the S curve where a lane changes its offset.\n *\n * - `biarc`: two circular arcs. The curvature jumps at each end and at the inflection.\n * - `cubic`: one cubic Bezier curve with its handles along the leg. The curvature jumps at each end.\n * - `quintic`: the quintic `y = d (10 t³ - 15 t⁴ + 6 t⁵)`, in G2 cubic pieces. The curvature is 0 at each end and has no jump.\n *\n * Each shape keeps its curvature at `1 / radius` or less. The polynomial shapes are longer than the biarc for this reason.\n */\nexport type JogStyle = \"biarc\" | \"cubic\" | \"quintic\";\n\n/**\n * The S curves of the lanes, by the order of `laneRoutes`. Each S curve has the first and the last index of its segments in the curve of its lane, and its shape.\n * A polynomial S curve that does not fit on its leg is a biarc.\n */\nexport type JogTrace = (readonly [number, number, JogStyle])[][];\n\n/** The curve of the lane of one edge: a list of segments for any renderer, as `curveOf` gives. */\nexport interface LaneCurve {\n readonly edge: string;\n readonly segments: CurveSegment[];\n}\n\n/** A turn smaller than this angle, in radians, is no corner. A turn nearer to a half turn than this angle stays sharp. */\nconst FLAT = 1e-6;\nconst SAME = 1e-6;\n/** A turn nearer to a half turn than this angle, in radians, is a spike: the route goes back on itself. */\nconst SPIKE = 0.01;\n/** A miter point farther from its vertex than this multiple of the offset gives two corners in place of one. */\nconst BEVEL = 4;\n/** The number of halvings of the search for a clear size. */\nconst STEPS = 8;\n\n/** One leg of the route of an edge, in the order of the route, with the offset of the lane on it. */\ninterface Leg {\n readonly a: Point;\n readonly b: Point;\n /** The unit direction. */\n readonly u: Point;\n /** The unit normal on the left, in a frame with the y axis down. */\n readonly n: Point;\n readonly len: number;\n /** The offset of the lane to the left of the leg. */\n readonly off: number;\n /** The number of lanes of the segment of the leg. A leg of a closed or private segment has 1. */\n readonly lanes: number;\n readonly segment: string;\n /** The indexes of the ends of the leg in the distinct points of its segment. */\n readonly from: number;\n readonly to: number;\n}\n\n/** A vertex of the lane polyline, with the radius of its arc. A radius of 0 keeps the vertex sharp. */\ninterface LaneVertex {\n readonly p: Point;\n readonly r: number;\n /** A fixed arc keeps its radius when an arc next to it on a short leg must shrink. The bends of a bundle are fixed. */\n readonly fixed?: boolean;\n /** The mark of an S curve. The first vertex of an S curve has the part `start`, and the last vertex has the part `end`. */\n readonly jog?: JogMark;\n}\n\n/**\n * The mark of a vertex of an S curve. The two vertices of a biarc have arcs.\n * The first vertex of a polynomial S curve has the direction `u` of the leg. The curve goes from it to the next vertex along `u`.\n */\ninterface JogMark {\n readonly part: \"start\" | \"end\";\n readonly style: JogStyle;\n readonly u?: Point;\n readonly pieces?: number;\n}\n\n/** The ratio `l² / (d r)` of a quintic S curve with the length `l`, the shift `d` and the smallest radius `r`. It is the peak of `h''`. */\nconst QUINTIC_ROOM = 10 / Math.sqrt(3);\n/** The ratio `l² / (d r)` of a cubic S curve with its handles at half of the length. A numeric search gives the peak curvature. */\nconst CUBIC_ROOM = 5.5212;\n\n/** A shift of the lane from one offset to another on one end of a leg: two arcs in an S. */\ninterface Jog {\n /** The offset before the shift and after it. */\n readonly from: number;\n readonly to: number;\n}\n\nconst sub = (a: Point, b: Point): Point => ({ x: a.x - b.x, y: a.y - b.y });\nconst dot = (a: Point, b: Point): number => a.x * b.x + a.y * b.y;\nconst cross = (a: Point, b: Point): number => a.x * b.y - a.y * b.x;\nconst along = (p: Point, u: Point, s: number, n: Point, o: number): Point => ({ x: p.x + u.x * s + n.x * o, y: p.y + u.y * s + n.y * o });\n\n/** The signed turn from the direction `u` to the direction `w`, from -π to π. A positive turn goes from the x axis to the y axis. */\nconst turnOf = (u: Point, w: Point): number => Math.atan2(cross(u, w), dot(u, w));\n\n/** The point where the lines at the offset `o` of two legs meet: the miter point of the vertex `v`. */\nfunction miter(v: Point, nA: Point, nB: Point, o: number): Point {\n const c = 1 + dot(nA, nB);\n if (c < FLAT) return along(v, nA, 0, nA, o);\n return { x: v.x + ((nA.x + nB.x) * o) / c, y: v.y + ((nA.y + nB.y) * o) / c };\n}\n\n/**\n * This function gives the length along the leg of an S with the smallest radius `r` that shifts a lane by `shift`.\n * For a biarc, it gives also the angle of each arc. A radius smaller than half of the shift makes two quarter circles and a straight piece.\n * A polynomial S curve has the length `sqrt(c d r)`, so that its curvature is `1 / r` or less.\n */\nfunction jogShape(r: number, shift: number, style: JogStyle = \"biarc\"): { readonly length: number; readonly angle: number } {\n const d = Math.abs(shift);\n if (d < SAME) return { length: 0, angle: 0 };\n if (r <= 0) return { length: 0, angle: Math.PI / 2 };\n if (style !== \"biarc\") return { length: Math.sqrt((style === \"quintic\" ? QUINTIC_ROOM : CUBIC_ROOM) * d * r), angle: 0 };\n if (r < d / 2) return { length: 2 * r, angle: Math.PI / 2 };\n const angle = Math.acos(1 - d / (2 * r));\n return { length: 2 * r * Math.sin(angle), angle };\n}\n\n/** This function finds the largest size from `max` down to 0 for which `clear` is true. It halves the interval `STEPS` times. */\nfunction largestClear(max: number, clear: (size: number) => boolean): number {\n if (max <= 0 || clear(max)) return Math.max(0, max);\n let lo = 0;\n let hi = max;\n for (let i = 0; i < STEPS; i++) {\n const mid = (lo + hi) / 2;\n if (clear(mid)) lo = mid;\n else hi = mid;\n }\n return lo;\n}\n\n/**\n * This function gives the segments of a polyline with an arc at each vertex. The arc of a vertex has the radius of the vertex.\n * The arc is tangent to the two legs, so the curve has no break of its tangent. A vertex with the radius 0 stays sharp.\n */\nfunction filletPolyline(vertices: readonly LaneVertex[], trace?: [number, number, JogStyle][]): CurveSegment[] {\n const v: LaneVertex[] = [];\n for (const q of vertices) {\n const last = v[v.length - 1];\n if (last && Math.hypot(q.p.x - last.p.x, q.p.y - last.p.y) <= SAME) {\n const jog = q.jog?.part === \"start\" ? q.jog : (last.jog ?? q.jog);\n v[v.length - 1] = jog ? { ...last, r: Math.max(last.r, q.r), jog } : { ...last, r: Math.max(last.r, q.r) };\n } else v.push(q);\n }\n if (v.length === 0) return [];\n const out: CurveSegment[] = [{ kind: \"move\", to: v[0]!.p }];\n if (v.length === 1) return out;\n const unit = (a: Point, b: Point): Point => {\n const l = Math.hypot(b.x - a.x, b.y - a.y);\n return { x: (b.x - a.x) / l, y: (b.y - a.y) / l };\n };\n const len = (i: number): number => Math.hypot(v[i + 1]!.p.x - v[i]!.p.x, v[i + 1]!.p.y - v[i]!.p.y);\n // The tangent length of each inner vertex. Two arcs on one leg must not overlap, so a pair that is too long shrinks.\n const tan: number[] = v.map((q, i) => {\n if (i === 0 || i === v.length - 1 || q.r <= 0) return 0;\n const t = Math.abs(turnOf(unit(v[i - 1]!.p, q.p), unit(q.p, v[i + 1]!.p)));\n if (t < FLAT || Math.PI - t < FLAT) return 0;\n return q.r * Math.tan(t / 2);\n });\n for (let i = 0; i + 1 < v.length; i++) {\n const l = len(i);\n const sum = tan[i]! + tan[i + 1]!;\n if (sum <= l + 1e-9) continue;\n const a = v[i]!.fixed === true;\n const b = v[i + 1]!.fixed === true;\n // A fixed arc keeps its tangent when the arc on the other end of the leg can shrink.\n // The other arc keeps at least a quarter of the leg, so that it has a radius and the curve has no break.\n if (a && !b) {\n tan[i + 1] = Math.min(tan[i + 1]!, Math.max(l - tan[i]!, l / 4));\n tan[i] = Math.min(tan[i]!, l - tan[i + 1]!);\n } else if (b && !a) {\n tan[i] = Math.min(tan[i]!, Math.max(l - tan[i + 1]!, l / 4));\n tan[i + 1] = Math.min(tan[i + 1]!, l - tan[i]!);\n }\n if (tan[i]! + tan[i + 1]! > l + 1e-9) {\n const k = l / (tan[i]! + tan[i + 1]!);\n tan[i] = tan[i]! * k;\n tan[i + 1] = tan[i + 1]! * k;\n }\n }\n const at = (): Point => out[out.length - 1]!.to;\n // The start of the biarc that the pen draws now: the index of its first segment. A polynomial S curve has its trace in `reach`.\n let open = -1;\n const begin = (i: number): void => {\n if (v[i]!.jog?.part === \"start\" && v[i]!.jog?.style === \"biarc\") open = out.length;\n };\n const finish = (i: number): void => {\n if (open >= 0 && v[i]!.jog?.part === \"end\" && v[i]!.jog?.style === \"biarc\") {\n trace?.push([open, out.length - 1, \"biarc\"]);\n open = -1;\n }\n };\n // The pen goes from the vertex `i - 1` to the point `to`. After the first vertex of a polynomial S curve, it draws the S curve to the vertex `i`.\n const reach = (i: number, to: Point): void => {\n const mark = v[i - 1]!.jog;\n const from = at();\n if (mark?.part !== \"start\" || mark.style === \"biarc\" || mark.u === undefined || to !== v[i]!.p || Math.hypot(from.x - v[i - 1]!.p.x, from.y - v[i - 1]!.p.y) > 1e-9) {\n out.push({ kind: \"line\", to });\n return;\n }\n const first = out.length;\n out.push(...jogSegments(from, to, mark.u, mark.style, mark.pieces ?? 4));\n trace?.push([first, out.length - 1, mark.style]);\n };\n for (let i = 1; i + 1 < v.length; i++) {\n const q = v[i]!.p;\n const t = tan[i]!;\n if (t <= 0) {\n reach(i, q);\n finish(i);\n begin(i);\n continue;\n }\n const u = unit(v[i - 1]!.p, q);\n const w = unit(q, v[i + 1]!.p);\n const turn = turnOf(u, w);\n const k = Math.tan(Math.abs(turn) / 2);\n const r = t / k;\n const side = Math.sign(turn);\n const p1 = along(q, u, -t, u, 0);\n const p2 = along(q, w, t, w, 0);\n // The center is on the side of the turn, at the distance r from the first leg.\n const center = { x: p1.x - side * u.y * r, y: p1.y + side * u.x * r };\n if (Math.hypot(p1.x - at().x, p1.y - at().y) > 1e-9) reach(i, p1);\n begin(i);\n out.push({ kind: \"arc\", center, radius: r, start: Math.atan2(p1.y - center.y, p1.x - center.x), sweep: turn, to: p2 });\n finish(i);\n }\n reach(v.length - 1, v[v.length - 1]!.p);\n return out;\n}\n\n/**\n * This function gives the segments of a polynomial S curve from `from` to `to`, with the tangent `u` at each end.\n * The curve goes `l` along `u` and `d` to the side, with `l` and `d` from the chord.\n * A `cubic` S curve is one cubic Bezier curve with each handle at half of `l`. A `quintic` S curve is `y = d h(t)` with `h(t) = 10 t³ - 15 t⁴ + 6 t⁵`, in `pieces` G2 cubic pieces.\n */\nfunction jogSegments(from: Point, to: Point, u: Point, style: JogStyle, pieces: number): CurveSegment[] {\n const D = sub(to, from);\n const l = dot(D, u);\n const d = cross(u, D);\n if (l <= SAME) return [{ kind: \"line\", to }];\n const side = { x: -u.y, y: u.x };\n if (style === \"cubic\") return [{ kind: \"cubic\", c1: along(from, u, l / 2, u, 0), c2: along(to, u, -l / 2, u, 0), to }];\n const at = (t: number): { p: Point; d: Point; dd: Point } => {\n const h = t * t * t * (10 - 15 * t + 6 * t * t);\n const h1 = 30 * t * t * (1 - t) * (1 - t);\n const h2 = 60 * t * (1 - t) * (1 - 2 * t);\n return {\n p: { x: from.x + u.x * l * t + side.x * d * h, y: from.y + u.y * l * t + side.y * d * h },\n d: { x: u.x * l + side.x * d * h1, y: u.y * l + side.y * d * h1 },\n dd: { x: side.x * d * h2, y: side.y * d * h2 },\n };\n };\n const out: CurveSegment[] = fitPieces(at, Math.max(1, Math.min(8, Math.round(pieces)))).map((q) => ({ kind: \"cubic\", c1: q.c1, c2: q.c2, to: q.to }));\n // The last piece ends at the exact point of the vertex.\n const last = out[out.length - 1]!;\n if (last.kind === \"cubic\") out[out.length - 1] = { ...last, to };\n return out;\n}\n\n/** The radius of the center line at each bend of the bundles, by the key of the bend from `bendKey`. */\ntype Bends = ReadonlyMap<string, number>;\n\n/** The key of the bend between two legs. The lanes that go from one leg to the other bend with one center. */\nconst bendKey = (A: Leg, B: Leg): string => `${A.segment}:${A.to}>${B.segment}:${B.from}@${B.a.x},${B.a.y}`;\n\n/** One bend of the lanes of bundles: the leg before it, the leg after it, and the offset and the polyline of each lane. */\ninterface BendGroup {\n readonly A: Leg;\n readonly B: Leg;\n readonly lanes: { readonly offset: number; readonly polyline: readonly Point[] }[];\n}\n\n/** The legs of the route of one lane, with no spike, and the offset of the lane at each vertex of the route. */\ninterface LanePlan {\n readonly legs: readonly Leg[];\n readonly at: readonly number[];\n}\n\n/**\n * This function gives the offset of the lane at each vertex of its route. At a merge or a split, it is the offset on the leg with more lanes.\n * So a bundle keeps its spacing up to the vertex, and the lane shifts on the other leg.\n */\nfunction offsetsAt(legs: readonly Leg[]): number[] {\n const at: number[] = new Array<number>(legs.length + 1).fill(0);\n for (let j = 1; j < legs.length; j++) {\n const A = legs[j - 1]!;\n const B = legs[j]!;\n at[j] = A.lanes < B.lanes ? B.off : A.off;\n }\n return at;\n}\n\n/**\n * This function gives the curve of one polyline as a lane alone: an arc at each corner, as `arcCurve` gives.\n * A lane alone has no merge and no split, so the curve strategy `highway` gives this curve for one polyline.\n */\nexport function highwayCurve(points: readonly Point[], options: Pick<HighwayOptions, \"radius\" | \"space\"> = {}): CurveSegment[] {\n return arcCurve(points, { radius: options.radius ?? 12, ...(options.space ? { space: options.space } : {}) });\n}\n\n/**\n * This function gives the curve of each lane of `laneRoutes`. The lanes of one open segment bend as one highway.\n *\n * At each bend of an open segment, the lanes are arcs with one center. The radius of a lane is the radius of the center line,\n * plus or minus its offset. So the lanes stay at the lane spacing through the bend. The bend grows to keep the inner lane at `minRadius`,\n * and it shrinks to fit on the legs and in the free space.\n *\n * A lane joins (merges) or leaves (splits) a bundle on an S curve on the leg with fewer lanes. The option `jog` gives its shape.\n * The smallest radius of the S curve is `radius` or less.\n * Each curve has no break of its tangent where each radius is more than 0.\n * A lane that is in no open segment gets the curve of `arcCurve`.\n *\n * The function takes the same input as `laneRoutes`, and it gives the curves in the order of `laneRoutes`.\n * The output is a list of segments for any renderer. `toSvgPath` writes it as SVG path data, and `sampleCurve` gives points.\n */\nexport function highwayCurves(source: Result | SegmentGraph, open: ReadonlySet<string>, laneWidth: number, options: HighwayOptions = {}): LaneCurve[] {\n return tracedHighwayCurves(source, open, laneWidth, options).curves;\n}\n\n/**\n * This function gives the curves of `highwayCurves` and the S curves of each lane. The benchmark measures the S curves.\n * The package does not export this function.\n */\nexport function tracedHighwayCurves(\n source: Result | SegmentGraph,\n open: ReadonlySet<string>,\n laneWidth: number,\n options: HighwayOptions = {},\n): { readonly curves: LaneCurve[]; readonly jogs: JogTrace } {\n const graph = \"paths\" in source ? source : segmentsOf(source);\n const radius = Math.max(0, options.radius ?? 12);\n const minRadius = Math.max(0, options.minRadius ?? 4);\n const maxWidth = options.maxWidth ?? Infinity;\n const space = options.space;\n const style: JogStyle = options.jog ?? \"biarc\";\n const pieces = options.jogPieces ?? 4;\n const byId = new Map(graph.segments.map((s) => [s.id, s]));\n const spacingOf = (s: Segment): number => (s.count > 1 && open.has(runKey(s.edges)) ? Math.min(laneWidth, maxWidth / (s.count - 1)) : 0);\n // The polylines of `laneRoutes`: the free space keeps each curve out of the boxes that its polyline avoids.\n const polylines = laneRoutes(graph, open, laneWidth, maxWidth);\n const centers = new Map<string, Point[]>();\n const centerOf = (s: Segment): Point[] => {\n let c = centers.get(s.id);\n if (!c) {\n c = distinctPoints(s.points, SAME);\n centers.set(s.id, c);\n }\n return c;\n };\n const plans = graph.paths.map((path): LanePlan | undefined => {\n const legs: Leg[] = [];\n for (const ref of path.segments) {\n const s = byId.get(ref.segment);\n if (!s) continue;\n const sp = spacingOf(s);\n const c = centerOf(s);\n const offset = ((s.count - 1) / 2 - ref.lane) * sp;\n const off = ref.reverse ? -offset : offset;\n const n = c.length;\n for (let j = 0; j + 1 < n; j++) {\n const from = ref.reverse ? n - 1 - j : j;\n const to = ref.reverse ? n - 2 - j : j + 1;\n const a = c[from]!;\n const b = c[to]!;\n const len = Math.hypot(b.x - a.x, b.y - a.y);\n if (len <= SAME) continue;\n const u = { x: (b.x - a.x) / len, y: (b.y - a.y) / len };\n legs.push({ a, b, u, n: { x: u.y, y: -u.x }, len, off, lanes: sp > 0 ? s.count : 1, segment: s.id, from, to });\n }\n }\n if (legs.every((l) => l.lanes < 2)) return undefined;\n const kept = withoutSpikes(legs);\n return { legs: kept, at: offsetsAt(kept) };\n });\n // The lanes that go from one leg of a bundle to the next leg of a bundle bend about one center.\n const groups = new Map<string, BendGroup>();\n plans.forEach((plan, i) => {\n if (!plan) return;\n for (let j = 1; j < plan.legs.length; j++) {\n const A = plan.legs[j - 1]!;\n const B = plan.legs[j]!;\n if (A.lanes < 2 || B.lanes < 2) continue;\n const key = bendKey(A, B);\n const group = groups.get(key) ?? { A, B, lanes: [] };\n // A lane that goes the other way through the bend has its offset on the other side of its own direction.\n const same = dot(A.u, group.A.u) > 0;\n group.lanes.push({ offset: same ? plan.at[j]! : -plan.at[j]!, polyline: polylines[i]!.points });\n groups.set(key, group);\n }\n });\n const bends = bendRadii(groups, radius, minRadius, space);\n const jogs: JogTrace = [];\n const curves = graph.paths.map((path, i): LaneCurve => {\n const polyline = polylines[i]!.points;\n const plan = plans[i];\n const trace: [number, number, JogStyle][] = [];\n jogs.push(trace);\n if (!plan) return { edge: path.edge, segments: highwayCurve(polyline, { radius, ...(space ? { space } : {}) }) };\n if (plan.legs.length === 0) return { edge: path.edge, segments: [{ kind: \"move\", to: polyline[0]! }] };\n return { edge: path.edge, segments: laneCurve(plan, bends, polyline, { radius, minRadius, space, style, pieces }, trace) };\n });\n return { curves, jogs };\n}\n\n/**\n * This function gives the radius of the center line at each bend of the bundles.\n * The radius is `radius`, or more to keep the inner lane at `minRadius`. It shrinks so that each tangent point stays on the half of its leg.\n * It also shrinks so that no lane goes through a box that its polyline avoids.\n */\nfunction bendRadii(groups: ReadonlyMap<string, BendGroup>, radius: number, minRadius: number, space: CurveSpace | undefined): Map<string, number> {\n const out = new Map<string, number>();\n for (const [key, { A, B, lanes }] of groups) {\n const turn = turnOf(A.u, B.u);\n if (Math.abs(turn) < FLAT || Math.PI - Math.abs(turn) < FLAT) continue;\n const k = Math.tan(Math.abs(turn) / 2);\n const side = Math.sign(turn);\n const v = B.a;\n const half = Math.max(...lanes.map((l) => Math.abs(l.offset)));\n const max = Math.min(Math.max(radius, half + minRadius), A.len / (2 * k), B.len / (2 * k));\n const clear = (R: number): boolean => {\n if (!space) return true;\n return lanes.every(({ offset, polyline }) => {\n const r = R + side * offset;\n if (r <= 0) return true;\n const W = miter(v, A.n, B.n, offset);\n const piece = filletPolyline([\n { p: along(W, A.u, -r * k, A.u, 0), r: 0 },\n { p: W, r },\n { p: along(W, B.u, r * k, B.u, 0), r: 0 },\n ]);\n return !space.addsHit(sampleCurve(piece, space.tolerance), polyline);\n });\n };\n out.set(key, largestClear(max, clear));\n }\n return out;\n}\n\n/**\n * This function removes each place where the route goes back on itself: a leg, then a leg in the opposite direction.\n * Such a spike is a split point past the turn of a route. A lane cannot follow it with no break of its tangent.\n */\nfunction withoutSpikes(input: readonly Leg[]): Leg[] {\n const legs = [...input];\n for (let i = 1; i < legs.length; ) {\n const A = legs[i - 1]!;\n const B = legs[i]!;\n if (Math.PI - Math.abs(turnOf(A.u, B.u)) >= SPIKE) {\n i++;\n continue;\n }\n // The route goes from A.a to the tip and back to B.b. The rest is the part of the longer leg past B.b or past A.a.\n const rest = A.len - B.len;\n const keep: Leg[] = [];\n if (rest > SAME) keep.push({ ...A, b: B.b, len: rest, to: -1 });\n else if (-rest > SAME) keep.push({ ...B, a: A.a, len: -rest, from: -1 });\n legs.splice(i - 1, 2, ...keep);\n i = Math.max(1, i - 1);\n }\n return legs;\n}\n\n/** This function gives the curve of the lane of one edge from its legs. */\nfunction laneCurve(\n plan: LanePlan,\n bends: Bends,\n polyline: readonly Point[],\n { radius, minRadius, space, style: wanted, pieces }: { radius: number; minRadius: number; space: CurveSpace | undefined; style: JogStyle; pieces: number },\n trace?: [number, number, JogStyle][],\n): CurveSegment[] {\n const { legs, at } = plan;\n const L = legs.length;\n // The shifts on the ends of each leg, from the offset at a vertex to the offset of the leg.\n const startJog: (Jog | undefined)[] = new Array<Jog | undefined>(L).fill(undefined);\n const endJog: (Jog | undefined)[] = new Array<Jog | undefined>(L).fill(undefined);\n for (let j = 0; j < L; j++) {\n const leg = legs[j]!;\n if (Math.abs(at[j]! - leg.off) > SAME) startJog[j] = { from: at[j]!, to: leg.off };\n if (Math.abs(at[j + 1]! - leg.off) > SAME) endJog[j] = { from: leg.off, to: at[j + 1]! };\n }\n // The fixed radius of a lane at a bend of bundles: the radius of the center line, plus or minus the offset.\n const fixed = (j: number): number | undefined => {\n const A = legs[j - 1]!;\n const B = legs[j]!;\n if (A.lanes < 2 || B.lanes < 2) return undefined;\n const R = bends.get(bendKey(A, B)) ?? 0;\n const r = R + Math.sign(turnOf(A.u, B.u)) * at[j]!;\n return R > 0 && r > 0 ? r : undefined;\n };\n\n /** The shape of the lane near one vertex of the route. */\n interface Near {\n /** The vertices of the shift at the end of the leg before the vertex, the corner, and the shift on the leg after it. */\n readonly vertices: readonly LaneVertex[];\n /** The distance along each leg that the shape uses. */\n readonly back: number;\n readonly ahead: number;\n }\n // The shape near the vertex `j` for the scale `s` of the wanted radius. The radius of each arc is at least `floor`.\n // The arcs of a short leg shrink in `filletPolyline`, so a large floor keeps each tangent and does not make an arc too large for its leg.\n const near = (j: number, s: number, floor: number, loose: boolean, style: JogStyle): Near => {\n const A = j > 0 ? legs[j - 1] : undefined;\n const B = j < L ? legs[j] : undefined;\n const v = B ? B.a : A!.b;\n const c = at[j]!;\n const want = Math.max(radius * s, floor);\n const corner: LaneVertex[] = [];\n let xA = 0;\n let xB = 0;\n let t = 0;\n if (!A || !B) corner.push({ p: v, r: 0 });\n else {\n const turn = turnOf(A.u, B.u);\n const f = loose ? undefined : fixed(j);\n const W = miter(v, A.n, B.n, c);\n if (Math.abs(turn) < FLAT) {\n // A straight vertex has no corner.\n } else if (Math.hypot(W.x - v.x, W.y - v.y) > BEVEL * Math.abs(c)) {\n // A turn near a half turn puts the miter point far away. The lane turns at two points on the offset lines.\n corner.push({ p: along(v, A.n, 0, A.n, c), r: want }, { p: along(v, B.n, 0, B.n, c), r: want });\n } else {\n xA = dot(sub(W, v), A.u);\n xB = dot(sub(W, v), B.u);\n const r = f ?? want;\n corner.push(f === undefined ? { p: W, r } : { p: W, r, fixed: true });\n t = r * Math.tan(Math.abs(turn) / 2);\n }\n }\n // The arcs of a shift have the wanted radius too. So the radius of each arc of the lane is at least `floor`.\n const shift = (leg: Leg, jog: Jog | undefined, start: number, sign: 1 | -1): LaneVertex[] => {\n if (!jog) return [];\n const { length, angle } = jogShape(want, jog.to - jog.from, style);\n if (style !== \"biarc\") {\n // The S curve goes along the leg from the offset `jog.from` to the offset `jog.to`, in the order of the route.\n const s0 = sign === 1 ? start : -(start + length);\n const p0 = along(v, leg.u, s0, leg.n, jog.from);\n const p3 = along(v, leg.u, s0 + length, leg.n, jog.to);\n return [\n { p: p0, r: 0, jog: { part: \"start\", style, u: leg.u, pieces } },\n { p: p3, r: 0, jog: { part: \"end\", style } },\n ];\n }\n const k = want < Math.abs(jog.to - jog.from) / 2 ? want : want * Math.tan(angle / 2);\n // On the leg after the vertex, the shift goes forward from `start`. On the leg before it, it goes back from `start`.\n const p1 = along(v, leg.u, sign * (start + k), leg.n, sign === 1 ? jog.from : jog.to);\n const p2 = along(v, leg.u, sign * (start + length - k), leg.n, sign === 1 ? jog.to : jog.from);\n return sign === 1\n ? [{ p: p1, r: want, jog: { part: \"start\", style } }, { p: p2, r: want, jog: { part: \"end\", style } }]\n : [{ p: p2, r: want, jog: { part: \"start\", style } }, { p: p1, r: want, jog: { part: \"end\", style } }];\n };\n const lenOf = (jog: Jog | undefined): number => (jog ? jogShape(want, jog.to - jog.from, style).length : 0);\n return {\n vertices: [...(A ? shift(A, endJog[j - 1], t - xA, -1) : []), ...corner, ...(B ? shift(B, startJog[j], xB + t, 1) : [])],\n back: A ? Math.max(0, t - xA) + lenOf(endJog[j - 1]) : 0,\n ahead: B ? Math.max(0, xB + t) + lenOf(startJog[j]) : 0,\n };\n };\n // The vertices of the lane near `j`, between the middles of its two legs. The free space tests this piece.\n const piece = (j: number, s: number, floor: number, loose: boolean, style: JogStyle): LaneVertex[] => {\n const A = j > 0 ? legs[j - 1] : undefined;\n const B = j < L ? legs[j] : undefined;\n const v = B ? B.a : A!.b;\n const head = A ? [{ p: along(v, A.u, -A.len / 2, A.n, A.off), r: 0 }] : [];\n const tail = B ? [{ p: along(v, B.u, B.len / 2, B.n, B.off), r: 0 }] : [];\n return [...head, ...near(j, s, floor, loose, style).vertices, ...tail];\n };\n // Each vertex gets the half of each leg next to it. The scale of the radii is the largest that fits, then the largest that is clear.\n // A bend of bundles keeps its fixed radius. It is loose, with the radii of a lane alone, only when the fixed arc does not fit or is not clear.\n // The smallest radius shrinks only as far as a short leg or the free space needs. A radius of 0 makes a sharp corner.\n // A polynomial S curve is longer than a biarc. Where it does not fit on its leg, is not clear, or needs a smaller radius than the biarc, the vertex takes the biarc.\n const solve = (j: number, style: JogStyle): { readonly vertices: readonly LaneVertex[]; readonly ok: boolean; readonly want: number } => {\n const fits = (s: number, f: number, loose: boolean): boolean => {\n const q = near(j, s, f, loose, style);\n return (j === 0 || q.back <= legs[j - 1]!.len / 2 + 1e-9) && (j === L || q.ahead <= legs[j]!.len / 2 + 1e-9);\n };\n let floor = minRadius;\n let loose = !fits(0, floor, false);\n const fitFloor = (): void => {\n if (!fits(0, floor, loose) && fits(0, 0, loose)) floor = largestClear(floor, (f) => fits(0, f, loose));\n };\n const most = (): number => (fits(1, floor, loose) ? 1 : largestClear(1, (x) => fits(x, floor, loose)));\n fitFloor();\n let s = most();\n let clearAtEnd = true;\n if (space) {\n const clear = (x: number, f: number): boolean => !space.addsHit(sampleCurve(filletPolyline(piece(j, x, f, loose, style)), space.tolerance), polyline);\n s = largestClear(s, (x) => clear(x, floor));\n if (!loose && !clear(s, floor)) {\n loose = true;\n fitFloor();\n s = largestClear(most(), (x) => clear(x, floor));\n }\n if (!clear(s, floor)) {\n const f = largestClear(floor, (x) => clear(s, x));\n if (clear(s, f)) floor = f;\n }\n clearAtEnd = clear(s, floor);\n }\n return { vertices: near(j, s, floor, loose, style).vertices, ok: fits(s, floor, loose) && clearAtEnd, want: Math.max(radius * s, floor) };\n };\n const vertices: LaneVertex[] = [];\n for (let j = 0; j <= L; j++) {\n const first = solve(j, wanted);\n if (wanted === \"biarc\" || (startJog[j] === undefined && (j === 0 || endJog[j - 1] === undefined))) {\n vertices.push(...first.vertices);\n continue;\n }\n const biarc = solve(j, \"biarc\");\n vertices.push(...(first.ok && first.want >= biarc.want - 1e-9 ? first : biarc).vertices);\n }\n return filletPolyline(vertices, trace);\n}\n","import type { Point } from \"../geom.ts\";\nimport { arcCurve } from \"./arc/index.ts\";\nimport { clothoidCurve } from \"./clothoid/index.ts\";\nimport type { CurveSegment, CurveType } from \"./model.ts\";\nimport { roundedCurve } from \"./rounded/index.ts\";\nimport { smoothCurve } from \"./smooth/index.ts\";\nimport type { CurveSpace } from \"./space.ts\";\nimport { splineCurve } from \"./spline/index.ts\";\nimport { straightCurve } from \"./straight/index.ts\";\n\nexport * from \"./model.ts\";\nexport { cubicAt, sampleCurve, toSvgPath } from \"./sample.ts\";\nexport { curveSpace, type CurveSpace } from \"./space.ts\";\nexport { straightCurve } from \"./straight/index.ts\";\nexport { roundedCurve, type RoundedOptions } from \"./rounded/index.ts\";\nexport { splineCurve, type SplineOptions } from \"./spline/index.ts\";\nexport { arcCurve, type ArcOptions } from \"./arc/index.ts\";\nexport { smoothCurve, type SmoothOptions } from \"./smooth/index.ts\";\nexport { clothoidCurve, type ClothoidOptions } from \"./clothoid/index.ts\";\nexport { highwayCurve, highwayCurves, type HighwayOptions, type JogStyle, type LaneCurve } from \"./highway/index.ts\";\n\n/** The options of `curveOf`. Each type reads only the options that it uses. */\nexport interface CurveOptions {\n readonly type: CurveType;\n /** The types `rounded`, `arc`, `smooth` and `clothoid` read this radius of the corners. The default is 12. */\n readonly radius?: number;\n /** The type `spline` reads this tension, from 0 to 1. The default is 0. */\n readonly tension?: number;\n /** The type `smooth` reads this share of the turn of a corner in its spirals, from 0 to 1. The default is 0.6. */\n readonly smoothing?: number;\n /** The type `clothoid` reads this share of the turn of a corner in its clothoids, from 0 to 1. The default is 0.5. */\n readonly spiral?: number;\n /** The type `clothoid` reads this largest distance from its cubic pieces to the true clothoid. The default is 0.25. */\n readonly tolerance?: number;\n /** The type `spline` leaves the first point along this outward normal of its plug. */\n readonly startNormal?: Point;\n /** The type `spline` comes into the last point against this outward normal of its plug. */\n readonly endNormal?: Point;\n /** The boxes that the curve must not go through, from `curveSpace`. The type `straight` does not read it. */\n readonly space?: CurveSpace;\n}\n\n/**\n * This function gives the curve of a route: a polyline of a router, a lane of `laneRoutes` or a link of a zoom level.\n * The curve starts at the first point and ends at the last point of the polyline.\n * The output is a list of segments for any renderer. `toSvgPath` writes it as SVG path data, and `sampleCurve` gives points.\n */\nexport function curveOf(points: readonly Point[], options: CurveOptions): CurveSegment[] {\n switch (options.type) {\n case \"straight\":\n return straightCurve(points);\n case \"rounded\":\n return roundedCurve(points, options);\n case \"spline\":\n return splineCurve(points, options);\n case \"arc\":\n return arcCurve(points, options);\n case \"smooth\":\n return smoothCurve(points, options);\n case \"clothoid\":\n return clothoidCurve(points, options);\n }\n}\n","import { TOLERANCE } from \"./bench/properties.ts\";\nimport { dist, inflate, segmentHitsBox, segmentHitsRect, type Box, 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 return this.hit(a, b, pad, skip) === undefined;\n }\n\n /**\n * This method gives a node whose box, made larger by `pad`, the segment `ab` goes into, or `undefined` when the segment is clear.\n * The nodes in `skip` do not count. The test stops at the first such node.\n */\n hit(a: Point, b: Point, pad: number, skip?: ReadonlySet<Node>): Node | undefined {\n let found: Node | undefined;\n this.#grid.someSegment(a, b, pad, (n) => {\n if (skip?.has(n) || !hits(a, b, n, pad)) return false;\n found = n;\n return true;\n });\n return found;\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 /**\n * This method gives each node whose box the segment `ab` goes through to `visit`, one time each.\n * The segment goes through a box when a part of it longer than `TOLERANCE` is inside the box made smaller by `TOLERANCE`.\n * The link measures (`measureLinks`) use the same test.\n */\n through(a: Point, b: Point, visit: (n: Node) => void): void {\n this.#grid.querySegment(a, b, 0, (n) => {\n if (segmentHitsBox(a, b, inflate(n.box, -TOLERANCE), TOLERANCE)) visit(n);\n });\n }\n\n /** This method gives each node whose bucket the box touches to `visit`. A node can be outside the box. */\n query(box: Box, visit: (n: Node) => void): void {\n this.#grid.query(box, visit);\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/** This function tells if the segment `ab` goes into the box of the node, made larger by `pad`. */\nfunction hits(a: Point, b: Point, n: Node, pad: number): boolean {\n const x = n.box;\n return segmentHitsRect(a, b, x.x - pad, x.y - pad, x.x + x.w + pad, x.y + x.h + pad);\n}\n\n/** A free point at an end of a search of `CornerGraph.pathAmong`, and the cost to reach it. */\nexport interface Terminal {\n readonly point: Point;\n readonly cost: number;\n}\n\n/** A path of `CornerGraph.pathAmong`: its points, the index of its first point in `from`, the index of its last point in `to`, and its cost. */\nexport interface Among {\n readonly points: Point[];\n readonly from: number;\n readonly to: number;\n readonly cost: number;\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 * With `cones`, each corner also links to the nearest corner that it can see in each of four cones around the axes.\n * Then a path can go along a long corridor between rows or columns of boxes. The default is false.\n */\n readonly cones?: boolean;\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 corners in each bucket of the point grid, by the key of the bucket. A corner is in one bucket: the bucket of its point.\n readonly #buckets = new Map<number, number[]>();\n // The distance from the point of the last call of nearestVisible to each corner that the call found.\n #dist = new Float64Array(0);\n // The corners of one ring of nearestVisible, nearest first.\n readonly #near = new MinHeap();\n // The corners that each end of a path sees, by the coordinates of the end.\n readonly #endCache = new Map<string, number[]>();\n // The corners that each end of a path of `pathAmong` sees. Such a path has several ends, so each end takes fewer corners.\n readonly #fewCache = new Map<string, number[]>();\n // The connected part of the graph of each corner. The first call of `path` makes it.\n #part: Int32Array | undefined;\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 // The k nearest corners of a corner in a long corridor are often all on one side. The cones add a link along the corridor.\n for (const j of this.#nearestVisible(this.points[i]!, this.#k, i, this.#pad, options.cones ?? false)) {\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 const j = this.points.length;\n this.#pointGrid.add(j, { x: c.x, y: c.y, w: 0, h: 0 });\n const key = bucketKey(Math.floor(c.x / this.#cell), Math.floor(c.y / this.#cell));\n const list = this.#buckets.get(key);\n if (list === undefined) this.#buckets.set(key, [j]);\n else list.push(j);\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 /**\n * This method tests the corners in rings of radius `r` = 1, 2, 4 and 8 cells. In each ring, it tests the corners\n * within `r` that an earlier ring did not test, nearest first, and equal distances by index.\n * The ring of `r` takes the corners of the buckets that the square of side `2r` around `p` touches.\n * A corner of these buckets beyond `r` waits for the next ring. So the method visits each bucket one time.\n * With `cones`, the method also gives the nearest visible corner of each of four cones around the axes that the `k` nearest corners leave empty.\n */\n #nearestVisible(p: Point, k: number, self: number, pad: number, cones = false): number[] {\n const out: number[] = [];\n // The bits of the full cones: 1 is +x, 2 is +y, 4 is -x and 8 is -y.\n let full = 0;\n if (this.#dist.length < this.points.length) this.#dist = new Float64Array(this.points.length);\n const dd = this.#dist;\n const points = this.points;\n const cell = this.#cell;\n const reach = CONE_CELLS * cell;\n const blockers: Node[] = [];\n const now = this.#near;\n // The corners that the rings found beyond their radius. The next ring takes them.\n let wait: number[] = [];\n // The bucket range of the ring before. The first ring has none.\n let pi0 = 1;\n let pi1 = 0;\n let pj0 = 1;\n let pj1 = 0;\n for (let r = cell; r <= cell * 8; r *= 2) {\n // The ring of `r` holds the corners beyond `r / 2`. With the k nearest corners, the cones take no corner beyond `reach`.\n if (out.length >= k && r / 2 >= reach) return out;\n // These bounds are the bounds of a query of the box at (p.x - r, p.y - r) with the side 2r.\n const x0 = p.x - r;\n const y0 = p.y - r;\n const i0 = Math.floor(x0 / cell);\n const j0 = Math.floor(y0 / cell);\n const i1 = Math.floor((x0 + 2 * r) / cell);\n const j1 = Math.floor((y0 + 2 * r) / cell);\n const later: number[] = [];\n now.clear();\n for (const j of wait) {\n if (dd[j]! > r) later.push(j);\n else now.add(dd[j]!, j);\n }\n for (let bi = i0; bi <= i1; bi++) {\n const before = bi >= pi0 && bi <= pi1;\n for (let bj = j0; bj <= j1; bj++) {\n if (before && bj >= pj0 && bj <= pj1) continue;\n const list = this.#buckets.get(bucketKey(bi, bj));\n if (list === undefined) continue;\n for (const j of list) {\n if (j === self) continue;\n const d = dist(p, points[j]!);\n dd[j] = d;\n if (d > r) later.push(j);\n else now.add(d, j);\n }\n }\n }\n // The heap gives the corners nearest first, and equal distances by index. A call often stops after a few corners.\n now.build();\n while (now.size > 0) {\n const j = now.pop();\n // A node that stopped an earlier segment often stops this segment too, so the test takes these nodes first.\n // The order of the nodes does not change the result.\n const q = points[j]!;\n const cone = cones ? coneOf(q.x - p.x, q.y - p.y) : 0;\n if (out.length >= k) {\n // After the k nearest corners, only a corner of an empty cone counts, up to `CONE_CELLS` cells from `p`.\n if (dd[j]! > reach) return out;\n if ((full & cone) !== 0) continue;\n }\n let blocked = false;\n for (let b = 0; b < blockers.length && !blocked; b++) blocked = hits(p, q, blockers[b]!, pad);\n if (blocked) continue;\n const hit = this.#obstacles.hit(p, q, pad);\n if (hit !== undefined) blockers.push(hit);\n else {\n out.push(j);\n full |= cone;\n if (out.length >= k && (!cones || full === 15)) return out;\n }\n }\n wait = later;\n pi0 = i0;\n pi1 = i1;\n pj0 = j0;\n pj1 = j1;\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 return this.#search([{ point: from, cost: 0 }], [{ point: to, cost: 0 }], cost, floor, this.#k * 2)?.points;\n }\n\n /**\n * This method gives the shortest path from a point of `from` to a point of `to`, or `undefined` when the graph has none.\n * The cost of a path includes the costs of its two points. One search finds the path, so this method is faster than a call of `path` for each pair.\n */\n pathAmong(from: readonly Terminal[], to: readonly Terminal[]): Among | undefined {\n const found = this.#search(from, to, undefined, 1, this.#k);\n // A straight line between two points that costs less than the found path is better. The test takes the lines in order of cost.\n const lines: Among[] = [];\n from.forEach((a, i) =>\n to.forEach((b, k) => {\n const c = a.cost + dist(a.point, b.point) + b.cost;\n if (!found || c < found.cost) lines.push({ points: [a.point, b.point], from: i, to: k, cost: c });\n }),\n );\n lines.sort((u, v) => u.cost - v.cost);\n return lines.find((l) => this.#obstacles.clear(l.points[0]!, l.points[1]!, this.#pad)) ?? found;\n }\n\n /** This method is the search (A*) of `path` and `pathAmong`. */\n #search(\n from: readonly Terminal[],\n to: readonly Terminal[],\n cost: ((i: number, j: number, d: number) => number) | undefined,\n floor: number,\n count: number,\n ): Among | undefined {\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 points = this.points;\n // The cost from each corner near a point of `to` to that point, and the index of that point.\n const goal = new Map<number, number>();\n const goalOf = new Map<number, number>();\n to.forEach((b, k) => {\n for (const j of this.#ends(b.point, count)) {\n const tail = dist(points[j]!, b.point) + b.cost;\n const now = goal.get(j);\n if (now === undefined || tail < now) {\n goal.set(j, tail);\n goalOf.set(j, k);\n }\n }\n });\n if (goal.size === 0) return undefined;\n const starts = from.map((a) => this.#ends(a.point, count));\n // Without a start and a goal in one connected part, A* finds no path. This test stops it before it visits the whole part.\n if (!starts.some((list) => this.#joined(list, goal))) return undefined;\n const heap = new MinHeap();\n const G = this.#g;\n const parentOf = this.#parent;\n const open = this.#open;\n const closed = this.#closed;\n const estimate = (p: Point): number => {\n let h = Infinity;\n for (const b of to) h = Math.min(h, dist(p, b.point));\n return floor * h;\n };\n const relax = (j: number, g: number, parent: number): void => {\n if (closed[j] === stamp) return;\n if (open[j] === stamp && G[j]! <= g) return;\n open[j] = stamp;\n G[j] = g;\n parentOf[j] = parent;\n heap.push(g + estimate(points[j]!), j);\n };\n // The parent of a first corner is -1 - i, where i is the index of its point in `from`.\n from.forEach((a, i) => {\n for (const j of starts[i]!) relax(j, a.cost + dist(a.point, points[j]!), -1 - i);\n });\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 (closed[i] === stamp) continue;\n closed[i] = stamp;\n const gi = 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 if (closed[j] === stamp) continue;\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 k = goalOf.get(bestEnd)!;\n const out: Point[] = [to[k]!.point];\n for (let i = bestEnd; ; i = parentOf[i]!) {\n out.push(points[i]!);\n if (parentOf[i]! < 0) {\n const f = -1 - parentOf[i]!;\n out.push(from[f]!.point);\n return { points: out.reverse(), from: f, to: k, cost: best };\n }\n }\n }\n\n /** This method tells if a corner of `starts` and a corner of `goal` are in one connected part of the graph. */\n #joined(starts: readonly number[], goal: ReadonlyMap<number, number>): boolean {\n const part = (this.#part ??= this.#parts());\n const goals = new Set<number>();\n for (const j of goal.keys()) goals.add(part[j]!);\n for (const j of starts) if (goals.has(part[j]!)) return true;\n return false;\n }\n\n /** This method gives the number of the connected part of each corner. */\n #parts(): Int32Array {\n const part = new Int32Array(this.points.length).fill(-1);\n const stack: number[] = [];\n let count = 0;\n for (let i = 0; i < part.length; i++) {\n if (part[i] !== -1) continue;\n part[i] = count;\n stack.push(i);\n while (stack.length > 0) {\n for (const j of this.#adj[stack.pop()!]!) {\n if (part[j] !== -1) continue;\n part[j] = count;\n stack.push(j);\n }\n }\n count++;\n }\n return part;\n }\n\n /**\n * This method gives at most `count` 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, count: number): number[] {\n const cache = count === this.#k * 2 ? this.#endCache : this.#fewCache;\n const key = `${p.x},${p.y}`;\n let out = cache.get(key);\n if (!out) {\n out = this.nearestVisible(p, count);\n if (out.length === 0) out = this.#nearestVisible(p, count, -1, 0);\n cache.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/** The options of the soft graph. */\nexport interface SoftGraphOptions {\n /** The distance from a box to its corners. */\n readonly margin: number;\n /** The number of nearest neighbours of each vertex. */\n readonly k: number;\n /**\n * The spacing of a lattice of points in the bounding box of the boxes, in units of the mean node size. The default is 3, and 0 turns it off.\n * The lattice links groups of boxes across empty space.\n */\n readonly lattice?: number;\n}\n\n/**\n * A graph whose links can go through the boxes. Its vertices are the corners of the boxes, made larger by `margin`,\n * and a lattice of points in the bounding box of the boxes. Each vertex links to its `k` nearest vertices, in view or not.\n * The graph keeps the boxes that each link goes through (`Obstacles.through`).\n * A search gives each box a cost, so a path goes through few boxes, and only through boxes of a low cost.\n */\nexport class SoftGraph {\n readonly points: Point[] = [];\n readonly #nodes: readonly Node[];\n readonly #obstacles: Obstacles;\n readonly #adj: number[][] = [];\n readonly #len: number[][] = [];\n // The indices of the nodes that each link goes through, in the order of #adj.\n readonly #through: (readonly number[])[][] = [];\n readonly #grid: Grid<number>;\n readonly #cell: number;\n readonly #k: number;\n\n /** This constructor makes the graph of the nodes. */\n constructor(nodes: readonly Node[], obstacles: Obstacles, options: SoftGraphOptions) {\n this.#nodes = nodes;\n this.#obstacles = obstacles;\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.#grid = new Grid<number>(this.#cell);\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\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 this.#add(c);\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 // The lattice stays in the bounding box of the boxes, so a path does not go around the outer edge of the board.\n const spacing = (options.lattice ?? 3) * this.#cell;\n if (spacing > 0) for (let x = x0 + spacing / 2; x < x1; x += spacing) for (let y = y0 + spacing / 2; y < y1; y += spacing) this.#add({ x, y });\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.#nearest(this.points[i]!, this.#k, i)) {\n links[i]!.add(j);\n links[j]!.add(i);\n }\n const index = new Map(nodes.map((n, i) => [n, i]));\n // The boxes of each link, found one time for the two directions of the link.\n const known = new Map<number, readonly number[]>();\n const count = this.points.length;\n links.forEach((set, i) => {\n const adj = [...set].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 this.#through.push(\n adj.map((j) => {\n const key = Math.min(i, j) * count + Math.max(i, j);\n let list = known.get(key);\n if (list === undefined) {\n const found: number[] = [];\n obstacles.through(this.points[i]!, this.points[j]!, (n) => found.push(index.get(n)!));\n list = found;\n known.set(key, list);\n }\n return list;\n }),\n );\n });\n }\n\n #add(c: Point): void {\n this.#grid.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 at most `k` vertices nearest to `p`, in view or not, nearest first, and equal distances by index. The vertex `self` does not count. */\n #nearest(p: Point, k: number, self = -1): number[] {\n const all = this.points.length - (self >= 0 ? 1 : 0);\n const want = Math.min(k, all);\n if (want <= 0) return [];\n for (let r = this.#cell; ; r *= 2) {\n const found: number[] = [];\n this.#grid.query({ x: p.x - r, y: p.y - r, w: 2 * r, h: 2 * r }, (j) => {\n if (j !== self && dist(p, this.points[j]!) <= r) found.push(j);\n });\n if (found.length >= want) {\n const d = (j: number): number => dist(p, this.points[j]!);\n return found.sort((a, b) => d(a) - d(b) || a - b).slice(0, want);\n }\n }\n }\n\n /**\n * This method gives a path of least cost from `from` to `to` (A*), with the two points as its ends.\n * The cost of a path is its length, plus `cost(n)` for each link of the path and each box `n` of that link.\n * Each cost must be 0 or more. The straight line from `from` to `to` is a path too, so the method always gives a path.\n */\n path(from: Point, to: Point, cost: (n: Node) => number): Point[] {\n const points = this.points;\n const nodes = this.#nodes;\n const extra = (a: Point, b: Point): number => {\n let c = 0;\n this.#obstacles.through(a, b, (m) => {\n c += cost(m);\n });\n return c;\n };\n let best = dist(from, to) + extra(from, to);\n let bestEnd = -1;\n const goal = new Map<number, number>();\n for (const j of this.#nearest(to, 2 * this.#k)) goal.set(j, dist(points[j]!, to) + extra(points[j]!, to));\n const n = points.length;\n const g = new Float64Array(n).fill(Infinity);\n const parent = new Int32Array(n).fill(-1);\n const closed = new Uint8Array(n);\n const heap = new MinHeap();\n for (const j of this.#nearest(from, 2 * this.#k)) {\n const c = dist(from, points[j]!) + extra(from, points[j]!);\n if (c < g[j]!) {\n g[j] = c;\n heap.push(c + dist(points[j]!, to), j);\n }\n }\n while (heap.size > 0) {\n if (heap.topKey >= best) break;\n const i = heap.pop();\n if (closed[i] === 1) continue;\n closed[i] = 1;\n const gi = 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 const through = this.#through[i]!;\n for (let m = 0; m < adj.length; m++) {\n const j = adj[m]!;\n if (closed[j] === 1) continue;\n let c = gi + len[m]!;\n for (const b of through[m]!) c += cost(nodes[b]!);\n if (c < g[j]!) {\n g[j] = c;\n parent[j] = i;\n heap.push(c + dist(points[j]!, to), j);\n }\n }\n }\n const out: Point[] = [to];\n for (let i = bestEnd; i >= 0; i = parent[i]!) out.push(points[i]!);\n out.push(from);\n return out.reverse();\n }\n}\n\n/** A link of a cone is at most this number of cells long. A longer search costs time on a dense level and finds few new links. */\nconst CONE_CELLS = 3;\n\n/** This function gives the bit of the cone of the offset (`dx`, `dy`): 1 is +x, 2 is +y, 4 is -x and 8 is -y. A diagonal offset is in a cone of the x axis. */\nconst coneOf = (dx: number, dy: number): number => (Math.abs(dx) >= Math.abs(dy) ? (dx > 0 ? 1 : 4) : dy > 0 ? 2 : 8);\n\n/** This function packs the two indices of a bucket into one number. Each index stays within ±2^20. */\nconst bucketKey = (i: number, j: number): number => (i + 1_048_576) * 2_097_152 + (j + 1_048_576);\n\n/**\n * A binary min-heap of (key, value) pairs in typed arrays. The pairs come out by key, and equal keys by value, so the order is deterministic.\n * The method `push` adds a pair to the heap. The method `add` only appends a pair, and the method `build` then makes the heap of all the pairs.\n */\nclass MinHeap {\n #d = new Float64Array(64);\n #j = new Int32Array(64);\n size = 0;\n\n /** The smallest key. */\n get topKey(): number {\n return this.#d[0]!;\n }\n\n push(key: number, value: number): void {\n this.add(key, value);\n const d = this.#d;\n const jj = this.#j;\n let i = this.size - 1;\n while (i > 0) {\n const p = (i - 1) >> 1;\n if (!(key < d[p]! || (key === d[p] && value < jj[p]!))) break;\n d[i] = d[p]!;\n jj[i] = jj[p]!;\n i = p;\n }\n d[i] = key;\n jj[i] = value;\n }\n\n clear(): void {\n this.size = 0;\n }\n\n add(d: number, j: number): void {\n if (this.size === this.#d.length) {\n const dd = new Float64Array(2 * this.size);\n dd.set(this.#d);\n this.#d = dd;\n const jj = new Int32Array(2 * this.size);\n jj.set(this.#j);\n this.#j = jj;\n }\n this.#d[this.size] = d;\n this.#j[this.size] = j;\n this.size++;\n }\n\n build(): void {\n for (let i = (this.size >> 1) - 1; i >= 0; i--) this.#down(i);\n }\n\n /** This method removes the pair with the smallest key and gives its value. */\n pop(): number {\n const top = this.#j[0]!;\n this.size--;\n if (this.size > 0) {\n this.#d[0] = this.#d[this.size]!;\n this.#j[0] = this.#j[this.size]!;\n this.#down(0);\n }\n return top;\n }\n\n #down(i: number): void {\n const d = this.#d;\n const jj = this.#j;\n const n = this.size;\n const di = d[i]!;\n const ji = jj[i]!;\n for (;;) {\n const l = 2 * i + 1;\n if (l >= n) break;\n const r = l + 1;\n let m = l;\n if (r < n && (d[r]! < d[l]! || (d[r] === d[l] && jj[r]! < jj[l]!))) m = r;\n if (!(d[m]! < di || (d[m] === di && jj[m]! < ji))) break;\n d[i] = d[m]!;\n jj[i] = jj[m]!;\n i = m;\n }\n d[i] = di;\n jj[i] = ji;\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 { center, type Box } from \"./geom.ts\";\nimport type { LevelItem, 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 /** A cell shrinks to one quarter at most this many times without a split. Then it stops. The default is 32. */\n readonly collapse?: number;\n}\n\n/** The default values of `SectionOptions`. */\nexport const SECTION_DEFAULTS: Readonly<Required<SectionOptions>> = Object.freeze({ cap: 8, maxDepth: 16, collapse: 32 });\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 ?? SECTION_DEFAULTS.cap);\n const maxDepth = options.maxDepth ?? SECTION_DEFAULTS.maxDepth;\n const collapse = options.collapse ?? SECTION_DEFAULTS.collapse;\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 < collapse; 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\n/**\n * This function examines a tree of sections from a grouping rule. It throws an error when the tree is not valid for `count` nodes.\n * In a valid tree, each node is in exactly one leaf. The children of a section split its nodes, and a child is one level deeper than its parent.\n */\nexport function checkSections(root: Section, count: number): void {\n const seen = new Array<number>(count).fill(0);\n const ids = new Set<string>();\n const fail = (s: Section, what: string): never => {\n throw new Error(`The tree of sections is not valid at the section \"${s.id}\": ${what}.`);\n };\n if (root.depth !== 0) fail(root, \"the root has a depth that is not 0\");\n if (root.nodes.length !== count) fail(root, `the root has ${root.nodes.length} nodes, and the graph has ${count}`);\n const walk = (s: Section): void => {\n if (ids.has(s.id)) fail(s, \"two sections have this id\");\n ids.add(s.id);\n if (s.children.length === 0) {\n for (const i of s.nodes) {\n if (!Number.isInteger(i) || i < 0 || i >= count) fail(s, `the node index ${i} is not in the graph`);\n seen[i]!++;\n }\n return;\n }\n let total = 0;\n const own = new Set(s.nodes);\n for (const c of s.children) {\n if (c.depth !== s.depth + 1) fail(c, \"a child is not one level deeper than its parent\");\n for (const i of c.nodes) if (!own.has(i)) fail(c, `the node index ${i} is not in the parent`);\n total += c.nodes.length;\n walk(c);\n }\n if (total !== s.nodes.length) fail(s, \"the children do not split the nodes of the section\");\n };\n walk(root);\n const lost = seen.findIndex((n) => n !== 1);\n if (lost >= 0) fail(root, `the node index ${lost} is in ${seen[lost]} leaves, not in one`);\n}\n\n/** The items of one zoom level of a tree of sections, and the item of each node. */\nexport interface LevelCut {\n /** The items of the level: a section of the depth of the level, or one node of a leaf above that depth. */\n readonly items: LevelItem[];\n /** The index in `items` of the item of each node, in the order of the nodes. */\n readonly owner: readonly number[];\n}\n\n/**\n * This function gives the items of the zoom level at `depth`. A section of that depth is one item, with the bounding box of its nodes.\n * A node of a leaf above that depth is an item alone. The items come in the order of the walk of the tree, parents before children.\n * A depth past the depth of the deepest section gives each node alone.\n */\nexport function levelCut(nodes: readonly Pick<Node, \"id\" | \"box\">[], root: Section, depth: number): LevelCut {\n const items: LevelItem[] = [];\n const owner: 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 = 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 >= depth) {\n for (const i of s.nodes) owner[i] = items.length;\n items.push({ id: s.id, box: boxOf(s.nodes), nodes: s.nodes.map((i) => nodes[i]!.id) });\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 = nodes[i]!;\n owner[i] = items.length;\n items.push({ id: n.id, box: n.box, nodes: [n.id] });\n }\n };\n if (nodes.length > 0) visit(root);\n return { items, owner };\n}\n","import type { Graph } from \"../../model.ts\";\nimport { buildSections, type Section, type SectionOptions } from \"../../sections.ts\";\n\n/**\n * This function gives the tree of sections of the grouping rule `quadtree`: the cells of a quadtree of the plane (`buildSections`).\n * It is the default grouping rule of the router `sections`.\n */\nexport function quadtreeGroups(graph: Graph, options: SectionOptions = {}): Section {\n return buildSections(graph.nodes, options);\n}\n","import type { Box } from \"../../geom.ts\";\nimport type { Graph, Node } from \"../../model.ts\";\nimport { buildSections, type Section, type SectionOptions } from \"../../sections.ts\";\n\n/** A key rule gives the key of the group of a node. A node without a key is a group alone. */\nexport type NodeKey = (node: Node, index: number) => string | undefined;\n\n/** The options of the grouping rule `keys`. */\nexport interface KeyOptions {\n /** This function gives the key of the group of each node. The default is `byDataGroup`. */\n readonly key?: NodeKey;\n /**\n * With this value, a group with more nodes than its `cap` splits into the cells of a quadtree, as `buildSections` does.\n * Without it, each group is one leaf. The default is no split.\n */\n readonly split?: SectionOptions;\n}\n\n/** This key rule gives the string `data.group` of the node, or `undefined` when the node has no such string. */\nexport const byDataGroup: NodeKey = (node) => {\n const group = node.data?.[\"group\"];\n return typeof group === \"string\" ? group : undefined;\n};\n\n/** This function gives the bounding box of the boxes of the nodes of the list. */\nfunction boundsOf(nodes: readonly Node[], 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 = 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 list.length ? { x: x0, y: y0, w: x1 - x0, h: y1 - y0 } : { x: 0, y: 0, w: 0, h: 0 };\n}\n\n/**\n * This function gives the tree of sections of the grouping rule `keys`. The root holds each node. Each child of the root holds the nodes of one key,\n * in the order of their first node. The id of a group is `s:` and its key. A node without a key is a group alone, with the id `s#` and its index.\n * Thus the far view of the router `sections` shows one item for each group.\n */\nexport function keyedSections(nodes: readonly Node[], options: KeyOptions = {}): Section {\n const key = options.key ?? byDataGroup;\n const groups = new Map<string, number[]>();\n nodes.forEach((n, i) => {\n const k = key(n, i);\n const id = k === undefined ? `s#${i}` : `s:${k}`;\n const list = groups.get(id);\n if (list) list.push(i);\n else groups.set(id, [i]);\n });\n const children = [...groups].map(([id, list]) => group(nodes, id, list, options.split));\n return { id: \"s\", depth: 0, cell: boundsOf(nodes, nodes.map((_, i) => i)), nodes: nodes.map((_, i) => i), children };\n}\n\n/** This function gives the section of one group at depth 1. With `split`, the section has the quadtree of its nodes below it. */\nfunction group(nodes: readonly Node[], id: string, list: readonly number[], split: SectionOptions | undefined): Section {\n if (!split) return { id, depth: 1, cell: boundsOf(nodes, list), nodes: list, children: [] };\n const tree = buildSections(\n list.map((i) => nodes[i]!),\n split,\n );\n // The quadtree numbers the nodes of the group from 0. Each section gets the indices of the graph, one more level and the id of the group before its path.\n const rebase = (s: Section): Section => ({\n id: s.id === \"s\" ? id : `${id}/${s.id.slice(1)}`,\n depth: s.depth + 1,\n cell: s.cell,\n nodes: s.nodes.map((j) => list[j]!),\n children: s.children.map(rebase),\n });\n return rebase(tree);\n}\n\n/** This function gives the tree of sections of the grouping rule `keys` for a graph. */\nexport function keyGroups(graph: Graph, options: KeyOptions = {}): Section {\n return keyedSections(graph.nodes, options);\n}\n","import { center, type Box, type Point } from \"../../geom.ts\";\nimport type { Graph, Node } from \"../../model.ts\";\nimport type { Section } from \"../../sections.ts\";\n\n/** The place of the line of a split of the rule `kd`. */\nexport type KdLine = \"median\" | \"middle\" | \"slide\";\n\n/** The axis of each split of the rule `kd`. */\nexport type KdAxis = \"longer\" | \"alternate\";\n\n/** The options of the grouping rule `kd` (S3 of GRP-R). */\nexport interface KdOptions {\n /** A section with more nodes splits. The default is 8, as for the quadtree. */\n readonly cap?: number;\n /** The tree stops at this depth. The default is 16. */\n readonly maxDepth?: number;\n /**\n * This value sets the place of the line in the cell. The value `median` puts half of the nodes on each side. The value `middle` cuts the cell in half,\n * and an empty half makes the cell shrink to the other half. The value `slide` cuts the cell in half, and a line with an empty side slides to the nearest node.\n * The default is `slide`.\n */\n readonly line?: KdLine;\n /** The number of children of a section: 2 or 4. With 4, a section splits two times on one level. The default is 4. */\n readonly fanout?: number;\n /** The value `longer` cuts across the longer side of the cell. The value `alternate` cuts across x, then y, then x again. The default is `longer`. */\n readonly axis?: KdAxis;\n}\n\n/** The default values of `KdOptions`. */\nexport const KD_DEFAULTS: Readonly<Required<KdOptions>> = Object.freeze({ cap: 8, maxDepth: 16, line: \"slide\", fanout: 4, axis: \"longer\" });\n\n/** One child of a split: the digit of its id, its cell and the indices of its nodes, in the order of the graph. */\nexport interface SplitPart {\n readonly digit: number;\n readonly cell: Box;\n readonly list: readonly number[];\n}\n\n/** A split rule gives the children of a section, or `undefined` when the section cannot split. */\nexport type SplitRule = (list: readonly number[], cell: Box, depth: number) => readonly SplitPart[] | undefined;\n\n/** This function gives the bounding box of the boxes of the nodes. */\nexport function nodeBounds(nodes: readonly Node[]): 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 return nodes.length ? { x: x0, y: y0, w: x1 - x0, h: y1 - y0 } : { x: 0, y: 0, w: 0, h: 0 };\n}\n\n/**\n * This function makes a tree of sections with a split rule. The root cell is the bounding box of the nodes.\n * A section with more than `cap` nodes, above `maxDepth`, gets the children of the rule. A child without nodes does not become a section.\n * The id of a child is the id of its parent and the digit of the child.\n */\nexport function growSections(nodes: readonly Node[], cap: number, maxDepth: number, rule: SplitRule): Section {\n const limit = Math.max(1, cap);\n const make = (id: string, depth: number, cell: Box, list: readonly number[]): Section => {\n if (list.length > limit && depth < maxDepth) {\n const parts = (rule(list, cell, depth) ?? []).filter((p) => p.list.length > 0);\n if (parts.length > 1) return { id, depth, cell, nodes: list, children: parts.map((p) => make(`${id}${p.digit}`, depth + 1, p.cell, p.list)) };\n }\n return { id, depth, cell, nodes: list, children: [] };\n };\n return make(\n \"s\",\n 0,\n nodeBounds(nodes),\n nodes.map((_, i) => i),\n );\n}\n\n/** This function gives the coordinate of a point on an axis: 0 is x, and 1 is y. */\nexport const coord = (p: Point, axis: 0 | 1): number => (axis === 0 ? p.x : p.y);\n\n/** This function gives the two halves of a cell, cut across the axis at the coordinate `at`. */\nexport function halves(cell: Box, axis: 0 | 1, at: number): [Box, Box] {\n if (axis === 0) {\n const w = Math.min(cell.w, Math.max(0, at - cell.x));\n return [\n { x: cell.x, y: cell.y, w, h: cell.h },\n { x: cell.x + w, y: cell.y, w: cell.w - w, h: cell.h },\n ];\n }\n const h = Math.min(cell.h, Math.max(0, at - cell.y));\n return [\n { x: cell.x, y: cell.y, w: cell.w, h },\n { x: cell.x, y: cell.y + h, w: cell.w, h: cell.h - h },\n ];\n}\n\n/** This function puts each node of the list on its side of a split: `low` tells if a node goes to the first part. Each part keeps the order of the graph. */\nexport function sides(list: readonly number[], low: (i: number) => boolean): [number[], number[]] {\n const a: number[] = [];\n const b: number[] = [];\n for (const i of list) (low(i) ? a : b).push(i);\n return [a, b];\n}\n\n/** This function gives the nodes of the list in the order of their centers on the axis. Two nodes at one coordinate keep the order of the graph. */\nexport function sortOn(list: readonly number[], centers: readonly Point[], axis: 0 | 1): number[] {\n return [...list].sort((i, j) => coord(centers[i]!, axis) - coord(centers[j]!, axis) || i - j);\n}\n\n/** The most times that the rule `middle` shrinks a cell to one half without a split. The quadtree has the same limit (`collapse`). */\nconst SHRINK = 32;\n\n/** This function splits the list in two on one axis with the line rule. It gives `undefined` when no line of the rule has a node on each side. */\nfunction lineSplit(list: readonly number[], cell: Box, centers: readonly Point[], axis: 0 | 1, line: KdLine): [SplitPart, SplitPart] | undefined {\n const c = (i: number): number => coord(centers[i]!, axis);\n const part = (cells: [Box, Box], [a, b]: [number[], number[]]): [SplitPart, SplitPart] | undefined =>\n a.length > 0 && b.length > 0\n ? [\n { digit: 0, cell: cells[0], list: a },\n { digit: 1, cell: cells[1], list: b },\n ]\n : undefined;\n const lo = axis === 0 ? cell.x : cell.y;\n const size = axis === 0 ? cell.w : cell.h;\n if (line === \"median\") {\n const order = sortOn(list, centers, axis);\n const k = Math.floor(order.length / 2);\n const rank = new Map(order.map((i, r) => [i, r]));\n const at = (c(order[k - 1]!) + c(order[k]!)) / 2;\n return part(\n halves(cell, axis, at),\n sides(list, (i) => rank.get(i)! < k),\n );\n }\n if (line === \"slide\") {\n const mid = lo + size / 2;\n let [a, b] = sides(list, (i) => c(i) < mid);\n let at = mid;\n if (a.length === 0) {\n // Each center is at the middle or past it. The line slides to the nearest center, and the nodes at that coordinate go to the first part.\n at = list.reduce((m, i) => Math.min(m, c(i)), Infinity);\n [a, b] = sides(list, (i) => c(i) <= at);\n } else if (b.length === 0) {\n at = list.reduce((m, i) => Math.max(m, c(i)), -Infinity);\n [a, b] = sides(list, (i) => c(i) < at);\n }\n return part(halves(cell, axis, at), [a, b]);\n }\n // The rule `middle`: an empty half makes the cell shrink to the other half, up to `SHRINK` times.\n let box = cell;\n for (let n = 0; n < SHRINK; n++) {\n const blo = axis === 0 ? box.x : box.y;\n const bsize = axis === 0 ? box.w : box.h;\n if (!(bsize > 0)) return undefined;\n const mid = blo + bsize / 2;\n const split = sides(list, (i) => c(i) < mid);\n const cells = halves(box, axis, mid);\n if (split[0].length > 0 && split[1].length > 0) return part(cells, split);\n box = split[0].length > 0 ? cells[0] : cells[1];\n }\n return undefined;\n}\n\n/** This function gives the axes of one binary split, in the order to try: the axis of the rule first, then the other axis. */\nfunction axesOf(cell: Box, axis: KdAxis, step: number): [0 | 1, 0 | 1] {\n const first: 0 | 1 = axis === \"longer\" ? (cell.w >= cell.h ? 0 : 1) : step % 2 === 0 ? 0 : 1;\n return first === 0 ? [0, 1] : [1, 0];\n}\n\n/** This function splits the list in two with the line rule. When no line on the first axis has a node on each side, it tries the other axis. */\nfunction binarySplit(list: readonly number[], cell: Box, centers: readonly Point[], o: Readonly<Required<KdOptions>>, step: number): [SplitPart, SplitPart] | undefined {\n for (const axis of axesOf(cell, o.axis, step)) {\n const split = lineSplit(list, cell, centers, axis, o.line);\n if (split) return split;\n }\n return undefined;\n}\n\n/**\n * This function makes a split rule of fan-out 4 from a binary split. The binary split cuts the section in two. Then it cuts each half with 2 nodes or more.\n * The digit of a quarter is 2 times the digit of its half plus its own digit. A half that does not split keeps the digit of its first quarter.\n */\nexport function twoSteps(binary: (list: readonly number[], cell: Box, step: number) => readonly SplitPart[] | undefined, fanout: number): SplitRule {\n return (list, cell, depth) => {\n if (fanout < 4) return binary(list, cell, depth);\n const first = binary(list, cell, 2 * depth);\n if (!first) return undefined;\n return first.flatMap((half) => {\n const second = half.list.length >= 2 ? binary(half.list, half.cell, 2 * depth + 1) : undefined;\n return second ? second.map((q) => ({ ...q, digit: 2 * half.digit + q.digit })) : [{ ...half, digit: 2 * half.digit }];\n });\n };\n}\n\n/**\n * This function gives the tree of sections of the grouping rule `kd`: a k-d tree of the plane (S3 of GRP-R).\n * A section with more than `cap` nodes splits in two with a line across one axis. With the fan-out 4, each half splits again on the same level.\n * The cells nest and do not overlap. The line `median` gives halves of equal size.\n */\nexport function kdGroups(graph: Graph, options: KdOptions = {}): Section {\n const o: Required<KdOptions> = { ...KD_DEFAULTS, ...options };\n const centers = graph.nodes.map((n) => center(n.box));\n const fanout = o.fanout >= 4 ? 4 : 2;\n const binary = (list: readonly number[], cell: Box, step: number): readonly SplitPart[] | undefined => binarySplit(list, cell, centers, o, step);\n return growSections(graph.nodes, o.cap, o.maxDepth, twoSteps(binary, fanout));\n}\n","import { center, type Box, type Point } from \"../../geom.ts\";\nimport type { Graph } from \"../../model.ts\";\nimport type { Section } from \"../../sections.ts\";\nimport { coord, growSections, halves, sides, sortOn, type SplitPart } from \"../kd/index.ts\";\n\n/** The cost of a line of the rule `cut`, from the cut `c` and the parts `A` and `B` of the split. */\nexport type CutObjective = \"ratio\" | \"normalized\" | \"sparsest\";\n\n/** The options of the grouping rule `cut` (M1 of GRP-R, the guillotine cut). */\nexport interface CutOptions {\n /** A section with more nodes splits. The default is 8, as for the quadtree. */\n readonly cap?: number;\n /** The tree stops at this depth. The default is 16. */\n readonly maxDepth?: number;\n /** The number of children of a section: 2 or 4. With 4, a section splits two times on one level. The default is 4. */\n readonly fanout?: number;\n /** The smallest share of the nodes in each part of a split (`β`), from 0.05 to 0.5. The default is 0.25. */\n readonly balance?: number;\n /**\n * The cost of a line. The value `ratio` is `c / min(|A|, |B|)`. The value `normalized` is `c / vol(A) + c / vol(B)`, with `vol` the sum of the degrees\n * inside the section. The value `sparsest` is `c / (|A| · |B|)`. The default is `ratio`.\n */\n readonly objective?: CutObjective;\n /**\n * The cost of a line grows by the factor `1 + pull · d`. The value `d` is the distance of the line from the middle of the cell, as a share of the side.\n * A large value prefers the middle line, as the quadtree does. The default is 0.5.\n */\n readonly pull?: number;\n /**\n * With `true`, each section also tests the split of the quadtree, and keeps the split that cuts fewer edges.\n * Thus no section cuts more edges than the quadtree split of its cell. With the fan-out 2, the test uses each midline of the cell. The default is `true`.\n */\n readonly guard?: boolean;\n}\n\n/** The default values of `CutOptions`. */\nexport const CUT_DEFAULTS: Readonly<Required<CutOptions>> = Object.freeze({ cap: 8, maxDepth: 16, fanout: 4, balance: 0.25, objective: \"ratio\", pull: 0.5, guard: true });\n\n/** A split with the number of edges between its parts. */\ninterface CutSplit {\n readonly parts: readonly SplitPart[];\n readonly cut: number;\n}\n\n/** The most times that the guard shrinks a cell to one quarter without a split, as `buildSections` does. */\nconst SHRINK = 32;\n\n/**\n * This function gives the tree of sections of the grouping rule `cut`: a guillotine cut that reads the edges (M1 of GRP-R).\n * A section with more than `cap` nodes splits in two along the line with the lowest cost, on either axis. A line goes between two centers.\n * Each part of a split holds at least the share `balance` of the nodes. With the fan-out 4, each half splits again on the same level.\n *\n * The cells nest and do not overlap. The option `guard` keeps the split of the quadtree when that split cuts fewer edges.\n */\nexport function cutGroups(graph: Graph, options: CutOptions = {}): Section {\n const o: Required<CutOptions> = { ...CUT_DEFAULTS, ...options };\n const fanout = o.fanout >= 4 ? 4 : 2;\n const balance = Math.min(0.5, Math.max(0, o.balance));\n const pull = Math.max(0, o.pull);\n const nodes = graph.nodes;\n const n = nodes.length;\n const centers: Point[] = nodes.map((v) => center(v.box));\n const cx = Float64Array.from(centers, (c) => c.x);\n const cy = Float64Array.from(centers, (c) => c.y);\n const index = new Map(nodes.map((v, i) => [v.id, i]));\n const adj: number[][] = nodes.map(() => []);\n for (const e of graph.edges) {\n const a = index.get(e.source.node);\n const b = index.get(e.target.node);\n if (a === undefined || b === undefined || a === b) continue;\n adj[a]!.push(b);\n adj[b]!.push(a);\n }\n const mark = new Int32Array(n);\n const rank = new Int32Array(n);\n const degree = new Float64Array(n);\n const owner = new Int32Array(n);\n let token = 0;\n // The orders of the nodes of a part on each axis, by the list of the part. A split hands the orders of a section down to its parts, so only the root sorts.\n const orders = new WeakMap<readonly number[], readonly [number[], number[]]>();\n const ordersOf = (list: readonly number[]): readonly [number[], number[]] => {\n let both = orders.get(list);\n if (!both) {\n both = [sortOn(list, centers, 0), sortOn(list, centers, 1)];\n orders.set(list, both);\n }\n return both;\n };\n const handDown = (list: readonly number[], parts: readonly SplitPart[]): void => {\n parts.forEach((p, k) => {\n for (const i of p.list) owner[i] = k;\n });\n const [ox, oy] = ordersOf(list);\n const xs: number[][] = parts.map(() => []);\n const ys: number[][] = parts.map(() => []);\n for (const i of ox) xs[owner[i]!]!.push(i);\n for (const i of oy) ys[owner[i]!]!.push(i);\n parts.forEach((p, k) => orders.set(p.list, [xs[k]!, ys[k]!]));\n };\n\n /** This function gives the edges with both ends in the list, as a flat list of index pairs. It keeps the pairs of the last list for the guard. */\n let lastList: readonly number[] | undefined;\n let lastPairs: number[] = [];\n const insideEdges = (list: readonly number[]): number[] => {\n if (list === lastList) return lastPairs;\n token++;\n for (const i of list) mark[i] = token;\n const out: number[] = [];\n for (const i of list) for (const j of adj[i]!) if (j > i && mark[j] === token) out.push(i, j);\n lastList = list;\n lastPairs = out;\n return out;\n };\n\n /** This function gives the number of edges of the list between two parts: `part` gives the part of a node. */\n const cutOf = (list: readonly number[], part: (i: number) => number): number => {\n const pairs = insideEdges(list);\n let cut = 0;\n for (let p = 0; p < pairs.length; p += 2) if (part(pairs[p]!) !== part(pairs[p + 1]!)) cut++;\n return cut;\n };\n\n /** This function gives the cost of a line. Its inputs are the cut `c`, and the sizes `a`, `b` and the volumes `va`, `vb` of the parts. */\n const objective = (c: number, a: number, b: number, va: number, vb: number): number => {\n if (o.objective === \"sparsest\") return c / (a * b);\n if (o.objective === \"normalized\") return (va > 0 ? c / va : 0) + (vb > 0 ? c / vb : 0);\n return c / Math.min(a, b);\n };\n\n /**\n * This function splits the list in two along the line with the lowest cost. It tests each line between two centers on each axis.\n * When no line keeps the share `balance` in each part, it takes the line with the largest smaller part.\n */\n const guillotine = (list: readonly number[], cell: Box): CutSplit | undefined => {\n const len = list.length;\n if (len < 2) return undefined;\n const pairs = insideEdges(list);\n for (const i of list) degree[i] = 0;\n for (const i of pairs) degree[i]!++;\n let total = 0;\n for (const i of list) total += degree[i]!;\n const minPart = Math.max(1, Math.ceil(balance * len - 1e-9));\n // The best line, and the most even line for a list where no line keeps the balance. An axis of -1 is no line.\n let bestAxis = -1;\n let bestT = 0;\n let bestAt = 0;\n let bestCut = 0;\n let bestCost = Infinity;\n let bestShare = Infinity;\n let fbAxis = -1;\n let fbT = 0;\n let fbAt = 0;\n let fbCut = 0;\n let fbSmall = 0;\n let fbShare = Infinity;\n const both = ordersOf(list);\n for (const axis of [0, 1] as const) {\n const order = both[axis];\n const at0 = axis === 0 ? cx : cy;\n for (let r = 0; r < len; r++) rank[order[r]!] = r;\n const diff = new Int32Array(len + 1);\n for (let p = 0; p < pairs.length; p += 2) {\n const ra = rank[pairs[p]!]!;\n const rb = rank[pairs[p + 1]!]!;\n if (ra < rb) {\n diff[ra + 1]!++;\n diff[rb + 1]!--;\n } else {\n diff[rb + 1]!++;\n diff[ra + 1]!--;\n }\n }\n const side = axis === 0 ? cell.w : cell.h;\n const mid = (axis === 0 ? cell.x : cell.y) + side / 2;\n let cut = 0;\n let va = 0;\n let before = at0[order[0]!]!;\n for (let t = 1; t < len; t++) {\n cut += diff[t]!;\n va += degree[order[t - 1]!]!;\n const after = at0[order[t]!]!;\n const prev = before;\n before = after;\n // A line goes between two centers, so two nodes at one coordinate stay in one part.\n if (!(after > prev)) continue;\n const at = (prev + after) / 2;\n const share = side > 0 ? Math.abs(at - mid) / side : 0;\n const small = t < len - t ? t : len - t;\n if (small < minPart) {\n if (small > fbSmall || (small === fbSmall && share < fbShare)) {\n fbAxis = axis;\n fbT = t;\n fbAt = at;\n fbCut = cut;\n fbSmall = small;\n fbShare = share;\n }\n continue;\n }\n const cost = objective(cut, t, len - t, va, total - va) * (1 + pull * share);\n if (cost < bestCost - 1e-12 || (Math.abs(cost - bestCost) <= 1e-12 && share < bestShare)) {\n bestAxis = axis;\n bestT = t;\n bestAt = at;\n bestCut = cut;\n bestCost = cost;\n bestShare = share;\n }\n }\n }\n const found = bestAxis >= 0;\n const axis = (found ? bestAxis : fbAxis) as 0 | 1 | -1;\n if (axis < 0) return undefined;\n const t = found ? bestT : fbT;\n const order = both[axis as 0 | 1];\n token++;\n for (let r = 0; r < t; r++) mark[order[r]!] = token;\n const [a, b] = sides(list, (i) => mark[i] === token);\n const cells = halves(cell, axis as 0 | 1, found ? bestAt : fbAt);\n const parts: SplitPart[] = [\n { digit: 0, cell: cells[0], list: a },\n { digit: 1, cell: cells[1], list: b },\n ];\n handDown(list, parts);\n return { parts, cut: found ? bestCut : fbCut };\n };\n\n /** This function gives the guillotine split of a section. With the fan-out 2, it is one cut. With the fan-out 4, it also cuts each half. */\n const split = (list: readonly number[], cell: Box): CutSplit | undefined => {\n const first = guillotine(list, cell);\n if (!first || fanout < 4) return first;\n let cut = first.cut;\n const parts = first.parts.flatMap((half) => {\n const second = guillotine(half.list, half.cell);\n if (!second) return [{ ...half, digit: 2 * half.digit }];\n cut += second.cut;\n return second.parts.map((q) => ({ ...q, digit: 2 * half.digit + q.digit }));\n });\n return { parts, cut };\n };\n\n /**\n * This function gives the split of the quadtree at the cell, as `buildSections` makes it: four quarters at the middle of the cell.\n * When the nodes are all in one quarter, the cell shrinks to that quarter. With the fan-out 2, it gives the midline of the cell with the lower cut.\n */\n const quadSplit = (list: readonly number[], cell: Box): CutSplit | undefined => {\n if (fanout < 4) {\n let out: CutSplit | undefined;\n for (const axis of [0, 1] as const) {\n const lo = axis === 0 ? cell.x : cell.y;\n const mid = lo + (axis === 0 ? cell.w : cell.h) / 2;\n const [a, b] = sides(list, (i) => coord(centers[i]!, axis) < mid);\n if (a.length === 0 || b.length === 0) continue;\n const cut = cutOf(list, (i) => (coord(centers[i]!, axis) < mid ? 0 : 1));\n const cells = halves(cell, axis, mid);\n if (!out || cut < out.cut)\n out = {\n parts: [\n { digit: 0, cell: cells[0], list: a },\n { digit: 1, cell: cells[1], list: b },\n ],\n cut,\n };\n }\n if (out) handDown(list, out.parts);\n return out;\n }\n let box = cell;\n for (let s = 0; s < SHRINK; s++) {\n const mx = box.x + box.w / 2;\n const my = box.y + box.h / 2;\n const quarterOf = (i: number): number => (centers[i]!.x < mx ? 0 : 1) + (centers[i]!.y < my ? 0 : 2);\n const lists: number[][] = [[], [], [], []];\n for (const i of list) lists[quarterOf(i)]!.push(i);\n const quarter = (q: number): Box => ({ x: q % 2 === 0 ? box.x : mx, y: q < 2 ? box.y : my, w: box.w / 2, h: box.h / 2 });\n const full = lists.map((l, q) => ({ digit: q, cell: quarter(q), list: l })).filter((p) => p.list.length > 0);\n if (full.length > 1) {\n handDown(list, full);\n return { parts: full, cut: cutOf(list, quarterOf) };\n }\n box = full[0]?.cell ?? box;\n }\n return undefined;\n };\n\n return growSections(nodes, o.cap, o.maxDepth, (list, cell) => {\n const cut = split(list, cell);\n if (!o.guard) return cut?.parts;\n const quad = quadSplit(list, cell);\n return quad && (!cut || quad.cut < cut.cut) ? quad.parts : cut?.parts;\n });\n}\n","import type { Level } from \"./model.ts\";\n\n/** This function gives the median width of the shown items of each level, in units of the plane. */\nexport function itemSizes(levels: readonly Level[]): number[] {\n return levels.map((level) => {\n const sizes = level.items.map((i) => Math.max(i.box.w, i.box.h)).sort((a, b) => a - b);\n return sizes.length ? sizes[Math.floor(sizes.length / 2)]! : 0;\n });\n}\n\n/** The far-view thresholds of `pickLevel`, in pixels on the screen. */\nexport interface PickOptions {\n /** When a node is at least this wide on the screen, the view shows each route. */\n readonly routesAt: number;\n /** A level is fine enough when its median item is at least this wide on the screen. */\n readonly itemAt: number;\n}\n\n/** The default thresholds: a node of 22 pixels shows its routes, and a group of 120 pixels shows its parts. */\nexport const PICK: PickOptions = Object.freeze({ routesAt: 22, itemAt: 120 });\n\n/**\n * This function picks the level that a camera shows at a scale, in pixels for each unit of the plane. The sizes come from `itemSizes`.\n * The value `sizes.length` stands for the routes of each edge. The last level holds the nodes alone.\n * Each threshold that `options` does not give gets its value from `PICK`.\n */\nexport function pickLevel(sizes: readonly number[], scale: number, options: Partial<PickOptions> = PICK): number {\n const routesAt = options.routesAt ?? PICK.routesAt;\n const itemAt = options.itemAt ?? PICK.itemAt;\n const n = sizes.length;\n if (n === 0) return 0;\n if (sizes[n - 1]! * scale >= routesAt) return n;\n let pick = 0;\n for (let d = 0; d < n - 1; d++) if (sizes[d]! * scale >= itemAt) pick = d;\n return pick;\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 { dist, inflate, pointSegmentDistance, polylineLength, segmentHitsBox, type Box, type Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport type { Graph, Level, Result } from \"../model.ts\";\nimport { TOLERANCE } from \"./properties.ts\";\n\n/**\n * The faults of a set of links: the routes of the edges, or the links of one zoom level.\n * Each value counts links, except `worstDetour`. Lower is better for each value.\n */\nexport interface LinkFaults {\n /** The number of links that the measure examined. */\n readonly links: number;\n /**\n * The number of links that go through the inside of a box that is not one of their two ends.\n * A segment goes through a box when a part of it longer than `TOLERANCE` is inside the box made smaller by `TOLERANCE`.\n */\n readonly through: number;\n /**\n * The number of links of `through` that no route can keep out of the other boxes.\n * Each box that such a link goes through overlaps the box of its source or of its target, as `countOverlaps` sees it.\n */\n readonly unavoidable: number;\n /** The number of links of `through` that go through at least one box that overlaps neither end. `through` is `unavoidable` plus `avoidable`. */\n readonly avoidable: number;\n /**\n * The number of links that go out and back. The distance from a point of the link to its last point grows after the nearest approach.\n * A link goes out and back when this growth is more than `BACKTRACK_SHARE` of the distance between its ends, and more than `BACKTRACK_MIN` units.\n */\n readonly backtrack: number;\n /** The largest ratio of the length of a link to the distance between its ends. Links with ends nearer than 1 unit do not count. */\n readonly worstDetour: number;\n /**\n * The number of links with a point outside the bounding box of all the boxes, made larger by `slack`.\n * Both ends of a link are always in that bounding box, so such a link goes around the outer edge of the board.\n */\n readonly outside: number;\n}\n\n/** The faults of the links of one zoom level. */\nexport interface LevelFaults extends LinkFaults {\n readonly depth: number;\n /** The number of items of the level. */\n readonly items: number;\n /** The number of items that hold more than one node. */\n readonly groups: number;\n /** The number of pairs of items whose boxes overlap by more than `TOLERANCE` on each axis. */\n readonly overlaps: number;\n}\n\n/** The options of the link measures. */\nexport interface LinkFaultOptions {\n /** A link that goes farther than this distance outside the bounding box of all the boxes counts in `outside`. The default is 24. */\n readonly slack?: number;\n}\n\n/** A link goes out and back when its distance to its target grows by more than this share of the distance between its ends. */\nexport const BACKTRACK_SHARE = 0.25;\n/** A link goes out and back only when its distance to its target grows by more than this number of units. */\nexport const BACKTRACK_MIN = 40;\n/** The default `slack` of `LinkFaultOptions`. */\nexport const OUTSIDE_SLACK = 24;\n\n/** A link from one box to another box, as `measureLinks` sees it. */\nexport interface MeasuredLink {\n readonly source: string;\n readonly target: string;\n readonly points: readonly Point[];\n}\n\n/**\n * This function gives the largest growth of the distance to the last point of a polyline.\n * The growth at a vertex is its distance to the last point, less the nearest approach of the polyline before that vertex.\n */\nexport function backtrackOf(p: readonly Point[]): number {\n if (p.length < 3) return 0;\n const end = p[p.length - 1]!;\n let near = dist(p[0]!, end);\n let worst = 0;\n for (let i = 1; i < p.length; i++) {\n worst = Math.max(worst, dist(p[i]!, end) - near);\n near = Math.min(near, pointSegmentDistance(end, p[i - 1]!, p[i]!));\n }\n return worst;\n}\n\n/** This function tells if the polyline `p` goes out and back: `backtrackOf(p)` is more than `BACKTRACK_MIN` and more than `BACKTRACK_SHARE` of the span. */\nexport function goesOutAndBack(p: readonly Point[]): boolean {\n if (p.length < 3) return false;\n const span = dist(p[0]!, p[p.length - 1]!);\n return backtrackOf(p) > Math.max(BACKTRACK_MIN, BACKTRACK_SHARE * span);\n}\n\n/**\n * This function measures the faults of links between boxes. The map `boxes` gives the box of each end.\n * The bounding box of `outside` is the bounding box of all the boxes of the map.\n */\nexport function measureLinks(boxes: ReadonlyMap<string, Box>, links: readonly MeasuredLink[], options: LinkFaultOptions = {}): LinkFaults {\n const slack = options.slack ?? OUTSIDE_SLACK;\n let size = 0;\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const b of boxes.values()) {\n size += Math.max(b.w, b.h);\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 // Large items cover many buckets of a small grid, so the buckets grow with the items.\n const grid = new Grid<string>(Math.max(180, (2 * size) / Math.max(1, boxes.size)));\n for (const [id, b] of boxes) grid.add(id, b);\n let through = 0;\n let avoidable = 0;\n let backtrack = 0;\n let worstDetour = 0;\n let outside = 0;\n for (const l of links) {\n const p = l.points;\n if (p.length === 0) continue;\n // The test stops at the first box that overlaps neither end. Before it, a box that overlaps an end only marks the link.\n let hit = false;\n let far = false;\n const ends = [boxes.get(l.source), boxes.get(l.target)].filter((b): b is Box => b !== undefined);\n for (let i = 1; i < p.length && !far; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n grid.querySegment(a, b, 0, (id) => {\n if (far || id === l.source || id === l.target) return;\n const box = boxes.get(id)!;\n if (!segmentHitsBox(a, b, inflate(box, -TOLERANCE), TOLERANCE)) return;\n hit = true;\n if (!ends.some((e) => boxesOverlap(e, box))) far = true;\n });\n }\n if (hit) through++;\n if (far) avoidable++;\n if (goesOutAndBack(p)) backtrack++;\n const span = dist(p[0]!, p[p.length - 1]!);\n if (span > 1) worstDetour = Math.max(worstDetour, polylineLength(p) / span);\n if (p.some((q) => q.x < x0 - slack || q.x > x1 + slack || q.y < y0 - slack || q.y > y1 + slack)) outside++;\n }\n return { links: links.length, through, unavoidable: through - avoidable, avoidable, backtrack, worstDetour, outside };\n}\n\n/** This function tells if two boxes overlap by more than `TOLERANCE` on each axis, as `countOverlaps` counts them. */\nexport function boxesOverlap(a: Box, b: Box): boolean {\n return Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x) > TOLERANCE && Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y) > TOLERANCE;\n}\n\n/** This function measures the faults of the routes of a result. The ends of a route are the nodes of its edge. */\nexport function measureRouteFaults(graph: Graph, result: Result, options: LinkFaultOptions = {}): LinkFaults {\n const boxes = new Map(graph.nodes.map((n) => [n.id, n.box]));\n const edges = new Map(graph.edges.map((e) => [e.id, e]));\n const links: MeasuredLink[] = [];\n for (const r of result.routes) {\n const e = edges.get(r.edge);\n if (e) links.push({ source: e.source.node, target: e.target.node, points: r.points });\n }\n return measureLinks(boxes, links, options);\n}\n\n/** This function counts the pairs of boxes that overlap by more than `TOLERANCE` on each axis. */\nexport function countOverlaps(boxes: readonly Box[]): number {\n let size = 0;\n for (const b of boxes) size += Math.max(b.w, b.h);\n const grid = new Grid<number>(Math.max(180, (2 * size) / Math.max(1, boxes.length)));\n boxes.forEach((b, i) => grid.add(i, b));\n let n = 0;\n boxes.forEach((a, i) => {\n grid.query(a, (j) => {\n if (j > i && boxesOverlap(a, boxes[j]!)) n++;\n });\n });\n return n;\n}\n\n/** This function measures the faults of the links of one zoom level. The items of the level are the boxes. */\nexport function measureLevel(level: Level, options: LinkFaultOptions = {}): LevelFaults {\n const boxes = new Map(level.items.map((i) => [i.id, i.box]));\n return {\n depth: level.depth,\n items: level.items.length,\n groups: level.items.filter((i) => i.nodes.length > 1).length,\n overlaps: countOverlaps(level.items.map((i) => i.box)),\n ...measureLinks(boxes, level.links, options),\n };\n}\n\n/**\n * This function measures the faults of each zoom level of a result that has groups: the levels of the far view.\n * A level of single nodes only is the near view. Its links are routes, and `measureRouteFaults` measures them.\n */\nexport function measureLevelFaults(result: Result, options: LinkFaultOptions = {}): LevelFaults[] {\n return (result.levels ?? []).filter((l) => l.items.some((i) => i.nodes.length > 1)).map((l) => measureLevel(l, options));\n}\n\n/** This function adds the faults of several levels: it sums the counts and keeps the largest `worstDetour`. */\nexport function sumFaults(list: readonly LinkFaults[]): LinkFaults {\n return list.reduce<LinkFaults>(\n (s, f) => ({\n links: s.links + f.links,\n through: s.through + f.through,\n unavoidable: s.unavoidable + f.unavoidable,\n avoidable: s.avoidable + f.avoidable,\n backtrack: s.backtrack + f.backtrack,\n worstDetour: Math.max(s.worstDetour, f.worstDetour),\n outside: s.outside + f.outside,\n }),\n { links: 0, through: 0, unavoidable: 0, avoidable: 0, backtrack: 0, worstDetour: 0, outside: 0 },\n );\n}\n","import { boxesOverlap, goesOutAndBack } from \"./bench/links.ts\";\nimport { center, dist, polylineLength, 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, SoftGraph } 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\n/** The free plugs of a node, and the reach of each plug. */\ninterface FreePlugs {\n readonly plugs: readonly Plug[];\n readonly reach: readonly number[];\n}\n\n/** The ways of a level, with a second corner graph and the free plugs of the nodes. */\ninterface LevelWays extends Ways {\n /** This function gives a second corner graph with a small margin. The first link that needs it makes it. */\n readonly tight: () => CornerGraph;\n /** The free plugs of each node that a link needed. */\n readonly free: Map<Node, FreePlugs>;\n /** This function gives the graph of `SoftGraph`. The first link that needs it makes it. */\n readonly soft: () => SoftGraph;\n /** The mean size of the boxes: the mean of the larger side of each box. */\n readonly size: number;\n}\n\n/** The options of the links of a level: the options of the ways, and two limits of the level links. */\nexport interface LevelLinkOptions extends WayOptions {\n /**\n * The margin of the second corner graph. A gap between two boxes wider than approximately 1.5 times this margin lets a link through.\n * The second graph uses the smaller of this value and `margin`. The default is 1.\n */\n readonly tightMargin?: number;\n /** A plug stays at least this far from the corners of its side. The level links use the smaller of this value and `margin`. The default is 6. */\n readonly plugInset?: number;\n /**\n * The cost of a level link through a far box, in units of the mean box size. A far box overlaps neither end of the link.\n * A link through a far box gets a second way that can go through boxes (`SoftGraph`). The link keeps the way with fewer far boxes.\n * The value 0 turns the second way off and gives the links of version 0.1.5. The default is 8.\n */\n readonly throughCost?: number;\n}\n\n/** The default values of the three limits of `LevelLinkOptions`. */\nexport const LEVEL_LINK_DEFAULTS: Readonly<Required<Pick<LevelLinkOptions, \"tightMargin\" | \"plugInset\" | \"throughCost\">>> = Object.freeze({\n tightMargin: 1,\n plugInset: 6,\n throughCost: 8,\n});\n\n/** The values of `throughCost` of the sweep of ER3d in the benchmark. The value 0 gives the links of version 0.1.5. */\nexport const THROUGH_COST_SWEEP: readonly number[] = [0, 2, 4, 8, 16];\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 * A way of two points or more keeps two points: its first point and its last point.\n * Two items that touch can get a link of zero length, and such a link keeps an end on each item.\n */\nfunction tidy(p: readonly Point[]): Point[] {\n const out = tidyPoints(p);\n return out.length === 1 && p.length > 1 ? [p[0]!, p[p.length - 1]!] : out;\n}\n\n/** This function does the work of `tidy`. It can give one point only. */\nfunction tidyPoints(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: LevelLinkOptions = {}): 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(options.plugInset ?? LEVEL_LINK_DEFAULTS.plugInset, ways.margin);\n const throughCost = options.throughCost ?? LEVEL_LINK_DEFAULTS.throughCost;\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 ??= sideWay(ways, s, t, inset);\n out.push({ source: p.source, target: p.target, count: p.count, points });\n }\n if (throughCost <= 0) return out;\n // The second way never makes the worst detour of the level longer.\n const limit = out.reduce((m, l) => Math.max(m, detour(l.points)), 1);\n return out.map((l) => ({ ...l, points: fewerFar(ways, byId.get(l.source)!, byId.get(l.target)!, l.points, throughCost, limit) }));\n}\n\n/** This function gives the length of the polyline divided by the distance between its ends, as the measure `worstDetour` gives it. */\nfunction detour(p: readonly Point[]): number {\n const span = p.length > 1 ? dist(p[0]!, p[p.length - 1]!) : 0;\n return span > 1 ? polylineLength(p) / span : 1;\n}\n\n/**\n * This function gives a way from plug to plug between the plugs at the middle of a side of the two nodes.\n * Without a way in the corner graph, the link goes straight between the ends, with legs parallel to the axes where they are clear.\n * When that line goes through another box, the link goes between the free plugs of the two nodes (`freeWay`) instead.\n */\nfunction sideWay(ways: LevelWays, s: Node, t: Node, inset: number): Point[] {\n const e = ends(ways, s, sidePlug(ways, s, center(t.box)), t, sidePlug(ways, t, center(s.box)));\n const quick = quickWay(ways, e);\n if (quick) return quick;\n const path = ways.corners.path(e.a, e.b);\n const way = pulled(ways, e.ps, path ?? [e.a, e.b], e.pt);\n if (path || ways.obstacles.clearPath(way, 0, new Set([s, t]))) return way;\n return freeWay(ways, s, t, inset) ?? way;\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 * The corner graphs use `cones`, so a link goes along the corridors between the groups, not around the outer edge of the board.\n */\nfunction levelWays(nodes: readonly Node[], options: LevelLinkOptions): LevelWays {\n const margin = options.margin ?? 5;\n const k = options.k ?? 8;\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, cones: true });\n const out = (p: Plug): Point => ({ x: p.point.x + p.normal.x * margin, y: p.point.y + p.normal.y * margin });\n let tight: CornerGraph | undefined;\n const tightGraph = (): CornerGraph => (tight ??= new CornerGraph(nodes, obstacles, { margin: Math.min(margin, options.tightMargin ?? LEVEL_LINK_DEFAULTS.tightMargin), k, cones: true }));\n let soft: SoftGraph | undefined;\n const softGraph = (): SoftGraph => (soft ??= new SoftGraph(nodes, obstacles, { margin, k }));\n return { obstacles, corners, margin, out, tight: tightGraph, free: new Map(), soft: softGraph, size: size / Math.max(1, nodes.length) };\n}\n\n/** This function gives the boxes that the polyline goes through, without the boxes of `s` and `t`, and the number of far boxes among them. */\nfunction boxesThrough(ways: Ways, p: readonly Point[], s: Node, t: Node, near: ReadonlySet<Node>): { boxes: Set<Node>; far: number } {\n const boxes = new Set<Node>();\n let far = 0;\n for (let i = 1; i < p.length; i++)\n ways.obstacles.through(p[i - 1]!, p[i]!, (n) => {\n if (n === s || n === t || boxes.has(n)) return;\n boxes.add(n);\n if (!near.has(n)) far++;\n });\n return { boxes, far };\n}\n\n/** This function gives the nodes whose boxes overlap the box of `s` or the box of `t`, as `boxesOverlap` sees it. */\nfunction nearBoxes(ways: Ways, s: Node, t: Node): Set<Node> {\n const near = new Set<Node>();\n for (const end of [s, t])\n ways.obstacles.query(end.box, (n) => {\n if (n !== s && n !== t && boxesOverlap(n.box, end.box)) near.add(n);\n });\n return near;\n}\n\n/**\n * This function gives a way with fewer far boxes than `way`, or `way`. A far box overlaps neither end of the link.\n * On a walled-in level, each box overlaps its neighbours, so a link can find no way around the boxes.\n * Then a search of `SoftGraph` goes from the center of `s` to the center of `t`.\n *\n * In the search, a far box costs `cost` mean box sizes, and a near box costs one mean box size.\n * The way starts where the path leaves the box of `s` for the last time. It ends where the path then first enters the box of `t`.\n * The link keeps `way` when the new way goes out and back and `way` does not.\n * It also keeps `way` when the detour of the new way is longer than `limit`.\n */\nfunction fewerFar(ways: LevelWays, s: Node, t: Node, way: readonly Point[], cost: number, limit: number): readonly Point[] {\n const near = nearBoxes(ways, s, t);\n const before = boxesThrough(ways, way, s, t, near);\n if (before.far === 0) return way;\n const far = cost * ways.size;\n const path = ways.soft().path(center(s.box), center(t.box), (n) => (n === s || n === t ? 0 : near.has(n) ? ways.size : far));\n const clipped = clip(path, s.box, t.box);\n if (!clipped) return way;\n const soft = tidy(pullThrough(ways, clipped, s, t));\n // A way that goes out and back is a new fault, so the link keeps the old way.\n if (goesOutAndBack(soft) && !goesOutAndBack(way)) return way;\n if (detour(soft) > limit) return way;\n return boxesThrough(ways, soft, s, t, near).far < before.far ? soft : way;\n}\n\n/** This function tells if the point is inside the box, not on its boundary. */\nconst within = (p: Point, b: Box): boolean => p.x > b.x && p.x < b.x + b.w && p.y > b.y && p.y < b.y + b.h;\n\n/** This function gives the point where the segment from `a`, inside the box, to `b` leaves the box. */\nfunction exitPoint(a: Point, b: Point, box: Box): Point {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n let u = 1;\n if (dx > 0) u = Math.min(u, (box.x + box.w - a.x) / dx);\n if (dx < 0) u = Math.min(u, (box.x - a.x) / dx);\n if (dy > 0) u = Math.min(u, (box.y + box.h - a.y) / dy);\n if (dy < 0) u = Math.min(u, (box.y - a.y) / dy);\n u = Math.max(0, u);\n return { x: a.x + u * dx, y: a.y + u * dy };\n}\n\n/**\n * This function cuts a path from the inside of the box `a` to the inside of the box `b`. The cut path starts where the path leaves `a` for the last time.\n * It ends where the path then first enters `b`. It gives `undefined` when no such part is left.\n */\nfunction clip(p: readonly Point[], a: Box, b: Box): Point[] | undefined {\n let i = -1;\n for (let k = 0; k < p.length; k++) if (within(p[k]!, a)) i = k;\n if (i < 0 || i === p.length - 1) return undefined;\n let j = -1;\n for (let k = i + 1; k < p.length && j < 0; k++) if (within(p[k]!, b)) j = k;\n if (j < 0) return undefined;\n const start = exitPoint(p[i]!, p[i + 1]!, a);\n const end = exitPoint(p[j]!, p[j - 1]!, b);\n if (within(start, b) || within(end, a)) return undefined;\n return [start, ...p.slice(i + 1, j), end];\n}\n\n/**\n * This function pulls a soft path tight. From each vertex, it goes to the farthest vertex of the next 16 vertices with a straight line.\n * The line can go only through the boxes that the path between the two vertices goes through.\n */\nfunction pullThrough(ways: Ways, p: readonly Point[], s: Node, t: Node, lookahead = 16): Point[] {\n if (p.length < 3) return [...p];\n const boxesOf = (a: Point, b: Point): Node[] => {\n const out: Node[] = [];\n ways.obstacles.through(a, b, (n) => {\n if (n !== s && n !== t) out.push(n);\n });\n return out;\n };\n // The boxes of each leg of the path, found one time.\n const legs = p.map((q, m) => (m === 0 ? [] : boxesOf(p[m - 1]!, q)));\n const out: Point[] = [p[0]!];\n let i = 0;\n while (i < p.length - 1) {\n let next = i + 1;\n const last = Math.min(p.length - 1, i + lookahead);\n // The boxes of the path from vertex i to each vertex j.\n const along: Set<Node>[] = [];\n let seen = new Set<Node>();\n for (let j = i + 1; j <= last; j++) {\n seen = new Set([...seen, ...legs[j]!]);\n along[j] = seen;\n }\n for (let j = last; j > i + 1; j--) {\n if (boxesOf(p[i]!, p[j]!).every((n) => along[j]!.has(n))) {\n next = j;\n break;\n }\n }\n out.push(p[next]!);\n i = next;\n }\n return out;\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/**\n * This function gives the free plugs of a node: on each side, the free point nearest to the middle of the side.\n * A point is free when it and the point at `margin` from it are in no other box. The function keeps the plugs of each node.\n */\nfunction freePlugs(ways: LevelWays, node: Node, inset: number): FreePlugs {\n const known = ways.free.get(node);\n if (known) return known;\n const b = node.box;\n const out: Plug[] = [];\n for (const side of SIDES) {\n const n = SIDE_NORMAL[side];\n const across = n.x === 0;\n // The side goes from `lo` to `hi` along its axis, at the coordinate `at` of the other axis.\n const lo = across ? b.x : b.y;\n const hi = across ? b.x + b.w : b.y + b.h;\n const at = across ? (n.y > 0 ? b.y + b.h : b.y) : n.x > 0 ? b.x + b.w : b.x;\n const far = at + (across ? n.y : n.x) * ways.margin;\n // A box covers a point of the side when the point or its way out is inside the box, as in `isFree`.\n const covered: [number, number][] = [];\n const strip = across\n ? { x: lo, y: Math.min(at, far), w: hi - lo, h: Math.abs(far - at) }\n : { x: Math.min(at, far), y: lo, w: Math.abs(far - at), h: hi - lo };\n ways.obstacles.query(strip, (m) => {\n if (m === node) return;\n const o = m.box;\n const [o0, o1, p0, p1] = across ? [o.x, o.x + o.w, o.y, o.y + o.h] : [o.y, o.y + o.h, o.x, o.x + o.w];\n if ((at > p0 && at < p1) || (far > p0 && far < p1)) covered.push([o0, o1]);\n });\n const mid = (lo + hi) / 2;\n let best: number | undefined;\n for (const [f0, f1] of freeSpans(lo, hi, covered)) {\n const room = Math.min(inset, (f1 - f0) / 2);\n const u = Math.max(f0 + room, Math.min(f1 - room, mid));\n if (best === undefined || Math.abs(u - mid) < Math.abs(best - mid)) best = u;\n }\n if (best !== undefined) out.push({ point: across ? { x: best, y: at } : { x: at, y: best }, normal: n });\n }\n const free = { plugs: out, reach: out.map((p) => reach(ways, node, p)) };\n ways.free.set(node, free);\n return free;\n}\n\n/** This function gives the indices of the plugs, and the plugs that face `toward` most come first. */\nfunction facingOrder(plugs: readonly Plug[], from: Point, toward: Point): number[] {\n const facing = (p: Plug): number => p.normal.x * (toward.x - from.x) + p.normal.y * (toward.y - from.y);\n return plugs.map((_, i) => i).sort((u, v) => facing(plugs[v]!) - facing(plugs[u]!) || u - v);\n}\n\n/** This function gives the parts of the span from `lo` to `hi` outside each open interval of `covered`. A part of zero length does not count. */\nfunction freeSpans(lo: number, hi: number, covered: [number, number][]): [number, number][] {\n covered.sort((u, v) => u[0] - v[0]);\n const out: [number, number][] = [];\n let x = lo;\n for (const [c0, c1] of covered) {\n if (c0 > x) out.push([x, Math.min(c0, hi)]);\n x = Math.max(x, c1);\n if (x >= hi) break;\n }\n if (x < hi) out.push([x, hi]);\n return out.filter(([a, b]) => b - a > EPS);\n}\n\n/**\n * This function gives the shortest way between the free plugs of the two nodes, or `undefined` when the second corner graph has none.\n * A link uses it when its plugs at the middle of a side find no way. Other boxes can cover such a plug, or close the space in front of it.\n */\nfunction freeWay(ways: LevelWays, s: Node, t: Node, inset: number): Point[] | undefined {\n const fs = freePlugs(ways, s, inset);\n const ft = freePlugs(ways, t, inset);\n const cs = center(s.box);\n const ct = center(t.box);\n const is = facingOrder(fs.plugs, cs, ct);\n const it = facingOrder(ft.plugs, ct, cs);\n const from = is.map((i) => fs.plugs[i]!);\n const to = it.map((k) => ft.plugs[k]!);\n const ra = is.map((i) => fs.reach[i]!);\n const rb = it.map((k) => ft.reach[k]!);\n // A pair of plugs with one or two clear legs between them gives the short way.\n let best: Point[] | undefined;\n let bestLength = Infinity;\n from.forEach((ps, i) =>\n to.forEach((pt, k) => {\n const way = quickWay(ways, endsAt(ps, ra[i]!, pt, rb[k]!));\n const length = way ? polylineLength(way) : Infinity;\n if (length < bestLength) {\n best = way;\n bestLength = length;\n }\n }),\n );\n if (best) return best;\n // Else one search of the second corner graph finds the shortest way from a plug of `s` to a plug of `t`.\n // The corners of the second graph are near the boxes, so the way can go through a gap that is narrower than the margin.\n const a = from.map((ps, i) => ({ point: along(ps, ra[i]!), cost: ra[i]! }));\n const b = to.map((pt, k) => ({ point: along(pt, rb[k]!), cost: rb[k]! }));\n const found = ways.tight().pathAmong(a, b);\n return found && pulled(ways, from[found.from]!, found.points, to[found.to]!);\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 return endsAt(ps, reach(ways, s, ps), pt, reach(ways, t, pt));\n}\n\n/** This function gives the ends of a link from the plug `ps` to the plug `pt`, with the reach of each plug. */\nfunction endsAt(ps: Plug, ra: number, pt: Plug, rb: number): Ends {\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 the plug `ps` through the points of `path` to the plug `pt`.\n * The way leaves and enters each plug along its normal. Then it pulls the corners tight with legs that are parallel to the axes, where the obstacles let it.\n */\nfunction pulled(ways: Ways, ps: Plug, path: readonly Point[], pt: Plug): Point[] {\n const legs = squarePull(path, ways.obstacles, ways.margin / 2, axisOf(ps.normal), axisOf(pt.normal));\n return tidy([ps.point, ...legs, 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 { BACKTRACK_MIN, goesOutAndBack } from \"../bench/links.ts\";\nimport { center, dist, pointSegmentDistance, polylineLength, type Point } from \"../geom.ts\";\nimport { LEVEL_LINK_DEFAULTS, levelLinks, type ItemPair, type LevelLinkOptions } from \"../levels.ts\";\nimport { nodeIndex, type Graph, type Level, type Node, type Result, type Route, type Router, type SharedRun } from \"../model.ts\";\nimport { placePlug } from \"../plugs.ts\";\nimport { allSections, buildSections, checkSections, levelCut, SECTION_DEFAULTS, treeDepth, type Section, type SectionOptions } from \"../sections.ts\";\nimport { orderLanes, type RunOrder } from \"../segments.ts\";\nimport type { Strategy } from \"../strategies/model.ts\";\nimport { WayFinder } from \"../ways.ts\";\n\n/**\n * The options of the router with sections. Each option has a default, and the defaults give the output of version 0.1.5.\n * The options `cap`, `maxDepth` and `collapse` are the limits of the default grouping rule, the quadtree of `buildSections`.\n * The options `tightMargin`, `plugInset` and `throughCost` are the limits of the level links (`levelLinks`).\n */\nexport interface SectionsOptions extends LevelLinkOptions, 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 /**\n * The hub limit. A way through the hubs can be at most this many times as long as the line between its plugs, plus `stretchPad` margins.\n * Else the edge goes directly. The default is 2. The value `Infinity` keeps each way through the hubs.\n */\n readonly stretch?: number;\n /** A way through the hubs can be this many margins longer than `stretch` times the line between its plugs. The default is 4. */\n readonly stretchPad?: number;\n /**\n * A way skips a hub that is more than this many units farther from the target than the nearest approach of the way before it.\n * The default is 80, two times `BACKTRACK_MIN`. The value `Infinity` keeps each hub.\n */\n readonly hubSlack?: number;\n /**\n * The grouping rule: a strategy of the step `group` that makes the tree of sections. The hubs and the zoom levels come from this tree.\n * Without it, the router uses the quadtree of `buildSections` with the options `cap`, `maxDepth` and `collapse`.\n */\n readonly group?: Strategy<\"group\">;\n /** The options of the strategy `group`. The strategy gets its `defaults` for each option that this object does not give. */\n readonly groupOptions?: object;\n /**\n * The depths of the tree that get a zoom level with groups. The last level, with each node alone, always comes after them.\n * The default is each depth, from 0 to the depth of the deepest section.\n */\n readonly levels?: readonly number[];\n /** The lane order of the runs. With `run`, the default, each run gets its order alone. With `bundle`, two edges keep one order on each run of their common stretch. */\n readonly laneOrder?: RunOrder;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\n/** The default values of the numbers of `SectionsOptions`: the limits of the hubs, of the tree and of the level links. */\nexport const SECTIONS_DEFAULTS: Readonly<Required<Pick<SectionsOptions, \"cap\" | \"maxDepth\" | \"collapse\" | \"tightMargin\" | \"plugInset\" | \"throughCost\" | \"hubs\" | \"stretch\" | \"stretchPad\" | \"hubSlack\">>> =\n Object.freeze({\n cap: SECTION_DEFAULTS.cap,\n maxDepth: SECTION_DEFAULTS.maxDepth,\n collapse: SECTION_DEFAULTS.collapse,\n tightMargin: LEVEL_LINK_DEFAULTS.tightMargin,\n plugInset: LEVEL_LINK_DEFAULTS.plugInset,\n throughCost: LEVEL_LINK_DEFAULTS.throughCost,\n hubs: Infinity,\n stretch: 2,\n stretchPad: 4,\n hubSlack: 2 * BACKTRACK_MIN,\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 * An edge skips a hub that takes it away from its target. A way that still goes out and back gives way to the direct way.\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 ?? SECTIONS_DEFAULTS.stretch;\n const stretchPad = options.stretchPad ?? SECTIONS_DEFAULTS.stretchPad;\n const hubSlack = options.hubSlack ?? SECTIONS_DEFAULTS.hubSlack;\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 = groupNodes(graph, 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 // The sections of the chain whose hubs do not take the way away from its target. The test uses the straight lines from hub to hub.\n const forward = (list: readonly Section[], from: Point, to: Point): Section[] => {\n const kept: Section[] = [];\n let near = dist(from, to);\n let last = from;\n for (const c of list) {\n const h = hub(c);\n if (dist(h, to) > near + hubSlack) continue;\n near = Math.min(near, pointSegmentDistance(to, last, h));\n last = h;\n kept.push(c);\n }\n return kept;\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 ?? SECTIONS_DEFAULTS.hubs;\n const side = (list: Section[]): Section[] => list.slice(Math.max(0, list.indexOf(lca) - keep), list.indexOf(lca));\n const end = ways.out(pt);\n const start = ways.out(ps);\n const chain = forward([...side(a), ...side(b).reverse()], start, pt.point);\n if (chain.length === 0) {\n routes.push({ edge: e.id, points: ways.between(ps, pt, new Set<Node>([s, t])) });\n continue;\n }\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 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 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, or that goes out and back, gives way to the direct way.\n if (polylineLength(out) > stretch * dist(ps.point, pt.point) + stretchPad * ways.margin || goesOutAndBack(out)) {\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)!), options.laneOrder) });\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/** This function gives the tree of sections of the grouping rule. It examines the tree of a strategy (`checkSections`). */\nfunction groupNodes(graph: Graph, options: SectionsOptions): Section {\n if (!options.group) return buildSections(graph.nodes, options);\n const root = options.group.run(graph, options.groupOptions);\n checkSections(root, graph.nodes.length);\n return root;\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 * With the option `levels`, only those depths get a level with groups.\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: SectionsOptions): Level[] {\n const indexOfNode = new Map(graph.nodes.map((n, i) => [n.id, i]));\n const levels: Level[] = [];\n const deepest = treeDepth(root);\n const shown = options.levels && new Set(options.levels);\n for (let d = 0; d <= deepest + 1; d++) {\n if (shown && d <= deepest && !shown.has(d)) continue;\n const { items, owner } = levelCut(graph.nodes, root, d);\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 = owner[iu]!;\n const b = owner[iv]!;\n if (a === b) continue;\n const ida = items[a]!.id;\n const idb = items[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 { orderLanes, type RunOrder } from \"../segments.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 lane order of the runs. With `bundle`, the default, two edges keep one order on each run of their common stretch. With `run`, each run gets its order alone. */\n readonly laneOrder?: RunOrder;\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 const routeOf = new Map(routes.map((r) => [r.edge, r]));\n for (const run of runs.values()) {\n const edges = options.laneOrder === \"run\" ? laneOrderOfRun(run) : orderLanes(run.points, run.ways.map((w) => routeOf.get(w.edge.id)!), \"bundle\");\n shared.push({ id: `r${shared.length}`, key: run.key, points: run.points, edges });\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 with the option `laneOrder: \"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, type SharedRun } from \"../model.ts\";\nimport { placePlug, type Plug } from \"../plugs.ts\";\nimport { orderLanes, type RunOrder } from \"../segments.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 lane order of a trunk. With `bundle`, the default, the branches part in lane order. With `run`, the first leg of each branch tells the order. */\n readonly laneOrder?: RunOrder;\n /**\n * The place where each lane leaves the trunk. With `part`, the default, a lane leaves where its way parts from the ways of the other lanes.\n * A lane that turns back over the trunk leaves at an earlier point of the trunk. With `split`, each lane leaves at the split point, as in version 0.2.0.\n */\n readonly leave?: TrunkLeave;\n /** The benchmark skips a fixture with more nodes. */\n readonly maxNodes?: number;\n}\n\n/** The place where the lanes of a trunk leave it: where their ways part, or at the split point. */\nexport type TrunkLeave = \"part\" | \"split\";\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/** The place where a branch leaves its trunk. */\nexport interface TrunkExit {\n /** The place along the trunk: the index of a point of the trunk, plus the share of the next leg. Point `i` of the trunk is at `i`. */\n readonly at: number;\n /** The point where the branch leaves the trunk. */\n readonly point: Point;\n /** The branch past `point`, to the plug of the target. */\n readonly rest: readonly Point[];\n}\n\n/**\n * This function gives the place where a branch leaves its trunk. The branch starts at the last point of the trunk and ends at the plug of the target.\n *\n * A branch that turns back over the trunk, by more than 90 degrees, leaves at the point of the trunk before.\n * It does so when it goes back along the trunk to that point. It also does so when `clear` tells that the line from that point is free.\n * The first two legs of the trunk stay. When the branch still turns back, it leaves the last leg at the foot of its next point, if the line from there is free.\n * Each step makes the route shorter or keeps its length.\n *\n * The function gives `undefined` when the foot on the second leg of the trunk is less than `min` past the start of that leg.\n * Then the target is behind or beside the plug, and the edge does not go well in the bundle.\n */\nexport function leaveTrunk(trunk: readonly Point[], branch: readonly Point[], clear: (a: Point, b: Point) => boolean, min = 0): TrunkExit | undefined {\n const back = (a: Point, b: Point, q: Point): boolean => (b.x - a.x) * (q.x - b.x) + (b.y - a.y) * (q.y - b.y) < 0;\n let at = trunk.length - 1;\n let rest = branch.slice(1);\n while (at >= 3 && rest.length >= 2) {\n const a = trunk[at - 1]!;\n if (!back(a, trunk[at]!, rest[0]!)) break;\n const next = dist(rest[0]!, a) <= 1e-9 ? rest.slice(1) : rest;\n if (next === rest && !clear(a, rest[0]!)) break;\n rest = next;\n at -= 1;\n }\n const exit: TrunkExit = { at, point: trunk[at]!, rest };\n if (at < 1 || rest.length < 2 || !back(trunk[at - 1]!, trunk[at]!, rest[0]!)) return exit;\n const a = trunk[at - 1]!;\n const b = trunk[at]!;\n const q = rest[0]!;\n const u = ((q.x - a.x) * (b.x - a.x) + (q.y - a.y) * (b.y - a.y)) / ((b.x - a.x) ** 2 + (b.y - a.y) ** 2);\n if (at <= 2 ? u * Math.hypot(b.x - a.x, b.y - a.y) < min : u <= 0) return at <= 2 ? undefined : exit;\n const foot = { x: a.x + u * (b.x - a.x), y: a.y + u * (b.y - a.y) };\n return at >= 2 && clear(foot, q) ? { at: at - 1 + u, point: foot, rest } : exit;\n}\n\n/** This function gives the number of points at the start of each route that all the routes share. */\nfunction commonStart(routes: readonly Route[], from: number): number {\n const first = routes[0]!.points;\n let n = from;\n while (n < first.length && routes.every((r) => n < r.points.length && dist(r.points[n]!, first[n]!) <= 1e-9)) n++;\n return n;\n}\n\n/**\n * This function gives the shared ways of the routes of one bundle past the trunk. The routes share their first `from` points.\n * At the last of these points, the routes part. The routes that go on to one next point share a way to the point where they part again.\n * Each shared way has two edges or more, in the order of the routes.\n */\nexport function sharedWays(routes: readonly Route[], from: number): { points: Point[]; edges: string[] }[] {\n const out: { points: Point[]; edges: string[] }[] = [];\n const next = new Map<string, Route[]>();\n for (const r of routes) {\n const q = r.points[from];\n if (!q) continue;\n const key = `${q.x},${q.y}`;\n const list = next.get(key);\n if (list) list.push(r);\n else next.set(key, [r]);\n }\n for (const list of next.values()) {\n if (list.length < 2) continue;\n const end = commonStart(list, from);\n out.push({ points: list[0]!.points.slice(from - 1, end), edges: list.map((r) => r.edge) });\n out.push(...sharedWays(list, end));\n }\n return out;\n}\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, readonly Point[]>();\n const bundles: Bundle[] = [];\n const runs: SharedRun[] = [];\n const part = (options.leave ?? \"part\") === \"part\";\n // A branch leaves the trunk early only on a line that keeps out of the boxes as far as the corner graph does.\n const clear = (a: Point, b: Point): boolean => ways.obstacles.clear(a, b, ways.margin / 2);\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 const own: Route[] = [];\n const exits: { edge: string; exit: TrunkExit }[] = [];\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 if (!part) {\n own.push({ edge: e.id, points: dedupe([...trunk, ...branch.slice(1)]) });\n branches.push({ edge: e.id, next: branch[1] ?? pt.point });\n return;\n }\n // An edge whose target is behind the plug goes alone, as an edge outside the groups.\n const exit = leaveTrunk(trunk, branch, clear, 2 * ways.margin);\n if (exit) exits.push({ edge: e.id, exit });\n });\n const key = id.split(\"\\u0000\")[2]!;\n if (!part) {\n for (const r of own) points.set(r.edge, r.points);\n const edges = options.laneOrder === \"run\" || trunk.length < 2 ? laneOrder(dir, end, branches) : orderLanes(trunk, own, \"bundle\");\n bundles.push({ id: `b${bundles.length}`, key, node: s.id, edges, trunk });\n continue;\n }\n // A group that keeps fewer than `minSize` edges stays unbundled.\n if (exits.length < (options.minSize ?? 2)) continue;\n // The trunk gets a point at each place where a branch leaves it. Thus each route holds the points of the trunk up to its exit.\n const stops = new Map<number, Point>(trunk.map((p, i) => [i, p]));\n for (const { exit } of exits) if (!stops.has(exit.at)) stops.set(exit.at, exit.point);\n const line = [...stops].sort((x, y) => x[0] - y[0]);\n for (const { edge, exit } of exits) {\n const p = dedupe([...line.filter(([at]) => at <= exit.at).map(([, q]) => q), ...exit.rest]);\n points.set(edge, p);\n own.push({ edge, points: p });\n }\n // The bundle keeps the points that all the routes share. Past them, the routes that go on together share a run.\n const order = options.laneOrder ?? \"bundle\";\n const common = own[0]!.points.slice(0, commonStart(own, 0));\n bundles.push({ id: `b${bundles.length}`, key, node: s.id, edges: orderLanes(common, own, order), trunk: common });\n for (const way of sharedWays(own, common.length)) {\n const users = own.filter((r) => way.edges.includes(r.edge));\n runs.push({ id: `r${runs.length}`, key, points: way.points, edges: orderLanes(way.points, users, order) });\n }\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 runs.length > 0 ? { routes, bundles, runs } : { 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 built-in routers. The registry `STRATEGIES` holds the same routers as strategies, and the benchmark races the routers of the registry. */\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 type { Box, Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport type { Edge, Router } from \"../model.ts\";\nimport { segmentsOf, type SegmentGraph } from \"../segments.ts\";\nimport type { Boxed, Gap, RoomLink } from \"./index.ts\";\n\n/**\n * The options of the room for the bends of the bundles (HWC-D). With them, `roomDemand` also opens the gaps where a bundle bends.\n * The values agree with the options of `highwayCurves` that draw the bundles.\n */\nexport interface RoomBends {\n /** The router that bundles the edges. Each segment of its routes with two or more edges is a bundle. */\n readonly router: Router;\n /** The edges that the router routes. Without them, each link gives `count` edges, with no data. */\n readonly edges?: readonly Edge[];\n /** The distance between two lanes of a bundle, as `laneWidth` of `highwayCurves`. The default is 4. */\n readonly spacing?: number;\n /** The largest width of a bundle, from its outer lane to its outer lane, as `maxWidth` of `highwayCurves`. The default is `Infinity`. */\n readonly maxWidth?: number;\n /** The smallest radius of each lane, as `minRadius` of `highwayCurves`. The default is 4. */\n readonly minRadius?: number;\n /** The number of passes of the demand of the bends. Each pass routes the board that the passes before it opened. The default is 1. */\n readonly passes?: number;\n}\n\n/** One leg of the route of an edge: a straight piece of the center line of one segment. */\ninterface BendLeg {\n readonly a: Point;\n readonly b: Point;\n readonly u: Point;\n readonly len: number;\n /** The number of lanes of the segment of the leg. A segment of one edge has 1. */\n readonly lanes: number;\n /** The offset of the lane of the edge from the center line, to the left of the leg. */\n readonly off: number;\n /** The key of the leg: its segment and its place in the segment. Two edges of one segment share the key. */\n readonly key: string;\n}\n\n/** A turn smaller than this angle, in radians, is no corner. A turn nearer to a half turn than this angle is a spike, and it gets no arc. */\nconst FLAT = 1e-6;\nconst SPIKE = 0.01;\nconst SAME = 1e-6;\n/** A leg with a smaller share of its length on an axis does not grow on that axis. */\nconst SLANT = 0.2;\n\nconst turnOf = (u: Point, w: Point): number => Math.atan2(u.x * w.y - u.y * w.x, u.x * w.x + u.y * w.y);\n\n/**\n * This function gives the length along a leg of an S of two arcs with the radius `r` that shifts a lane by `shift`.\n * It is the length of the shift of `highwayCurves` at a merge or a split.\n */\nfunction jogLength(r: number, shift: number): number {\n const d = Math.abs(shift);\n if (d < SAME || r <= 0) return 0;\n if (r < d / 2) return 2 * r;\n return 2 * r * Math.sin(Math.acos(1 - d / (2 * r)));\n}\n\n/** This function gives the legs of the route of each edge, with the lanes and the offset of the lane on each leg. */\nfunction legsOf(graph: SegmentGraph, spacing: number, maxWidth: number): BendLeg[][] {\n const byId = new Map(graph.segments.map((s) => [s.id, s]));\n return graph.paths.map((path) => {\n const legs: BendLeg[] = [];\n for (const ref of path.segments) {\n const s = byId.get(ref.segment);\n if (!s) continue;\n const sp = s.count > 1 ? Math.min(spacing, maxWidth / (s.count - 1)) : 0;\n const offset = ((s.count - 1) / 2 - ref.lane) * sp;\n const c: Point[] = [];\n for (const p of s.points) if (c.length === 0 || Math.hypot(p.x - c[c.length - 1]!.x, p.y - c[c.length - 1]!.y) > SAME) c.push(p);\n const n = c.length;\n for (let j = 0; j + 1 < n; j++) {\n const from = ref.reverse ? n - 1 - j : j;\n const to = ref.reverse ? n - 2 - j : j + 1;\n const a = c[from]!;\n const b = c[to]!;\n const len = Math.hypot(b.x - a.x, b.y - a.y);\n legs.push({\n a,\n b,\n u: { x: (b.x - a.x) / len, y: (b.y - a.y) / len },\n len,\n lanes: sp > 0 ? s.count : 1,\n off: ref.reverse ? -offset : offset,\n key: `${s.id}:${Math.min(from, to)}`,\n });\n }\n }\n return legs;\n });\n}\n\n/**\n * This function gives the length that the arcs at one end of a leg use on the leg, as the lanes of `highwayCurves` use it.\n * `A` is the leg before the vertex, `B` the leg after it, and `X` the leg of the two that the length is for.\n *\n * - At a bend of two bundles, the center line has the radius `R = W/2 + minRadius`, with `W` the width of the wider bundle. The tangent length is `T = R tan(φ/2)`.\n * Each lane uses the same part of the leg, because the arcs are concentric.\n * - At another corner, the lane has the radius `minRadius` at its own corner, at the offset `c` of the lane. The tangent length is `(minRadius + |c|) tan(φ/2)`.\n * - A lane that joins or leaves a bundle shifts on the leg with fewer lanes. The S of the shift adds its length on that leg.\n */\nfunction endLength(A: BendLeg, B: BendLeg, X: BendLeg, minRadius: number): number {\n const phi = Math.abs(turnOf(A.u, B.u));\n if (Math.PI - phi < SPIKE) return 0;\n const k = phi < FLAT ? 0 : Math.tan(phi / 2);\n const c = A.lanes < B.lanes ? B.off : A.off;\n if (A.lanes > 1 && B.lanes > 1) return k * (Math.max(Math.abs(A.off), Math.abs(B.off), Math.abs(c)) + minRadius);\n return k * (minRadius + Math.abs(c)) + jogLength(minRadius, c - X.off);\n}\n\n/**\n * This function gives, for each leg of the routes, the length that the leg lacks for the arcs at its two ends.\n * `highwayCurves` gives each end of a leg at most the half of the leg. So a leg needs `2 max(T_A, T_B)`, and this length is at least `T_A + T_B`.\n * The first and the last leg of a route end at a plug, and the plug end needs no length.\n */\nfunction shortLegs(legs: readonly (readonly BendLeg[])[], minRadius: number): Map<string, { leg: BendLeg; short: number }> {\n const out = new Map<string, { leg: BendLeg; short: number }>();\n for (const path of legs) {\n if (path.every((l) => l.lanes < 2)) continue;\n for (let j = 0; j < path.length; j++) {\n const X = path[j]!;\n const start = j > 0 ? endLength(path[j - 1]!, X, X, minRadius) : 0;\n const end = j + 1 < path.length ? endLength(X, path[j + 1]!, X, minRadius) : 0;\n const short = 2 * Math.max(start, end) - X.len;\n if (short <= SAME) continue;\n const known = out.get(X.key);\n if (!known || known.short < short) out.set(X.key, { leg: X, short });\n }\n }\n return out;\n}\n\n/** This function gives the mean of the longer side of the boxes. */\nfunction meanSide(items: readonly Boxed[]): number {\n let s = 0;\n for (const i of items) s += Math.max(i.box.w, i.box.h);\n return items.length ? s / items.length : 1;\n}\n\n/** This function gives the box nearest to a point, among the boxes within `reach` of it. */\nfunction nearestBox(grid: Grid<Box>, p: Point, reach: number): Box | undefined {\n let best: Box | undefined;\n let bestD = Infinity;\n grid.query({ x: p.x - reach, y: p.y - reach, w: 2 * reach, h: 2 * reach }, (b) => {\n const dx = Math.max(b.x - p.x, 0, p.x - b.x - b.w);\n const dy = Math.max(b.y - p.y, 0, p.y - b.y - b.h);\n const d = Math.hypot(dx, dy);\n if (d < bestD || (d === bestD && best && (b.x < best.x || (b.x === best.x && b.y < best.y)))) [best, bestD] = [b, d];\n });\n return bestD <= reach ? best : undefined;\n}\n\n/**\n * This function gives the growth that each gap of the board needs for the bends of the bundles, in the order of `gaps`.\n * The router routes the board. Each segment with two or more edges is a bundle, as `highwayCurves` opens it.\n *\n * A leg that is too short for the arcs at its ends grows by the gaps between its two ends.\n * Each end of a leg moves with its nearest box, as `openGaps` moves the boxes. So a gap between the left (or top) edges of the two boxes lengthens the leg.\n * The leg grows on the axis of its longer side. The gap nearest to the middle of the leg takes the growth.\n * A gap that more legs need takes the largest growth, not the sum.\n */\nexport function bendGrowth(items: readonly Boxed[], links: readonly RoomLink[], gaps: readonly Gap[], bends: RoomBends, snap: number): number[] {\n const spacing = Math.max(0, bends.spacing ?? 4);\n const maxWidth = bends.maxWidth ?? Infinity;\n const minRadius = Math.max(0, bends.minRadius ?? 4);\n const edges: Edge[] = bends.edges\n ? [...bends.edges]\n : links.flatMap((l, i) => Array.from({ length: Math.max(1, l.count ?? 1) }, (_, k) => ({ id: `l${i}-${k}`, source: { node: l.source }, target: { node: l.target } })));\n const graph = segmentsOf(bends.router.route({ nodes: items, edges }));\n const short = shortLegs(legsOf(graph, spacing, maxWidth), minRadius);\n const grow: number[] = gaps.map(() => 0);\n if (short.size === 0) return grow;\n const side = meanSide(items);\n const grid = new Grid<Box>(Math.max(20, side));\n for (const i of items) grid.add(i.box, i.box);\n const anchor = (p: Point): Box | undefined => nearestBox(grid, p, side) ?? nearestBox(grid, p, 4 * side);\n const byAxis = { x: [] as number[], y: [] as number[] };\n gaps.forEach((g, i) => byAxis[g.axis].push(i));\n for (const { leg, short: s } of short.values()) {\n const A = anchor(leg.a);\n const B = anchor(leg.b);\n if (!A || !B) continue;\n const axes = ([\"x\", \"y\"] as const).filter((x) => Math.abs(leg.u[x]) >= SLANT).sort((p, q) => Math.abs(leg.u[q]) - Math.abs(leg.u[p]));\n for (const axis of axes) {\n const la = A[axis];\n const lb = B[axis];\n const lo = Math.min(la, lb);\n const hi = Math.max(la, lb);\n const mid = (leg.a[axis] + leg.b[axis]) / 2;\n let pick = -1;\n for (const i of byAxis[axis]) {\n const g = gaps[i]!;\n if (g.at <= lo + snap || g.at > hi + snap) continue;\n if (pick < 0 || Math.abs(g.at - mid) < Math.abs(gaps[pick]!.at - mid)) pick = i;\n }\n if (pick < 0) continue;\n grow[pick] = Math.max(grow[pick]!, s / Math.abs(leg.u[axis]));\n break;\n }\n }\n return grow;\n}\n","import { center, type Box, type Point } from \"../geom.ts\";\nimport { levelLinks } from \"../levels.ts\";\nimport type { Edge, Graph, Router } from \"../model.ts\";\nimport { bendGrowth, type RoomBends } from \"./bends.ts\";\n\nexport type { RoomBends } from \"./bends.ts\";\n\n/** An item with a box: a node of a graph, an item of a level or a box of a host layout. */\nexport interface Boxed {\n readonly id: string;\n readonly box: Box;\n}\n\n/** A link between two boxes. For a bundled link, `count` is the number of its edges. The default count is 1. */\nexport interface RoomLink {\n readonly source: string;\n readonly target: string;\n readonly count?: number;\n}\n\n/**\n * A gap of a board: a boundary of the sweep over the left or top edges of the boxes.\n * On the axis `x`, the gap is a vertical channel between two columns. On the axis `y`, it is a horizontal channel between two rows.\n */\nexport interface Gap {\n readonly axis: \"x\" | \"y\";\n /** The place of the gap in the order of the gaps on its axis, from 0. */\n readonly index: number;\n /** The coordinate where the boxes after the gap start, on the axis of the gap. */\n readonly at: number;\n /** The ids of the boxes that end at the near side of the gap. */\n readonly before: readonly string[];\n /** The ids of the boxes that start at the far side of the gap, at `at`. */\n readonly after: readonly string[];\n /** The current width of the gap: the distance from the nearest box edge before the gap to `at`. */\n readonly width: number;\n /** The number of lanes that the links need in the gap. */\n readonly lanes: number;\n /** The width that the gap needs: at least the current width, and at least `gutter + lanes × spacing`. */\n readonly need: number;\n}\n\n/** The ways that `roomDemand` finds the lanes of each gap. */\nexport type RoomMethod = \"routes\" | \"lines\";\n\n/** The options of `roomDemand` and `makeRoom`. */\nexport interface RoomOptions {\n /** The smallest width of each gap. The default is 8. */\n readonly gutter?: number;\n /** The width of one lane: the distance between two lines that run side by side. The default is 4. */\n readonly spacing?: number;\n /**\n * The largest growth of the board on each axis, as a share of its size. The default is `Infinity`.\n * When the lanes need more, each gap gets its gutter, and the lanes share the rest in proportion.\n */\n readonly maxGrowth?: number;\n /**\n * The way to find the lanes. The default is `routes`.\n * With `routes`, the function routes the links one time on the board with each gap open to the gutter.\n * The lanes of a gap are the most routes that run along the gap side by side.\n * With `lines`, the lanes of a gap are the straight lines between the centers of the boxes that cross the gap.\n */\n readonly method?: RoomMethod;\n /** The router of the method `routes`. Without it, the links go as the links of a zoom level (`levelLinks`), with the margin `gutter / 2`. */\n readonly router?: Router;\n /** With `count`, a link takes one lane for each of its edges. With `link`, the default, a link takes one lane. */\n readonly lanes?: \"link\" | \"count\";\n /** Two box edges nearer than this distance make one boundary of the sweep. The default is 0.5. */\n readonly snap?: number;\n /**\n * The number of passes of the demand. The default is 1.\n * Each pass after the first finds the lanes again on the board that the passes before it opened, and adds the growth that it needs.\n * The limit `maxGrowth` applies to the sum of the passes.\n */\n readonly passes?: number;\n /**\n * The room for the bends of the bundles (HWC-D). Without it, the default, the demand counts only the lanes of the links.\n * With it, the router of `bends` routes the open board. Each leg of a bundle that is too short for its arcs grows by a gap.\n * The limit `maxGrowth` applies to the sum of the growth of the links and of the bends.\n */\n readonly bends?: RoomBends;\n}\n\n/** The demand of a board and the board with its gaps open. */\nexport interface Room<T extends Boxed> {\n readonly gaps: readonly Gap[];\n readonly items: T[];\n}\n\nconst DEFAULT_GUTTER = 8;\nconst DEFAULT_SPACING = 4;\nconst DEFAULT_SNAP = 0.5;\n\ntype Axis = \"x\" | \"y\";\n\nconst lo = (b: Box, a: Axis): number => (a === \"x\" ? b.x : b.y);\nconst len = (b: Box, a: Axis): number => (a === \"x\" ? b.w : b.h);\nconst other = (a: Axis): Axis => (a === \"x\" ? \"y\" : \"x\");\n\n/**\n * This function gives the gaps of a board. A sweep over each axis sorts the left (or top) edges of the boxes.\n * Each distinct edge after the first is a gap. The `lanes` of each gap are 0, and its `need` is its current width.\n */\nexport function boardGaps(items: readonly Boxed[], snap: number = DEFAULT_SNAP): Gap[] {\n return [...axisGaps(items, \"x\", snap), ...axisGaps(items, \"y\", snap)];\n}\n\nfunction axisGaps(items: readonly Boxed[], axis: Axis, snap: number): Gap[] {\n const starts = [...new Set(items.map((i) => lo(i.box, axis)))].sort((u, v) => u - v);\n const bounds: number[] = [];\n for (const s of starts) if (bounds.length === 0 || s - bounds[bounds.length - 1]! > snap) bounds.push(s);\n const after: string[][] = bounds.map(() => []);\n for (const i of items) after[lastAtOrBefore(bounds, lo(i.box, axis) + snap)]!.push(i.id);\n const ends = items.map((i) => ({ id: i.id, end: lo(i.box, axis) + len(i.box, axis) })).sort((u, v) => u.end - v.end);\n const gaps: Gap[] = [];\n let k = 0;\n for (let n = 1; n < bounds.length; n++) {\n const at = bounds[n]!;\n // The nearest box edge before the gap is the largest end at or before the boundary.\n while (k < ends.length && ends[k]!.end <= at + snap) k++;\n const near = k > 0 ? ends[k - 1]!.end : at;\n const before: string[] = [];\n for (let j = k - 1; j >= 0 && ends[j]!.end >= near - snap; j--) before.push(ends[j]!.id);\n gaps.push({ axis, index: n - 1, at, before: before.reverse(), after: after[n]!, width: Math.max(0, at - near), lanes: 0, need: Math.max(0, at - near) });\n }\n return gaps;\n}\n\n/** This function gives the index of the last value of the sorted list `v` that is at or before `x`, or 0. */\nfunction lastAtOrBefore(v: readonly number[], x: number): number {\n let a = 0;\n let b = v.length - 1;\n while (a < b) {\n const m = (a + b + 1) >> 1;\n if (v[m]! <= x) a = m;\n else b = m - 1;\n }\n return a;\n}\n\n/**\n * This function moves the boxes apart, so that each gap gets the width `need`. The boxes keep their size, their order and their alignment.\n * A box moves by the sum of the growth of each gap at or before its left (or top) edge. Thus a grid stays a grid.\n * The function moves no box nearer to another box, so it makes no overlap.\n */\nexport function openGaps<T extends Boxed>(items: readonly T[], gaps: readonly Gap[], snap: number = DEFAULT_SNAP): T[] {\n const shift = (axis: Axis): ((v: number) => number) => {\n const list = gaps.filter((g) => g.axis === axis).sort((u, v) => u.at - v.at);\n const at = list.map((g) => g.at);\n const sum: number[] = [];\n let s = 0;\n for (const g of list) sum.push((s += Math.max(0, g.need - g.width)));\n return (v) => (list.length === 0 || at[0]! > v + snap ? 0 : sum[lastAtOrBefore(at, v + snap)]!);\n };\n const sx = shift(\"x\");\n const sy = shift(\"y\");\n return items.map((i) => ({ ...i, box: { ...i.box, x: i.box.x + sx(i.box.x), y: i.box.y + sy(i.box.y) } }));\n}\n\n/**\n * This function gives the room that the links need in each gap of the board.\n * The lanes of a gap come from the `method` of the options. The need of a gap is `gutter + lanes × spacing`, and not less than its current width.\n */\nexport function roomDemand(items: readonly Boxed[], links: readonly RoomLink[], options: RoomOptions = {}): Gap[] {\n const gutter = options.gutter ?? DEFAULT_GUTTER;\n const snap = options.snap ?? DEFAULT_SNAP;\n const passes = Math.max(1, Math.floor(options.passes ?? 1));\n let total = demandOnce(items, links, options);\n for (let p = 1; p < passes; p++) {\n // The next pass measures the board that the passes before it opened. Its gaps are the same gaps, in the same order.\n const next = demandOnce(openGaps(items, total, snap), links, options);\n if (next.length !== total.length || next.some((g, i) => g.axis !== total[i]!.axis)) break;\n total = total.map((g, i) => ({ ...g, lanes: Math.max(g.lanes, next[i]!.lanes), need: g.need + Math.max(0, next[i]!.need - next[i]!.width) }));\n }\n if (options.bends) total = withBends(items, links, total, options.bends, snap);\n return capGrowth(items, total, gutter, options.maxGrowth ?? Infinity);\n}\n\n/**\n * This function adds the growth for the bends of the bundles to the need of each gap. Each pass routes the board with each gap open to its need.\n * The open board has the same gaps in the same order. So the growth of each gap adds to the need of that gap.\n */\nexport function withBends(items: readonly Boxed[], links: readonly RoomLink[], gaps: readonly Gap[], bends: RoomBends, snap: number = DEFAULT_SNAP): Gap[] {\n let total = [...gaps];\n const passes = Math.max(1, Math.floor(bends.passes ?? 1));\n for (let p = 0; p < passes; p++) {\n const board = openGaps(items, total, snap);\n const open = boardGaps(board, snap);\n if (open.length !== total.length || open.some((g, i) => g.axis !== total[i]!.axis)) break;\n const grow = bendGrowth(board, links, open, bends, snap);\n if (grow.every((g) => g <= 0)) break;\n total = total.map((g, i) => (grow[i]! > 0 ? { ...g, need: g.need + grow[i]! } : g));\n }\n return total;\n}\n\n/** This function gives the demand of one pass, without the limit `maxGrowth`. */\nfunction demandOnce(items: readonly Boxed[], links: readonly RoomLink[], options: RoomOptions): Gap[] {\n const gutter = options.gutter ?? DEFAULT_GUTTER;\n const spacing = options.spacing ?? DEFAULT_SPACING;\n const snap = options.snap ?? DEFAULT_SNAP;\n const weight = (l: RoomLink): number => (options.lanes === \"count\" ? Math.max(1, l.count ?? 1) : 1);\n const gaps = boardGaps(items, snap);\n const lanes = (options.method ?? \"routes\") === \"lines\" ? lineLanes(items, links, gaps, weight) : routeLanes(items, links, gaps, gutter, snap, weight, options.router);\n return gaps.map((g, i) => ({ ...g, lanes: lanes[i]!, need: Math.max(g.width, gutter + lanes[i]! * spacing) }));\n}\n\n/** This function gives the demand of the board and the board with each gap open to its need. */\nexport function makeRoom<T extends Boxed>(items: readonly T[], links: readonly RoomLink[], options: RoomOptions = {}): Room<T> {\n const gaps = roomDemand(items, links, options);\n return { gaps, items: openGaps(items, gaps, options.snap ?? DEFAULT_SNAP) };\n}\n\n/** This function gives the links between the nodes of a graph, with the count of the edges of each pair. A loop does not count. */\nexport function roomLinks(graph: Graph): RoomLink[] {\n const byPair = new Map<string, { source: string; target: string; count: number }>();\n for (const e of graph.edges) {\n const [s, t] = [e.source.node, e.target.node];\n if (s === t) continue;\n const key = s < t ? `${s}\\u0000${t}` : `${t}\\u0000${s}`;\n const known = byPair.get(key);\n if (known) known.count++;\n else byPair.set(key, { source: s, target: t, count: 1 });\n }\n return [...byPair.values()];\n}\n\n/** This function counts, for each gap, the straight lines between the centers of the boxes of a link that cross the gap. */\nfunction lineLanes(items: readonly Boxed[], links: readonly RoomLink[], gaps: readonly Gap[], weight: (l: RoomLink) => number): number[] {\n const byId = new Map(items.map((i) => [i.id, center(i.box)]));\n return gaps.map((g) => {\n let n = 0;\n for (const l of links) {\n const a = byId.get(l.source);\n const b = byId.get(l.target);\n if (a && b && Math.min(a[g.axis], b[g.axis]) < g.at && Math.max(a[g.axis], b[g.axis]) > g.at) n += weight(l);\n }\n return n;\n });\n}\n\n/**\n * This function routes the links one time on the board with each gap open to the gutter.\n * The lanes of a gap are the largest number of routes that run along the gap at one place.\n * A piece of a route goes along a gap when it is in the channel of the gap.\n * It must also go farther along the gap than across it.\n */\nfunction routeLanes(\n items: readonly Boxed[],\n links: readonly RoomLink[],\n gaps: readonly Gap[],\n gutter: number,\n snap: number,\n weight: (l: RoomLink) => number,\n router: Router | undefined,\n): number[] {\n const probeGaps = gaps.map((g) => ({ ...g, need: Math.max(g.width, gutter) }));\n const probe = openGaps(items, probeGaps, snap);\n const ways = probeWays(probe, links, gutter, router);\n return probeGaps.map((g) => {\n // The channel of the gap on the probe board: its far side moves with the growth of each gap up to this one.\n let grow = 0;\n for (const h of probeGaps) if (h.axis === g.axis && h.at <= g.at + snap) grow += h.need - h.width;\n const hi = g.at + grow;\n const lo = hi - g.need;\n const spans: { from: number; to: number; w: number }[] = [];\n ways.forEach((points, i) => {\n const along = alongSpans(points, g.axis, lo, hi);\n for (const [from, to] of merge(along)) spans.push({ from, to, w: weight(links[i]!) });\n });\n return density(spans);\n });\n}\n\n/** This function gives the points of the way of each link on the probe board, in the order of the links. */\nfunction probeWays(items: readonly Boxed[], links: readonly RoomLink[], gutter: number, router: Router | undefined): (readonly Point[])[] {\n if (router) {\n const edges: Edge[] = links.map((l, i) => ({ id: `l${i}`, source: { node: l.source }, target: { node: l.target } }));\n const routes = new Map(router.route({ nodes: items, edges }).routes.map((r) => [r.edge, r.points]));\n return edges.map((e) => routes.get(e.id) ?? []);\n }\n const level = items.map((i) => ({ id: i.id, box: i.box, nodes: [i.id] }));\n const pairs = links.map((l) => ({ source: l.source, target: l.target, count: l.count ?? 1 }));\n // The margin puts the corners of the two sides of a gap on its middle line.\n const out = levelLinks(level, pairs, { margin: Math.max(1, gutter / 2) });\n const byPair = new Map(out.map((l) => [`${l.source}\\u0000${l.target}`, l.points]));\n return links.map((l) => byPair.get(`${l.source}\\u0000${l.target}`) ?? []);\n}\n\n/**\n * This function gives the spans along the axis of a gap where the polyline goes along the channel from `lo` to `hi`.\n * The axis `x` gap is a vertical channel, so its spans are on the y axis.\n */\nfunction alongSpans(p: readonly Point[], axis: Axis, lo: number, hi: number): [number, number][] {\n const across = axis;\n const along = other(axis);\n const out: [number, number][] = [];\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n const da = b[across] - a[across];\n // The part of the segment inside the channel, as the parameters t0 and t1 of the segment.\n let t0 = 0;\n let t1 = 1;\n if (Math.abs(da) < 1e-9) {\n if (a[across] < lo - 1e-6 || a[across] > hi + 1e-6) continue;\n } else {\n const u = (lo - a[across]) / da;\n const v = (hi - a[across]) / da;\n t0 = Math.max(0, Math.min(u, v));\n t1 = Math.min(1, Math.max(u, v));\n if (t1 <= t0) continue;\n }\n const s = a[along] + (b[along] - a[along]) * t0;\n const e = a[along] + (b[along] - a[along]) * t1;\n const run = Math.abs(e - s);\n const cross = Math.abs(da) * (t1 - t0);\n if (run > cross && run > 1e-6) out.push([Math.min(s, e), Math.max(s, e)]);\n }\n return out;\n}\n\n/** This function joins the spans that overlap, so that one link counts one time at each place. */\nfunction merge(spans: [number, number][]): [number, number][] {\n spans.sort((u, v) => u[0] - v[0]);\n const out: [number, number][] = [];\n for (const s of spans) {\n const last = out[out.length - 1];\n if (last && s[0] <= last[1]) last[1] = Math.max(last[1], s[1]);\n else out.push([s[0], s[1]]);\n }\n return out;\n}\n\n/** This function gives the largest sum of the weights of the spans that overlap at one place. Spans that only touch do not overlap. */\nfunction density(spans: readonly { from: number; to: number; w: number }[]): number {\n const events: [number, number][] = [];\n for (const s of spans) events.push([s.from, s.w], [s.to, -s.w]);\n // At one coordinate, the ends come before the starts.\n events.sort((u, v) => u[0] - v[0] || u[1] - v[1]);\n let n = 0;\n let best = 0;\n for (const [, w] of events) {\n n += w;\n best = Math.max(best, n);\n }\n return best;\n}\n\n/**\n * This function keeps the growth of the board on each axis at most `maxGrowth` times its size.\n * Each gap keeps its gutter. The lanes of all gaps of the axis share the rest of the growth in proportion.\n */\nfunction capGrowth(items: readonly Boxed[], gaps: Gap[], gutter: number, maxGrowth: number): Gap[] {\n if (!Number.isFinite(maxGrowth)) return gaps;\n const out = [...gaps];\n for (const axis of [\"x\", \"y\"] as const) {\n let x0 = Infinity;\n let x1 = -Infinity;\n for (const i of items) {\n x0 = Math.min(x0, lo(i.box, axis));\n x1 = Math.max(x1, lo(i.box, axis) + len(i.box, axis));\n }\n const budget = Math.max(0, maxGrowth) * Math.max(0, x1 - x0);\n let base = 0;\n let spare = 0;\n for (const g of gaps) {\n if (g.axis !== axis) continue;\n const b = Math.max(0, gutter - g.width);\n base += b;\n spare += Math.max(0, g.need - g.width - b);\n }\n if (base + spare <= budget || spare === 0) continue;\n const f = Math.max(0, (budget - base) / spare);\n gaps.forEach((g, i) => {\n if (g.axis !== axis) return;\n const b = Math.max(0, gutter - g.width);\n out[i] = { ...g, need: g.width + b + f * Math.max(0, g.need - g.width - b) };\n });\n }\n return out;\n}\n","import { segmentHitsBox, type Box, type Point } from \"../geom.ts\";\nimport { Grid } from \"../grid.ts\";\nimport type { LevelLink } from \"../model.ts\";\nimport { boardGaps, type Boxed } from \"./index.ts\";\n\n/**\n * The lane order of the pieces of the links in one gap.\n *\n * - `links`: the order of the list of links. This order reads nothing of the board.\n * - `ends`: the pieces that turn to the near side at their two ends come first. The pieces that turn to the far side come last.\n * - `crossings`: the order with the fewest crossings between the pieces of the gap and the legs at their ends. A local search finds it.\n */\nexport type LaneOrder = \"links\" | \"ends\" | \"crossings\";\n\n/** The lane orders of `gapLanes`, in the order of the benchmark. */\nexport const LANE_ORDERS: readonly LaneOrder[] = [\"links\", \"ends\", \"crossings\"];\n\n/** The options of `gapLanes`. */\nexport interface GapLaneOptions {\n /** The largest distance between two lanes. A narrow gap puts its lanes nearer. The default is 4. */\n readonly spacing?: number;\n /** The lane order in each gap. The default is `crossings`. */\n readonly order?: LaneOrder;\n /** Two box edges nearer than this distance make one boundary of the sweep, as in `boardGaps`. The default is 0.5. */\n readonly snap?: number;\n}\n\n/** A piece of a link: a leg of the link that runs along a gap. */\ninterface Piece {\n /** The index of the link. */\n readonly link: number;\n /** The index of the last point of the leg. The leg goes from the point `seg - 1` to the point `seg`. */\n readonly seg: number;\n /** The span of the leg along the gap. */\n readonly lo: number;\n readonly hi: number;\n /** For each end of the leg: its place along the gap, and the side (-1 or 1) across the gap where the link turns. */\n readonly turns: readonly (readonly [number, number])[];\n}\n\nconst EPS = 1e-6;\nconst ROUNDS = 8;\n\n/**\n * This function gives each link that runs along a gap its own lane in the gap. The lanes of a gap are `spacing` apart, around its middle line.\n * A leg of a link moves across its gap only, so the link keeps its plugs and the axes of its legs.\n * When a move puts a link through more boxes than before, the link keeps its points.\n */\nexport function gapLanes(items: readonly Boxed[], links: readonly LevelLink[], options: GapLaneOptions = {}): LevelLink[] {\n const spacing = Math.max(0, options.spacing ?? 4);\n const order = options.order ?? \"crossings\";\n const moved = links.map((l) => l.points.map((p) => ({ x: p.x, y: p.y })));\n for (const g of boardGaps(items, options.snap)) {\n if (g.width <= EPS) continue;\n const across = g.axis;\n const along = g.axis === \"x\" ? \"y\" : \"x\";\n const lo = g.at - g.width;\n const hi = g.at;\n const pieces: Piece[] = [];\n links.forEach((l, li) => {\n const p = l.points;\n // The first and the last legs hold the plugs, so they do not move.\n for (let i = 2; i <= p.length - 2; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n if (Math.abs(a[across] - b[across]) > EPS || a[across] <= lo + EPS || a[across] >= hi - EPS) continue;\n if (Math.abs(a[along] - b[along]) <= EPS) continue;\n const side = (q: Point, r: Point): number => Math.sign(r[across] - q[across]);\n pieces.push({\n link: li,\n seg: i,\n lo: Math.min(a[along], b[along]),\n hi: Math.max(a[along], b[along]),\n turns: [\n [a[along], side(a, p[i - 2]!)],\n [b[along], side(b, p[i + 1]!)],\n ],\n });\n }\n });\n if (pieces.length === 0) continue;\n const list = orderPieces(pieces, order);\n // A piece goes one lane past each piece before it in the order that it overlaps. Thus two pieces that overlap keep their order.\n const lane: number[] = [];\n let n = 0;\n list.forEach((P, i) => {\n let k = 0;\n for (let j = 0; j < i; j++) if (overlaps(list[j]!, P)) k = Math.max(k, lane[j]! + 1);\n lane.push(k);\n n = Math.max(n, k + 1);\n });\n const step = Math.min(spacing, g.width / (n + 1));\n const mid = (lo + hi) / 2;\n list.forEach((P, i) => {\n const v = mid + (lane[i]! - (n - 1) / 2) * step;\n moved[P.link]![P.seg - 1]![across] = v;\n moved[P.link]![P.seg]![across] = v;\n });\n }\n const boxes = new Grid<Box>(Math.max(20, meanSide(items)));\n for (const i of items) boxes.add(i.box, i.box);\n return links.map((l, i) => (hits(boxes, moved[i]!) > hits(boxes, l.points) ? l : { ...l, points: moved[i]! }));\n}\n\nconst overlaps = (P: Piece, Q: Piece): boolean => Math.min(P.hi, Q.hi) - Math.max(P.lo, Q.lo) > EPS;\n\n/**\n * This function counts the crossings when the piece `P` is on the near side of the piece `Q`.\n * A turn of `P` to the far side crosses `Q` when it is inside the span of `Q`. A turn of `Q` to the near side crosses `P` in the same way.\n */\nfunction cost(P: Piece, Q: Piece): number {\n let c = 0;\n for (const [y, s] of P.turns) if (s > 0 && y > Q.lo + EPS && y < Q.hi - EPS) c++;\n for (const [y, s] of Q.turns) if (s < 0 && y > P.lo + EPS && y < P.hi - EPS) c++;\n return c;\n}\n\n/** This function gives the pieces of one gap in lane order, from the near side to the far side. */\nfunction orderPieces(pieces: readonly Piece[], order: LaneOrder): Piece[] {\n if (order === \"links\") return [...pieces];\n const sum = (P: Piece): number => P.turns.reduce((s, [, side]) => s + side, 0);\n const list = [...pieces].sort((P, Q) => sum(P) - sum(Q) || P.link - Q.link || P.seg - Q.seg);\n if (order === \"ends\") return list;\n // The local search moves one piece to the place that removes the most crossings, until no move removes one.\n const n = list.length;\n const index = new Map(list.map((P, i) => [P, i]));\n const c: number[][] = list.map((P) => list.map((Q) => (P !== Q && overlaps(P, Q) ? cost(P, Q) : 0)));\n const at = (P: Piece, Q: Piece): number => c[index.get(P)!]![index.get(Q)!]!;\n for (let round = 0; round < ROUNDS; round++) {\n let better = false;\n for (let i = 0; i < n; i++) {\n const x = list[i]!;\n // The change of the crossings when `x` moves to the place `k`, for each `k`.\n let best = 0;\n let to = i;\n let d = 0;\n for (let k = i - 1; k >= 0; k--) {\n d += at(x, list[k]!) - at(list[k]!, x);\n if (d < best) [best, to] = [d, k];\n }\n d = 0;\n for (let k = i + 1; k < n; k++) {\n d += at(list[k]!, x) - at(x, list[k]!);\n if (d < best) [best, to] = [d, k];\n }\n if (to !== i) {\n list.splice(i, 1);\n list.splice(to, 0, x);\n better = true;\n }\n }\n if (!better) break;\n }\n return list;\n}\n\n/** This function gives the mean of the longer side of the boxes. */\nfunction meanSide(items: readonly Boxed[]): number {\n let s = 0;\n for (const i of items) s += Math.max(i.box.w, i.box.h);\n return items.length ? s / items.length : 1;\n}\n\n/** This function counts the legs of a polyline that go through a box, for each box. */\nfunction hits(boxes: Grid<Box>, p: readonly Point[]): number {\n let n = 0;\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n boxes.querySegment(a, b, 0, (box) => {\n if (segmentHitsBox(a, b, box)) n++;\n });\n }\n return n;\n}\n","import type { ItemPair } from \"../../levels.ts\";\nimport type { LevelItem } from \"../../model.ts\";\nimport { levelCut, treeDepth, type Section } from \"../../sections.ts\";\nimport { boardGaps, openGaps, roomDemand, withBends, type Boxed, type Gap, type RoomLink, type RoomOptions } from \"../index.ts\";\n\n/**\n * The boards of the zoom levels of `levelRoom`.\n *\n * - `shared`: each level uses the board of the nearest level. No box moves between two levels. A far level gets the area of the nearest level.\n * - `each`: each level has its own board. A far level opens only the gaps of its own links, and a nearer level adds to them.\n * Thus the items of a far level are nearer together, but a box moves in its parent when the level changes.\n */\nexport type LevelBoard = \"each\" | \"shared\";\n\n/** The options of `levelRoom`: the options of `roomDemand` for each level, and the levels that get room. */\nexport interface LevelRoomOptions extends RoomOptions {\n /** The depths of the tree that get room for their links. The default is each depth from 1 to the depth of the deepest section. */\n readonly depths?: readonly number[];\n /** With `true`, the last level, with each node alone, also gets room for the links between the nodes. The default is `false`. */\n readonly nodes?: boolean;\n /** The board of each level. The default is `shared`. */\n readonly board?: LevelBoard;\n}\n\n/** One zoom level of `levelRoom`: its items at their open places, its links and its demand. */\nexport interface RoomLevel<T extends Boxed> {\n readonly depth: number;\n /** The items of the level, with the bounding box of their nodes at the places of this level. */\n readonly items: LevelItem[];\n /** The links between the items of the level. A link counts the links of the nodes between its two items. */\n readonly pairs: ItemPair[];\n /** The demand of the level on the board that it gets from the level before it. A level without room has no gaps. */\n readonly gaps: Gap[];\n /** The nodes at the places of this level. */\n readonly nodes: T[];\n}\n\n/** The room of each zoom level, and the board of the nearest level. */\nexport interface LevelRoom<T extends Boxed> {\n /** The levels from depth 0 to the level with each node alone, in order. */\n readonly levels: RoomLevel<T>[];\n /** The gaps of the board of the nodes. `openGaps(nodes, gaps)` gives the nodes of the nearest level. */\n readonly gaps: Gap[];\n /** The nodes of the nearest level. */\n readonly items: T[];\n}\n\nconst DEFAULT_SNAP = 0.5;\n\n/**\n * This function gives the links between the items of a level. Each pair of items gets one link, in the order of the first link of the pair.\n * The count of a link is the sum of the counts of its node links. A link inside one item does not count.\n */\nexport function levelPairs(items: readonly LevelItem[], owner: readonly number[], indexOf: ReadonlyMap<string, number>, links: readonly RoomLink[]): ItemPair[] {\n const byPair = new Map<string, { source: string; target: string; count: number }>();\n for (const l of links) {\n const iu = indexOf.get(l.source);\n const iv = indexOf.get(l.target);\n if (iu === undefined || iv === undefined) continue;\n const a = owner[iu]!;\n const b = owner[iv]!;\n if (a === b) continue;\n const key = a < b ? `${a} ${b}` : `${b} ${a}`;\n const known = byPair.get(key);\n if (known) known.count += l.count ?? 1;\n else byPair.set(key, { source: items[a]!.id, target: items[b]!.id, count: l.count ?? 1 });\n }\n return [...byPair.values()];\n}\n\n/**\n * This function gives the room of each zoom level of a tree of sections. The indices of the nodes of the tree are the indices of `nodes`.\n * The far levels open first, and each nearer level keeps their growth.\n *\n * At each level, `roomDemand` measures the links of that level on the board of the level before it. Then the nodes move with `openGaps`.\n * The nodes move by one monotone shift on each axis, so each level keeps the order and the alignment of the boxes.\n * A nearer level only adds growth, so no gap of a far level gets narrower, and a box moves with its parent.\n */\nexport function levelRoom<T extends Boxed>(nodes: readonly T[], links: readonly RoomLink[], root: Section, options: LevelRoomOptions = {}): LevelRoom<T> {\n const snap = options.snap ?? DEFAULT_SNAP;\n const deepest = treeDepth(root);\n const depths = new Set(options.depths ?? Array.from({ length: deepest }, (_, i) => i + 1));\n if (options.nodes) depths.add(deepest + 1);\n const indexOf = new Map(nodes.map((n, i) => [n.id, i]));\n const levels: RoomLevel<T>[] = [];\n let current: T[] = [...nodes];\n // The edges of the bends join nodes, not the items of a level. So the bends get room on the board of the nodes, at the last level.\n const { bends, ...room } = options;\n for (let d = 0; d <= deepest + 1; d++) {\n let gaps: Gap[] = [];\n let cut = levelCut(current, root, d);\n const pairs = levelPairs(cut.items, cut.owner, indexOf, links);\n if (depths.has(d) && pairs.length > 0) {\n gaps = roomDemand(cut.items, pairs, room);\n // The shift of each gap applies to the nodes, so a node moves with its item, and the items of a far level stay apart.\n if (gaps.some((g) => g.need > g.width)) {\n current = openGaps(current, gaps, snap);\n cut = levelCut(current, root, d);\n }\n }\n if (bends && d === deepest + 1) {\n const bent = withBends(current, links, boardGaps(current, snap), bends, snap);\n if (bent.some((g) => g.need > g.width)) {\n current = openGaps(current, bent, snap);\n cut = levelCut(current, root, d);\n }\n }\n levels.push({ depth: d, items: cut.items, pairs, gaps, nodes: current });\n }\n const shared = (options.board ?? \"shared\") === \"shared\";\n const out = shared ? levels.map((l) => ({ ...l, items: levelCut(current, root, l.depth).items, nodes: current })) : levels;\n return { levels: out, gaps: nodeGaps(nodes, current, levels, snap), items: current };\n}\n\n/**\n * This function gives the gaps of the board of the nodes that move each node from `from` to `to`.\n * The growth of a gap is the shift of the nodes after it, less the shift of the nodes before it. Its lanes are the most lanes of a level gap there.\n */\nfunction nodeGaps<T extends Boxed>(from: readonly T[], to: readonly T[], levels: readonly RoomLevel<T>[], snap: number): Gap[] {\n const indexOf = new Map(from.map((n, i) => [n.id, i]));\n const gaps = boardGaps(from, snap);\n const shift = (id: string, axis: \"x\" | \"y\"): number => {\n const i = indexOf.get(id)!;\n return to[i]!.box[axis] - from[i]!.box[axis];\n };\n // The lanes of each level gap go to the gap of the nodes at the left (or top) edge of its first item after it.\n const lanes = new Map<number, number>();\n const boundaryOf = new Map<string, number>();\n gaps.forEach((g, k) => {\n for (const id of g.after) boundaryOf.set(`${g.axis} ${id}`, k);\n });\n for (const level of levels) {\n const byId = new Map(level.items.map((i) => [i.id, i]));\n for (const g of level.gaps) {\n if (g.lanes === 0) continue;\n for (const id of g.after) {\n const item = byId.get(id);\n if (!item) continue;\n // The first node of the item on the axis of the gap starts the item.\n let first = item.nodes[0]!;\n for (const n of item.nodes) if (from[indexOf.get(n)!]!.box[g.axis] < from[indexOf.get(first)!]!.box[g.axis]) first = n;\n const k = boundaryOf.get(`${g.axis} ${first}`);\n if (k !== undefined) lanes.set(k, Math.max(lanes.get(k) ?? 0, g.lanes));\n }\n }\n }\n const last: Record<\"x\" | \"y\", number> = { x: 0, y: 0 };\n return gaps.map((g, k) => {\n let s = Infinity;\n for (const id of g.after) s = Math.min(s, shift(id, g.axis));\n const growth = Math.max(0, s - last[g.axis]);\n last[g.axis] = Math.max(last[g.axis], s);\n return { ...g, lanes: lanes.get(k) ?? 0, need: g.width + growth };\n });\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 { measureLevelFaults, measureRouteFaults, sumFaults, type LevelFaults, type LinkFaults } from \"./links.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 /** The faults of the routes of the edges (`measureRouteFaults`). */\n readonly faults: LinkFaults;\n /** The faults of each zoom level with groups (`measureLevelFaults`). The list is empty for a router without levels. */\n readonly levelFaults: readonly LevelFaults[];\n /** The routes of this cell took longer than the cell limit. The cell did not start more routes. A row within the limit has no such field. */\n readonly overLimit?: OverLimit;\n}\n\n/** The record of a cell over its time limit. */\nexport interface OverLimit {\n /** The cell limit, in milliseconds. */\n readonly limit: number;\n /** The number of routes that the cell finished. With one route, the cell did not check \"same twice\". */\n readonly runs: number;\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 * The time limit of one cell (one router on one fixture), in milliseconds. The default is no limit.\n * After the routes of a cell pass the limit, the cell starts no more routes, and its row gets `overLimit`.\n * A route that runs does not stop.\n */\n readonly cellLimit?: 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, options.cellLimit));\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/**\n * This function routes one graph with one router and measures the result. It routes at least two times, for the rule \"same twice\".\n * After the routes pass `cellLimit` milliseconds, it starts no more routes and marks the row with `overLimit`.\n */\nexport function benchOne(router: Router, fixture: string, graph: Graph, repeat = 3, cellLimit: number = Infinity): BenchRow {\n return benchRun(router, fixture, graph, repeat, cellLimit).row;\n}\n\n/** One run of `benchRun`: the row of the benchmark and the result that the row measures. */\nexport interface BenchRun {\n readonly row: BenchRow;\n readonly result: Result;\n}\n\n/** This function does the work of `benchOne` and also gives the result, so more measures can read it without a second route. */\nexport function benchRun(router: Router, fixture: string, graph: Graph, repeat = 3, cellLimit: number = Infinity): BenchRun {\n const times: number[] = [];\n let first: Result | undefined;\n let deterministic = true;\n let spent = 0;\n for (let i = 0; i < Math.max(2, repeat); i++) {\n const t0 = now();\n const r = router.route(graph);\n const t = now() - t0;\n times.push(t);\n spent += t;\n if (!first) first = r;\n else if (i === 1 && !sameData(r, first)) deterministic = false;\n if (spent > cellLimit) break;\n }\n const runs = times.length;\n times.sort((a, b) => a - b);\n const result = first!;\n const all = checkProperties(graph, result, 1_000_000);\n const row: BenchRow = {\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 faults: measureRouteFaults(graph, result),\n levelFaults: measureLevelFaults(result),\n ...(spent > cellLimit ? { overLimit: { limit: cellLimit, runs } } : {}),\n };\n return { row, result };\n}\n\n/**\n * This function puts rows in the order of one benchmark run: by fixture, then by router, each in the order of its list.\n * A name that is not in its list goes after the names of the list. Rows with the same place keep their order.\n * The workflow `Bench` uses it to join the rows of its parts.\n */\nexport function orderRows(rows: readonly BenchRow[], routers: readonly string[], fixtures: readonly string[]): BenchRow[] {\n const place = (list: readonly string[], name: string): number => {\n const i = list.indexOf(name);\n return i < 0 ? list.length : i;\n };\n return rows\n .map((row, i) => ({ row, i, f: place(fixtures, row.fixture), r: place(routers, row.router) }))\n .sort((a, b) => a.f - b.f || a.r - b.r || a.i - b.i)\n .map((x) => x.row);\n}\n\n/** This function writes the rows as a Markdown table. A cell over its limit shows \"over the limit\" after its time, and a dash for \"same twice\" when it did not check it. */\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 const over = r.overLimit;\n const ms = over ? `${f(r.ms, 1)} over the limit` : f(r.ms, 1);\n const same = over && over.runs < 2 ? \"-\" : r.deterministic ? \"yes\" : \"NO\";\n return `| ${r.router} | ${r.fixture} | ${r.nodes} | ${r.edges} | ${ms} | ${same} | ${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\n/**\n * This function writes the faults of the rows as a Markdown table: the routes first, then the sum of the levels with groups.\n * A router without such levels gets a dash in the columns of the levels.\n */\nexport function formatFaults(rows: readonly BenchRow[]): string {\n const head =\n \"| router | fixture | through | out and back | worst detour | outside | level links | level overlaps | level through | level unavoidable | level avoidable | level out and back | level worst detour | level outside |\";\n const line = \"|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map((r) => {\n const f = r.faults;\n const cells = [r.router, r.fixture, f.through, f.backtrack, f.worstDetour.toFixed(2), f.outside];\n if (r.levelFaults.length === 0) cells.push(\"-\", \"-\", \"-\", \"-\", \"-\", \"-\", \"-\", \"-\");\n else {\n const l = sumFaults(r.levelFaults);\n cells.push(l.links, r.levelFaults.reduce((s, x) => s + x.overlaps, 0), l.through, l.unavoidable, l.avoidable, l.backtrack, l.worstDetour.toFixed(2), l.outside);\n }\n return `| ${cells.join(\" | \")} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n\n/** A row with the faults of each zoom level, as `formatLevels` reads it: a router or a setting on one fixture. */\nexport interface LevelRow {\n readonly router: string;\n readonly fixture: string;\n readonly levelFaults: readonly LevelFaults[];\n}\n\n/** This function writes the faults of each zoom level with groups as a Markdown table, one line for each level. */\nexport function formatLevels(rows: readonly LevelRow[]): string {\n const head = \"| router | fixture | depth | items | groups | overlaps | links | through | unavoidable | avoidable | out and back | worst detour | outside |\";\n const line = \"|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const body = rows.flatMap((r) =>\n r.levelFaults.map((l) =>\n [r.router, r.fixture, l.depth, l.items, l.groups, l.overlaps, l.links, l.through, l.unavoidable, l.avoidable, l.backtrack, l.worstDetour.toFixed(2), l.outside].join(\" | \"),\n ),\n );\n return [head, line, ...body.map((b) => `| ${b} |`)].join(\"\\n\");\n}\n","import type { CurveSegment } from \"../curves/model.ts\";\nimport type { CurveSpace } from \"../curves/space.ts\";\nimport type { Point } from \"../geom.ts\";\nimport type { Graph, Result, Router } from \"../model.ts\";\nimport type { Boxed, Gap, RoomLink } from \"../room/index.ts\";\nimport type { Section } from \"../sections.ts\";\nimport type { OptionSchema } from \"./options.ts\";\n\n/** The input of a curve strategy: one polyline and the context of its route. */\nexport interface CurveInput {\n /** These points are the polyline: a route of a router, a lane of `laneRoutes` or a link of a zoom level. */\n readonly points: readonly Point[];\n /** The curve leaves the first point along this outward normal of its plug, if the strategy reads it. */\n readonly startNormal?: Point;\n /** The curve comes into the last point against this outward normal of its plug, if the strategy reads it. */\n readonly endNormal?: Point;\n /** The boxes that the curve must not go through, from `curveSpace`. */\n readonly space?: CurveSpace;\n}\n\n/** The input of a room strategy: the boxes of a board and the links between them. */\nexport interface RoomInput {\n readonly items: readonly Boxed[];\n readonly links: readonly RoomLink[];\n /**\n * The tree of sections of the items, for a strategy that gives room to each zoom level. The indices of its nodes are the indices of `items`.\n * Without it, such a strategy makes the quadtree of `buildSections`. The other strategies do not read it.\n */\n readonly sections?: Section;\n}\n\n/**\n * The steps that have strategies, with the fixed input and output type of each step.\n *\n * - `group`: a graph in, the tree of sections out. The router `sections` makes its hubs and its zoom levels from this tree.\n * - `router`: a graph in, the routes (and the `levels`, `bundles` and `runs`) out.\n * - `curve`: a polyline in, the segments of a curve out.\n * - `room`: the boxes and links of a board in, the gaps of the board with their need out.\n */\nexport interface StepTypes {\n readonly group: { readonly input: Graph; readonly output: Section };\n readonly router: { readonly input: Graph; readonly output: Result };\n readonly curve: { readonly input: CurveInput; readonly output: CurveSegment[] };\n readonly room: { readonly input: RoomInput; readonly output: Gap[] };\n}\n\n/** The name of a step that has strategies. */\nexport type Step = keyof StepTypes;\n\n/** The input type of a step. */\nexport type StepInput<S extends Step> = StepTypes[S][\"input\"];\n\n/** The output type of a step. */\nexport type StepOutput<S extends Step> = StepTypes[S][\"output\"];\n\n/** The steps that have strategies, in the order of the pipeline. */\nexport const STEPS: readonly Step[] = [\"group\", \"router\", \"curve\", \"room\"];\n\n/**\n * A strategy: one way to do one step, with a name and a description.\n * The same input and the same options must give the same output.\n */\nexport interface Strategy<S extends Step = Step, O extends object = object> {\n /** The step of the strategy. It fixes the input and the output type. */\n readonly step: S;\n /** The name of the strategy. Each name is unique in its step of a registry. */\n readonly name: string;\n /** One or two sentences that tell what the strategy does. The site and the documents show them. */\n readonly describe: string;\n /** The values of the options when the caller gives no value. */\n readonly defaults: Readonly<O>;\n /** The declarations of the options: the type, the range, the step and the meaning of each one. A strategy without it declares nothing. */\n readonly schema?: OptionSchema<O>;\n /** The benchmark skips an input with more nodes than this. Without it, the strategy takes each input. */\n readonly maxNodes?: number;\n /** This method does the step. Each option that `options` does not give gets its value from `defaults`. */\n run(input: StepInput<S>, options?: Partial<O>): StepOutput<S>;\n}\n\n/** A strategy of any step. A registry holds a list of these. */\nexport type AnyStrategy = { [S in Step]: Strategy<S> }[Step];\n\n/** The definition of a strategy, for `defineStrategy`. */\nexport interface StrategyDefinition<S extends Step, O extends object> {\n readonly step: S;\n readonly name: string;\n readonly describe: string;\n /** These values are the options when the caller gives no value. Give `{}` for a strategy without options. */\n readonly defaults: O;\n /** These declarations tell the type, the range, the step and the meaning of each option. `checkSchema` examines them. */\n readonly schema?: NoInfer<OptionSchema<O>>;\n readonly maxNodes?: number;\n /** This function does the step. It gets each option, from the caller or from `defaults`. */\n run(input: StepInput<S>, options: Readonly<O>): StepOutput<S>;\n}\n\n/** This function gives a frozen copy of a schema, with each declaration frozen. */\nfunction freezeSchema<O>(schema: OptionSchema<O>): OptionSchema<O> {\n const out: Record<string, unknown> = {};\n for (const [key, d] of Object.entries(schema)) out[key] = Object.freeze({ ...(d as object) });\n return Object.freeze(out) as OptionSchema<O>;\n}\n\n/**\n * This function makes a strategy from its definition. The strategy fills the missing options from `defaults`.\n * When the caller gives no option, the definition gets the `defaults` object itself.\n */\nexport function defineStrategy<S extends Step, O extends object>(definition: StrategyDefinition<S, O>): Strategy<S, O> {\n const { step, name, describe, defaults, schema, maxNodes } = definition;\n if (name.length === 0) throw new Error(`A strategy of the step \"${step}\" has no name.`);\n const strategy: Strategy<S, O> = {\n step,\n name,\n describe,\n defaults: Object.freeze({ ...defaults }),\n ...(schema === undefined ? {} : { schema: freezeSchema(schema) }),\n ...(maxNodes === undefined ? {} : { maxNodes }),\n run(input: StepInput<S>, options?: Partial<O>): StepOutput<S> {\n const all = options === undefined || Object.keys(options).length === 0 ? strategy.defaults : { ...strategy.defaults, ...options };\n return definition.run(input, all as Readonly<O>);\n },\n };\n return Object.freeze(strategy);\n}\n\n/**\n * A registry: the strategies of each step, in order. A registry is data. No import changes it.\n * A consumer makes its own registry with `createRegistry`, and adds a strategy with `register`.\n * The list `group` is optional in the type, so a registry from version 0.1.5 stays a registry. `createRegistry` always gives it.\n */\nexport type Registry = { readonly [S in Exclude<Step, \"group\">]: readonly Strategy<S>[] } & { readonly group?: readonly Strategy<\"group\">[] };\n\n/** This function makes a registry from a list of strategies. It keeps their order. Two strategies with one step and one name are an error. */\nexport function createRegistry(strategies: readonly AnyStrategy[]): Registry {\n const out: { [S in Step]: Strategy<S>[] } = { group: [], router: [], curve: [], room: [] };\n for (const s of strategies) {\n const list = out[s.step] as AnyStrategy[] | undefined;\n if (!list) throw new Error(`There is no step \"${String(s.step)}\". The steps are ${STEPS.join(\", \")}.`);\n if (list.some((t) => t.name === s.name)) throw new Error(`The step \"${s.step}\" has two strategies with the name \"${s.name}\".`);\n list.push(s);\n }\n return Object.freeze({ group: Object.freeze(out.group), router: Object.freeze(out.router), curve: Object.freeze(out.curve), room: Object.freeze(out.room) });\n}\n\n/** This function gives a new registry with the strategies of `registry` and then `strategies`. It does not change `registry`. */\nexport function register(registry: Registry, ...strategies: readonly AnyStrategy[]): Registry {\n return createRegistry([...(registry.group ?? []), ...registry.router, ...registry.curve, ...registry.room, ...strategies]);\n}\n\n/** This function gives the strategies of one step of a registry, in order. */\nexport function listStrategies<S extends Step>(registry: Registry, step: S): readonly Strategy<S>[] {\n return (registry[step] ?? []) as readonly Strategy<S>[];\n}\n\n/** This function gives the strategy of one step with a name, or `undefined` when the registry has no such strategy. */\nexport function findStrategy<S extends Step>(registry: Registry, step: S, name: string): Strategy<S> | undefined {\n return listStrategies(registry, step).find((s) => s.name === name);\n}\n\n/** This function gives the strategy of one step with a name. When the registry has no such strategy, the function throws an error. */\nexport function getStrategy<S extends Step>(registry: Registry, step: S, name: string): Strategy<S> {\n const s = findStrategy(registry, step, name);\n if (!s) throw new Error(`There is no ${step} \"${name}\". The registry has ${listStrategies(registry, step).map((t) => t.name).join(\", \")}.`);\n return s;\n}\n\n/** This function gives a `Router` that runs a router strategy with the options. The router keeps the name and the `maxNodes` of the strategy. */\nexport function asRouter<O extends object>(strategy: Strategy<\"router\", O>, options?: Partial<O>): Router {\n return {\n name: strategy.name,\n ...(strategy.maxNodes === undefined ? {} : { maxNodes: strategy.maxNodes }),\n route: (graph: Graph): Result => strategy.run(graph, options),\n };\n}\n\n/** This function gives the router strategies of a registry as `Router` objects, in order. The benchmark races them. */\nexport function routersOf(registry: Registry): Router[] {\n return listStrategies(registry, \"router\").map((s) => asRouter(s));\n}\n","import type { CutOptions } from \"../groups/cut/index.ts\";\nimport type { KdOptions } from \"../groups/kd/index.ts\";\nimport type { KeyOptions } from \"../groups/keys/index.ts\";\nimport type { CornersOptions } from \"../routers/corners.ts\";\nimport type { SectionsOptions } from \"../routers/sections.ts\";\nimport type { SharedOptions } from \"../routers/shared.ts\";\nimport type { TrunksOptions } from \"../routers/trunks.ts\";\nimport type { SectionOptions } from \"../sections.ts\";\nimport type { RunOrder } from \"../segments.ts\";\nimport type { ClothoidStrategyOptions, HighwayStrategyOptions, LevelRoomPreset, RadiusOptions, RoomPreset, RouterPreset, SmoothStrategyOptions, TensionOptions } from \"./builtins.ts\";\nimport type { EnumOption, OptionSchema } from \"./options.ts\";\n\n// The declarations of the options of the built-in strategies. Each `default` is the value that the function uses without the option.\n// The test of the defaults runs each strategy with `optionDefaults` and with no option, and compares the output.\n\n/** The options of the way finder (`WayOptions`), for each router that goes around the nodes. */\nconst WAY_SCHEMA: OptionSchema<RouterPreset<CornersOptions>> = {\n margin: { type: \"number\", min: 1, max: 20, step: 1, default: 5, describe: \"The distance from a box to the corners of the graph.\" },\n k: { type: \"integer\", min: 2, max: 16, step: 1, default: 8, describe: \"The number of visible neighbours of each corner.\" },\n smooth: { type: \"boolean\", default: false, describe: \"With `true`, a way in clear view uses the inflection rule, and the other ways get round corners.\" },\n};\n\n/** The declaration of the lane order of the shared ways of the routers `trunks` and `shared`. */\nconst LANE_ORDER: EnumOption<RunOrder> = {\n type: \"enum\",\n values: [\"bundle\", \"run\"],\n default: \"bundle\",\n describe: \"With `bundle`, two edges keep one lane order on each shared way of their common stretch. With `run`, each shared way gets its order alone.\",\n};\n\n/** The declaration of the lane order of the runs of the router `sections`. The default keeps the lane order of version 0.2.0. */\nconst RUN_LANE_ORDER: EnumOption<RunOrder> = { ...LANE_ORDER, default: \"run\" };\n\n/** The declarations of the options of the routers `corners` and `corners-smooth`. */\nexport const CORNERS_SCHEMA: OptionSchema<RouterPreset<CornersOptions>> = WAY_SCHEMA;\n\n/** The declarations of the options of the router `trunks`. */\nexport const TRUNKS_SCHEMA: OptionSchema<RouterPreset<TrunksOptions>> = {\n ...WAY_SCHEMA,\n rule: { type: \"function\", describe: \"The grouping rule. The edges from one plug with one key share a trunk.\" },\n split: { type: \"number\", min: 0.1, max: 0.9, step: 0.05, default: 0.5, describe: \"The split point is at this share of the way to the center of the targets.\" },\n minSize: { type: \"integer\", min: 1, max: 8, step: 1, default: 2, describe: \"A group with fewer edges stays unbundled.\" },\n laneOrder: LANE_ORDER,\n leave: {\n type: \"enum\",\n values: [\"part\", \"split\"],\n default: \"part\",\n describe: \"With `part`, a lane leaves the trunk where its way parts from the other ways. With `split`, each lane leaves at the split point.\",\n },\n};\n\n/** The declarations of the options of the routers `shared` and `shared-all`. */\nexport const SHARED_SCHEMA: OptionSchema<RouterPreset<SharedOptions>> = {\n ...WAY_SCHEMA,\n rule: { type: \"function\", describe: \"The edges with one key share their ways. Without a rule, all edges share.\" },\n discount: {\n type: \"number\",\n min: 0.05,\n max: 1,\n step: 0.05,\n default: 0.5,\n describe: \"The cost of a link that an edge with the same key uses already, as a share of its length.\",\n },\n laneOrder: LANE_ORDER,\n};\n\n/** The declarations of the limits of the tree of sections (`SectionOptions`). */\nexport const SECTION_SCHEMA: OptionSchema<Required<SectionOptions>> = {\n cap: { type: \"integer\", min: 1, max: 32, step: 1, scale: \"log\", marks: [4, 6, 8, 12, 16], default: 8, describe: \"The section limit. A section with more nodes splits in four.\" },\n maxDepth: { type: \"integer\", min: 1, max: 32, step: 1, default: 16, describe: \"The depth limit of the tree.\" },\n collapse: { type: \"integer\", min: 1, max: 64, step: 1, default: 32, describe: \"A cell shrinks to one quarter at most this many times without a split.\" },\n};\n\n/** The declarations of the options of the routers `sections` and `sections-tree`. */\nexport const SECTIONS_SCHEMA: OptionSchema<RouterPreset<SectionsOptions>> = {\n ...WAY_SCHEMA,\n ...SECTION_SCHEMA,\n hubs: {\n type: \"integer\",\n min: 0,\n max: 8,\n step: 1,\n special: [Infinity],\n default: Infinity,\n describe: \"The number of hubs on each side of the lowest common section that a way passes. `Infinity` passes each hub.\",\n },\n stretch: {\n type: \"number\",\n min: 1,\n max: 4,\n step: 0.25,\n special: [Infinity],\n marks: [1.25, 1.5, 2, 3, Infinity],\n default: 2,\n describe: \"The hub limit. A way through the hubs is at most this many times the straight line. `Infinity` keeps each such way.\",\n },\n stretchPad: { type: \"number\", min: 0, max: 16, step: 1, default: 4, describe: \"A way through the hubs can be this many margins longer than the hub limit.\" },\n hubSlack: {\n type: \"number\",\n min: 0,\n max: 320,\n step: 10,\n special: [Infinity],\n marks: [0, 40, 80, 160, Infinity],\n default: 80,\n describe: \"A way skips a hub that is this many units farther from the target than the way was before.\",\n },\n tightMargin: { type: \"number\", min: 0, max: 5, step: 0.5, default: 1, describe: \"The margin of the second corner graph of the level links.\" },\n plugInset: { type: \"number\", min: 0, max: 12, step: 1, default: 6, describe: \"A plug of a level link stays this far from the corners of its side.\" },\n throughCost: {\n type: \"number\",\n min: 0,\n max: 16,\n step: 1,\n marks: [0, 2, 4, 8, 16],\n default: 8,\n describe: \"The cost of a level link through a far box, in mean box sizes. The value 0 gives the links of version 0.1.5.\",\n },\n group: { type: \"strategy\", step: \"group\", describe: \"The grouping rule: a strategy of the step `group`. Without it, the router uses the quadtree.\" },\n groupOptions: { type: \"object\", describe: \"The options of the strategy `group`.\" },\n levels: { type: \"list\", describe: \"The depths of the tree that get a level with groups. Without it, each depth gets a level.\" },\n laneOrder: RUN_LANE_ORDER,\n};\n\n/** The declarations of the option of the curves `rounded` and `arc`. */\nexport const RADIUS_SCHEMA: OptionSchema<RadiusOptions> = {\n radius: { type: \"number\", min: 0, max: 48, step: 1, describe: \"The radius of the corners.\" },\n};\n\n/** The declarations of the options of the curve `highway`. */\nexport const HIGHWAY_SCHEMA: OptionSchema<HighwayStrategyOptions> = {\n ...RADIUS_SCHEMA,\n minRadius: { type: \"number\", min: 0, max: 24, step: 1, describe: \"The smallest radius of a lane at a bend of a bundle.\" },\n jog: {\n type: \"enum\",\n values: [\"biarc\", \"cubic\", \"quintic\"],\n default: \"biarc\",\n describe: \"The shape of the S curve where a lane changes its offset. A `quintic` S curve has no jump of the curvature.\",\n },\n jogPieces: { type: \"integer\", min: 1, max: 8, step: 1, default: 4, describe: \"The number of cubic pieces of a `quintic` S curve.\" },\n};\n\n/** The declarations of the options of the curve `smooth`. */\nexport const SMOOTH_SCHEMA: OptionSchema<SmoothStrategyOptions> = {\n ...RADIUS_SCHEMA,\n smoothing: { type: \"number\", min: 0, max: 1, step: 0.05, describe: \"The share of the turn of a corner in its two spirals. The value 0 gives the curve `arc`.\" },\n};\n\n/** The declarations of the options of the curve `clothoid`. */\nexport const CLOTHOID_SCHEMA: OptionSchema<ClothoidStrategyOptions> = {\n ...RADIUS_SCHEMA,\n spiral: { type: \"number\", min: 0, max: 1, step: 0.05, describe: \"The share of the turn of a corner in its two clothoids. The value 0 gives the curve `arc`.\" },\n tolerance: { type: \"number\", min: 0.05, max: 1, step: 0.05, describe: \"The largest distance from the cubic pieces to the true clothoid.\" },\n};\n\n/** The declarations of the option of the curve `spline`. */\nexport const TENSION_SCHEMA: OptionSchema<TensionOptions> = {\n tension: { type: \"number\", min: 0, max: 1, step: 0.05, describe: \"The tension of the spline, from 0 (the spline) to 1 (the polyline).\" },\n};\n\n/** The declarations of the options of the room strategies: the options of `roomDemand`, without the method. */\nexport const ROOM_SCHEMA: OptionSchema<RoomPreset> = {\n gutter: { type: \"number\", min: 0, max: 32, step: 1, marks: [4, 8, 12, 16], default: 8, describe: \"The smallest width of each gap.\" },\n spacing: { type: \"number\", min: 1, max: 12, step: 1, marks: [2, 4, 6, 8], default: 4, describe: \"The width of one lane: the distance between two lines that run side by side.\" },\n maxGrowth: {\n type: \"number\",\n min: 0,\n max: 1,\n step: 0.01,\n special: [Infinity],\n marks: [0, 0.06, 0.09, 0.12, 0.15, 0.18, 0.21, 0.25, 0.3, 0.35, 0.5, Infinity],\n default: Infinity,\n describe: \"The largest growth of the board on each axis, as a share of its size. `Infinity` sets no limit.\",\n },\n router: { type: \"object\", describe: \"The router of the method `routes`. Without it, the links go as the links of a zoom level.\" },\n lanes: { type: \"enum\", values: [\"link\", \"count\"], default: \"link\", describe: \"With `count`, a link takes one lane for each of its edges. With `link`, a link takes one lane.\" },\n snap: { type: \"number\", min: 0, max: 4, step: 0.25, default: 0.5, describe: \"Two box edges nearer than this distance make one boundary of the sweep.\" },\n passes: { type: \"integer\", min: 1, max: 4, step: 1, marks: [1, 2], default: 1, describe: \"The number of passes of the demand. Each pass after the first finds the lanes on the open board.\" },\n bends: {\n type: \"object\",\n describe: \"The room for the bends of the bundles: a router that bundles, and the lane options of `highwayCurves`. Without it, the bends get no room.\",\n },\n};\n\n/** The declarations of the options of the room strategy `levels`. They are the options of the room, the levels with room and the limits of the quadtree. */\nexport const LEVEL_ROOM_SCHEMA: OptionSchema<LevelRoomPreset> = {\n ...ROOM_SCHEMA,\n depths: { type: \"list\", describe: \"The depths of the tree that get room. Without it, each depth with groups gets room.\" },\n nodes: { type: \"boolean\", default: false, describe: \"With `true`, the last level, with each node alone, also gets room.\" },\n board: { type: \"enum\", values: [\"shared\", \"each\"], default: \"shared\", describe: \"With `shared`, each level uses the board of the nearest level. With `each`, each level has its own board.\" },\n ...SECTION_SCHEMA,\n};\n\n/** The declarations of the options of the grouping rule `keys`. */\nexport const KEY_SCHEMA: OptionSchema<KeyOptions> = {\n key: { type: \"function\", describe: \"This function gives the key of the group of each node.\" },\n split: { type: \"object\", describe: \"With these limits of the quadtree, a large group splits into cells. Without them, each group is one leaf.\" },\n};\n\n/** The declarations of the limits of the tree of the grouping rules `kd` and `cut`. */\nconst SPLIT_TREE_SCHEMA: OptionSchema<Required<Pick<KdOptions, \"cap\" | \"maxDepth\" | \"fanout\">>> = {\n cap: { ...SECTION_SCHEMA.cap, describe: \"The section limit. A section with more nodes splits.\" },\n maxDepth: SECTION_SCHEMA.maxDepth,\n fanout: { type: \"integer\", min: 2, max: 4, step: 2, default: 4, describe: \"The number of children of a section. With 4, a section splits two times on one level.\" },\n};\n\n/** The declarations of the options of the grouping rule `kd`. */\nexport const KD_SCHEMA: OptionSchema<KdOptions> = {\n ...SPLIT_TREE_SCHEMA,\n line: { type: \"enum\", values: [\"median\", \"middle\", \"slide\"], default: \"slide\", describe: \"The place of the line in the cell: the median node, the middle, or the middle that slides to the nearest node.\" },\n axis: { type: \"enum\", values: [\"longer\", \"alternate\"], default: \"longer\", describe: \"The axis of each split: across the longer side of the cell, or x and y in turn.\" },\n};\n\n/** The declarations of the options of the grouping rule `cut`. */\nexport const CUT_SCHEMA: OptionSchema<CutOptions> = {\n ...SPLIT_TREE_SCHEMA,\n balance: { type: \"number\", min: 0.05, max: 0.5, step: 0.05, marks: [0.1, 0.25, 0.4], default: 0.25, describe: \"The smallest share of the nodes in each part of a split.\" },\n objective: { type: \"enum\", values: [\"ratio\", \"normalized\", \"sparsest\"], default: \"ratio\", describe: \"The cost of a line: the ratio cut, the normalized cut or the sparsest cut.\" },\n pull: { type: \"number\", min: 0, max: 4, step: 0.25, marks: [0, 0.5, 1, 2, 4], default: 0.5, describe: \"The cost of a line grows with its distance from the middle of the cell, by this factor.\" },\n guard: { type: \"boolean\", default: true, describe: \"With `true`, each section also tests the quadtree split, and keeps the split that cuts fewer edges.\" },\n};\n","import { arcCurve, type ArcOptions } from \"../curves/arc/index.ts\";\nimport { clothoidCurve, type ClothoidOptions } from \"../curves/clothoid/index.ts\";\nimport { highwayCurve, type JogStyle } from \"../curves/highway/index.ts\";\nimport { roundedCurve, type RoundedOptions } from \"../curves/rounded/index.ts\";\nimport { smoothCurve, type SmoothOptions } from \"../curves/smooth/index.ts\";\nimport { splineCurve, type SplineOptions } from \"../curves/spline/index.ts\";\nimport { straightCurve } from \"../curves/straight/index.ts\";\nimport { CUT_DEFAULTS, cutGroups, type CutOptions } from \"../groups/cut/index.ts\";\nimport { KD_DEFAULTS, kdGroups, type KdOptions } from \"../groups/kd/index.ts\";\nimport { byDataGroup, keyGroups, type KeyOptions } from \"../groups/keys/index.ts\";\nimport { quadtreeGroups } from \"../groups/quadtree/index.ts\";\nimport type { Graph, Result, Router } from \"../model.ts\";\nimport { roomDemand, type RoomMethod, type RoomOptions } from \"../room/index.ts\";\nimport { levelRoom, type LevelRoomOptions } from \"../room/levels/index.ts\";\nimport { cornersRouter, type CornersOptions } from \"../routers/corners.ts\";\nimport { plugsRouter } from \"../routers/plugs.ts\";\nimport { sectionsRouter, type SectionsOptions } from \"../routers/sections.ts\";\nimport { sharedRouter, type SharedOptions } from \"../routers/shared.ts\";\nimport { straightRouter } from \"../routers/straight.ts\";\nimport { byCollection, trunksRouter, type TrunksOptions } from \"../routers/trunks.ts\";\nimport { buildSections, SECTION_DEFAULTS, type SectionOptions } from \"../sections.ts\";\nimport { createRegistry, defineStrategy, type AnyStrategy, type CurveInput, type Registry, type Strategy } from \"./model.ts\";\nimport type { OptionSchema } from \"./options.ts\";\nimport { CLOTHOID_SCHEMA, CORNERS_SCHEMA, CUT_SCHEMA, HIGHWAY_SCHEMA, KD_SCHEMA, KEY_SCHEMA, LEVEL_ROOM_SCHEMA, RADIUS_SCHEMA, ROOM_SCHEMA, SECTION_SCHEMA, SECTIONS_SCHEMA, SHARED_SCHEMA, SMOOTH_SCHEMA, TENSION_SCHEMA, TRUNKS_SCHEMA } from \"./schemas.ts\";\n\n/** The options of a router strategy: the options of its router, without the name and the limit of the benchmark. */\nexport type RouterPreset<O> = Omit<O, \"name\" | \"maxNodes\">;\n\n/** This function makes a router strategy from a router factory and a preset of its options. Each call makes the router of its options. */\nfunction routerStrategy<O extends object>(\n name: string,\n describe: string,\n maxNodes: number,\n defaults: O,\n make: (options: O & { readonly name: string }) => Router,\n schema: OptionSchema<O>,\n): Strategy<\"router\", O> {\n return defineStrategy({ step: \"router\", name, describe, defaults, schema, maxNodes, run: (graph: Graph, options: Readonly<O>): Result => make({ ...options, name }).route(graph) });\n}\n\n/** This function makes a router strategy for a router without options. */\nfunction fixedRouter(router: Router, describe: string): Strategy<\"router\", object> {\n return defineStrategy({ step: \"router\", name: router.name, describe, defaults: {}, schema: {}, run: (graph: Graph): Result => router.route(graph) });\n}\n\n/** The built-in router strategies, in the order of the benchmark. They route as the routers of `ROUTERS`. */\nexport const routerStrategies: {\n readonly straight: Strategy<\"router\", object>;\n readonly plugs: Strategy<\"router\", object>;\n readonly corners: Strategy<\"router\", RouterPreset<CornersOptions>>;\n readonly \"corners-smooth\": Strategy<\"router\", RouterPreset<CornersOptions>>;\n readonly trunks: Strategy<\"router\", RouterPreset<TrunksOptions>>;\n readonly shared: Strategy<\"router\", RouterPreset<SharedOptions>>;\n readonly \"shared-all\": Strategy<\"router\", RouterPreset<SharedOptions>>;\n readonly sections: Strategy<\"router\", RouterPreset<SectionsOptions>>;\n readonly \"sections-tree\": Strategy<\"router\", RouterPreset<SectionsOptions>>;\n} = Object.freeze({\n straight: fixedRouter(straightRouter, \"The control. Each edge is one straight line between its plugs.\"),\n plugs: fixedRouter(\n plugsRouter,\n \"Each edge leaves its plug along the normal of the side and follows the curve of the inflection rule. It does not go around the nodes.\",\n ),\n corners: routerStrategy<RouterPreset<CornersOptions>>(\n \"corners\",\n \"Each edge goes around the nodes on a shortest path (A*) through a sparse visibility graph of the box corners.\",\n 10_000,\n {},\n cornersRouter,\n CORNERS_SCHEMA,\n ),\n \"corners-smooth\": routerStrategy<RouterPreset<CornersOptions>>(\n \"corners-smooth\",\n \"The same paths as `corners`. A route in clear view follows the inflection rule, and the other routes get round corners.\",\n 10_000,\n { smooth: true },\n cornersRouter,\n CORNERS_SCHEMA,\n ),\n trunks: routerStrategy<RouterPreset<TrunksOptions>>(\n \"trunks\",\n \"A rule puts edges in groups. The edges of a group leave one plug of one node on one trunk. At a split point, each edge goes on to its target.\",\n 10_000,\n { rule: byCollection },\n trunksRouter,\n TRUNKS_SCHEMA,\n ),\n shared: routerStrategy<RouterPreset<SharedOptions>>(\n \"shared\",\n \"The edges of one collection share their ways through the corner graph. A link that the group uses already costs half.\",\n 10_000,\n { rule: byCollection },\n sharedRouter,\n SHARED_SCHEMA,\n ),\n \"shared-all\": routerStrategy<RouterPreset<SharedOptions>>(\"shared-all\", \"The same as `shared`, but all edges share their ways.\", 10_000, {}, sharedRouter, SHARED_SCHEMA),\n sections: routerStrategy<RouterPreset<SectionsOptions>>(\n \"sections\",\n \"A tree of sections, with a hub in each section. A long edge goes through the hubs, and a short edge goes directly.\",\n 100_000,\n {},\n sectionsRouter,\n SECTIONS_SCHEMA,\n ),\n \"sections-tree\": routerStrategy<RouterPreset<SectionsOptions>>(\n \"sections-tree\",\n \"The same as `sections`, but without the limit of the stretch.\",\n 100_000,\n { stretch: Infinity },\n sectionsRouter,\n SECTIONS_SCHEMA,\n ),\n});\n\n/** The context of a curve input, without the keys that have no value. */\nconst contextOf = (input: CurveInput): Omit<CurveInput, \"points\"> => ({\n ...(input.startNormal ? { startNormal: input.startNormal } : {}),\n ...(input.endNormal ? { endNormal: input.endNormal } : {}),\n ...(input.space ? { space: input.space } : {}),\n});\n\n/** The options of the curve strategies `rounded` and `arc`. */\nexport interface RadiusOptions {\n /** The radius of the corners. The default is 12. */\n readonly radius: number;\n}\n\n/** The options of the curve strategy `spline`. */\nexport interface TensionOptions {\n /** The tension of the spline, from 0 (the spline) to 1 (the polyline). The default is 0. */\n readonly tension: number;\n}\n\n/** The options of the curve strategy `highway`. */\nexport interface HighwayStrategyOptions {\n /** The radius of the center line of a bundle at a bend, and of each lone corner. The default is 12. */\n readonly radius: number;\n /** The smallest radius of a lane at a bend of a bundle. The default is 4. */\n readonly minRadius: number;\n /** The shape of the S curve where a lane changes its offset. The default is `biarc`. */\n readonly jog: JogStyle;\n /** The number of cubic pieces of a `quintic` S curve. The default is 4. */\n readonly jogPieces: number;\n}\n\n/** The options of the curve strategy `smooth`. */\nexport interface SmoothStrategyOptions {\n /** The radius of the arc of each corner. The default is 12. */\n readonly radius: number;\n /** The share of the turn of a corner in its two spirals, from 0 to 1. The default is 0.6. */\n readonly smoothing: number;\n}\n\n/** The options of the curve strategy `clothoid`. */\nexport interface ClothoidStrategyOptions {\n /** The radius of the arc of each corner. The default is 12. */\n readonly radius: number;\n /** The share of the turn of a corner in its two clothoids, from 0 to 1. The default is 0.5. */\n readonly spiral: number;\n /** The largest distance from the cubic pieces to the true clothoid. The default is 0.25. */\n readonly tolerance: number;\n}\n\n/**\n * The built-in curve strategies. The first six are in the order of `CURVE_TYPES`, and each one gives the same segments as `curveOf` with its type.\n * The strategy `highway` gives the curve of `arc` for one polyline. `highwayCurves` bends the lanes of a bundle as one.\n */\nexport const curveStrategies: {\n readonly straight: Strategy<\"curve\", object>;\n readonly rounded: Strategy<\"curve\", RadiusOptions>;\n readonly spline: Strategy<\"curve\", TensionOptions>;\n readonly arc: Strategy<\"curve\", RadiusOptions>;\n readonly smooth: Strategy<\"curve\", SmoothStrategyOptions>;\n readonly clothoid: Strategy<\"curve\", ClothoidStrategyOptions>;\n readonly highway: Strategy<\"curve\", HighwayStrategyOptions>;\n} = Object.freeze({\n straight: defineStrategy({ step: \"curve\", name: \"straight\", describe: \"The polyline as it is.\", defaults: {}, schema: {}, run: (input: CurveInput) => straightCurve(input.points) }),\n rounded: defineStrategy({\n step: \"curve\",\n name: \"rounded\",\n describe: \"A quadratic Bezier curve at each corner, as `roundCorners` draws it. The first and the last legs stay.\",\n defaults: { radius: 12 },\n schema: RADIUS_SCHEMA,\n run: (input: CurveInput, o: Readonly<RadiusOptions>) => roundedCurve(input.points, { ...contextOf(input), radius: o.radius } satisfies RoundedOptions),\n }),\n spline: defineStrategy({\n step: \"curve\",\n name: \"spline\",\n describe: \"A centripetal Catmull-Rom spline through each point. It does not overshoot or make loops in a piece.\",\n defaults: { tension: 0 },\n schema: TENSION_SCHEMA,\n run: (input: CurveInput, o: Readonly<TensionOptions>) => splineCurve(input.points, { ...contextOf(input), tension: o.tension } satisfies SplineOptions),\n }),\n arc: defineStrategy({\n step: \"curve\",\n name: \"arc\",\n describe: \"A circular arc at each corner, tangent to the two legs. The first and the last legs stay.\",\n defaults: { radius: 12 },\n schema: RADIUS_SCHEMA,\n run: (input: CurveInput, o: Readonly<RadiusOptions>) => arcCurve(input.points, { ...contextOf(input), radius: o.radius } satisfies ArcOptions),\n }),\n smooth: defineStrategy({\n step: \"curve\",\n name: \"smooth\",\n describe: \"A cubic spiral, an arc and a second cubic spiral at each corner, as the corner smoothing of Figma. The curvature has no jump.\",\n defaults: { radius: 12, smoothing: 0.6 },\n schema: SMOOTH_SCHEMA,\n run: (input: CurveInput, o: Readonly<SmoothStrategyOptions>) =>\n smoothCurve(input.points, { ...(input.space ? { space: input.space } : {}), radius: o.radius, smoothing: o.smoothing } satisfies SmoothOptions),\n }),\n clothoid: defineStrategy({\n step: \"curve\",\n name: \"clothoid\",\n describe: \"A clothoid, an arc and a second clothoid at each corner, as a transition curve of a road. Cubic pieces draw each clothoid.\",\n defaults: { radius: 12, spiral: 0.5, tolerance: 0.25 },\n schema: CLOTHOID_SCHEMA,\n run: (input: CurveInput, o: Readonly<ClothoidStrategyOptions>) =>\n clothoidCurve(input.points, {\n ...(input.space ? { space: input.space } : {}),\n radius: o.radius,\n spiral: o.spiral,\n tolerance: o.tolerance,\n } satisfies ClothoidOptions),\n }),\n highway: defineStrategy({\n step: \"curve\",\n name: \"highway\",\n describe: \"The lanes of a bundle bend as one, with concentric arcs at the lane spacing. One lane alone gets the curve of `arc`.\",\n defaults: { radius: 12, minRadius: 4, jog: \"biarc\" as JogStyle, jogPieces: 4 },\n schema: HIGHWAY_SCHEMA,\n run: (input: CurveInput, o: Readonly<HighwayStrategyOptions>) => highwayCurve(input.points, { radius: o.radius, ...(input.space ? { space: input.space } : {}) }),\n }),\n});\n\n/** The options of a room strategy: the options of `roomDemand`, without the method. */\nexport type RoomPreset = Omit<RoomOptions, \"method\">;\n\nconst roomStrategy = (method: RoomMethod, describe: string): Strategy<\"room\", RoomPreset> =>\n defineStrategy<\"room\", RoomPreset>({ step: \"room\", name: method, describe, defaults: {}, schema: ROOM_SCHEMA, run: (input, o) => roomDemand(input.items, input.links, { ...o, method }) });\n\n/** The options of the room strategy `levels`: the options of `levelRoom` without the method, and the limits of the quadtree. */\nexport type LevelRoomPreset = Omit<LevelRoomOptions, \"method\"> & SectionOptions;\n\n/** The built-in room strategies: the methods of `roomDemand`, and the room of each zoom level (`levelRoom`). */\nexport const roomStrategies: {\n readonly routes: Strategy<\"room\", RoomPreset>;\n readonly lines: Strategy<\"room\", RoomPreset>;\n readonly levels: Strategy<\"room\", LevelRoomPreset>;\n} = Object.freeze({\n routes: roomStrategy(\"routes\", \"The lanes of a gap are the most routes that run along it side by side, with each gap open to the gutter.\"),\n lines: roomStrategy(\"lines\", \"The lanes of a gap are the straight lines between the centers of the boxes that cross the gap.\"),\n levels: defineStrategy<\"room\", LevelRoomPreset>({\n step: \"room\",\n name: \"levels\",\n describe: \"Each zoom level gets the gaps that its links need. The far levels open first, and a box moves with its parent.\",\n defaults: {},\n schema: LEVEL_ROOM_SCHEMA,\n run: (input, o) => {\n const { cap, maxDepth, collapse, ...room } = o;\n const root = input.sections ?? buildSections(input.items, { cap: cap ?? SECTION_DEFAULTS.cap, maxDepth: maxDepth ?? SECTION_DEFAULTS.maxDepth, collapse: collapse ?? SECTION_DEFAULTS.collapse });\n return levelRoom(input.items, input.links, root, room).gaps;\n },\n }),\n});\n\n/** The built-in grouping rules: the strategies of the step `group`. The router `sections` makes its hubs and its zoom levels from their tree. */\nexport const groupStrategies: {\n readonly quadtree: Strategy<\"group\", Required<SectionOptions>>;\n readonly keys: Strategy<\"group\", KeyOptions>;\n readonly kd: Strategy<\"group\", Required<KdOptions>>;\n readonly cut: Strategy<\"group\", Required<CutOptions>>;\n} = Object.freeze({\n quadtree: defineStrategy({\n step: \"group\",\n name: \"quadtree\",\n describe: \"The cells of a quadtree of the plane. A cell with more than `cap` nodes splits in four. It is the default rule of the router `sections`.\",\n defaults: { ...SECTION_DEFAULTS },\n schema: SECTION_SCHEMA,\n run: (graph: Graph, o: Readonly<Required<SectionOptions>>) => quadtreeGroups(graph, o),\n }),\n keys: defineStrategy({\n step: \"group\",\n name: \"keys\",\n describe: \"One group for each key of the nodes. The default key is the string `data.group` of the node. A node without a key is a group alone.\",\n defaults: { key: byDataGroup } as KeyOptions,\n schema: KEY_SCHEMA,\n run: (graph: Graph, o: Readonly<KeyOptions>) => keyGroups(graph, o),\n }),\n kd: defineStrategy({\n step: \"group\",\n name: \"kd\",\n describe: \"The cells of a k-d tree of the plane. A cell with more than `cap` nodes splits in two with a line across one axis, and each half splits again.\",\n defaults: { ...KD_DEFAULTS },\n schema: KD_SCHEMA,\n run: (graph: Graph, o: Readonly<Required<KdOptions>>) => kdGroups(graph, o),\n }),\n cut: defineStrategy({\n step: \"group\",\n name: \"cut\",\n describe: \"A guillotine cut that reads the edges. Each line goes where it cuts the fewest edges for its balance, so the far view has fewer links.\",\n defaults: { ...CUT_DEFAULTS },\n schema: CUT_SCHEMA,\n run: (graph: Graph, o: Readonly<Required<CutOptions>>) => cutGroups(graph, o),\n }),\n});\n\n/** The built-in strategies of each step, in order. A consumer adds its own: `createRegistry([...BUILT_IN_STRATEGIES, mine])`. */\nexport const BUILT_IN_STRATEGIES: readonly AnyStrategy[] = Object.freeze([\n ...Object.values(groupStrategies),\n ...Object.values(routerStrategies),\n ...Object.values(curveStrategies),\n ...Object.values(roomStrategies),\n]);\n\n/** The registry of the built-in strategies. The benchmark and the site take their lists from it. */\nexport const STRATEGIES: Registry = createRegistry(BUILT_IN_STRATEGIES);\n","import type { CurveSegment } from \"../../curves/model.ts\";\nimport type { CurveSpace } from \"../../curves/space.ts\";\nimport { dist, polylineLength, segmentsCross, turns, type Point } from \"../../geom.ts\";\nimport { Grid } from \"../../grid.ts\";\nimport { TOLERANCE } from \"../properties.ts\";\n\nconst EPS = 1e-9;\nconst DEG = 180 / Math.PI;\n\n/** A joint of a curve: the end of one drawn segment and the start of the next drawn segment. */\nexport interface CurveJoint {\n readonly at: Point;\n /** The angle between the tangent at the end of the first segment and the tangent at the start of the second segment, in degrees. */\n readonly angle: number;\n /** The jump of the curvature at the joint, `abs(κ^- - κ^+)`, in 1 / units. */\n readonly jump: number;\n /** The unit tangent at the end of the first segment. */\n readonly before: Point;\n /** The unit tangent at the start of the second segment. */\n readonly after: Point;\n}\n\nconst unit = (x: number, y: number): Point | undefined => {\n const l = Math.hypot(x, y);\n return l > EPS ? { x: x / l, y: y / l } : undefined;\n};\n\n/** This function gives the unit tangent and the curvature at the start (`t = 0`) or at the end (`t = 1`) of a segment that starts at `from`. */\nfunction frame(from: Point, s: CurveSegment, t: 0 | 1): { tangent: Point | undefined; curvature: number } {\n if (s.kind === \"line\" || s.kind === \"move\") return { tangent: unit(s.to.x - from.x, s.to.y - from.y), curvature: 0 };\n if (s.kind === \"arc\") {\n const a = t === 0 ? s.start : s.start + s.sweep;\n const sign = Math.sign(s.sweep) || 1;\n return { tangent: { x: -Math.sin(a) * sign, y: Math.cos(a) * sign }, curvature: s.radius > EPS ? sign / s.radius : 0 };\n }\n // A cubic curve: B'(0) = 3 (c1 - p0), B''(0) = 6 (p0 - 2 c1 + c2), B'(1) = 3 (p3 - c2), B''(1) = 6 (c1 - 2 c2 + p3).\n const [p0, p1, p2, p3] = [from, s.c1, s.c2, s.to];\n const d = t === 0 ? { x: 3 * (p1.x - p0.x), y: 3 * (p1.y - p0.y) } : { x: 3 * (p3.x - p2.x), y: 3 * (p3.y - p2.y) };\n const dd = t === 0 ? { x: 6 * (p0.x - 2 * p1.x + p2.x), y: 6 * (p0.y - 2 * p1.y + p2.y) } : { x: 6 * (p1.x - 2 * p2.x + p3.x), y: 6 * (p1.y - 2 * p2.y + p3.y) };\n const speed = Math.hypot(d.x, d.y);\n if (speed > EPS) return { tangent: { x: d.x / speed, y: d.y / speed }, curvature: (d.x * dd.y - d.y * dd.x) / speed ** 3 };\n // A handle of length 0: the tangent comes from the next control point that differs.\n const fallback = t === 0 ? (unit(p2.x - p0.x, p2.y - p0.y) ?? unit(p3.x - p0.x, p3.y - p0.y)) : (unit(p3.x - p1.x, p3.y - p1.y) ?? unit(p3.x - p0.x, p3.y - p0.y));\n return { tangent: fallback, curvature: 0 };\n}\n\nconst angleOf = (u: Point, v: Point): number => Math.acos(Math.max(-1, Math.min(1, u.x * v.x + u.y * v.y))) * DEG;\n\n/**\n * This function gives the joints of a curve: each point where one drawn segment ends and the next one starts.\n * A segment of length 0 has no tangent, so the joint skips it. The analytic tangents and curvatures of lines, cubic curves and arcs give the values.\n */\nexport function curveJoints(segments: readonly CurveSegment[]): CurveJoint[] {\n const out: CurveJoint[] = [];\n let at: Point | undefined;\n let last: { tangent: Point; curvature: number } | undefined;\n for (const s of segments) {\n if (s.kind === \"move\" || at === undefined) {\n at = s.to;\n last = undefined;\n continue;\n }\n const start = frame(at, s, 0);\n const end = frame(at, s, 1);\n if (start.tangent && end.tangent) {\n if (last) out.push({ at, angle: angleOf(last.tangent, start.tangent), jump: Math.abs(last.curvature - start.curvature), before: last.tangent, after: start.tangent });\n last = { tangent: end.tangent, curvature: end.curvature };\n }\n at = s.to;\n }\n return out;\n}\n\n/**\n * This function gives the G1 defect of a curve (C1 of MEAS0): `g1 = max_j angle(T_j^-, T_j^+)` over the joints, in degrees.\n * Lower is better. A curve is G1 when `g1` is 0.5 degrees or less. The cost is linear.\n */\nexport function g1Defect(segments: readonly CurveSegment[]): number {\n return curveJoints(segments).reduce((m, j) => Math.max(m, j.angle), 0);\n}\n\n/**\n * This function gives the G2 defect of a curve (C2 of MEAS0): `g2 = max_j abs(κ_j^- - κ_j^+) · u` over the joints.\n * The value has no unit, and lower is better. `u` is the unit of the board (`boardUnit`). The cost is linear.\n */\nexport function g2Defect(segments: readonly CurveSegment[], u: number): number {\n return curveJoints(segments).reduce((m, j) => Math.max(m, j.jump * u), 0);\n}\n\n/**\n * This function gives the bending energy of a sampled curve (C3 of MEAS0): `E = L · ∫ κ(s)^2 ds`.\n * At each inner sample, `κ = φ / l`, so `E = L · Σ φ_i^2 / l_i`. The length `l_i` is the mean of the two legs, with a limit of `8τ / φ_i`.\n * Thus a sharp corner counts as an arc with a sagitta of `τ`, the tolerance of the samples.\n *\n * The value has no unit, and lower is better. A full circle gives `4π^2`. The cost is linear.\n */\nexport function bendingEnergy(points: readonly Point[], tolerance = 0.25): number {\n const q: Point[] = [];\n for (const v of points) if (q.length === 0 || dist(q[q.length - 1]!, v) > EPS) q.push(v);\n if (q.length < 3) return 0;\n const phi = turns(q);\n let sum = 0;\n for (let i = 1; i + 1 < q.length; i++) {\n const t = Math.abs(phi[i - 1]!);\n if (t < EPS) continue;\n const l = Math.min((dist(q[i - 1]!, q[i]!) + dist(q[i]!, q[i + 1]!)) / 2, (8 * tolerance) / t);\n sum += (t * t) / l;\n }\n return polylineLength(q) * sum;\n}\n\n/** This function tells if a polyline crosses itself. Two legs next to each other do not count. The cost is `n log n`. */\nexport function crossesItself(p: readonly Point[]): boolean {\n if (p.length < 4) return false;\n const len = polylineLength(p) / (p.length - 1);\n const grid = new Grid<number>(Math.max(1, len * 4));\n for (let i = 1; i < p.length; i++) grid.addSegment(i, p[i - 1]!, p[i]!);\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n const hit = grid.someSegment(a, b, 0, (j) => j > i + 1 && segmentsCross(a, b, p[j - 1]!, p[j]!));\n if (hit) return true;\n }\n return false;\n}\n\n/** This function tells if a polyline turns back on itself at a vertex: a turn of more than 179 degrees, as at a cusp. */\nexport function hasCusp(p: readonly Point[]): boolean {\n return turns(p).some((t) => Math.abs(t) * DEG > 179);\n}\n\n/** The input of `curveFaults`: one curve and the polyline that it draws. */\nexport interface CurveCheck {\n /** The polyline of the route. */\n readonly polyline: readonly Point[];\n /** The segments of the curve. */\n readonly segments: readonly CurveSegment[];\n /** The samples of the curve (`sampleCurve`). */\n readonly samples: readonly Point[];\n /** The free space of the board. Without it, the check `clear` gives false. */\n readonly space?: CurveSpace;\n /** With these normals, the check `ends` also examines the direction of the curve at its two ends. */\n readonly startNormal?: Point;\n readonly endNormal?: Point;\n /** With this value, the check `g1` examines the joints. Give it for a curve type that is G1 by its design. */\n readonly smooth?: boolean;\n}\n\n/** The faults of one curve: one value for each proposed hard rule of the curves in MEAS0. */\nexport interface CurveFaults {\n /** `curve-clear`: the curve goes through a box that its polyline avoids (C7). */\n readonly clear: boolean;\n /** `curve-ends`: the curve misses an end of its polyline, or an end tangent is more than 1 degree off its normal (C10). */\n readonly ends: boolean;\n /** `curve-g1`: a joint has a G1 defect of more than 0.5 degrees, and it is not a corner that the free space keeps sharp (C1). */\n readonly g1: boolean;\n /** `curve-simple`: the curve crosses itself or turns back at a cusp, and its polyline does not (C9). */\n readonly simple: boolean;\n}\n\n/**\n * This function tells if a joint is a corner that the free space keeps sharp. The joint is a vertex of the polyline,\n * and the curve on one side of it goes along the leg of the polyline.\n */\nfunction keptSharp(j: CurveJoint, polyline: readonly Point[]): boolean {\n for (let i = 1; i + 1 < polyline.length; i++) {\n const v = polyline[i]!;\n if (dist(v, j.at) > 1e-6) continue;\n const a = unit(v.x - polyline[i - 1]!.x, v.y - polyline[i - 1]!.y);\n const b = unit(polyline[i + 1]!.x - v.x, polyline[i + 1]!.y - v.y);\n if ((a && angleOf(a, j.before) <= 0.5) || (b && angleOf(b, j.after) <= 0.5)) return true;\n }\n return false;\n}\n\n/** This function checks one curve against the proposed hard rules of the curves of MEAS0. The cost is `n log n` for each curve. */\nexport function curveFaults(c: CurveCheck): CurveFaults {\n const p = c.polyline;\n const s = c.samples;\n const clear = c.space !== undefined && s.length > 1 && c.space.addsHit(s, p);\n let ends = p.length > 0 && (s.length === 0 || dist(s[0]!, p[0]!) > TOLERANCE || dist(s[s.length - 1]!, p[p.length - 1]!) > TOLERANCE);\n if (!ends && (c.startNormal || c.endNormal)) {\n const joints = drawnFrames(c.segments);\n const n0 = c.startNormal && unit(c.startNormal.x, c.startNormal.y);\n const n1 = c.endNormal && unit(-c.endNormal.x, -c.endNormal.y);\n if (n0 && joints.first && angleOf(n0, joints.first) > 1) ends = true;\n if (n1 && joints.last && angleOf(n1, joints.last) > 1) ends = true;\n }\n const g1 = c.smooth === true && curveJoints(c.segments).some((j) => j.angle > 0.5 && !keptSharp(j, p));\n const simple = !crossesItself(p) && !hasCusp(p) && (crossesItself(s) || hasCusp(s));\n return { clear, ends, g1, simple };\n}\n\n/** This function gives the unit tangent at the start of the first drawn segment and at the end of the last drawn segment. */\nfunction drawnFrames(segments: readonly CurveSegment[]): { first: Point | undefined; last: Point | undefined } {\n let at: Point | undefined;\n let first: Point | undefined;\n let last: Point | undefined;\n for (const s of segments) {\n if (s.kind === \"move\" || at === undefined) {\n at = s.to;\n continue;\n }\n const t0 = frame(at, s, 0).tangent;\n const t1 = frame(at, s, 1).tangent;\n if (first === undefined && t0) first = t0;\n if (t1) last = t1;\n at = s.to;\n }\n return { first, last };\n}\n","import { tracedHighwayCurves, type JogStyle, type JogTrace, type LaneCurve } from \"../curves/highway/index.ts\";\nimport { CURVE_TYPES, curveSpace, distinctPoints, sampleCurve, type CubicSegment, type CurveSegment, type CurveSpace, type CurveType } from \"../curves/index.ts\";\nimport { polylineLength, segmentsCross, type Point } from \"../geom.ts\";\nimport { nodeIndex, type Graph, type Router } from \"../model.ts\";\nimport { nearestSide, SIDE_NORMAL } from \"../plugs.ts\";\nimport { laneRoutes, runKey, segmentsOf, type SegmentGraph } from \"../segments.ts\";\nimport { curveStrategies } from \"../strategies/builtins.ts\";\nimport type { Strategy } from \"../strategies/model.ts\";\nimport { measureLinks, type MeasuredLink } from \"./links.ts\";\nimport { g1Defect } from \"./measures/curves.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/**\n * One row of the benchmark of the curves: one curve type on the routes of one router on one fixture.\n * The type `T` of the name of the curve is `CurveType` for `benchCurves`, and `string` for `benchCurveStrategies`.\n */\nexport interface CurveBenchRow<T extends string = CurveType> {\n readonly router: string;\n readonly fixture: string;\n readonly type: T;\n /** The number of routes. */\n readonly links: number;\n /** The number of polylines that go through a box that is not one of their ends (`measureLinks`). */\n readonly through: number;\n /** The number of curves without a free space that go through such a box. */\n readonly free: number;\n /** The number of curves with the free space of the nodes (`curveSpace`) that go through such a box. */\n readonly clamped: number;\n /** The ratio of the length of all curves with the free space to the length of all polylines. */\n readonly length: number;\n /** The time to make all curves with the free space, in milliseconds. */\n readonly ms: number;\n}\n\n/** The options of `benchCurves`. */\nexport interface CurveBenchOptions {\n /** The radius of the types `rounded` and `arc`. The default is 12. */\n readonly radius?: number;\n /** The tolerance of the samples of the curves. The default is 0.25. */\n readonly tolerance?: number;\n}\n\n/**\n * This function routes a graph with a router and makes each curve type of each route.\n * It counts the curves that go through a box, with and without the free space, and it compares their length to the polylines.\n * The type `spline` leaves each plug along the normal of the nearest side of its node.\n */\nexport function benchCurves(router: Router, fixture: string, graph: Graph, options: CurveBenchOptions = {}): CurveBenchRow[] {\n // Each built-in curve strategy has the name of its curve type, so each row has a `CurveType`.\n return benchCurveStrategies(\n router,\n fixture,\n graph,\n CURVE_TYPES.map((t) => curveStrategies[t]),\n options,\n ) as CurveBenchRow[];\n}\n\n/**\n * This function does the work of `benchCurves` with a list of curve strategies, in place of the curve types.\n * The option `radius` goes to each strategy. A strategy without such an option does not read it.\n */\nexport function benchCurveStrategies(\n router: Router,\n fixture: string,\n graph: Graph,\n curves: readonly Strategy<\"curve\">[],\n options: CurveBenchOptions = {},\n): CurveBenchRow<string>[] {\n const tolerance = options.tolerance ?? 0.25;\n const result = router.route(graph);\n const byId = nodeIndex(graph);\n const boxes = new Map(graph.nodes.map((n) => [n.id, n.box]));\n const edges = new Map(graph.edges.map((e) => [e.id, e]));\n const space = curveSpace(\n graph.nodes.map((n) => n.box),\n tolerance,\n );\n const routes = result.routes.flatMap((r) => {\n const e = edges.get(r.edge);\n const s = e && byId.get(e.source.node);\n const t = e && byId.get(e.target.node);\n if (!e || !s || !t || r.points.length < 2) return [];\n const first = r.points[0]!;\n const last = r.points[r.points.length - 1]!;\n return [{ source: s.id, target: t.id, points: r.points, startNormal: SIDE_NORMAL[nearestSide(s.box, first)], endNormal: SIDE_NORMAL[nearestSide(t.box, last)] }];\n });\n const base = measureLinks(boxes, routes);\n const ink = routes.reduce((sum, r) => sum + polylineLength(r.points), 0);\n const radius = { radius: options.radius ?? 12 };\n return curves.map((curve): CurveBenchRow<string> => {\n const make = (withSpace: boolean): MeasuredLink[] =>\n routes.map((r) => ({\n source: r.source,\n target: r.target,\n points: sampleCurve(\n curve.run({ points: r.points, startNormal: r.startNormal, endNormal: r.endNormal, ...(withSpace ? { space } : {}) }, radius),\n tolerance,\n ),\n }));\n const free = measureLinks(boxes, make(false));\n const t0 = now();\n const clamped = make(true);\n const ms = now() - t0;\n const length = clamped.reduce((sum, l) => sum + polylineLength(l.points), 0);\n return {\n router: router.name,\n fixture,\n type: curve.name,\n links: routes.length,\n through: base.through,\n free: free.through,\n clamped: measureLinks(boxes, clamped).through,\n length: ink > 0 ? length / ink : 1,\n ms,\n };\n });\n}\n\n/** This function writes the rows of `benchCurves` as a Markdown table. */\nexport function formatCurves(rows: readonly CurveBenchRow<string>[]): string {\n const head = \"| router | fixture | curve | routes | through, polyline | through, free | through, clamped | length | ms |\";\n const line = \"|---|---|---|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map((r) => `| ${r.router} | ${r.fixture} | ${r.type} | ${r.links} | ${r.through} | ${r.free} | ${r.clamped} | ${r.length.toFixed(3)} | ${r.ms.toFixed(1)} |`);\n return [head, line, ...body].join(\"\\n\");\n}\n\n/** The options of `measureHighways`. */\nexport interface HighwayMeasureOptions {\n /** The largest width of an open segment, as in `laneRoutes`. The default is 16. */\n readonly maxWidth?: number;\n /** A piece of a curve with a radius under this value counts in `underMin`. The default is 4. */\n readonly minRadius?: number;\n /** The length at each end of a segment that the spacing does not sample, for the merges and the splits. The default is 12. */\n readonly ends?: number;\n /** The free space of the board. With it, the measure counts the lanes that go through a box that their polyline avoids. */\n readonly space?: CurveSpace;\n}\n\n/**\n * The measures of the lanes of the open segments of a board, after a curve.\n * The spacing errors are shares of the spacing of the segment: 0.05 is 5% of the spacing.\n */\nexport interface HighwayMeasures {\n /** The number of open segments with two lanes or more. */\n readonly bundles: number;\n /** The number of curves of edges in an open segment. */\n readonly lanes: number;\n /** The number of sample points of the spacing. */\n readonly samples: number;\n /** The largest spacing error at a sample point. */\n readonly worstSpacing: number;\n /** The mean spacing error of the sample points. */\n readonly meanSpacing: number;\n /** The share of the sample points with a spacing error over `SPACING_LIMIT`. */\n readonly overLimit: number;\n /** The number of points where two lanes of one open segment cross, in the body of the segment: its bends and its straight parts. */\n readonly crossings: number;\n /** The number of points where two lanes of one open segment cross near an end of the segment, in the option `ends`. These are the merges and splits. */\n readonly endCrossings: number;\n /** The number of breaks of the tangent (G1 faults) near the open segments, by more than `BREAK` radians. */\n readonly breaks: number;\n /** The smallest radius of an arc or a cubic piece near the open segments. It is `Infinity` when there is no such piece. */\n readonly minRadius: number;\n /** The number of arcs and cubic pieces near the open segments with a radius under the option `minRadius`. */\n readonly underMin: number;\n /** The number of lanes that go through a box that their polyline of `laneRoutes` avoids. */\n readonly through: number;\n}\n\n/** A break of the tangent larger than this angle, in radians, counts in `breaks`. */\nexport const BREAK = 0.01;\n\n/** A spacing error over this share of the spacing counts in `overLimit`. */\nexport const SPACING_LIMIT = 0.05;\n\n/** A lane goes along a segment for the spacing where the cosine of the angle between their directions is at least this value. */\nconst ALONG = Math.cos(Math.PI / 6);\n/** A lane is in a segment for the crossings where the cosine of the angle between their directions is at least this value. */\nconst FORWARD = Math.cos((5 * Math.PI) / 12);\n\n/** This function gives the unit tangent at the start and at the end of a segment that starts at `from`. */\nfunction tangents(from: Point, s: CurveSegment): [Point, Point] | undefined {\n const unit = (a: Point, b: Point): Point | undefined => {\n const l = Math.hypot(b.x - a.x, b.y - a.y);\n return l > 1e-9 ? { x: (b.x - a.x) / l, y: (b.y - a.y) / l } : undefined;\n };\n if (s.kind === \"move\") return undefined;\n if (s.kind === \"line\") {\n const u = unit(from, s.to);\n return u && [u, u];\n }\n if (s.kind === \"cubic\") {\n const a = unit(from, s.c1) ?? unit(from, s.c2) ?? unit(from, s.to);\n const b = unit(s.c2, s.to) ?? unit(s.c1, s.to) ?? unit(from, s.to);\n return a && b && [a, b];\n }\n const d = Math.sign(s.sweep);\n const end = s.start + s.sweep;\n return [\n { x: -d * Math.sin(s.start), y: d * Math.cos(s.start) },\n { x: -d * Math.sin(end), y: d * Math.cos(end) },\n ];\n}\n\n/** This function gives the smallest radius of curvature of a cubic piece from `p0`, from 33 sample points. */\nfunction cubicRadius(p0: Point, c: CubicSegment): number {\n let min = Infinity;\n for (let i = 0; i <= 32; i++) {\n const t = i / 32;\n const u = 1 - t;\n const dx = 3 * (u * u * (c.c1.x - p0.x) + 2 * u * t * (c.c2.x - c.c1.x) + t * t * (c.to.x - c.c2.x));\n const dy = 3 * (u * u * (c.c1.y - p0.y) + 2 * u * t * (c.c2.y - c.c1.y) + t * t * (c.to.y - c.c2.y));\n const ddx = 6 * (u * (c.c2.x - 2 * c.c1.x + p0.x) + t * (c.to.x - 2 * c.c2.x + c.c1.x));\n const ddy = 6 * (u * (c.c2.y - 2 * c.c1.y + p0.y) + t * (c.to.y - 2 * c.c2.y + c.c1.y));\n const k = Math.abs(dx * ddy - dy * ddx);\n if (k > 1e-12) min = Math.min(min, Math.hypot(dx, dy) ** 3 / k);\n }\n return min;\n}\n\n/** This function gives points along a polyline, `step` apart, with the first point and the last point. */\nfunction resample(p: readonly Point[], step: number): Point[] {\n const out: Point[] = p.length > 0 ? [p[0]!] : [];\n let next = step;\n let s = 0;\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n const l = Math.hypot(b.x - a.x, b.y - a.y);\n while (next < s + l) {\n const t = (next - s) / l;\n out.push({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t });\n next += step;\n }\n s += l;\n }\n if (p.length > 1) out.push(p[p.length - 1]!);\n return out;\n}\n\n/** The nearest point of a polyline to a point. */\ninterface Nearest {\n /** The distance to the polyline. */\n readonly d: number;\n /** The place of the nearest point along the polyline. */\n readonly s: number;\n /** The unit direction of the piece of the polyline with the nearest point. */\n readonly u: Point;\n}\n\n/** This function gives the nearest point of a polyline to `q`. */\nfunction nearest(q: Point, p: readonly Point[]): Nearest {\n let best = Infinity;\n let at = 0;\n let u: Point = { x: 1, y: 0 };\n let s = 0;\n for (let i = 1; i < p.length; i++) {\n const a = p[i - 1]!;\n const b = p[i]!;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const l = Math.hypot(dx, dy);\n const t = l === 0 ? 0 : Math.max(0, Math.min(1, ((q.x - a.x) * dx + (q.y - a.y) * dy) / (l * l)));\n const d = Math.hypot(q.x - (a.x + t * dx), q.y - (a.y + t * dy));\n if (d < best && l > 0) {\n best = d;\n at = s + t * l;\n u = { x: dx / l, y: dy / l };\n }\n s += l;\n }\n return { d: best, s: at, u };\n}\n\n/** One open segment with two lanes or more, as the measure sees it. */\ninterface Bundle {\n /** The center line, with no repeated points. */\n readonly c: readonly Point[];\n readonly edges: readonly string[];\n /** The direction of each lane along the center line: 1 forward, -1 back. */\n readonly sign: readonly number[];\n readonly spacing: number;\n /** The largest distance from the center line of a point of a lane in the segment. */\n readonly band: number;\n readonly total: number;\n}\n\n/**\n * This function gives the parts of a sampled lane that go along a bundle. Each part is near its center line, between the places `from` and `to`.\n * Each part goes in the direction of the lane in the bundle. A lane that passes near the bundle in another direction is not in it there.\n */\nfunction partsAlong(p: readonly Point[], b: Bundle, sign: number, from: number, to: number, cos: number): Point[][] {\n const xs = b.c.map((q) => q.x);\n const ys = b.c.map((q) => q.y);\n const x0 = Math.min(...xs) - b.band;\n const x1 = Math.max(...xs) + b.band;\n const y0 = Math.min(...ys) - b.band;\n const y1 = Math.max(...ys) + b.band;\n const parts: Point[][] = [];\n let cur: Point[] = [];\n for (let i = 0; i < p.length; i++) {\n const q = p[i]!;\n let ok = q.x >= x0 && q.x <= x1 && q.y >= y0 && q.y <= y1;\n if (ok) {\n const m = nearest(q, b.c);\n const a = p[Math.max(0, i - 1)]!;\n const z = p[Math.min(p.length - 1, i + 1)]!;\n const l = Math.hypot(z.x - a.x, z.y - a.y);\n ok = m.d <= b.band && m.s >= from && m.s <= to && l > 0 && sign * ((z.x - a.x) * m.u.x + (z.y - a.y) * m.u.y) >= cos * l;\n }\n if (ok) cur.push(q);\n else if (cur.length > 0) {\n parts.push(cur);\n cur = [];\n }\n }\n if (cur.length > 0) parts.push(cur);\n return parts;\n}\n\n/**\n * This function measures the lanes of the open segments of a board after a curve. It measures the spacing, the crossings,\n * the breaks of the tangent, the radii and the lanes that go through a box.\n *\n * A lane is in a segment where it goes near the center line of the segment, in its direction along the segment.\n * The spacing samples each lane `spacing / 4` apart, from the middle of the first leg to the middle of the last leg.\n * It does not sample the lane in the option `ends`. The ends of a segment are for the merges and the splits.\n *\n * A sample compares the distance to the next lane with the spacing. It counts when the next lane is in the band of the segment.\n * The crossings, the breaks and the radii count along the full segment, and `ends` past each end of it.\n */\nexport function measureHighways(\n graph: SegmentGraph,\n open: ReadonlySet<string>,\n laneWidth: number,\n curves: readonly LaneCurve[],\n options: HighwayMeasureOptions = {},\n): HighwayMeasures {\n const maxWidth = options.maxWidth ?? 16;\n const minRadius = options.minRadius ?? 4;\n const ends = options.ends ?? 12;\n const signs = new Map<string, number>();\n for (const path of graph.paths) for (const ref of path.segments) signs.set(`${ref.segment}|${path.edge}`, ref.reverse ? -1 : 1);\n const bundles: Bundle[] = [];\n for (const s of graph.segments) {\n const c = distinctPoints(s.points);\n if (s.count < 2 || !open.has(runKey(s.edges)) || c.length < 2) continue;\n const spacing = Math.min(laneWidth, maxWidth / (s.count - 1));\n const sign = s.edges.map((e) => signs.get(`${s.id}|${e}`) ?? 1);\n bundles.push({ c, edges: s.edges, sign, spacing, band: ((s.count - 1) / 2) * spacing + spacing, total: polylineLength(c) });\n }\n const inBundle = new Set(bundles.flatMap((s) => s.edges));\n const lanes = curves.filter((c) => inBundle.has(c.edge));\n // The samples of the curves are within 0.5% of the spacing of the curve, so the samples add almost no error.\n const fine = Math.max(1e-3, Math.min(laneWidth, maxWidth) * 0.005);\n const sampled = new Map(lanes.map((c) => [c.edge, sampleCurve(c.segments, fine)]));\n let samples = 0;\n let worst = 0;\n let sum = 0;\n let over = 0;\n const crossings = new Set<string>();\n const endCrossings = new Set<string>();\n for (const b of bundles) {\n const sp = b.spacing;\n const c = b.c;\n const from = Math.max(ends, Math.hypot(c[1]!.x - c[0]!.x, c[1]!.y - c[0]!.y) / 2);\n const to = b.total - Math.max(ends, Math.hypot(c[c.length - 1]!.x - c[c.length - 2]!.x, c[c.length - 1]!.y - c[c.length - 2]!.y) / 2);\n const body = b.edges.map((e, k) => partsAlong(sampled.get(e) ?? [], b, b.sign[k]!, from, to, ALONG));\n const whole = b.edges.map((e, k) => partsAlong(sampled.get(e) ?? [], b, b.sign[k]!, 0, b.total, ALONG));\n const crossing = b.edges.map((e, k) => partsAlong(sampled.get(e) ?? [], b, b.sign[k]!, 0, b.total, FORWARD));\n for (let k = 0; k + 1 < b.edges.length; k++)\n for (const [x, y] of [\n [k, k + 1],\n [k + 1, k],\n ] as const)\n for (const part of body[x]!)\n for (const q of resample(part, sp / 4)) {\n let d = Infinity;\n for (const other of whole[y]!) d = Math.min(d, nearest(q, other).d);\n if (d > b.band) continue;\n const err = Math.abs(d - sp) / sp;\n samples += 1;\n sum += err;\n if (err > SPACING_LIMIT) over += 1;\n worst = Math.max(worst, err);\n }\n for (let i = 0; i < b.edges.length; i++)\n for (let j = i + 1; j < b.edges.length; j++)\n for (const P of crossing[i]!)\n for (const Q of crossing[j]!)\n for (let x = 1; x < P.length; x++)\n for (let y = 1; y < Q.length; y++) {\n if (!segmentsCross(P[x - 1]!, P[x]!, Q[y - 1]!, Q[y]!)) continue;\n const q = { x: (P[x - 1]!.x + P[x]!.x) / 2, y: (P[x - 1]!.y + P[x]!.y) / 2 };\n const pair = [b.edges[i]!, b.edges[j]!].sort().join(\"|\");\n const at = nearest(q, c).s;\n (at >= from && at <= to ? crossings : endCrossings).add(`${pair}@${Math.round(q.x)},${Math.round(q.y)}`);\n }\n }\n // A piece of a lane is near a segment of the lane when its start is near the center line, or past an end by no more than `ends`.\n const near = new Map<string, Bundle[]>();\n for (const b of bundles) for (const e of b.edges) near.set(e, [...(near.get(e) ?? []), b]);\n const isNear = (edge: string, q: Point): boolean => (near.get(edge) ?? []).some((b) => nearest(q, b.c).d <= b.band + ends);\n let breaks = 0;\n let least = Infinity;\n let underMin = 0;\n let through = 0;\n const polylines = options.space ? new Map(laneRoutes(graph, open, laneWidth, maxWidth).map((r) => [r.edge, r.points])) : undefined;\n for (const lane of lanes) {\n let at: Point | undefined;\n let before: Point | undefined;\n for (const s of lane.segments) {\n if (s.kind === \"move\" || at === undefined) {\n at = s.to;\n before = undefined;\n continue;\n }\n const t = tangents(at, s);\n const close = isNear(lane.edge, at);\n if (close && t && before && Math.acos(Math.max(-1, Math.min(1, before.x * t[0].x + before.y * t[0].y))) > BREAK) breaks += 1;\n const r = s.kind === \"arc\" ? s.radius : s.kind === \"cubic\" ? cubicRadius(at, s) : Infinity;\n if (close && r < Infinity) {\n least = Math.min(least, r);\n if (r < minRadius - 1e-9) underMin += 1;\n }\n if (t) before = t[1];\n at = s.to;\n }\n const p = polylines?.get(lane.edge);\n if (options.space && p && options.space.addsHit(sampleCurve(lane.segments, options.space.tolerance), p)) through += 1;\n }\n return {\n bundles: bundles.length,\n lanes: lanes.length,\n samples,\n worstSpacing: worst,\n meanSpacing: samples > 0 ? sum / samples : 0,\n overLimit: samples > 0 ? over / samples : 0,\n crossings: crossings.size,\n endCrossings: endCrossings.size,\n breaks,\n minRadius: least,\n underMin,\n through,\n };\n}\n\n/** One row of `benchHighways`: the measures of the lanes of one router on one board, after one way to curve them. */\nexport interface HighwayBenchRow extends HighwayMeasures {\n readonly router: string;\n readonly fixture: string;\n /** The way to curve the lanes: `rounded` curves each lane alone, and `highway` curves the lanes of a bundle together. */\n readonly curve: \"rounded\" | \"highway\";\n /** The shape of the S curves of a row `highway`. */\n readonly jog?: JogStyle;\n /** The measures of the S curves of a row `highway`. */\n readonly jogs?: JogMeasures;\n /** The time to make all curves, in milliseconds. */\n readonly ms: number;\n}\n\n/** The measures of the S curves where the lanes join or leave a bundle. Each curvature is in 1 / units. */\nexport interface JogMeasures {\n /** The number of S curves. */\n readonly count: number;\n /** The number of S curves that are a biarc. A polynomial S curve that does not fit on its leg is a biarc. */\n readonly biarcs: number;\n /** The median and the largest of the peak curvature of each S curve with the shape of the row. */\n readonly peakMedian: number;\n readonly peakMax: number;\n /** The median ratio of the peak curvature of each S curve of the row to the peak curvature of the same biarc S curve. */\n readonly peakRatio?: number;\n /** The largest curvature at an end of an S curve with the shape of the row. The straight leg next to it has the curvature 0, so it is the jump at the end. */\n readonly endJump: number;\n /** The largest jump of the curvature at a joint inside an S curve with the shape of the row. */\n readonly innerJump: number;\n}\n\n/** This function gives the median of the values, or 0 when there are none. */\nfunction medianOf(values: number[]): number {\n values.sort((a, b) => a - b);\n const n = values.length;\n return n === 0 ? 0 : n % 2 === 1 ? values[(n - 1) / 2]! : (values[n / 2 - 1]! + values[n / 2]!) / 2;\n}\n\n/** This function gives the curvature of the cubic `(p0, c1, c2, p3)` at `t`. */\nfunction cubicCurvature(p0: Point, s: CubicSegment, t: number): number {\n const u = 1 - t;\n const [c1, c2, p3] = [s.c1, s.c2, s.to];\n const dx = 3 * u * u * (c1.x - p0.x) + 6 * u * t * (c2.x - c1.x) + 3 * t * t * (p3.x - c2.x);\n const dy = 3 * u * u * (c1.y - p0.y) + 6 * u * t * (c2.y - c1.y) + 3 * t * t * (p3.y - c2.y);\n const ddx = 6 * u * (c2.x - 2 * c1.x + p0.x) + 6 * t * (p3.x - 2 * c2.x + c1.x);\n const ddy = 6 * u * (c2.y - 2 * c1.y + p0.y) + 6 * t * (p3.y - 2 * c2.y + c1.y);\n const speed = Math.hypot(dx, dy);\n return speed > 1e-12 ? (dx * ddy - dy * ddx) / speed ** 3 : 0;\n}\n\n/** This function gives the signed curvature at the start (`t = 0`) and at the end (`t = 1`) of a segment, and its largest absolute curvature. */\nfunction curvatureOf(from: Point, s: CurveSegment): { readonly start: number; readonly end: number; readonly peak: number } {\n if (s.kind === \"arc\") {\n const k = s.radius > 0 ? Math.sign(s.sweep) / s.radius : 0;\n return { start: k, end: k, peak: Math.abs(k) };\n }\n if (s.kind !== \"cubic\") return { start: 0, end: 0, peak: 0 };\n let peak = 0;\n for (let i = 0; i <= 64; i++) peak = Math.max(peak, Math.abs(cubicCurvature(from, s, i / 64)));\n return { start: cubicCurvature(from, s, 0), end: cubicCurvature(from, s, 1), peak };\n}\n\n/** This function gives the peak curvature of each S curve, by lane. `jogs` has the first and the last index of each S curve in the segments of its lane. */\nexport function jogPeaks(curves: readonly LaneCurve[], jogs: JogTrace): number[][] {\n return curves.map((c, i) =>\n (jogs[i] ?? []).map(([first, last]) => {\n let peak = 0;\n for (let k = first; k <= last; k++) peak = Math.max(peak, curvatureOf(c.segments[k - 1]?.to ?? c.segments[k]!.to, c.segments[k]!).peak);\n return peak;\n }),\n );\n}\n\n/**\n * This function gives the peak curvature of one curve, in 1 / units: the largest curvature of its lines, cubic pieces and arcs (C5 of MEAS0 as `1 / rmin`).\n * A joint with a tangent break of more than 0.5 degrees is a sharp corner, so such a curve gets `Infinity`. A curve of lines only gives 0.\n */\nexport function peakCurvature(segments: readonly CurveSegment[]): number {\n if (g1Defect(segments) > 0.5) return Infinity;\n let peak = 0;\n for (let k = 1; k < segments.length; k++) peak = Math.max(peak, curvatureOf(segments[k - 1]!.to, segments[k]!).peak);\n return peak;\n}\n\n/**\n * This function measures the S curves of the lanes that have the shape `style`. `jogs` has the first and the last index of each S curve in the segments of its lane.\n * With `biarcPeaks`, the peak curvatures of the same S curves as biarcs, it also gives the median ratio of the peaks.\n */\nexport function measureJogs(curves: readonly LaneCurve[], jogs: JogTrace, style: JogStyle = \"biarc\", biarcPeaks?: readonly (readonly number[])[]): JogMeasures {\n const peaks: number[] = [];\n const ratios: number[] = [];\n let endJump = 0;\n let innerJump = 0;\n let biarcs = 0;\n let count = 0;\n curves.forEach((c, i) => {\n (jogs[i] ?? []).forEach(([first, last, shape], n) => {\n count++;\n if (shape === \"biarc\") biarcs++;\n if (shape !== style) return;\n let peak = 0;\n let before: number | undefined;\n for (let k = first; k <= last; k++) {\n const s = c.segments[k]!;\n const m = curvatureOf(c.segments[k - 1]?.to ?? s.to, s);\n peak = Math.max(peak, m.peak);\n if (k === first) endJump = Math.max(endJump, Math.abs(m.start));\n if (k === last) endJump = Math.max(endJump, Math.abs(m.end));\n if (before !== undefined) innerJump = Math.max(innerJump, Math.abs(before - m.start));\n before = m.end;\n }\n peaks.push(peak);\n const b = biarcPeaks?.[i]?.[n];\n if (b !== undefined && b > 0) ratios.push(peak / b);\n });\n });\n const peakMax = peaks.reduce((a, b) => Math.max(a, b), 0);\n return { count, biarcs, peakMedian: medianOf(peaks), peakMax, ...(biarcPeaks ? { peakRatio: medianOf(ratios) } : {}), endJump, innerJump };\n}\n\n/** The options of `benchHighways`. */\nexport interface HighwayBenchOptions {\n /** The spacing of the lanes. The default is 4. */\n readonly spacing?: number;\n /** The largest width of an open segment. The default is 16. */\n readonly maxWidth?: number;\n /** The radius of each curve. The default is 12. */\n readonly radius?: number;\n /** The smallest radius of `highwayCurves`, and the limit of `underMin`. The default is 4. */\n readonly minRadius?: number;\n /** The shapes of the S curves. Each shape gives one row `highway`. The default is `[\"biarc\"]`. */\n readonly jogs?: readonly JogStyle[];\n /** The number of cubic pieces of a `quintic` S curve. The default is 4. */\n readonly jogPieces?: number;\n}\n\n/**\n * This function routes a graph, opens each shared segment, and curves the lanes in two ways.\n * The row `rounded` curves each lane of `laneRoutes` alone with the curve `rounded`. Each row `highway` curves them with `highwayCurves` and one shape of S curve.\n * Both ways get the free space of the nodes.\n */\nexport function benchHighways(router: Router, fixture: string, graph: Graph, options: HighwayBenchOptions = {}): HighwayBenchRow[] {\n const spacing = options.spacing ?? 4;\n const maxWidth = options.maxWidth ?? 16;\n const radius = options.radius ?? 12;\n const minRadius = options.minRadius ?? 4;\n const segments = segmentsOf(router.route(graph));\n const open = new Set(segments.segments.filter((s) => s.count > 1).map((s) => runKey(s.edges)));\n const space = curveSpace(graph.nodes.map((n) => n.box));\n const measure = { maxWidth, minRadius, ends: radius, space };\n const t0 = now();\n const alone = laneRoutes(segments, open, spacing, maxWidth).map((r) => ({ edge: r.edge, segments: curveStrategies.rounded.run({ points: r.points, space }, { radius }) }));\n const t1 = now();\n const rows: HighwayBenchRow[] = [{ router: router.name, fixture, curve: \"rounded\", ...measureHighways(segments, open, spacing, alone, measure), ms: t1 - t0 }];\n // The rows of the other shapes compare their peaks with the S curves of the row `biarc` before them.\n let biarcPeaks: number[][] | undefined;\n for (const jog of options.jogs ?? [\"biarc\"]) {\n const t2 = now();\n const together = tracedHighwayCurves(segments, open, spacing, { maxWidth, radius, minRadius, space, jog, jogPieces: options.jogPieces ?? 4 });\n const t3 = now();\n if (jog === \"biarc\") biarcPeaks = jogPeaks(together.curves, together.jogs);\n rows.push({\n router: router.name,\n fixture,\n curve: \"highway\",\n jog,\n jogs: measureJogs(together.curves, together.jogs, jog, jog === \"biarc\" ? undefined : biarcPeaks),\n ...measureHighways(segments, open, spacing, together.curves, measure),\n ms: t3 - t2,\n });\n }\n return rows;\n}\n\n/** This function writes the rows of `benchHighways` as a Markdown table. The spacing errors are percents of the spacing. */\nexport function formatHighways(rows: readonly HighwayBenchRow[]): string {\n const head =\n \"| router | fixture | curve | jog | bundles | lanes | worst spacing | mean spacing | over 5% | crossings | end crossings | tangent breaks | min radius | under min | through | S curves | S biarcs | S peak κ median | S peak κ max | S peak ratio | S end κ | S inner jump | ms |\";\n const line = \"|---|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const pct = (v: number): string => `${(v * 100).toFixed(1)}%`;\n const k = (v: number | undefined): string => (v === undefined ? \"-\" : v.toFixed(4));\n const body = rows.map(\n (r) =>\n `| ${r.router} | ${r.fixture} | ${r.curve} | ${r.jog ?? \"-\"} | ${r.bundles} | ${r.lanes} | ${pct(r.worstSpacing)} | ${pct(r.meanSpacing)} | ${pct(r.overLimit)} | ${r.crossings} | ${r.endCrossings} | ${r.breaks} | ${r.minRadius === Infinity ? \"-\" : r.minRadius.toFixed(2)} | ${r.underMin} | ${r.through} | ${r.jogs?.count ?? \"-\"} | ${r.jogs?.biarcs ?? \"-\"} | ${k(r.jogs?.peakMedian)} | ${k(r.jogs?.peakMax)} | ${k(r.jogs?.peakRatio)} | ${k(r.jogs?.endJump)} | ${k(r.jogs?.innerJump)} | ${r.ms.toFixed(1)} |`,\n );\n return [head, line, ...body].join(\"\\n\");\n}\n","import type { Box } from \"../geom.ts\";\nimport { levelLinks } from \"../levels.ts\";\nimport type { Graph, LevelLink, Node, Result, Router } from \"../model.ts\";\nimport { makeRoom, openGaps, roomLinks, type RoomOptions } from \"../room/index.ts\";\nimport { gapLanes, LANE_ORDERS, type LaneOrder } from \"../room/lanes.ts\";\nimport { levelPairs, levelRoom, type LevelRoomOptions } from \"../room/levels/index.ts\";\nimport { buildSections, levelCut, treeDepth, type SectionOptions } from \"../sections.ts\";\nimport { sectionsRouter } from \"../routers/sections.ts\";\nimport { laneRoutes, runKey, segmentsOf } from \"../segments.ts\";\nimport { roomStrategies } from \"../strategies/builtins.ts\";\nimport type { Strategy } from \"../strategies/model.ts\";\nimport { benchHighways, type HighwayMeasures } from \"./curves.ts\";\nimport { measureLinks, measureRouteFaults, type LinkFaults } from \"./links.ts\";\nimport { measureQuality } 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 of the room: one state of a board, packed or open, and the measures of its links. */\nexport interface RoomBenchRow {\n readonly fixture: string;\n /** The state of the board: `packed`, `gutter` (each gap open to the gutter only), or a method of `roomDemand`. */\n readonly board: string;\n /** The area of the bounding box of the boxes, as a share of the area of the packed board. */\n readonly area: number;\n /** The faults of the links of the far view (`levelLinks` with each box as one item). */\n readonly faults: LinkFaults;\n /** The crossings of the links of the far view (`measureQuality`). */\n readonly crossings: number;\n /** The ink of the links of the far view. */\n readonly ink: number;\n /** The mean detour of the links of the far view. */\n readonly detour: number;\n /**\n * The number of lane routes of the router `sections` that go through a box. Each shared segment opens to one lane for each edge,\n * at the spacing of the options (`laneRoutes`).\n */\n readonly laneThrough: number;\n /** The time of `makeRoom`, in milliseconds. It is 0 for the packed board. */\n readonly ms: number;\n}\n\n/** This function gives the area of the bounding box of the nodes. */\nfunction areaOf(nodes: readonly { readonly box: Box }[]): number {\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 return nodes.length ? (x1 - x0) * (y1 - y0) : 0;\n}\n\n/**\n * This function measures the links of one board. It measures the links of the far view, with each node of the graph as one item of a level.\n * With a lane order, each link of the far view gets its own lane in each gap (`gapLanes` at the lane width `spacing`).\n * Without it, the links of a gap share the lines of the level links.\n * The function also measures the lane routes of the router `sections` at the lane width `spacing`.\n */\nexport function measureBoard(graph: Graph, spacing: number, order?: LaneOrder): Omit<RoomBenchRow, \"fixture\" | \"board\" | \"area\" | \"ms\"> {\n const links = roomLinks(graph);\n const items = graph.nodes.map((n) => ({ id: n.id, box: n.box, nodes: [n.id] }));\n const level = levelLinks(\n items,\n links.map((l) => ({ source: l.source, target: l.target, count: l.count ?? 1 })),\n );\n const drawn = order ? gapLanes(graph.nodes, level, { spacing, order }) : level;\n const boxes = new Map(graph.nodes.map((n) => [n.id, n.box]));\n // `measureQuality` reads routes of edges, so each link of the far view stands for the first edge of its pair.\n const edgeOf = new Map<string, string>();\n for (const e of graph.edges) {\n const key = `${e.source.node}\\u0000${e.target.node}`;\n if (!edgeOf.has(key)) edgeOf.set(key, e.id);\n }\n const asRoutes: Result = { routes: drawn.map((l) => ({ edge: edgeOf.get(`${l.source}\\u0000${l.target}`)!, points: l.points })) };\n const q = measureQuality(graph, asRoutes);\n const routed = sectionsRouter({ name: \"sections\" }).route(graph);\n const segments = segmentsOf(routed);\n const open = new Set(segments.segments.filter((s) => s.count > 1).map((s) => runKey(s.edges)));\n const lanes = laneRoutes(segments, open, spacing);\n return {\n faults: measureLinks(boxes, drawn),\n crossings: q.crossings,\n ink: q.ink,\n detour: q.detour,\n laneThrough: measureRouteFaults(graph, { routes: lanes }).through,\n };\n}\n\n/**\n * This function measures a packed board, the board with each gap open to the gutter only, and the board that each room strategy opens.\n * The options are the same for each strategy, except `method`. The default strategies are the methods `routes` and `lines` of `roomDemand`.\n */\nexport function benchRoom(\n fixture: string,\n graph: Graph,\n options: RoomOptions = {},\n methods: readonly Strategy<\"room\">[] = [roomStrategies.routes, roomStrategies.lines],\n): RoomBenchRow[] {\n const spacing = options.spacing ?? 4;\n const area0 = areaOf(graph.nodes);\n const links = roomLinks(graph);\n const row = (board: string, nodes: readonly Node[], ms: number): RoomBenchRow => ({\n fixture,\n board,\n area: area0 > 0 ? areaOf(nodes) / area0 : 1,\n ms,\n ...measureBoard({ nodes, edges: graph.edges }, spacing),\n });\n const rows = [row(\"packed\", graph.nodes, 0)];\n const t0 = now();\n const gutter = makeRoom(graph.nodes, links, { ...options, spacing: 0, method: \"routes\" });\n rows.push(row(\"gutter\", gutter.items, now() - t0));\n const { method: _method, ...preset } = options;\n for (const s of methods) {\n const t1 = now();\n const gaps = s.run({ items: graph.nodes, links }, preset);\n const nodes = openGaps(graph.nodes, gaps, options.snap);\n rows.push(row(s.name, nodes, now() - t1));\n }\n return rows;\n}\n\n/** One setting of a sweep of the room: the options of `makeRoom` and the lane order of the far view. */\nexport interface RoomSetting {\n /** The name of the setting in the column `board`. */\n readonly name: string;\n readonly options: RoomOptions;\n /** The lane order of the far view. Without it, the links of a gap share the lines of the level links. */\n readonly lanes?: LaneOrder;\n}\n\n/**\n * This function measures the board that `makeRoom` opens with each setting, with the method `routes`.\n * The first row is the fair baseline: the board with each gap open to the gutter of `baseline` only, measured at the spacing of `baseline`.\n */\nexport function sweepRoom(fixture: string, graph: Graph, settings: readonly RoomSetting[], baseline: RoomOptions = { gutter: 8, spacing: 4 }): RoomBenchRow[] {\n const area0 = areaOf(graph.nodes);\n const links = roomLinks(graph);\n const row = (board: string, nodes: readonly Node[], ms: number, spacing: number, lanes?: LaneOrder): RoomBenchRow => ({\n fixture,\n board,\n area: area0 > 0 ? areaOf(nodes) / area0 : 1,\n ms,\n ...measureBoard({ nodes, edges: graph.edges }, spacing, lanes),\n });\n const fair = makeRoom(graph.nodes, links, { ...baseline, spacing: 0, method: \"routes\", maxGrowth: Infinity, passes: 1 });\n const rows = [row(\"gutter\", fair.items, 0, baseline.spacing ?? 4)];\n for (const s of settings) {\n const t0 = now();\n const open = makeRoom(graph.nodes, links, { ...s.options, method: \"routes\" });\n rows.push(row(s.name, open.items, now() - t0, s.options.spacing ?? 4, s.lanes));\n }\n return rows;\n}\n\n/** The values of `maxGrowth` of the sweep of ROOM-A. */\nexport const GROWTH_SWEEP: readonly number[] = [0, 0.06, 0.09, 0.12, 0.15, 0.18, 0.21, 0.25, 0.3, 0.35, 0.5, Infinity];\n\n/** This function gives the settings of ROOM-A: the area and the faults for each `maxGrowth`, at gutter 8 and spacing 4. */\nexport function growthSettings(values: readonly number[] = GROWTH_SWEEP): RoomSetting[] {\n return values.map((m) => ({ name: `maxGrowth ${m}`, options: { gutter: 8, spacing: 4, maxGrowth: m } }));\n}\n\n/**\n * This function gives the settings of ROOM-C: each lane order of the far view at each spacing, at gutter 8.\n * The order `shared` is the far view without lanes, as before ROOM-C.\n */\nexport function laneSettings(spacings: readonly number[] = [2, 4, 6, 8], orders: readonly LaneOrder[] = LANE_ORDERS): RoomSetting[] {\n return spacings.flatMap((spacing) => [\n { name: `shared spacing ${spacing}`, options: { gutter: 8, spacing } },\n ...orders.map((lanes) => ({ name: `${lanes} spacing ${spacing}`, options: { gutter: 8, spacing }, lanes })),\n ]);\n}\n\n/** This function gives the settings of ROOM-D: each gutter with each number of passes, at spacing 4. */\nexport function passSettings(gutters: readonly number[] = [4, 8, 12, 16], passes: readonly number[] = [1, 2]): RoomSetting[] {\n return gutters.flatMap((gutter) => passes.map((p) => ({ name: `gutter ${gutter} passes ${p}`, options: { gutter, spacing: 4, passes: p } })));\n}\n\n/** This function writes the rows of `benchRoom` as a Markdown table. */\nexport function formatRoom(rows: readonly RoomBenchRow[]): string {\n const head = \"| fixture | board | area | links | through | outside | out and back | worst detour | crossings | ink | detour | lane through | ms |\";\n const line = \"|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map((r) => {\n const f = r.faults;\n return `| ${r.fixture} | ${r.board} | ${r.area.toFixed(3)} | ${f.links} | ${f.through} | ${f.outside} | ${f.backtrack} | ${f.worstDetour.toFixed(2)} | ${r.crossings} | ${Math.round(r.ink)} | ${r.detour.toFixed(3)} | ${r.laneThrough} | ${r.ms.toFixed(1)} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n\n/** One row of the benchmark of the room of the zoom levels: one level with groups of one board. */\nexport interface LevelRoomRow {\n readonly fixture: string;\n /** The board: `packed`, `gutter` (each level open to the gutter only), `routes` (the room of the nodes alone), `levels` or `levels each`. */\n readonly board: string;\n readonly depth: number;\n /** The number of items of the level. */\n readonly items: number;\n /** The number of links of the level. */\n readonly links: number;\n /** The area of the bounding box of the items of the level, as a share of the area of the packed board. */\n readonly area: number;\n /** The number of level links that go through a box that is not one of their ends. */\n readonly through: number;\n /** The crossings of the level links, with a lane for each link in each gap (`gapLanes` with the order `crossings`). */\n readonly crossings: number;\n /** The crossings of the level links without lanes. The links of a gap share one line, so this count hides crossings. */\n readonly sharedCrossings: number;\n /** The mean detour of the level links. */\n readonly detour: number;\n /** The worst detour of the level links. */\n readonly worstDetour: number;\n /** The number of pairs of items of the level whose order or alignment on an axis is not the order of the packed board. */\n readonly order: number;\n /** The number of pairs of items of the level before whose order or alignment on an axis changes at this level. */\n readonly levelOrder: number;\n /**\n * The mean shift of an item against its parent from the level before, in gutters. The shift compares the place of the item in its parent\n * at this level with its place in its parent at the level before. The value 0 means that the item moves with its parent.\n */\n readonly shift: number;\n /** The largest shift of an item against its parent, in gutters. */\n readonly worstShift: number;\n /** The time to open the board of all levels, in milliseconds. It is 0 for the packed board. */\n readonly ms: number;\n}\n\n/** One board of the benchmark of the room of the zoom levels. It has a name and the nodes at each depth, from 0 to the level with each node alone. */\ninterface LevelBoards {\n readonly name: string;\n readonly nodes: readonly (readonly Node[])[];\n readonly ms: number;\n}\n\n/** This function gives the sign of `d`, with 0 for a value nearer to 0 than `snap`. */\nconst sign = (d: number, snap: number): number => (Math.abs(d) <= snap ? 0 : Math.sign(d));\n\n/**\n * This function counts the pairs of boxes whose order or alignment on an axis is not the same in `a` and in `b`.\n * The order of two boxes is the order of their left (or top) edges. The cost is quadratic in the number of boxes.\n */\nexport function orderChanges(a: readonly Box[], b: readonly Box[], snap: number = 0.5): number {\n let n = 0;\n for (const axis of [\"x\", \"y\"] as const)\n for (let i = 0; i < a.length; i++)\n for (let j = i + 1; j < a.length; j++) if (sign(a[i]![axis] - a[j]![axis], snap) !== sign(b[i]![axis] - b[j]![axis], snap)) n++;\n return n;\n}\n\nconst middle = (b: Box): { x: number; y: number } => ({ x: b.x + b.w / 2, y: b.y + b.h / 2 });\n\n/**\n * This function measures the room of the zoom levels of a board. The rows of each board give each level with groups, from depth 1.\n * The boards are the packed board, the fair baseline with each level open to the gutter only, and the room of the nodes alone (`makeRoom`).\n * Then come two boards of `levelRoom` with the options. The board `levels` uses the board of the nearest level for each level.\n * The board `levels each` has a board for each level.\n *\n * The links of each level are `levelLinks` with their defaults. Each link gets a lane of `spacing` in each gap.\n */\nexport function benchLevelRoom(fixture: string, graph: Graph, options: LevelRoomOptions = {}, sections: SectionOptions = {}): LevelRoomRow[] {\n const gutter = options.gutter ?? 8;\n const spacing = options.spacing ?? 4;\n const snap = options.snap ?? 0.5;\n const root = buildSections(graph.nodes, sections);\n const deepest = treeDepth(root);\n const links = roomLinks(graph);\n const all = (nodes: readonly Node[]): (readonly Node[])[] => Array.from({ length: deepest + 2 }, () => nodes);\n const timed = (name: string, make: () => (readonly Node[])[]): LevelBoards => {\n const t0 = now();\n const nodes = make();\n return { name, nodes, ms: now() - t0 };\n };\n const boards: LevelBoards[] = [\n { name: \"packed\", nodes: all(graph.nodes), ms: 0 },\n timed(\"gutter\", () => levelRoom(graph.nodes, links, root, { ...options, spacing: 0, maxGrowth: Infinity, passes: 1, board: \"each\" }).levels.map((l) => l.nodes)),\n timed(\"routes\", () => all(makeRoom(graph.nodes, links, { ...options, method: \"routes\" }).items)),\n timed(\"levels\", () => levelRoom(graph.nodes, links, root, { ...options, board: \"shared\" }).levels.map((l) => l.nodes)),\n timed(\"levels each\", () => levelRoom(graph.nodes, links, root, { ...options, board: \"each\" }).levels.map((l) => l.nodes)),\n ];\n const indexOf = new Map(graph.nodes.map((n, i) => [n.id, i]));\n const area0 = areaOf(graph.nodes);\n const rows: LevelRoomRow[] = [];\n for (const board of boards) {\n for (let d = 1; d <= deepest; d++) {\n const here = board.nodes[d]!;\n const before = board.nodes[d - 1]!;\n const cut = levelCut(here, root, d);\n const pairs = levelPairs(cut.items, cut.owner, indexOf, links);\n const boxes = new Map(cut.items.map((i) => [i.id, i.box]));\n const shared = levelLinks(cut.items, pairs);\n const drawn = gapLanes(cut.items, shared, { spacing, order: \"crossings\", snap });\n const asGraph: Graph = { nodes: cut.items, edges: pairs.map((p, i) => ({ id: `l${i}`, source: { node: p.source }, target: { node: p.target } })) };\n const asRoutes = (list: readonly LevelLink[]): Result => ({ routes: list.map((l, i) => ({ edge: `l${i}`, points: l.points })) });\n const q = measureQuality(asGraph, asRoutes(drawn));\n const faults = measureLinks(boxes, drawn);\n // The level before: its items at its own places, and the same items at the places of this level.\n const parentsThen = levelCut(before, root, d - 1);\n const parentsNow = levelCut(here, root, d - 1);\n const childrenThen = levelCut(before, root, d);\n let shift = 0;\n let worstShift = 0;\n cut.items.forEach((c, k) => {\n const parent = parentsThen.owner[indexOf.get(c.nodes[0]!)!]!;\n const at = middle(c.box);\n const was = middle(childrenThen.items[k]!.box);\n const parentAt = middle(parentsNow.items[parent]!.box);\n const parentWas = middle(parentsThen.items[parent]!.box);\n const s = Math.hypot(at.x - parentAt.x - (was.x - parentWas.x), at.y - parentAt.y - (was.y - parentWas.y)) / gutter;\n shift += s;\n worstShift = Math.max(worstShift, s);\n });\n rows.push({\n fixture,\n board: board.name,\n depth: d,\n items: cut.items.length,\n links: pairs.length,\n area: area0 > 0 ? areaOf(cut.items) / area0 : 1,\n through: faults.through,\n crossings: q.crossings,\n sharedCrossings: measureQuality(asGraph, asRoutes(shared)).crossings,\n detour: q.detour,\n worstDetour: faults.worstDetour,\n order: orderChanges(\n levelCut(graph.nodes, root, d).items.map((i) => i.box),\n cut.items.map((i) => i.box),\n snap,\n ),\n levelOrder: orderChanges(\n parentsThen.items.map((i) => i.box),\n parentsNow.items.map((i) => i.box),\n snap,\n ),\n shift: cut.items.length ? shift / cut.items.length : 0,\n worstShift,\n ms: board.ms,\n });\n }\n }\n return rows;\n}\n\n/** This function writes the rows of `benchLevelRoom` as a Markdown table. */\nexport function formatLevelRoom(rows: readonly LevelRoomRow[]): string {\n const head = \"| fixture | board | depth | items | links | area | through | crossings | shared crossings | detour | worst detour | order | level order | shift | worst shift | ms |\";\n const line = \"|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map(\n (r) =>\n `| ${r.fixture} | ${r.board} | ${r.depth} | ${r.items} | ${r.links} | ${r.area.toFixed(3)} | ${r.through} | ${r.crossings} | ${r.sharedCrossings} | ${r.detour.toFixed(3)} | ${r.worstDetour.toFixed(2)} | ${r.order} | ${r.levelOrder} | ${r.shift.toFixed(2)} | ${r.worstShift.toFixed(2)} | ${r.ms.toFixed(1)} |`,\n );\n return [head, line, ...body].join(\"\\n\");\n}\n\n/** One row of `benchBendRoom`: the lanes of the bundles of one router on one open board, after `highwayCurves`. */\nexport interface BendRoomRow extends HighwayMeasures {\n readonly router: string;\n readonly fixture: string;\n /** The board: `room` opens the gaps for the links only, and `room + bends` also opens them for the bends of the bundles. */\n readonly board: \"room\" | \"room + bends\";\n /** The area of the bounding box of the boxes, as a share of the area of the board before the room. */\n readonly area: number;\n}\n\n/**\n * This function measures the room for the bends of the bundles (HWC-D). It opens the board two times with `makeRoom`, without and with the option `bends`.\n * The option `bends` gets the router and the lane options of the curves. Then the router routes each open board, and `benchHighways` curves its bundles with `highway`.\n */\nexport function benchBendRoom(router: Router, fixture: string, graph: Graph, options: RoomOptions = { gutter: 8, spacing: 4 }): BendRoomRow[] {\n const lanes = { spacing: 4, maxWidth: 16, minRadius: 4 };\n const links = roomLinks(graph);\n const area0 = areaOf(graph.nodes);\n const boards = [\n [\"room\", makeRoom(graph.nodes, links, options).items],\n [\"room + bends\", makeRoom(graph.nodes, links, { ...options, bends: { router, edges: graph.edges, ...lanes } }).items],\n ] as const;\n return boards.map(([board, nodes]) => {\n const [, highway] = benchHighways(router, fixture, { nodes, edges: graph.edges }, { spacing: lanes.spacing, maxWidth: lanes.maxWidth, minRadius: lanes.minRadius });\n const { router: name, fixture: _f, curve: _c, ms: _ms, ...measures } = highway!;\n return { router: name, fixture, board, area: area0 > 0 ? areaOf(nodes) / area0 : 1, ...measures };\n });\n}\n\n/** This function writes the rows of `benchBendRoom` as a Markdown table. The spacing error is a percent of the spacing. */\nexport function formatBendRoom(rows: readonly BendRoomRow[]): string {\n const head = \"| router | fixture | board | area | bundles | worst spacing | min radius | under min | through |\";\n const line = \"|---|---|---|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map(\n (r) =>\n `| ${r.router} | ${r.fixture} | ${r.board} | ${r.area.toFixed(3)} | ${r.bundles} | ${(r.worstSpacing * 100).toFixed(1)}% | ${r.minRadius === Infinity ? \"-\" : r.minRadius.toFixed(2)} | ${r.underMin} | ${r.through} |`,\n );\n return [head, line, ...body].join(\"\\n\");\n}\n","import type { Graph, Result } from \"../model.ts\";\nimport { sectionsRouter, type SectionsOptions } from \"../routers/sections.ts\";\nimport { groupStrategies } from \"../strategies/builtins.ts\";\nimport type { Strategy } from \"../strategies/model.ts\";\nimport { sameData } from \"./run.ts\";\nimport { measureLevelFaults, measureRouteFaults, sumFaults, type LinkFaults } from \"./links.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/** The options of one setting of the router `sections`, without the name. */\nexport type SectionsSettingOptions = Omit<SectionsOptions, \"name\" | \"maxNodes\">;\n\n/** One setting of a sweep of the router `sections`. */\nexport interface SectionsSetting {\n /** The name of the setting in the column `setting`. */\n readonly name: string;\n readonly options: SectionsSettingOptions;\n}\n\n/** One row of a sweep of the router `sections`: one setting on one board, and the measures of its routes and of its zoom levels. */\nexport interface SectionsBenchRow {\n readonly fixture: string;\n readonly setting: string;\n /** The faults of the routes of the edges (`measureRouteFaults`). */\n readonly faults: LinkFaults;\n /** The sum of the faults of the levels with groups (`measureLevelFaults` and `sumFaults`). */\n readonly levelFaults: LinkFaults;\n /** The sum of the overlaps of the levels with groups. */\n readonly overlaps: number;\n /** The number of routes that go through hubs: the routes that are not the same as the direct route of their edge. */\n readonly hubRoutes: number;\n /** The number of shared stretches of way of the result (`runs`). */\n readonly runs: number;\n /** The number of zoom levels, with the last level of single nodes. */\n readonly levels: number;\n /** The number of items of the far view: the first level with more than one item. */\n readonly farItems: number;\n /** The time of one route, in milliseconds. */\n readonly ms: number;\n}\n\n/** This function gives the number of items of the first level with more than one item, or 0 for a result without levels. */\nfunction farItems(result: Result): number {\n return result.levels?.find((l) => l.items.length > 1)?.items.length ?? 0;\n}\n\n/**\n * This function measures the router `sections` on one board with each setting. The first row is the fair baseline: the defaults, with no option.\n * The direct routes come from the hub limit 0, so `hubRoutes` counts the routes that use the hubs.\n */\nexport function sweepSections(fixture: string, graph: Graph, settings: readonly SectionsSetting[]): SectionsBenchRow[] {\n const all: SectionsSetting[] = [{ name: \"defaults\", options: {} }, ...settings];\n return all.map((s) => {\n const direct = sectionsRouter({ ...s.options, name: \"direct\", stretch: 0, stretchPad: 0 }).route(graph);\n const t0 = now();\n const result = sectionsRouter({ ...s.options, name: s.name }).route(graph);\n const ms = now() - t0;\n const levelFaults = measureLevelFaults(result);\n return {\n fixture,\n setting: s.name,\n faults: measureRouteFaults(graph, result),\n levelFaults: sumFaults(levelFaults),\n overlaps: levelFaults.reduce((n, f) => n + f.overlaps, 0),\n hubRoutes: result.routes.filter((r, i) => !sameData(r.points, direct.routes[i]?.points)).length,\n runs: result.runs?.length ?? 0,\n levels: result.levels?.length ?? 0,\n farItems: farItems(result),\n ms,\n };\n });\n}\n\n/** The values of the hub limit (`stretch`) of the sweep of CUSTOM. The default is 2. */\nexport const STRETCH_SWEEP: readonly number[] = [1.25, 1.5, 2, 3, Infinity];\n\n/** This function gives the settings of the sweep of the hub limit: one setting for each value of `stretch`. */\nexport function stretchSettings(values: readonly number[] = STRETCH_SWEEP): SectionsSetting[] {\n return values.map((stretch) => ({ name: `stretch ${stretch}`, options: { stretch } }));\n}\n\n/** The values of `hubSlack` of the sweep of CUSTOM. The default is 80. */\nexport const SLACK_SWEEP: readonly number[] = [0, 40, 80, 160, Infinity];\n\n/** This function gives the settings of the sweep of the slack of the hubs: one setting for each value of `hubSlack`. */\nexport function slackSettings(values: readonly number[] = SLACK_SWEEP): SectionsSetting[] {\n return values.map((hubSlack) => ({ name: `hubSlack ${hubSlack}`, options: { hubSlack } }));\n}\n\n/** The values of the section limit (`cap`) of the sweep of CUSTOM. The default is 8. */\nexport const CAP_SWEEP: readonly number[] = [4, 6, 8, 12, 16];\n\n/** This function gives the settings of the sweep of the section limit: one setting for each value of `cap`. */\nexport function capSettings(values: readonly number[] = CAP_SWEEP): SectionsSetting[] {\n return values.map((cap) => ({ name: `cap ${cap}`, options: { cap } }));\n}\n\n/**\n * This function gives one setting for each grouping rule: the router `sections` with the strategy as its option `group`.\n * The map `options` gives the options of a strategy by its name.\n */\nexport function groupSettings(\n strategies: readonly Strategy<\"group\">[] = Object.values(groupStrategies),\n options: Readonly<Record<string, object>> = {},\n): SectionsSetting[] {\n return strategies.map((group) => ({ name: `group ${group.name}`, options: { group, ...(options[group.name] ? { groupOptions: options[group.name] } : {}) } }));\n}\n\n/** This function writes the rows of `sweepSections` as a Markdown table. */\nexport function formatSections(rows: readonly SectionsBenchRow[]): string {\n const head =\n \"| fixture | setting | through | out and back | worst detour | outside | hub routes | runs | levels | far items | level through | level out and back | level outside | level overlaps | ms |\";\n const line = \"|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\";\n const body = rows.map((r) => {\n const f = r.faults;\n const l = r.levelFaults;\n return `| ${r.fixture} | ${r.setting} | ${f.through} | ${f.backtrack} | ${f.worstDetour.toFixed(2)} | ${f.outside} | ${r.hubRoutes} | ${r.runs} | ${r.levels} | ${r.farItems} | ${l.through} | ${l.backtrack} | ${l.outside} | ${r.overlaps} | ${r.ms.toFixed(1)} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n","import { rng } from \"../../fixtures.ts\";\n\n/**\n * This function gives the `p` quantile of the values, with a linear step between two ranks (type 7 of Hyndman and Fan).\n * The result is `NaN` for an empty list.\n */\nexport function quantile(values: readonly number[], p: number): number {\n if (values.length === 0) return Number.NaN;\n const s = [...values].sort((a, b) => a - b);\n const at = Math.max(0, Math.min(1, p)) * (s.length - 1);\n const lo = Math.floor(at);\n const hi = Math.min(s.length - 1, lo + 1);\n return s[lo]! + (s[hi]! - s[lo]!) * (at - lo);\n}\n\n/** The spread of a measure over the seeds of a fixture family. */\nexport interface Spread {\n /** The number of values. */\n readonly n: number;\n readonly median: number;\n /** The `0.25` quantile. */\n readonly q1: number;\n /** The `0.75` quantile. */\n readonly q3: number;\n /** The interquartile range: `q3 - q1`. */\n readonly iqr: number;\n readonly min: number;\n readonly max: number;\n}\n\n/** This function gives the median, the quartiles, the interquartile range, the smallest and the largest value of a list. */\nexport function summarize(values: readonly number[]): Spread {\n const v = values.filter((x) => !Number.isNaN(x));\n const q1 = quantile(v, 0.25);\n const q3 = quantile(v, 0.75);\n return {\n n: v.length,\n median: quantile(v, 0.5),\n q1,\n q3,\n iqr: q3 - q1,\n min: v.length ? v.reduce((m, x) => Math.min(m, x), Infinity) : Number.NaN,\n max: v.length ? v.reduce((m, x) => Math.max(m, x), -Infinity) : Number.NaN,\n };\n}\n\n/** The largest number of values for which `kendallTau` examines each pair. Above it, the function examines a seeded sample of pairs. */\nexport const KENDALL_EXACT = 1500;\nconst KENDALL_SAMPLE = 200_000;\n\n/**\n * This function gives the Kendall tau-b of two lists of the same length (Kendall, 1938).\n * The value is from -1 to 1. A value of 1 means the same order. A pair with a tie in both lists does not count.\n * When one list has only ties, the value is 1. Above `KENDALL_EXACT` values, a seeded sample of 200 000 pairs gives an estimate.\n */\nexport function kendallTau(a: readonly number[], b: readonly number[], seed = 1): number {\n const n = Math.min(a.length, b.length);\n if (n < 2) return 1;\n let concordant = 0;\n let discordant = 0;\n let tieA = 0;\n let tieB = 0;\n const visit = (i: number, j: number): void => {\n const da = Math.sign(a[i]! - a[j]!);\n const db = Math.sign(b[i]! - b[j]!);\n if (da === 0 && db === 0) return;\n if (da === 0) tieA++;\n else if (db === 0) tieB++;\n else if (da === db) concordant++;\n else discordant++;\n };\n if (n <= KENDALL_EXACT) {\n for (let i = 0; i < n; i++) for (let j = i + 1; j < n; j++) visit(i, j);\n } else {\n const R = rng(seed);\n for (let k = 0; k < KENDALL_SAMPLE; k++) {\n const i = Math.floor(R() * n);\n const j = Math.floor(R() * n);\n if (i !== j) visit(i, j);\n }\n }\n const den = Math.sqrt((concordant + discordant + tieA) * (concordant + discordant + tieB));\n return den === 0 ? 1 : (concordant - discordant) / den;\n}\n\nconst pairs = (k: number): number => (k * (k - 1)) / 2;\n\n/**\n * This function gives the adjusted Rand index of two groupings of the same items (Hubert and Arabie, 1985).\n * The item `i` is in the group `a[i]` of the first grouping and in the group `b[i]` of the second grouping.\n * The value is 1 for the same grouping, and near 0 for a random grouping. Two groupings with one group each give 1.\n */\nexport function adjustedRandIndex(a: readonly (string | number)[], b: readonly (string | number)[]): number {\n const n = Math.min(a.length, b.length);\n if (n < 2) return 1;\n const cells = new Map<string, number>();\n const rows = new Map<string | number, number>();\n const cols = new Map<string | number, number>();\n for (let i = 0; i < n; i++) {\n const key = `${String(a[i])}\\u0000${String(b[i])}`;\n cells.set(key, (cells.get(key) ?? 0) + 1);\n rows.set(a[i]!, (rows.get(a[i]!) ?? 0) + 1);\n cols.set(b[i]!, (cols.get(b[i]!) ?? 0) + 1);\n }\n let index = 0;\n for (const c of cells.values()) index += pairs(c);\n let sa = 0;\n let sb = 0;\n for (const c of rows.values()) sa += pairs(c);\n for (const c of cols.values()) sb += pairs(c);\n const expected = (sa * sb) / pairs(n);\n const top = (sa + sb) / 2;\n return top === expected ? 1 : (index - expected) / (top - expected);\n}\n","import { dist, polylineLength, turns, type Point } from \"../../geom.ts\";\nimport { rng } from \"../../fixtures.ts\";\nimport { Grid } from \"../../grid.ts\";\nimport { nodeIndex, type Graph, type Route } from \"../../model.ts\";\nimport { nearestSide } from \"../../plugs.ts\";\nimport { TOLERANCE } from \"../properties.ts\";\nimport { quantile } from \"./stats.ts\";\n\n/** A drawn segment: a pair of points. */\nexport type DrawnSegment = readonly [Point, Point];\n\nconst key = (p: Point): string => `${Math.round(p.x * 8)},${Math.round(p.y * 8)}`;\n\n/**\n * This function gives the drawn segments of the routes: one segment for each distinct pair of ends.\n * A segment that several routes share is one drawn segment, as in `measureQuality`.\n */\nexport function drawnSegments(routes: readonly Route[]): DrawnSegment[] {\n const segs: DrawnSegment[] = [];\n const seen = new Set<string>();\n for (const r of 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 }\n return segs;\n}\n\n/** This function gives the key of the drawn segment between two points. Two routes share a segment when they give the same key. */\nexport function segmentKey(a: Point, b: Point): string | undefined {\n const ka = key(a);\n const kb = key(b);\n if (ka === kb) return undefined;\n return ka < kb ? `${ka}|${kb}` : `${kb}|${ka}`;\n}\n\n/**\n * This function gives the unit of length of a board: the median of the short sides of the boxes of the nodes.\n * A length divided by the unit has no unit, so boards of different sizes compare. The unit of a board without nodes is 1.\n */\nexport function boardUnit(graph: Graph): number {\n if (graph.nodes.length === 0) return 1;\n const u = quantile(\n graph.nodes.map((n) => Math.min(n.box.w, n.box.h)),\n 0.5,\n );\n return u > 0 ? u : 1;\n}\n\n/** The crossings of a set of drawn segments and their angles (R1 and R2 of MEAS0). */\nexport interface CrossingAngles {\n /** The number of crossings (R1). It is the same value as `crossings` of `measureQuality`. */\n readonly crossings: number;\n /** This value is true when the values come from a sample of the segments. */\n readonly estimated: boolean;\n /** The mean angle of a crossing, divided by 90 degrees (R2). The scale is 0 to 1, and higher is better. A set without crossings gives 1. */\n readonly mean: number;\n /** The smallest angle of a crossing, in degrees from 0 to 90 (R2). Higher is better. A set without crossings gives 90. */\n readonly min: number;\n}\n\nconst EXACT_CROSSINGS = 20_000;\nconst SAMPLE = 2_000;\n\n/** This function gives the angle between two segments, in degrees from 0 to 90. */\nexport function crossingAngle(a: Point, b: Point, c: Point, d: Point): number {\n const ux = b.x - a.x;\n const uy = b.y - a.y;\n const vx = d.x - c.x;\n const vy = d.y - c.y;\n const l = Math.hypot(ux, uy) * Math.hypot(vx, vy);\n if (l === 0) return 0;\n return (Math.acos(Math.min(1, Math.abs(ux * vx + uy * vy) / l)) * 180) / Math.PI;\n}\n\n/**\n * This function measures the crossings of a set of segments and their angles (R1 and R2 of MEAS0).\n * It uses the grid and the sample of `countCrossings`. Above 20 000 segments, a seeded sample of 2 000 segments gives an estimate.\n * The cost is `n log n`.\n */\nexport function crossingAngles(segs: readonly DrawnSegment[]): CrossingAngles {\n if (segs.length < 2) return { crossings: 0, estimated: false, mean: 1, min: 90 };\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 let sum = 0;\n let min = 90;\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 (!segmentsCrossInside(a, b, c, d)) return;\n count++;\n const t = crossingAngle(a, b, c, d);\n sum += t;\n min = Math.min(min, t);\n });\n }\n const crossings = exact ? count : Math.round((count * segs.length) / (2 * pick.length));\n return { crossings, estimated: !exact, mean: count ? sum / count / 90 : 1, min: count ? min : 90 };\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/** This test is the test of `segmentsCross`, so the count of `crossingAngles` is the count of `countCrossings`. */\nfunction segmentsCrossInside(a: Point, b: Point, c: Point, d: Point): boolean {\n return orient(c, d, a) * orient(c, d, b) < 0 && orient(a, b, c) * orient(a, b, d) < 0;\n}\n\n/** The total turn of the routes (R4 of MEAS0). */\nexport interface TotalTurn {\n /** The mean over the routes of `T(r) = Σ abs(φ_i) / π`, in half turns. Lower is better. */\n readonly mean: number;\n /** The largest turn at one vertex of a route, in degrees from 0 to 180. Lower is better. */\n readonly max: number;\n}\n\n/** This function measures the total turn of the routes (R4 of MEAS0). A path that goes straight on has 0. The cost is linear. */\nexport function totalTurn(routes: readonly Route[]): TotalTurn {\n let sum = 0;\n let max = 0;\n for (const r of routes) {\n let t = 0;\n for (const phi of turns(r.points)) {\n t += Math.abs(phi);\n max = Math.max(max, Math.abs(phi));\n }\n sum += t / Math.PI;\n }\n return { mean: routes.length ? sum / routes.length : 0, max: (max * 180) / Math.PI };\n}\n\n/** The spread of the detour of the routes (R5 of MEAS0). */\nexport interface DetourSpread {\n /** The median of `δ(e) = L(r_e) / span(e)`. */\n readonly median: number;\n /** The `0.95` quantile of `δ(e)`: the tail of bad routes. */\n readonly q95: number;\n readonly mean: number;\n}\n\n/**\n * This function measures the spread of the detour `δ(e) = L(r_e) / span(e)` of the routes (R5 of MEAS0).\n * A route with ends nearer than 1 unit does not count. Each value is 1 or more, and lower is better. The cost is linear.\n */\nexport function detourSpread(routes: readonly Route[]): DetourSpread {\n const d: number[] = [];\n for (const r of routes) {\n const p = r.points;\n if (p.length < 2) continue;\n const span = dist(p[0]!, p[p.length - 1]!);\n if (span > 1) d.push(polylineLength(p) / span);\n }\n if (d.length === 0) return { median: 1, q95: 1, mean: 1 };\n return { median: quantile(d, 0.5), q95: quantile(d, 0.95), mean: d.reduce((s, x) => s + x, 0) / d.length };\n}\n\n/** The spacing of the plugs on the sides of the boxes (R11 of MEAS0). */\nexport interface PlugSpacing {\n /** The smallest spacing of a side. The scale is 0 to 1, and higher is better. A value of 1 is even spacing. */\n readonly min: number;\n /** The `0.05` quantile of the spacing of the sides. */\n readonly q05: number;\n /** The number of sides with two plugs or more. */\n readonly sides: number;\n}\n\n/**\n * This function measures the spacing of the plugs on each side of each box (R11 of MEAS0), the angular resolution of a box.\n * For a side with `k` distinct plugs, `ps = min gap / (side / (k + 1))`, with a limit of 1.\n * Two ends nearer than `TOLERANCE` are one plug, because a bundle shares its plug. An end farther than 1 unit from the side does not count.\n * Without a side with two plugs, each value is 1. The cost is `n log n`.\n */\nexport function plugSpacing(graph: Graph, routes: readonly Route[]): PlugSpacing {\n const byId = nodeIndex(graph);\n const edges = new Map(graph.edges.map((e) => [e.id, e]));\n const at = new Map<string, number[]>();\n const add = (nodeId: string, p: Point): void => {\n const n = byId.get(nodeId);\n if (!n) return;\n const b = n.box;\n const side = nearestSide(b, p);\n const off = side === \"north\" ? Math.abs(p.y - b.y) : side === \"south\" ? Math.abs(p.y - b.y - b.h) : side === \"west\" ? Math.abs(p.x - b.x) : Math.abs(p.x - b.x - b.w);\n if (off > 1) return;\n const pos = side === \"north\" || side === \"south\" ? p.x - b.x : p.y - b.y;\n const k = `${nodeId}\\u0000${side}`;\n const list = at.get(k);\n if (list) list.push(pos);\n else at.set(k, [pos]);\n };\n for (const r of routes) {\n const e = edges.get(r.edge);\n const p = r.points;\n if (!e || p.length < 2) continue;\n add(e.source.node, p[0]!);\n add(e.target.node, p[p.length - 1]!);\n }\n const values: number[] = [];\n for (const [k, list] of at) {\n const node = byId.get(k.slice(0, k.indexOf(\"\\u0000\")))!;\n const side = k.slice(k.indexOf(\"\\u0000\") + 1);\n const length = side === \"north\" || side === \"south\" ? node.box.w : node.box.h;\n list.sort((a, b) => a - b);\n const plugs: number[] = [];\n for (const x of list) if (plugs.length === 0 || x - plugs[plugs.length - 1]! > TOLERANCE) plugs.push(x);\n if (plugs.length < 2 || length <= 0) continue;\n let gap = Infinity;\n for (let i = 1; i < plugs.length; i++) gap = Math.min(gap, plugs[i]! - plugs[i - 1]!);\n values.push(Math.min(1, gap / (length / (plugs.length + 1))));\n }\n if (values.length === 0) return { min: 1, q05: 1, sides: 0 };\n return { min: values.reduce((m, x) => Math.min(m, x), 1), q05: quantile(values, 0.05), sides: values.length };\n}\n","import { dist, polylineLength } from \"../../geom.ts\";\nimport { rng } from \"../../fixtures.ts\";\nimport type { Graph, Route } from \"../../model.ts\";\nimport { drawnSegments, segmentKey } from \"./routes.ts\";\n\n/**\n * This function gives the share of the ink that shared segments save (B1 of MEAS0): `inkSaved = 1 - ink(S) / Σ_e L(r_e)`.\n * `ink(S)` counts a shared segment one time, as `measureQuality` does. The scale is 0 to 1, and higher is better. The cost is `n log n`.\n */\nexport function inkSaved(routes: readonly Route[]): number {\n let total = 0;\n for (const r of routes) total += polylineLength(r.points);\n if (total <= 0) return 0;\n let ink = 0;\n for (const [a, b] of drawnSegments(routes)) ink += dist(a, b);\n return Math.max(0, 1 - ink / total);\n}\n\n/** The ambiguity of a result (B4 of MEAS0). */\nexport interface Ambiguity {\n /** The share of false neighbours, from 0 to 1. Lower is better. */\n readonly value: number;\n /** This value is true when the value comes from a sample of the nodes. */\n readonly estimated: boolean;\n}\n\n/** The options of `ambiguity`. */\nexport interface AmbiguityOptions {\n /** Up to this number of nodes, the function examines each node. The default is 1000. */\n readonly exact?: number;\n /** Above `exact` nodes, the function examines this number of nodes from a seeded sample. The default is 2000. */\n readonly sample?: number;\n /** The seed of the sample. The default is 1. */\n readonly seed?: number;\n}\n\n/**\n * This function measures the ambiguity of the routes (B4 of MEAS0), with one step of neighbours.\n * `N(v)` holds the nodes whose routes share a drawn segment with a route of `v`.\n * `amb = Σ_v count(w in N(v) : no edge v-w) / Σ_v count(N(v))`. The cost is quadratic, so a seeded sample serves above `exact` nodes.\n */\nexport function ambiguity(graph: Graph, routes: readonly Route[], options: AmbiguityOptions = {}): Ambiguity {\n const n = graph.nodes.length;\n const index = new Map(graph.nodes.map((v, i) => [v.id, i] as const));\n const ends = new Map<string, readonly [number, number]>();\n for (const e of graph.edges) {\n const s = index.get(e.source.node);\n const t = index.get(e.target.node);\n if (s !== undefined && t !== undefined) ends.set(e.id, [s, t]);\n }\n // Each drawn segment gets a number. `keysOf` holds the segments of each edge, and `nodesOf` the distinct end nodes of the edges of each segment.\n const keyIds = new Map<string, number>();\n const nodesOf: number[][] = [];\n const keysOf = new Map<string, number[]>();\n for (const r of routes) {\n const end = ends.get(r.edge);\n if (!end) continue;\n const own: number[] = [];\n for (let i = 1; i < r.points.length; i++) {\n const k = segmentKey(r.points[i - 1]!, r.points[i]!);\n if (k === undefined) continue;\n let id = keyIds.get(k);\n if (id === undefined) {\n id = nodesOf.length;\n keyIds.set(k, id);\n nodesOf.push([]);\n }\n if (own.includes(id)) continue;\n own.push(id);\n nodesOf[id]!.push(end[0], end[1]);\n }\n keysOf.set(r.edge, own);\n }\n const mark = new Int32Array(n).fill(-1);\n nodesOf.forEach((list, k) => {\n let j = 0;\n for (const v of list)\n if (mark[v] !== k) {\n mark[v] = k;\n list[j++] = v;\n }\n list.length = j;\n });\n const incident: string[][] = Array.from({ length: n }, () => []);\n const adjacent: number[][] = Array.from({ length: n }, () => []);\n for (const e of graph.edges) {\n const end = ends.get(e.id);\n if (!end) continue;\n incident[end[0]]!.push(e.id);\n incident[end[1]]!.push(e.id);\n adjacent[end[0]]!.push(end[1]);\n adjacent[end[1]]!.push(end[0]);\n }\n const exact = n <= (options.exact ?? 1000);\n const R = rng(options.seed ?? 1);\n const pick = exact ? Array.from({ length: n }, (_, i) => i) : Array.from({ length: options.sample ?? 2000 }, () => Math.floor(R() * n));\n // The stamps mark the segments, the near nodes and the neighbours of the current node, with no new set for each node.\n const keyStamp = new Int32Array(nodesOf.length).fill(-1);\n const nearStamp = new Int32Array(n).fill(-1);\n const linkStamp = new Int32Array(n).fill(-1);\n let all = 0;\n let wrong = 0;\n pick.forEach((v, step) => {\n for (const w of adjacent[v]!) linkStamp[w] = step;\n nearStamp[v] = step;\n for (const e of incident[v]!)\n for (const k of keysOf.get(e) ?? []) {\n if (keyStamp[k] === step) continue;\n keyStamp[k] = step;\n for (const w of nodesOf[k]!) {\n if (nearStamp[w] === step) continue;\n nearStamp[w] = step;\n all++;\n if (linkStamp[w] !== step) wrong++;\n }\n }\n });\n return { value: all ? wrong / all : 0, estimated: !exact };\n}\n","import { center, dist } from \"../../geom.ts\";\nimport type { Graph, Level } from \"../../model.ts\";\nimport { kendallTau } from \"./stats.ts\";\n\n/** This function gives the levels in the order of their depth, from the far view to the near view. */\nfunction byDepth(levels: readonly Level[]): Level[] {\n return [...levels].sort((a, b) => a.depth - b.depth);\n}\n\n/** This function gives a map from the id of each node to the index of its item in the level. */\nfunction itemIndex(level: Level): Map<string, number> {\n const m = new Map<string, number>();\n level.items.forEach((item, i) => {\n for (const n of item.nodes) m.set(n, i);\n });\n return m;\n}\n\n/**\n * This function counts the faults of the nesting of the levels (Z6 of MEAS0, the proposed rule `level-nesting`).\n * It counts the items of each level whose nodes are in more than one item of the level before it. Lower is better, and 0 is correct.\n * The cost is linear.\n */\nexport function nestingFaults(levels: readonly Level[]): number {\n const list = byDepth(levels);\n let faults = 0;\n for (let d = 1; d < list.length; d++) {\n const coarse = itemIndex(list[d - 1]!);\n for (const item of list[d]!.items) {\n const parents = new Set<number | undefined>(item.nodes.map((n) => coarse.get(n)));\n if (parents.size > 1) faults++;\n }\n }\n return faults;\n}\n\n/**\n * This function measures the position stability of the levels (Z7 of MEAS0).\n * `ps = mean_(v,d) dist(center(item_d(v)), center(item_(d+1)(v))) / size(item_d(v))`, with `size` the longer side of the box.\n * The value has no unit, and lower is better. A result with one level gives 0. The cost is linear.\n */\nexport function positionStability(levels: readonly Level[]): number {\n const list = byDepth(levels);\n let sum = 0;\n let n = 0;\n for (let d = 0; d + 1 < list.length; d++) {\n const a = list[d]!;\n const fine = itemIndex(list[d + 1]!);\n const items = list[d + 1]!.items;\n for (const item of a.items) {\n const size = Math.max(item.box.w, item.box.h);\n if (size <= 0) continue;\n const c = center(item.box);\n for (const v of item.nodes) {\n const j = fine.get(v);\n if (j === undefined) continue;\n sum += dist(c, center(items[j]!.box)) / size;\n n++;\n }\n }\n }\n return n ? sum / n : 0;\n}\n\n/**\n * This function measures the order stability of the levels with groups (Z8 of MEAS0).\n * For each level, `τ_x` and `τ_y` are the Kendall tau between the item centers and the centroids of their nodes on each axis.\n * The value is the mean of `(τ_x + τ_y) / 2` over the levels with groups and two items or more. The scale is -1 to 1, and higher is better.\n * A result without such a level gives 1. The cost is `n log n`, with a sample above 1500 items.\n */\nexport function orderStability(graph: Graph, levels: readonly Level[]): number {\n const centers = new Map(graph.nodes.map((n) => [n.id, center(n.box)] as const));\n let sum = 0;\n let n = 0;\n for (const level of levels) {\n if (level.items.length < 2 || !level.items.some((i) => i.nodes.length > 1)) continue;\n const ix: number[] = [];\n const iy: number[] = [];\n const nx: number[] = [];\n const ny: number[] = [];\n for (const item of level.items) {\n let x = 0;\n let y = 0;\n let k = 0;\n for (const v of item.nodes) {\n const c = centers.get(v);\n if (!c) continue;\n x += c.x;\n y += c.y;\n k++;\n }\n if (k === 0) continue;\n const c = center(item.box);\n ix.push(c.x);\n iy.push(c.y);\n nx.push(x / k);\n ny.push(y / k);\n }\n sum += (kendallTau(ix, nx, level.depth + 1) + kendallTau(iy, ny, level.depth + 1)) / 2;\n n++;\n }\n return n ? sum / n : 1;\n}\n","import type { Graph, Level } from \"../../model.ts\";\nimport type { Section } from \"../../sections.ts\";\nimport { adjustedRandIndex } from \"./stats.ts\";\n\n/** A grouping of the nodes: a map from the id of each node to the id of its group. */\nexport type Grouping = ReadonlyMap<string, string>;\n\n/** This function gives the grouping of one level: each node goes to the id of its item. */\nexport function levelGrouping(level: Level): Map<string, string> {\n const m = new Map<string, string>();\n for (const item of level.items) for (const n of item.nodes) m.set(n, item.id);\n return m;\n}\n\n/** This function gives the far view of a result: the first level with more than one item, in the order of depth. */\nexport function farLevel(levels: readonly Level[]): Level | undefined {\n return [...levels].sort((a, b) => a.depth - b.depth).find((l) => l.items.length > 1);\n}\n\n/**\n * This function gives the modularity of a grouping (G1 of MEAS0, Newman and Girvan, 2004).\n * `Q = Σ_c (e_c / m - (d_c / (2m))^2)`, with `e_c` the edges inside `c` and `d_c` the sum of the degrees in `c`.\n * The scale is -0.5 to 1, and higher is better. A node without a group is a group alone. The cost is linear.\n */\nexport function modularity(graph: Graph, groups: Grouping): number {\n const m = graph.edges.length;\n if (m === 0) return 0;\n const inside = new Map<string, number>();\n const degree = new Map<string, number>();\n const of = (v: string): string => groups.get(v) ?? `\\u0000${v}`;\n for (const e of graph.edges) {\n const a = of(e.source.node);\n const b = of(e.target.node);\n degree.set(a, (degree.get(a) ?? 0) + 1);\n degree.set(b, (degree.get(b) ?? 0) + 1);\n if (a === b) inside.set(a, (inside.get(a) ?? 0) + 1);\n }\n let q = 0;\n for (const [c, d] of degree) q += (inside.get(c) ?? 0) / m - (d / (2 * m)) ** 2;\n return q;\n}\n\n/**\n * This function gives the cut share of a grouping (G2 of MEAS0): the share of the edges between two groups.\n * For the grouping of a level, it is the sum of the counts of the links of the level, divided by `m`. The scale is 0 to 1, and lower is better.\n */\nexport function cutShare(graph: Graph, groups: Grouping): number {\n const m = graph.edges.length;\n if (m === 0) return 0;\n let cut = 0;\n for (const e of graph.edges) if ((groups.get(e.source.node) ?? e.source.node) !== (groups.get(e.target.node) ?? e.target.node)) cut++;\n return cut / m;\n}\n\n/**\n * This function gives the balance of one level (G6 of MEAS0): `H(s) / log(k)`, with `s` the shares of the nodes of the `k` items and `H` the entropy.\n * The scale is 0 to 1, and higher is better. A value of 1 is items of equal size. A level with one item gives 1.\n */\nexport function balance(level: Level): number {\n const k = level.items.length;\n const total = level.items.reduce((s, item) => s + item.nodes.length, 0);\n if (k < 2 || total === 0) return 1;\n let h = 0;\n for (const item of level.items) {\n const p = item.nodes.length / total;\n if (p > 0) h -= p * Math.log(p);\n }\n return h / Math.log(k);\n}\n\n/**\n * This function gives the tree cost of the levels (G8 of MEAS0, Dasgupta, 2016): `D = Σ_(u,v) leaves(lca(u, v)) / (m n)`.\n * The levels make the tree. `leaves(lca(u, v))` is the number of nodes of the deepest item that holds both ends.\n * Without such an item, the value is `n`. The scale is 0 to 1, and lower is better. The cost is linear times the depth.\n */\nexport function treeCost(graph: Graph, levels: readonly Level[]): number {\n const n = graph.nodes.length;\n const m = graph.edges.length;\n if (n === 0 || m === 0) return 0;\n const list = [...levels].sort((a, b) => b.depth - a.depth);\n const maps = list.map((l) => {\n const size = new Map<string, number>();\n const of = new Map<string, string>();\n for (const item of l.items) {\n size.set(item.id, item.nodes.length);\n for (const v of item.nodes) of.set(v, item.id);\n }\n return { size, of };\n });\n let sum = 0;\n for (const e of graph.edges) {\n let leaves = n;\n for (const { size, of } of maps) {\n const a = of.get(e.source.node);\n if (a !== undefined && a === of.get(e.target.node)) {\n leaves = size.get(a)!;\n break;\n }\n }\n sum += leaves;\n }\n return sum / (m * n);\n}\n\n/** This function gives the leaf of each node in a tree of sections: the id of the leaf, by the index of the node. */\nexport function leafGroups(root: Section, count: number): string[] {\n const out = new Array<string>(count).fill(\"\");\n const walk = (s: Section): void => {\n if (s.children.length === 0) for (const i of s.nodes) out[i] = s.id;\n else for (const c of s.children) walk(c);\n };\n walk(root);\n return out.map((id, i) => id || `#${i}`);\n}\n\n/**\n * This function gives the group stability of two trees of the same nodes (G9 of MEAS0): the adjusted Rand index of their leaves.\n * The second tree comes from the graph after a small change (`changeGraph`). The scale is -1 to 1, and higher is better.\n */\nexport function groupStability(before: Section, after: Section, count: number): number {\n return adjustedRandIndex(leafGroups(before, count), leafGroups(after, count));\n}\n","import { inflate, type Box } from \"../../geom.ts\";\nimport { rng } from \"../../fixtures.ts\";\nimport type { Edge, Graph, Node, Result } from \"../../model.ts\";\nimport { measureStability } from \"../quality.ts\";\nimport { boardUnit } from \"./routes.ts\";\n\n/** A small change of a graph, for the stability measures Z10 and G9 of MEAS0. */\nexport interface GraphChange {\n /** The graph after the change. It keeps the order of the nodes. */\n readonly graph: Graph;\n /** The node that moved by one unit, if a free place was found. */\n readonly moved?: string;\n /** The new edge, if the graph has two nodes without an edge between them. */\n readonly added?: string;\n /** The edge that the change removed. */\n readonly removed?: string;\n}\n\n/**\n * This function makes a seeded small change of a graph: one node moves by `boardUnit`, one edge goes and one new edge comes.\n * The moved box keeps a gap of 4 units to the other boxes. The same graph and the same seed give the same change.\n */\nexport function changeGraph(graph: Graph, seed: number): GraphChange {\n const R = rng(seed * 2654435761 + 97);\n const n = graph.nodes.length;\n const u = boardUnit(graph);\n let nodes: readonly Node[] = graph.nodes;\n let moved: string | undefined;\n if (n > 0) {\n const i = Math.floor(R() * n);\n const v = graph.nodes[i]!;\n const free = (b: Box): boolean => {\n const g = inflate(b, 4);\n return graph.nodes.every((o, j) => j === i || o.box.x >= g.x + g.w || g.x >= o.box.x + o.box.w || o.box.y >= g.y + g.h || g.y >= o.box.y + o.box.h);\n };\n const start = Math.floor(R() * 4);\n for (let k = 0; k < 4 && moved === undefined; k++) {\n const [dx, dy] = [\n [u, 0],\n [0, u],\n [-u, 0],\n [0, -u],\n ][(start + k) % 4]!;\n const box = { ...v.box, x: v.box.x + dx!, y: v.box.y + dy! };\n if (free(box)) {\n nodes = graph.nodes.map((o, j) => (j === i ? { ...o, box } : o));\n moved = v.id;\n }\n }\n }\n let edges: Edge[] = [...graph.edges];\n let removed: string | undefined;\n let added: string | undefined;\n if (edges.length > 1) {\n const j = Math.floor(R() * edges.length);\n const gone = edges[j]!;\n removed = gone.id;\n edges.splice(j, 1);\n const linked = new Set(graph.edges.flatMap((e) => [`${e.source.node}\\u0000${e.target.node}`, `${e.target.node}\\u0000${e.source.node}`]));\n for (let t = 0; t < 64 && added === undefined && n > 1; t++) {\n const a = graph.nodes[Math.floor(R() * n)]!.id;\n const b = graph.nodes[Math.floor(R() * n)]!.id;\n if (a === b || linked.has(`${a}\\u0000${b}`)) continue;\n added = `${gone.id}~`;\n edges = [...edges, { id: added, source: { node: a }, target: { node: b }, ...(gone.data ? { data: gone.data } : {}) }];\n }\n }\n return { graph: { nodes, edges }, ...(moved ? { moved } : {}), ...(added ? { added } : {}), ...(removed ? { removed } : {}) };\n}\n\n/** The route stability of a router (Z10 of MEAS0). */\nexport interface RouteStability {\n /** The mean Fréchet distance between the two routes of an edge, divided by the unit of the board. */\n readonly mean: number;\n /** The largest Fréchet distance, divided by the unit of the board. */\n readonly max: number;\n /** The share of the routes that moved more than 1 unit of length. */\n readonly moved: number;\n}\n\n/** The options of `routeStability`. */\nexport interface RouteStabilityOptions {\n /** Above this number of routes, a seeded sample of this size serves. The default is 2000. */\n readonly sample?: number;\n readonly seed?: number;\n}\n\n/**\n * This function measures the route stability of a router (Z10 of MEAS0) with `measureStability`.\n * It compares the routes of the edges that both results have. Each distance is divided by the unit of the board.\n * The cost is quadratic for each route, so a seeded sample serves above `sample` routes.\n */\nexport function routeStability(graph: Graph, before: Result, after: Result, options: RouteStabilityOptions = {}): RouteStability {\n const max = options.sample ?? 2000;\n const prev = new Set(before.routes.map((r) => r.edge));\n let routes = after.routes.filter((r) => prev.has(r.edge));\n if (routes.length > max) {\n const R = rng(options.seed ?? 1);\n routes = Array.from({ length: max }, () => routes[Math.floor(R() * routes.length)]!);\n }\n const s = measureStability(before, { routes });\n const u = boardUnit(graph);\n return { mean: s.mean / u, max: s.max / u, moved: s.moved };\n}\n","import { rng } from \"../../fixtures.ts\";\nimport type { Box } from \"../../geom.ts\";\nimport type { Boxed } from \"../../room/index.ts\";\n\n/** Up to this number of boxes, `roomOrderFaults` examines each pair. */\nconst EXACT_PAIRS = 2000;\nconst SAMPLE_PAIRS = 2_000_000;\n\n/**\n * This function counts the pairs of boxes whose order or alignment changes on an axis (M2 of MEAS0, the proposed rule `room-order`).\n * On each axis, it compares the order of the low edges, the order of the high edges, and the relation \"a ends before b starts\".\n * Two values nearer than `snap` are equal. Lower is better, and 0 is correct. Above 2000 boxes, a seeded sample of pairs gives an estimate.\n */\nexport function roomOrderFaults(before: readonly Boxed[], after: readonly Boxed[], snap = 0.5): number {\n const next = new Map(after.map((b) => [b.id, b.box] as const));\n const list: [Box, Box][] = [];\n for (const b of before) {\n const a = next.get(b.id);\n if (a) list.push([b.box, a]);\n }\n const sign = (x: number): number => (x > snap ? 1 : x < -snap ? -1 : 0);\n // The key packs the eight relations of a pair into one number in base 3.\n const axis = (p0: number, p1: number, q0: number, q1: number): number =>\n (sign(p0 - q0) + 1) * 27 + (sign(p1 - q1) + 1) * 9 + (q0 - p1 >= -snap ? 3 : 0) + (p0 - q1 >= -snap ? 1 : 0);\n const key = (p: Box, q: Box): number => axis(p.x, p.x + p.w, q.x, q.x + q.w) * 81 + axis(p.y, p.y + p.h, q.y, q.y + q.h);\n const changed = (i: number, j: number): boolean => key(list[i]![0], list[j]![0]) !== key(list[i]![1], list[j]![1]);\n const n = list.length;\n let faults = 0;\n if (n <= EXACT_PAIRS) {\n for (let i = 0; i < n; i++) for (let j = i + 1; j < n; j++) if (changed(i, j)) faults++;\n return faults;\n }\n const R = rng(n);\n let seen = 0;\n for (let k = 0; k < SAMPLE_PAIRS; k++) {\n const i = Math.floor(R() * n);\n const j = Math.floor(R() * n);\n if (i === j) continue;\n seen++;\n if (changed(i, j)) faults++;\n }\n return Math.round((faults * (n * (n - 1)) / 2) / Math.max(1, seen));\n}\n","/** One axis of a Pareto front: the key of a measure and the direction that is better. */\nexport interface Objective {\n readonly key: string;\n /** `min`: lower is better. `max`: higher is better. */\n readonly better: \"min\" | \"max\";\n}\n\n/** This function gives the value of a measure as a cost: lower is better. A value that is not a number is the worst cost. */\nfunction cost(values: Readonly<Record<string, number>>, o: Objective): number {\n const v = values[o.key];\n if (v === undefined || Number.isNaN(v)) return Infinity;\n return o.better === \"min\" ? v : -v;\n}\n\n/**\n * This function tells if the values `a` dominate the values `b`: `a` is no worse on each objective and better on one objective.\n * A missing value or `NaN` is the worst value.\n */\nexport function dominates(a: Readonly<Record<string, number>>, b: Readonly<Record<string, number>>, objectives: readonly Objective[]): boolean {\n let better = false;\n for (const o of objectives) {\n const ca = cost(a, o);\n const cb = cost(b, o);\n if (ca > cb) return false;\n if (ca < cb) better = true;\n }\n return better;\n}\n\n/**\n * This function gives the Pareto front of a list: the items that no other item dominates (MEAS0, \"Pareto fronts\").\n * The function `values` gives the measures of an item. The front keeps the order of the list. The cost is quadratic in the items.\n */\nexport function paretoFront<T>(items: readonly T[], values: (item: T) => Readonly<Record<string, number>>, objectives: readonly Objective[]): T[] {\n const v = items.map(values);\n return items.filter((_, i) => !v.some((w, j) => j !== i && dominates(w, v[i]!, objectives)));\n}\n","import { packedGridBoard } from \"../cases.ts\";\nimport { curveSpace, sampleCurve, type CurveSegment } from \"../curves/index.ts\";\nimport { FIXTURES, makeFixture, type FixtureSpec } from \"../fixtures.ts\";\nimport { polylineLength } from \"../geom.ts\";\nimport { nodeIndex, type Graph, type Node, type Result } from \"../model.ts\";\nimport { nearestSide, SIDE_NORMAL } from \"../plugs.ts\";\nimport { makeRoom, openGaps, roomLinks } from \"../room/index.ts\";\nimport { sectionsRouter } from \"../routers/sections.ts\";\nimport { checkSections, type Section } from \"../sections.ts\";\nimport { STRATEGIES } from \"../strategies/builtins.ts\";\nimport { asRouter, listStrategies, STEPS, type Registry, type Step, type Strategy } from \"../strategies/model.ts\";\nimport { measureLevelFaults, sumFaults } from \"./links.ts\";\nimport { checkLevels } from \"./properties.ts\";\nimport { ambiguity, inkSaved } from \"./measures/bundles.ts\";\nimport { bendingEnergy, curveFaults, g1Defect, g2Defect } from \"./measures/curves.ts\";\nimport { balance, cutShare, farLevel, groupStability, levelGrouping, modularity, treeCost } from \"./measures/groups.ts\";\nimport { nestingFaults, orderStability, positionStability } from \"./measures/levels.ts\";\nimport { paretoFront, type Objective } from \"./measures/pareto.ts\";\nimport { roomOrderFaults } from \"./measures/room.ts\";\nimport { boardUnit, crossingAngles, detourSpread, drawnSegments, plugSpacing, totalTurn } from \"./measures/routes.ts\";\nimport { changeGraph, routeStability } from \"./measures/stability.ts\";\nimport { quantile, summarize, type Spread } from \"./measures/stats.ts\";\nimport { measureBoard } from \"./room.ts\";\nimport { benchRun, type BenchRow } from \"./run.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/** The names of the proposed hard rules of MEAS0. The suite counts them. It does not apply them as rules yet. */\nexport const PROPOSED_RULES: readonly string[] = [\"curve-clear\", \"curve-ends\", \"curve-g1\", \"curve-simple\", \"level-nesting\", \"room-order\"];\n\n/** The options of `runSuite`. */\nexport interface SuiteOptions {\n /** The largest fixture, in nodes. The default is 1000. */\n readonly max?: number;\n /** The number of seeds of each fixture family. The default is 5. The first seed is the seed of the fixture. */\n readonly seeds?: number;\n /** A fixture family or a room family with more nodes than this number gets one seed only. The default is 1000. */\n readonly seedsMaxNodes?: number;\n /** The number of timed routes of the first seed. The other seeds route two times, for the rule \"same twice\". The default is 3. */\n readonly repeat?: number;\n /** The route stability (Z10) routes a changed graph again, so the suite measures it only up to this number of nodes. The default is 1000. */\n readonly stabilityMax?: number;\n /** The step `curve` draws the routes of the fixtures up to this number of nodes. The default is 1000. */\n readonly curveMax?: number;\n /** The router whose routes the step `curve` draws. The default is `corners`. */\n readonly curveRouter?: string;\n /** The curve strategies that are G1 by their design. The rule `curve-g1` examines them. The default is `rounded`, `arc`, `spline`, `smooth`, `clothoid` and `highway`. */\n readonly smoothCurves?: readonly string[];\n /** The curve strategies that read the normals of the plugs. The rule `curve-ends` examines their end tangents. The default is `spline`. */\n readonly normalCurves?: readonly string[];\n /** The strategies of each step. The default is the registry of the built-in strategies. */\n readonly registry?: Registry;\n /** The fixtures of the families of the steps `router`, `curve` and `group`. The default is `FIXTURES`. */\n readonly fixtures?: readonly FixtureSpec[];\n /** The families of the step `room`. The default is `ROOM_FAMILIES`. */\n readonly roomFamilies?: readonly RoomFamily[];\n /** The names of the routers of the step `router`. The default is each router of the registry. */\n readonly routers?: readonly string[];\n /** The steps that the suite runs. The default is each step. Each part of the workflow `Bench` runs some steps only. The step `curve` needs the step `router`. */\n readonly steps?: readonly Step[];\n /** The time limit of one cell of the step `router`, in milliseconds, as `BenchOptions.cellLimit` gives it. The default is no limit. */\n readonly cellLimit?: number;\n /** This function gets one line of progress for each fixture and seed. */\n readonly log?: (line: string) => void;\n}\n\n/** A family of packed boards for the step `room`: `packedGridBoard` with a seed for each member. */\nexport interface RoomFamily {\n readonly name: string;\n readonly cols: number;\n readonly rows: number;\n /** The number of long links. */\n readonly long: number;\n}\n\n/** The families of the step `room`: the board of ROOM, and a board of 1000 boxes. */\nexport const ROOM_FAMILIES: readonly RoomFamily[] = [\n { name: \"packed-grid\", cols: 12, rows: 8, long: 48 },\n { name: \"packed-grid-1000\", cols: 40, rows: 25, long: 500 },\n];\n\n/** One row of the suite: one strategy of one step on one member of a fixture family. */\nexport interface SuiteRow {\n readonly step: Step;\n /** The name of the fixture family. */\n readonly fixture: string;\n /** The index of the seed in the family, from 0. */\n readonly seed: number;\n readonly strategy: string;\n readonly nodes: number;\n readonly edges: number;\n /**\n * The violations of the hard rules of today. The step `router` checks `checkProperties` and \"same twice\".\n * The step `group` checks `checkSections` and the rules of the levels (`checkLevels`).\n */\n readonly violations: number;\n /** The time of the step and of the measures of today, in milliseconds. */\n readonly ms: number;\n /** The time of the new measures of MEAS1, without the extra runs, in milliseconds. */\n readonly measureMs: number;\n /** The time of the extra routes of the stability measures (Z10 and G9), in milliseconds. */\n readonly extraMs: number;\n /** The time of the grouping rule alone, without the router, in milliseconds. Only the rows of the step `group` have it. */\n readonly treeMs?: number;\n /** The measures, by a key that starts with the id of MEAS0, or the name of a proposed rule. */\n readonly values: Readonly<Record<string, number>>;\n}\n\n/** The spread of each measure of one strategy on one fixture family, over the seeds. */\nexport interface SuiteSummary {\n readonly step: Step;\n readonly fixture: string;\n readonly strategy: string;\n readonly nodes: number;\n readonly seeds: number;\n /** The sum of the violations over the seeds. */\n readonly violations: number;\n readonly measures: Readonly<Record<string, Spread>>;\n}\n\n/** The Pareto front of one step on one fixture family, over the medians of the seeds. */\nexport interface SuiteFront {\n readonly step: Step;\n readonly fixture: string;\n readonly nodes: number;\n readonly objectives: readonly Objective[];\n /** The strategies on the front, in the order of the registry. */\n readonly front: readonly string[];\n /** The strategies with a violation of a hard rule. They do not enter the front. */\n readonly excluded: readonly string[];\n /** Each strategy that the front compares. */\n readonly strategies: readonly string[];\n}\n\n/** The count of one proposed hard rule for one strategy, over each fixture and each seed. */\nexport interface RuleCount {\n readonly step: Step;\n readonly strategy: string;\n readonly rule: string;\n readonly count: number;\n}\n\n/** The report of the suite. The workflow `Bench` keeps it as an artifact. */\nexport interface SuiteReport {\n readonly options: {\n readonly max: number;\n readonly seeds: number;\n readonly seedsMaxNodes: number;\n readonly repeat: number;\n readonly stabilityMax: number;\n readonly curveMax: number;\n readonly curveRouter: string;\n };\n readonly rows: readonly SuiteRow[];\n readonly summaries: readonly SuiteSummary[];\n readonly fronts: readonly SuiteFront[];\n readonly rules: readonly RuleCount[];\n}\n\n/** The axes of the Pareto front of each step. The note MEAS0 asks for two to four scores. */\nexport const FRONT_OBJECTIVES: Readonly<Record<Step, readonly Objective[]>> = {\n router: [\n { key: \"R1.perEdge\", better: \"min\" },\n { key: \"R5.median\", better: \"min\" },\n { key: \"B1.inkSaved\", better: \"max\" },\n { key: \"R4.turn\", better: \"min\" },\n ],\n curve: [\n { key: \"C1.share\", better: \"min\" },\n { key: \"C2.median\", better: \"min\" },\n { key: \"C3.median\", better: \"min\" },\n { key: \"C6.length\", better: \"min\" },\n ],\n room: [\n { key: \"M1.area\", better: \"min\" },\n { key: \"M4.laneThrough\", better: \"min\" },\n { key: \"crossings\", better: \"min\" },\n ],\n group: [\n { key: \"G1.modularity\", better: \"max\" },\n { key: \"G2.cut\", better: \"min\" },\n { key: \"G8.treeCost\", better: \"min\" },\n { key: \"G9.ari\", better: \"max\" },\n ],\n};\n\n/** This function gives the seed of the member `k` of the family of a fixture. The member 0 is the fixture itself. */\nexport function familySeed(spec: FixtureSpec, k: number): number {\n return k === 0 ? spec.seed : spec.seed + 1009 * k;\n}\n\n/** This function gives the measures of the levels of a result: Z6, Z7, Z8, and G1, G2 and G8 of the far view. A result without groups gives none. */\nexport function levelMeasures(graph: Graph, result: Result): Record<string, number> {\n const levels = result.levels ?? [];\n if (!levels.some((l) => l.items.some((i) => i.nodes.length > 1))) return {};\n const far = farLevel(levels);\n const groups = far ? levelGrouping(far) : new Map<string, string>();\n return {\n \"level-nesting\": nestingFaults(levels),\n \"Z4.farItems\": far?.items.length ?? 0,\n \"Z7.position\": positionStability(levels),\n \"Z8.order\": orderStability(graph, levels),\n \"G1.modularity\": modularity(graph, groups),\n \"G2.cut\": cutShare(graph, groups),\n \"G6.balance\": far ? balance(far) : 1,\n \"G8.treeCost\": treeCost(graph, levels),\n };\n}\n\n/** This function gives the new measures of the routes of a result (MEAS1). The row of `benchRun` gives the values of today. */\nexport function routeMeasures(graph: Graph, result: Result, row: BenchRow): Record<string, number> {\n const routes = result.routes;\n const m = Math.max(1, graph.edges.length);\n const ca = crossingAngles(drawnSegments(routes));\n const turn = totalTurn(routes);\n const detour = detourSpread(routes);\n const plugs = plugSpacing(graph, routes);\n return {\n \"R1.crossings\": row.quality.crossings,\n \"R1.perEdge\": row.quality.crossings / m,\n \"R2.angle\": ca.mean,\n \"R2.min\": ca.min,\n \"B1.inkSaved\": inkSaved(routes),\n \"R4.turn\": turn.mean,\n \"R4.max\": turn.max,\n \"R5.median\": detour.median,\n \"R5.q95\": detour.q95,\n \"R5.mean\": detour.mean,\n \"R6.worstDetour\": row.faults.worstDetour,\n \"R7.backtrack\": row.faults.backtrack / m,\n \"R9.through\": row.faults.through,\n \"R13.outside\": row.faults.outside,\n \"R11.min\": plugs.min,\n \"R11.q05\": plugs.q05,\n \"B4.ambiguity\": ambiguity(graph, routes).value,\n ...levelMeasures(graph, result),\n };\n}\n\n/** The input of one curve: a route with the normals of its plugs. */\ninterface CurveRoute {\n readonly points: readonly { x: number; y: number }[];\n readonly startNormal: { x: number; y: number };\n readonly endNormal: { x: number; y: number };\n}\n\n/** The options of `curveRuns`. */\nexport interface CurveRunOptions {\n /** The name of the fixture family, for the rows. */\n readonly fixture: string;\n /** The index of the seed in the family, for the rows. */\n readonly seed: number;\n /** The curve strategies that are G1 by their design. The rule `curve-g1` examines them. */\n readonly smooth: ReadonlySet<string>;\n /** The curve strategies that read the normals of the plugs. The rule `curve-ends` examines their end tangents. */\n readonly normals: ReadonlySet<string>;\n /** The options of each curve strategy, by its name. A strategy without an entry gets its defaults. */\n readonly curveOptions?: Readonly<Record<string, object>>;\n}\n\n/** One curve strategy on the routes of one result: the row of the suite and the drawn curves. */\nexport interface CurveRun {\n readonly row: SuiteRow;\n /** The segments of each curve, in the order of the routes that have two points or more. */\n readonly drawn: readonly CurveSegment[][];\n /** The edge of each curve of `drawn`. */\n readonly edges: readonly string[];\n}\n\n/** This function draws the routes of a result with each curve strategy and measures the curves (C1, C2, C3, C6 and the curve rules). */\nexport function curveRuns(graph: Graph, result: Result, curves: readonly Strategy<\"curve\">[], options: CurveRunOptions): CurveRun[] {\n const byId = nodeIndex(graph);\n const edges = new Map(graph.edges.map((e) => [e.id, e]));\n const space = curveSpace(\n graph.nodes.map((n) => n.box),\n 0.25,\n );\n const u = boardUnit(graph);\n const routes: CurveRoute[] = [];\n const ids: string[] = [];\n for (const r of result.routes) {\n const e = edges.get(r.edge);\n const s = e && byId.get(e.source.node);\n const t = e && byId.get(e.target.node);\n if (!s || !t || r.points.length < 2) continue;\n ids.push(r.edge);\n routes.push({ points: r.points, startNormal: SIDE_NORMAL[nearestSide(s.box, r.points[0]!)], endNormal: SIDE_NORMAL[nearestSide(t.box, r.points[r.points.length - 1]!)] });\n }\n const ink = routes.reduce((sum, r) => sum + polylineLength(r.points), 0);\n return curves.map((curve): CurveRun => {\n const own = options.curveOptions?.[curve.name];\n const t0 = now();\n const drawn = routes.map((r) => curve.run({ points: r.points, startNormal: r.startNormal, endNormal: r.endNormal, space }, own));\n const samples = drawn.map((d) => sampleCurve(d, 0.25));\n const ms = now() - t0;\n const t1 = now();\n const g1: number[] = [];\n const g2: number[] = [];\n const energy: number[] = [];\n const rules = { \"curve-clear\": 0, \"curve-ends\": 0, \"curve-g1\": 0, \"curve-simple\": 0 };\n let length = 0;\n drawn.forEach((segments, i) => {\n const r = routes[i]!;\n const s = samples[i]!;\n g1.push(g1Defect(segments));\n g2.push(g2Defect(segments, u));\n energy.push(bendingEnergy(s, 0.25));\n length += polylineLength(s);\n const normals = options.normals.has(curve.name);\n const f = curveFaults({\n polyline: r.points,\n segments,\n samples: s,\n space,\n smooth: options.smooth.has(curve.name),\n ...(normals ? { startNormal: r.startNormal, endNormal: r.endNormal } : {}),\n });\n if (f.clear) rules[\"curve-clear\"]++;\n if (f.ends) rules[\"curve-ends\"]++;\n if (f.g1) rules[\"curve-g1\"]++;\n if (f.simple) rules[\"curve-simple\"]++;\n });\n const n = Math.max(1, drawn.length);\n const values = {\n \"C1.max\": g1.reduce((m, x) => Math.max(m, x), 0),\n \"C1.share\": g1.filter((x) => x > 0.5).length / n,\n \"C2.median\": quantile(g2, 0.5) || 0,\n \"C2.max\": g2.reduce((m, x) => Math.max(m, x), 0),\n \"C3.median\": quantile(energy, 0.5) || 0,\n \"C3.q95\": quantile(energy, 0.95) || 0,\n \"C6.length\": ink > 0 ? length / ink : 1,\n ...rules,\n };\n const row: SuiteRow = {\n step: \"curve\",\n fixture: options.fixture,\n seed: options.seed,\n strategy: curve.name,\n nodes: graph.nodes.length,\n edges: graph.edges.length,\n violations: 0,\n ms,\n measureMs: now() - t1,\n extraMs: 0,\n values,\n };\n return { row, drawn, edges: ids };\n });\n}\n\n/** One grouping rule on one graph: the row of the suite, the tree of the rule and the result of `sections` on that tree. */\nexport interface GroupRun {\n readonly row: SuiteRow;\n readonly tree: Section;\n /** The result of the router `sections` with the tree of the rule. A tree that `checkSections` refuses gives no result. */\n readonly result?: Result;\n}\n\n/**\n * This function groups one graph with one grouping rule, routes it with the router `sections` on that tree, and measures the levels.\n * The grouping of the changed graph gives the group stability (G9). `options` are the options of the rule on `graph`.\n */\nexport function groupRun(\n graph: Graph,\n strategy: Strategy<\"group\">,\n options: object,\n change: { readonly graph: Graph; readonly options: object },\n at: { readonly fixture: string; readonly seed: number },\n): GroupRun {\n const t0 = now();\n const tree = strategy.run(graph, options);\n const treeMs = now() - t0;\n const base = { step: \"group\" as const, fixture: at.fixture, seed: at.seed, strategy: strategy.name, nodes: graph.nodes.length, edges: graph.edges.length };\n // A tree that `checkSections` refuses is one violation. The router refuses it too, so the row has no measures.\n try {\n checkSections(tree, graph.nodes.length);\n } catch {\n return { row: { ...base, violations: 1, ms: treeMs, measureMs: 0, extraMs: 0, treeMs, values: {} }, tree };\n }\n const result = sectionsRouter({ name: \"sections\", group: strategy, groupOptions: options }).route(graph);\n const ms = now() - t0;\n const t1 = now();\n // The hard rules of the levels (`counts-sum` and `link-ends`) are the violations of the step `group`.\n const violations = checkLevels(graph, result.levels ?? []).length;\n const values: Record<string, number> = { ...levelMeasures(graph, result), \"Z3.through\": sumFaults(measureLevelFaults(result)).through };\n const measureMs = now() - t1;\n const t2 = now();\n values[\"G9.ari\"] = groupStability(tree, strategy.run(change.graph, change.options), graph.nodes.length);\n const extraMs = now() - t2;\n return { row: { ...base, violations, ms, measureMs, extraMs, treeMs, values }, tree, result };\n}\n\n/**\n * This function gives the options of a grouping rule on a fixture. The rule `keys` gets a key from the data of the edges:\n * the collection of the first edge into the node. A node without such an edge is a group alone.\n */\nexport function fixtureGroupOptions(strategy: string, graph: Graph): object {\n if (strategy !== \"keys\") return {};\n const key = new Map<string, string>();\n for (const e of graph.edges) {\n const c = e.data?.[\"collection\"];\n if (typeof c === \"string\" && !key.has(e.target.node)) key.set(e.target.node, c);\n }\n return { key: (n: Node) => key.get(n.id) };\n}\n\n/**\n * This function starts the measure suite of MEAS1. The suite measures each strategy of each step on each seed of each fixture family.\n * The step `router` keeps the rows of today in `bench` for the first seed, so the tables of the benchmark stay the same.\n */\nexport function runSuite(options: SuiteOptions = {}): { report: SuiteReport; bench: BenchRow[] } {\n const max = options.max ?? 1000;\n const seeds = Math.max(1, Math.floor(options.seeds ?? 5));\n const seedsMaxNodes = options.seedsMaxNodes ?? 1000;\n const seedsOf = (nodes: number): number => (nodes > seedsMaxNodes ? 1 : seeds);\n const steps = new Set<Step>(options.steps ?? STEPS);\n const cellLimit = options.cellLimit ?? Infinity;\n const repeat = options.repeat ?? 3;\n const stabilityMax = options.stabilityMax ?? 1000;\n const curveMax = options.curveMax ?? 1000;\n const curveRouter = options.curveRouter ?? \"corners\";\n const registry = options.registry ?? STRATEGIES;\n const smooth = new Set(options.smoothCurves ?? [\"rounded\", \"arc\", \"spline\", \"smooth\", \"clothoid\", \"highway\"]);\n const normals = new Set(options.normalCurves ?? [\"spline\"]);\n const log = options.log ?? ((): void => {});\n const fixtures = steps.has(\"router\") || steps.has(\"group\") ? (options.fixtures ?? FIXTURES).filter((f) => f.nodes <= max) : [];\n const routers = steps.has(\"router\") ? listStrategies(registry, \"router\").filter((s) => options.routers?.includes(s.name) ?? true) : [];\n const curves = steps.has(\"curve\") ? listStrategies(registry, \"curve\") : [];\n const groups = steps.has(\"group\") ? listStrategies(registry, \"group\") : [];\n const rooms = listStrategies(registry, \"room\");\n const rows: SuiteRow[] = [];\n const bench: BenchRow[] = [];\n\n for (const spec of fixtures) {\n for (let k = 0; k < seedsOf(spec.nodes); k++) {\n const seed = familySeed(spec, k);\n const graph = makeFixture({ ...spec, seed });\n const change = changeGraph(graph, seed);\n log(`${spec.name} seed ${k}: ${graph.nodes.length} nodes, ${graph.edges.length} edges`);\n const first = rows.length;\n // The step `router`: the hard rules and the measures of today, then the new measures.\n for (const strategy of routers) {\n if (graph.nodes.length > (strategy.maxNodes ?? Infinity)) continue;\n const router = asRouter(strategy);\n const t0 = now();\n const { row, result } = benchRun(router, spec.name, graph, k === 0 ? repeat : 1, cellLimit);\n const ms = now() - t0;\n if (k === 0) bench.push(row);\n const t1 = now();\n const values: Record<string, number> = routeMeasures(graph, result, row);\n const measureMs = now() - t1;\n let extraMs = 0;\n if (graph.nodes.length <= stabilityMax) {\n const t2 = now();\n const s = routeStability(graph, result, router.route(change.graph), { seed });\n extraMs = now() - t2;\n values[\"Z10.mean\"] = s.mean;\n values[\"Z10.max\"] = s.max;\n values[\"Z10.moved\"] = s.moved;\n }\n rows.push({\n step: \"router\",\n fixture: spec.name,\n seed: k,\n strategy: strategy.name,\n nodes: row.nodes,\n edges: row.edges,\n violations: row.violations + (row.deterministic ? 0 : 1),\n ms,\n measureMs,\n extraMs,\n values,\n });\n if (strategy.name === curveRouter && curves.length > 0 && graph.nodes.length <= curveMax)\n rows.push(...curveRuns(graph, result, curves, { fixture: spec.name, seed: k, smooth, normals }).map((c) => c.row));\n }\n // The step `group`: the router `sections` with each grouping rule, and the grouping of the changed graph (G9).\n for (const strategy of groups) {\n const opts = fixtureGroupOptions(strategy.name, graph);\n const changed = { graph: change.graph, options: fixtureGroupOptions(strategy.name, change.graph) };\n rows.push(groupRun(graph, strategy, opts, changed, { fixture: spec.name, seed: k }).row);\n }\n // The time of each row, in milliseconds: the step, the new measures and the extra routes.\n log(\n ` ${rows\n .slice(first)\n .map((r) => `${r.step}/${r.strategy} ${r.ms.toFixed(0)}+${r.measureMs.toFixed(0)}+${r.extraMs.toFixed(0)}`)\n .join(\", \")}`,\n );\n }\n }\n\n // The step `room`: the board with each gap open to the gutter only, then each room strategy.\n for (const family of steps.has(\"room\") ? (options.roomFamilies ?? ROOM_FAMILIES) : []) {\n if (family.cols * family.rows > max) continue;\n for (let k = 0; k < seedsOf(family.cols * family.rows); k++) {\n const graph = packedGridBoard({ seed: 11 + 1009 * k, cols: family.cols, rows: family.rows, long: family.long });\n log(`${family.name} seed ${k}: ${graph.nodes.length} nodes, ${graph.edges.length} edges`);\n const links = roomLinks(graph);\n const area0 = areaOf(graph.nodes);\n const boards: { name: string; open: () => readonly Node[] }[] = [\n { name: \"gutter\", open: () => makeRoom(graph.nodes, links, { gutter: 8, spacing: 0, method: \"routes\" }).items },\n ...rooms.map((s) => ({ name: s.name, open: () => openGaps(graph.nodes, s.run({ items: graph.nodes, links }, { gutter: 8, spacing: 4 })) })),\n ];\n for (const b of boards) {\n const t0 = now();\n const nodes = b.open();\n const m = measureBoard({ nodes, edges: graph.edges }, 4);\n const ms = now() - t0;\n const t1 = now();\n const order = roomOrderFaults(graph.nodes, nodes);\n const measureMs = now() - t1;\n rows.push({\n step: \"room\",\n fixture: family.name,\n seed: k,\n strategy: b.name,\n nodes: graph.nodes.length,\n edges: graph.edges.length,\n violations: 0,\n ms,\n measureMs,\n extraMs: 0,\n values: {\n \"M1.area\": area0 > 0 ? areaOf(nodes) / area0 : 1,\n \"M4.laneThrough\": m.laneThrough,\n crossings: m.crossings,\n through: m.faults.through,\n \"R6.worstDetour\": m.faults.worstDetour,\n \"room-order\": order,\n },\n });\n }\n }\n }\n\n const summaries = summarizeRows(rows);\n return {\n report: {\n options: { max, seeds, seedsMaxNodes, repeat, stabilityMax, curveMax, curveRouter },\n rows,\n summaries,\n fronts: suiteFronts(summaries),\n rules: ruleCounts(rows),\n },\n bench,\n };\n}\n\n/**\n * This function puts the rows of the suite in the order of one run. It sorts them by fixture family, then by seed.\n * In one seed, the routers come first, and the curves come after the router of the curves. The grouping rules and the room come last.\n * A name that is not in its list goes after the names of the list.\n * The workflow `Bench` uses it to join the reports of its parts.\n */\nexport function orderSuiteRows(\n rows: readonly SuiteRow[],\n options: { registry?: Registry; fixtures?: readonly FixtureSpec[]; roomFamilies?: readonly RoomFamily[]; curveRouter?: string } = {},\n): SuiteRow[] {\n const registry = options.registry ?? STRATEGIES;\n const families = [...(options.fixtures ?? FIXTURES).map((f) => f.name), ...(options.roomFamilies ?? ROOM_FAMILIES).map((f) => f.name)];\n const place = (list: readonly string[], name: string): number => {\n const i = list.indexOf(name);\n return i < 0 ? list.length : i;\n };\n const names = (step: Step): string[] => listStrategies(registry, step).map((s) => s.name);\n const routers = names(\"router\");\n const curves = names(\"curve\");\n const after = place(routers, options.curveRouter ?? \"corners\");\n // The routers and the curves share one rank. Each curve comes after the router of the curves, as `runSuite` gives them.\n const rank = (r: SuiteRow): [number, number] => {\n if (r.step === \"router\") return [0, 2 * place(routers, r.strategy) * (curves.length + 1)];\n if (r.step === \"curve\") return [0, 2 * after * (curves.length + 1) + 1 + place(curves, r.strategy)];\n if (r.step === \"group\") return [1, place(names(\"group\"), r.strategy)];\n return [2, r.strategy === \"gutter\" ? -1 : place(names(\"room\"), r.strategy)];\n };\n return rows\n .map((row, i) => ({ row, i, f: place(families, row.fixture), rank: rank(row) }))\n .sort((a, b) => a.f - b.f || a.row.seed - b.row.seed || a.rank[0] - b.rank[0] || a.rank[1] - b.rank[1] || a.i - b.i)\n .map((x) => x.row);\n}\n\n/**\n * This function joins the reports of the parts of one benchmark into one report. It puts the rows in the order of one run.\n * Then it calculates the summaries, the fronts and the rule counts again from all the rows.\n */\nexport function joinReports(reports: readonly SuiteReport[], options: { registry?: Registry; fixtures?: readonly FixtureSpec[]; roomFamilies?: readonly RoomFamily[] } = {}): SuiteReport {\n const first = reports[0]?.options;\n const rows = orderSuiteRows(\n reports.flatMap((r) => r.rows),\n { ...options, curveRouter: first?.curveRouter ?? \"corners\" },\n );\n const summaries = summarizeRows(rows);\n return {\n options: {\n max: Math.max(0, ...reports.map((r) => r.options.max)),\n seeds: first?.seeds ?? 0,\n seedsMaxNodes: first?.seedsMaxNodes ?? 0,\n repeat: first?.repeat ?? 0,\n stabilityMax: first?.stabilityMax ?? 0,\n curveMax: first?.curveMax ?? 0,\n curveRouter: first?.curveRouter ?? \"corners\",\n },\n rows,\n summaries,\n fronts: suiteFronts(summaries),\n rules: ruleCounts(rows),\n };\n}\n\n/** This function gives the area of the bounding box of the nodes. */\nfunction areaOf(nodes: readonly Node[]): number {\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 return nodes.length ? (x1 - x0) * (y1 - y0) : 0;\n}\n\n/** This function gives the spread of each measure of each strategy on each fixture family, over the seeds. It keeps the order of the rows. */\nexport function summarizeRows(rows: readonly SuiteRow[]): SuiteSummary[] {\n const groups = new Map<string, SuiteRow[]>();\n for (const r of rows) {\n const key = `${r.step}\\u0000${r.fixture}\\u0000${r.strategy}`;\n const list = groups.get(key);\n if (list) list.push(r);\n else groups.set(key, [r]);\n }\n return [...groups.values()].map((list) => {\n const first = list[0]!;\n const keys = [...new Set(list.flatMap((r) => Object.keys(r.values)))];\n const measures: Record<string, Spread> = {};\n for (const k of keys) measures[k] = summarize(list.map((r) => r.values[k] ?? Number.NaN));\n measures[\"ms\"] = summarize(list.map((r) => r.ms));\n measures[\"measureMs\"] = summarize(list.map((r) => r.measureMs));\n if (list.some((r) => r.treeMs !== undefined)) measures[\"treeMs\"] = summarize(list.map((r) => r.treeMs ?? Number.NaN));\n return {\n step: first.step,\n fixture: first.fixture,\n strategy: first.strategy,\n nodes: first.nodes,\n seeds: list.length,\n violations: list.reduce((s, r) => s + r.violations, 0),\n measures,\n };\n });\n}\n\n/**\n * This function gives the Pareto front of each step on each fixture family, over the medians of the seeds.\n * A strategy with a violation of a hard rule does not enter the front, as MEAS0 asks.\n */\nexport function suiteFronts(summaries: readonly SuiteSummary[], objectives: Readonly<Record<Step, readonly Objective[]>> = FRONT_OBJECTIVES): SuiteFront[] {\n const groups = new Map<string, SuiteSummary[]>();\n for (const s of summaries) {\n const key = `${s.step}\\u0000${s.fixture}`;\n const list = groups.get(key);\n if (list) list.push(s);\n else groups.set(key, [s]);\n }\n return [...groups.values()].map((list) => {\n const first = list[0]!;\n const axes = objectives[first.step];\n const fair = list.filter((s) => s.violations === 0);\n const medians = (s: SuiteSummary): Record<string, number> => Object.fromEntries(axes.map((o) => [o.key, s.measures[o.key]?.median ?? Number.NaN]));\n return {\n step: first.step,\n fixture: first.fixture,\n nodes: first.nodes,\n objectives: axes,\n front: paretoFront(fair, medians, axes).map((s) => s.strategy),\n excluded: list.filter((s) => s.violations > 0).map((s) => s.strategy),\n strategies: list.map((s) => s.strategy),\n };\n });\n}\n\n/** This function sums each proposed hard rule of MEAS0 for each strategy of each step, over each fixture and each seed. */\nexport function ruleCounts(rows: readonly SuiteRow[]): RuleCount[] {\n const out = new Map<string, RuleCount>();\n for (const r of rows)\n for (const rule of PROPOSED_RULES) {\n const v = r.values[rule];\n if (v === undefined) continue;\n const key = `${r.step}\\u0000${r.strategy}\\u0000${rule}`;\n const known = out.get(key);\n out.set(key, { step: r.step, strategy: r.strategy, rule, count: (known?.count ?? 0) + v });\n }\n return [...out.values()];\n}\n\nconst fmt = (v: number | undefined, d = 3): string => (v === undefined || Number.isNaN(v) ? \"-\" : Number.isInteger(v) ? String(v) : v.toFixed(d));\n\n/** The columns of the tables of `formatSuite`: the keys of the measures of each step. */\nexport const SUITE_COLUMNS: Readonly<Record<Step, readonly string[]>> = {\n router: [\"R1.perEdge\", \"R2.angle\", \"R2.min\", \"B1.inkSaved\", \"R5.median\", \"R5.q95\", \"R4.turn\", \"R11.q05\", \"B4.ambiguity\", \"Z10.moved\", \"Z8.order\", \"Z7.position\", \"G8.treeCost\"],\n curve: [\"C1.share\", \"C1.max\", \"C2.median\", \"C3.median\", \"C3.q95\", \"C6.length\"],\n room: [\"M1.area\", \"M4.laneThrough\", \"crossings\", \"through\", \"room-order\"],\n group: [\"Z4.farItems\", \"G1.modularity\", \"G2.cut\", \"G6.balance\", \"G8.treeCost\", \"G9.ari\", \"Z7.position\", \"Z8.order\", \"Z3.through\", \"treeMs\"],\n};\n\n/**\n * This function writes the summaries of one step as a Markdown table. Each cell is the median over the seeds, with the interquartile range in brackets.\n * The column `R1 IQR/median` gives the spread of the crossings.\n */\nexport function formatSummaries(summaries: readonly SuiteSummary[], step: Step, columns: readonly string[] = SUITE_COLUMNS[step]): string {\n const extra = step === \"router\" ? [\"R1 IQR/median\"] : [];\n const head = `| ${step} | fixture | seeds | violations | ${[...columns, ...extra].join(\" | \")} |`;\n const line = `|---|---|---:|---:|${[...columns, ...extra].map(() => \"---:\").join(\"|\")}|`;\n const body = summaries\n .filter((s) => s.step === step)\n .map((s) => {\n const cells = columns.map((c) => {\n const m = s.measures[c];\n return m && m.n > 0 ? `${fmt(m.median)} (${fmt(m.iqr)})` : \"-\";\n });\n if (step === \"router\") {\n const c = s.measures[\"R1.crossings\"];\n cells.push(c && c.median > 0 ? fmt(c.iqr / c.median) : \"-\");\n }\n return `| ${s.strategy} | ${s.fixture} | ${s.seeds} | ${s.violations} | ${cells.join(\" | \")} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n\n/** This function writes the Pareto fronts as a Markdown table. */\nexport function formatFronts(fronts: readonly SuiteFront[]): string {\n const head = \"| step | fixture | nodes | axes | front | not on the front | excluded (hard rules) |\";\n const line = \"|---|---|---:|---|---|---|---|\";\n const body = fronts.map((f) => {\n const axes = f.objectives.map((o) => `${o.key} ${o.better === \"min\" ? \"↓\" : \"↑\"}`).join(\", \");\n const off = f.strategies.filter((s) => !f.front.includes(s) && !f.excluded.includes(s));\n return `| ${f.step} | ${f.fixture} | ${f.nodes} | ${axes} | ${f.front.join(\", \")} | ${off.join(\", \") || \"-\"} | ${f.excluded.join(\", \") || \"-\"} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n\n/** This function writes the counts of the proposed hard rules as a Markdown table: one row for each step and strategy. */\nexport function formatRules(rules: readonly RuleCount[]): string {\n const head = `| step | strategy | ${PROPOSED_RULES.join(\" | \")} |`;\n const line = `|---|---|${PROPOSED_RULES.map(() => \"---:\").join(\"|\")}|`;\n const keys = [...new Set(rules.map((r) => `${r.step}\\u0000${r.strategy}`))];\n const body = keys.map((k) => {\n const [step, strategy] = k.split(\"\\u0000\");\n const cells = PROPOSED_RULES.map((rule) => {\n const r = rules.find((x) => x.step === step && x.strategy === strategy && x.rule === rule);\n return r ? String(r.count) : \"-\";\n });\n return `| ${step} | ${strategy} | ${cells.join(\" | \")} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n\n/**\n * This function compares the time of the new measures with the time of the step and the measures of today.\n * It gives one row for each fixture family of a step. The extra routes of the stability measures have their own column.\n */\nexport function formatMeasureTime(rows: readonly SuiteRow[], step: Step = \"router\"): string {\n const head = \"| step | fixture | nodes | rows | ms of today | ms of the new measures | share | ms of the extra runs |\";\n const line = \"|---|---|---:|---:|---:|---:|---:|---:|\";\n const byFixture = new Map<string, SuiteRow[]>();\n for (const r of rows.filter((x) => x.step === step)) {\n const list = byFixture.get(r.fixture);\n if (list) list.push(r);\n else byFixture.set(r.fixture, [r]);\n }\n const body = [...byFixture].map(([fixture, list]) => {\n const old = list.reduce((s, r) => s + r.ms, 0);\n const added = list.reduce((s, r) => s + r.measureMs, 0);\n const extra = list.reduce((s, r) => s + r.extraMs, 0);\n return `| ${step} | ${fixture} | ${list[0]!.nodes} | ${list.length} | ${old.toFixed(0)} | ${added.toFixed(0)} | ${old > 0 ? ((100 * added) / old).toFixed(1) : \"-\"}% | ${extra.toFixed(0)} |`;\n });\n return [head, line, ...body].join(\"\\n\");\n}\n","import type { Step, Strategy } from \"./model.ts\";\n\n/** The scale of a number option. A sweep on the scale `log` gives values with equal ratios, not with equal differences. */\nexport type OptionScale = \"linear\" | \"log\";\n\n/** The fields of each option declaration. */\ninterface OptionBase {\n /** One short sentence that tells what the option sets. The site and the documents show it. */\n readonly describe: string;\n}\n\n/**\n * The declaration of a number option. The range from `min` to `max` is the range of a control and of a sweep.\n * The strategy can take a value outside the range. `checkOptions` reports such a value, and `clampOptions` moves it into the range.\n */\nexport interface NumberOption extends OptionBase {\n /** The type `integer` takes only whole numbers. */\n readonly type: \"number\" | \"integer\";\n readonly min: number;\n readonly max: number;\n /** The grain of a control and of a sweep. A value off the step is valid. Without it, the grain is free (or 1 for an integer). */\n readonly step?: number;\n /** The scale of a control and of a sweep. The default is `linear`. The scale `log` needs a `min` above 0. */\n readonly scale?: OptionScale;\n /** These values are valid outside the range. For example, `Infinity` sets no limit. */\n readonly special?: readonly number[];\n /** These values are the notable values of the option: the default and the values of the sweeps of the benchmark. */\n readonly marks?: readonly number[];\n /** The strategy uses this value when the caller and `defaults` give no value. */\n readonly default?: number;\n}\n\n/** The declaration of a boolean option. */\nexport interface BooleanOption extends OptionBase {\n readonly type: \"boolean\";\n /** The strategy uses this value when the caller and `defaults` give no value. */\n readonly default?: boolean;\n}\n\n/** The declaration of an option with a fixed list of string values. */\nexport interface EnumOption<V extends string = string> extends OptionBase {\n readonly type: \"enum\";\n /** The values of the option, in the order of a control. */\n readonly values: readonly V[];\n /** The strategy uses this value when the caller and `defaults` give no value. */\n readonly default?: V;\n}\n\n/**\n * The declaration of an option that a control or a sweep cannot set from a range.\n * The type `function` is a rule, `strategy` is a strategy of the step `step`, `list` is an array and `object` is any other object.\n */\nexport interface ValueOption<V = unknown> extends OptionBase {\n readonly type: \"function\" | \"strategy\" | \"list\" | \"object\";\n /** The step of the strategy, for the type `strategy`. A control lists the strategies of this step of a registry. */\n readonly step?: Step;\n /** The strategy uses this value when the caller and `defaults` give no value. */\n readonly default?: V;\n}\n\n/** The declaration of one option of any type. */\nexport type AnyOption = NumberOption | BooleanOption | EnumOption | ValueOption;\n\n/** The declaration that fits the type of an option value: numbers, booleans, string unions or other values. */\nexport type OptionDeclaration<V> = [V] extends [number] ? NumberOption : [V] extends [boolean] ? BooleanOption : [V] extends [string] ? EnumOption<V> : ValueOption<V>;\n\n/** The declarations of the options of a strategy. The schema has one declaration for each key of the options type, and no other key. */\nexport type OptionSchema<O> = { readonly [K in keyof O]-?: OptionDeclaration<NonNullable<O[K]>> };\n\n/** One problem of an option value against its declaration. */\nexport interface OptionIssue {\n /** The key of the option. */\n readonly key: string;\n readonly value: unknown;\n /** The kind of the problem: no declaration, the wrong type, out of the range, not a whole number or not one of the values. */\n readonly problem: \"unknown\" | \"type\" | \"range\" | \"integer\" | \"value\";\n /** One sentence that tells the problem. */\n readonly message: string;\n}\n\n/** One setting of a sweep: a name for the rows of a table, and the options of the strategy. */\nexport interface OptionSetting<O extends object> {\n /** The key and the value of each option of the setting, for example `stretch 1.5`. */\n readonly name: string;\n readonly options: Partial<O>;\n}\n\n/** The options of `sweepValues`, `sweepOf` and `sweepGrid`. */\nexport interface SweepOptions {\n /**\n * The number of values on the range of a number option. Without it, the sweep gives the `marks` of the declaration.\n * A declaration without `marks` gets 5 values.\n */\n readonly count?: number;\n /** With `true`, a sweep of a number option on the range also gives the `special` values. The default is `false`. */\n readonly special?: boolean;\n}\n\n/** The number of values of a sweep on a range when the call and the declaration give no number. */\nconst SWEEP_COUNT = 5;\n\n/** This function gives the declarations of a strategy as a record. A strategy without a schema gives an empty record. */\nfunction schemaOf(strategy: Strategy<Step, object>): Readonly<Record<string, AnyOption>> {\n return (strategy.schema ?? {}) as Readonly<Record<string, AnyOption>>;\n}\n\n/** This function gives the declared options of a strategy, in the order of its schema, with the effective default of each one. */\nexport function listOptions<S extends Step, O extends object>(\n strategy: Strategy<S, O>,\n): { readonly key: keyof O & string; readonly declaration: AnyOption; readonly value: unknown }[] {\n const defaults = optionDefaults(strategy) as Record<string, unknown>;\n return Object.entries(schemaOf(strategy)).map(([key, declaration]) => ({ key: key as keyof O & string, declaration, value: defaults[key] }));\n}\n\n/**\n * This function gives the effective default of each declared option: the value of `defaults`, else the `default` of the declaration.\n * An option without either value stays out. The strategy gives the same output with this object as with no options.\n */\nexport function optionDefaults<S extends Step, O extends object>(strategy: Strategy<S, O>): Partial<O> {\n const out: Record<string, unknown> = {};\n const defaults = strategy.defaults as Readonly<Record<string, unknown>>;\n for (const [key, declaration] of Object.entries(schemaOf(strategy))) {\n if (key in defaults) out[key] = defaults[key];\n else if (declaration.default !== undefined) out[key] = declaration.default;\n }\n for (const key of Object.keys(defaults)) if (!(key in out)) out[key] = defaults[key];\n return out as Partial<O>;\n}\n\n/** This function gives `true` if the number is one of the special values of the declaration. */\nconst isSpecial = (d: NumberOption, v: number): boolean => (d.special ?? []).some((s) => Object.is(s, v) || s === v);\n\n/** This function gives the problem of one value against its declaration, or `undefined` when the value fits. */\nfunction issueOf(key: string, value: unknown, d: AnyOption): OptionIssue | undefined {\n const issue = (problem: OptionIssue[\"problem\"], message: string): OptionIssue => ({ key, value, problem, message });\n if (value === undefined) return undefined;\n switch (d.type) {\n case \"number\":\n case \"integer\": {\n if (typeof value !== \"number\" || Number.isNaN(value)) return issue(\"type\", `The option \"${key}\" takes a number.`);\n if (isSpecial(d, value)) return undefined;\n if (value < d.min || value > d.max) return issue(\"range\", `The option \"${key}\" is ${value}, out of the range ${d.min} to ${d.max}.`);\n if (d.type === \"integer\" && !Number.isInteger(value)) return issue(\"integer\", `The option \"${key}\" takes a whole number, not ${value}.`);\n return undefined;\n }\n case \"boolean\":\n return typeof value === \"boolean\" ? undefined : issue(\"type\", `The option \"${key}\" takes true or false.`);\n case \"enum\":\n return d.values.includes(value as string) ? undefined : issue(\"value\", `The option \"${key}\" takes ${d.values.join(\", \")}, not ${String(value)}.`);\n case \"function\":\n return typeof value === \"function\" ? undefined : issue(\"type\", `The option \"${key}\" takes a function.`);\n case \"list\":\n return Array.isArray(value) ? undefined : issue(\"type\", `The option \"${key}\" takes a list.`);\n default:\n return typeof value === \"object\" && value !== null ? undefined : issue(\"type\", `The option \"${key}\" takes an object.`);\n }\n}\n\n/**\n * This function examines option values against the schema of a strategy. It gives one issue for each key without a declaration.\n * It also gives one issue for each value of the wrong type, out of the range, not whole or not one of the values.\n * It changes no value.\n * A strategy without a schema gives no issue.\n */\nexport function checkOptions<S extends Step, O extends object>(strategy: Strategy<S, O>, options: Partial<O>): OptionIssue[] {\n if (strategy.schema === undefined) return [];\n const schema = schemaOf(strategy);\n const out: OptionIssue[] = [];\n for (const [key, value] of Object.entries(options)) {\n const d = schema[key];\n const issue = d ? issueOf(key, value, d) : { key, value, problem: \"unknown\" as const, message: `The strategy \"${strategy.name}\" has no option \"${key}\".` };\n if (issue) out.push(issue);\n }\n return out;\n}\n\n/**\n * This function moves each number option into the range of its declaration, for a control. An integer option gets the nearest whole number.\n * A special value stays. The function keeps each other value as it is. `checkOptions` reports the values that this function cannot correct.\n */\nexport function clampOptions<S extends Step, O extends object>(strategy: Strategy<S, O>, options: Partial<O>): Partial<O> {\n const schema = schemaOf(strategy);\n const out: Record<string, unknown> = { ...options };\n for (const [key, value] of Object.entries(options)) {\n const d = schema[key];\n if (!d || (d.type !== \"number\" && d.type !== \"integer\") || typeof value !== \"number\" || Number.isNaN(value) || isSpecial(d, value)) continue;\n const v = Math.min(d.max, Math.max(d.min, value));\n out[key] = d.type === \"integer\" ? Math.min(d.max, Math.max(d.min, Math.round(v))) : v;\n }\n return out as Partial<O>;\n}\n\n/** This function gives `count` values from `min` to `max` on the scale, on the grain of the step, without repeats. */\nfunction rangeValues(d: NumberOption, count: number): number[] {\n const n = Math.max(1, Math.floor(count));\n const log = d.scale === \"log\" && d.min > 0;\n const at = (t: number): number => (log ? d.min * (d.max / d.min) ** t : d.min + (d.max - d.min) * t);\n const step = d.step ?? (d.type === \"integer\" ? 1 : undefined);\n const snap = (v: number): number => {\n const s = step === undefined ? v : d.min + Math.round((v - d.min) / step) * step;\n const r = Number(s.toPrecision(12));\n return Math.min(d.max, Math.max(d.min, d.type === \"integer\" ? Math.round(r) : r));\n };\n const out: number[] = [];\n for (let i = 0; i < n; i++) {\n const v = snap(at(n === 1 ? 0 : i / (n - 1)));\n if (!out.includes(v)) out.push(v);\n }\n return out;\n}\n\n/**\n * This function gives the values of a sweep of one option declaration.\n * A number option gives its `marks`, or `count` values on its range and its scale. A boolean gives `false` and `true`. An enum gives its values.\n * An option of another type has no sweep, so the function throws an error.\n */\nexport function sweepValues(declaration: AnyOption, options: SweepOptions = {}): unknown[] {\n switch (declaration.type) {\n case \"number\":\n case \"integer\": {\n if (options.count === undefined && declaration.marks !== undefined) return [...declaration.marks];\n const values = rangeValues(declaration, options.count ?? SWEEP_COUNT);\n return options.special ? [...values, ...(declaration.special ?? []).filter((s) => !values.includes(s))] : values;\n }\n case \"boolean\":\n return [false, true];\n case \"enum\":\n return [...declaration.values];\n default:\n throw new Error(`An option of the type \"${declaration.type}\" has no sweep. A sweep takes a number, an integer, a boolean or an enum.`);\n }\n}\n\n/** This function gives the declaration of one option of a strategy. When the strategy has no such declaration, the function throws an error. */\nfunction declarationOf(strategy: Strategy<Step, object>, key: string): AnyOption {\n const d = schemaOf(strategy)[key];\n if (!d) throw new Error(`The strategy \"${strategy.name}\" has no declaration of the option \"${key}\".`);\n return d;\n}\n\n/**\n * This function gives the settings of a sweep of one option of a strategy, from its declaration only.\n * The name of each setting is the key and the value, for example `stretch 1.5`.\n */\nexport function sweepOf<S extends Step, O extends object>(strategy: Strategy<S, O>, key: keyof O & string, options: SweepOptions = {}): OptionSetting<O>[] {\n return sweepValues(declarationOf(strategy, key), options).map((value) => ({ name: `${key} ${String(value)}`, options: { [key]: value } as Partial<O> }));\n}\n\n/**\n * This function gives the settings of a grid of options: each combination of the values of the sweeps of the keys.\n * The name of a setting joins the names of its values with commas, in the order of the keys.\n */\nexport function sweepGrid<S extends Step, O extends object>(strategy: Strategy<S, O>, keys: readonly (keyof O & string)[], options: SweepOptions = {}): OptionSetting<O>[] {\n let out: OptionSetting<O>[] = [{ name: \"\", options: {} }];\n for (const key of keys) {\n const sweep = sweepOf(strategy, key, options);\n out = out.flatMap((s) => sweep.map((t) => ({ name: s.name === \"\" ? t.name : `${s.name}, ${t.name}`, options: { ...s.options, ...t.options } })));\n }\n return keys.length === 0 ? [] : out;\n}\n\n/** This function gives the problems of one declaration: a bad range, a bad step, or marks and a default that do not fit. */\nfunction declarationIssues(key: string, d: AnyOption): string[] {\n const out: string[] = [];\n if (d.describe.trim().length === 0) out.push(`The option \"${key}\" has no description.`);\n if (d.type === \"number\" || d.type === \"integer\") {\n if (!Number.isFinite(d.min) || !Number.isFinite(d.max) || d.min > d.max) out.push(`The option \"${key}\" has the bad range ${d.min} to ${d.max}.`);\n if (d.type === \"integer\" && (!Number.isInteger(d.min) || !Number.isInteger(d.max))) out.push(`The integer option \"${key}\" has a range that is not whole.`);\n if (d.step !== undefined && !(d.step > 0)) out.push(`The option \"${key}\" has the step ${d.step}. A step is more than 0.`);\n if (d.scale === \"log\" && !(d.min > 0)) out.push(`The option \"${key}\" has the scale log and the min ${d.min}. The scale log needs a min above 0.`);\n for (const v of [...(d.marks ?? []), ...(d.default === undefined ? [] : [d.default])]) {\n const issue = issueOf(key, v, d);\n if (issue) out.push(issue.message);\n }\n } else if (d.type === \"enum\") {\n if (d.values.length === 0) out.push(`The enum option \"${key}\" has no values.`);\n if (d.default !== undefined && !d.values.includes(d.default)) out.push(`The default of the option \"${key}\" is not one of its values.`);\n } else if (d.type === \"boolean\") {\n if (d.default !== undefined && typeof d.default !== \"boolean\") out.push(`The default of the option \"${key}\" is not true or false.`);\n }\n return out;\n}\n\n/**\n * This function examines the schema of a strategy. It gives one message for each option of `defaults` without a declaration.\n * It also gives one message for each bad declaration, and for each value of `defaults` that does not fit its declaration.\n * A good schema gives an empty list.\n */\nexport function checkSchema(strategy: Strategy<Step, object>): string[] {\n const schema = schemaOf(strategy);\n const out: string[] = [];\n for (const key of Object.keys(strategy.defaults)) if (!(key in schema)) out.push(`The strategy \"${strategy.name}\" has the option \"${key}\" in its defaults, without a declaration.`);\n for (const [key, d] of Object.entries(schema)) out.push(...declarationIssues(key, d).map((m) => `The strategy \"${strategy.name}\": ${m}`));\n out.push(...checkOptions(strategy, strategy.defaults).filter((i) => i.problem !== \"unknown\").map((i) => `The strategy \"${strategy.name}\": ${i.message}`));\n return out;\n}\n","import type { CurveSegment } from \"../curves/model.ts\";\nimport type { Graph, Result } from \"../model.ts\";\nimport type { Section } from \"../sections.ts\";\nimport { STRATEGIES } from \"../strategies/builtins.ts\";\nimport { asRouter, getStrategy, listStrategies, type Registry, type Step } from \"../strategies/model.ts\";\nimport { peakCurvature } from \"./curves.ts\";\nimport { paretoFront, type Objective } from \"./measures/pareto.ts\";\nimport { boardUnit } from \"./measures/routes.ts\";\nimport { changeGraph, routeStability } from \"./measures/stability.ts\";\nimport { benchRun } from \"./run.ts\";\nimport { curveRuns, fixtureGroupOptions, FRONT_OBJECTIVES, groupRun, routeMeasures } from \"./suite.ts\";\n\n/** This function gives the median of a list that can hold `Infinity`. An empty list gives 0. */\nfunction medianOf(values: readonly number[]): number {\n if (values.length === 0) return 0;\n const s = [...values].sort((a, b) => a - b);\n const mid = s.length >> 1;\n if (s.length % 2 === 1) return s[mid]!;\n const [a, b] = [s[mid - 1]!, s[mid]!];\n return a === b ? a : (a + b) / 2;\n}\n\n/** The steps that `compareStep` compares. The step `room` takes a packed board, not a graph, so it is not in the list. */\nexport type CompareStep = Exclude<Step, \"room\">;\n\n/** The steps that `compareStep` compares, in the order of the pipeline. */\nexport const COMPARE_STEPS: readonly CompareStep[] = [\"group\", \"router\", \"curve\"];\n\n/** The options of `compareStep`. */\nexport interface CompareOptions {\n /** The strategies of each step. The default is the registry of the built-in strategies. */\n readonly registry?: Registry;\n /** The options of each strategy of the step, by its name. A strategy without an entry gets its defaults. */\n readonly options?: Readonly<Record<string, object>>;\n /** The router whose routes the step `curve` draws. The default is `corners`, as in `runSuite`. */\n readonly curveRouter?: string;\n /** The seed of the small change of the graph for the stability measures (Z10 and G9). The default is 1. */\n readonly seed?: number;\n /** The route stability (Z10) routes a changed graph again, so the function measures it only up to this number of nodes. The default is 1000. */\n readonly stabilityMax?: number;\n /** The name of the graph in the rows. The default is `board`. */\n readonly name?: string;\n}\n\n/** One strategy of one step on one graph: its measures and its output. */\nexport interface CompareRow {\n readonly step: CompareStep;\n readonly strategy: string;\n /** The violations of the hard rules, as `runSuite` counts them. A strategy with a violation does not enter the front. */\n readonly violations: number;\n /** The time of the step, in milliseconds. For the step `router`, it is the median of two routes. */\n readonly ms: number;\n /** The measures, by the keys of `runSuite`, and `ms`. The step `router` adds `ink`, and the step `curve` adds `C5.peak`. */\n readonly values: Readonly<Record<string, number>>;\n /** The reason when the strategy did not run, for example a graph over its `maxNodes`. */\n readonly skipped?: string;\n /** The result of the router, for the steps `router` and `group`. The step `group` routes with `sections` on the tree of the rule. */\n readonly result?: Result;\n /** The tree of the grouping rule, for the step `group`. */\n readonly tree?: Section;\n /** The segments of each curve, for the step `curve`, in the order of `edges`. */\n readonly curves?: readonly CurveSegment[][];\n /** The edge of each curve of `curves`. */\n readonly edges?: readonly string[];\n}\n\n/** The comparison of the strategies of one step on one graph. */\nexport interface StepComparison {\n readonly step: CompareStep;\n /** One row for each strategy of the step, in the order of the registry. */\n readonly rows: readonly CompareRow[];\n /** The axes of the Pareto front: `FRONT_OBJECTIVES` of the step. */\n readonly objectives: readonly Objective[];\n /** The strategies on the Pareto front, in the order of the registry. */\n readonly front: readonly string[];\n /** The strategies with a violation of a hard rule, or that did not run. They do not enter the front. */\n readonly excluded: readonly string[];\n}\n\n/**\n * This function runs each strategy of one step on one graph and measures it with the measures of `runSuite`. Then it gives the Pareto front.\n * The step `router` routes the graph with each router. The step `curve` draws the routes of `curveRouter` with each curve.\n * The step `group` routes the graph with `sections` on the tree of each grouping rule.\n *\n * The same graph and the same options give the same measures. Only the times change.\n */\nexport function compareStep(step: CompareStep, graph: Graph, options: CompareOptions = {}): StepComparison {\n const registry = options.registry ?? STRATEGIES;\n const own = options.options ?? {};\n const name = options.name ?? \"board\";\n const seed = options.seed ?? 1;\n const stabilityMax = options.stabilityMax ?? 1000;\n const at = { fixture: name, seed: 0 };\n let rows: CompareRow[];\n if (step === \"router\") {\n const change = graph.nodes.length <= stabilityMax ? changeGraph(graph, seed) : undefined;\n rows = listStrategies(registry, \"router\").map((strategy): CompareRow => {\n if (graph.nodes.length > (strategy.maxNodes ?? Infinity)) return { step, strategy: strategy.name, violations: 0, ms: 0, values: {}, skipped: `over ${strategy.maxNodes} nodes` };\n const router = asRouter(strategy, own[strategy.name]);\n const { row, result } = benchRun(router, name, graph, 2);\n const values: Record<string, number> = { ...routeMeasures(graph, result, row), ink: row.quality.ink, ms: row.ms };\n if (change) {\n const s = routeStability(graph, result, router.route(change.graph), { seed });\n values[\"Z10.mean\"] = s.mean;\n values[\"Z10.max\"] = s.max;\n values[\"Z10.moved\"] = s.moved;\n }\n return { step, strategy: strategy.name, violations: row.violations + (row.deterministic ? 0 : 1), ms: row.ms, values, result };\n });\n } else if (step === \"curve\") {\n const router = asRouter(getStrategy(registry, \"router\", options.curveRouter ?? \"corners\"));\n const result = router.route(graph);\n const u = boardUnit(graph);\n const runs = curveRuns(graph, result, listStrategies(registry, \"curve\"), {\n ...at,\n smooth: new Set([\"rounded\", \"arc\", \"spline\", \"smooth\", \"clothoid\", \"highway\"]),\n normals: new Set([\"spline\"]),\n curveOptions: own,\n });\n rows = runs.map(({ row, drawn, edges }): CompareRow => {\n const peaks = drawn.map((d) => peakCurvature(d) * u);\n const values = { ...row.values, \"C5.peak\": medianOf(peaks), ms: row.ms };\n return { step, strategy: row.strategy, violations: row.violations, ms: row.ms, values, curves: drawn, edges };\n });\n } else {\n const change = changeGraph(graph, seed);\n rows = listStrategies(registry, \"group\").map((strategy): CompareRow => {\n const opts = { ...fixtureGroupOptions(strategy.name, graph), ...own[strategy.name] };\n const changed = { ...fixtureGroupOptions(strategy.name, change.graph), ...own[strategy.name] };\n const run = groupRun(graph, strategy, opts, { graph: change.graph, options: changed }, at);\n const ms = run.row.treeMs ?? run.row.ms;\n const values = { ...run.row.values, ms };\n return { step, strategy: strategy.name, violations: run.row.violations, ms, values, tree: run.tree, ...(run.result ? { result: run.result } : {}) };\n });\n }\n const objectives = FRONT_OBJECTIVES[step];\n const fair = rows.filter((r) => r.violations === 0 && r.skipped === undefined);\n return {\n step,\n rows,\n objectives,\n front: paretoFront(fair, (r) => r.values, objectives).map((r) => r.strategy),\n excluded: rows.filter((r) => !fair.includes(r)).map((r) => r.strategy),\n };\n}\n"],"mappings":"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"}