@ixfx/components 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.d.ts +50 -27
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +82 -38
- package/bundle/index.js.map +1 -1
- package/dist/{icon-epZd-JIO.d.ts → icon-Bd5BiU4b.d.ts} +2 -2
- package/dist/{icon-epZd-JIO.d.ts.map → icon-Bd5BiU4b.d.ts.map} +1 -1
- package/dist/icons.d.ts +1 -1
- package/dist/{index-JuEVfmr-.d.ts → index-s_IhSnwc.d.ts} +2 -2
- package/dist/{index-JuEVfmr-.d.ts.map → index-s_IhSnwc.d.ts.map} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{labelled-input-base-Cz6qE6Dk.d.ts → labelled-input-base-ORb1rGq6.d.ts} +2 -2
- package/dist/{labelled-input-base-Cz6qE6Dk.d.ts.map → labelled-input-base-ORb1rGq6.d.ts.map} +1 -1
- package/dist/labelled-radial-input.d.ts +2 -2
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/plots.d.ts +1 -1
- package/dist/plots.js +1 -1
- package/dist/{xy-axis-CEI7ojks.d.ts → xy-axis-BeWRMmbo.d.ts} +46 -23
- package/dist/xy-axis-BeWRMmbo.d.ts.map +1 -0
- package/dist/{xy-axis-DbPezP6A.js → xy-axis-no0OL_O1.js} +83 -39
- package/dist/xy-axis-no0OL_O1.js.map +1 -0
- package/package.json +2 -2
- package/dist/xy-axis-CEI7ojks.d.ts.map +0 -1
- package/dist/xy-axis-DbPezP6A.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xy-axis-DbPezP6A.js","names":["__defProp","__exportAll","getPointParameter","Empty","piPi","length","interpolate","interpolator","length","guard","isPositioned","guardPositioned","pow","pi$1","pi","abs","sqrt","min","max","cos","sin","interpolator","interpolate","distanceFromExterior","__defProp","__exportAll","#store","#disposed","#listeners","isPositioned","last","max","min","last","max","min","min$3","max$3","last$2","last$1","#data","Queues","getPointParameter","isEqual$1","distanceFromExterior$1","distanceFromExterior","distance$1","interpolator$1","multiply$2","pi","subtract$2","angleRadian$1","rotate$2","average","bbox$1","guard","isPlaceholder$1","sum$2","toString$2","Points","Beziers","Flow.ofTotal","Flow.elapsedMillisecondsAbsolute","Flow.relative","Flow.timerWithFunction","Flow.ofTotalTicks","Flow.elapsedTicksAbsolute","Colour","Easings","#options","#rangeStream","#recompute","#addToSeries","#ensurePlot","#seriesSet","#seriesOrder","#instances","#pendingStyles","#onSubPlotPointerMove","#onSubPlotPointerLeave","#escapeHTML","customElement","#hasProgrammaticData","#series","#parseDeclarativeData","#readCssVar","#getGapPx","#getBarLengthOverride","#emitClick","customElement","#lastClientX","#lastClientY","#updateTooltip","#getIndexFromX","#series","#hasProgrammaticData","#updateTooltipAtLastPos","#parseDeclarativeData","#computePoints","#renderByStyle","#onPointerMove","#onPointerLeave","#onClick","customElement","#lastClientX","#lastClientY","#updateTooltip","#findNearestPoint","#lastPoints","#xSeries","#ySeries","#updateTooltipAtLastPos","#computePoints","#computeColours","#onPointerMove","#onPointerLeave","#onClick","customElement"],"sources":["../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/chunk-pbuEa-1d.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/to-oKNQeMO-.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/polar-ZdU4ci-4.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/from-points-hWl1SWEr.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/max-NDZ04wx6.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/bbox-BH5rnhlc.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/guard-Bg57Xzmd.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/length-ChosppvJ.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/interpolate-DhLKNStN.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/guard-C2opUnGy.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/from-top-left-D_I93JN9.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/guard-D8jtfB4t.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/bezier-NMQ88x8M.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/intersects-BOuj4lnQ.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/multiply-CwzF4Hcr.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/is-equal-BS9hk_L_.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/compare-DzZYeaAF.js","../node_modules/.pnpm/@ixfx+core@0.56.13/node_modules/@ixfx/core/dist/is-equal-BOIjfI3O.js","../node_modules/.pnpm/@ixfx+core@0.56.13/node_modules/@ixfx/core/dist/maps-D25APhug.js","../node_modules/.pnpm/@ixfx+collections@0.56.13/node_modules/@ixfx/collections/dist/chunk-ZRW5x4aP.js","../node_modules/.pnpm/@ixfx+core@0.56.13/node_modules/@ixfx/core/dist/text-CovhuGNs.js","../node_modules/.pnpm/@ixfx+core@0.56.13/node_modules/@ixfx/core/dist/src-C6LGm3yY.js","../node_modules/.pnpm/@ixfx+events@0.56.13/node_modules/@ixfx/events/dist/index.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/join-points-to-lines-CEdHRF9i.js","../node_modules/.pnpm/@ixfx+collections@0.56.13/node_modules/@ixfx/collections/dist/queue-mutable-lrZyCqgq.js","../node_modules/.pnpm/@ixfx+iterables@0.56.13/node_modules/@ixfx/iterables/dist/guard-COHp1bP0.js","../node_modules/.pnpm/@ixfx+iterables@0.56.13/node_modules/@ixfx/iterables/dist/sync-CP_0yIYe.js","../node_modules/.pnpm/@ixfx+iterables@0.56.13/node_modules/@ixfx/iterables/dist/async.js","../node_modules/.pnpm/@ixfx+iterables@0.56.13/node_modules/@ixfx/iterables/dist/index.js","../node_modules/.pnpm/@ixfx+collections@0.56.13/node_modules/@ixfx/collections/dist/priority-mutable-C9pMxKNT.js","../node_modules/.pnpm/@ixfx+collections@0.56.13/node_modules/@ixfx/collections/dist/queue-CCn_cD23.js","../node_modules/.pnpm/@ixfx+flow@0.56.13/node_modules/@ixfx/flow/dist/index.js","../node_modules/.pnpm/@ixfx+trackers@0.56.13/node_modules/@ixfx/trackers/dist/index.js","../node_modules/.pnpm/@ixfx+geometry@0.56.13/node_modules/@ixfx/geometry/dist/line-DZj7hi4y.js","../node_modules/.pnpm/@ixfx+modulation@0.56.13/node_modules/@ixfx/modulation/dist/chunk-pbuEa-1d.js","../node_modules/.pnpm/@ixfx+modulation@0.56.13/node_modules/@ixfx/modulation/dist/easing-BCATR3oC.js","../src/plots/colour-map.ts","../src/plots/data.ts","../src/plots/svg-utils.ts","../src/plots/multi-axis.ts","../src/plots/plot-histogram.ts","../src/plots/single-axis.ts","../src/plots/xy-axis.ts"],"sourcesContent":["//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __exportAll = (all, no_symbols) => {\n\tlet target = {};\n\tfor (var name in all) __defProp(target, name, {\n\t\tget: all[name],\n\t\tenumerable: true\n\t});\n\tif (!no_symbols) __defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\treturn target;\n};\n//#endregion\nexport { __exportAll as t };\n","import { c as isPoint3d, s as isPoint, t as guard } from \"./guard-hlhkAOMZ.js\";\n//#region src/point/get-point-parameter.ts\nfunction getTwoPointParameters(a1, ab2, ab3, ab4, ab5, ab6) {\n\tif (isPoint3d(a1) && isPoint3d(ab2)) return [a1, ab2];\n\tif (isPoint(a1) && isPoint(ab2)) return [a1, ab2];\n\tif (isPoint3d(a1)) {\n\t\tconst b = {\n\t\t\tx: ab2,\n\t\t\ty: ab3,\n\t\t\tz: ab4\n\t\t};\n\t\tif (!isPoint3d(b)) throw new Error(`Expected x, y & z parameters`);\n\t\treturn [a1, b];\n\t}\n\tif (isPoint(a1)) {\n\t\tconst b = {\n\t\t\tx: ab2,\n\t\t\ty: ab3\n\t\t};\n\t\tif (!isPoint(b)) throw new Error(`Expected x & y parameters`);\n\t\treturn [a1, b];\n\t}\n\tif (typeof ab5 !== `undefined` && typeof ab4 !== `undefined`) {\n\t\tconst a = {\n\t\t\tx: a1,\n\t\t\ty: ab2,\n\t\t\tz: ab3\n\t\t};\n\t\tconst b = {\n\t\t\tx: ab4,\n\t\t\ty: ab5,\n\t\t\tz: ab6\n\t\t};\n\t\tif (!isPoint3d(a)) throw new Error(`Expected x,y,z for first point`);\n\t\tif (!isPoint3d(b)) throw new Error(`Expected x,y,z for second point`);\n\t\treturn [a, b];\n\t}\n\tconst a = {\n\t\tx: a1,\n\t\ty: ab2\n\t};\n\tconst b = {\n\t\tx: ab3,\n\t\ty: ab4\n\t};\n\tif (!isPoint(a)) throw new Error(`Expected x,y for first point`);\n\tif (!isPoint(b)) throw new Error(`Expected x,y for second point`);\n\treturn [a, b];\n}\n/**\n* Returns a Point form of either a point, x,y params or x,y,z params.\n* If parameters are undefined, an empty point is returned (0, 0)\n* @ignore\n* @param a\n* @param b\n* @returns\n*/\nfunction getPointParameter(a, b, c) {\n\tif (a === void 0) return {\n\t\tx: 0,\n\t\ty: 0\n\t};\n\tif (Array.isArray(a)) {\n\t\tif (a.length === 0) return Object.freeze({\n\t\t\tx: 0,\n\t\t\ty: 0\n\t\t});\n\t\tif (a.length === 1) return Object.freeze({\n\t\t\tx: a[0],\n\t\t\ty: 0\n\t\t});\n\t\tif (a.length === 2) return Object.freeze({\n\t\t\tx: a[0],\n\t\t\ty: a[1]\n\t\t});\n\t\tif (a.length === 3) return Object.freeze({\n\t\t\tx: a[0],\n\t\t\ty: a[1],\n\t\t\tz: a[2]\n\t\t});\n\t\tthrow new Error(`Expected array to be 1-3 elements in length. Got ${a.length}.`);\n\t}\n\tif (isPoint(a)) return a;\n\telse if (typeof a !== `number` || typeof b !== `number`) throw new TypeError(`Expected point or x,y as parameters. Got: a: ${JSON.stringify(a)} b: ${JSON.stringify(b)}`);\n\tif (typeof c === `number`) return Object.freeze({\n\t\tx: a,\n\t\ty: b,\n\t\tz: c\n\t});\n\treturn Object.freeze({\n\t\tx: a,\n\t\ty: b\n\t});\n}\n//#endregion\n//#region src/point/distance.ts\n/**\n* Calculate distance between two points.\n* If both points have a `z` property, the distance is 3D distance is calculated.\n* If only one point has a `z`, it is ignored. To force 2D distance, use {@link distance2d}\n*\n* ```js\n* // Distance between two points\n* const ptA = { x: 0.5, y:0.8 };\n* const ptB = { x: 1, y: 0.4 };\n* distance(ptA, ptB);\n* // Or, provide x,y as parameters\n* distance(ptA, 0.4, 0.9);\n*\n* // Distance from ptA to x: 0.5, y:0.8, z: 0.1\n* const ptC = { x: 0.5, y:0.5, z: 0.3 };\n* // With x,y,z as parameters:\n* distance(ptC, 0.5, 0.8, 0.1);\n* ```\n* @param a First point\n* @param xOrB Second point, or x coord\n* @param y y coord, if x coord is given\n* @param z Optional z coord, if x and y are given.\n* @returns\n*/\nfunction distance(a, xOrB, y, z) {\n\tconst pt = getPointParameter(xOrB, y, z);\n\tguard(pt, `b`);\n\tguard(a, `a`);\n\treturn isPoint3d(pt) && isPoint3d(a) ? Math.hypot(pt.x - a.x, pt.y - a.y, pt.z - a.z) : Math.hypot(pt.x - a.x, pt.y - a.y);\n}\n/**\n* As {@link distance} but always compares by x,y only.\n* @param a\n* @param xOrB \n* @param y\n* @returns \n*/\nfunction distance2d(a, xOrB, y) {\n\tconst pt = getPointParameter(xOrB, y);\n\tguard(pt, `b`);\n\tguard(a, `a`);\n\treturn Math.hypot(pt.x - a.x, pt.y - a.y);\n}\n//#endregion\n//#region src/point/subtract.ts\n/**\n* Returns a Point with the x,y,z values of two points subtracted (a-b).\n* \n* `z` parameter is used if present. Uses a default value of 0 for 'z' when subtracting a 2D point with a 3D one.\n*\n* Examples:\n*\n* ```js\n* subtract(ptA, ptB);\n* subtract(x1, y1, x2, y2);\n* subtract(ptA, x2, y2);\n* ```\n*/\nfunction subtract(a1, ab2, ab3, ab4, ab5, ab6) {\n\tconst [ptA, ptB] = getTwoPointParameters(a1, ab2, ab3, ab4, ab5, ab6);\n\tguard(ptA, `a`);\n\tguard(ptB, `b`);\n\tconst pt = {\n\t\tx: ptA.x - ptB.x,\n\t\ty: ptA.y - ptB.y\n\t};\n\tif (isPoint3d(ptA) || isPoint3d(ptB)) pt.z = (ptA.z ?? 0) - (ptB.z ?? 0);\n\treturn Object.freeze(pt);\n}\n//#endregion\n//#region src/point/to.ts\n/**\n* Returns a point with rounded x,y coordinates. By default uses `Math.round` to round.\n* ```js\n* toIntegerValues({x:1.234, y:5.567}); // Yields: {x:1, y:6}\n* ```\n*\n* ```js\n* toIntegerValues(pt, Math.ceil); // Use Math.ceil to round x,y of `pt`.\n* ```\n* @param pt Point to round\n* @param rounder Rounding function, or Math.round by default\n* @returns\n*/\nconst toIntegerValues = (pt, rounder = Math.round) => {\n\tguard(pt, `pt`);\n\treturn Object.freeze({\n\t\tx: rounder(pt.x),\n\t\ty: rounder(pt.y)\n\t});\n};\n/**\n* Returns a copy of `pt` with `z` field omitted.\n* If it didn't have one to begin within, a copy is still returned.\n* @param pt \n* @returns \n*/\nconst to2d = (pt) => {\n\tguard(pt, `pt`);\n\tlet copy = { ...pt };\n\tdelete copy.z;\n\treturn Object.freeze(copy);\n};\n/**\n* Returns a copy of `pt` with a `z` field set.\n* Defaults to a z value of 0.\n* @param pt Point\n* @param z Z-value, defaults to 0\n* @returns \n*/\nconst to3d = (pt, z = 0) => {\n\tguard(pt, `pt`);\n\treturn Object.freeze({\n\t\t...pt,\n\t\tz\n\t});\n};\n/**\n* Returns a human-friendly string representation `(x, y)`.\n* If `precision` is supplied, this will be the number of significant digits.\n* @param p\n* @returns\n*/\nfunction toString(p, digits) {\n\tif (p === void 0) return `(undefined)`;\n\tif (p === null) return `(null)`;\n\tguard(p, `pt`);\n\tconst x = digits ? p.x.toFixed(digits) : p.x;\n\tconst y = digits ? p.y.toFixed(digits) : p.y;\n\tif (p.z === void 0) return `(${x},${y})`;\n\telse return `(${x},${y},${digits ? p.z.toFixed(digits) : p.z})`;\n}\n//#endregion\nexport { subtract as a, getPointParameter as c, toString as i, getTwoPointParameters as l, to3d as n, distance as o, toIntegerValues as r, distance2d as s, to2d as t };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { A as piPi, S as radiansNormalise, _ as radianToDegree, b as radiansBetweenCircular, g as radianRange, o as degreeToRadian } from \"./angles-BkBEzlEN.js\";\nimport { s as isPoint, t as guard$1 } from \"./guard-hlhkAOMZ.js\";\nimport { a as subtract, i as toString$2, o as distance } from \"./to-oKNQeMO-.js\";\nimport { numberTest, resultThrow } from \"@ixfx/guards\";\n//#region src/polar/guard.ts\n/**\n* Returns true if `p` seems to be a {@link Polar.Coord} (ie has both distance & angleRadian fields)\n* @param p\n* @returns True if `p` seems to be a PolarCoord\n*/\nconst isPolarCoord = (p) => {\n\tif (p.distance === void 0) return false;\n\tif (p.angleRadian === void 0) return false;\n\treturn true;\n};\n/**\n* Throws an error if Coord is invalid\n* @param p\n* @param name\n*/\nconst guard = (p, name = `Point`) => {\n\tif (p === void 0) throw new Error(`'${name}' is undefined. Expected {distance, angleRadian} got ${JSON.stringify(p)}`);\n\tif (p === null) throw new Error(`'${name}' is null. Expected {distance, angleRadian} got ${JSON.stringify(p)}`);\n\tif (p.angleRadian === void 0) throw new Error(`'${name}.angleRadian' is undefined. Expected {distance, angleRadian} got ${JSON.stringify(p)}`);\n\tif (p.distance === void 0) throw new Error(`'${name}.distance' is undefined. Expected {distance, angleRadian} got ${JSON.stringify(p)}`);\n\tif (typeof p.angleRadian !== `number`) throw new TypeError(`'${name}.angleRadian' must be a number. Got ${p.angleRadian}`);\n\tif (typeof p.distance !== `number`) throw new TypeError(`'${name}.distance' must be a number. Got ${p.distance}`);\n\tif (p.angleRadian === null) throw new Error(`'${name}.angleRadian' is null`);\n\tif (p.distance === null) throw new Error(`'${name}.distance' is null`);\n\tif (Number.isNaN(p.angleRadian)) throw new TypeError(`'${name}.angleRadian' is NaN`);\n\tif (Number.isNaN(p.distance)) throw new Error(`'${name}.distance' is NaN`);\n};\n//#endregion\n//#region src/polar/angles.ts\n/**\n* Returns a rotated coordinate\n* @param c Coordinate\n* @param amountRadian Amount to rotate, in radians\n* @returns\n*/\nconst rotate = (c, amountRadian) => Object.freeze({\n\t...c,\n\tangleRadian: c.angleRadian + amountRadian\n});\n/**\n* Inverts the direction of coordinate. Ie if pointing north, will point south.\n* @param p\n* @returns\n*/\nconst invert = (p) => {\n\tguard(p, `c`);\n\treturn Object.freeze({\n\t\t...p,\n\t\tangleRadian: p.angleRadian - Math.PI\n\t});\n};\n/**\n* Returns true if PolarCoords have same magnitude but opposite direction\n* @param a\n* @param b\n* @returns\n*/\nconst isOpposite = (a, b) => {\n\tguard(a, `a`);\n\tguard(b, `b`);\n\tif (a.distance !== b.distance) return false;\n\treturn a.angleRadian === -b.angleRadian;\n};\n/**\n* Returns true if Coords have the same direction, regardless of magnitude\n* @param a\n* @param b\n* @returns\n*/\nconst isParallel$1 = (a, b) => {\n\tguard(a, `a`);\n\tguard(b, `b`);\n\treturn a.angleRadian === b.angleRadian;\n};\n/**\n* Returns true if coords are opposite direction, regardless of magnitude\n* @param a\n* @param b\n* @returns\n*/\nconst isAntiParallel = (a, b) => {\n\tguard(a, `a`);\n\tguard(b, `b`);\n\treturn a.angleRadian === -b.angleRadian;\n};\n/**\n* Returns a rotated coordinate\n* @param c Coordinate\n* @param amountDeg Amount to rotate, in degrees\n* @returns\n*/\nconst rotateDegrees = (c, amountDeg) => Object.freeze({\n\t...c,\n\tangleRadian: c.angleRadian + degreeToRadian(amountDeg)\n});\n//#endregion\n//#region src/point/empty.ts\n/**\n* An empty point of `{ x: 0, y: 0 }`.\n*\n* Use `isEmpty` to check if a point is empty.\n* Use `Empty3d` to get an empty point with `z`.\n*/\nconst Empty = {\n\tx: 0,\n\ty: 0\n};\n/**\n* Returns { x:1, y:1 }\n*/\nconst Unit = {\n\tx: 1,\n\ty: 1\n};\n/**\n* An empty Point of `{ x: 0, y: 0, z: 0}`\n* Use `isEmpty` to check if a point is empty.\n* Use `Empty` to get an empty point without `z`.\n*/\nconst Empty3d = {\n\tx: 0,\n\ty: 0,\n\tz: 0\n};\n/**\n* Returns { x:1,y:1,z:1 }\n*/\nconst Unit3d = {\n\tx: 1,\n\ty: 1,\n\tz: 1\n};\n//#endregion\n//#region src/polar/conversions.ts\n/**\n* Converts a polar coordinate to a Line.\n* \n* ```js\n* const line = toLine({ angleRadian: Math.Pi, distance: 0.5 }, { x: 0.2, y: 0.1 });\n* // Yields { a: { x, y}, b: { x, y } }\n* ```\n* \n* The 'start' parameter is taken to be the origin of the Polar coordinate.\n* @param c \n* @param start \n* @returns \n*/\nconst toLine = (c, start) => {\n\treturn {\n\t\ta: start,\n\t\tb: toCartesian$1(c, start)\n\t};\n};\n/**\n* Converts to Cartesian coordinate from polar.\n*\n* ```js\n*\n* const origin = { x: 50, y: 50}; // Polar origin\n* // Yields: { x, y }\n* const polar = Polar.toCartesian({ distance: 10, angleRadian: 0 }, origin);\n* ```\n*\n* Distance and angle can be provided as numbers intead:\n*\n* ```\n* // Yields: { x, y }\n* const polar = Polar.toCartesian(10, 0, origin);\n* ```\n*\n* @param a\n* @param b\n* @param c\n* @returns\n*/\nconst toCartesian$1 = (a, b, c) => {\n\tif (isPolarCoord(a)) {\n\t\tif (typeof b === `undefined`) b = Empty;\n\t\tif (isPoint(b)) return polarToCartesian(a.distance, a.angleRadian, b);\n\t\tthrow new Error(`Expecting (Coord, Point). Second parameter is not a point`);\n\t} else if (typeof a === `object`) throw new TypeError(`First param is an object, but not a Coord: ${JSON.stringify(a)}`);\n\telse if (typeof a === `number` && typeof b === `number`) {\n\t\tif (typeof c === `undefined`) c = Empty;\n\t\tif (!isPoint(c)) throw new Error(`Expecting (number, number, Point). Point param wrong type`);\n\t\treturn polarToCartesian(a, b, c);\n\t} else throw new TypeError(`Expecting parameters of (number, number). Got: (${typeof a}, ${typeof b}, ${typeof c}). a: ${JSON.stringify(a)}`);\n};\n/**\n* Converts a Cartesian coordinate to polar\n*\n* ```js\n*\n* // Yields: { angleRadian, distance }\n* const polar = Polar.fromCartesian({x: 50, y: 50}, origin);\n* ```\n*\n* Any additional properties of `point` are copied to object.\n* \n* Options:\n* * fullCircle: If _true_ (default) returns values on 0..2PI range. If _false_, 0....PI..-PI range.\n* * digits: Rounding to apply\n* @param point Point\n* @param origin Origin. If unspecified, {x:0,y:0} is used\n* @param options Options\n* @returns\n*/\nconst fromCartesian = (point, origin, options = {}) => {\n\tif (typeof point !== `object`) throw new TypeError(`Param 'point' wrong. Expecting a Point, got: ${typeof point}`);\n\tconst fullCircle = options.fullCircle ?? true;\n\tif (typeof origin === `object`) point = subtract(point, origin);\n\tlet angle = Math.atan2(point.y, point.x);\n\tif (fullCircle) angle = radiansNormalise(angle);\n\tlet distance = Math.hypot(point.x, point.y);\n\tif (typeof options.digits === `number`) {\n\t\tangle = parseFloat(angle.toFixed(options.digits));\n\t\tdistance = parseFloat(distance.toFixed(options.digits));\n\t}\n\tconst polar = {\n\t\t...point,\n\t\tangleRadian: angle,\n\t\tdistance\n\t};\n\tdelete polar.x;\n\tdelete polar.y;\n\treturn Object.freeze(polar);\n};\n/**\n* Converts a polar coordinate to Cartesian\n* @param distance Distance\n* @param angleRadians Angle in radians\n* @param origin Origin, or 0,0 by default.\n* @returns\n*/\nconst polarToCartesian = (distance, angleRadians, origin = Empty) => {\n\tguard$1(origin);\n\treturn Object.freeze({\n\t\tx: origin.x + distance * Math.cos(angleRadians),\n\t\ty: origin.y + distance * Math.sin(angleRadians)\n\t});\n};\n/**\n* Returns a human-friendly string representation `(distance, angleDeg)`.\n* If `precision` is supplied, this will be the number of significant digits.\n* @param p\n* @returns\n*/\nconst toString$1 = (p, digits) => {\n\tif (p === void 0) return `(undefined)`;\n\tif (p === null) return `(null)`;\n\tconst angleDeg = radianToDegree(p.angleRadian);\n\treturn `(${digits ? p.distance.toFixed(digits) : p.distance},${digits ? angleDeg.toFixed(digits) : angleDeg})`;\n};\nconst toPoint = (v, origin = Empty) => {\n\tguard(v, `v`);\n\treturn Object.freeze({\n\t\tx: origin.x + v.distance * Math.cos(v.angleRadian),\n\t\ty: origin.y + v.distance * Math.sin(v.angleRadian)\n\t});\n};\n/**\n* Converts a line to a PolarLine\n* \n* A/B points of the line can optionally be reordered based on angle or distance.\n* @param lineOrLines \n* @param origin \n* @param orderBy Whether a/b points are reordered based on `angle` or `distance`. Default: `none`\n* @returns \n*/\nfunction toPolarLine(lineOrLines, origin, opts = {}) {\n\tconst lines = Array.isArray(lineOrLines) ? lineOrLines : [lineOrLines];\n\tif (lines.length === 0) return [];\n\tconst orderBy = opts.orderBy ?? `none`;\n\tconst pl = lines.map((line) => {\n\t\tlet a = fromCartesian(line.a, origin, opts);\n\t\tlet b = fromCartesian(line.b, origin, opts);\n\t\tconst ranges = radianRange(a.angleRadian, b.angleRadian);\n\t\tif (orderBy === `angle-min` && ranges.min.start !== a.angleRadian) [a, b] = [b, a];\n\t\telse if (orderBy === `angle-max` && ranges.max.start < a.angleRadian) [a, b] = [b, a];\n\t\telse if (orderBy === `distance` && b.distance < a.distance) [a, b] = [b, a];\n\t\treturn Object.freeze({\n\t\t\ta,\n\t\t\tb,\n\t\t\torigin\n\t\t});\n\t});\n\tif (Array.isArray(lineOrLines)) return pl;\n\treturn pl[0];\n}\n/**\n* Returns a string representation of a PolarLine\n* @param line \n* @param digits \n* @returns \n*/\nfunction polarLineToString(line, digits = 2) {\n\treturn `angle: ${line.a.angleRadian.toFixed(digits)}-${line.b.angleRadian.toFixed(digits)} dist: ${line.a.distance.toFixed(digits)}-${line.b.distance.toFixed(digits)}`;\n}\nfunction lineToCartesian(lineOrLines, origin) {\n\tconst lines = Array.isArray(lineOrLines) ? lineOrLines : [lineOrLines];\n\tif (lines.length === 0) return [];\n\tconst cart = lines.map((line) => Object.freeze({\n\t\ta: toCartesian$1(line.a, origin),\n\t\tb: toCartesian$1(line.b, origin)\n\t}));\n\tif (Array.isArray(lineOrLines)) return cart;\n\treturn cart[0];\n}\n//#endregion\n//#region src/polar/math.ts\nconst normalise = (c) => {\n\tif (c.distance === 0) throw new Error(`Cannot normalise vector of length 0`);\n\treturn Object.freeze({\n\t\t...c,\n\t\tdistance: 1\n\t});\n};\n/**\n* Clamps the magnitude of a vector\n* @param v\n* @param max\n* @param min\n* @returns\n*/\nconst clampMagnitude = (v, max = 1, min = 0) => {\n\tlet mag = v.distance;\n\tif (mag > max) mag = max;\n\tif (mag < min) mag = min;\n\treturn Object.freeze({\n\t\t...v,\n\t\tdistance: mag\n\t});\n};\n/**\n* Calculate dot product of two PolarCoords.\n*\n* Eg, power is the dot product of force and velocity\n*\n* Dot products are also useful for comparing similarity of\n* angle between two unit PolarCoords.\n* @param a\n* @param b\n* @returns\n*/\nconst dotProduct = (a, b) => {\n\tguard(a, `a`);\n\tguard(b, `b`);\n\treturn a.distance * b.distance * Math.cos(b.angleRadian - a.angleRadian);\n};\n/**\n* Multiplies the magnitude of a coord by `amt`.\n* Direction is unchanged.\n* @param v\n* @param amt\n* @returns\n*/\nconst multiply = (v, amt) => {\n\tguard(v);\n\tresultThrow(numberTest(amt, ``, `amt`));\n\treturn Object.freeze({\n\t\t...v,\n\t\tdistance: v.distance * amt\n\t});\n};\n/**\n* Divides the magnitude of a coord by `amt`.\n* Direction is unchanged.\n* @param v\n* @param amt\n* @returns\n*/\nconst divide = (v, amt) => {\n\tguard(v);\n\tresultThrow(numberTest(amt, ``, `amt`));\n\treturn Object.freeze({\n\t\t...v,\n\t\tdistance: v.distance / amt\n\t});\n};\n/**\n* Returns _true_ if `check` is between `start` and `end` angles.\n* @param start \n* @param end \n* @param check \n* @returns \n*/\nconst between = (check, start, end) => {\n\treturn radiansBetweenCircular(check.angleRadian, start.angleRadian, end.angleRadian);\n};\n//#endregion\n//#region src/point/angle.ts\n/**\n* Returns the angle in radians between `a` and `b`.\n*\n* Eg if `a` is the origin, and `b` is another point,\n* in degrees one would get 0 to -180 when `b` was above `a`.\n* -180 would be `b` in line with `a`.\n* Same for under `a`.\n*\n* Providing a third point `c` gives the interior angle, where `b` is the middle point.\n* \n* See also {@link angleRadianCircle} which returns coordinates on 0..Math.Pi*2\n* range. This avoids negative numbers.\n* \n* @example Calculate angle between a middle of canvas and the cursor\n* ```js\n* const canvasEl = document.querySelector('canvas');\n* const middle = { x: canvasEl.width/2, y: canvasEl.height /2 }\n* \n* canvasEl.addEventListener(`pointermove`, event => { \n* const cursor = {\n* x: event.offsetX,\n* y: event.offsetY\n* }\n* const a = G.Points.angleRadian(middle, cursor);\n*});\n* ```\n* @param a\n* @param b\n* @param c\n* @returns\n*/\nconst angleRadian = (a, b, c) => {\n\tguard$1(a, `a`);\n\tif (b === void 0) return Math.atan2(a.y, a.x);\n\tguard$1(b, `b`);\n\tif (c === void 0) return Math.atan2(b.y - a.y, b.x - a.x);\n\tguard$1(c, `c`);\n\treturn Math.atan2(b.y - a.y, b.x - a.x) - Math.atan2(c.y - a.y, c.x - a.x);\n};\n/**\n* Returns the angle between point(s) using a radian circle system.\n* ```\n* 90deg\n* Pi/2\n* |\n* Pi ---+--- 0\n* 180 |\n* 3PI/2\n* 270deg\n* ```\n* @param a \n* @param b \n* @param c \n* @returns \n*/\nconst angleRadianCircle = (a, b, c) => {\n\tconst angle = angleRadian(a, b, c);\n\tif (angle < 0) return angle + piPi;\n\treturn angle;\n};\n/**\n* Return the angle of a wedge, defined by a, b and C points, where 'b'\n* could be thought of as the origin or pivot.\n* \n* @param a \n* @param b \n* @param c \n* @returns \n*/\nconst angleRadianThreePoint = (a, b, c) => {\n\tconst ab = Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2));\n\tconst bc = Math.sqrt(Math.pow(b.x - c.x, 2) + Math.pow(b.y - c.y, 2));\n\tconst ac = Math.sqrt(Math.pow(c.x - a.x, 2) + Math.pow(c.y - a.y, 2));\n\treturn Math.acos((bc * bc + ab * ab - ac * ac) / (2 * bc * ab));\n};\n//#endregion\n//#region src/polar/ray.ts\nvar ray_exports = /* @__PURE__ */ __exportAll({\n\tfromLine: () => fromLine,\n\tisParallel: () => isParallel,\n\ttoCartesian: () => toCartesian,\n\ttoString: () => toString\n});\n/**\n* Converts a ray (or array of rays) to a Line in cartesian coordinates.\n* \n* By default, the ray's origin is taken to be 0,0.\n* Passing in an origin will override this default, or whatever\n* the ray's origin property is.\n* @param ray Ray\n* @param origin Override or provide origin point\n* @returns \n*/\nfunction toCartesian(rayOrRays, origin) {\n\tconst rays = Array.isArray(rayOrRays) ? rayOrRays : [rayOrRays];\n\tif (rays.length === 0) return [];\n\tconst lines = rays.map((ray) => {\n\t\tconst o = getOrigin(ray, origin);\n\t\treturn {\n\t\t\ta: toCartesian$1(ray.offset ?? 0, ray.angleRadian, o),\n\t\t\tb: toCartesian$1((ray.offset ?? 0) + ray.length, ray.angleRadian, o)\n\t\t};\n\t});\n\tif (Array.isArray(rayOrRays)) return lines;\n\treturn lines[0];\n}\nconst isParallel = (a, b) => a.angleRadian === b.angleRadian;\nconst getOrigin = (ray, origin) => {\n\tif (origin !== void 0) return origin;\n\tif (ray.origin !== void 0) return ray.origin;\n\treturn {\n\t\tx: 0,\n\t\ty: 0\n\t};\n};\n/**\n* Returns a string representation of the ray, useful for debugging.\n* \n* ```js\n* \"PolarRay(angle: ... offset: ... len: ... origin: ...)\"\n* ```\n* @param ray \n* @returns \n*/\nconst toString = (ray) => {\n\tlet basic = `PolarRay(angle: ${ray.angleRadian} offset: ${ray.offset} len: ${ray.length}`;\n\tif (ray.origin) basic += ` origin: ${toString$2(ray.origin)}`;\n\tbasic += `)`;\n\treturn basic;\n};\n/**\n* Returns a PolarRay based on a line(s) and origin.\n* \n* If `origin` is omitted, the origin is taken to be the 'a' point of the line.\n* Otherwise, the origin value is used to determine the 'offset' of the ray.\n* \n* @param lineOrLines Single line or array of lines \n* @param origin \n* @returns \n*/\nfunction fromLine(lineOrLines, origin) {\n\tconst lines = Array.isArray(lineOrLines) ? lineOrLines : [lineOrLines];\n\tif (lines.length === 0) return [];\n\tconst rays = lines.map((line) => {\n\t\tif (origin) return {\n\t\t\tangleRadian: angleRadian(line.a, origin),\n\t\t\toffset: distance(line.a, origin),\n\t\t\tlength: distance(line.b, line.a),\n\t\t\torigin\n\t\t};\n\t\telse return {\n\t\t\tangleRadian: angleRadian(line.a, line.b),\n\t\t\tlength: distance(line.b, line.a),\n\t\t\torigin: line.a\n\t\t};\n\t});\n\tif (Array.isArray(lineOrLines)) return rays;\n\treturn rays[0];\n}\n//#endregion\n//#region src/polar/spiral.ts\nfunction* spiral(smoothness, zoom) {\n\tlet step = 0;\n\twhile (true) {\n\t\tconst a = smoothness * step++;\n\t\tyield {\n\t\t\tdistance: zoom * a,\n\t\t\tangleRadian: a,\n\t\t\tstep\n\t\t};\n\t}\n}\n/**\n* Produces an Archimedian spiral with manual stepping.\n* @param step Step number. Typically 0, 1, 2 ...\n* @param smoothness 0.1 pretty rounded, at around 5 it starts breaking down\n* @param zoom At smoothness 0.1, zoom starting at 1 is OK\n* @returns\n*/\nconst spiralRaw = (step, smoothness, zoom) => {\n\tconst a = smoothness * step;\n\treturn Object.freeze({\n\t\tdistance: zoom * a,\n\t\tangleRadian: a\n\t});\n};\n//#endregion\n//#region src/polar/intersects.ts\n/**\n* Returns a generator function that checks for intersections with a static set of lines.\n* The generator yields values of `{ distance: number, line: PolarLine }`. Lines which have no\n* intersecton are not returned.\n* \n* ```js\n* const c = intersectionDistanceCompute(line1, line2, line3);\n* \n* // Get all results for angle 0.2 as an array\n* const computed = [...c.compute(0.2)]\n* \n* // Sort array by distance (ascending)\n* computed.sort((a, b) => a.distance - b.distance);\n* ```\n* @param lines \n* @returns \n*/\nconst intersectionDistanceCompute = (...lines) => {\n\tconst precompute = (line) => {\n\t\tconst angleMin = Math.min(line.a.angleRadian, line.b.angleRadian);\n\t\tconst angleMax = Math.max(line.a.angleRadian, line.b.angleRadian);\n\t\treturn {\n\t\t\t...line,\n\t\t\tsinBA: Math.sin(line.b.angleRadian - line.a.angleRadian),\n\t\t\tangleMin,\n\t\t\tangleMax,\n\t\t\twraps: Math.abs(line.b.angleRadian - line.a.angleRadian) > Math.PI\n\t\t};\n\t};\n\tconst cache = lines.map((line) => precompute(line));\n\tconst visibilityPolygon = (feather = 1e-6) => {\n\t\tconst angles = [];\n\t\tlines.forEach((line) => {\n\t\t\tangles.push(line.a.angleRadian, line.b.angleRadian, line.a.angleRadian - feather, line.a.angleRadian + feather, line.b.angleRadian - feather, line.b.angleRadian + feather);\n\t\t});\n\t\tangles.sort((a, b) => a - b);\n\t\tconst polygon = [];\n\t\tfor (const angleCalc of angles) {\n\t\t\tlet minDistribution = Infinity;\n\t\t\tfor (const seg of cache) {\n\t\t\t\tconst d = distance(angleCalc, seg);\n\t\t\t\tif (d < minDistribution) minDistribution = d;\n\t\t\t}\n\t\t\tif (minDistribution < Infinity) polygon.push({\n\t\t\t\tangleRadian: angleCalc,\n\t\t\t\tdistance: minDistribution\n\t\t\t});\n\t\t}\n\t\treturn polygon;\n\t};\n\tconst distance = (angle, seg) => {\n\t\tif (!(seg.wraps ? angle >= seg.angleMax || angle <= seg.angleMin : angle >= seg.angleMin && angle <= seg.angleMax)) return NaN;\n\t\tconst sin2θ = Math.sin(seg.b.angleRadian - angle);\n\t\tconst sinθ1 = Math.sin(angle - seg.a.angleRadian);\n\t\tconst denom = seg.b.distance * sin2θ + seg.a.distance * sinθ1;\n\t\tif (denom <= 0) return NaN;\n\t\treturn seg.a.distance * seg.b.distance * seg.sinBA / denom;\n\t};\n\tfunction* compute(angleRadian) {\n\t\tfor (let index = 0; index < cache.length; index++) {\n\t\t\tconst d = distance(angleRadian, cache[index]);\n\t\t\tif (Number.isNaN(d)) continue;\n\t\t\tyield {\n\t\t\t\tdistance: d,\n\t\t\t\tline: lines[index]\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tcompute,\n\t\tvisibilityPolygon\n\t};\n};\n/**\n* Returns the distance at which a line from `angleRadian` hits `line`. Returns `Infinity`\n* if there's no intersection.\n* \n* Calculations assume that all angles etc are in relation to a common origin point.\n* If repeatedly comparing against the same line (or set of lines), use {@link intersectionDistanceCompute} for\n* improved performance.\n* \n* @param angleRadian \n* @param line \n* @returns \n*/\nconst intersectionDistance = (angleRadian, line) => {\n\tconst ray = radiansNormalise(angleRadian);\n\tconst a = radiansNormalise(line.a.angleRadian);\n\tconst b = radiansNormalise(line.b.angleRadian);\n\tif (!radiansBetweenCircular(ray, a, b)) return Infinity;\n\tconst ad = line.a.distance;\n\tconst ab = line.b.distance;\n\tconst sineBA = Math.sin(b - a);\n\tconst sineBRay = Math.sin(b - ray);\n\tconst sineRayA = Math.sin(ray - a);\n\tconst denominator = ab * sineBRay + ad * sineRayA;\n\tif (Math.abs(denominator) < 1e-10) return Infinity;\n\tconst r = ad * ab * sineBA / denominator;\n\tif (r < 0) return Infinity;\n\treturn r;\n};\n//#endregion\n//#region src/polar/index.ts\nvar polar_exports = /* @__PURE__ */ __exportAll({\n\tRay: () => ray_exports,\n\tbetween: () => between,\n\tclampMagnitude: () => clampMagnitude,\n\tdivide: () => divide,\n\tdotProduct: () => dotProduct,\n\tfromCartesian: () => fromCartesian,\n\tguard: () => guard,\n\tintersectionDistance: () => intersectionDistance,\n\tintersectionDistanceCompute: () => intersectionDistanceCompute,\n\tinvert: () => invert,\n\tisAntiParallel: () => isAntiParallel,\n\tisOpposite: () => isOpposite,\n\tisParallel: () => isParallel$1,\n\tisPolarCoord: () => isPolarCoord,\n\tlineToCartesian: () => lineToCartesian,\n\tmultiply: () => multiply,\n\tnormalise: () => normalise,\n\tpolarLineToString: () => polarLineToString,\n\trotate: () => rotate,\n\trotateDegrees: () => rotateDegrees,\n\tspiral: () => spiral,\n\tspiralRaw: () => spiralRaw,\n\ttoCartesian: () => toCartesian$1,\n\ttoLine: () => toLine,\n\ttoPoint: () => toPoint,\n\ttoPolarLine: () => toPolarLine,\n\ttoString: () => toString$1\n});\n//#endregion\nexport { isOpposite as A, toString$1 as C, Unit3d as D, Unit as E, isPolarCoord as F, rotate as M, rotateDegrees as N, invert as O, guard as P, toPolarLine as S, Empty3d as T, lineToCartesian as _, spiralRaw as a, toLine as b, angleRadianCircle as c, clampMagnitude as d, divide as f, fromCartesian as g, normalise as h, spiral as i, isParallel$1 as j, isAntiParallel as k, angleRadianThreePoint as l, multiply as m, intersectionDistance as n, ray_exports as o, dotProduct as p, intersectionDistanceCompute as r, angleRadian as s, polar_exports as t, between as u, polarLineToString as v, Empty as w, toPoint as x, toCartesian$1 as y };\n","import { t as guard } from \"./guard-hlhkAOMZ.js\";\n//#region src/line/from-points.ts\n/**\n* Returns a line from two points\n* \n* ```js\n* // Line from 0,1 to 10,15\n* const line = Lines.fromPoints( { x:0, y:1 }, { x:10, y:15 });\n* // line is: { a: { x: 0, y: 1}, b: { x: 10, y: 15 } };\n* ```\n* @param a Start point\n* @param b End point\n* @returns \n*/\nconst fromPoints = (a, b) => {\n\tguard(a, `a`);\n\tguard(b, `b`);\n\ta = Object.freeze({ ...a });\n\tb = Object.freeze({ ...b });\n\treturn Object.freeze({\n\t\ta,\n\t\tb\n\t});\n};\n//#endregion\nexport { fromPoints as t };\n","//#region src/rect/max.ts\n/**\n* Returns a rectangle based on provided four corners.\n*\n* To create a rectangle that contains an arbitary set of points, use {@link Points.bbox}.\n*\n* Does some sanity checking such as:\n* - x will be smallest of topLeft/bottomLeft\n* - y will be smallest of topRight/topLeft\n* - width will be largest between top/bottom left and right\n* - height will be largest between left and right top/bottom\n*\n*/\nconst maxFromCorners = (topLeft, topRight, bottomRight, bottomLeft) => {\n\tif (topLeft.y > bottomRight.y) throw new Error(`topLeft.y greater than bottomRight.y`);\n\tif (topLeft.y > bottomLeft.y) throw new Error(`topLeft.y greater than bottomLeft.y`);\n\tconst w1 = topRight.x - topLeft.x;\n\tconst w2 = bottomRight.x - bottomLeft.x;\n\tconst h1 = Math.abs(bottomLeft.y - topLeft.y);\n\tconst h2 = Math.abs(bottomRight.y - topRight.y);\n\treturn {\n\t\tx: Math.min(topLeft.x, bottomLeft.x),\n\t\ty: Math.min(topRight.y, topLeft.y),\n\t\twidth: Math.max(w1, w2),\n\t\theight: Math.max(h1, h2)\n\t};\n};\n//#endregion\nexport { maxFromCorners as t };\n","import { c as isPoint3d } from \"./guard-hlhkAOMZ.js\";\nimport { t as maxFromCorners } from \"./max-NDZ04wx6.js\";\n//#region src/point/find-minimum.ts\n/**\n* Returns the 'minimum' point from an array of points, using a comparison function.\n*\n* @example Find point closest to a coordinate\n* ```js\n* const points = [...];\n* const center = {x: 100, y: 100};\n*\n* const closestToCenter = findMinimum((a, b) => {\n* const aDist = distance(a, center);\n* const bDist = distance(b, center);\n* if (aDistance < bDistance) return a;\n* return b;\n* }, points);\n* ```\n* @param comparer Compare function returns the smallest of `a` or `b`\n* @param points\n* @returns\n*/\nfunction findMinimum(comparer, ...points) {\n\tif (points.length === 0) throw new Error(`No points provided`);\n\tlet min = points[0];\n\tfor (const p of points) if (isPoint3d(min) && isPoint3d(p)) min = comparer(min, p);\n\telse min = comparer(min, p);\n\treturn min;\n}\n//#endregion\n//#region src/point/bbox.ts\n/**\n* Returns the minimum rectangle that can enclose all provided points\n* @param points\n* @returns\n*/\nconst bbox = (...points) => {\n\tconst leftMost = findMinimum((a, b) => {\n\t\treturn a.x < b.x ? a : b;\n\t}, ...points);\n\tconst rightMost = findMinimum((a, b) => {\n\t\treturn a.x > b.x ? a : b;\n\t}, ...points);\n\tconst topMost = findMinimum((a, b) => {\n\t\treturn a.y < b.y ? a : b;\n\t}, ...points);\n\tconst bottomMost = findMinimum((a, b) => {\n\t\treturn a.y > b.y ? a : b;\n\t}, ...points);\n\treturn maxFromCorners({\n\t\tx: leftMost.x,\n\t\ty: topMost.y\n\t}, {\n\t\tx: rightMost.x,\n\t\ty: topMost.y\n\t}, {\n\t\tx: rightMost.x,\n\t\ty: bottomMost.y\n\t}, {\n\t\tx: leftMost.x,\n\t\ty: bottomMost.y\n\t});\n};\nconst bbox3d = (...points) => {\n\tconst box = bbox(...points);\n\tconst zMin = findMinimum((a, b) => {\n\t\treturn a.z < b.z ? a : b;\n\t}, ...points);\n\tconst zMax = findMinimum((a, b) => {\n\t\treturn a.z > b.z ? a : b;\n\t}, ...points);\n\treturn {\n\t\t...box,\n\t\tz: zMin.z,\n\t\tdepth: zMax.z - zMin.z\n\t};\n};\n//#endregion\nexport { bbox3d as n, findMinimum as r, bbox as t };\n","import { s as isPoint } from \"./guard-hlhkAOMZ.js\";\n//#region src/line/guard.ts\n/**\n* Returns true if `p` is a valid line, containing `a` and `b` Points.\n* ```js\n* Lines.isLine(l);\n* ```\n* @param p Value to check\n* @returns True if a valid line.\n*/\nfunction isLine(p) {\n\tif (p === void 0) return false;\n\tif (p.a === void 0) return false;\n\tif (p.b === void 0) return false;\n\tif (!isPoint(p.a)) return false;\n\tif (!isPoint(p.b)) return false;\n\treturn true;\n}\n/**\n* Returns true if `p` is a {@link PolyLine}, ie. an array of {@link Line}s.\n* Validates all items in array.\n* @param p\n* @returns\n*/\nfunction isPolyLine(p) {\n\tif (!Array.isArray(p)) return false;\n\treturn !p.some((v) => !isLine(v));\n}\n/**\n* Returns a failure if:\n* - line is undefined\n* - a or b parameters are missing\n*\n* Does not validate points\n* @param line\n* @param name\n*/\nfunction lineTest(line, name = `line`) {\n\tif (line === void 0) return {\n\t\tsuccess: false,\n\t\terror: `${name} undefined`\n\t};\n\tif (line.a === void 0) return {\n\t\tsuccess: false,\n\t\terror: `${name}.a undefined. Expected {a:Point, b:Point}. Got: ${JSON.stringify(line)}`\n\t};\n\tif (line.b === void 0) return {\n\t\tsuccess: false,\n\t\terror: `${name}.b undefined. Expected {a:Point, b:Point} Got: ${JSON.stringify(line)}`\n\t};\n\treturn {\n\t\tsuccess: true,\n\t\tvalue: true\n\t};\n}\n//#endregion\nexport { isPolyLine as n, lineTest as r, isLine as t };\n","import { t as guard } from \"./guard-hlhkAOMZ.js\";\nimport { n as isPolyLine, t as isLine } from \"./guard-Bg57Xzmd.js\";\n//#region src/line/get-points-parameter.ts\n/**\n* Returns [a,b] points from either a line parameter, or two points.\n* It additionally applies the guardPoint function to ensure validity.\n* This supports function overloading.\n* @ignore\n* @param aOrLine \n* @param b \n* @returns \n*/\nconst getPointParameter = (aOrLine, b) => {\n\tlet a;\n\tif (isLine(aOrLine)) {\n\t\tb = aOrLine.b;\n\t\ta = aOrLine.a;\n\t} else {\n\t\ta = aOrLine;\n\t\tif (b === void 0) throw new Error(`Since first parameter is not a line, two points are expected. Got a: ${JSON.stringify(a)} b: ${JSON.stringify(b)}`);\n\t}\n\tguard(a, `a`);\n\tguard(a, `b`);\n\treturn [a, b];\n};\n//#endregion\n//#region src/line/length.ts\n/**\n* Returns length of line, polyline or between two points\n* \n* @param aOrLine Point A, line or polyline (array of lines)\n* @param pointB Point B, if first parameter is a point\n* @returns Length (total accumulated length for arrays)\n*/\nfunction length(aOrLine, pointBOrForce2d, force2d) {\n\tif (isPolyLine(aOrLine)) {\n\t\tconst _force2d = typeof pointBOrForce2d === `boolean` ? pointBOrForce2d : false;\n\t\treturn aOrLine.reduce((accumulator, v) => length(v, _force2d) + accumulator, 0);\n\t}\n\tif (aOrLine === void 0) throw new TypeError(`Parameter 'aOrLine' is undefined`);\n\tconst [a, b] = typeof pointBOrForce2d === `object` ? getPointParameter(aOrLine, pointBOrForce2d) : getPointParameter(aOrLine);\n\tconst x = b.x - a.x;\n\tconst y = b.y - a.y;\n\tif (!(typeof pointBOrForce2d === `boolean` ? pointBOrForce2d : typeof force2d === `boolean` ? force2d : false) && a.z !== void 0 && b.z !== void 0) {\n\t\tconst z = b.z - a.z;\n\t\treturn Math.hypot(x, y, z);\n\t} else return Math.hypot(x, y);\n}\n//#endregion\nexport { getPointParameter as n, length as t };\n","import { r as lineTest } from \"./guard-Bg57Xzmd.js\";\nimport { n as getPointParameter, t as length } from \"./length-ChosppvJ.js\";\nimport { numberTest, percentTest, resultThrow } from \"@ixfx/guards\";\n//#region src/line/reverse.ts\n/**\n* Reverses a line.\n* ````js\n* const a = { x: 10, y: 20 };\n* const b = { x: 100, y: 200 };\n* const line = reverse({ a, b });\n* // { a: { x: 100, y: 200 }, b: { x: 10, y: 20 } }\n* ```\n* @param line\n* @returns\n*/\nfunction reverse(line) {\n\tresultThrow(lineTest(line, `line`));\n\treturn {\n\t\ta: line.b,\n\t\tb: line.a\n\t};\n}\n//#endregion\n//#region src/line/interpolate.ts\n/**\n* Calculates a point in-between a line's start and end points.\n*\n* @param amount Interpolation amount\n* @param aOrLine Line, or first point\n* @param pointBOrAllowOverflow Second point (if needed) or allowOverflow.\n* @param allowOverflow If true, interpolation amount is permitted to exceed 0..1, extending the line.\n*/\nfunction interpolate(amount, aOrLine, pointBOrAllowOverflow, allowOverflow) {\n\tif (typeof pointBOrAllowOverflow === `boolean`) {\n\t\tallowOverflow = pointBOrAllowOverflow;\n\t\tpointBOrAllowOverflow = void 0;\n\t}\n\tif (!allowOverflow) resultThrow(percentTest(amount, `amount`));\n\telse resultThrow(numberTest(amount, ``, `amount`));\n\tconst [a, b] = getPointParameter(aOrLine, pointBOrAllowOverflow);\n\treturn interpolator({\n\t\ta,\n\t\tb\n\t}, allowOverflow)(amount);\n}\n/**\n* Returns a function that interpolates along `line`, returning a {@link Point}.\n* ```js\n* const i = interpolator(a: {x:0,y:0}, b:{x:100, y:100});\n* i(0.5); // Returns point 50% between a and b.\n* ```\n* @param line Line to interpolate along\n* @param allowOverflow If _true_ interpolation amount can exceed 0..1, extending the line.\n*/\nfunction interpolator(line, allowOverflow = false) {\n\tresultThrow(lineTest(line));\n\tconst d = length(line);\n\tconst { a, b } = line;\n\treturn (amount) => {\n\t\tif (!allowOverflow) resultThrow(percentTest(amount, `amount`));\n\t\telse resultThrow(numberTest(amount, ``, `amount`));\n\t\tconst d2 = d * (1 - amount);\n\t\tif (d === 0 && d2 === 0) return Object.freeze({ ...b });\n\t\tconst x = b.x - d2 * (b.x - a.x) / d;\n\t\tconst y = b.y - d2 * (b.y - a.y) / d;\n\t\treturn Object.freeze({\n\t\t\t...b,\n\t\t\tx,\n\t\t\ty\n\t\t});\n\t};\n}\n/**\n* Returns the point along a line from its start (A)\n* @param line Line\n* @param distance Distance\n* @param fromA If _true_ (default) returns from A. Use _false_ to calculate from end\n* @returns Point at distance along line\n*/\nfunction pointAtDistance(line, distance, fromA = true) {\n\tif (!fromA) line = reverse(line);\n\tconst dx = line.b.x - line.a.x;\n\tconst dy = line.b.y - line.a.y;\n\tconst theta = Math.atan2(dy, dx);\n\tconst xp = distance * Math.cos(theta);\n\tconst yp = distance * Math.sin(theta);\n\treturn {\n\t\tx: xp + line.a.x,\n\t\ty: yp + line.a.y\n\t};\n}\n//#endregion\nexport { reverse as i, interpolator as n, pointAtDistance as r, interpolate as t };\n","import { t as guard$1 } from \"./guard-hlhkAOMZ.js\";\n//#region src/rect/guard.ts\n/**\n* Throws an error if the dimensions of the rectangle are undefined, NaN or negative.\n* @param d \n* @param name \n*/\nconst guardDim = (d, name = `Dimension`) => {\n\tif (d === void 0) throw new Error(`${name} is undefined`);\n\tif (Number.isNaN(d)) throw new Error(`${name} is NaN`);\n\tif (d < 0) throw new Error(`${name} cannot be negative`);\n};\n/**\n* Throws an error if rectangle is missing fields or they\n* are not valid.\n* \n* Checks:\n* * `width` and `height` must be defined on `rect`\n* * dimensions (w & h) must not be NaN\n* * dimensions (w & h) must not be negative\n* \n* If `rect` has x,y, this value is checked as well.\n* @param rect\n* @param name\n*/\nconst guard = (rect, name = `rect`) => {\n\tif (rect === void 0) throw new Error(`{$name} undefined`);\n\tif (isPositioned(rect)) guard$1(rect, name);\n\tguardDim(rect.width, name + `.width`);\n\tguardDim(rect.height, name + `.height`);\n};\n/**\n* Returns a positioned rect or if it's not possible, throws an error.\n* \n* If `rect` does not have a position, `origin` is used.\n* If `rect` is positioned and `origin` is provided, returned result uses `origin` as x,y instead.\n* ```js\n* // Returns input because it's positioned\n* getRectPositioned({ x:1, y:2, width:10, height:20 });\n* \n* // Returns { x:1, y:2, width:10, height:20 }\n* getRectPositioned({ width:10, height:20 }, { x:1, y:2 });\n* \n* // Throws, because we have no point\n* getRectPositioned({width:10,height:20})\n* ```\n* @param rect \n* @param origin \n* @returns \n*/\nconst getRectPositioned = (rect, origin) => {\n\tguard(rect);\n\tif (isPositioned(rect) && origin === void 0) return rect;\n\tif (origin === void 0) throw new Error(`Unpositioned rect needs origin parameter`);\n\treturn Object.freeze({\n\t\t...rect,\n\t\t...origin\n\t});\n};\n/**\n* Throws an error if `rect` is does not have a position, or\n* is an invalid rectangle\n* @param rect \n* @param name \n*/\nconst guardPositioned = (rect, name = `rect`) => {\n\tif (!isPositioned(rect)) throw new Error(`Expected ${name} to have x,y`);\n\tguard(rect, name);\n};\n/**\n* Returns _true_ if `rect` has width and height values of 0.\n* Use Rects.Empty or Rects.EmptyPositioned to generate an empty rectangle.\n* @param rect \n* @returns \n*/\nconst isEmpty = (rect) => rect.width === 0 && rect.height === 0;\n/**\n* Returns _true_ if `rect` is a placeholder, with both width and height values of NaN.\n* Use Rects.Placeholder or Rects.PlaceholderPositioned to generate a placeholder.\n* @param rect \n* @returns \n*/\nconst isPlaceholder = (rect) => Number.isNaN(rect.width) && Number.isNaN(rect.height);\n/**\n* Returns _true_ if `rect` has position (x,y) fields.\n* @param rect Point, Rect or RectPositiond\n* @returns\n*/\nconst isPositioned = (rect) => rect.x !== void 0 && rect.y !== void 0;\n/**\n* Returns _true_ if `rect` has width and height fields.\n* @param rect\n* @returns\n*/\nconst isRect = (rect) => {\n\tif (rect === void 0) return false;\n\tif (rect.width === void 0) return false;\n\tif (rect.height === void 0) return false;\n\treturn true;\n};\n/**\n* Returns _true_ if `rect` is a positioned rectangle\n* Having width, height, x and y properties.\n* @param rect\n* @returns\n*/\nconst isRectPositioned = (rect) => isRect(rect) && isPositioned(rect);\n//#endregion\nexport { isEmpty as a, isRect as c, guardPositioned as i, isRectPositioned as l, guard as n, isPlaceholder as o, guardDim as r, isPositioned as s, getRectPositioned as t };\n","import { t as guard } from \"./guard-hlhkAOMZ.js\";\nimport { r as guardDim } from \"./guard-C2opUnGy.js\";\n//#region src/rect/from-top-left.ts\n/**\n* Creates a rectangle from its top-left coordinate, a width and height.\n*\n* ```js\n* // Rectangle at 50,50 with width of 100, height of 200.\n* const rect = Rects.fromTopLeft({ x: 50, y:50 }, 100, 200);\n* ```\n* @param origin\n* @param width\n* @param height\n*/\nfunction fromTopLeft(origin, width, height) {\n\tguardDim(width, `width`);\n\tguardDim(height, `height`);\n\tguard(origin, `origin`);\n\treturn {\n\t\tx: origin.x,\n\t\ty: origin.y,\n\t\twidth,\n\t\theight\n\t};\n}\n//#endregion\nexport { fromTopLeft as t };\n","//#region src/bezier/guard.ts\nconst isQuadraticBezier = (path) => path.quadratic !== void 0;\nconst isCubicBezier = (path) => path.cubic1 !== void 0 && path.cubic2 !== void 0;\n//#endregion\nexport { isQuadraticBezier as n, isCubicBezier as t };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { t as interpolate } from \"./interpolate-DhLKNStN.js\";\nimport { t as fromTopLeft } from \"./from-top-left-D_I93JN9.js\";\nimport { n as isQuadraticBezier, t as isCubicBezier } from \"./guard-D8jtfB4t.js\";\n//#region ../../node_modules/.pnpm/bezier-js@6.1.4/node_modules/bezier-js/src/utils.js\nconst { abs: abs$1, cos: cos$1, sin: sin$1, acos: acos$1, atan2, sqrt: sqrt$1, pow } = Math;\nfunction crt(v) {\n\treturn v < 0 ? -pow(-v, 1 / 3) : pow(v, 1 / 3);\n}\nconst pi$1 = Math.PI, tau = 2 * pi$1, quart = pi$1 / 2, epsilon = 1e-6, nMax = Number.MAX_SAFE_INTEGER || 9007199254740991, nMin = Number.MIN_SAFE_INTEGER || -9007199254740991, ZERO = {\n\tx: 0,\n\ty: 0,\n\tz: 0\n};\nconst utils = {\n\tTvalues: [\n\t\t-.06405689286260563,\n\t\t.06405689286260563,\n\t\t-.1911188674736163,\n\t\t.1911188674736163,\n\t\t-.3150426796961634,\n\t\t.3150426796961634,\n\t\t-.4337935076260451,\n\t\t.4337935076260451,\n\t\t-.5454214713888396,\n\t\t.5454214713888396,\n\t\t-.6480936519369755,\n\t\t.6480936519369755,\n\t\t-.7401241915785544,\n\t\t.7401241915785544,\n\t\t-.820001985973903,\n\t\t.820001985973903,\n\t\t-.8864155270044011,\n\t\t.8864155270044011,\n\t\t-.9382745520027328,\n\t\t.9382745520027328,\n\t\t-.9747285559713095,\n\t\t.9747285559713095,\n\t\t-.9951872199970213,\n\t\t.9951872199970213\n\t],\n\tCvalues: [\n\t\t.12793819534675216,\n\t\t.12793819534675216,\n\t\t.1258374563468283,\n\t\t.1258374563468283,\n\t\t.12167047292780339,\n\t\t.12167047292780339,\n\t\t.1155056680537256,\n\t\t.1155056680537256,\n\t\t.10744427011596563,\n\t\t.10744427011596563,\n\t\t.09761865210411388,\n\t\t.09761865210411388,\n\t\t.08619016153195327,\n\t\t.08619016153195327,\n\t\t.0733464814110803,\n\t\t.0733464814110803,\n\t\t.05929858491543678,\n\t\t.05929858491543678,\n\t\t.04427743881741981,\n\t\t.04427743881741981,\n\t\t.028531388628933663,\n\t\t.028531388628933663,\n\t\t.0123412297999872,\n\t\t.0123412297999872\n\t],\n\tarcfn: function(t, derivativeFn) {\n\t\tconst d = derivativeFn(t);\n\t\tlet l = d.x * d.x + d.y * d.y;\n\t\tif (typeof d.z !== \"undefined\") l += d.z * d.z;\n\t\treturn sqrt$1(l);\n\t},\n\tcompute: function(t, points, _3d) {\n\t\tif (t === 0) {\n\t\t\tpoints[0].t = 0;\n\t\t\treturn points[0];\n\t\t}\n\t\tconst order = points.length - 1;\n\t\tif (t === 1) {\n\t\t\tpoints[order].t = 1;\n\t\t\treturn points[order];\n\t\t}\n\t\tconst mt = 1 - t;\n\t\tlet p = points;\n\t\tif (order === 0) {\n\t\t\tpoints[0].t = t;\n\t\t\treturn points[0];\n\t\t}\n\t\tif (order === 1) {\n\t\t\tconst ret = {\n\t\t\t\tx: mt * p[0].x + t * p[1].x,\n\t\t\t\ty: mt * p[0].y + t * p[1].y,\n\t\t\t\tt\n\t\t\t};\n\t\t\tif (_3d) ret.z = mt * p[0].z + t * p[1].z;\n\t\t\treturn ret;\n\t\t}\n\t\tif (order < 4) {\n\t\t\tlet mt2 = mt * mt, t2 = t * t, a, b, c, d = 0;\n\t\t\tif (order === 2) {\n\t\t\t\tp = [\n\t\t\t\t\tp[0],\n\t\t\t\t\tp[1],\n\t\t\t\t\tp[2],\n\t\t\t\t\tZERO\n\t\t\t\t];\n\t\t\t\ta = mt2;\n\t\t\t\tb = mt * t * 2;\n\t\t\t\tc = t2;\n\t\t\t} else if (order === 3) {\n\t\t\t\ta = mt2 * mt;\n\t\t\t\tb = mt2 * t * 3;\n\t\t\t\tc = mt * t2 * 3;\n\t\t\t\td = t * t2;\n\t\t\t}\n\t\t\tconst ret = {\n\t\t\t\tx: a * p[0].x + b * p[1].x + c * p[2].x + d * p[3].x,\n\t\t\t\ty: a * p[0].y + b * p[1].y + c * p[2].y + d * p[3].y,\n\t\t\t\tt\n\t\t\t};\n\t\t\tif (_3d) ret.z = a * p[0].z + b * p[1].z + c * p[2].z + d * p[3].z;\n\t\t\treturn ret;\n\t\t}\n\t\tconst dCpts = JSON.parse(JSON.stringify(points));\n\t\twhile (dCpts.length > 1) {\n\t\t\tfor (let i = 0; i < dCpts.length - 1; i++) {\n\t\t\t\tdCpts[i] = {\n\t\t\t\t\tx: dCpts[i].x + (dCpts[i + 1].x - dCpts[i].x) * t,\n\t\t\t\t\ty: dCpts[i].y + (dCpts[i + 1].y - dCpts[i].y) * t\n\t\t\t\t};\n\t\t\t\tif (typeof dCpts[i].z !== \"undefined\") dCpts[i].z = dCpts[i].z + (dCpts[i + 1].z - dCpts[i].z) * t;\n\t\t\t}\n\t\t\tdCpts.splice(dCpts.length - 1, 1);\n\t\t}\n\t\tdCpts[0].t = t;\n\t\treturn dCpts[0];\n\t},\n\tcomputeWithRatios: function(t, points, ratios, _3d) {\n\t\tconst mt = 1 - t, r = ratios, p = points;\n\t\tlet f1 = r[0], f2 = r[1], f3 = r[2], f4 = r[3], d;\n\t\tf1 *= mt;\n\t\tf2 *= t;\n\t\tif (p.length === 2) {\n\t\t\td = f1 + f2;\n\t\t\treturn {\n\t\t\t\tx: (f1 * p[0].x + f2 * p[1].x) / d,\n\t\t\t\ty: (f1 * p[0].y + f2 * p[1].y) / d,\n\t\t\t\tz: !_3d ? false : (f1 * p[0].z + f2 * p[1].z) / d,\n\t\t\t\tt\n\t\t\t};\n\t\t}\n\t\tf1 *= mt;\n\t\tf2 *= 2 * mt;\n\t\tf3 *= t * t;\n\t\tif (p.length === 3) {\n\t\t\td = f1 + f2 + f3;\n\t\t\treturn {\n\t\t\t\tx: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x) / d,\n\t\t\t\ty: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y) / d,\n\t\t\t\tz: !_3d ? false : (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z) / d,\n\t\t\t\tt\n\t\t\t};\n\t\t}\n\t\tf1 *= mt;\n\t\tf2 *= 1.5 * mt;\n\t\tf3 *= 3 * mt;\n\t\tf4 *= t * t * t;\n\t\tif (p.length === 4) {\n\t\t\td = f1 + f2 + f3 + f4;\n\t\t\treturn {\n\t\t\t\tx: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x + f4 * p[3].x) / d,\n\t\t\t\ty: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y + f4 * p[3].y) / d,\n\t\t\t\tz: !_3d ? false : (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z + f4 * p[3].z) / d,\n\t\t\t\tt\n\t\t\t};\n\t\t}\n\t},\n\tderive: function(points, _3d) {\n\t\tconst dpoints = [];\n\t\tfor (let p = points, d = p.length, c = d - 1; d > 1; d--, c--) {\n\t\t\tconst list = [];\n\t\t\tfor (let j = 0, dpt; j < c; j++) {\n\t\t\t\tdpt = {\n\t\t\t\t\tx: c * (p[j + 1].x - p[j].x),\n\t\t\t\t\ty: c * (p[j + 1].y - p[j].y)\n\t\t\t\t};\n\t\t\t\tif (_3d) dpt.z = c * (p[j + 1].z - p[j].z);\n\t\t\t\tlist.push(dpt);\n\t\t\t}\n\t\t\tdpoints.push(list);\n\t\t\tp = list;\n\t\t}\n\t\treturn dpoints;\n\t},\n\tbetween: function(v, m, M) {\n\t\treturn m <= v && v <= M || utils.approximately(v, m) || utils.approximately(v, M);\n\t},\n\tapproximately: function(a, b, precision) {\n\t\treturn abs$1(a - b) <= (precision || epsilon);\n\t},\n\tlength: function(derivativeFn) {\n\t\tconst z = .5, len = utils.Tvalues.length;\n\t\tlet sum = 0;\n\t\tfor (let i = 0, t; i < len; i++) {\n\t\t\tt = z * utils.Tvalues[i] + z;\n\t\t\tsum += utils.Cvalues[i] * utils.arcfn(t, derivativeFn);\n\t\t}\n\t\treturn z * sum;\n\t},\n\tmap: function(v, ds, de, ts, te) {\n\t\tconst d1 = de - ds;\n\t\treturn ts + (te - ts) * ((v - ds) / d1);\n\t},\n\tlerp: function(r, v1, v2) {\n\t\tconst ret = {\n\t\t\tx: v1.x + r * (v2.x - v1.x),\n\t\t\ty: v1.y + r * (v2.y - v1.y)\n\t\t};\n\t\tif (v1.z !== void 0 && v2.z !== void 0) ret.z = v1.z + r * (v2.z - v1.z);\n\t\treturn ret;\n\t},\n\tpointToString: function(p) {\n\t\tlet s = p.x + \"/\" + p.y;\n\t\tif (typeof p.z !== \"undefined\") s += \"/\" + p.z;\n\t\treturn s;\n\t},\n\tpointsToString: function(points) {\n\t\treturn \"[\" + points.map(utils.pointToString).join(\", \") + \"]\";\n\t},\n\tcopy: function(obj) {\n\t\treturn JSON.parse(JSON.stringify(obj));\n\t},\n\tangle: function(o, v1, v2) {\n\t\tconst dx1 = v1.x - o.x, dy1 = v1.y - o.y, dx2 = v2.x - o.x, dy2 = v2.y - o.y;\n\t\treturn atan2(dx1 * dy2 - dy1 * dx2, dx1 * dx2 + dy1 * dy2);\n\t},\n\tround: function(v, d) {\n\t\tconst s = \"\" + v;\n\t\tconst pos = s.indexOf(\".\");\n\t\treturn parseFloat(s.substring(0, pos + 1 + d));\n\t},\n\tdist: function(p1, p2) {\n\t\tconst dx = p1.x - p2.x, dy = p1.y - p2.y;\n\t\treturn sqrt$1(dx * dx + dy * dy);\n\t},\n\tclosest: function(LUT, point) {\n\t\tlet mdist = pow(2, 63), mpos, d;\n\t\tLUT.forEach(function(p, idx) {\n\t\t\td = utils.dist(point, p);\n\t\t\tif (d < mdist) {\n\t\t\t\tmdist = d;\n\t\t\t\tmpos = idx;\n\t\t\t}\n\t\t});\n\t\treturn {\n\t\t\tmdist,\n\t\t\tmpos\n\t\t};\n\t},\n\tabcratio: function(t, n) {\n\t\tif (n !== 2 && n !== 3) return false;\n\t\tif (typeof t === \"undefined\") t = .5;\n\t\telse if (t === 0 || t === 1) return t;\n\t\tconst bottom = pow(t, n) + pow(1 - t, n);\n\t\treturn abs$1((bottom - 1) / bottom);\n\t},\n\tprojectionratio: function(t, n) {\n\t\tif (n !== 2 && n !== 3) return false;\n\t\tif (typeof t === \"undefined\") t = .5;\n\t\telse if (t === 0 || t === 1) return t;\n\t\tconst top = pow(1 - t, n);\n\t\treturn top / (pow(t, n) + top);\n\t},\n\tlli8: function(x1, y1, x2, y2, x3, y3, x4, y4) {\n\t\tconst nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\n\t\tif (d == 0) return false;\n\t\treturn {\n\t\t\tx: nx / d,\n\t\t\ty: ny / d\n\t\t};\n\t},\n\tlli4: function(p1, p2, p3, p4) {\n\t\tconst x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y, x3 = p3.x, y3 = p3.y, x4 = p4.x, y4 = p4.y;\n\t\treturn utils.lli8(x1, y1, x2, y2, x3, y3, x4, y4);\n\t},\n\tlli: function(v1, v2) {\n\t\treturn utils.lli4(v1, v1.c, v2, v2.c);\n\t},\n\tmakeline: function(p1, p2) {\n\t\treturn new Bezier(p1.x, p1.y, (p1.x + p2.x) / 2, (p1.y + p2.y) / 2, p2.x, p2.y);\n\t},\n\tfindbbox: function(sections) {\n\t\tlet mx = nMax, my = nMax, MX = nMin, MY = nMin;\n\t\tsections.forEach(function(s) {\n\t\t\tconst bbox = s.bbox();\n\t\t\tif (mx > bbox.x.min) mx = bbox.x.min;\n\t\t\tif (my > bbox.y.min) my = bbox.y.min;\n\t\t\tif (MX < bbox.x.max) MX = bbox.x.max;\n\t\t\tif (MY < bbox.y.max) MY = bbox.y.max;\n\t\t});\n\t\treturn {\n\t\t\tx: {\n\t\t\t\tmin: mx,\n\t\t\t\tmid: (mx + MX) / 2,\n\t\t\t\tmax: MX,\n\t\t\t\tsize: MX - mx\n\t\t\t},\n\t\t\ty: {\n\t\t\t\tmin: my,\n\t\t\t\tmid: (my + MY) / 2,\n\t\t\t\tmax: MY,\n\t\t\t\tsize: MY - my\n\t\t\t}\n\t\t};\n\t},\n\tshapeintersections: function(s1, bbox1, s2, bbox2, curveIntersectionThreshold) {\n\t\tif (!utils.bboxoverlap(bbox1, bbox2)) return [];\n\t\tconst intersections = [];\n\t\tconst a1 = [\n\t\t\ts1.startcap,\n\t\t\ts1.forward,\n\t\t\ts1.back,\n\t\t\ts1.endcap\n\t\t];\n\t\tconst a2 = [\n\t\t\ts2.startcap,\n\t\t\ts2.forward,\n\t\t\ts2.back,\n\t\t\ts2.endcap\n\t\t];\n\t\ta1.forEach(function(l1) {\n\t\t\tif (l1.virtual) return;\n\t\t\ta2.forEach(function(l2) {\n\t\t\t\tif (l2.virtual) return;\n\t\t\t\tconst iss = l1.intersects(l2, curveIntersectionThreshold);\n\t\t\t\tif (iss.length > 0) {\n\t\t\t\t\tiss.c1 = l1;\n\t\t\t\t\tiss.c2 = l2;\n\t\t\t\t\tiss.s1 = s1;\n\t\t\t\t\tiss.s2 = s2;\n\t\t\t\t\tintersections.push(iss);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t\treturn intersections;\n\t},\n\tmakeshape: function(forward, back, curveIntersectionThreshold) {\n\t\tconst bpl = back.points.length;\n\t\tconst fpl = forward.points.length;\n\t\tconst start = utils.makeline(back.points[bpl - 1], forward.points[0]);\n\t\tconst end = utils.makeline(forward.points[fpl - 1], back.points[0]);\n\t\tconst shape = {\n\t\t\tstartcap: start,\n\t\t\tforward,\n\t\t\tback,\n\t\t\tendcap: end,\n\t\t\tbbox: utils.findbbox([\n\t\t\t\tstart,\n\t\t\t\tforward,\n\t\t\t\tback,\n\t\t\t\tend\n\t\t\t])\n\t\t};\n\t\tshape.intersections = function(s2) {\n\t\t\treturn utils.shapeintersections(shape, shape.bbox, s2, s2.bbox, curveIntersectionThreshold);\n\t\t};\n\t\treturn shape;\n\t},\n\tgetminmax: function(curve, d, list) {\n\t\tif (!list) return {\n\t\t\tmin: 0,\n\t\t\tmax: 0\n\t\t};\n\t\tlet min = nMax, max = nMin, t, c;\n\t\tif (list.indexOf(0) === -1) list = [0].concat(list);\n\t\tif (list.indexOf(1) === -1) list.push(1);\n\t\tfor (let i = 0, len = list.length; i < len; i++) {\n\t\t\tt = list[i];\n\t\t\tc = curve.get(t);\n\t\t\tif (c[d] < min) min = c[d];\n\t\t\tif (c[d] > max) max = c[d];\n\t\t}\n\t\treturn {\n\t\t\tmin,\n\t\t\tmid: (min + max) / 2,\n\t\t\tmax,\n\t\t\tsize: max - min\n\t\t};\n\t},\n\talign: function(points, line) {\n\t\tconst tx = line.p1.x, ty = line.p1.y, a = -atan2(line.p2.y - ty, line.p2.x - tx), d = function(v) {\n\t\t\treturn {\n\t\t\t\tx: (v.x - tx) * cos$1(a) - (v.y - ty) * sin$1(a),\n\t\t\t\ty: (v.x - tx) * sin$1(a) + (v.y - ty) * cos$1(a)\n\t\t\t};\n\t\t};\n\t\treturn points.map(d);\n\t},\n\troots: function(points, line) {\n\t\tline = line || {\n\t\t\tp1: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0\n\t\t\t},\n\t\t\tp2: {\n\t\t\t\tx: 1,\n\t\t\t\ty: 0\n\t\t\t}\n\t\t};\n\t\tconst order = points.length - 1;\n\t\tconst aligned = utils.align(points, line);\n\t\tconst reduce = function(t) {\n\t\t\treturn 0 <= t && t <= 1;\n\t\t};\n\t\tif (order === 2) {\n\t\t\tconst a = aligned[0].y, b = aligned[1].y, c = aligned[2].y, d = a - 2 * b + c;\n\t\t\tif (d !== 0) {\n\t\t\t\tconst m1 = -sqrt$1(b * b - a * c), m2 = -a + b;\n\t\t\t\treturn [-(m1 + m2) / d, -(-m1 + m2) / d].filter(reduce);\n\t\t\t} else if (b !== c && d === 0) return [(2 * b - c) / (2 * b - 2 * c)].filter(reduce);\n\t\t\treturn [];\n\t\t}\n\t\tconst pa = aligned[0].y, pb = aligned[1].y, pc = aligned[2].y, pd = aligned[3].y;\n\t\tlet d = -pa + 3 * pb - 3 * pc + pd, a = 3 * pa - 6 * pb + 3 * pc, b = -3 * pa + 3 * pb, c = pa;\n\t\tif (utils.approximately(d, 0)) {\n\t\t\tif (utils.approximately(a, 0)) {\n\t\t\t\tif (utils.approximately(b, 0)) return [];\n\t\t\t\treturn [-c / b].filter(reduce);\n\t\t\t}\n\t\t\tconst q = sqrt$1(b * b - 4 * a * c), a2 = 2 * a;\n\t\t\treturn [(q - b) / a2, (-b - q) / a2].filter(reduce);\n\t\t}\n\t\ta /= d;\n\t\tb /= d;\n\t\tc /= d;\n\t\tconst p = (3 * b - a * a) / 3, p3 = p / 3, q = (2 * a * a * a - 9 * a * b + 27 * c) / 27, q2 = q / 2, discriminant = q2 * q2 + p3 * p3 * p3;\n\t\tlet u1, v1, x1, x2, x3;\n\t\tif (discriminant < 0) {\n\t\t\tconst mp3 = -p / 3, r = sqrt$1(mp3 * mp3 * mp3), t = -q / (2 * r), phi = acos$1(t < -1 ? -1 : t > 1 ? 1 : t), t1 = 2 * crt(r);\n\t\t\tx1 = t1 * cos$1(phi / 3) - a / 3;\n\t\t\tx2 = t1 * cos$1((phi + tau) / 3) - a / 3;\n\t\t\tx3 = t1 * cos$1((phi + 2 * tau) / 3) - a / 3;\n\t\t\treturn [\n\t\t\t\tx1,\n\t\t\t\tx2,\n\t\t\t\tx3\n\t\t\t].filter(reduce);\n\t\t} else if (discriminant === 0) {\n\t\t\tu1 = q2 < 0 ? crt(-q2) : -crt(q2);\n\t\t\tx1 = 2 * u1 - a / 3;\n\t\t\tx2 = -u1 - a / 3;\n\t\t\treturn [x1, x2].filter(reduce);\n\t\t} else {\n\t\t\tconst sd = sqrt$1(discriminant);\n\t\t\tu1 = crt(-q2 + sd);\n\t\t\tv1 = crt(q2 + sd);\n\t\t\treturn [u1 - v1 - a / 3].filter(reduce);\n\t\t}\n\t},\n\tdroots: function(p) {\n\t\tif (p.length === 3) {\n\t\t\tconst a = p[0], b = p[1], c = p[2], d = a - 2 * b + c;\n\t\t\tif (d !== 0) {\n\t\t\t\tconst m1 = -sqrt$1(b * b - a * c), m2 = -a + b;\n\t\t\t\treturn [-(m1 + m2) / d, -(-m1 + m2) / d];\n\t\t\t} else if (b !== c && d === 0) return [(2 * b - c) / (2 * (b - c))];\n\t\t\treturn [];\n\t\t}\n\t\tif (p.length === 2) {\n\t\t\tconst a = p[0], b = p[1];\n\t\t\tif (a !== b) return [a / (a - b)];\n\t\t\treturn [];\n\t\t}\n\t\treturn [];\n\t},\n\tcurvature: function(t, d1, d2, _3d, kOnly) {\n\t\tlet num, dnm, adk, dk, k = 0, r = 0;\n\t\tconst d = utils.compute(t, d1);\n\t\tconst dd = utils.compute(t, d2);\n\t\tconst qdsum = d.x * d.x + d.y * d.y;\n\t\tif (_3d) {\n\t\t\tnum = sqrt$1(pow(d.y * dd.z - dd.y * d.z, 2) + pow(d.z * dd.x - dd.z * d.x, 2) + pow(d.x * dd.y - dd.x * d.y, 2));\n\t\t\tdnm = pow(qdsum + d.z * d.z, 3 / 2);\n\t\t} else {\n\t\t\tnum = d.x * dd.y - d.y * dd.x;\n\t\t\tdnm = pow(qdsum, 3 / 2);\n\t\t}\n\t\tif (num === 0 || dnm === 0) return {\n\t\t\tk: 0,\n\t\t\tr: 0\n\t\t};\n\t\tk = num / dnm;\n\t\tr = dnm / num;\n\t\tif (!kOnly) {\n\t\t\tconst pk = utils.curvature(t - .001, d1, d2, _3d, true).k;\n\t\t\tconst nk = utils.curvature(t + .001, d1, d2, _3d, true).k;\n\t\t\tdk = (nk - k + (k - pk)) / 2;\n\t\t\tadk = (abs$1(nk - k) + abs$1(k - pk)) / 2;\n\t\t}\n\t\treturn {\n\t\t\tk,\n\t\t\tr,\n\t\t\tdk,\n\t\t\tadk\n\t\t};\n\t},\n\tinflections: function(points) {\n\t\tif (points.length < 4) return [];\n\t\tconst p = utils.align(points, {\n\t\t\tp1: points[0],\n\t\t\tp2: points.slice(-1)[0]\n\t\t}), a = p[2].x * p[1].y, b = p[3].x * p[1].y, c = p[1].x * p[2].y, d = p[3].x * p[2].y, v1 = 18 * (-3 * a + 2 * b + 3 * c - d), v2 = 18 * (3 * a - b - 3 * c), v3 = 18 * (c - a);\n\t\tif (utils.approximately(v1, 0)) {\n\t\t\tif (!utils.approximately(v2, 0)) {\n\t\t\t\tlet t = -v3 / v2;\n\t\t\t\tif (0 <= t && t <= 1) return [t];\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\t\tconst d2 = 2 * v1;\n\t\tif (utils.approximately(d2, 0)) return [];\n\t\tconst trm = v2 * v2 - 4 * v1 * v3;\n\t\tif (trm < 0) return [];\n\t\tconst sq = Math.sqrt(trm);\n\t\treturn [(sq - v2) / d2, -(v2 + sq) / d2].filter(function(r) {\n\t\t\treturn 0 <= r && r <= 1;\n\t\t});\n\t},\n\tbboxoverlap: function(b1, b2) {\n\t\tconst dims = [\"x\", \"y\"], len = dims.length;\n\t\tfor (let i = 0, dim, l, t, d; i < len; i++) {\n\t\t\tdim = dims[i];\n\t\t\tl = b1[dim].mid;\n\t\t\tt = b2[dim].mid;\n\t\t\td = (b1[dim].size + b2[dim].size) / 2;\n\t\t\tif (abs$1(l - t) >= d) return false;\n\t\t}\n\t\treturn true;\n\t},\n\texpandbox: function(bbox, _bbox) {\n\t\tif (_bbox.x.min < bbox.x.min) bbox.x.min = _bbox.x.min;\n\t\tif (_bbox.y.min < bbox.y.min) bbox.y.min = _bbox.y.min;\n\t\tif (_bbox.z && _bbox.z.min < bbox.z.min) bbox.z.min = _bbox.z.min;\n\t\tif (_bbox.x.max > bbox.x.max) bbox.x.max = _bbox.x.max;\n\t\tif (_bbox.y.max > bbox.y.max) bbox.y.max = _bbox.y.max;\n\t\tif (_bbox.z && _bbox.z.max > bbox.z.max) bbox.z.max = _bbox.z.max;\n\t\tbbox.x.mid = (bbox.x.min + bbox.x.max) / 2;\n\t\tbbox.y.mid = (bbox.y.min + bbox.y.max) / 2;\n\t\tif (bbox.z) bbox.z.mid = (bbox.z.min + bbox.z.max) / 2;\n\t\tbbox.x.size = bbox.x.max - bbox.x.min;\n\t\tbbox.y.size = bbox.y.max - bbox.y.min;\n\t\tif (bbox.z) bbox.z.size = bbox.z.max - bbox.z.min;\n\t},\n\tpairiteration: function(c1, c2, curveIntersectionThreshold) {\n\t\tconst c1b = c1.bbox(), c2b = c2.bbox(), r = 1e5, threshold = curveIntersectionThreshold || .5;\n\t\tif (c1b.x.size + c1b.y.size < threshold && c2b.x.size + c2b.y.size < threshold) return [(r * (c1._t1 + c1._t2) / 2 | 0) / r + \"/\" + (r * (c2._t1 + c2._t2) / 2 | 0) / r];\n\t\tlet cc1 = c1.split(.5), cc2 = c2.split(.5), pairs = [\n\t\t\t{\n\t\t\t\tleft: cc1.left,\n\t\t\t\tright: cc2.left\n\t\t\t},\n\t\t\t{\n\t\t\t\tleft: cc1.left,\n\t\t\t\tright: cc2.right\n\t\t\t},\n\t\t\t{\n\t\t\t\tleft: cc1.right,\n\t\t\t\tright: cc2.right\n\t\t\t},\n\t\t\t{\n\t\t\t\tleft: cc1.right,\n\t\t\t\tright: cc2.left\n\t\t\t}\n\t\t];\n\t\tpairs = pairs.filter(function(pair) {\n\t\t\treturn utils.bboxoverlap(pair.left.bbox(), pair.right.bbox());\n\t\t});\n\t\tlet results = [];\n\t\tif (pairs.length === 0) return results;\n\t\tpairs.forEach(function(pair) {\n\t\t\tresults = results.concat(utils.pairiteration(pair.left, pair.right, threshold));\n\t\t});\n\t\tresults = results.filter(function(v, i) {\n\t\t\treturn results.indexOf(v) === i;\n\t\t});\n\t\treturn results;\n\t},\n\tgetccenter: function(p1, p2, p3) {\n\t\tconst dx1 = p2.x - p1.x, dy1 = p2.y - p1.y, dx2 = p3.x - p2.x, dy2 = p3.y - p2.y, dx1p = dx1 * cos$1(quart) - dy1 * sin$1(quart), dy1p = dx1 * sin$1(quart) + dy1 * cos$1(quart), dx2p = dx2 * cos$1(quart) - dy2 * sin$1(quart), dy2p = dx2 * sin$1(quart) + dy2 * cos$1(quart), mx1 = (p1.x + p2.x) / 2, my1 = (p1.y + p2.y) / 2, mx2 = (p2.x + p3.x) / 2, my2 = (p2.y + p3.y) / 2, mx1n = mx1 + dx1p, my1n = my1 + dy1p, mx2n = mx2 + dx2p, my2n = my2 + dy2p, arc = utils.lli8(mx1, my1, mx1n, my1n, mx2, my2, mx2n, my2n), r = utils.dist(arc, p1);\n\t\tlet s = atan2(p1.y - arc.y, p1.x - arc.x), m = atan2(p2.y - arc.y, p2.x - arc.x), e = atan2(p3.y - arc.y, p3.x - arc.x), _;\n\t\tif (s < e) {\n\t\t\tif (s > m || m > e) s += tau;\n\t\t\tif (s > e) {\n\t\t\t\t_ = e;\n\t\t\t\te = s;\n\t\t\t\ts = _;\n\t\t\t}\n\t\t} else if (e < m && m < s) {\n\t\t\t_ = e;\n\t\t\te = s;\n\t\t\ts = _;\n\t\t} else e += tau;\n\t\tarc.s = s;\n\t\tarc.e = e;\n\t\tarc.r = r;\n\t\treturn arc;\n\t},\n\tnumberSort: function(a, b) {\n\t\treturn a - b;\n\t}\n};\n//#endregion\n//#region ../../node_modules/.pnpm/bezier-js@6.1.4/node_modules/bezier-js/src/poly-bezier.js\n/**\n* Poly Bezier\n* @param {[type]} curves [description]\n*/\nvar PolyBezier = class PolyBezier {\n\tconstructor(curves) {\n\t\tthis.curves = [];\n\t\tthis._3d = false;\n\t\tif (!!curves) {\n\t\t\tthis.curves = curves;\n\t\t\tthis._3d = this.curves[0]._3d;\n\t\t}\n\t}\n\tvalueOf() {\n\t\treturn this.toString();\n\t}\n\ttoString() {\n\t\treturn \"[\" + this.curves.map(function(curve) {\n\t\t\treturn utils.pointsToString(curve.points);\n\t\t}).join(\", \") + \"]\";\n\t}\n\taddCurve(curve) {\n\t\tthis.curves.push(curve);\n\t\tthis._3d = this._3d || curve._3d;\n\t}\n\tlength() {\n\t\treturn this.curves.map(function(v) {\n\t\t\treturn v.length();\n\t\t}).reduce(function(a, b) {\n\t\t\treturn a + b;\n\t\t});\n\t}\n\tcurve(idx) {\n\t\treturn this.curves[idx];\n\t}\n\tbbox() {\n\t\tconst c = this.curves;\n\t\tvar bbox = c[0].bbox();\n\t\tfor (var i = 1; i < c.length; i++) utils.expandbox(bbox, c[i].bbox());\n\t\treturn bbox;\n\t}\n\toffset(d) {\n\t\tconst offset = [];\n\t\tthis.curves.forEach(function(v) {\n\t\t\toffset.push(...v.offset(d));\n\t\t});\n\t\treturn new PolyBezier(offset);\n\t}\n};\n//#endregion\n//#region ../../node_modules/.pnpm/bezier-js@6.1.4/node_modules/bezier-js/src/bezier.js\n/**\nA javascript Bezier curve library by Pomax.\n\nBased on http://pomax.github.io/bezierinfo\n\nThis code is MIT licensed.\n**/\nconst { abs, min, max, cos, sin, acos, sqrt } = Math;\nconst pi = Math.PI;\n/**\n* Bezier curve constructor.\n*\n* ...docs pending...\n*/\nvar Bezier = class Bezier {\n\tconstructor(coords) {\n\t\tlet args = coords && coords.forEach ? coords : Array.from(arguments).slice();\n\t\tlet coordlen = false;\n\t\tif (typeof args[0] === \"object\") {\n\t\t\tcoordlen = args.length;\n\t\t\tconst newargs = [];\n\t\t\targs.forEach(function(point) {\n\t\t\t\t[\n\t\t\t\t\t\"x\",\n\t\t\t\t\t\"y\",\n\t\t\t\t\t\"z\"\n\t\t\t\t].forEach(function(d) {\n\t\t\t\t\tif (typeof point[d] !== \"undefined\") newargs.push(point[d]);\n\t\t\t\t});\n\t\t\t});\n\t\t\targs = newargs;\n\t\t}\n\t\tlet higher = false;\n\t\tconst len = args.length;\n\t\tif (coordlen) {\n\t\t\tif (coordlen > 4) {\n\t\t\t\tif (arguments.length !== 1) throw new Error(\"Only new Bezier(point[]) is accepted for 4th and higher order curves\");\n\t\t\t\thigher = true;\n\t\t\t}\n\t\t} else if (len !== 6 && len !== 8 && len !== 9 && len !== 12) {\n\t\t\tif (arguments.length !== 1) throw new Error(\"Only new Bezier(point[]) is accepted for 4th and higher order curves\");\n\t\t}\n\t\tconst _3d = this._3d = !higher && (len === 9 || len === 12) || coords && coords[0] && typeof coords[0].z !== \"undefined\";\n\t\tconst points = this.points = [];\n\t\tfor (let idx = 0, step = _3d ? 3 : 2; idx < len; idx += step) {\n\t\t\tvar point = {\n\t\t\t\tx: args[idx],\n\t\t\t\ty: args[idx + 1]\n\t\t\t};\n\t\t\tif (_3d) point.z = args[idx + 2];\n\t\t\tpoints.push(point);\n\t\t}\n\t\tconst order = this.order = points.length - 1;\n\t\tconst dims = this.dims = [\"x\", \"y\"];\n\t\tif (_3d) dims.push(\"z\");\n\t\tthis.dimlen = dims.length;\n\t\tconst aligned = utils.align(points, {\n\t\t\tp1: points[0],\n\t\t\tp2: points[order]\n\t\t});\n\t\tconst baselength = utils.dist(points[0], points[order]);\n\t\tthis._linear = aligned.reduce((t, p) => t + abs(p.y), 0) < baselength / 50;\n\t\tthis._lut = [];\n\t\tthis._t1 = 0;\n\t\tthis._t2 = 1;\n\t\tthis.update();\n\t}\n\tstatic quadraticFromPoints(p1, p2, p3, t) {\n\t\tif (typeof t === \"undefined\") t = .5;\n\t\tif (t === 0) return new Bezier(p2, p2, p3);\n\t\tif (t === 1) return new Bezier(p1, p2, p2);\n\t\treturn new Bezier(p1, Bezier.getABC(2, p1, p2, p3, t).A, p3);\n\t}\n\tstatic cubicFromPoints(S, B, E, t, d1) {\n\t\tif (typeof t === \"undefined\") t = .5;\n\t\tconst abc = Bezier.getABC(3, S, B, E, t);\n\t\tif (typeof d1 === \"undefined\") d1 = utils.dist(B, abc.C);\n\t\tconst d2 = d1 * (1 - t) / t;\n\t\tconst selen = utils.dist(S, E), lx = (E.x - S.x) / selen, ly = (E.y - S.y) / selen, bx1 = d1 * lx, by1 = d1 * ly, bx2 = d2 * lx, by2 = d2 * ly;\n\t\tconst e1 = {\n\t\t\tx: B.x - bx1,\n\t\t\ty: B.y - by1\n\t\t}, e2 = {\n\t\t\tx: B.x + bx2,\n\t\t\ty: B.y + by2\n\t\t}, A = abc.A, v1 = {\n\t\t\tx: A.x + (e1.x - A.x) / (1 - t),\n\t\t\ty: A.y + (e1.y - A.y) / (1 - t)\n\t\t}, v2 = {\n\t\t\tx: A.x + (e2.x - A.x) / t,\n\t\t\ty: A.y + (e2.y - A.y) / t\n\t\t};\n\t\treturn new Bezier(S, {\n\t\t\tx: S.x + (v1.x - S.x) / t,\n\t\t\ty: S.y + (v1.y - S.y) / t\n\t\t}, {\n\t\t\tx: E.x + (v2.x - E.x) / (1 - t),\n\t\t\ty: E.y + (v2.y - E.y) / (1 - t)\n\t\t}, E);\n\t}\n\tstatic getUtils() {\n\t\treturn utils;\n\t}\n\tgetUtils() {\n\t\treturn Bezier.getUtils();\n\t}\n\tstatic get PolyBezier() {\n\t\treturn PolyBezier;\n\t}\n\tvalueOf() {\n\t\treturn this.toString();\n\t}\n\ttoString() {\n\t\treturn utils.pointsToString(this.points);\n\t}\n\ttoSVG() {\n\t\tif (this._3d) return false;\n\t\tconst p = this.points, s = [\n\t\t\t\"M\",\n\t\t\tp[0].x,\n\t\t\tp[0].y,\n\t\t\tthis.order === 2 ? \"Q\" : \"C\"\n\t\t];\n\t\tfor (let i = 1, last = p.length; i < last; i++) {\n\t\t\ts.push(p[i].x);\n\t\t\ts.push(p[i].y);\n\t\t}\n\t\treturn s.join(\" \");\n\t}\n\tsetRatios(ratios) {\n\t\tif (ratios.length !== this.points.length) throw new Error(\"incorrect number of ratio values\");\n\t\tthis.ratios = ratios;\n\t\tthis._lut = [];\n\t}\n\tverify() {\n\t\tconst print = this.coordDigest();\n\t\tif (print !== this._print) {\n\t\t\tthis._print = print;\n\t\t\tthis.update();\n\t\t}\n\t}\n\tcoordDigest() {\n\t\treturn this.points.map(function(c, pos) {\n\t\t\treturn \"\" + pos + c.x + c.y + (c.z ? c.z : 0);\n\t\t}).join(\"\");\n\t}\n\tupdate() {\n\t\tthis._lut = [];\n\t\tthis.dpoints = utils.derive(this.points, this._3d);\n\t\tthis.computedirection();\n\t}\n\tcomputedirection() {\n\t\tconst points = this.points;\n\t\tthis.clockwise = utils.angle(points[0], points[this.order], points[1]) > 0;\n\t}\n\tlength() {\n\t\treturn utils.length(this.derivative.bind(this));\n\t}\n\tstatic getABC(order = 2, S, B, E, t = .5) {\n\t\tconst u = utils.projectionratio(t, order), um = 1 - u, C = {\n\t\t\tx: u * S.x + um * E.x,\n\t\t\ty: u * S.y + um * E.y\n\t\t}, s = utils.abcratio(t, order);\n\t\treturn {\n\t\t\tA: {\n\t\t\t\tx: B.x + (B.x - C.x) / s,\n\t\t\t\ty: B.y + (B.y - C.y) / s\n\t\t\t},\n\t\t\tB,\n\t\t\tC,\n\t\t\tS,\n\t\t\tE\n\t\t};\n\t}\n\tgetABC(t, B) {\n\t\tB = B || this.get(t);\n\t\tlet S = this.points[0];\n\t\tlet E = this.points[this.order];\n\t\treturn Bezier.getABC(this.order, S, B, E, t);\n\t}\n\tgetLUT(steps) {\n\t\tthis.verify();\n\t\tsteps = steps || 100;\n\t\tif (this._lut.length === steps + 1) return this._lut;\n\t\tthis._lut = [];\n\t\tsteps++;\n\t\tthis._lut = [];\n\t\tfor (let i = 0, p, t; i < steps; i++) {\n\t\t\tt = i / (steps - 1);\n\t\t\tp = this.compute(t);\n\t\t\tp.t = t;\n\t\t\tthis._lut.push(p);\n\t\t}\n\t\treturn this._lut;\n\t}\n\ton(point, error) {\n\t\terror = error || 5;\n\t\tconst lut = this.getLUT(), hits = [];\n\t\tfor (let i = 0, c, t = 0; i < lut.length; i++) {\n\t\t\tc = lut[i];\n\t\t\tif (utils.dist(c, point) < error) {\n\t\t\t\thits.push(c);\n\t\t\t\tt += i / lut.length;\n\t\t\t}\n\t\t}\n\t\tif (!hits.length) return false;\n\t\treturn t /= hits.length;\n\t}\n\tproject(point) {\n\t\tconst LUT = this.getLUT(), l = LUT.length - 1, closest = utils.closest(LUT, point), mpos = closest.mpos, t1 = (mpos - 1) / l, t2 = (mpos + 1) / l, step = .1 / l;\n\t\tlet mdist = closest.mdist, t = t1, ft = t, p;\n\t\tmdist += 1;\n\t\tfor (let d; t < t2 + step; t += step) {\n\t\t\tp = this.compute(t);\n\t\t\td = utils.dist(point, p);\n\t\t\tif (d < mdist) {\n\t\t\t\tmdist = d;\n\t\t\t\tft = t;\n\t\t\t}\n\t\t}\n\t\tft = ft < 0 ? 0 : ft > 1 ? 1 : ft;\n\t\tp = this.compute(ft);\n\t\tp.t = ft;\n\t\tp.d = mdist;\n\t\treturn p;\n\t}\n\tget(t) {\n\t\treturn this.compute(t);\n\t}\n\tpoint(idx) {\n\t\treturn this.points[idx];\n\t}\n\tcompute(t) {\n\t\tif (this.ratios) return utils.computeWithRatios(t, this.points, this.ratios, this._3d);\n\t\treturn utils.compute(t, this.points, this._3d, this.ratios);\n\t}\n\traise() {\n\t\tconst p = this.points, np = [p[0]], k = p.length;\n\t\tfor (let i = 1, pi, pim; i < k; i++) {\n\t\t\tpi = p[i];\n\t\t\tpim = p[i - 1];\n\t\t\tnp[i] = {\n\t\t\t\tx: (k - i) / k * pi.x + i / k * pim.x,\n\t\t\t\ty: (k - i) / k * pi.y + i / k * pim.y\n\t\t\t};\n\t\t}\n\t\tnp[k] = p[k - 1];\n\t\treturn new Bezier(np);\n\t}\n\tderivative(t) {\n\t\treturn utils.compute(t, this.dpoints[0], this._3d);\n\t}\n\tdderivative(t) {\n\t\treturn utils.compute(t, this.dpoints[1], this._3d);\n\t}\n\talign() {\n\t\tlet p = this.points;\n\t\treturn new Bezier(utils.align(p, {\n\t\t\tp1: p[0],\n\t\t\tp2: p[p.length - 1]\n\t\t}));\n\t}\n\tcurvature(t) {\n\t\treturn utils.curvature(t, this.dpoints[0], this.dpoints[1], this._3d);\n\t}\n\tinflections() {\n\t\treturn utils.inflections(this.points);\n\t}\n\tnormal(t) {\n\t\treturn this._3d ? this.__normal3(t) : this.__normal2(t);\n\t}\n\t__normal2(t) {\n\t\tconst d = this.derivative(t);\n\t\tconst q = sqrt(d.x * d.x + d.y * d.y);\n\t\treturn {\n\t\t\tt,\n\t\t\tx: -d.y / q,\n\t\t\ty: d.x / q\n\t\t};\n\t}\n\t__normal3(t) {\n\t\tconst r1 = this.derivative(t), r2 = this.derivative(t + .01), q1 = sqrt(r1.x * r1.x + r1.y * r1.y + r1.z * r1.z), q2 = sqrt(r2.x * r2.x + r2.y * r2.y + r2.z * r2.z);\n\t\tr1.x /= q1;\n\t\tr1.y /= q1;\n\t\tr1.z /= q1;\n\t\tr2.x /= q2;\n\t\tr2.y /= q2;\n\t\tr2.z /= q2;\n\t\tconst c = {\n\t\t\tx: r2.y * r1.z - r2.z * r1.y,\n\t\t\ty: r2.z * r1.x - r2.x * r1.z,\n\t\t\tz: r2.x * r1.y - r2.y * r1.x\n\t\t};\n\t\tconst m = sqrt(c.x * c.x + c.y * c.y + c.z * c.z);\n\t\tc.x /= m;\n\t\tc.y /= m;\n\t\tc.z /= m;\n\t\tconst R = [\n\t\t\tc.x * c.x,\n\t\t\tc.x * c.y - c.z,\n\t\t\tc.x * c.z + c.y,\n\t\t\tc.x * c.y + c.z,\n\t\t\tc.y * c.y,\n\t\t\tc.y * c.z - c.x,\n\t\t\tc.x * c.z - c.y,\n\t\t\tc.y * c.z + c.x,\n\t\t\tc.z * c.z\n\t\t];\n\t\treturn {\n\t\t\tt,\n\t\t\tx: R[0] * r1.x + R[1] * r1.y + R[2] * r1.z,\n\t\t\ty: R[3] * r1.x + R[4] * r1.y + R[5] * r1.z,\n\t\t\tz: R[6] * r1.x + R[7] * r1.y + R[8] * r1.z\n\t\t};\n\t}\n\thull(t) {\n\t\tlet p = this.points, _p = [], q = [], idx = 0;\n\t\tq[idx++] = p[0];\n\t\tq[idx++] = p[1];\n\t\tq[idx++] = p[2];\n\t\tif (this.order === 3) q[idx++] = p[3];\n\t\twhile (p.length > 1) {\n\t\t\t_p = [];\n\t\t\tfor (let i = 0, pt, l = p.length - 1; i < l; i++) {\n\t\t\t\tpt = utils.lerp(t, p[i], p[i + 1]);\n\t\t\t\tq[idx++] = pt;\n\t\t\t\t_p.push(pt);\n\t\t\t}\n\t\t\tp = _p;\n\t\t}\n\t\treturn q;\n\t}\n\tsplit(t1, t2) {\n\t\tif (t1 === 0 && !!t2) return this.split(t2).left;\n\t\tif (t2 === 1) return this.split(t1).right;\n\t\tconst q = this.hull(t1);\n\t\tconst result = {\n\t\t\tleft: this.order === 2 ? new Bezier([\n\t\t\t\tq[0],\n\t\t\t\tq[3],\n\t\t\t\tq[5]\n\t\t\t]) : new Bezier([\n\t\t\t\tq[0],\n\t\t\t\tq[4],\n\t\t\t\tq[7],\n\t\t\t\tq[9]\n\t\t\t]),\n\t\t\tright: this.order === 2 ? new Bezier([\n\t\t\t\tq[5],\n\t\t\t\tq[4],\n\t\t\t\tq[2]\n\t\t\t]) : new Bezier([\n\t\t\t\tq[9],\n\t\t\t\tq[8],\n\t\t\t\tq[6],\n\t\t\t\tq[3]\n\t\t\t]),\n\t\t\tspan: q\n\t\t};\n\t\tresult.left._t1 = utils.map(0, 0, 1, this._t1, this._t2);\n\t\tresult.left._t2 = utils.map(t1, 0, 1, this._t1, this._t2);\n\t\tresult.right._t1 = utils.map(t1, 0, 1, this._t1, this._t2);\n\t\tresult.right._t2 = utils.map(1, 0, 1, this._t1, this._t2);\n\t\tif (!t2) return result;\n\t\tt2 = utils.map(t2, t1, 1, 0, 1);\n\t\treturn result.right.split(t2).left;\n\t}\n\textrema() {\n\t\tconst result = {};\n\t\tlet roots = [];\n\t\tthis.dims.forEach(function(dim) {\n\t\t\tlet mfn = function(v) {\n\t\t\t\treturn v[dim];\n\t\t\t};\n\t\t\tlet p = this.dpoints[0].map(mfn);\n\t\t\tresult[dim] = utils.droots(p);\n\t\t\tif (this.order === 3) {\n\t\t\t\tp = this.dpoints[1].map(mfn);\n\t\t\t\tresult[dim] = result[dim].concat(utils.droots(p));\n\t\t\t}\n\t\t\tresult[dim] = result[dim].filter(function(t) {\n\t\t\t\treturn t >= 0 && t <= 1;\n\t\t\t});\n\t\t\troots = roots.concat(result[dim].sort(utils.numberSort));\n\t\t}.bind(this));\n\t\tresult.values = roots.sort(utils.numberSort).filter(function(v, idx) {\n\t\t\treturn roots.indexOf(v) === idx;\n\t\t});\n\t\treturn result;\n\t}\n\tbbox() {\n\t\tconst extrema = this.extrema(), result = {};\n\t\tthis.dims.forEach(function(d) {\n\t\t\tresult[d] = utils.getminmax(this, d, extrema[d]);\n\t\t}.bind(this));\n\t\treturn result;\n\t}\n\toverlaps(curve) {\n\t\tconst lbbox = this.bbox(), tbbox = curve.bbox();\n\t\treturn utils.bboxoverlap(lbbox, tbbox);\n\t}\n\toffset(t, d) {\n\t\tif (typeof d !== \"undefined\") {\n\t\t\tconst c = this.get(t), n = this.normal(t);\n\t\t\tconst ret = {\n\t\t\t\tc,\n\t\t\t\tn,\n\t\t\t\tx: c.x + n.x * d,\n\t\t\t\ty: c.y + n.y * d\n\t\t\t};\n\t\t\tif (this._3d) ret.z = c.z + n.z * d;\n\t\t\treturn ret;\n\t\t}\n\t\tif (this._linear) {\n\t\t\tconst nv = this.normal(0);\n\t\t\treturn [new Bezier(this.points.map(function(p) {\n\t\t\t\tconst ret = {\n\t\t\t\t\tx: p.x + t * nv.x,\n\t\t\t\t\ty: p.y + t * nv.y\n\t\t\t\t};\n\t\t\t\tif (p.z && nv.z) ret.z = p.z + t * nv.z;\n\t\t\t\treturn ret;\n\t\t\t}))];\n\t\t}\n\t\treturn this.reduce().map(function(s) {\n\t\t\tif (s._linear) return s.offset(t)[0];\n\t\t\treturn s.scale(t);\n\t\t});\n\t}\n\tsimple() {\n\t\tif (this.order === 3) {\n\t\t\tconst a1 = utils.angle(this.points[0], this.points[3], this.points[1]);\n\t\t\tconst a2 = utils.angle(this.points[0], this.points[3], this.points[2]);\n\t\t\tif (a1 > 0 && a2 < 0 || a1 < 0 && a2 > 0) return false;\n\t\t}\n\t\tconst n1 = this.normal(0);\n\t\tconst n2 = this.normal(1);\n\t\tlet s = n1.x * n2.x + n1.y * n2.y;\n\t\tif (this._3d) s += n1.z * n2.z;\n\t\treturn abs(acos(s)) < pi / 3;\n\t}\n\treduce() {\n\t\tlet i, t1 = 0, t2 = 0, step = .01, segment, pass1 = [], pass2 = [];\n\t\tlet extrema = this.extrema().values;\n\t\tif (extrema.indexOf(0) === -1) extrema = [0].concat(extrema);\n\t\tif (extrema.indexOf(1) === -1) extrema.push(1);\n\t\tfor (t1 = extrema[0], i = 1; i < extrema.length; i++) {\n\t\t\tt2 = extrema[i];\n\t\t\tsegment = this.split(t1, t2);\n\t\t\tsegment._t1 = t1;\n\t\t\tsegment._t2 = t2;\n\t\t\tpass1.push(segment);\n\t\t\tt1 = t2;\n\t\t}\n\t\tpass1.forEach(function(p1) {\n\t\t\tt1 = 0;\n\t\t\tt2 = 0;\n\t\t\twhile (t2 <= 1) for (t2 = t1 + step; t2 <= 1 + step; t2 += step) {\n\t\t\t\tsegment = p1.split(t1, t2);\n\t\t\t\tif (!segment.simple()) {\n\t\t\t\t\tt2 -= step;\n\t\t\t\t\tif (abs(t1 - t2) < step) return [];\n\t\t\t\t\tsegment = p1.split(t1, t2);\n\t\t\t\t\tsegment._t1 = utils.map(t1, 0, 1, p1._t1, p1._t2);\n\t\t\t\t\tsegment._t2 = utils.map(t2, 0, 1, p1._t1, p1._t2);\n\t\t\t\t\tpass2.push(segment);\n\t\t\t\t\tt1 = t2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (t1 < 1) {\n\t\t\t\tsegment = p1.split(t1, 1);\n\t\t\t\tsegment._t1 = utils.map(t1, 0, 1, p1._t1, p1._t2);\n\t\t\t\tsegment._t2 = p1._t2;\n\t\t\t\tpass2.push(segment);\n\t\t\t}\n\t\t});\n\t\treturn pass2;\n\t}\n\ttranslate(v, d1, d2) {\n\t\td2 = typeof d2 === \"number\" ? d2 : d1;\n\t\tconst o = this.order;\n\t\tlet d = this.points.map((_, i) => (1 - i / o) * d1 + i / o * d2);\n\t\treturn new Bezier(this.points.map((p, i) => ({\n\t\t\tx: p.x + v.x * d[i],\n\t\t\ty: p.y + v.y * d[i]\n\t\t})));\n\t}\n\tscale(d) {\n\t\tconst order = this.order;\n\t\tlet distanceFn = false;\n\t\tif (typeof d === \"function\") distanceFn = d;\n\t\tif (distanceFn && order === 2) return this.raise().scale(distanceFn);\n\t\tconst clockwise = this.clockwise;\n\t\tconst points = this.points;\n\t\tif (this._linear) return this.translate(this.normal(0), distanceFn ? distanceFn(0) : d, distanceFn ? distanceFn(1) : d);\n\t\tconst r1 = distanceFn ? distanceFn(0) : d;\n\t\tconst r2 = distanceFn ? distanceFn(1) : d;\n\t\tconst v = [this.offset(0, 10), this.offset(1, 10)];\n\t\tconst np = [];\n\t\tconst o = utils.lli4(v[0], v[0].c, v[1], v[1].c);\n\t\tif (!o) throw new Error(\"cannot scale this curve. Try reducing it first.\");\n\t\t[0, 1].forEach(function(t) {\n\t\t\tconst p = np[t * order] = utils.copy(points[t * order]);\n\t\t\tp.x += (t ? r2 : r1) * v[t].n.x;\n\t\t\tp.y += (t ? r2 : r1) * v[t].n.y;\n\t\t});\n\t\tif (!distanceFn) {\n\t\t\t[0, 1].forEach((t) => {\n\t\t\t\tif (order === 2 && !!t) return;\n\t\t\t\tconst p = np[t * order];\n\t\t\t\tconst d = this.derivative(t);\n\t\t\t\tconst p2 = {\n\t\t\t\t\tx: p.x + d.x,\n\t\t\t\t\ty: p.y + d.y\n\t\t\t\t};\n\t\t\t\tnp[t + 1] = utils.lli4(p, p2, o, points[t + 1]);\n\t\t\t});\n\t\t\treturn new Bezier(np);\n\t\t}\n\t\t[0, 1].forEach(function(t) {\n\t\t\tif (order === 2 && !!t) return;\n\t\t\tvar p = points[t + 1];\n\t\t\tvar ov = {\n\t\t\t\tx: p.x - o.x,\n\t\t\t\ty: p.y - o.y\n\t\t\t};\n\t\t\tvar rc = distanceFn ? distanceFn((t + 1) / order) : d;\n\t\t\tif (distanceFn && !clockwise) rc = -rc;\n\t\t\tvar m = sqrt(ov.x * ov.x + ov.y * ov.y);\n\t\t\tov.x /= m;\n\t\t\tov.y /= m;\n\t\t\tnp[t + 1] = {\n\t\t\t\tx: p.x + rc * ov.x,\n\t\t\t\ty: p.y + rc * ov.y\n\t\t\t};\n\t\t});\n\t\treturn new Bezier(np);\n\t}\n\toutline(d1, d2, d3, d4) {\n\t\td2 = d2 === void 0 ? d1 : d2;\n\t\tif (this._linear) {\n\t\t\tconst n = this.normal(0);\n\t\t\tconst start = this.points[0];\n\t\t\tconst end = this.points[this.points.length - 1];\n\t\t\tlet s, mid, e;\n\t\t\tif (d3 === void 0) {\n\t\t\t\td3 = d1;\n\t\t\t\td4 = d2;\n\t\t\t}\n\t\t\ts = {\n\t\t\t\tx: start.x + n.x * d1,\n\t\t\t\ty: start.y + n.y * d1\n\t\t\t};\n\t\t\te = {\n\t\t\t\tx: end.x + n.x * d3,\n\t\t\t\ty: end.y + n.y * d3\n\t\t\t};\n\t\t\tmid = {\n\t\t\t\tx: (s.x + e.x) / 2,\n\t\t\t\ty: (s.y + e.y) / 2\n\t\t\t};\n\t\t\tconst fline = [\n\t\t\t\ts,\n\t\t\t\tmid,\n\t\t\t\te\n\t\t\t];\n\t\t\ts = {\n\t\t\t\tx: start.x - n.x * d2,\n\t\t\t\ty: start.y - n.y * d2\n\t\t\t};\n\t\t\te = {\n\t\t\t\tx: end.x - n.x * d4,\n\t\t\t\ty: end.y - n.y * d4\n\t\t\t};\n\t\t\tmid = {\n\t\t\t\tx: (s.x + e.x) / 2,\n\t\t\t\ty: (s.y + e.y) / 2\n\t\t\t};\n\t\t\tconst bline = [\n\t\t\t\te,\n\t\t\t\tmid,\n\t\t\t\ts\n\t\t\t];\n\t\t\tconst ls = utils.makeline(bline[2], fline[0]);\n\t\t\tconst le = utils.makeline(fline[2], bline[0]);\n\t\t\treturn new PolyBezier([\n\t\t\t\tls,\n\t\t\t\tnew Bezier(fline),\n\t\t\t\tle,\n\t\t\t\tnew Bezier(bline)\n\t\t\t]);\n\t\t}\n\t\tconst reduced = this.reduce(), len = reduced.length, fcurves = [];\n\t\tlet bcurves = [], p, alen = 0, tlen = this.length();\n\t\tconst graduated = typeof d3 !== \"undefined\" && typeof d4 !== \"undefined\";\n\t\tfunction linearDistanceFunction(s, e, tlen, alen, slen) {\n\t\t\treturn function(v) {\n\t\t\t\tconst f1 = alen / tlen, f2 = (alen + slen) / tlen, d = e - s;\n\t\t\t\treturn utils.map(v, 0, 1, s + f1 * d, s + f2 * d);\n\t\t\t};\n\t\t}\n\t\treduced.forEach(function(segment) {\n\t\t\tconst slen = segment.length();\n\t\t\tif (graduated) {\n\t\t\t\tfcurves.push(segment.scale(linearDistanceFunction(d1, d3, tlen, alen, slen)));\n\t\t\t\tbcurves.push(segment.scale(linearDistanceFunction(-d2, -d4, tlen, alen, slen)));\n\t\t\t} else {\n\t\t\t\tfcurves.push(segment.scale(d1));\n\t\t\t\tbcurves.push(segment.scale(-d2));\n\t\t\t}\n\t\t\talen += slen;\n\t\t});\n\t\tbcurves = bcurves.map(function(s) {\n\t\t\tp = s.points;\n\t\t\tif (p[3]) s.points = [\n\t\t\t\tp[3],\n\t\t\t\tp[2],\n\t\t\t\tp[1],\n\t\t\t\tp[0]\n\t\t\t];\n\t\t\telse s.points = [\n\t\t\t\tp[2],\n\t\t\t\tp[1],\n\t\t\t\tp[0]\n\t\t\t];\n\t\t\treturn s;\n\t\t}).reverse();\n\t\tconst fs = fcurves[0].points[0], fe = fcurves[len - 1].points[fcurves[len - 1].points.length - 1], bs = bcurves[len - 1].points[bcurves[len - 1].points.length - 1], be = bcurves[0].points[0], ls = utils.makeline(bs, fs), le = utils.makeline(fe, be);\n\t\treturn new PolyBezier([ls].concat(fcurves).concat([le]).concat(bcurves));\n\t}\n\toutlineshapes(d1, d2, curveIntersectionThreshold) {\n\t\td2 = d2 || d1;\n\t\tconst outline = this.outline(d1, d2).curves;\n\t\tconst shapes = [];\n\t\tfor (let i = 1, len = outline.length; i < len / 2; i++) {\n\t\t\tconst shape = utils.makeshape(outline[i], outline[len - i], curveIntersectionThreshold);\n\t\t\tshape.startcap.virtual = i > 1;\n\t\t\tshape.endcap.virtual = i < len / 2 - 1;\n\t\t\tshapes.push(shape);\n\t\t}\n\t\treturn shapes;\n\t}\n\tintersects(curve, curveIntersectionThreshold) {\n\t\tif (!curve) return this.selfintersects(curveIntersectionThreshold);\n\t\tif (curve.p1 && curve.p2) return this.lineIntersects(curve);\n\t\tif (curve instanceof Bezier) curve = curve.reduce();\n\t\treturn this.curveintersects(this.reduce(), curve, curveIntersectionThreshold);\n\t}\n\tlineIntersects(line) {\n\t\tconst mx = min(line.p1.x, line.p2.x), my = min(line.p1.y, line.p2.y), MX = max(line.p1.x, line.p2.x), MY = max(line.p1.y, line.p2.y);\n\t\treturn utils.roots(this.points, line).filter((t) => {\n\t\t\tvar p = this.get(t);\n\t\t\treturn utils.between(p.x, mx, MX) && utils.between(p.y, my, MY);\n\t\t});\n\t}\n\tselfintersects(curveIntersectionThreshold) {\n\t\tconst reduced = this.reduce(), len = reduced.length - 2, results = [];\n\t\tfor (let i = 0, result, left, right; i < len; i++) {\n\t\t\tleft = reduced.slice(i, i + 1);\n\t\t\tright = reduced.slice(i + 2);\n\t\t\tresult = this.curveintersects(left, right, curveIntersectionThreshold);\n\t\t\tresults.push(...result);\n\t\t}\n\t\treturn results;\n\t}\n\tcurveintersects(c1, c2, curveIntersectionThreshold) {\n\t\tconst pairs = [];\n\t\tc1.forEach(function(l) {\n\t\t\tc2.forEach(function(r) {\n\t\t\t\tif (l.overlaps(r)) pairs.push({\n\t\t\t\t\tleft: l,\n\t\t\t\t\tright: r\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t\tlet intersections = [];\n\t\tpairs.forEach(function(pair) {\n\t\t\tconst result = utils.pairiteration(pair.left, pair.right, curveIntersectionThreshold);\n\t\t\tif (result.length > 0) intersections = intersections.concat(result);\n\t\t});\n\t\treturn intersections;\n\t}\n\tarcs(errorThreshold) {\n\t\terrorThreshold = errorThreshold || .5;\n\t\treturn this._iterate(errorThreshold, []);\n\t}\n\t_error(pc, np1, s, e) {\n\t\tconst q = (e - s) / 4, c1 = this.get(s + q), c2 = this.get(e - q), ref = utils.dist(pc, np1), d1 = utils.dist(pc, c1), d2 = utils.dist(pc, c2);\n\t\treturn abs(d1 - ref) + abs(d2 - ref);\n\t}\n\t_iterate(errorThreshold, circles) {\n\t\tlet t_s = 0, t_e = 1, safety;\n\t\tdo {\n\t\t\tsafety = 0;\n\t\t\tt_e = 1;\n\t\t\tlet np1 = this.get(t_s), np2, np3, arc, prev_arc;\n\t\t\tlet curr_good = false, prev_good = false, done;\n\t\t\tlet t_m = t_e, prev_e = 1, step = 0;\n\t\t\tdo {\n\t\t\t\tprev_good = curr_good;\n\t\t\t\tprev_arc = arc;\n\t\t\t\tt_m = (t_s + t_e) / 2;\n\t\t\t\tstep++;\n\t\t\t\tnp2 = this.get(t_m);\n\t\t\t\tnp3 = this.get(t_e);\n\t\t\t\tarc = utils.getccenter(np1, np2, np3);\n\t\t\t\tarc.interval = {\n\t\t\t\t\tstart: t_s,\n\t\t\t\t\tend: t_e\n\t\t\t\t};\n\t\t\t\tcurr_good = this._error(arc, np1, t_s, t_e) <= errorThreshold;\n\t\t\t\tdone = prev_good && !curr_good;\n\t\t\t\tif (!done) prev_e = t_e;\n\t\t\t\tif (curr_good) {\n\t\t\t\t\tif (t_e >= 1) {\n\t\t\t\t\t\tarc.interval.end = prev_e = 1;\n\t\t\t\t\t\tprev_arc = arc;\n\t\t\t\t\t\tif (t_e > 1) {\n\t\t\t\t\t\t\tlet d = {\n\t\t\t\t\t\t\t\tx: arc.x + arc.r * cos(arc.e),\n\t\t\t\t\t\t\t\ty: arc.y + arc.r * sin(arc.e)\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tarc.e += utils.angle({\n\t\t\t\t\t\t\t\tx: arc.x,\n\t\t\t\t\t\t\t\ty: arc.y\n\t\t\t\t\t\t\t}, d, this.get(1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tt_e = t_e + (t_e - t_s) / 2;\n\t\t\t\t} else t_e = t_m;\n\t\t\t} while (!done && safety++ < 100);\n\t\t\tif (safety >= 100) break;\n\t\t\tprev_arc = prev_arc ? prev_arc : arc;\n\t\t\tcircles.push(prev_arc);\n\t\t\tt_s = prev_e;\n\t\t} while (t_e < 1);\n\t\treturn circles;\n\t}\n};\n//#endregion\n//#region src/bezier/index.ts\nvar bezier_exports = /* @__PURE__ */ __exportAll({\n\tcubic: () => cubic,\n\tinterpolator: () => interpolator,\n\tisCubicBezier: () => isCubicBezier,\n\tisQuadraticBezier: () => isQuadraticBezier,\n\tquadratic: () => quadratic,\n\tquadraticSimple: () => quadraticSimple,\n\tquadraticToSvgString: () => quadraticToSvgString,\n\ttoPath: () => toPath\n});\n/**\n* Returns a new quadratic bezier with specified bend amount\n*\n* @param {QuadraticBezier} b Curve\n* @param {number} [bend=0] Bend amount, from -1 to 1\n* @returns {QuadraticBezier}\n*/\n/**\n* Creates a simple quadratic bezier with a specified amount of 'bend'.\n* Bend of -1 will pull curve down, 1 will pull curve up. 0 is no curve.\n* \n* Use {@link interpolator} to calculate a point along the curve.\n* @param {Point} start Start of curve\n* @param {Point} end End of curve\n* @param {number} [bend=0] Bend amount, -1 to 1\n* @returns {QuadraticBezier}\n*/\nconst quadraticSimple = (start, end, bend = 0) => {\n\tif (Number.isNaN(bend)) throw new Error(`bend is NaN`);\n\tif (bend < -1 || bend > 1) throw new Error(`Expects bend range of -1 to 1`);\n\tconst middle = interpolate(.5, start, end);\n\tlet target = middle;\n\tif (end.y < start.y) target = bend > 0 ? {\n\t\tx: Math.min(start.x, end.x),\n\t\ty: Math.min(start.y, end.y)\n\t} : {\n\t\tx: Math.max(start.x, end.x),\n\t\ty: Math.max(start.y, end.y)\n\t};\n\telse target = bend > 0 ? {\n\t\tx: Math.max(start.x, end.x),\n\t\ty: Math.min(start.y, end.y)\n\t} : {\n\t\tx: Math.min(start.x, end.x),\n\t\ty: Math.max(start.y, end.y)\n\t};\n\treturn quadratic(start, end, interpolate(Math.abs(bend), middle, target));\n};\n/**\n* Returns a relative point on a simple quadratic \n* @param start Start\n* @param end End\n* @param bend Bend (-1 to 1)\n* @param amt Amount\n* @returns Point\n*/\n/**\n* Interpolate cubic or quadratic bezier\n* ```js\n* const i = interpolator(myBezier);\n* \n* // Get point at 50%\n* i(0.5); // { x, y }\n* ```\n* @param q \n* @returns \n*/\nconst interpolator = (q) => {\n\tconst bzr = isCubicBezier(q) ? new Bezier(q.a.x, q.a.y, q.cubic1.x, q.cubic1.y, q.cubic2.x, q.cubic2.y, q.b.x, q.b.y) : new Bezier(q.a, q.quadratic, q.b);\n\treturn (amount) => bzr.compute(amount);\n};\nconst quadraticToSvgString = (start, end, handle) => [`M ${start.x} ${start.y} Q ${handle.x} ${handle.y} ${end.x} ${end.y}`];\nconst toPath = (cubicOrQuadratic) => {\n\tif (isCubicBezier(cubicOrQuadratic)) return cubicToPath(cubicOrQuadratic);\n\telse if (isQuadraticBezier(cubicOrQuadratic)) return quadratictoPath(cubicOrQuadratic);\n\telse throw new Error(`Unknown bezier type`);\n};\nconst cubic = (start, end, cubic1, cubic2) => ({\n\ta: Object.freeze(start),\n\tb: Object.freeze(end),\n\tcubic1: Object.freeze(cubic1),\n\tcubic2: Object.freeze(cubic2)\n});\nconst cubicToPath = (cubic) => {\n\tconst { a, cubic1, cubic2, b } = cubic;\n\tconst bzr = new Bezier(a, cubic1, cubic2, b);\n\treturn Object.freeze({\n\t\t...cubic,\n\t\tlength: () => bzr.length(),\n\t\tinterpolate: (t) => bzr.compute(t),\n\t\tnearest: (_) => {\n\t\t\tthrow new Error(`not implemented`);\n\t\t},\n\t\tbbox: () => {\n\t\t\tconst { x, y } = bzr.bbox();\n\t\t\tconst xSize = x.size;\n\t\t\tconst ySize = y.size;\n\t\t\tif (xSize === void 0) throw new Error(`x.size not present on calculated bbox`);\n\t\t\tif (ySize === void 0) throw new Error(`x.size not present on calculated bbox`);\n\t\t\treturn fromTopLeft({\n\t\t\t\tx: x.min,\n\t\t\t\ty: y.min\n\t\t\t}, xSize, ySize);\n\t\t},\n\t\trelativePosition: (_point, _intersectionThreshold) => {\n\t\t\tthrow new Error(`Not implemented`);\n\t\t},\n\t\tdistanceToPoint: (_point) => {\n\t\t\tthrow new Error(`Not implemented`);\n\t\t},\n\t\ttoSvgString: () => [`brrup`],\n\t\tkind: `bezier/cubic`\n\t});\n};\nconst quadratic = (start, end, handle) => ({\n\ta: Object.freeze(start),\n\tb: Object.freeze(end),\n\tquadratic: Object.freeze(handle)\n});\nconst quadratictoPath = (quadraticBezier) => {\n\tconst { a, b, quadratic } = quadraticBezier;\n\tconst bzr = new Bezier(a, quadratic, b);\n\treturn Object.freeze({\n\t\t...quadraticBezier,\n\t\tlength: () => bzr.length(),\n\t\tinterpolate: (t) => bzr.compute(t),\n\t\tnearest: (_) => {\n\t\t\tthrow new Error(`not implemented`);\n\t\t},\n\t\tbbox: () => {\n\t\t\tconst { x, y } = bzr.bbox();\n\t\t\tconst xSize = x.size;\n\t\t\tconst ySize = y.size;\n\t\t\tif (xSize === void 0) throw new Error(`x.size not present on calculated bbox`);\n\t\t\tif (ySize === void 0) throw new Error(`x.size not present on calculated bbox`);\n\t\t\treturn fromTopLeft({\n\t\t\t\tx: x.min,\n\t\t\t\ty: y.min\n\t\t\t}, xSize, ySize);\n\t\t},\n\t\tdistanceToPoint: (_point) => {\n\t\t\tthrow new Error(`Not implemented`);\n\t\t},\n\t\trelativePosition: (_point, _intersectionThreshold) => {\n\t\t\tthrow new Error(`Not implemented`);\n\t\t},\n\t\ttoString: () => bzr.toString(),\n\t\ttoSvgString: () => quadraticToSvgString(a, b, quadratic),\n\t\tkind: `bezier/quadratic`\n\t});\n};\n//#endregion\nexport { quadraticSimple as a, quadratic as i, cubic as n, quadraticToSvgString as o, interpolator as r, toPath as s, bezier_exports as t };\n","import { c as isPoint3d, t as guard$1 } from \"./guard-hlhkAOMZ.js\";\nimport { a as subtract, l as getTwoPointParameters } from \"./to-oKNQeMO-.js\";\n//#region src/circle/guard.ts\n/**\n* Throws if radius is out of range. If x,y is present, these will be validated too.\n* @param circle \n* @param parameterName \n*/\nconst guard = (circle, parameterName = `circle`) => {\n\tif (isCirclePositioned(circle)) guard$1(circle, `circle`);\n\tif (Number.isNaN(circle.radius)) throw new Error(`${parameterName}.radius is NaN`);\n\tif (circle.radius <= 0) throw new Error(`${parameterName}.radius must be greater than zero`);\n};\n/**\n* Throws if `circle` is not positioned or has dodgy fields\n* @param circle \n* @param parameterName \n* @returns \n*/\nconst guardPositioned = (circle, parameterName = `circle`) => {\n\tif (!isCirclePositioned(circle)) throw new Error(`Expected a positioned circle with x,y`);\n\tguard(circle, parameterName);\n};\n/***\n* Returns true if radius, x or y are NaN\n*/\nconst isNaN = (a) => {\n\tif (Number.isNaN(a.radius)) return true;\n\tif (isCirclePositioned(a)) {\n\t\tif (Number.isNaN(a.x)) return true;\n\t\tif (Number.isNaN(a.y)) return true;\n\t}\n\treturn false;\n};\n/**\n* Returns true if parameter has x,y. Does not verify if parameter is a circle or not\n* \n* ```js\n* const circleA = { radius: 5 };\n* Circles.isPositioned(circle); // false\n* \n* const circleB = { radius: 5, x: 10, y: 10 }\n* Circles.isPositioned(circle); // true\n* ```\n* @param p Circle\n* @returns \n*/\nconst isPositioned = (p) => p.x !== void 0 && p.y !== void 0;\nconst isCircle = (p) => p.radius !== void 0;\nconst isCirclePositioned = (p) => isCircle(p) && isPositioned(p);\n//#endregion\n//#region src/circle/is-equal.ts\n/**\n* Returns true if the two objects have the same values\n*\n* ```js\n* const circleA = { radius: 10, x: 5, y: 5 };\n* const circleB = { radius: 10, x: 5, y: 5 };\n* \n* circleA === circleB; // false, because identity of objects is different\n* Circles.isEqual(circleA, circleB); // true, because values are the same\n* ```\n* \n* Circles must both be positioned or not.\n* @param a\n* @param b\n* @returns\n*/\nconst isEqual = (a, b) => {\n\tif (a.radius !== b.radius) return false;\n\tif (isCirclePositioned(a) && isCirclePositioned(b)) {\n\t\tif (a.x !== b.x) return false;\n\t\tif (a.y !== b.y) return false;\n\t\tif (a.z !== b.z) return false;\n\t\treturn true;\n\t} else if (!isCirclePositioned(a) && !isCirclePositioned(b)) return true;\n\telse return false;\n\treturn false;\n};\n//#endregion\n//#region src/point/sum.ts\n/**\n* Returns a Point with the x,y,z values of two points added.\n* \n* `z` parameter is used, if present. Uses a default value of 0 for 'z' when adding a 2D point with a 3D one.\n*\n* Examples:\n*\n* ```js\n* sum(ptA, ptB);\n* sum(x1, y1, x2, y2);\n* sum(ptA, x2, y2);\n* ```\n*/\nfunction sum(a1, ab2, ab3, ab4, ab5, ab6) {\n\tconst [ptA, ptB] = getTwoPointParameters(a1, ab2, ab3, ab4, ab5, ab6);\n\tguard$1(ptA, `a`);\n\tguard$1(ptB, `b`);\n\tconst pt = {\n\t\tx: ptA.x + ptB.x,\n\t\ty: ptA.y + ptB.y\n\t};\n\tif (isPoint3d(ptA) || isPoint3d(ptB)) pt.z = (ptA.z ?? 0) + (ptB.z ?? 0);\n\treturn Object.freeze(pt);\n}\n//#endregion\n//#region src/circle/intersections.ts\n/**\n* Returns the point(s) of intersection between a circle and line.\n* \n* ```js\n* const circle = { radius: 5, x: 5, y: 5 };\n* const line = { a: { x: 0, y: 0 }, b: { x: 10, y: 10 } };\n* const pts = Circles.intersectionLine(circle, line);\n* ```\n* @param circle \n* @param line \n* @returns Point(s) of intersection, or empty array\n*/\nconst intersectionLine = (circle, line) => {\n\tconst v1 = {\n\t\tx: line.b.x - line.a.x,\n\t\ty: line.b.y - line.a.y\n\t};\n\tconst v2 = {\n\t\tx: line.a.x - circle.x,\n\t\ty: line.a.y - circle.y\n\t};\n\tconst b = (v1.x * v2.x + v1.y * v2.y) * -2;\n\tconst c = 2 * (v1.x * v1.x + v1.y * v1.y);\n\tconst d = Math.sqrt(b * b - 2 * c * (v2.x * v2.x + v2.y * v2.y - circle.radius * circle.radius));\n\tif (Number.isNaN(d)) return [];\n\tconst u1 = (b - d) / c;\n\tconst u2 = (b + d) / c;\n\tconst returnValue = [];\n\tif (u1 <= 1 && u1 >= 0) returnValue.push({\n\t\tx: line.a.x + v1.x * u1,\n\t\ty: line.a.y + v1.y * u1\n\t});\n\tif (u2 <= 1 && u2 >= 0) returnValue.push({\n\t\tx: line.a.x + v1.x * u2,\n\t\ty: line.a.y + v1.y * u2\n\t});\n\treturn returnValue;\n};\n/**\n* \n* Returns the points of intersection betweeen `a` and `b`.\n* \n* Returns an empty array if circles are equal, one contains the other or if they don't touch at all.\n*\n* @param a Circle\n* @param b Circle\n* @returns Points of intersection, or an empty list if there are none\n*/\nconst intersections = (a, b) => {\n\tconst vector = subtract(b, a);\n\tconst centerD = Math.hypot(vector.y, vector.x);\n\tif (centerD > a.radius + b.radius) return [];\n\tif (centerD < Math.abs(a.radius - b.radius)) return [];\n\tif (isEqual(a, b)) return [];\n\tconst centroidD = (a.radius * a.radius - b.radius * b.radius + centerD * centerD) / (2 * centerD);\n\tconst centroid = {\n\t\tx: a.x + vector.x * centroidD / centerD,\n\t\ty: a.y + vector.y * centroidD / centerD\n\t};\n\tconst centroidIntersectionD = Math.sqrt(a.radius * a.radius - centroidD * centroidD);\n\tconst intersection = {\n\t\tx: -vector.y * (centroidIntersectionD / centerD),\n\t\ty: vector.x * (centroidIntersectionD / centerD)\n\t};\n\treturn [sum(centroid, intersection), subtract(centroid, intersection)];\n};\n//#endregion\n//#region src/intersects.ts\nconst circleRect = (a, b) => {\n\tconst deltaX = a.x - Math.max(b.x, Math.min(a.x, b.x + b.width));\n\tconst deltaY = a.y - Math.max(b.y, Math.min(a.y, b.y + b.height));\n\treturn deltaX * deltaX + deltaY * deltaY < a.radius * a.radius;\n};\nconst circleCircle = (a, b) => intersections(a, b).length === 2;\n//#endregion\nexport { sum as a, guardPositioned as c, isNaN as d, isPositioned as f, intersections as i, isCircle as l, circleRect as n, isEqual as o, intersectionLine as r, guard as s, circleCircle as t, isCirclePositioned as u };\n","import { c as isPoint3d, s as isPoint, t as guard } from \"./guard-hlhkAOMZ.js\";\nimport { l as getTwoPointParameters, o as distance } from \"./to-oKNQeMO-.js\";\nimport { c as guardPositioned, u as isCirclePositioned } from \"./intersects-BOuj4lnQ.js\";\n//#region src/circle/distance-center.ts\n/**\n* Returns the distance between two circle centers.\n* \n* ```js\n* const circleA = { radius: 5, x: 5, y: 5 }\n* const circleB = { radius: 10, x: 20, y: 20 }\n* const distance = Circles.distanceCenter(circleA, circleB);\n* ```\n* Throws an error if either is lacking position.\n* @param a \n* @param b \n* @returns Distance\n*/\nconst distanceCenter = (a, b) => {\n\tguardPositioned(a, `a`);\n\tif (isCirclePositioned(b)) guardPositioned(b, `b`);\n\treturn distance(a, b);\n};\n//#endregion\n//#region src/circle/distance-from-exterior.ts\n/**\n* Returns the distance between the exterior of two circles, or between the exterior of a circle and point.\n* If `b` overlaps or is enclosed by `a`, distance is 0.\n* \n* ```js\n* const circleA = { radius: 5, x: 5, y: 5 }\n* const circleB = { radius: 10, x: 20, y: 20 }\n* const distance = Circles.distanceCenter(circleA, circleB);\n* ```\n* @param a\n* @param b \n*/\nconst distanceFromExterior = (a, b) => {\n\tguardPositioned(a, `a`);\n\tif (isCirclePositioned(b)) return Math.max(0, distanceCenter(a, b) - a.radius - b.radius);\n\telse if (isPoint(b)) {\n\t\tconst distribution = distance(a, b);\n\t\tif (distribution < a.radius) return 0;\n\t\treturn distribution;\n\t} else throw new Error(`Second parameter invalid type`);\n};\n//#endregion\n//#region src/point/multiply.ts\n/**\n* Returns a Point with the x,y,z values of two points multiply (a/b).\n* \n* `z` parameter is used, if present. Uses a default value of 0 for 'z' when multiplying a 2D point with a 3D one.\n*\n* Examples:\n*\n* ```js\n* multiply(ptA, ptB);\n* multiply(x1, y1, x2, y2);\n* multiply(ptA, x2, y2);\n* ```\n*/\nfunction multiply(a1, ab2, ab3, ab4, ab5, ab6) {\n\tconst [ptA, ptB] = getTwoPointParameters(a1, ab2, ab3, ab4, ab5, ab6);\n\tguard(ptA, `a`);\n\tguard(ptB, `b`);\n\tconst pt = {\n\t\tx: ptA.x * ptB.x,\n\t\ty: ptA.y * ptB.y\n\t};\n\tif (isPoint3d(ptA) || isPoint3d(ptB)) pt.z = (ptA.z ?? 0) * (ptB.z ?? 0);\n\treturn Object.freeze(pt);\n}\n/**\n* Multiplies all components by `v`.\n* Existing properties of `pt` are maintained.\n*\n* ```js\n* multiplyScalar({ x:2, y:4 }, 2);\n* // Yields: { x:4, y:8 }\n* ```\n* @param pt Point\n* @param v Value to multiply by\n* @returns\n*/\nconst multiplyScalar = (pt, v) => {\n\treturn isPoint3d(pt) ? Object.freeze({\n\t\t...pt,\n\t\tx: pt.x * v,\n\t\ty: pt.y * v,\n\t\tz: pt.z * v\n\t}) : Object.freeze({\n\t\t...pt,\n\t\tx: pt.x * v,\n\t\ty: pt.y * v\n\t});\n};\n//#endregion\nexport { distanceCenter as i, multiplyScalar as n, distanceFromExterior as r, multiply as t };\n","//#region src/point/is-equal.ts\n/**\n* Returns _true_ if the points have identical values\n*\n* ```js\n* const a = {x: 10, y: 10};\n* const b = {x: 10, y: 10;};\n* a === b // False, because a and be are different objects\n* isEqual(a, b) // True, because a and b are same value\n* ```\n* @param p Points\n* @returns _True_ if points are equal\n*/\nconst isEqual = (...p) => {\n\tif (p === void 0) throw new Error(`parameter 'p' is undefined`);\n\tif (p.length < 2) return true;\n\tfor (let index = 1; index < p.length; index++) {\n\t\tif (p[index].x !== p[0].x) return false;\n\t\tif (p[index].y !== p[0].y) return false;\n\t}\n\treturn true;\n};\n//#endregion\nexport { isEqual as t };\n","//#region src/point/compare.ts\n/**\n* Returns -2 if both x & y of a is less than b\n* Returns -1 if either x/y of a is less than b\n*\n* Returns 2 if both x & y of a is greater than b\n* Returns 1 if either x/y of a is greater than b's x/y\n*\n* Returns 0 if x/y of a and b are equal\n* @param a\n* @param b\n*/\nfunction compare(a, b) {\n\tif (a.x < b.x && a.y < b.y) return -2;\n\tif (a.x > b.x && a.y > b.y) return 2;\n\tif (a.x < b.x || a.y < b.y) return -1;\n\tif (a.x > b.x || a.y > b.y) return 1;\n\tif (a.x === b.x && a.x === b.y) return 0;\n\treturn NaN;\n}\n/**\n* Compares points row-wise.\n*\n* A point is considered less if has a lower `y` value, or if `y` values are equal, a lower `x` value.\n*\n* Returns 0 if points are equal, -1 if a is less than b, 1 if a is greater than b.\n*\n* This can be used for sorting points in a row-wise manner, for example:\n* ```js\n* arrayOfPoints.sort(Points.compareRowwise);\n* ```\n* @param a\n* @param b\n*/\nfunction compareRowwise(a, b) {\n\tif (a.y < b.y) return -1;\n\tif (a.y > b.y) return 1;\n\tif (a.x < b.x) return -1;\n\tif (a.x > b.x) return 1;\n\treturn 0;\n}\n/**\n* Returns a rectangle from two points, where it's uncertain if\n* a/b ought to be top-left or bottom-right.\n*\n* To resolve this, we use Points.compareRowwise to determine which point is top-left and which is bottom-right.\n* @param a\n* @param b\n*/\nfunction getAsBounds(a, b) {\n\tconst topLeft = compareRowwise(a, b) <= 0 ? a : b;\n\treturn {\n\t\ttopLeft,\n\t\tbottomRight: topLeft === a ? b : a\n\t};\n}\n/**\n* Compares points based on x value. Y value is ignored.\n*\n* Return values:\n* 0: If a.x === b.x\n* 1: a is to the right of b (ie. a.x > b.x)\n* -1: a is to the left of b (ie. a.x < b.x)\n*\n* @example Sorting by x\n* ```js\n* arrayOfPoints.sort(Points.compareByX);\n* ```\n*\n* @param a\n* @param b\n* @returns\n*/\nfunction compareByX(a, b) {\n\tif (a.x === b.x) return 0;\n\tif (a.x < b.x) return -1;\n\treturn 1;\n}\n/**\n* Compares points based on Y value. X value is ignored.\n*\n* Return values:\n* 0: If a.y === b.y\n* 1: A is below B (ie. a.y > b.y)\n* -1: A is above B (ie. a.y < b.y)\n*\n* @example Sorting by Y\n* ```js\n* arrayOfPoints.sort(Points.compareByY);\n* ```\n* @param a\n* @param b\n* @returns\n*/\nfunction compareByY(a, b) {\n\tif (a.y === b.y) return 0;\n\tif (a.y < b.y) return -1;\n\treturn 1;\n}\n/**\n* Compares points based on Z value. XY values are ignored.\n*\n* Return values:\n* 0: If a.z === b.z\n* 1: A is below B (ie. a.z > b.z)\n* -1: A is above B (ie. a.z < b.z)\n*\n* @example Sorting by Y\n* ```js\n* arrayOfPoints.sort(Points.compareByZ);\n* ```\n* @param a\n* @param b\n* @returns\n*/\nfunction compareByZ(a, b) {\n\tif (a.z === b.z) return 0;\n\tif (a.z < b.z) return -1;\n\treturn 1;\n}\n//#endregion\nexport { compareRowwise as a, compareByZ as i, compareByX as n, getAsBounds as o, compareByY as r, compare as t };\n","//#region src/records/circular.ts\nconst removeCircularReferences = (value, replaceWith = null, seen = /* @__PURE__ */ new WeakSet(), path = ``) => {\n\tif (value === null) return value;\n\tif (typeof value !== `object`) throw new TypeError(`Param 'value' must be an object. Got type: ${typeof value}`);\n\tseen.add(value);\n\tconst entries = Object.entries(value);\n\tfor (const entry of entries) {\n\t\tif (entry[1] === null) continue;\n\t\tif (typeof entry[1] !== `object`) continue;\n\t\tif (seen.has(entry[1])) {\n\t\t\tentry[1] = replaceWith;\n\t\t\tcontinue;\n\t\t}\n\t\tentry[1] = removeCircularReferences(entry[1], replaceWith, seen, `${entry[0]}.`);\n\t}\n\treturn Object.fromEntries(entries);\n};\n//#endregion\n//#region src/to-string.ts\nconst objectToString = Object.prototype.toString;\nfunction toTypeString(value) {\n\treturn objectToString.call(value);\n}\n/**\n* Returns _true_ if `value` is a Map type\n* @param value\n* @returns\n*/\nfunction isMap(value) {\n\treturn toTypeString(value) === `[object Map]`;\n}\n/**\n* Returns _true_ if `value` is a Set type\n* @param value\n* @returns\n*/\nfunction isSet(value) {\n\treturn toTypeString(value) === `[object Set]`;\n}\n/**\n* A default converter to string that uses JSON.stringify if its an object, or the thing itself if it's a string\n*/\nfunction toStringDefault(itemToMakeStringFor) {\n\treturn typeof itemToMakeStringFor === `string` ? itemToMakeStringFor : JSON.stringify(itemToMakeStringFor);\n}\n/**\n* Converts a value to string form.\n* For simple objects, .toString() is used, other JSON.stringify is used.\n* It is meant for creating debugging output or 'hash' versions of objects, and does\n* not necessarily maintain full fidelity of the input\n* @param value\n* @returns\n*/\nfunction defaultToString(value) {\n\tif (value === null) return `null`;\n\tif (typeof value === `boolean` || typeof value === `number`) return value.toString();\n\tif (typeof value === `string`) return value;\n\tif (typeof value === `symbol`) throw new TypeError(`Symbol cannot be converted to string`);\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch (error) {\n\t\tif (typeof value === `object`) return JSON.stringify(removeCircularReferences(value, `(circular)`));\n\t\telse throw error;\n\t}\n}\n/**\n* If input is a string, it is returned.\n* Otherwise, it returns the result of JSON.stringify() with fields ordered.\n*\n* This allows for more consistent comparisons when object field orders are different but values the same.\n* @param itemToMakeStringFor\n*/\nfunction toStringOrdered(itemToMakeStringFor) {\n\tif (typeof itemToMakeStringFor === `string`) return itemToMakeStringFor;\n\tconst replacer = (key, value) => value instanceof Object && !Array.isArray(value) ? Object.keys(value).sort().reduce((sorted, key) => {\n\t\tsorted[key] = value[key];\n\t\treturn sorted;\n\t}, {}) : value;\n\treturn JSON.stringify(itemToMakeStringFor, replacer);\n}\n//#endregion\n//#region src/is-equal.ts\n/**\n* Default comparer function is equiv to checking `a === b`.\n* Use {@link isEqualValueDefault} to compare by value, via comparing JSON string representation.\n*/\nconst isEqualDefault = (a, b) => a === b;\n/**\n* Comparer returns true if string representation of `a` and `b` are equal.\n* Use {@link isEqualDefault} to compare using === semantics\n* Uses `toStringDefault` to generate a string representation (via `JSON.stringify`).\n*\n* Returns _false_ if the ordering of fields is different, even though values are identical:\n* ```js\n* isEqualValueDefault({ a: 10, b: 20}, { b: 20, a: 10 }); // false\n* ```\n*\n* Use {@link isEqualValueIgnoreOrder} to ignore order (with an overhead of additional processing).\n* ```js\n* isEqualValueIgnoreOrder({ a: 10, b: 20}, { b: 20, a: 10 }); // true\n* ```\n*\n* Use {@link isEqualValuePartial} to partially match `b` against `a`.\n* @returns True if the contents of `a` and `b` are equal\n*/\nfunction isEqualValueDefault(a, b) {\n\tif (a === b) return true;\n\treturn toStringDefault(a) === toStringDefault(b);\n}\n/**\n* Returns _true_ if `a` contains the values of `b`. `a` may contain other values, but we\n* only check against what is in `b`. `a` and `b` must both be simple objects.\n*\n* ```js\n* const obj = {\n* name: `Elle`,\n* size: 100,\n* colour: {\n* red: 0.5,\n* green: 0.1,\n* blue: 0.2\n* }\n* }\n*\n* isEqualValuePartial(obj, { name: `Elle` }); // true\n* isEqualValuePartial(obj, { name: { colour: red: { 0.5, green: 0.1 }} }); // true\n*\n* isEqualValuePartial(obj, { name: `Ellen` }); // false\n* isEqualValuePartial(obj, { lastname: `Elle` }); // false\n* ```\n* @param a\n* @param b\n* @param fieldComparer\n* @returns\n*/\nfunction isEqualValuePartial(a, b, fieldComparer) {\n\tif (typeof a !== `object`) throw new Error(`Param 'a' expected to be object`);\n\tif (typeof b !== `object`) throw new Error(`Param 'b' expected to be object`);\n\tif (Object.is(a, b)) return true;\n\tconst comparer = fieldComparer ?? isEqualValuePartial;\n\tfor (const entryB of Object.entries(b)) {\n\t\tconst valueOnAKeyFromB = a[entryB[0]];\n\t\tconst valueB = entryB[1];\n\t\tif (typeof valueOnAKeyFromB === `object` && typeof valueB === `object`) {\n\t\t\tif (!comparer(valueOnAKeyFromB, valueB)) return false;\n\t\t} else if (valueOnAKeyFromB !== valueB) return false;\n\t}\n\treturn true;\n}\n/**\n* Comparer returns true if string representation of `a` and `b` are equal, regardless of field ordering.\n* Uses `toStringOrdered` to generate a string representation (via JSON.stringify`).\n*\n* ```js\n* isEqualValueIgnoreOrder({ a: 10, b: 20}, { b: 20, a: 10 }); // true\n* isEqualValue({ a: 10, b: 20}, { b: 20, a: 10 }); // false, fields are different order\n* ```\n*\n* There is an overhead to ordering fields. Use {@link isEqualValueDefault} if it's not possible that field ordering will change.\n* @returns True if the contents of `a` and `b` are equal\n* @typeParam T - Type of objects being compared\n*/\nfunction isEqualValueIgnoreOrder(a, b) {\n\tif (a === b) return true;\n\treturn toStringOrdered(a) === toStringOrdered(b);\n}\n/**\n* Returns _true_ if Object.entries() is empty for `value`\n* @param value\n* @returns\n*/\nconst isEmptyEntries = (value) => [...Object.entries(value)].length === 0;\n/**\n* Returns _true_ if `a` and `b` are equal based on their JSON representations.\n* `path` is ignored.\n* @param a\n* @param b\n* @param path\n* @returns\n*/\nconst isEqualContextString = (a, b, _path) => {\n\treturn JSON.stringify(a) === JSON.stringify(b);\n};\n//#endregion\nexport { isEqualValueIgnoreOrder as a, isMap as c, toStringOrdered as d, removeCircularReferences as f, isEqualValueDefault as i, isSet as l, isEqualContextString as n, isEqualValuePartial as o, isEqualDefault as r, defaultToString as s, isEmptyEntries as t, toStringDefault as u };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { r as isEqualDefault, s as defaultToString, u as toStringDefault } from \"./is-equal-BOIjfI3O.js\";\n//#region src/comparers.ts\n/**\n* Sort numbers in ascending order.\n*\n* ```js\n* [10, 4, 5, 0].sort(numericComparer);\n* // Yields: [0, 4, 5, 10]\n* [10, 4, 5, 0].sort(comparerInverse(numericComparer));\n* // Yields: [ 10, 5, 4, 0]\n* ```\n*\n* Returns:\n* 0: values are equal\n* negative: `a` should be before `b`\n* positive: `a` should come after `b`\n* @param a\n* @param b\n* @returns\n*/\nfunction numericComparer(a, b) {\n\tif (a === b) return 0;\n\tif (a > b) return 1;\n\treturn -1;\n}\n/**\n* Default sort comparer, following same sematics as Array.sort.\n* Consider using {@link defaultComparer} to get more logical sorting of numbers.\n*\n* Note: numbers are sorted in alphabetical order, eg:\n* ```js\n* [ 10, 20, 5, 100 ].sort(jsComparer); // same as .sort()\n* // Yields: [10, 100, 20, 5]\n* ```\n*\n* Returns -1 if x is less than y\n* Returns 1 if x is greater than y\n* Returns 0 if x is the same as y\n* @param x\n* @param y\n* @returns\n*/\nfunction jsComparer(x, y) {\n\tif (x === void 0 && y === void 0) return 0;\n\tif (x === void 0) return 1;\n\tif (y === void 0) return -1;\n\tconst xString = defaultToString(x);\n\tconst yString = defaultToString(y);\n\tif (xString < yString) return -1;\n\tif (xString > yString) return 1;\n\treturn 0;\n}\n/**\n* Inverts the source comparer.\n* @param comparer\n* @returns\n*/\nfunction comparerInverse(comparer) {\n\treturn (x, y) => {\n\t\treturn comparer(x, y) * -1;\n\t};\n}\n/**\n* Compares numbers by numeric value, otherwise uses the default\n* logic of string comparison.\n*\n* Is an ascending sort:\n* b, a, c -> a, b, c\n* 10, 5, 100 -> 5, 10, 100\n*\n* Returns -1 if x is less than y\n* Returns 1 if x is greater than y\n* Returns 0 if x is the same as y\n* @param x\n* @param y\n* @see {@link comparerInverse} Inverted order\n* @returns\n*/\nfunction defaultComparer(x, y) {\n\tif (typeof x === `number` && typeof y === `number`) return numericComparer(x, y);\n\treturn jsComparer(x, y);\n}\n//#endregion\n//#region src/maps.ts\nvar maps_exports = /* @__PURE__ */ __exportAll({\n\taddObjectEntriesMutate: () => addObjectEntriesMutate,\n\taddValue: () => addValue,\n\taddValueMutate: () => addValueMutate,\n\taddValueMutator: () => addValueMutator,\n\tdeleteByValueCompareMutate: () => deleteByValueCompareMutate,\n\tfilterValues: () => filterValues,\n\tfindBySomeKey: () => findBySomeKey,\n\tfindEntryByPredicate: () => findEntryByPredicate,\n\tfindEntryByValue: () => findEntryByValue,\n\tfindValue: () => findValue,\n\tfromIterable: () => fromIterable,\n\tfromObject: () => fromObject,\n\tgetClosestIntegerKey: () => getClosestIntegerKey,\n\tgetOrGenerate: () => getOrGenerate,\n\tgetOrGenerateSync: () => getOrGenerateSync,\n\thasAnyValue: () => hasAnyValue,\n\thasKeyValue: () => hasKeyValue,\n\tmapToArray: () => mapToArray,\n\tmapToObjectTransform: () => mapToObjectTransform,\n\tmergeByKey: () => mergeByKey,\n\tsome: () => some,\n\tsortByValue: () => sortByValue,\n\tsortByValueProperty: () => sortByValueProperty,\n\ttoArray: () => toArray,\n\ttoObject: () => toObject,\n\ttransformMap: () => transformMap,\n\tzipKeyValue: () => zipKeyValue\n});\n/**\n* Gets the closest integer key to `target` in `data`.\n* * Requires map to have numbers as keys, not strings\n* * Math.round is used for rounding `target`.\n*\n* Examples:\n* ```js\n* // Assuming numeric keys 1, 2, 3, 4 exist:\n* getClosestIntegerKey(map, 3); // 3\n* getClosestIntegerKey(map, 3.1); // 3\n* getClosestIntegerKey(map, 3.5); // 4\n* getClosestIntegerKey(map, 3.6); // 4\n* getClosestIntegerKey(map, 100); // 4\n* getClosestIntegerKey(map, -100); // 1\n* ```\n* @param data Map\n* @param target Target value\n* @returns\n*/\nconst getClosestIntegerKey = (data, target) => {\n\ttarget = Math.round(target);\n\tif (data.has(target)) return target;\n\telse {\n\t\tlet offset = 1;\n\t\twhile (offset < 1e3) {\n\t\t\tif (data.has(target - offset)) return target - offset;\n\t\t\telse if (data.has(target + offset)) return target + offset;\n\t\t\toffset++;\n\t\t}\n\t\tthrow new Error(`Could not find target ${target.toString()}`);\n\t}\n};\n/**\n* Returns the first value in `data` that matches a key from `keys`.\n* ```js\n* // Iterate, yielding: `a.b.c.d`, `b.c.d`, `c.d`, `d`\n* const keys = Text.segmentsFromEnd(`a.b.c.d`);\n* // Gets first value that matches a key (starting from most precise)\n* const value = findBySomeKey(data, keys);\n* ```\n* @param data \n* @param keys \n* @returns \n*/\nconst findBySomeKey = (data, keys) => {\n\tfor (const key of keys) if (data.has(key)) return data.get(key);\n};\n/**\n* Returns true if map contains `value` under `key`, using `comparer` function. Use {@link hasAnyValue} if you don't care\n* what key value might be under.\n*\n* Having a comparer function is useful to check by value rather than object reference.\n*\n* @example Find key value based on string equality\n* ```js\n* hasKeyValue(map,`hello`, `samantha`, (a, b) => a === b);\n* ```\n* @param map Map to search\n* @param key Key to search\n* @param value Value to search\n* @param comparer Function to determine match. By default uses === comparison.\n* @returns True if key is found\n*/\nconst hasKeyValue = (map, key, value, comparer = isEqualDefault) => {\n\tif (!map.has(key)) return false;\n\treturn [...map.values()].some((v) => comparer(v, value));\n};\n/**\n* Deletes all key/values from map where value matches `value`,\n* with optional comparer. Mutates map.\n*\n* ```js\n* // Compare fruits based on their colour property\n* const colourComparer = (a, b) => a.colour === b.colour;\n*\n* // Deletes all values where .colour = `red`\n* deleteByValueCompareMutate(map, { colour: `red` }, colourComparer);\n* ```\n* @param map\n* @param value\n* @param comparer Uses === equality by default. Use isEqualValueDefault to compare by value\n*/\nconst deleteByValueCompareMutate = (map, value, comparer = isEqualDefault) => {\n\tfor (const entry of map.entries()) if (comparer(entry[1], value)) map.delete(entry[0]);\n};\n/**\n* Finds first entry by iterable value. Expects a map with an iterable as values.\n*\n* ```js\n* const map = new Map();\n* map.set('hello', 'a');\n* map.set('there', 'b');\n*\n* const entry = findEntryByPredicate(map, (value, key) => {\n* return (value === 'b');\n* });\n* // Entry is: ['there', 'b']\n* ```\n*\n* An alternative is {@link findEntryByValue} to search by value.\n* @param map Map to search\n* @param predicate Filter function returns true when there is a match of value\n* @returns Entry, or _undefined_ if `filter` function never returns _true_\n*/\nconst findEntryByPredicate = (map, predicate) => {\n\tfor (const entry of map.entries()) if (predicate(entry[1], entry[0])) return entry;\n};\n/**\n* Finds first entry by value.\n*\n* ```js\n* const map = new Map();\n* map.set('hello', 'a');\n* map.set('there', 'b');\n*\n* const entry = findEntryByValue(map, 'b');\n* // Entry is: ['there', 'b']\n* ```\n*\n* Uses JS's === comparison by default. Consider using `isEqualValueDefault` to match by value.\n* An alternative is {@link findEntryByValue} to search by predicate function.\n* @param map Map to search\n* @param value Value to seek\n* @param isEqual Filter function which checks equality. Uses JS comparer by default.\n* @returns Entry, or _undefined_ if `value` not found.\n*/\nconst findEntryByValue = (map, value, isEqual = isEqualDefault) => {\n\tfor (const entry of map.entries()) if (isEqual(entry[1], value)) return entry;\n};\n/**\n* Adds items to a map only if their key doesn't already exist\n*\n* Uses provided {@link ToString} function to create keys for items. Item is only added if it doesn't already exist.\n* Thus the older item wins out, versus normal `Map.set` where the newest wins.\n*\n* Returns a copy of the input map.\n* @example\n* ```js\n* const map = new Map();\n* const peopleArray = [ _some people objects..._];\n* addKeepingExisting(map, p => p.name, ...peopleArray);\n* ```\n* @param set\n* @param hasher\n* @param values\n* @returns\n*/\n/**\n* Mutates `map`, adding each value to it using a\n* function to produce a key. Use {@link addValue} for an immutable version.\n* ```\n* const map = new Map();\n* addValueMutate(map, v=>v.name, { name:`Jane`, size:10 }, { name:`Bob`, size: 9 });\n* // Map consists of entries:\n* // [ `Jane`, { name:`Jane`, size:10 } ],\n* // [ `Bob` { name:`Bob`, size: 9 } ]\n* ```\n* \n* Uses {@link addValueMutator} under the hood.\n* @param map Map to modify. If _undefined_, a new map is created\n* @param hasher Function to generate a string key for a given object value\n* @param values Values to add\n* @param collisionPolicy What to do if the key already exists\n* @returns Map instance\n*/\nconst addValueMutate = (map, hasher, collisionPolicy, ...values) => {\n\tconst m = map ?? /* @__PURE__ */ new Map();\n\taddValueMutator(m, hasher, collisionPolicy)(...values);\n\treturn m;\n};\n/**\n* Adds values to a map, returning a new, modified copy and leaving the original\n* intact.\n* \n* Use {@link addValueMutate} for a mutable \n* @param map Map to start with, or _undefined_ to automatically create a map \n* @param hasher Function to create keys for values\n* @param collisionPolicy What to do if a key already exists\n* @param values Values to add\n* @returns A new map containing values\n*/\nconst addValue = (map, hasher, collisionPolicy, ...values) => {\n\tconst m = map === void 0 ? /* @__PURE__ */ new Map() : new Map(map);\n\tfor (const v of values) {\n\t\tconst hashResult = hasher(v);\n\t\tif (collisionPolicy !== `overwrite`) {\n\t\t\tif (m.has(hashResult)) {\n\t\t\t\tif (collisionPolicy === `throw`) throw new Error(`Key '${hashResult}' already in map`);\n\t\t\t\tif (collisionPolicy === `skip`) continue;\n\t\t\t}\n\t\t}\n\t\tm.set(hashResult, v);\n\t}\n\treturn m;\n};\n/**\n* Returns a function that adds values to a map, using a hashing function to produce a key.\n* Use {@link addValueMutate} if you don't need a reusable function.\n* \n* ```js\n* const map = new Map(); // Create map\n* const mutate = addValueMutator(map, v=>v.name); // Create a mutator using default 'overwrite' policy\n* mutate( { name:`Bob`, size:10 }, { name: `Alice`, size: 2 }); // Add values to map\n* mutate( {name: `Bob`, size: 11 }); // Change the value stored under key `Bob`.\n* map.get(`Bob`); // { name: `Bob`, size: 11 }\n* ```\n* \n* The 'collision policy' determines what to do if the key already exists. The default behaviour\n* is to overwrite the key, just as Map.set would.\n* ```js\n* const map = new Map();\n* const mutate = addValueMutator(map, v=>v.name, `skip`);\n* mutate( { name:`Bob`,size:10 }, { name: `Alice`, size: 2 }); // Add values to map\n* mutate( { name:`Bob`, size: 20 }); // This value would be skipped because map already contains 'Bob'\n* map.get(`Bob`); // { name: `Bob`, size: 10 }\n* ``` \n*\n* @param map Map to modify\n* @param hasher Hashing function to make a key for a value\n* @param collisionPolicy What to do if a value is already stored under a key\n* @returns Function\n*/\nconst addValueMutator = (map, hasher, collisionPolicy = `overwrite`) => {\n\treturn (...values) => {\n\t\tfor (const v of values) {\n\t\t\tconst hashResult = hasher(v);\n\t\t\tif (collisionPolicy !== `overwrite`) {\n\t\t\t\tif (map.has(hashResult)) {\n\t\t\t\t\tif (collisionPolicy === `throw`) throw new Error(`Key '${hashResult}' already in map`);\n\t\t\t\t\tif (collisionPolicy === `skip`) continue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tmap.set(hashResult, v);\n\t\t}\n\t\treturn map;\n\t};\n};\n/**\n* Returns a array of entries from a map, sorted by value.\n*\n* ```js\n* const m = new Map();\n* m.set(`4491`, { name: `Bob` });\n* m.set(`2319`, { name: `Alice` });\n*\n* // Compare by name\n* const comparer = (a, b) => defaultComparer(a.name, b.name);\n*\n* // Get sorted values\n* const sorted = Maps.sortByValue(m, comparer);\n* ```\n*\n* `sortByValue` takes a comparison function that should return -1, 0 or 1 to indicate order of `a` to `b`.\n* @param map\n* @param comparer\n* @returns\n*/\nconst sortByValue = (map, comparer) => {\n\tconst f = comparer ?? defaultComparer;\n\treturn [...map.entries()].sort((a, b) => f(a[1], b[1]));\n};\n/**\n* Returns an array of entries from a map, sorted by a property of the value\n*\n* ```js\n* const m = new Map();\n* m.set(`4491`, { name: `Bob` });\n* m.set(`2319`, { name: `Alice` });\n* const sorted = sortByValueProperty(m, `name`);\n* ```\n* @param map Map to sort\n* @param property Property of value\n* @param compareFunction Comparer. If unspecified, uses a default.\n*/\nconst sortByValueProperty = (map, property, compareFunction) => {\n\tconst cfn = typeof compareFunction === `undefined` ? defaultComparer : compareFunction;\n\treturn [...map.entries()].sort((aE, bE) => {\n\t\tconst a = aE[1];\n\t\tconst b = bE[1];\n\t\treturn cfn(a[property], b[property]);\n\t});\n};\n/**\n* Returns _true_ if any key contains `value`, based on the provided `comparer` function. Use {@link hasKeyValue}\n* if you only want to find a value under a certain key.\n*\n* Having a comparer function is useful to check by value rather than object reference.\n* @example Finds value where name is 'samantha', regardless of other properties\n* ```js\n* hasAnyValue(map, {name:`samantha`}, (a, b) => a.name === b.name);\n* ```\n*\n* Works by comparing `value` against all values contained in `map` for equality using the provided `comparer`.\n*\n* @param map Map to search\n* @param value Value to find\n* @param comparer Function that determines matching. Should return true if `a` and `b` are considered equal.\n* @returns True if value is found\n*/\nconst hasAnyValue = (map, value, comparer) => {\n\treturn [...map.entries()].some((kv) => comparer(kv[1], value));\n};\n/**\n* Returns values where `predicate` returns true.\n*\n* If you just want the first match, use `find`\n*\n* @example All people over thirty\n* ```js\n* // for-of loop\n* for (const v of filterValues(people, person => person.age > 30)) {\n*\n* }\n* // If you want an array\n* const overThirty = Array.from(filterValues(people, person => person.age > 30));\n* ```\n* @param map Map\n* @param predicate Filtering predicate\n* @returns Values that match predicate\n*/\nfunction* filterValues(map, predicate) {\n\tfor (const v of map.values()) if (predicate(v)) yield v;\n}\n/**\n* Copies data to an array\n* @param map\n* @returns\n*/\nconst toArray = (map) => [...map.values()];\n/**\n* Returns a Map from an iterable. By default throws an exception\n* if iterable contains duplicate values.\n*\n* ```js\n* const data = [\n* { fruit: `granny-smith`, family: `apple`, colour: `green` },\n* { fruit: `mango`, family: `stone-fruit`, colour: `orange` }\n* ];\n* const map = fromIterable(data, v => v.fruit);\n* map.get(`granny-smith`); // { fruit: `granny-smith`, family: `apple`, colour: `green` }\n* ```\n* @param data Input data\n* @param keyFunction Function which returns a string id. By default uses the JSON value of the object.\n* @param collisionPolicy By default, values with same key overwrite previous (`overwrite`)\n* @returns\n*/\nconst fromIterable = (data, keyFunction = toStringDefault, collisionPolicy = `overwrite`) => {\n\tconst m = /* @__PURE__ */ new Map();\n\tfor (const d of data) {\n\t\tconst key = keyFunction(d);\n\t\tif (m.has(key)) {\n\t\t\tif (collisionPolicy === `throw`) throw new Error(`Key '${key}' is already used and new data will overwrite it. `);\n\t\t\tif (collisionPolicy === `skip`) continue;\n\t\t}\n\t\tm.set(key, d);\n\t}\n\treturn m;\n};\n/**\n* Returns a Map from an object, or array of objects.\n* Assumes the top-level properties of the object is the key.\n*\n* ```js\n* const data = {\n* Sally: { name: `Sally`, colour: `red` },\n* Bob: { name: `Bob`, colour: `pink` }\n* };\n* const map = fromObject(data);\n* map.get(`Sally`); // { name: `Sally`, colour: `red` }\n* ```\n*\n* To add an object to an existing map, use {@link addObjectEntriesMutate}.\n* @param data\n* @returns\n*/\nconst fromObject = (data) => {\n\tconst map = /* @__PURE__ */ new Map();\n\tif (Array.isArray(data)) for (const d of data) addObjectEntriesMutate(map, d);\n\telse addObjectEntriesMutate(map, data);\n\treturn map;\n};\n/**\n* Adds an object to an existing map, mutating it. \n* It assumes a structure where each top-level property is a key:\n*\n* ```js\n* const data = {\n* Sally: { colour: `red` },\n* Bob: { colour: `pink` }\n* };\n* const map = new Map();\n* addObjectEntriesMutate(map, data);\n*\n* map.get(`Sally`); // { name: `Sally`, colour: `red` }\n* ```\n*\n* To create a new map from an object, use {@link fromObject} instead.\n* @param map\n* @param data\n*/\nconst addObjectEntriesMutate = (map, data) => {\n\tconst entries = Object.entries(data);\n\tfor (const [key, value] of entries) map.set(key, value);\n};\n/**\n* Returns the first found value that matches `predicate` or _undefined_.\n* To get an entry see {@link findEntryByPredicate}\n*\n* Use {@link some} if you don't care about the value, just whether it appears.\n* Use {@link filterValues} to get all value(s) that match `predicate`.\n*\n* @example First person over thirty\n* ```js\n* const overThirty = findValue(people, person => person.age > 30);\n* ```\n* @param map Map to search\n* @param predicate Function that returns true for a matching value\n* @returns Found value or _undefined_\n*/\nconst findValue = (map, predicate) => [...map.values()].find((v) => predicate(v));\n/**\n* Returns _true_ if `predicate` yields _true_ for any value in `map`.\n* Use {@link findValue} if you want the matched value.\n* ```js\n* const map = new Map();\n* map.set(`fruit`, `apple`);\n* map.set(`colour`, `red`);\n* Maps.some(map, v => v === `red`); // true\n* Maps.some(map, v => v === `orange`); // false\n* ```\n* @param map \n* @param predicate \n* @returns \n*/\nconst some = (map, predicate) => [...map.values()].some((v) => predicate(v));\n/**\n* Converts a map to a simple object, transforming from type `T` to `K` as it does so. If no transforms are needed, use {@link toObject}.\n*\n* ```js\n* const map = new Map();\n* map.set(`name`, `Alice`);\n* map.set(`pet`, `dog`);\n*\n* const o = mapToObjectTransform(map, v => {\n* ...v,\n* registered: true\n* });\n*\n* // Yields: { name: `Alice`, pet: `dog`, registered: true }\n* ```\n*\n* If the goal is to create a new map with transformed values, use {@link transformMap}.\n* @param m\n* @param valueTransform\n* @typeParam T Value type of input map\n* @typeParam K Value type of destination map\n* @returns\n*/\nconst mapToObjectTransform = (m, valueTransform) => [...m].reduce((object, [key, value]) => {\n\tobject[key] = valueTransform(value);\n\treturn object;\n}, {});\n/**\n* Zips together an array of keys and values into an object. Requires that\n* `keys` and `values` are the same length.\n*\n* @example\n* ```js\n* const o = zipKeyValue([`a`, `b`, `c`], [0, 1, 2])\n* Yields: { a: 0, b: 1, c: 2}\n*```\n* @param keys String keys\n* @param values Values\n* @typeParam V Type of values\n* @return Object with keys and values\n*/\nconst zipKeyValue = (keys, values) => {\n\tif (keys.length !== values.length) throw new Error(`Keys and values arrays should be same length`);\n\treturn Object.fromEntries(keys.map((k, index) => [k, values[index]]));\n};\n/**\n* Like `Array.map`, but for a Map. Transforms from Map<K,V> to Map<K,R>, returning as a new Map.\n*\n* @example\n* ```js\n* const mapOfStrings = new Map();\n* mapOfStrings.set(`a`, `10`);\n* mapOfStrings.get(`a`); // Yields `10` (a string)\n*\n* // Convert a map of string->string to string->number\n* const mapOfInts = transformMap(mapOfStrings, (value, key) => parseInt(value));\n*\n* mapOfInts.get(`a`); // Yields 10 (a proper number)\n* ```\n*\n* If you want to combine values into a single object, consider instead {@link mapToObjectTransform}.\n* @param source\n* @param transformer\n* @typeParam K Type of keys (generally a string)\n* @typeParam V Type of input map values\n* @typeParam R Type of output map values\n* @returns\n*/\nconst transformMap = (source, transformer) => new Map(Array.from(source, (v) => [v[0], transformer(v[1], v[0])]));\n/**\n* Converts a `Map` to a plain object, useful for serializing to JSON.\n* To convert back to a map use {@link fromObject}.\n*\n* @example\n* ```js\n* const map = new Map();\n* map.set(`Sally`, { name: `Sally`, colour: `red` });\n* map.set(`Bob`, { name: `Bob`, colour: `pink });\n*\n* const objects = Maps.toObject(map);\n* // Yields: {\n* // Sally: { name: `Sally`, colour: `red` },\n* // Bob: { name: `Bob`, colour: `pink` }\n* // }\n* ```\n* @param m\n* @returns\n*/\nconst toObject = (m) => [...m].reduce((object, [key, value]) => {\n\tobject[key] = value;\n\treturn object;\n}, {});\n/**\n* Converts Map to Array with a provided `transformer` function. Useful for plucking out certain properties\n* from contained values and for creating a new map based on transformed values from an input map.\n*\n* @example Get an array of ages from a map of Person objects\n* ```js\n* const person = { age: 29, name: `John`};\n* map.set(person.name, person);\n*\n* const ages = mapToArray(map, (key, person) => person.age);\n* // [29, ...]\n* ```\n*\n* In the above example, the `transformer` function returns a number, but it could\n* just as well return a transformed version of the input:\n*\n* ```js\n* // Return with random heights and uppercased name\n* mapToArray(map, (key, person) => ({\n* ...person,\n* height: Math.random(),\n* name: person.name.toUpperCase();\n* }))\n* // Yields:\n* // [{height: 0.12, age: 29, name: \"JOHN\"}, ...]\n* ```\n* @param m\n* @param transformer A function that takes a key and item, returning a new item.\n* @returns\n*/\nconst mapToArray = (m, transformer) => [...m.entries()].map((x) => transformer(x[0], x[1]));\n/**\n* Merges maps left to right, using the provided\n* `reconcile` function to choose a winner when keys overlap.\n*\n* There's also @ixfx/arrays/mergeByKey if you don't already have a map.\n*\n* For example, if we have the map A:\n* 1 => `A-1`, 2 => `A-2`, 3 => `A-3`\n*\n* And map B:\n* 1 => `B-1`, 2 => `B-2`, 4 => `B-4`\n*\n* If they are merged with the reconile function:\n* ```js\n* const reconcile = (a, b) => b.replace(`-`, `!`);\n* const output = mergeByKey(reconcile, mapA, mapB);\n* ```\n*\n* The final result will be:\n*\n* 1 => `B!1`, 2 => `B!2`, 3 => `A-3`, 4 => `B-4`\n*\n* In this toy example, it's obvious how the reconciler transforms\n* data where the keys overlap. For the keys that do not overlap -\n* 3 and 4 in this example - they are copied unaltered.\n*\n* A practical use for `mergeByKey` has been in smoothing keypoints\n* from a TensorFlow pose. In this case, we want to smooth new keypoints\n* with older keypoints. But if a keypoint is not present, for it to be\n* passed through.\n*\n* @param reconcile\n* @param maps\n*/\nconst mergeByKey = (reconcile, ...maps) => {\n\tconst result = /* @__PURE__ */ new Map();\n\tfor (const m of maps) for (const [mk, mv] of m) {\n\t\tlet v = result.get(mk);\n\t\tv = v ? reconcile(v, mv) : mv;\n\t\tresult.set(mk, v);\n\t}\n\treturn result;\n};\n/**\n* @inheritDoc getOrGenerate\n* @param map\n* @param fn\n* @returns\n*/\nconst getOrGenerateSync = (map, fn) => (key, args) => {\n\tlet value = map.get(key);\n\tif (value !== void 0) return value;\n\tvalue = fn(key, args);\n\tmap.set(key, value);\n\treturn value;\n};\n/**\n* Returns a function that fetches a value from a map, or generates and sets it if not present.\n* Undefined is never returned, because if `fn` yields that, an error is thrown.\n*\n* See {@link getOrGenerateSync} for a synchronous version.\n*\n* ```\n* const m = getOrGenerate(new Map(), (key) => {\n* return key.toUppercase();\n* });\n*\n* // Not contained in map, so it will run the uppercase function,\n* // setting the value to the key 'hello'.\n* const v = await m(`hello`); // Yields 'HELLO'\n* const v1 = await m(`hello`); // Value exists, so it is returned ('HELLO')\n* ```\n*\n*/\nconst getOrGenerate = (map, fn) => async (key, args) => {\n\tlet value = map.get(key);\n\tif (value !== void 0) return value;\n\tvalue = await fn(key, args);\n\tif (value === void 0) throw new Error(`fn returned undefined`);\n\tmap.set(key, value);\n\treturn value;\n};\n//#endregion\nexport { defaultComparer as A, sortByValue as C, transformMap as D, toObject as E, numericComparer as M, zipKeyValue as O, some as S, toArray as T, hasKeyValue as _, deleteByValueCompareMutate as a, maps_exports as b, findEntryByPredicate as c, fromIterable as d, fromObject as f, hasAnyValue as g, getOrGenerateSync as h, addValueMutator as i, jsComparer as j, comparerInverse as k, findEntryByValue as l, getOrGenerate as m, addValue as n, filterValues as o, getClosestIntegerKey as p, addValueMutate as r, findBySomeKey as s, addObjectEntriesMutate as t, findValue as u, mapToArray as v, sortByValueProperty as w, mergeByKey as x, mapToObjectTransform as y };\n","//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __exportAll = (all, no_symbols) => {\n\tlet target = {};\n\tfor (var name in all) __defProp(target, name, {\n\t\tget: all[name],\n\t\tenumerable: true\n\t});\n\tif (!no_symbols) __defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\treturn target;\n};\nvar __copyProps = (to, from, except, desc) => {\n\tif (from && typeof from === \"object\" || typeof from === \"function\") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {\n\t\tkey = keys[i];\n\t\tif (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {\n\t\t\tget: ((k) => from[k]).bind(null, key),\n\t\t\tenumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable\n\t\t});\n\t}\n\treturn to;\n};\nvar __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, \"default\"), secondTarget && __copyProps(secondTarget, mod, \"default\"));\n//#endregion\nexport { __reExport as n, __exportAll as t };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { integerTest, resultThrow } from \"@ixfx/guards\";\n//#region src/text-edit-distance.ts\nvar text_edit_distance_exports = /* @__PURE__ */ __exportAll({ levenshteinOps: () => levenshteinOps });\n/**\n* Compute the Levenshtein operations needed to transform `a` into string `b`.\n* @param a\n* @param b\n* @returns\n*/\nfunction levenshteinOps(a, b) {\n\tif (typeof a !== `string`) throw new TypeError(`Param 'a' is not a string. Got: ${typeof a}`);\n\tif (typeof b !== `string`) throw new TypeError(`Param 'b' is not a string. Got: ${typeof b}`);\n\tconst dp = [];\n\tfor (let i = 0; i <= a.length; i++) {\n\t\tdp[i] = [];\n\t\tfor (let j = 0; j <= b.length; j++) if (i === 0) dp[i][j] = j;\n\t\telse if (j === 0) dp[i][j] = i;\n\t\telse dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));\n\t}\n\tconst ops = [];\n\tlet i = a.length;\n\tlet j = b.length;\n\twhile (i > 0 || j > 0) if (i > 0 && j > 0 && dp[i][j] === dp[i - 1][j - 1] && a[i - 1] === b[j - 1]) {\n\t\tops.push({\n\t\t\ttype: `keep`,\n\t\t\tchar: a[i - 1]\n\t\t});\n\t\ti--;\n\t\tj--;\n\t} else if (i > 0 && j > 0 && dp[i][j] === dp[i - 1][j - 1] + 1) {\n\t\tops.push({\n\t\t\ttype: `replace`,\n\t\t\tfrom: a[i - 1],\n\t\t\tto: b[j - 1]\n\t\t});\n\t\ti--;\n\t\tj--;\n\t} else if (j > 0 && dp[i][j] === dp[i][j - 1] + 1) {\n\t\tops.push({\n\t\t\ttype: `insert`,\n\t\t\tchar: b[j - 1]\n\t\t});\n\t\tj--;\n\t} else {\n\t\tops.push({\n\t\t\ttype: `delete`,\n\t\t\tchar: a[i - 1]\n\t\t});\n\t\ti--;\n\t}\n\treturn ops.reverse();\n}\n//#endregion\n//#region src/text-tokenise.ts\nvar text_tokenise_exports = /* @__PURE__ */ __exportAll({\n\tbyCharacter: () => byCharacter,\n\tbyWord: () => byWord\n});\nconst byWordRegex = /\\s+/;\nfunction byCharacter() {\n\treturn {\n\t\tsplit: (s) => [...s],\n\t\tjoinWith: ``\n\t};\n}\nfunction byWord() {\n\treturn {\n\t\tsplit: (s) => s.split(byWordRegex),\n\t\tjoinWith: ` `\n\t};\n}\n//#endregion\n//#region src/text.ts\nconst htmlEntitiesRegexPattern = /[&<>\\u00A0-\\u9999]/g;\nconst escapeRegexPattern = /([!$()*+./:=?[\\\\\\]^{|}])/g;\n/**\n* Returns chunks of `source`, broken up by `delimiter` (default '.').\n*\n* Whittles down from whole string to last token.\n*\n* If `delimiter` is not found, no results are yielded.\n*\n* ```js\n* stringSegmentsWholeToEnd(`a.b.c.d`);\n* // Yields:\n* // `a.b.c.d`\n* // `b.c.d`\n* // `c.d`\n* // `d`\n* ```\n* @param source\n* @param delimiter\n*/\nfunction* stringSegmentsWholeToEnd(source, delimiter = `.`) {\n\twhile (source.length > 0) {\n\t\tyield source;\n\t\tconst trimmed = afterMatch(source, delimiter);\n\t\tif (trimmed === source) break;\n\t\tsource = trimmed;\n\t}\n}\n/**\n* Returns chunks of `source`, broken up by `delimiter` (default '.').\n*\n* Starts with last token, builds to whole.\n*\n* If `delimiter` is not found, no results are yielded.\n*\n* ````js\n* stringSegmentsLastToWhole(`a.b.c.d`);\n* // Yields:\n* // `d`\n* // `c.d`\n* // `b.c.d`\n* // `a.b.c.d`\n* ```\n* @param source\n* @param delimiter\n*/\nfunction* stringSegmentsLastToWhole(source, delimiter = `.`) {\n\tlet accumulator = ``;\n\tconst orig = source;\n\twhile (source.length > 0) {\n\t\tconst ba = beforeAfterMatch(source, delimiter, {\n\t\t\tfromEnd: true,\n\t\t\tifNoMatch: `original`\n\t\t});\n\t\tif (ba[0] === ba[1] && ba[1] === source) break;\n\t\tconst v = ba[1] + accumulator;\n\t\tyield v;\n\t\taccumulator = delimiter + v;\n\t\tsource = ba[0];\n\t}\n\tyield orig;\n}\n/**\n* Returns chunks of `source`, broken up by `delimiter` (default '.').\n*\n* We start with the first token and build up until end.\n*\n* If `delimiter` is not found, no results are yielded.\n*\n* ```js\n* stringSegmentsFirstToWhole(`a.b.c.d`);\n* // Yields:\n* // `a`\n* // `a.b`\n* // `a.b.c`\n* // `a.b.c.d`\n* ```\n* @param source\n* @param delimiter\n*/\nfunction* stringSegmentsFirstToWhole(source, delimiter = `.`) {\n\tlet accumulator = ``;\n\tconst orig = source;\n\twhile (source.length > 0) {\n\t\tconst ba = beforeAfterMatch(source, delimiter, { ifNoMatch: `original` });\n\t\tif (ba[0] === source && ba[1] === source) break;\n\t\taccumulator += ba[0];\n\t\tyield accumulator;\n\t\taccumulator += delimiter;\n\t\tsource = ba[1];\n\t}\n\tyield orig;\n}\n/**\n* Returns chunks of `source`, broken up by `delimiter` (default '.').\n*\n* We start with whole string and whittle down to starting token.\n*\n* If `delimiter` is not found, no results are yielded.\n*\n* ```js\n* stringSegmentsWholeToFirst(`a.b.c.d`);\n* // Yields:\n* // `a.b.c.d`\n* // `a.b.c`,\n* // `a.b`,\n* // `a`,\n* ```\n* @param source\n* @param delimiter\n*/\nfunction* stringSegmentsWholeToFirst(source, delimiter = `.`) {\n\twhile (source.length > 0) {\n\t\tyield source;\n\t\tconst b = beforeMatch(source, delimiter, {\n\t\t\tifNoMatch: `original`,\n\t\t\tfromEnd: true\n\t\t});\n\t\tif (b === source) break;\n\t\tsource = b;\n\t}\n}\n/**\n* Given a long string, abbreviates it with ...\n* ```js\n* abbreviate(`This is something`, 7); // `This is...`\n* ```\n*\n* If `source` is under `maxLength` the original is returned.\n* @param source\n* @param maxLength Maximum length. Defaults to 20\n* @returns\n*/\nfunction abbreviate(source, maxLength = 15) {\n\tresultThrow(integerTest(maxLength, `aboveZero`, `maxLength`));\n\tif (typeof source !== `string`) throw new Error(`Parameter 'source' is not a string`);\n\tif (source.length > maxLength && source.length > 3) {\n\t\tif (maxLength > 15) {\n\t\t\tconst chunk = Math.round((maxLength - 2) / 2);\n\t\t\treturn `${source.slice(0, chunk)}...${source.slice(-chunk)}`;\n\t\t}\n\t\treturn `${source.slice(0, maxLength)}...`;\n\t}\n\treturn source;\n}\n/**\n* Uses JSON.toString() on `source`, but abbreviates result.\n* @param source Object to stringify\n* @param maxLength Default 20\n* @returns\n*/\nfunction toStringAbbreviate(source, maxLength = 20) {\n\tif (source === void 0) return `(undefined)`;\n\tif (source === null) return `(null)`;\n\treturn abbreviate(JSON.stringify(source), maxLength);\n}\n/**\n* Returns source text that is between `start` and `end` match strings. Returns _undefined_ if start/end is not found.\n*\n* ```js\n* // Yields ` orange `;\n* between(`apple orange melon`, `apple`, `melon`);\n* ```\n* @param source Source text\n* @param start Start match\n* @param end If undefined, the `start` string will be looked for\n* @param lastEndMatch If true, looks for the last match of `end` (default). If false, looks for the first match.\n* @returns\n*/\nfunction between(source, start, end, lastEndMatch = true) {\n\tconst startPos = source.indexOf(start);\n\tif (startPos < 0) return;\n\tif (typeof end === `undefined`) end = start;\n\tconst endPos = lastEndMatch ? source.lastIndexOf(end) : source.indexOf(end, startPos + 1);\n\tif (endPos < 0) return;\n\treturn source.slice(startPos + 1, endPos);\n}\n/**\n* Like {@link between}, but also returns the source string without the start/end match and what's between.\n* ```js\n* const [src,between] = betweenChomp('hello [there] friend', '[', ']');\n* // src: 'hello friend'\n* // between: 'there'\n* ```\n* @param source\n* @param start\n* @param end\n* @param lastEndMatch\n* @returns\n*/\nfunction betweenChomp(source, start, end, lastEndMatch = true) {\n\tif (typeof source !== `string`) throw new Error(`Parameter 'source' is not a string`);\n\tif (typeof start !== `string`) throw new Error(`Parameter 'start' is not a string`);\n\tif (end !== void 0 && typeof end !== `string`) throw new Error(`Parameter 'end' is not a string`);\n\tconst startPos = source.indexOf(start);\n\tif (startPos < 0) return [source, void 0];\n\tif (typeof end === `undefined`) end = start;\n\tconst endPos = lastEndMatch ? source.lastIndexOf(end) : source.indexOf(end, startPos + 1);\n\tif (endPos < 0) return [source, void 0];\n\tconst between = source.slice(startPos + 1, endPos);\n\treturn [source.slice(0, startPos) + source.slice(endPos + 1), between];\n}\n/**\n* Returns first position of the given character code, or -1 if not found.\n* @param source Source string\n* @param code Code to seek\n* @param start Start index, 0 by default\n* @param end End index (inclusive), source.length-1 by default\n* @returns Found position, or -1 if not found\n*/\nfunction indexOfCharCode(source, code, start = 0, end = source.length - 1) {\n\tfor (let index = start; index <= end; index++) if (source.codePointAt(index) === code) return index;\n\treturn -1;\n}\n/**\n* Returns `source` with a given number of characters removed from start position.\n*\n* ```js\n* // Remove three characters starting at position 1\n* omitChars(`hello there`, 1, 3); // ie. removes 'ell'\n* // Yields: `ho there`\n* ```\n* @param source\n* @param removeStart Start point to remove\n* @param removeLength Number of characters to remove\n* @returns\n*/\nfunction omitChars(source, removeStart, removeLength) {\n\treturn source.slice(0, removeStart) + source.slice(removeStart + removeLength);\n}\n/**\n* Splits a string into `length`-size chunks.\n*\n* If `length` is less than or equal to 0 or greater than the length of `source`, the whole text is yielded.\n* The final yielded text may be smaller if we ran out of characters.\n*\n* ```js\n* for (const c of chunkByLength(`hello there`, 2)) {\n* // Yields:\n* // `he`, `ll`, `o `, `th`, `er`, `e`\n* }\n* ```\n* @param source Source string\n* @param size Length of each chunk\n* @returns Generator that yields each chunk\n*/\nfunction* chunkByLength(source, size) {\n\tif (source === null) throw new Error(`source parameter null`);\n\tif (size <= 0) {\n\t\tyield source;\n\t\treturn;\n\t}\n\tresultThrow(integerTest(size, `aboveZero`, `length`));\n\tif (typeof source !== `string`) throw new TypeError(`source parameter not a string`);\n\tlet pos = 0;\n\twhile (pos + size < source.length) {\n\t\tyield source.slice(pos, pos + size);\n\t\tpos += size;\n\t}\n\tif (pos < source.length) yield source.slice(pos);\n}\n/**\n* Returns all the text in `source` that precedes (and does not include) `match`. If not found, `source` is returned.\n*\n* See also: {@link beforeMatch}, {@link beforeAfterMatch}.\n*\n* ```js\n* afterMatch(`Hello. There`, `.`); // ' There'\n* afterMatch(`Hello, there', `,`); // 'Hello, there'\n* ```\n*\n* If `source` is _undefined_, an error is thrown.\n* @param source\n* @param match\n* @param options\n* @returns\n*/\nfunction beforeMatch(source, match, options = {}) {\n\treturn beforeAfterMatch(source, match, options)[0];\n}\n/**\n* Returns all the text in `source` that follows `match`. If not found, `source` is returned.\n*\n* See also: {@link beforeMatch}, {@link beforeAfterMatch}.\n*\n* ```js\n* afterMatch(`Hello. There`, `.`); // ' There'\n* afterMatch(`Hello, there', `,`); // 'Hello, there'\n* ```\n*\n* If `source` is _undefined_, an error is thrown.\n* @param source\n* @param match\n* @param options\n* @returns\n*/\nfunction afterMatch(source, match, options = {}) {\n\treturn beforeAfterMatch(source, match, options)[1];\n}\n/**\n* Returns the text that is before and after `match`.\n*\n* See also: {@link beforeMatch}, {@link afterMatch}.\n*\n* If `match` is at the end of start of `source`, after or before might be an empty string.\n* @param source\n* @param match\n* @param options\n* @returns\n*/\nfunction beforeAfterMatch(source, match, options = {}) {\n\tif (source === void 0) throw new Error(`Param 'source' is undefined`);\n\tlet fallback = options.fallback;\n\tconst ifNoMatch = options.ifNoMatch ?? (fallback ? `fallback` : `original`);\n\tif (ifNoMatch === `original`) fallback = source;\n\tif (ifNoMatch === `fallback` && fallback === void 0) throw new Error(`Fallback must be provided`);\n\tconst startPos = options.startPos ?? void 0;\n\tconst m = options.fromEnd ?? false ? source.lastIndexOf(match, startPos) : source.indexOf(match, startPos);\n\tif (m < 0 && ifNoMatch === `throw`) throw new Error(`Match '${match}' not found in source.`);\n\tif (m < 0 && ifNoMatch === `original`) return [source, source];\n\tif (m < 0 && ifNoMatch === `fallback`) return [fallback, fallback];\n\treturn [source.slice(0, m), source.slice(Math.max(0, m + match.length))];\n}\n/**\n* 'Unwraps' a string, removing one or more 'wrapper' strings that it starts and ends with.\n* Only removes when a matching end is found.\n* ```js\n* unwrap(\"'hello'\", \"'\"); // hello\n* // No mataching end 'a', so nothing happens\n* unwrap(\"apple\", \"a\"); // apple\n* unwrap(\"wow\", \"w\"); // o\n* unwrap(`\"'blah'\"`, '\"', \"'\"); // blah\n* ```\n* @param source\n* @param wrappers\n* @returns\n*/\nfunction unwrap(source, ...wrappers) {\n\tlet matched = false;\n\tdo {\n\t\tmatched = false;\n\t\tfor (const w of wrappers) if (source.startsWith(w) && source.endsWith(w)) {\n\t\t\tsource = source.slice(w.length, source.length - w.length * 2 + 1);\n\t\t\tmatched = true;\n\t\t}\n\t} while (matched);\n\treturn source;\n}\n/**\n* Calculates the span, defined in {@link Range} indexes, that includes `start` through to `end` character positions.\n*\n* After using {@link splitRanges} to split text, `lineSpan` is used to associate some text coordinates with ranges.\n*\n* @param ranges Ranges\n* @param start Start character position, in source text reference\n* @param end End character position, in source text reference\n* @returns Span\n*/\nfunction lineSpan(ranges, start, end) {\n\tlet s = -1;\n\tlet endPos = -1;\n\tfor (const [index, r] of ranges.entries()) {\n\t\ts = index;\n\t\tif (r.text.length === 0) continue;\n\t\tif (start < r.end) break;\n\t}\n\tfor (let index = s; index < ranges.length; index++) {\n\t\tconst r = ranges[index];\n\t\tendPos = index;\n\t\tif (end === r.end) {\n\t\t\tendPos = index + 1;\n\t\t\tbreak;\n\t\t}\n\t\tif (end < r.end) break;\n\t}\n\treturn {\n\t\tlength: endPos - s,\n\t\tstart: s,\n\t\tend: endPos\n\t};\n}\n/**\n* Splits a source string into ranges:\n* ```js\n* const ranges = splitRanges(\"hello;there;fella\", \";\");\n* ```\n*\n* Each range consists of:\n* ```js\n* {\n* text: string - the text of range\n* start: number - start pos of range, wrt to source\n* end: number - end pos of range, wrt to source\n* index: number - index of range (starting at 0)\n* }\n* ```\n* @param source\n* @param split\n* @returns\n*/\nfunction splitRanges(source, split) {\n\tlet start = 0;\n\tlet text = ``;\n\tconst ranges = [];\n\tlet index = 0;\n\tfor (let index_ = 0; index_ < source.length; index_++) if (source.indexOf(split, index_) === index_) {\n\t\tconst end = index_;\n\t\tranges.push({\n\t\t\ttext,\n\t\t\tstart,\n\t\t\tend,\n\t\t\tindex\n\t\t});\n\t\tstart = end + 1;\n\t\ttext = ``;\n\t\tindex++;\n\t} else text += source.charAt(index_);\n\tif (start < source.length) ranges.push({\n\t\ttext,\n\t\tstart,\n\t\tindex,\n\t\tend: source.length\n\t});\n\treturn ranges;\n}\n/**\n* Counts the number of times one of `chars` appears at the front of\n* a string, contiguously.\n*\n* ```js\n* countCharsFromStart(` hi`, ` `); // 2\n* countCharsFromStart(`hi `, ` `); // 0\n* countCharsFromStart(` hi `, ` `); // 2\n* ```\n* @param source\n* @param chars\n* @returns\n*/\nfunction countCharsFromStart(source, ...chars) {\n\tlet counted = 0;\n\tfor (let index = 0; index < source.length; index++) if (chars.includes(source.charAt(index))) counted++;\n\telse break;\n\treturn counted;\n}\n/**\n* Returns _true_ if `source` starts and ends with `start` and `end`. Case-sensitive.\n* If _end_ is omitted, the the `start` value will be used.\n*\n* ```js\n* startsEnds(`This is a string`, `This`, `string`); // True\n* startsEnds(`This is a string`, `is`, `a`); // False\n* starsEnds(`test`, `t`); // True, starts and ends with 't'\n* ```\n* @param source String to search within\n* @param start Start\n* @param end End (if omitted, start will be looked for at end as well)\n* @returns True if source starts and ends with provided values.\n*/\nfunction startsEnds(source, start, end = start) {\n\treturn source.startsWith(start) && source.endsWith(end);\n}\nfunction htmlEntities(source) {\n\treturn source.replaceAll(htmlEntitiesRegexPattern, (index) => `&#${index.codePointAt(0)};`);\n}\n/**\n* Simple wilcard matching. Use '*' in `pattern` to denote any number of characters.\n* ```js\n* // Must start with 'cat'\n* wildcard(`cat*`,`caterpillar`); // true\n* // Must end with 'cat'\n* wildcat(`*cat`, `bobcat`); // true\n* // 'cat' anywhere in string\n* wildcard(`*cat*`, `see cat run`); // true\n* ```\n* @param pattern\n* @returns\n*/\nfunction wildcard(pattern) {\n\tconst escapeRegex = (value) => value.replaceAll(escapeRegexPattern, `\\\\$1`);\n\tpattern = pattern.split(`*`).map((m) => escapeRegex(m)).join(`.*`);\n\tpattern = `^${pattern}$`;\n\tconst regex = new RegExp(pattern);\n\treturn (value) => {\n\t\treturn regex.test(value);\n\t};\n}\n/**\n* Deterministic string hash. Converts string to number of 0..1 scale.\n*/\nfunction hash(input) {\n\tif (typeof input !== `string`) throw new TypeError(`Param 'input' is not a string. Got: ${typeof input}`);\n\tlet h = 2166136261;\n\tfor (let i = 0; i < input.length; i++) {\n\t\th ^= input.charCodeAt(i);\n\t\th = Math.imul(h, 16777619);\n\t}\n\th >>>= 0;\n\treturn h / 4294967296;\n}\n//#endregion\nexport { text_tokenise_exports as C, wildcard as S, stringSegmentsLastToWhole as _, between as a, toStringAbbreviate as b, countCharsFromStart as c, indexOfCharCode as d, lineSpan as f, stringSegmentsFirstToWhole as g, startsEnds as h, beforeMatch as i, hash as l, splitRanges as m, afterMatch as n, betweenChomp as o, omitChars as p, beforeAfterMatch as r, chunkByLength as s, abbreviate as t, htmlEntities as u, stringSegmentsWholeToEnd as v, text_edit_distance_exports as w, unwrap as x, stringSegmentsWholeToFirst as y };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { f as removeCircularReferences, n as isEqualContextString, r as isEqualDefault, u as toStringDefault } from \"./is-equal-BOIjfI3O.js\";\nimport { A as defaultComparer } from \"./maps-D25APhug.js\";\nimport { b as toStringAbbreviate } from \"./text-CovhuGNs.js\";\nimport { integerTest, nullUndefTest, numberTest, resultThrow, testPlainObjectOrPrimitive } from \"@ixfx/guards\";\nimport { getErrorMessage } from \"@ixfx/debug\";\n//#region src/records/clone-from-fields.ts\nconst cloneFromFields = (source) => {\n\tconst entries = [];\n\tfor (const field in source) {\n\t\tconst value = source[field];\n\t\tif (testPlainObjectOrPrimitive(value)) entries.push([field, value]);\n\t}\n\treturn Object.fromEntries(entries);\n};\n//#endregion\n//#region src/records/map-object-keys.ts\n/**\n* Maps the keys of an object, returning a transformed object.\n* ```js\n* const input = {\n* hello: `there`,\n* chap: `chappie`\n* }\n* \n* mapObjectKeys(input, key => key.toUppercase());\n* \n* // Yields: { HELLO: `there`, CHAP: `chappie` }\n* ```\n* @param object \n* @param mapFunction \n* @returns \n*/\nconst mapObjectKeys = (object, mapFunction) => {\n\tconst destinationObject = {};\n\tfor (const entries of Object.entries(object)) {\n\t\tconst key = mapFunction(entries[0]);\n\t\tdestinationObject[key] = entries[1];\n\t}\n\treturn destinationObject;\n};\n//#endregion\n//#region src/records/compare.ts\n/**\n* Compares the keys of two objects, returning a set of those in\n* common, and those in either A or B exclusively.\n* ```js\n* const a = { colour: `red`, intensity: 5 };\n* const b = { colour: `pink`, size: 10 };\n* const c = compareObjectKeys(a, b);\n* // c.shared = [ `colour` ]\n* // c.a = [ `intensity` ]\n* // c.b = [ `size` ]\n* ```\n* @param a \n* @param b \n* @returns \n*/\nconst compareObjectKeys = (a, b) => {\n\treturn compareIterableValuesShallow(Object.keys(a), Object.keys(b));\n};\n/**\n* Returns the changed fields from A -> B. It's assumed that A and B have the same shape.\n* ie. returns an object that only consists of fields which have changed in B compared to A.\n* \n* ```js\n* const a = { msg: `hi`, v: 10 };\n* \n* changedProperties(a, { msg: `hi`, v: 10 }); // {}\n* changedProperties(a, { msg: `hi!!`, v: 10 }); // { msg: `hi!!` }\n* changedProperties(a, { msg: `hi!!` }); // { msg: `hi!!`, v: undefined }\n* ```\n* \n* If B has additional or removed fields, this is considered an error.\n* \n* If a field is an array, the whole array is returned, rather than a diff.\n* @param a \n* @param b \n*/\nconst changedProperties = (a, b) => {\n\tconst r = compareObjectData(a, b, true);\n\tif (Object.entries(r.added).length > 0) throw new Error(`Shape of data has changed`);\n\tif (Object.entries(r.removed).length > 0) throw new Error(`Shape of data has changed`);\n\treturn compareResultToObject(r, b);\n};\nconst compareResultToObject = (r, b) => {\n\tconst output = {};\n\tif (r.isArray) return b;\n\tfor (const entry of Object.entries(r.changed)) output[entry[0]] = entry[1];\n\tfor (const entry of Object.entries(r.added)) output[entry[0]] = entry[1];\n\tfor (const childEntry of Object.entries(r.children)) {\n\t\tconst childResult = childEntry[1];\n\t\tif (childResult.hasChanged) output[childEntry[0]] = compareResultToObject(childResult, b[childEntry[0]]);\n\t}\n\treturn output;\n};\n/**\n* Produces a {@link CompareChangeSet} between two arrays.\n* \n* @param a Earlier array to compare\n* @param b Later array to compare\n* @param eq Equality comparison for values\n* @returns Change set.\n*/\nconst compareArrays = (a, b, eq = isEqualDefault) => {\n\tif (!Array.isArray(a)) throw new Error(`Param 'a' is not an array`);\n\tif (!Array.isArray(b)) throw new Error(`Param 'b' is not an array`);\n\tconst c = compareObjectData(a, b, false, eq);\n\tif (!c.isArray) throw new Error(`Change set does not have arrays as parameters`);\n\tconst convert = (key) => {\n\t\tif (key.startsWith(`_`)) return Number.parseInt(key.slice(1));\n\t\telse throw new Error(`Unexpected key '${key}'`);\n\t};\n\treturn {\n\t\t...c,\n\t\tadded: mapObjectKeys(c.added, convert),\n\t\tchanged: mapObjectKeys(c.changed, convert),\n\t\tremoved: c.removed.map((v) => convert(v)),\n\t\tsummary: c.summary.map((value) => {\n\t\t\treturn [\n\t\t\t\tvalue[0],\n\t\t\t\tconvert(value[1]),\n\t\t\t\tvalue[2]\n\t\t\t];\n\t\t})\n\t};\n};\n/**\n* Compares A to B. Assumes they are simple objects, essentially key-value pairs, where the \n* values are primitive values or other simple objects. It also works with arrays.\n* \n* Uses === equality semantics by default.\n* @param a \n* @param b \n*/\nconst compareObjectData = (a, b, assumeSameShape = false, eq = isEqualDefault) => {\n\ta ??= {};\n\tb ??= {};\n\tconst entriesA = Object.entries(a);\n\tconst entriesB = Object.entries(b);\n\tconst scannedKeys = /* @__PURE__ */ new Set();\n\tconst changed = {};\n\tconst added = {};\n\tconst children = {};\n\tconst removed = [];\n\tconst isArray = Array.isArray(a);\n\tconst summary = new Array();\n\tlet hasChanged = false;\n\tfor (const entry of entriesA) {\n\t\tconst outputKey = isArray ? `_${entry[0]}` : entry[0];\n\t\tconst aValue = entry[1];\n\t\tconst bValue = b[entry[0]];\n\t\tscannedKeys.add(entry[0]);\n\t\tif (bValue === void 0) {\n\t\t\thasChanged = true;\n\t\t\tif (assumeSameShape && !isArray) {\n\t\t\t\tchanged[outputKey] = bValue;\n\t\t\t\tsummary.push([\n\t\t\t\t\t`mutate`,\n\t\t\t\t\toutputKey,\n\t\t\t\t\tbValue\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\tremoved.push(outputKey);\n\t\t\t\tsummary.push([\n\t\t\t\t\t`del`,\n\t\t\t\t\toutputKey,\n\t\t\t\t\taValue\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof aValue === `object`) {\n\t\t\tconst r = compareObjectData(aValue, bValue, assumeSameShape, eq);\n\t\t\tif (r.hasChanged) hasChanged = true;\n\t\t\tchildren[outputKey] = r;\n\t\t\tconst childSummary = r.summary.map((sum) => {\n\t\t\t\treturn [\n\t\t\t\t\tsum[0],\n\t\t\t\t\toutputKey + `.` + sum[1],\n\t\t\t\t\tsum[2]\n\t\t\t\t];\n\t\t\t});\n\t\t\tsummary.push(...childSummary);\n\t\t} else if (!eq(aValue, bValue)) {\n\t\t\tchanged[outputKey] = bValue;\n\t\t\thasChanged = true;\n\t\t\tsummary.push([\n\t\t\t\t`mutate`,\n\t\t\t\toutputKey,\n\t\t\t\tbValue\n\t\t\t]);\n\t\t}\n\t}\n\tif (!assumeSameShape || isArray) for (const entry of entriesB) {\n\t\tconst key = isArray ? `_${entry[0]}` : entry[0];\n\t\tif (scannedKeys.has(entry[0])) continue;\n\t\tadded[key] = entry[1];\n\t\thasChanged = true;\n\t\tsummary.push([\n\t\t\t`add`,\n\t\t\tkey,\n\t\t\tentry[1]\n\t\t]);\n\t}\n\treturn {\n\t\tchanged,\n\t\tadded,\n\t\tremoved,\n\t\tchildren,\n\t\thasChanged,\n\t\tisArray,\n\t\tsummary\n\t};\n};\n//#endregion\n//#region src/records/keys-to-numbers.ts\n/**\n* Returns a copy of `object` with integer numbers as keys instead of whatever it has.\n* ```js\n* keysToNumbers({ '1': true }); // Yields: { 1: true }\n* ```\n* \n* The `onInvalidKey` sets how to handle keys that cannot be converted to integers.\n* * 'throw' (default): throws an exception\n* * 'ignore': that key & value is ignored\n* * 'keep': uses the string key instead\n* \n* \n* ```js\n* keysToNumber({ hello: 'there' }, `ignore`); // Yields: { }\n* keysToNumber({ hello: 'there' }, `throw`); // Exception\n* keysToNumber({ hello: 'there' }, `keep`); // Yields: { hello: 'there' }\n* ```\n* \n* Floating-point numbers will be converted to integer by rounding.\n* ```js\n* keysToNumbers({ '2.4': 'hello' }); // Yields: { 2: 'hello' }\n* ```\n* @param object \n* @param onInvalidKey \n* @returns \n*/\nconst keysToNumbers = (object, onInvalidKey = `throw`) => {\n\tconst returnObject = {};\n\tfor (const entry of Object.entries(object)) {\n\t\tconst asNumber = Number.parseInt(entry[0]);\n\t\tif (Number.isNaN(asNumber)) switch (onInvalidKey) {\n\t\t\tcase `throw`: throw new TypeError(`Cannot convert key '${entry[0]}' to an integer`);\n\t\t\tcase `ignore`: continue;\n\t\t\tcase `keep`:\n\t\t\t\treturnObject[entry[0]] = entry[1];\n\t\t\t\tcontinue;\n\t\t\tdefault: throw new Error(`Param 'onInvalidKey' should be: 'throw', 'ignore' or 'keep'.`);\n\t\t}\n\t\treturnObject[asNumber] = entry[1];\n\t}\n\treturn returnObject;\n};\n//#endregion\n//#region src/records/map-object.ts\n/**\n* Maps the top-level properties of an object through a map function.\n* That is, run each of the values of an object through a function,\n* setting the result onto the same key structure as original.\n* \n* It is NOT recursive.\n*\n* The mapping function gets a single args object, consisting of `{ value, field, index }`,\n* where 'value' is the value of the field, 'field' the name, and 'index' a numeric count.\n* @example Double the value of all fields\n* ```js\n* const rect = { width: 100, height: 250 };\n* const doubled = mapObjectShallow(rect, args => {\n* return args.value*2;\n* });\n* // Yields: { width: 200, height: 500 }\n* ```\n*\n* Since the map callback gets the name of the property, it can do context-dependent things.\n* ```js\n* const rect = { width: 100, height: 250, colour: 'red' }\n* const doubled = mapObjectShallow(rect, args => {\n* if (args.field === 'width') return args.value*3;\n* else if (typeof args.value === 'number') return args.value*2;\n* return args.value;\n* });\n* // Yields: { width: 300, height: 500, colour: 'red' }\n* ```\n* In addition to bulk processing, it allows remapping of property types.\n*\n* In terms of type-safety, the mapped properties are assumed to have the\n* same type.\n*\n* ```js\n* const o = {\n* x: 10,\n* y: 20,\n* width: 200,\n* height: 200\n* }\n*\n* // Make each property use an averager instead\n* const oAvg = mapObjectShallow(o, args => {\n* return movingAverage(10);\n* });\n*\n* // Instead of { x:number, y:number... }, we now have { x:movingAverage(), y:movingAverage()... }\n* // Add a value to the averager\n* oAvg.x.add(20);\n* ```\n*/\nconst mapObjectShallow = (object, mapFunction) => {\n\tconst mapped = Object.entries(object).map(([sourceField, sourceFieldValue], index) => [sourceField, mapFunction({\n\t\tvalue: sourceFieldValue,\n\t\tfield: sourceField,\n\t\tindex,\n\t\tpath: sourceField\n\t})]);\n\treturn Object.fromEntries(mapped);\n};\n/**\n* Maps the contents of `data` using `mapper` as a structured set of map functions.\n* ```js\n* const a = {\n* person: {\n* size: 20\n* }\n* hello: `there`\n* }\n* mapObjectByObject(a, {\n* person: {\n* size: (value, context) => {\n* return value * 2\n* }\n* }\n* });\n* // Yields: { person: { size: 40 }, hello: `there` }\n* ```\n* @param data \n* @param mapper \n* @returns \n*/\nfunction mapObjectByObject(data, mapper) {\n\tconst entries = Object.entries(data);\n\tfor (const entry of entries) if (entry[0] in mapper) {\n\t\tconst m = mapper[entry[0]];\n\t\tentry[1] = typeof m === `object` ? mapObjectByObject(entry[1], m) : m(entry[1], data);\n\t}\n\treturn Object.fromEntries(entries);\n}\n//#endregion\n//#region src/records/merge.ts\n/**\n* Merges objects together, the rightmost objects overriding properties of earlier objects.\n* \n* The return type is the intersection of all properties\n* ```js\n* const a = { name: `jane`, age: 30 };\n* const b = { name: `fred`, age: 31, colour: `blue` };\n* const c = merge(a, b);\n* // Yields:\n* // { name: `fred`, age: 31, colour: `blue` } \n* ```\n* \n* Alternatively, use {@link mergeSameShape} if the return shape\n* should be based on the first object.\n* @param a \n* @returns Merged object\n*/\nfunction merge(...a) {\n\treturn Object.assign({}, ...a);\n}\n/**\n* Merges objects together, conforming to the shape of the first object.\n* Properties contained on later objects are ignored if they aren't part of the first.\n* \n* If a single object is passed in, a copy is returned.\n* \n* Use {@link merge} for object shape to be a union\n* @param a Object arrays to merge\n* @returns \n*/\nfunction mergeSameShape(...a) {\n\tconst aEntries = Object.entries(a[0]);\n\tfor (let index = 1; index < a.length; index++) {\n\t\tconst bEntries = Object.entries(a[index]);\n\t\tfor (const [key, value] of bEntries) {\n\t\t\tconst aEntry = aEntries.find(([aKey]) => aKey === key);\n\t\t\tif (aEntry) aEntry[1] = value;\n\t\t}\n\t}\n\treturn Object.fromEntries(aEntries);\n}\n//#endregion\n//#region src/records/prefix.ts\n/**\n* Returns a new object based on `data` but with all\n* properties prefixed by `prefix`.\n* \n* ```js\n* prefixProperties({ name: `x`, size: 10 }, `test-`);\n* \n* // Yields:\n* // { test-name: `x`, test-size: 10 }\n* ```\n* @param data \n* @param prefix \n* @returns \n*/\nfunction prefixProperties(data, prefix) {\n\tconst changed = [];\n\tfor (const d of data) {\n\t\tconst entries = Object.entries(d);\n\t\tconst changedEntries = [];\n\t\tfor (const [key, value] of entries) changedEntries.push([prefix + key, value]);\n\t\tchanged.push(Object.fromEntries(changedEntries));\n\t}\n\treturn changed;\n}\n//#endregion\n//#region src/is-primitive.ts\n/**\n* Returns _true_ if `value` is number, string, bigint or boolean.\n* Returns _false_ if `value` is an object, null, undefined\n* \n* Use {@link isPrimitiveOrObject} to also return true if `value` is an object.\n* @param value Value to check\n* @returns _True_ if value is number, string, bigint or boolean.\n*/\nfunction isPrimitive(value) {\n\tif (typeof value === `number`) return true;\n\tif (typeof value === `string`) return true;\n\tif (typeof value === `bigint`) return true;\n\tif (typeof value === `boolean`) return true;\n\treturn false;\n}\n/**\n* Returns _true_ if `value` is number, string, bigint, boolean or an object\n* \n* Use {@link isPrimitive} to not include objects.\n* @param value\n* @returns \n*/\nfunction isPrimitiveOrObject(value) {\n\tif (isPrimitive(value)) return true;\n\tif (typeof value === `object`) return true;\n\treturn false;\n}\n//#endregion\n//#region src/records/traverse.ts\n/**\n* Helper function to get a 'friendly' string representation of an array of {@link RecordEntry}.\n* @param entries\n* @returns\n*/\nfunction prettyPrintEntries(entries) {\n\tif (entries.length === 0) return `(empty)`;\n\tlet t = ``;\n\tfor (const [index, entry] of entries.entries()) {\n\t\tt += ` `.repeat(index);\n\t\tt += `${entry.name} = ${JSON.stringify(entry.nodeValue)}\\n`;\n\t}\n\treturn t;\n}\n/**\n* Returns a human-friendly debug string for a tree-like structure\n* ```js\n* console.log(Trees.prettyPrint(obj));\n* ```\n* @param indent\n* @param node\n* @param options\n* @returns\n*/\nfunction recordEntryPrettyPrint(node, indent = 0, options = {}) {\n\tresultThrow(nullUndefTest(node, `node`));\n\tconst entry = getNamedRecordEntry(node, options.name ?? `node`);\n\tconst t = `${` `.repeat(indent)} + name: ${entry.name} value: ${JSON.stringify(entry.nodeValue)}`;\n\tconst childrenAsArray = [...recordChildren(node, options)];\n\treturn childrenAsArray.length > 0 ? `${t}\\n${childrenAsArray.map((d) => recordEntryPrettyPrint(d.nodeValue, indent + 1, {\n\t\t...options,\n\t\tname: d.name\n\t})).join(`\\n`)}` : t;\n}\n/**\n* Returns the direct children of a tree-like object as a pairing\n* of node name and value. Supports basic objects, Maps and arrays.\n*\n* Sub-children are included as an object blob.\n*\n* @example Simple object\n* ```js\n* const o = {\n* colour: {\n* r: 0.5, g: 0.5, b: 0.5\n* }\n* };\n*\n* const children = [ ...Trees.children(o) ];\n* // Children:\n* // [\n* // { name: \"colour\", value: { b: 0.5, g: 0.5, r: 0.5 } }\n* // ]\n* const subChildren = [ ...Trees.children(o.colour) ];\n* // [ { name: \"r\", value: 0.5 }, { name: \"g\", value: 0.5 }, { name: \"b\", value: 0.5 } ]\n* ```\n*\n* Arrays are assigned a name based on index.\n* @example Arrays\n* ```js\n* const colours = [ { r: 1, g: 0, b: 0 }, { r: 0, g: 1, b: 0 }, { r: 0, g: 0, b: 1 } ];\n* // Children:\n* // [\n* // { name: \"array[0]\", value: {r:1,g:0,b:0} },\n* // { name: \"array[1]\", value: {r:0,g:1,b:0} },\n* // { name: \"array[2]\", value: {r:0,g:0,b:1} },\n* // ]\n* ```\n*\n* Pass in `options.name` (eg 'colours') to have names generated as 'colours[0]', etc.\n* Options can also be used to filter children. By default all direct children are returned.\n* @param node\n* @param options\n*/\nfunction* recordChildren(node, options = {}) {\n\tresultThrow(nullUndefTest(node, `node`));\n\tconst filter = options.filter ?? `none`;\n\tconst filterByValue = (v) => {\n\t\tif (filter === `none`) return [true, isPrimitive(v)];\n\t\telse if (filter === `leaves` && isPrimitive(v)) return [true, true];\n\t\telse if (filter === `branches` && !isPrimitive(v)) return [true, false];\n\t\treturn [false, isPrimitive(v)];\n\t};\n\tif (Array.isArray(node)) for (const [index, element] of node.entries()) {\n\t\tconst f = filterByValue(element);\n\t\tif (f[0]) yield {\n\t\t\tname: index.toString(),\n\t\t\tsourceValue: element,\n\t\t\tnodeValue: f[1] ? element : void 0\n\t\t};\n\t}\n\telse if (typeof node === `object`) if (options.withPrototype) for (const name in node) {\n\t\tconst value = node[name];\n\t\tconst f = filterByValue(value);\n\t\tif (f[0]) yield {\n\t\t\tname,\n\t\t\tsourceValue: value,\n\t\t\tnodeValue: f[1] ? value : void 0\n\t\t};\n\t}\n\telse {\n\t\tconst entriesIter = `entries` in node ? node.entries() : Object.entries(node);\n\t\tfor (const [name, value] of entriesIter) {\n\t\t\tconst f = filterByValue(value);\n\t\t\tif (f[0]) yield {\n\t\t\t\tname,\n\t\t\t\tsourceValue: value,\n\t\t\t\tnodeValue: f[1] ? value : void 0\n\t\t\t};\n\t\t}\n\t}\n}\nfunction* recordEntriesDepthFirst(node, options = {}, ancestors = []) {\n\tif (node === null || node === void 0) return;\n\tconst opts = {\n\t\tfilter: options.filter ?? `none`,\n\t\tname: options.name ?? ``,\n\t\twithPrototype: options.withPrototype ?? false,\n\t\tseen: options.seen ?? /* @__PURE__ */ new WeakSet()\n\t};\n\tif (typeof node === `object`) {\n\t\tif (opts.seen.has(node)) return;\n\t\topts.seen.add(node);\n\t}\n\tfor (const c of recordChildren(node, opts)) {\n\t\tyield {\n\t\t\t...c,\n\t\t\tancestors: [...ancestors]\n\t\t};\n\t\tyield* recordEntriesDepthFirst(c.sourceValue, opts, [...ancestors, c.name]);\n\t}\n}\n/**\n* Finds a given direct child by name\n* @param name\n* @param node\n* @returns\n*/\nfunction recordEntryChildByName(name, node) {\n\tfor (const d of recordChildren(node)) if (d.name === name) return d;\n}\n/**\n* Returns the closest matching entry, tracing `path` in an array, Map or simple object.\n* Returns an entry with _undefined_ value at the point where tracing stopped.\n* Use {@link traceRecordEntryByPath} to step through all the segments.\n*\n* ```js\n* const people = {\n* jane: {\n* address: {\n* postcode: 1000,\n* street: 'West St',\n* city: 'Blahville'\n* },\n* colour: 'red'\n* }\n* }\n* Trees.getByPath('jane.address.postcode', people); // '.' default separator\n* // ['postcode', 1000]\n* Trees.getByPath('jane.address.country.state', people);\n* // ['country', undefined] - since full path could not be resolved.\n* ```\n* @param path Path, eg `jane.address.postcode`\n* @param node Node to look within\n* @param options Options for parsing path. By default '.' is used as a separator\n* @returns\n*/\nfunction getRecordEntryByPath(path, node, options = {}) {\n\tconst paths = [...traceRecordEntryByPath(path, node, options)];\n\tif (paths.length === 0) throw new Error(`Could not trace path: ${path} `);\n\treturn paths.at(-1);\n}\n/**\n* Enumerates over children of `node` towards the node named in `path`.\n* This is useful if you want to get the interim steps to the target node.\n*\n* Use {@link getRecordEntryByPath} if you don't care about interim steps.\n*\n* ```js\n* const people = {\n* jane: {\n* address: {\n* postcode: 1000,\n* street: 'West St',\n* city: 'Blahville'\n* },\n* colour: 'red'\n* }\n* }\n* for (const p of Trees.traceByPath('jane.address.street', people)) {\n* // { name: \"jane\", value: { address: { postcode: 1000,street: 'West St', city: 'Blahville' }, colour: 'red'} },\n* // { name: \"address\", value: { postcode: 1000, street: 'West St', city: 'Blahville' } },\n* // { name: \"street\", value: \"West St\" } }\n* }\n* ```\n*\n* Results stop when the path can't be followed any further.\n* The last entry will have a name of the last sought path segment, and _undefined_ as its value.\n*\n* @param path Path to traverse\n* @param node Starting node\n* @param options Options for path traversal logic\n* @returns\n*/\nfunction* traceRecordEntryByPath(path, node, options = {}) {\n\tresultThrow(nullUndefTest(path, `path`), nullUndefTest(node, `node`));\n\tconst separator = options.separator ?? `.`;\n\tconst pathSplit = path.split(separator);\n\tconst ancestors = [];\n\tfor (const p of pathSplit) {\n\t\tconst entry = recordEntryChildByName(p, node);\n\t\tif (!entry) {\n\t\t\tyield {\n\t\t\t\tname: p,\n\t\t\t\tsourceValue: void 0,\n\t\t\t\tnodeValue: void 0,\n\t\t\t\tancestors\n\t\t\t};\n\t\t\treturn;\n\t\t}\n\t\tnode = entry.sourceValue;\n\t\tyield {\n\t\t\t...entry,\n\t\t\tancestors: [...ancestors]\n\t\t};\n\t\tancestors.push(p);\n\t}\n}\n/**\n* Generates a name for a node.\n* Uses the 'name' property if it exists, otherwise uses `defaultName`\n* @param node\n* @param defaultName\n* @returns\n*/\nfunction getNamedRecordEntry(node, defaultName = ``) {\n\tif (`name` in node && `nodeValue` in node && `sourceValue` in node) return node;\n\tif (`name` in node) return {\n\t\tname: node.name,\n\t\tnodeValue: node,\n\t\tsourceValue: node\n\t};\n\treturn {\n\t\tname: defaultName,\n\t\tnodeValue: node,\n\t\tsourceValue: node\n\t};\n}\n//#endregion\n//#region src/records/values.ts\n/**\n* Yields numerical values based on the an input of objects and the property to use.\n* \n* ```js\n* const data = [\n* { size: 10 }, { size: 20 }, { size: 0 }\n* ]\n* [...enumerateNumericalValues(data, `size`)]; // [ 10, 20, 0 ]\n* ```\n* \n* If any of objects has a non numerical value for `propertyName`, a TypeError is thrown.\n* @param records \n* @param propertyName \n* @returns \n*/\nfunction* enumerateNumericalValues(records, propertyName) {\n\tfor (const rec of records) {\n\t\tconst fieldValue = rec[propertyName];\n\t\tif (typeof fieldValue !== `number`) throw new TypeError(`Property value was not a number. Property: ${propertyName} Value: ${fieldValue} Type: ${typeof fieldValue}`);\n\t\tyield fieldValue;\n\t}\n}\n//#endregion\n//#region src/records/zip.ts\n/**\n* Merge corresponding objects from arrays. This is assuming objects at the same array indices are connected.\n* \n* Arrays must be the same length. When merging objects, the properties of later objects override those of earlier objects.\n* \n* ```js\n* const a = [ { name: `jane`, age: 30 }, { name: `bob`, age: 40 } ];\n* const b = [ { name: `fred`, colour: `red` }, { name: `johanne` } ];\n* const c = [...zip(a, b)];\n* // Yields:\n* // [\n* // { name: `fred`, age: 30, colour: `red` },\n* // { name: `johanne`, age: 40 }\n* // ]\n* ```\n* @param toMerge Arrays to merge\n* @throws {TypeError} If either parameter is not an array\n* @throws {TypeError} If the arrays are not of the same length\n* @returns Generator of merged records \n*/\nfunction* zip$1(...toMerge) {\n\tlet len = -1;\n\tfor (let index = 0; index < toMerge.length; index++) {\n\t\tif (!Array.isArray(toMerge[index])) throw new TypeError(`Value at index ${index} is not an array as expected`);\n\t\tif (len === -1) len = toMerge[index].length;\n\t\telse if (toMerge[index].length !== len) throw new TypeError(`Array length mismatch. Expected: ${len} Actual: ${toMerge[index].length} Array: ${index}`);\n\t}\n\tfor (let index = 0; index < len; index++) yield merge(...toMerge.map((arr) => arr[index]));\n}\n//#endregion\n//#region src/records.ts\nvar records_exports = /* @__PURE__ */ __exportAll({\n\tchangedProperties: () => changedProperties,\n\tcloneFromFields: () => cloneFromFields,\n\tcompareArrays: () => compareArrays,\n\tcompareObjectData: () => compareObjectData,\n\tcompareObjectKeys: () => compareObjectKeys,\n\tenumerateNumericalValues: () => enumerateNumericalValues,\n\tgetRecordEntryByPath: () => getRecordEntryByPath,\n\tkeysToNumbers: () => keysToNumbers,\n\tmapObjectByObject: () => mapObjectByObject,\n\tmapObjectKeys: () => mapObjectKeys,\n\tmapObjectShallow: () => mapObjectShallow,\n\tmerge: () => merge,\n\tmergeSameShape: () => mergeSameShape,\n\tprefixProperties: () => prefixProperties,\n\tprettyPrintEntries: () => prettyPrintEntries,\n\trecordChildren: () => recordChildren,\n\trecordEntriesDepthFirst: () => recordEntriesDepthFirst,\n\trecordEntryPrettyPrint: () => recordEntryPrettyPrint,\n\tremoveCircularReferences: () => removeCircularReferences,\n\ttraceRecordEntryByPath: () => traceRecordEntryByPath,\n\tzip: () => zip$1\n});\n//#endregion\n//#region src/pathed.ts\nvar pathed_exports = /* @__PURE__ */ __exportAll({\n\tapplyChanges: () => applyChanges,\n\tcompareData: () => compareData,\n\tgetField: () => getField,\n\tgetPaths: () => getPaths,\n\tgetPathsAndData: () => getPathsAndData,\n\tupdateByPath: () => updateByPath\n});\n/**\n* Get the entries for `target`.\n* \n* 'deep probe' uses alternative means to get entries of object, since `Object.entries`\n* can fail for some objects.\n* @param target Object to get entries from\n* @param deepProbe If true\n* @returns \n*/\nconst getEntries = (target, deepProbe) => {\n\tif (target === void 0) throw new Error(`Param 'target' is undefined`);\n\tif (target === null) throw new Error(`Param 'target' is null`);\n\tif (typeof target !== `object`) throw new Error(`Param 'target' is not an object (got: ${typeof target})`);\n\tif (deepProbe) {\n\t\tconst entries = [];\n\t\tfor (const field in target) {\n\t\t\tconst value = target[field];\n\t\t\tif (testPlainObjectOrPrimitive(value)) entries.push([field, value]);\n\t\t}\n\t\treturn entries;\n\t} else return Object.entries(target);\n};\n/**\n* Scans object, producing a list of changed fields where B's value (newer) differs from A (older).\n* \n* Options:\n* - `deepEntries` (_false_): If _false_ Object.entries are used to scan the object. However this won't work for some objects, eg event args, thus _true_ is needed.\n* - `eq` (JSON.stringify): By-value comparison function\n* - `includeMissingFromA` (_false): If _true_ includes fields present on B but missing on A.\n* - `asPartial` (_false): If _true_, treats B as a partial update to B. This means that things missing from B are not considered removals.\n* @param a 'Old' value\n* @param b 'New' value\n* @param options Options for comparison\n* @returns \n*/\nfunction* compareData(a, b, options = {}) {\n\tif (typeof a === `undefined`) {\n\t\tyield {\n\t\t\tpath: options.pathPrefix ?? ``,\n\t\t\tvalue: b,\n\t\t\tstate: `added`\n\t\t};\n\t\treturn;\n\t}\n\tif (typeof b === `undefined`) {\n\t\tyield {\n\t\t\tpath: options.pathPrefix ?? ``,\n\t\t\tprevious: a,\n\t\t\tvalue: void 0,\n\t\t\tstate: `removed`\n\t\t};\n\t\treturn;\n\t}\n\tconst asPartial = options.asPartial ?? false;\n\tconst skipInstances = options.skipInstances ?? /* @__PURE__ */ new WeakSet();\n\tconst undefinedValueMeansRemoved = options.undefinedValueMeansRemoved ?? false;\n\tconst pathPrefix = options.pathPrefix ?? ``;\n\tconst deepEntries = options.deepEntries ?? false;\n\tconst eq = options.eq ?? isEqualContextString;\n\tconst includeMissingFromA = options.includeMissingFromA ?? false;\n\tconst includeParents = options.includeParents ?? false;\n\tif (isPrimitive(a) && isPrimitive(b)) {\n\t\tif (a !== b) yield {\n\t\t\tpath: pathPrefix,\n\t\t\tvalue: b,\n\t\t\tprevious: a,\n\t\t\tstate: `change`\n\t\t};\n\t\treturn;\n\t}\n\tif (isPrimitive(b)) {\n\t\tyield {\n\t\t\tpath: pathPrefix,\n\t\t\tvalue: b,\n\t\t\tprevious: a,\n\t\t\tstate: `change`\n\t\t};\n\t\treturn;\n\t}\n\tconst entriesA = getEntries(a, deepEntries);\n\tconst entriesAKeys = /* @__PURE__ */ new Set();\n\tfor (const [key, valueA] of entriesA) {\n\t\tentriesAKeys.add(key);\n\t\tconst keyOfAInB = key in b;\n\t\tconst valueOfKeyInB = b[key];\n\t\tif (typeof valueA === `object` && valueA !== null) {\n\t\t\tif (skipInstances.has(valueA)) continue;\n\t\t\tskipInstances.add(valueA);\n\t\t\tif (keyOfAInB) if (valueOfKeyInB === void 0) throw new Error(`Pathed.compareData Value for key ${key} is undefined`);\n\t\t\telse {\n\t\t\t\tconst sub = [...compareData(valueA, valueOfKeyInB, {\n\t\t\t\t\t...options,\n\t\t\t\t\tskipInstances,\n\t\t\t\t\tpathPrefix: pathPrefix + key + `.`\n\t\t\t\t})];\n\t\t\t\tif (sub.length > 0) {\n\t\t\t\t\tfor (const s of sub) yield s;\n\t\t\t\t\tif (includeParents) yield {\n\t\t\t\t\t\tpath: pathPrefix + key,\n\t\t\t\t\t\tvalue: b[key],\n\t\t\t\t\t\tprevious: valueA,\n\t\t\t\t\t\tstate: `change`\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (asPartial) continue;\n\t\t\t\tyield {\n\t\t\t\t\tpath: pathPrefix + key,\n\t\t\t\t\tvalue: void 0,\n\t\t\t\t\tprevious: valueA,\n\t\t\t\t\tstate: `removed`\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tconst subPath = pathPrefix + key;\n\t\t\tif (keyOfAInB) {\n\t\t\t\tif (valueOfKeyInB === void 0 && undefinedValueMeansRemoved) yield {\n\t\t\t\t\tpath: subPath,\n\t\t\t\t\tprevious: valueA,\n\t\t\t\t\tvalue: void 0,\n\t\t\t\t\tstate: `removed`\n\t\t\t\t};\n\t\t\t\telse if (!eq(valueA, valueOfKeyInB, subPath)) yield {\n\t\t\t\t\tpath: subPath,\n\t\t\t\t\tprevious: valueA,\n\t\t\t\t\tvalue: valueOfKeyInB,\n\t\t\t\t\tstate: `change`\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tif (asPartial) continue;\n\t\t\t\tyield {\n\t\t\t\t\tpath: subPath,\n\t\t\t\t\tprevious: valueA,\n\t\t\t\t\tvalue: void 0,\n\t\t\t\t\tstate: `removed`\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\tif (includeMissingFromA) {\n\t\tconst entriesB = getEntries(b, deepEntries);\n\t\tfor (const [key, valueB] of entriesB) {\n\t\t\tif (entriesAKeys.has(key)) continue;\n\t\t\tyield {\n\t\t\t\tpath: pathPrefix + key,\n\t\t\t\tprevious: void 0,\n\t\t\t\tvalue: valueB,\n\t\t\t\tstate: `added`\n\t\t\t};\n\t\t}\n\t}\n}\n/**\n* Returns a copy of `source` with `changes` applied.\n* @param source \n* @param changes \n*/\nconst applyChanges = (source, changes) => {\n\tfor (const change of changes) source = updateByPath(source, change.path, change.value);\n\treturn source;\n};\n/**\n* Returns a copy of `target` object with a specified path changed to `value`.\n* \n* ```js\n* const a = {\n* message: `Hello`,\n* position: { x: 10, y: 20 }\n* }\n* \n* const a1 = updateByPath(a, `message`, `new message`);\n* // a1 = { message: `new message`, position: { x: 10, y: 20 }}\n* const a2 = updateByPath(a, `position.x`, 20);\n* // a2 = { message: `hello`, position: { x: 20, y: 20 }}\n* ```\n* \n* Paths can also be array indexes:\n* ```js\n* updateByPath([`a`,`b`,`c`], 2, `d`);\n* // Yields: [ `a`, `b`, `d` ]\n* ```\n* \n* By default, only existing array indexes can be updated. Use the `allowShapeChange` parameter \n* to allow setting arbitrary indexes.\n* ```js\n* // Throws because array index 3 is undefined\n* updateByPath([ `a`, `b`, `c` ], `3`, `d`);\n* \n* // With allowShapeChange flag\n* updateByPath([ `a`, `b`, `c` ], `3`, `d`, true);\n* // Returns: [ `a`, `b`, `c`, `d` ]\n* ```\n* \n* Throws an error if:\n* * `path` cannot be resolved (eg. `position.z` in the above example)\n* * `value` applied to `target` results in the object having a different shape (eg missing a field, field\n* changing type, or array index out of bounds). Use `allowShapeChange` to suppress this error.\n* * Path is undefined or not a string\n* * Target is undefined/null\n* @param target Object to update\n* @param path Path to set value\n* @param value Value to set\n* @param allowShapeChange By default _false_, throwing an error if an update change the shape of the original object.\n* @returns \n*/\nconst updateByPath = (target, path, value, allowShapeChange = false) => {\n\tif (path === void 0) throw new Error(`Parameter 'path' is undefined`);\n\tif (typeof path !== `string`) throw new Error(`Parameter 'path' should be a string. Got: ${typeof path}`);\n\tif (target === void 0) throw new Error(`Parameter 'target' is undefined`);\n\tif (target === null) throw new Error(`Parameter 'target' is null`);\n\treturn updateByPathImpl(target, path.split(`.`), value, allowShapeChange);\n};\nconst updateByPathImpl = (o, split, value, allowShapeChange) => {\n\tif (split.length === 0) {\n\t\tif (allowShapeChange) return value;\n\t\tif (Array.isArray(o) && !Array.isArray(value)) throw new Error(`Expected array value, got: '${JSON.stringify(value)}'. Set allowShapeChange=true to ignore.`);\n\t\tif (!Array.isArray(o) && Array.isArray(value)) throw new Error(`Unexpected array value, got: '${JSON.stringify(value)}'. Set allowShapeChange=true to ignore.`);\n\t\tif (typeof o !== typeof value) throw new Error(`Cannot reassign object type. (${typeof o} -> ${typeof value}). Set allowShapeChange=true to ignore.`);\n\t\tif (typeof o === `object` && !Array.isArray(o)) {\n\t\t\tconst c = compareObjectKeys(o, value);\n\t\t\tif (c.a.length > 0) throw new Error(`New value is missing key(s): ${c.a.join(`,`)}`);\n\t\t\tif (c.b.length > 0) throw new Error(`New value cannot add new key(s): ${c.b.join(`,`)}`);\n\t\t}\n\t\treturn value;\n\t}\n\tconst start = split.shift();\n\tif (!start) return value;\n\tif (isInteger(start) && Array.isArray(o)) {\n\t\tconst index = Number.parseInt(start);\n\t\tif (index >= o.length && !allowShapeChange) throw new Error(`Array index ${index.toString()} is outside of the existing length of ${o.length.toString()}. Use allowShapeChange=true to permit this.`);\n\t\tconst copy = [...o];\n\t\tcopy[index] = updateByPathImpl(copy[index], split, value, allowShapeChange);\n\t\treturn copy;\n\t} else if (start in o) {\n\t\tconst copy = { ...o };\n\t\tcopy[start] = updateByPathImpl(copy[start], split, value, allowShapeChange);\n\t\treturn copy;\n\t} else throw new Error(`Path ${start} not found in data`);\n};\n/**\n* Gets the data at `path` in `object`. Assumes '.' separates each segment of path.\n* \n* ```js\n* getField({ name: { first: `Thom`, last: `Yorke` }}, `name.first`); // { value: `Thom` success: true }\n* getField({ colours: [`red`, `green`, `blue` ]}, `colours.1`); // { value: `green` success: true }\n* ```\n* \n* Returns an error result with more details, eg `{ success: false, error: 'Path could not be found' }`\n* \n* Throws if:\n* * `path` is not a string or empty\n* * `object` is _undefined_ or null\n* @param object Object to query\n* @param path Path\n* @param separator Separator of chunks of path. Defaults to '.'\n* @returns \n*/\nconst getField = (object, path, separator = `.`) => {\n\tif (typeof path !== `string`) throw new Error(`Param 'path' ought to be a string. Got: '${typeof path}'`);\n\tif (path.length === 0) throw new Error(`Param string 'path' is empty`);\n\tif (object === void 0) throw new Error(`Param 'object' is undefined`);\n\tif (object === null) throw new Error(`Param 'object' is null`);\n\treturn getFieldImpl(object, path.split(separator), path);\n};\nconst getFieldImpl = (object, split, position) => {\n\tif (object === void 0) return {\n\t\tsuccess: false,\n\t\terror: `Param 'object' is undefined. Position: ${position}`\n\t};\n\tif (split.length === 0) return {\n\t\tsuccess: false,\n\t\terror: `Path has been exhausted. position: ${position}`\n\t};\n\tconst start = split.shift();\n\tif (!start) return {\n\t\tsuccess: false,\n\t\terror: `Unexpected empty split path. Position: ${position}`\n\t};\n\tif (isInteger(start) && Array.isArray(object)) {\n\t\tconst index = Number.parseInt(start);\n\t\tif (typeof object[index] === `undefined`) return {\n\t\t\tsuccess: false,\n\t\t\terror: `Index '${index}' does not exist. Length: ${object.length}. Position: ${position}`\n\t\t};\n\t\tif (split.length === 0) return {\n\t\t\tvalue: object[index],\n\t\t\tsuccess: true\n\t\t};\n\t\telse return getFieldImpl(object[index], split, split.join(`.`));\n\t} else if (typeof object === `object` && start in object) if (split.length === 0) return {\n\t\tvalue: object[start],\n\t\tsuccess: true\n\t};\n\telse return getFieldImpl(object[start], split, split.join(`.`));\n\telse return {\n\t\tsuccess: false,\n\t\terror: `Path '${start}' not found. Position: ${position}`\n\t};\n};\n/**\n* Iterates 'paths' for all the fields on `o`\n* ```\n* const d = {\n* accel: { x: 1, y: 2, z: 3 },\n* gyro: { x: 4, y: 5, z: 6 }\n* };\n* const paths = [...getFieldPaths(d)];\n* // Yields [ `accel`, `gyro`, `accel.x`, `accel.y`,`accel.z`,`gyro.x`,`gyro.y`,`gyro.z` ]\n* ```\n*\n* Use {@link getField} to fetch data based on a path\n*\n* If object is _null_ or _undefined_, no results are returned.\n* \n* If `onlyLeaves` is _true_ (default: _false_), only 'leaf' nodes are included. \n* Leaf nodes are those that contain a primitive value.\n* ```js\n* const paths = getFieldPaths(d, true);\n* // Yields [ `accel.x`, `accel.y`,`accel.z`,`gyro.x`,`gyro.y`,`gyro.z` ]\n* ```\n*\n* Options:\n* * onlyLeaves: If _true_, only paths to 'leaf' nodes are included. Leaf nodes are those that contain a primitive value. Default: _false_\n* * withPrototype: If _true_, includes prototype chain. Default: _false_\n* @param object Object to get paths for.\n* @param options Options\n* @returns\n*/\nfunction* getPaths(object, options = {}) {\n\tconst onlyLeaves = options.onlyLeaves ?? false;\n\tif (object === void 0 || object === null) return;\n\tconst iter = recordEntriesDepthFirst(object, {\n\t\tseen: /* @__PURE__ */ new WeakSet(),\n\t\twithPrototype: false,\n\t\tonlyLeaves: false,\n\t\tfilter: `none`,\n\t\tname: ``,\n\t\t...options\n\t});\n\tconst rootName = options.rootName ? options.rootName + `.` : ``;\n\tfor (const c of iter) {\n\t\tif (c.nodeValue === void 0 && onlyLeaves) continue;\n\t\tlet path = rootName + c.name;\n\t\tif (c.ancestors.length > 0) path = c.ancestors.join(`.`) + `.` + path;\n\t\tyield path;\n\t}\n}\n/**\n* Returns a representation of the object as a set of paths and data.\n* ```js\n* const o = { name: `hello`, size: 20, colour: { r:200, g:100, b:40 } }\n* const pd = [...getPathsAndData(o)];\n* // Yields:\n* // [ \n* // { path: `name`, value: `hello` },\n* // { path: `size`, value: `20` },\n* // { path: `colour.r`, value: `200` },\n* // { path: `colour.g`, value: `100` },\n* // { path: `colour.b`, value: `40` }\n* //]\n* ```\n* @param o Object to get paths and data for\n* @param maxDepth Set maximum recursion depth. By default unlimited.\n* @param prefix Manually set a path prefix if it's necessary\n* @returns \n*/\nfunction* getPathsAndData(o, onlyLeaves = false, maxDepth = Number.MAX_SAFE_INTEGER, prefix = ``) {\n\tif (o === null) return;\n\tif (o === void 0) return;\n\tyield* getPathsAndDataImpl(o, prefix, onlyLeaves, maxDepth);\n}\nfunction* getPathsAndDataImpl(o, prefix, onlyLeaves = false, maxDepth) {\n\tif (maxDepth <= 0) return;\n\tif (typeof o !== `object`) return;\n\tfor (const entries of Object.entries(o)) {\n\t\tconst sub = (prefix.length > 0 ? prefix + `.` : ``) + entries[0];\n\t\tconst value = entries[1];\n\t\tif (onlyLeaves && typeof value !== `object` || !onlyLeaves) yield {\n\t\t\tpath: sub,\n\t\t\tvalue\n\t\t};\n\t\tyield* getPathsAndDataImpl(value, sub, onlyLeaves, maxDepth - 1);\n\t}\n}\n//#endregion\n//#region src/trackers/track-unique.ts\n/**\n* Tracks unique values. Returns _true_ if value is unique.\n* Alternatively: {@link uniqueInstances}\n* \n* ```js\n* const t = unique();\n* t(`hello`); // true\n* t(`hello`); // false\n* ```\n* \n* Uses JSON.stringify to compare anything which is not a string.\n* \n* Provide a custom function to convert to string to track uniqueness\n* for more complicated objects.\n* \n* ```js\n* const t = unique(p => p.name);\n* t({ name:`John`, level:2 }); // true\n* \n* // Since we're judging uniques by name only\n* t({ name:`John`, level:3 }); // false\n* ```\n* \n* Return function throws an error if `value` is null or undefined.\n* @returns \n*/\nconst unique = (toString = toStringDefault) => {\n\tconst set = /* @__PURE__ */ new Set();\n\treturn (value) => {\n\t\tif (value === null) throw new TypeError(`Param 'value' cannot be null`);\n\t\tif (value === void 0) throw new TypeError(`Param 'value' cannot be undefined`);\n\t\tconst asString = typeof value === `string` ? value : toString(value);\n\t\tif (set.has(asString)) return false;\n\t\tset.add(asString);\n\t\treturn true;\n\t};\n};\n/**\n* Tracks unique object instances. Returns _true_ if value is unique.\n* Alternatively: {@link unique} to track by value.\n*/\nconst uniqueInstances = () => {\n\tconst set = /* @__PURE__ */ new Set();\n\treturn (value) => {\n\t\tif (value === null) throw new TypeError(`Param 'value' cannot be null`);\n\t\tif (value === void 0) throw new TypeError(`Param 'value' cannot be undefined`);\n\t\tif (set.has(value)) return false;\n\t\tset.add(value);\n\t\treturn true;\n\t};\n};\n//#endregion\n//#region src/trackers.ts\nvar trackers_exports = /* @__PURE__ */ __exportAll({\n\tunique: () => unique,\n\tuniqueInstances: () => uniqueInstances\n});\n//#endregion\n//#region src/continuously.ts\n/**\n* Returns a {@link Continuously} that continually executes `callback` at `interval` rate.\n* \n* By default, first the sleep period happens and then the callback happens.\n*\n* Call `start` to begin/reset loop. The looping stops when `cancel` is called, or when `callback` returns _false_.\n*\n* @example\n* Animation loop\n* ```js\n* const draw = () => {\n* // Draw on canvas\n* }\n*\n* // Run draw() synchronised with monitor refresh rate via `window.requestAnimationFrame`\n* continuously(draw).start();\n* ```\n*\n* @example\n* With delay\n* ```js\n* const fn = () => {\n* // Runs after one minute\n* }\n* const c = continuously(fn, { mins: 1 } );\n* c.start(); // Runs `fn` every minute\n* ```\n*\n* @example\n* Control a 'continuously'\n* ```js\n* c.cancel(); // Stop the loop, cancelling any up-coming calls to `fn`\n* c.elapsedMs; // How many milliseconds have elapsed since start\n* c.ticks; // How many iterations of loop since start\n* c.interval; // Get/set speed of loop. Change kicks-in at next loop.\n* // Use .start() to reset to new interval immediately\n* ```\n*\n* Asynchronous callback functions are supported too:\n* ```js\n* continuously(async () => { ..});\n* ```\n*\n* The `callback` function can receive a few arguments:\n* \n* ```js\n* continuously( (ticks, elapsedMs) => {\n* // ticks: how many times loop has run\n* // elapsedMs: how long since last loop\n* }).start();\n* ```\n*\n* If the callback explicitly returns _false_, the loop will be cancelled.\n* \n* ```js\n* continuously(ticks => {\n* // Stop after 100 iterations\n* if (ticks > 100) return false;\n* }).start();\n* ```\n*\n* You can intercept the logic for calls to `start()` with `onStartCalled`. It can determine\n* whether the `start()` proceeds, if the loop is cancelled, or the whole thing disposed,\n* so it can't run any longer.\n* \n* ```js\n* continuously(callback, intervalMs, {\n* onStartCalled:(ticks, elapsedMs) => {\n* // Cancel the loop after 1000ms has elapsed\n* if (elapsedMs > 1000) return `cancel`;\n* }\n* }).start();\n* ```\n*\n* To run `callback` *before* the sleep happens, set `fireBeforeWait`:\n* ```js\n* continuously(callback, intervalMs, { fireBeforeWait: true });\n* ```\n* @param callback - Function to run. If it returns _false_, loop exits.\n* @param options - {@link ContinuouslyOpts ContinuouslyOpts}\n* @param interval - Speed of loop (default: 0)\n* @returns Instance to control looping.\n* @see Flow.timeout if you want to trigger something once.\n*/\nconst continuously = (callback, interval = 0, options = {}) => {\n\tlet intervalMs = intervalToMs(interval, 0);\n\tresultThrow(integerTest(intervalMs, `positive`, `interval`));\n\tconst fireBeforeWait = options.fireBeforeWait ?? false;\n\tconst onStartCalled = options.onStartCalled;\n\tconst signal = options.signal;\n\tlet disposed = false;\n\tlet runState = `idle`;\n\tlet startCount = 0;\n\tlet startCountTotal = 0;\n\tlet startedAt = performance.now();\n\tlet intervalUsed = interval ?? 0;\n\tlet cancelled = false;\n\tlet currentTimer;\n\tconst deschedule = () => {\n\t\tif (currentTimer === void 0) return;\n\t\tglobalThis.clearTimeout(currentTimer);\n\t\tcurrentTimer = void 0;\n\t\tstartCount = 0;\n\t\tstartedAt = NaN;\n\t};\n\tconst schedule = (scheduledCallback) => {\n\t\tif (intervalMs === 0) if (typeof requestAnimationFrame === `undefined`) currentTimer = globalThis.setTimeout(scheduledCallback, 0);\n\t\telse {\n\t\t\tcurrentTimer = void 0;\n\t\t\trequestAnimationFrame(scheduledCallback);\n\t\t}\n\t\telse currentTimer = globalThis.setTimeout(scheduledCallback, intervalMs);\n\t};\n\tconst cancel = () => {\n\t\tif (cancelled) return;\n\t\tcancelled = true;\n\t\tif (runState === `idle`) return;\n\t\trunState = `idle`;\n\t\tdeschedule();\n\t};\n\tconst loop = async () => {\n\t\tif (signal?.aborted) runState = `idle`;\n\t\tif (runState === `idle`) return;\n\t\trunState = `running`;\n\t\tstartCount++;\n\t\tstartCountTotal++;\n\t\tconst valueOrPromise = callback(startCount, performance.now() - startedAt);\n\t\tconst value = typeof valueOrPromise === `object` ? await valueOrPromise : valueOrPromise;\n\t\tif (cancelled) return;\n\t\trunState = `scheduled`;\n\t\tif (value !== void 0 && !value) {\n\t\t\tcancel();\n\t\t\treturn;\n\t\t}\n\t\tif (cancelled) return;\n\t\tschedule(loop);\n\t};\n\tconst start = () => {\n\t\tif (disposed) throw new Error(`Disposed`);\n\t\tcancelled = false;\n\t\tif (onStartCalled !== void 0) switch (onStartCalled(startCount, performance.now() - startedAt)) {\n\t\t\tcase `cancel`:\n\t\t\t\tcancel();\n\t\t\t\treturn;\n\t\t\tcase `reset`:\n\t\t\t\treset();\n\t\t\t\treturn;\n\t\t\tcase `dispose`:\n\t\t\t\tdisposed = true;\n\t\t\t\tcancel();\n\t\t\t\treturn;\n\t\t}\n\t\tif (runState === `idle`) {\n\t\t\tstartCount = 0;\n\t\t\tstartedAt = performance.now();\n\t\t\trunState = `scheduled`;\n\t\t\tif (fireBeforeWait) loop();\n\t\t\telse schedule(loop);\n\t\t}\n\t};\n\tconst reset = () => {\n\t\tif (disposed) throw new Error(`Disposed`);\n\t\tcancelled = false;\n\t\tstartCount = 0;\n\t\tstartedAt = NaN;\n\t\tif (runState !== `idle`) cancel();\n\t\tstart();\n\t};\n\treturn {\n\t\tstart,\n\t\treset,\n\t\tcancel,\n\t\tget interval() {\n\t\t\treturn intervalUsed;\n\t\t},\n\t\tget runState() {\n\t\t\treturn runState;\n\t\t},\n\t\tget startCountTotal() {\n\t\t\treturn startCountTotal;\n\t\t},\n\t\tget startCount() {\n\t\t\treturn startCount;\n\t\t},\n\t\tset interval(interval) {\n\t\t\tconst ms = intervalToMs(interval, 0);\n\t\t\tresultThrow(integerTest(ms, `positive`, `interval`));\n\t\t\tintervalMs = ms;\n\t\t\tintervalUsed = interval;\n\t\t},\n\t\tget isDisposed() {\n\t\t\treturn disposed;\n\t\t},\n\t\tget elapsedMs() {\n\t\t\treturn performance.now() - startedAt;\n\t\t}\n\t};\n};\n//#endregion\n//#region src/correlate.ts\nconst orderScore = (a, b) => {\n\tif (a.score > b.score) return -1;\n\telse if (a.score < b.score) return 1;\n\treturn 0;\n};\n/**\n* Attempts to align prior data with new data, based on a provided similarity function.\n*\n* See also `alignById` for a version which encloses parameters.\n*\n* ```js\n* // Compare data based on x,y distance\n* const fn = (a, b) => {\n* return 1-Points.distance(a, b);\n* }\n* const lastData = [\n* { id:`1`, x:100, y:200 }\n* ...\n* ]\n* const newData = [\n* { id:`2`, x:101, y:200 }\n* ]\n* const aligned = Correlate.align(fn, lastdata, newData, opts);\n*\n* // Result:\n* [\n* { id:`1`, x:101, y:200 }\n* ]\n* ```\n* @param similarityFunction Function to compute similarity\n* @param lastData Old data\n* @param newData New data\n* @param options Options\n* @returns\n*/\nconst align = (similarityFunction, lastData, newData, options = {}) => {\n\tconst matchThreshold = options.matchThreshold ?? 0;\n\tconst debug = options.debug ?? false;\n\tconst results = /* @__PURE__ */ new Map();\n\tconst newThings = [];\n\tconst lastMap = /* @__PURE__ */ new Map();\n\tlastData?.forEach((d, index) => {\n\t\tif (typeof d === `undefined`) throw new Error(`'lastData' contains undefined (index: ${index.toString()})`);\n\t\tlastMap.set(d.id, d);\n\t});\n\tfor (const newD of newData) {\n\t\tif (!lastData || lastData.length === 0) {\n\t\t\tif (debug) console.debug(`Correlate.align() new id: ${newD.id}`);\n\t\t\tnewThings.push(newD);\n\t\t\tcontinue;\n\t\t}\n\t\tconst scoredLastValues = Array.from(lastMap.values()).map((last) => ({\n\t\t\tid: last.id,\n\t\t\tscore: last === null ? -1 : similarityFunction(last, newD),\n\t\t\tlast\n\t\t}));\n\t\tif (scoredLastValues.length === 0) {\n\t\t\tif (debug) console.debug(`Correlate.align() no valid last values id: ${newD.id}`);\n\t\t\tnewThings.push(newD);\n\t\t\tcontinue;\n\t\t}\n\t\tscoredLastValues.sort(orderScore);\n\t\tconst top = scoredLastValues[0];\n\t\tif (top.score < matchThreshold) {\n\t\t\tif (debug) console.debug(`Correlate.align() new item does not reach threshold. Top score: ${top.score.toString()} id: ${newD.id}`);\n\t\t\tnewThings.push(newD);\n\t\t\tcontinue;\n\t\t}\n\t\tif (debug && top.id !== newD.id) console.log(`Correlate.align() Remapped ${newD.id} -> ${top.id} (score: ${top.score.toString()})`);\n\t\tresults.set(top.id, {\n\t\t\t...newD,\n\t\t\tid: top.id\n\t\t});\n\t\tlastMap.delete(top.id);\n\t}\n\tnewThings.forEach((t) => results.set(t.id, t));\n\treturn Array.from(results.values());\n};\n/**\n* Returns a function that attempts to align a series of data by its id.\n* See also {@link align} for a version with no internal storage.\n*\n* ```js\n* // Compare data based on x,y distance\n* const fn = (a, b) => {\n* return 1-Points.distance(a, b);\n* }\n* const aligner = Correlate.alignById(fn, opts);\n*\n* const lastData = [\n* { id:`1`, x:100, y:200 }\n* ...\n* ]\n* const aligned = aligner(lastData);\n*\n* ```\n* @param fn Function to compute similarity\n* @param options Options\n* @returns\n*/\nconst alignById = (fn, options = {}) => {\n\tlet lastData = [];\n\tconst compute = (newData) => {\n\t\tlastData = align(fn, lastData, newData, options);\n\t\treturn [...lastData];\n\t};\n\treturn compute;\n};\n//#endregion\n//#region src/default-keyer.ts\n/**\n* If values are strings, uses that as the key.\n* Otherwise uses `JSON.stringify`.\n* @param a\n* @returns\n*/\nconst defaultKeyer = (a) => {\n\treturn typeof a === `string` ? a : JSON.stringify(a);\n};\n//#endregion\n//#region src/filters.ts\n/**\n* Returns `v` if `predicate` returns _true_,\n* alternatively returning `skipValue`.\n* \n* ```js\n* // Return true if value is less than 10\n* const p = v => v < 10;\n* \n* filterValue(5, p, 0); // 5\n* filterValue(20, p, 0); // 0\n* ```\n* @param v Value to test\n* @param predicate Predicate\n* @param skipValue Value to return if predicate returns false\n* @returns Input value if predicate is _true_, or `skipValue` if not.\n*/\nconst filterValue = (v, predicate, skipValue) => {\n\tif (predicate(v)) return v;\n\treturn skipValue;\n};\n//#endregion\n//#region src/is-equal-test.ts\n/**\n* Wraps the `eq` function, tracing the input data result\n* ```js\n* // Init trace\n* const traceEq = isEqualTrace(isEqualValueDefault); \n* // Use it in some function that takes IsEqual<T>\n* compare(a, b, eq);\n* ```\n* @param eq \n* @returns \n*/\nconst isEqualTrace = (eq) => {\n\treturn (a, b) => {\n\t\tconst result = eq(a, b);\n\t\tconsole.log(`isEqualTrace eq: ${result} a: ${toStringAbbreviate(a)} b: ${toStringAbbreviate(b)}`);\n\t\treturn result;\n\t};\n};\n//#endregion\n//#region src/is-integer.ts\n/**\n* Returns _true_ if `value` is an integer. Parses string input, but\n* all other data types return _false_.\n* \n* ```js\n* isInteger(1); // true\n* isInteger(1.1); // false\n* isInteger(`1`); // true\n* isInteger(`1.1`); // false\n* isInteger(true); // false\n* isInteger(false); // false\n* ```\n* \n* Returns _false_ for _undefined_, NaN, booleans and infinite numbers.\n* @param value \n* @returns \n*/\nconst isInteger = (value) => {\n\tif (value === void 0) return false;\n\tif (typeof value === `string`) {\n\t\tconst v = Number.parseInt(value);\n\t\tif (Number.isNaN(v)) return false;\n\t\tif (v.toString() === value.toString()) return true;\n\t\treturn false;\n\t}\n\tif (typeof value === `number`) {\n\t\tif (Number.isNaN(value)) return false;\n\t\tif (!Number.isFinite(value)) return false;\n\t\tif (Math.round(value) === value) return true;\n\t\treturn false;\n\t}\n\treturn false;\n};\n//#endregion\n//#region src/iterable-compare-values-shallow.ts\n/**\n* Compares the values of two iterables, returning a list\n* of items they have in common and those unique in `a` or `b`.\n* Ignores ordering of values, and is NOT recursive.\n*\n* ```js\n* const a = ['apples', 'oranges', 'pears' ]\n* const b = ['pears', 'kiwis', 'bananas' ];\n*\n* const r = compareValuesShallow(a, b);\n* r.shared; // [ 'pears' ]\n* r.a; // [ 'apples', 'oranges' ]\n* r.b; // [ 'kiwis', 'bananas' ]\n* ```\n* \n* By default uses === semantics for comparison.\n* @param a\n* @param b\n* @param eq\n* @returns\n*/\nconst compareIterableValuesShallow = (a, b, eq = isEqualDefault) => {\n\tconst shared = [];\n\tconst aUnique = [];\n\tconst bUnique = [];\n\tfor (const elementOfA of a) {\n\t\tlet seenInB = false;\n\t\tfor (const elementOfB of b) if (eq(elementOfA, elementOfB)) {\n\t\t\tseenInB = true;\n\t\t\tbreak;\n\t\t}\n\t\tif (seenInB) shared.push(elementOfA);\n\t\telse aUnique.push(elementOfA);\n\t}\n\tfor (const elementOfB of b) {\n\t\tlet seenInA = false;\n\t\tfor (const elementOfA of a) if (eq(elementOfB, elementOfA)) seenInA = true;\n\t\tif (!seenInA) bUnique.push(elementOfB);\n\t}\n\treturn {\n\t\tshared,\n\t\tisSame: aUnique.length === 0 && bUnique.length === 0,\n\t\ta: aUnique,\n\t\tb: bUnique\n\t};\n};\n//#endregion\n//#region src/key-value.ts\nconst sorterByValueIndex = (index, reverse = false) => {\n\treturn (values) => {\n\t\tconst s = values.toSorted((a, b) => {\n\t\t\treturn defaultComparer(a[index], b[index]);\n\t\t});\n\t\tif (reverse) return s.reverse();\n\t\treturn s;\n\t};\n};\nconst keyValueSorter = (sortStyle) => {\n\tswitch (sortStyle) {\n\t\tcase `value`: return sorterByValueIndex(1, false);\n\t\tcase `value-reverse`: return sorterByValueIndex(1, true);\n\t\tcase `key`: return sorterByValueIndex(0, false);\n\t\tcase `key-reverse`: return sorterByValueIndex(0, true);\n\t\tdefault: throw new Error(`Unknown sorting value '${sortStyle}'. Expecting: value, value-reverse, key or key-reverse`);\n\t}\n};\n//#endregion\n//#region src/util/round.ts\n/**\n* Rounds a number.\n*\n* If one parameter is given, it's the decimal places,\n* and a rounding function is returned:\n* ```js\n* const r = round(2);\n* r(10.12355); // 10.12\n* ```\n*\n* If two parameters are given, the first is decimal places,\n* the second the value to round.\n* ```js\n* round(2, 10.12355); // 10.12\n* ```\n* @param decimalPlaces\n* @returns\n*/\nfunction round(a, b, roundUp) {\n\tresultThrow(integerTest(a, `positive`, `decimalPlaces`));\n\tconst up = typeof b === `boolean` ? b : roundUp ?? false;\n\tlet rounder;\n\tif (a === 0) rounder = Math.round;\n\telse {\n\t\tconst p = Math.pow(10, a);\n\t\tif (up) rounder = (v) => Math.ceil(v * p) / p;\n\t\telse rounder = (v) => Math.floor(v * p) / p;\n\t}\n\tif (typeof b === `number`) return rounder(b);\n\treturn rounder;\n}\n//#endregion\n//#region src/interval-type.ts\n/**\n* Returns _true_ if `date` is an instance of Date\n* @param date\n* @returns \n*/\nfunction isDateObject(date) {\n\tif (typeof date !== `object`) return false;\n\tif (date instanceof Date) return true;\n\treturn false;\n}\n/**\n* Return the millisecond value of an Interval.\n* \n* ```js\n* intervalToMs(100); // 100\n* intervalToMs({ millis: 100 }); // 100\n* ```\n*\n* Use `defaultNumber` to return a default in the case of\n* _undefined_ or invalid input.\n*\n* ```js\n* intervalToMs(undefined); // throws error\n* intervalToMs(undefined, 100); // 100\n* ```\n*\n* If no default is provided, an exception is thrown.\n* @param interval Interval\n* @param defaultNumber Default value if `interval` is _undefined_ or invalid\n* @returns Milliseconds\n*/\nfunction intervalToMs(interval, defaultNumber) {\n\tif (isInterval(interval)) {\n\t\tif (typeof interval === `number`) return interval;\n\t\tlet ms = interval.millis ?? 0;\n\t\tms += (interval.hours ?? 0) * 60 * 60 * 1e3;\n\t\tms += (interval.mins ?? 0) * 60 * 1e3;\n\t\tms += (interval.secs ?? 0) * 1e3;\n\t\treturn ms;\n\t} else {\n\t\tif (typeof defaultNumber !== `undefined`) return defaultNumber;\n\t\tthrow new Error(`Not a valid interval: ${JSON.stringify(interval)}`);\n\t}\n}\n/**\n* Returns _true_ if `interval` matches the {@link Interval} type.\n* @param interval \n* @returns _True_ if `interval` is an {@link Interval}.\n*/\nfunction isInterval(interval) {\n\tif (typeof interval === `undefined`) return false;\n\tif (interval === null) return false;\n\tif (typeof interval === `number`) {\n\t\tif (Number.isNaN(interval)) return false;\n\t\tif (!Number.isFinite(interval)) return false;\n\t\treturn true;\n\t}\n\tif (typeof interval !== `object`) return false;\n\tconst hasMillis = `millis` in interval;\n\tconst hasSecs = `secs` in interval;\n\tconst hasMins = `mins` in interval;\n\tconst hasHours = `hours` in interval;\n\tif (hasMillis && !numberTest(interval.millis).success) return false;\n\tif (hasSecs && !numberTest(interval.secs).success) return false;\n\tif (hasMins && !numberTest(interval.mins).success) return false;\n\tif (hasHours && !numberTest(interval.hours).success) return false;\n\tif (hasMillis || hasSecs || hasHours || hasMins) return true;\n\treturn false;\n}\n/**\n* Returns a human-readable representation\n* of some elapsed milliseconds\n* \n* @example\n* ```js\n* elapsedToHumanString(10); // `10ms`\n* elapsedToHumanString(2000); // `2s`\n* elapsedToHumanString(65*1000); // `1mins`\n* ```\n* @param millisOrFunction Milliseconds as a number, {@link Interval} or function that resolve to a number\n* @param rounding Rounding (default: 2)\n* @returns \n*/\nconst elapsedToHumanString = (millisOrFunction, rounding = 2) => {\n\tlet interval = 0;\n\tif (typeof millisOrFunction === `function`) return elapsedToHumanString(millisOrFunction());\n\telse if (typeof millisOrFunction === `number`) interval = millisOrFunction;\n\telse if (typeof millisOrFunction === `object`) interval = intervalToMs(millisOrFunction);\n\tlet ms = intervalToMs(interval);\n\tif (typeof ms === `undefined`) return `(undefined)`;\n\tif (ms < 1e3) return `${round(rounding, ms)}ms`;\n\tms /= 1e3;\n\tif (ms < 120) return `${ms.toFixed(1)}secs`;\n\tms /= 60;\n\tif (ms < 60) return `${ms.toFixed(2)}mins`;\n\tms /= 60;\n\treturn `${ms.toFixed(2)}hrs`;\n};\n//#endregion\n//#region src/platform.ts\n/**\n* Returns _true_ if it seems like the code is running on iOS (iPad/iPhone)\n* @returns \n*/\nconst runningiOS = () => [\n\t`iPad Simulator`,\n\t`iPhone Simulator`,\n\t`iPod Simulator`,\n\t`iPad`,\n\t`iPhone`,\n\t`iPod`\n].includes(navigator.platform) || navigator.userAgent.includes(`Mac`) && `ontouchend` in document;\n//#endregion\n//#region src/promise-from-event.ts\nconst promiseFromEvent = (target, name) => {\n\treturn new Promise((resolve) => {\n\t\tconst handler = (...args) => {\n\t\t\ttarget.removeEventListener(name, handler);\n\t\t\tif (Array.isArray(args) && args.length === 1) resolve(args[0]);\n\t\t\telse resolve(args);\n\t\t};\n\t\ttarget.addEventListener(name, handler);\n\t});\n};\n//#endregion\n//#region src/reactive-core.ts\n/**\n* Returns _true_ if `rx` is a Reactive\n* @param rx \n* @returns \n*/\nconst isReactive = (rx) => {\n\tif (typeof rx !== `object`) return false;\n\tif (rx === null) return false;\n\treturn `on` in rx && `onValue` in rx;\n};\n/**\n* Returns _true_ if `rx` has a last value\n* \n* Judged seeing if `.last()` exists on `rx`.\n* @param rx Reactive\n* @returns \n*/\nconst hasLast = (rx) => {\n\tif (!isReactive(rx)) return false;\n\tif (`last` in rx) {\n\t\tif (rx.last() !== void 0) return true;\n\t}\n\treturn false;\n};\n//#endregion\n//#region src/resolve-core.ts\n/**\n* Resolves the input to a concrete value. \n* \n* The input can be:\n* * primitive value (string, boolean, number, object)\n* * a/sync function\n* * a/sync generator/iterator\n* * ReactiveNonInitial\n* \n* Examples:\n* ```js\n* await resolve(10); // 10\n* await resolve(() => 10); // 10\n* await resole(async () => {\n* sleep(100);\n* return 10;\n* }); // 10\n* ```\n* \n* If the input is a function, any arguments given to `resolve` are passed to it as a spread.\n* \n* Resolve is not recursive. If the input is an object, it will be returned, even\n* though its properties may be resolvable. Use {@link resolveFields} if you want to handle this case.\n* @param resolvable Input to resolve\n* @param args Additional arguments to pass to function-resolvables.\n* @returns \n*/\nasync function resolve(resolvable, ...args) {\n\tif (typeof resolvable === `object`) if (`next` in resolvable) {\n\t\tconst tag = resolvable[Symbol.toStringTag];\n\t\tif (tag === `Generator` || tag == `Array Iterator`) {\n\t\t\tconst v = resolvable.next();\n\t\t\tif (`done` in v && `value` in v) return v.value;\n\t\t\treturn v;\n\t\t} else if (tag === `AsyncGenerator`) {\n\t\t\tconst v = await resolvable.next();\n\t\t\tif (`done` in v && `value` in v) return v.value;\n\t\t\treturn v;\n\t\t} else throw new Error(`Object has 'next' prop, but does not have 'AsyncGenerator', 'Generator' or 'Array Iterator' string tag symbol. Got: '${tag}'`);\n\t} else if (isReactive(resolvable)) {\n\t\tif (hasLast(resolvable)) return resolvable.last();\n\t\tthrow new Error(`Reactive does not have last value`);\n\t} else return resolvable;\n\telse if (typeof resolvable === `function`) return await resolvable(...args);\n\telse return resolvable;\n}\n/**\n* For the given input, attempts to 'resolve' it. See {@link resolve} for details and asynchronous version.\n* @param resolvable \n* @param args \n* @returns \n*/\nfunction resolveSync(resolvable, ...args) {\n\tif (typeof resolvable === `object`) if (`next` in resolvable) {\n\t\tconst tag = resolvable[Symbol.toStringTag];\n\t\tif (tag === `Generator` || tag == `Array Iterator`) {\n\t\t\tconst v = resolvable.next();\n\t\t\tif (`done` in v && `value` in v) return v.value;\n\t\t\treturn v;\n\t\t} else if (tag === `AsyncGenerator`) throw new Error(`resolveSync cannot work with an async generator`);\n\t\telse throw new Error(`Object has 'next' prop, but does not have 'Generator' or 'Array Iterator' string tag symbol. Got: '${tag}'`);\n\t} else if (isReactive(resolvable)) {\n\t\tif (hasLast(resolvable)) return resolvable.last();\n\t\tthrow new Error(`Reactive does not have last value`);\n\t} else return resolvable;\n\telse if (typeof resolvable === `function`) return resolvable(...args);\n\telse return resolvable;\n}\n/**\n* Resolves a value as per {@link resolve}, however f an error is thrown \n* or the resolution results in _undefined_ \n* or NaN, the fallback value is returned instead.\n* \n* `null` is an allowed return value.\n* \n* ```js\n* // Function returns undefined 50% of the time or 0\n* const fn = () => {\n* if (Math.random() >= 0.5) return; // undefined\n* return 0;\n* }\n* const r = resolveWithFallback(fn, 1);\n* const value = r(); // Always 0 or 1\n* ```\n* \n* See also {@link resolveWithFallbackSync}\n* @param p Thing to resolve\n* @param options Fallback value if an error happens, undefined or NaN\n* @param args \n* @returns \n*/\nasync function resolveWithFallback(p, options, ...args) {\n\tlet errored = false;\n\tlet fallbackValue = options.value;\n\tconst overrideWithLast = options.overrideWithLast ?? false;\n\tif (fallbackValue === void 0) throw new Error(`Param 'options.value' is undefined`);\n\ttry {\n\t\tconst r = await resolve(p, ...args);\n\t\tif (typeof r === `undefined`) return fallbackValue;\n\t\tif (typeof r === `number` && Number.isNaN(r)) return fallbackValue;\n\t\tif (overrideWithLast) fallbackValue = r;\n\t\treturn r;\n\t} catch (error) {\n\t\tif (!errored) {\n\t\t\terrored = true;\n\t\t\tconsole.warn(`resolveWithFallback swallowed an error. Additional errors not reported.`, getErrorMessage(error));\n\t\t}\n\t\treturn fallbackValue;\n\t}\n}\n/**\n* Resolves a 'resolvable', using a fallback value if it results to _undefined_ or _NaN_. _null_ is allowed.\n* \n* See also {@link resolveWithFallback} for the asynchronous version.\n* \n* Options:\n* * value: Fallback value\n* * overrideWithLast: If true, uses the previously-valid value as the replacement fallback (default: false)\n* @param p \n* @param options \n* @param args \n* @returns \n*/\nfunction resolveWithFallbackSync(p, options, ...args) {\n\tlet errored = false;\n\tlet fallbackValue = options.value;\n\tconst overrideWithLast = options.overrideWithLast ?? false;\n\tif (fallbackValue === void 0) throw new Error(`Param 'options.value' is undefined`);\n\ttry {\n\t\tconst r = resolveSync(p, ...args);\n\t\tif (typeof r === `undefined`) return fallbackValue;\n\t\tif (typeof r === `number` && Number.isNaN(r)) return fallbackValue;\n\t\tif (overrideWithLast) fallbackValue = r;\n\t\treturn r;\n\t} catch (error) {\n\t\tif (!errored) {\n\t\t\terrored = true;\n\t\t\tconsole.warn(`resolveWithFallbackSync swallowed an error. Additional errors not reported.`, getErrorMessage(error));\n\t\t}\n\t\treturn fallbackValue;\n\t}\n}\n//#endregion\n//#region src/util/zip.ts\nconst zip = (...arrays) => {\n\tif (arrays.some((a) => !Array.isArray(a))) throw new Error(`All parameters must be an array`);\n\tconst lengths = arrays.map((a) => a.length);\n\tconst returnValue = [];\n\tconst length = lengths[0];\n\tfor (let index = 0; index < length; index++) returnValue.push(arrays.map((a) => a[index]));\n\treturn returnValue;\n};\n//#endregion\n//#region src/resolve-fields.ts\n/**\n* Returns a copy of `object`, with the same properties. For each property\n* that has a basic value (string, number, boolean, object), the value is set\n* for the return object. If the property is a function or generator, its value\n* is used instead. Async functions and generators are also usable.\n*\n* Use {@link resolveFieldsSync} for a synchronous version.\n*\n* Not recursive.\n*\n* In the below example, the function for the property `random` is invoked.\n* ```js\n* const state = {\n* length: 10,\n* random: () => Math.random();\n* }\n* const x = resolveFields(state);\n* // { length: 10, random: 0.1235 }\n* ```\n*\n* It also works with generators. Probably best with those that are infinite.\n*\n* ```js\n* import { count } from './numbers.js';\n*\n* const state = {\n* length: 10,\n* index: count(2) // Generator that yields: 0, 1 and then ends\n* }\n* resolveFields(state); // { length: 10, index: 0 }\n* resolveFields(state); // { length: 10, index: 1 }\n* // Generator finishes after counting twice:\n* resolveFields(state); // { length: 10, index: undefined }\n* ```\n* @param object\n* @returns\n*/\nasync function resolveFields(object) {\n\tconst resolvers = [];\n\tconst keys = [];\n\tfor (const entry of Object.entries(object)) {\n\t\tconst resolvable = entry[1];\n\t\tresolvers.push(resolve(resolvable));\n\t\tkeys.push(entry[0]);\n\t}\n\tconst entries = zip(keys, await Promise.all(resolvers));\n\treturn Object.fromEntries(entries);\n}\n/**\n* 'Resolves' all the fields of `object` in a synchronous manner.\n* Uses {@link resolveSync} under-the-hood\n* @param object\n* @returns\n*/\nfunction resolveFieldsSync(object) {\n\tconst entries = [];\n\tfor (const entry of Object.entries(object)) {\n\t\tconst resolvable = entry[1];\n\t\tconst value = resolveSync(resolvable);\n\t\tentries.push([entry[0], value]);\n\t}\n\treturn Object.fromEntries(entries);\n}\n/**\n* Returns a function that resolves `object`.\n*\n* Use {@link resolveFields} to resolve an object directly.\n* @param object\n* @returns\n*/\n//#endregion\n//#region src/sleep.ts\nif (typeof window === `undefined` || !(`requestAnimationFrame` in window)) {\n\tif (typeof window === `undefined`) globalThis.requestAnimationFrame = (callback) => {\n\t\tsetTimeout(callback, 1);\n\t};\n}\n/**\n* Returns after timeout period.\n*\n* @example In an async function\n* ```js\n* console.log(`Hello`);\n* await sleep(1000);\n* console.log(`There`); // Prints one second after\n* ```\n*\n* @example As a promise\n* ```js\n* console.log(`Hello`);\n* sleep({ millis: 1000 })\n* .then(() => console.log(`There`)); // Prints one second after\n* ```\n*\n* If a timeout of 0 is given, `requestAnimationFrame` is used instead of `setTimeout`.\n*\n* `Flow.delay()` and {@link sleep} are similar. `Flow.delay()` takes a parameter of what code to execute after the timeout, while `sleep()` just resolves after the timeout.\n*\n* A value can be provided, which is returned on awaking:\n* ```js\n* const v = await sleep({ seconds: 1, value: `hello`);\n* // v = `hello`\n* ```\n*\n* Provide an AbortSignal to cancel the sleep and throwing an exception\n* so code after the sleep doesn't happen.\n*\n* ```js\n* const ac = new AbortController();\n* setTimeout(() => { ac.abort(); }, 1000); // Abort after 1s\n*\n* // Sleep for 1min\n* await sleep({ minutes: 1, signal: ac.signal });\n* console.log(`Awake`); // This line doesn't get called because an exception is thrown when aborting\n* ```\n* @param optsOrMillis Milliseconds to sleep, or options\n* @return\n*/\nconst sleep = (optsOrMillis) => {\n\tconst timeoutMs = intervalToMs(optsOrMillis, 1);\n\tconst signal = optsOrMillis.signal;\n\tconst value = optsOrMillis.value;\n\tresultThrow(numberTest(timeoutMs, `positive`, `timeoutMs`));\n\tif (timeoutMs === 0) return new Promise((resolve) => requestAnimationFrame((_) => {\n\t\tresolve(value);\n\t}));\n\telse return new Promise((resolve, reject) => {\n\t\tconst onAbortSignal = () => {\n\t\t\tclearTimeout(t);\n\t\t\tif (signal) {\n\t\t\t\tsignal.removeEventListener(`abort`, onAbortSignal);\n\t\t\t\treject(new Error(signal.reason));\n\t\t\t} else reject(/* @__PURE__ */ new Error(`Cancelled`));\n\t\t};\n\t\tif (signal) signal.addEventListener(`abort`, onAbortSignal);\n\t\tconst t = setTimeout(() => {\n\t\t\tsignal?.removeEventListener(`abort`, onAbortSignal);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treject(new Error(signal.reason));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(value);\n\t\t}, timeoutMs);\n\t});\n};\n/**\n* Delays until `predicate` returns true.\n* Can be useful for synchronising with other async activities.\n* ```js\n* // Delay until 'count' reaches 5\n* await sleepWhile(() => count >= 5, 100);\n* ```\n* @param predicate \n* @param checkInterval \n*/\nconst sleepWhile = async (predicate, checkInterval = 100) => {\n\twhile (predicate()) await sleep(checkInterval);\n};\n//#endregion\n//#region src/url-parameters.ts\n/**\n* Allows for access to URL parameters.\n* \n* If `url` is not specified, `docment.location`'s .searchParams is used.\n* \n* ```js\n* const p = parseUrlParameters();\n* \n* // eg. gets an integer param called 'size`, using NaN as a default\n* p.int(`size`);\n* \n* // As above, but will return 10 if 'size' is not specified in URL.\n* p.int(`size`, 10);\n* \n* // Returns _true_ if 'engage' parameter is present and value is 'true'\n* p.bool(`engage`);\n* ```\n* @param url \n* @returns \n*/\nconst parseUrlParameters = (url) => {\n\tconst parameters = new URL(url ?? document.location.toString()).searchParams;\n\treturn {\n\t\tparams: parameters,\n\t\tint: (name, defaultValue = NaN) => intParamOrDefault(parameters, name, defaultValue),\n\t\tfloat: (name, defaultValue = NaN) => floatParamOrDefault(parameters, name, defaultValue),\n\t\tstring: (name, defaultValue = ``) => stringParamOrDefault(parameters, name, defaultValue),\n\t\tbool: (name) => boolParamOrDefault(parameters, name)\n\t};\n};\n/**\n* Return an integer value from URL parameter or use a default value.\n* Value is considered _false_ if it's not present, or it is explicitly 'false'\n* @returns \n*/\nfunction boolParamOrDefault(parameters, name) {\n\tconst p = parameters.get(name);\n\tif (p === null) return false;\n\tif (p === `true`) return true;\n\treturn false;\n}\n/**\n* Return an integer value from URL parameter or use a default value\n* @returns \n*/\nfunction intParamOrDefault(parameters, name, defaultValue) {\n\tconst p = parameters.get(name);\n\tif (p !== null) return Number.parseInt(p);\n\treturn defaultValue;\n}\n/**\n* Return a float value from URL parameter or use a default value\n* @returns \n*/\nfunction floatParamOrDefault(parameters, name, defaultValue) {\n\tconst p = parameters.get(name);\n\tif (p !== null) return Number.parseFloat(p);\n\treturn defaultValue;\n}\n/**\n* Return a string value from URL parameter or use a default value\n* @returns \n*/\nfunction stringParamOrDefault(parameters, name, defaultValue) {\n\tconst p = parameters.get(name);\n\tif (p !== null) return p;\n\treturn defaultValue;\n}\n//#endregion\nexport { cloneFromFields as $, pathed_exports as A, isPrimitive as B, defaultKeyer as C, trackers_exports as D, continuously as E, prettyPrintEntries as F, mapObjectByObject as G, prefixProperties as H, recordChildren as I, changedProperties as J, mapObjectShallow as K, recordEntriesDepthFirst as L, zip$1 as M, enumerateNumericalValues as N, unique as O, getRecordEntryByPath as P, mapObjectKeys as Q, recordEntryPrettyPrint as R, filterValue as S, alignById as T, merge as U, isPrimitiveOrObject as V, mergeSameShape as W, compareObjectData as X, compareArrays as Y, compareObjectKeys as Z, isInterval as _, resolveFieldsSync as a, isInteger as b, resolveWithFallback as c, isReactive as d, promiseFromEvent as f, isDateObject as g, intervalToMs as h, resolveFields as i, records_exports as j, uniqueInstances as k, resolveWithFallbackSync as l, elapsedToHumanString as m, sleep as n, resolve as o, runningiOS as p, keysToNumbers as q, sleepWhile as r, resolveSync as s, parseUrlParameters as t, hasLast as u, keyValueSorter as v, align as w, isEqualTrace as x, compareIterableValuesShallow as y, traceRecordEntryByPath as z };\n","//#region src/map-of.ts\nvar MapOfSimple = class {\n\t#store = /* @__PURE__ */ new Map();\n\t/**\n\t* Gets a copy of the underlying array storing values at `key`, or an empty array if\n\t* key does not exist\n\t* @param key \n\t* @returns \n\t*/\n\tget(key) {\n\t\tconst arr = this.#store.get(key);\n\t\tif (!arr) return [];\n\t\treturn [...arr];\n\t}\n\t/**\n\t* Returns the number of values stored under `key`\n\t* @param key \n\t* @returns \n\t*/\n\tsize(key) {\n\t\tconst arr = this.#store.get(key);\n\t\tif (!arr) return 0;\n\t\treturn arr.length;\n\t}\n\t/**\n\t* Iterate over all values contained under `key`\n\t* @param key \n\t* @returns \n\t*/\n\t*iterateKey(key) {\n\t\tconst arr = this.#store.get(key);\n\t\tif (!arr) return;\n\t\tyield* arr.values();\n\t}\n\t/**\n\t* Iterate all values, regardless of key\n\t*/\n\t*iterateValues() {\n\t\tfor (const key of this.#store.keys()) yield* this.iterateKey(key);\n\t}\n\t/**\n\t* Iterate all keys\n\t*/\n\t*iterateKeys() {\n\t\tyield* this.#store.keys();\n\t}\n\taddKeyedValues(key, ...values) {\n\t\tlet arr = this.#store.get(key);\n\t\tif (!arr) {\n\t\t\tarr = [];\n\t\t\tthis.#store.set(key, arr);\n\t\t}\n\t\tarr.push(...values);\n\t}\n\tdeleteKeyValue(key, value) {\n\t\tconst arr = this.#store.get(key);\n\t\tif (!arr) return false;\n\t\tconst arrCopy = arr.filter((v) => v !== value);\n\t\tif (arrCopy.length === arr.length) return false;\n\t\tthis.#store.set(key, arrCopy);\n\t\treturn true;\n\t}\n\tclear() {\n\t\tthis.#store.clear();\n\t}\n};\n//#endregion\n//#region src/simple-event-emitter.ts\nvar SimpleEventEmitter = class {\n\t#listeners = new MapOfSimple();\n\t#disposed = false;\n\tdispose() {\n\t\tif (this.#disposed) return;\n\t\tthis.clearEventListeners();\n\t}\n\tget isDisposed() {\n\t\treturn this.#disposed;\n\t}\n\t/**\n\t* Fire event\n\t* @param type Type of event\n\t* @param args Arguments for event\n\t* @returns\n\t*/\n\tfireEvent(type, args) {\n\t\tif (this.#disposed) throw new Error(`Disposed`);\n\t\tfor (const l of this.#listeners.iterateKey(type)) l(args, this);\n\t}\n\t/**\n\t* Adds event listener.\n\t* \n\t* @throws Error if emitter is disposed\n\t* @typeParam K - Events\n\t* @param name Event name\n\t* @param listener Event handler\n\t*/\n\taddEventListener(name, listener) {\n\t\tif (this.#disposed) throw new Error(`Disposed`);\n\t\tthis.#listeners.addKeyedValues(name, listener);\n\t}\n\t/**\n\t* Remove event listener\n\t*\n\t* @param listener\n\t*/\n\tremoveEventListener(type, listener) {\n\t\tif (this.#disposed) return;\n\t\tthis.#listeners.deleteKeyValue(type, listener);\n\t}\n\t/**\n\t* Clear all event listeners\n\t* @private\n\t*/\n\tclearEventListeners() {\n\t\tif (this.#disposed) return;\n\t\tthis.#listeners.clear();\n\t}\n};\n//#endregion\nexport { SimpleEventEmitter };\n","import { s as isPoint, t as guard } from \"./guard-hlhkAOMZ.js\";\nimport { t as fromPoints } from \"./from-points-hWl1SWEr.js\";\nimport { i as toString, o as distance } from \"./to-oKNQeMO-.js\";\nimport { i as guardPositioned, l as isRectPositioned, n as guard$1, s as isPositioned, t as getRectPositioned } from \"./guard-C2opUnGy.js\";\nimport { n as circleRect, u as isCirclePositioned } from \"./intersects-BOuj4lnQ.js\";\n//#region src/rect/center.ts\n/**\n* Returns the center of a rectangle as a {@link Point}.\n* If the rectangle lacks a position and `origin` parameter is not provided, 0,0 is used instead.\n*\n* ```js\n* const p = Rects.center({x:10, y:20, width:100, height:50});\n* const p2 = Rects.center({width: 100, height: 50}); // Assumes 0,0 for rect x,y\n* ```\n* @param rect Rectangle\n* @param origin Optional origin. Overrides `rect` position if available. If no position is available 0,0 is used by default.\n* @returns\n*/\nconst center = (rect, origin) => {\n\tguard$1(rect);\n\tif (origin === void 0 && isPoint(rect)) origin = rect;\n\telse if (origin === void 0) origin = {\n\t\tx: 0,\n\t\ty: 0\n\t};\n\tgetRectPositioned(rect, origin);\n\treturn Object.freeze({\n\t\tx: origin.x + rect.width / 2,\n\t\ty: origin.y + rect.height / 2\n\t});\n};\n//#endregion\n//#region src/rect/intersects.ts\n/**\n* Returns true if point is within or on boundary of `rect`.\n*\n* ```js\n* Rects.intersectsPoint(rect, { x: 100, y: 100});\n* Rects.intersectsPoint(rect, 100, 100);\n* ```\n* @param rect\n* @param a\n* @param b\n* @returns\n*/\nfunction intersectsPoint(rect, a, b) {\n\tguard$1(rect, `rect`);\n\tlet x = 0;\n\tlet y = 0;\n\tif (typeof a === `number`) {\n\t\tif (b === void 0) throw new Error(`x and y coordinate needed`);\n\t\tx = a;\n\t\ty = b;\n\t} else {\n\t\tx = a.x;\n\t\ty = a.y;\n\t}\n\tif (isPositioned(rect)) {\n\t\tif (x - rect.x > rect.width || x < rect.x) return false;\n\t\tif (y - rect.y > rect.height || y < rect.y) return false;\n\t} else {\n\t\tif (x > rect.width || x < 0) return false;\n\t\tif (y > rect.height || y < 0) return false;\n\t}\n\treturn true;\n}\n/**\n* Returns true if `a` or `b` overlap, are equal, or `a` contains `b`.\n* A rectangle can be checked for intersections with another RectPositioned, CirclePositioned or Point.\n*\n*/\nconst isIntersecting = (a, b) => {\n\tif (!isRectPositioned(a)) throw new Error(`a parameter should be RectPositioned`);\n\tif (isCirclePositioned(b)) return circleRect(b, a);\n\telse if (isPoint(b)) return intersectsPoint(a, b);\n\tthrow new Error(`Unknown shape for b: ${JSON.stringify(b)}`);\n};\n//#endregion\n//#region src/rect/distance.ts\n/**\n* Returns the distance from the perimeter of `rect` to `pt`.\n* If the point is within the rectangle, 0 is returned.\n*\n* If `rect` does not have an x,y it's assumed to be 0,0\n*\n* ```js\n* const rect = { width: 100, height: 100, x: 0, y: 0 };\n* Rects.distanceFromExterior(rect, { x: 20, y: 20 });\n* ```\n* @param rect Rectangle\n* @param pt Point\n* @returns Distance\n*/\nfunction distanceFromExterior(rect, pt) {\n\tguardPositioned(rect, `rect`);\n\tguard(pt, `pt`);\n\tif (intersectsPoint(rect, pt)) return 0;\n\tconst dx = Math.max(rect.x - pt.x, 0, pt.x - rect.x + rect.width);\n\tconst dy = Math.max(rect.y - pt.y, 0, pt.y - rect.y + rect.height);\n\treturn Math.hypot(dx, dy);\n}\n/**\n* Return the distance of `pt` to the center of `rect`.\n*\n* ```js\n* const rect = { width: 100, height: 100, x: 0, y: 0 };\n* Rects.distanceFromCenter(rect, { x: 20, y: 20 });\n* ```\n* @param rect\n* @param pt\n* @returns\n*/\nfunction distanceFromCenter(rect, pt) {\n\treturn distance(center(rect), pt);\n}\n//#endregion\n//#region src/line/join-points-to-lines.ts\n/**\n* Returns an array of lines that connects provided points. Note that line is not closed.\n* \n* Eg, if points a,b,c are provided, two lines are provided: a->b and b->c.\n* \n* ```js\n* const lines = Lines.joinPointsToLines(ptA, ptB, ptC);\n* // lines is an array of, well, lines\n* ```\n* @param points \n* @returns \n*/\nconst joinPointsToLines = (...points) => {\n\tconst lines = [];\n\tlet start = points[0];\n\tfor (let index = 1; index < points.length; index++) {\n\t\tlines.push(fromPoints(start, points[index]));\n\t\tstart = points[index];\n\t}\n\treturn lines;\n};\n/**\n* Converts a {@link PolyLine} to an array of points.\n* Duplicate points are optionally excluded\n* @param line \n* @returns \n*/\nconst polyLineToPoints = (line, skipDuplicates = false) => {\n\tif (skipDuplicates) {\n\t\tconst pt = [];\n\t\tconst seen = /* @__PURE__ */ new Set();\n\t\tfor (const l of line) {\n\t\t\tconst aa = toString(l.a);\n\t\t\tconst bb = toString(l.b);\n\t\t\tif (!seen.has(aa)) {\n\t\t\t\tseen.add(aa);\n\t\t\t\tpt.push(l.a);\n\t\t\t}\n\t\t\tif (seen.has(bb)) {\n\t\t\t\tseen.add(bb);\n\t\t\t\tpt.push(l.b);\n\t\t\t}\n\t\t}\n\t\treturn pt;\n\t} else {\n\t\tconst pt = [];\n\t\tfor (const l of line) pt.push(l.a, l.b);\n\t\treturn pt;\n\t}\n};\n//#endregion\nexport { intersectsPoint as a, distanceFromExterior as i, polyLineToPoints as n, isIntersecting as o, distanceFromCenter as r, center as s, joinPointsToLines as t };\n","import { isEqualDefault } from \"@ixfx/core\";\nimport { SimpleEventEmitter } from \"@ixfx/events\";\n//#region src/queue/queue-fns.ts\nconst debug = (opts, message) => {\n\topts.debug && console.log(`queue:${message}`);\n};\nconst trimQueue = (opts, queue, toAdd) => {\n\tconst potentialLength = queue.length + toAdd.length;\n\tconst capacity = opts.capacity ?? potentialLength;\n\tconst toRemove = potentialLength - capacity;\n\tconst policy = opts.discardPolicy ?? `additions`;\n\tswitch (policy) {\n\t\tcase `additions`:\n\t\t\tif (queue.length === 0) return toAdd.slice(0, toAdd.length - toRemove);\n\t\t\tif (queue.length === opts.capacity) return queue;\n\t\t\telse return [...queue, ...toAdd.slice(0, toRemove - 1)];\n\t\tcase `newer`: if (toRemove >= queue.length) {\n\t\t\tif (queue.length === 0) return [...toAdd.slice(0, capacity - 1), toAdd.at(-1)];\n\t\t\treturn toAdd.slice(Math.max(0, toAdd.length - capacity), Math.min(toAdd.length, capacity) + 1);\n\t\t} else {\n\t\t\tconst countToAdd = Math.max(1, toAdd.length - queue.length);\n\t\t\tconst toAddFinal = toAdd.slice(toAdd.length - countToAdd, toAdd.length);\n\t\t\treturn [...queue.slice(0, Math.min(queue.length, capacity - 1)), ...toAddFinal];\n\t\t}\n\t\tcase `older`: return [...queue, ...toAdd].slice(toRemove);\n\t\tdefault: throw new Error(`Unknown overflow policy ${policy}`);\n\t}\n};\n/**\n* Adds to the back of the queue (last array index)\n* Last item of `toAdd` will potentially be the new end of the queue (depending on capacity limit and overflow policy)\n* @typeParam V - Type of values\n* @param {QueueOpts} opts\n* @param {V[]} queue\n* @param {...V[]} toAdd\n* @returns {V[]}\n*/\nconst enqueue = (opts, queue, ...toAdd) => {\n\tif (opts === void 0) throw new Error(`opts parameter undefined`);\n\tconst potentialLength = queue.length + toAdd.length;\n\tconst overSize = opts.capacity && potentialLength > opts.capacity;\n\tconst toReturn = overSize ? trimQueue(opts, queue, toAdd) : [...queue, ...toAdd];\n\tif (opts.capacity && toReturn.length !== opts.capacity && overSize) throw new Error(`Bug! Expected return to be at capacity. Return len: ${toReturn.length} capacity: ${opts.capacity} opts: ${JSON.stringify(opts)}`);\n\tif (!opts.capacity && toReturn.length !== potentialLength) throw new Error(`Bug! Return length not expected. Return len: ${toReturn.length} expected: ${potentialLength} opts: ${JSON.stringify(opts)}`);\n\treturn toReturn;\n};\nconst dequeue = (opts, queue) => {\n\tif (queue.length === 0) throw new Error(`Queue is empty`);\n\treturn queue.slice(1);\n};\n/**\n* Returns front of queue (oldest item), or undefined if queue is empty\n*\n* @typeParam V - Type of values stored\n* @param {QueueOpts} opts\n* @param {V[]} queue\n* @returns {(V | undefined)}\n*/\nconst peek = (opts, queue) => queue[0];\nconst isEmpty = (opts, queue) => queue.length === 0;\nconst isFull = (opts, queue) => {\n\tif (opts.capacity) return queue.length >= opts.capacity;\n\treturn false;\n};\n//#endregion\n//#region src/queue/queue-mutable.ts\n/**\n* Mutable queue that fires events when manipulated.\n* \n* Queues are useful if you want to treat 'older' or 'newer'\n* items differently. _Enqueing_ adds items at the back of the queue, while\n* _dequeing_ removes items from the front (ie. the oldest).\n*\n* ```js\n* const q = Queues.mutable(); // Create\n* q.enqueue(`a`, `b`); // Add two strings\n* const front = q.dequeue(); // `a` is at the front of queue (oldest)\n* ```\n*\n* @example Cap size to 5 items, throwing away newest items already in queue.\n* ```js\n* const q = Queues.mutable({capacity: 5, discardPolicy: `newer`});\n* ```\n*\n* Events can be used to monitor data flows.\n* * 'enqueue': fires when item(s) are added\n* * 'dequeue': fires when an item is dequeued from front\n* * 'removed': fires when an item is dequeued, queue is cleared or .removeWhere is used to trim queue\n* \n* Each of the event handlers return the state of the queue as the 'finalData'\n* field.\n* \n* ```js\n* q.addEventListener(`enqueue`, e => {\n* // e.added, e.finalData\n* });\n* q.addEventListener(`removed`, e => {\n* // e.removed, e.finalData\n* });\n* q.addEventListener(`dequeue`, e=> {\n* // e.removed, e.finalData\n* })\n* ```\n* @typeParam V - Data type of items\n*/\nvar QueueMutable = class extends SimpleEventEmitter {\n\toptions;\n\tdata;\n\teq;\n\tconstructor(opts = {}, data = []) {\n\t\tsuper();\n\t\tif (opts === void 0) throw new Error(`opts parameter undefined`);\n\t\tthis.options = opts;\n\t\tthis.data = data;\n\t\tthis.eq = opts.eq ?? isEqualDefault;\n\t}\n\tclear() {\n\t\tconst copy = [...this.data];\n\t\tthis.data = [];\n\t\tthis.fireEvent(`removed`, {\n\t\t\tfinalData: this.data,\n\t\t\tremoved: copy\n\t\t});\n\t\tthis.onClear();\n\t}\n\t/**\n\t* Called when all data is cleared\n\t*/\n\tonClear() {}\n\tat(index) {\n\t\tif (index >= this.data.length) throw new Error(`Index outside bounds of queue`);\n\t\tconst v = this.data.at(index);\n\t\tif (v === void 0) throw new Error(`Index appears to be outside range of queue`);\n\t\treturn v;\n\t}\n\tenqueue(...toAdd) {\n\t\tthis.data = enqueue(this.options, this.data, ...toAdd);\n\t\tconst length = this.data.length;\n\t\tthis.onEnqueue(this.data, toAdd);\n\t\treturn length;\n\t}\n\tonEnqueue(result, attemptedToAdd) {\n\t\tthis.fireEvent(`enqueue`, {\n\t\t\tadded: attemptedToAdd,\n\t\t\tfinalData: result\n\t\t});\n\t}\n\tdequeue() {\n\t\tconst v = peek(this.options, this.data);\n\t\tif (v === void 0) return;\n\t\tthis.data = dequeue(this.options, this.data);\n\t\tthis.fireEvent(`dequeue`, {\n\t\t\tremoved: v,\n\t\t\tfinalData: this.data\n\t\t});\n\t\tthis.onRemoved([v], this.data);\n\t\treturn v;\n\t}\n\tonRemoved(removed, finalData) {\n\t\tthis.fireEvent(`removed`, {\n\t\t\tremoved,\n\t\t\tfinalData\n\t\t});\n\t}\n\t/**\n\t* Removes values that match `predicate`.\n\t* @param predicate \n\t* @returns Returns number of items removed.\n\t*/\n\tremoveWhere(predicate) {\n\t\tconst countPre = this.data.length;\n\t\tconst toRemove = this.data.filter((v) => predicate(v));\n\t\tif (toRemove.length === 0) return 0;\n\t\tthis.data = this.data.filter((element) => !predicate(element));\n\t\tthis.onRemoved(toRemove, this.data);\n\t\treturn countPre - this.data.length;\n\t}\n\t/**\n\t* Return a copy of the array\n\t* @returns \n\t*/\n\ttoArray() {\n\t\treturn [...this.data];\n\t}\n\tget isEmpty() {\n\t\treturn isEmpty(this.options, this.data);\n\t}\n\tget isFull() {\n\t\treturn isFull(this.options, this.data);\n\t}\n\tget length() {\n\t\treturn this.data.length;\n\t}\n\tget peek() {\n\t\treturn peek(this.options, this.data);\n\t}\n};\n/**\n* Creates a new QueueMutable\n* @param options \n* @param startingItems \n* @returns \n*/\nfunction mutable(options = {}, ...startingItems) {\n\treturn new QueueMutable({ ...options }, [...startingItems]);\n}\n//#endregion\nexport { enqueue as a, peek as c, dequeue as i, trimQueue as l, mutable as n, isEmpty as o, debug as r, isFull as s, QueueMutable as t };\n","//#region src/guard.ts\nconst isAsyncIterable = (v) => {\n\tif (typeof v !== `object`) return false;\n\tif (v === null) return false;\n\treturn Symbol.asyncIterator in v;\n};\nconst isIterable = (v) => {\n\tif (typeof v !== `object`) return false;\n\tif (v === null) return false;\n\treturn Symbol.iterator in v;\n};\n//#endregion\nexport { isIterable as n, isAsyncIterable as t };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { n as isIterable } from \"./guard-COHp1bP0.js\";\nimport { intervalToMs, isEqualDefault, toStringDefault } from \"@ixfx/core\";\n//#region src/sync/slice.ts\nfunction* slice(it, start = 0, end = Number.POSITIVE_INFINITY) {\n\tif (end < start) throw new Error(`Param 'end' should be more than 'start'`);\n\tif (start < 0) throw new Error(`Param 'start' should be at least 0`);\n\tlet index = 0;\n\tfor (const v of it) {\n\t\tif (index < start) {\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (index > end) break;\n\t\tyield v;\n\t\tindex++;\n\t}\n}\n//#endregion\n//#region src/sync/reduce.ts\nfunction reduce(it, f, start) {\n\tfor (const v of it) start = f(start, v);\n\treturn start;\n}\n//#endregion\n//#region src/sync.ts\nvar sync_exports = /* @__PURE__ */ __exportAll({\n\tasCallback: () => asCallback,\n\tchunks: () => chunks,\n\tchunksOverlapping: () => chunksOverlapping,\n\tconcat: () => concat,\n\tdropWhile: () => dropWhile,\n\tequals: () => equals,\n\tevery: () => every,\n\tfill: () => fill,\n\tfilter: () => filter,\n\tfind: () => find,\n\tfirst: () => first,\n\tflatten: () => flatten,\n\tforEach: () => forEach,\n\tfromArray: () => fromArray,\n\tfromIterable: () => fromIterable,\n\tlast: () => last,\n\tmap: () => map,\n\tmax: () => max,\n\tmin: () => min,\n\tnext: () => next,\n\treduce: () => reduce,\n\trepeat: () => repeat,\n\tslice: () => slice,\n\tsome: () => some,\n\ttoArray: () => toArray,\n\tunique: () => unique,\n\tuniqueByValue: () => uniqueByValue,\n\tuntil: () => until,\n\tyieldNumber: () => yieldNumber,\n\tzip: () => zip\n});\nfunction* uniqueByValue(input, toString = toStringDefault, seen = /* @__PURE__ */ new Set()) {\n\tfor (const v of input) {\n\t\tconst key = toString(v);\n\t\tif (seen.has(key)) continue;\n\t\tseen.add(key);\n\t\tyield v;\n\t}\n}\n/**\n* Calls `callback` whenever the generator produces a value.\n* \n* When using `asCallback`, call it with `await` to let generator \n* run its course before continuing:\n* ```js\n* await asCallback(tick({ interval:1000, loops:5 }), x => {\n* // Gets called 5 times, with 1000ms interval\n* });\n* console.log(`Hi`); // Prints after 5 seconds\n* ```\n* \n* Or if you skip the `await`, code continues and callback will still run:\n* ```js\n* asCallback(tick({ interval: 1000, loops: 5}), x => {\n* // Gets called 5 times, with 1000ms interval\n* });\n* console.log(`Hi`); // Prints immediately\n* ```\n* @param input \n* @param callback \n*/\nfunction asCallback(input, callback, onDone) {\n\tfor (const value of input) callback(value);\n\tif (onDone) onDone();\n}\n/**\n* Returns a function that yields a value from a generator.\n* ```js\n* const spring = yieldNumber(Oscillators.spring());\n*\n* spring(); // latest value\n* ```\n*\n* Instead of:\n* ```js\n* const spring = Oscillators.spring();\n*\n* spring.next().value\n* ```\n*\n* A `defaultValue` can be provided if the source generator returns undefined:\n* ```js\n* const spring = yieldNumber(Oscillators.spring(), 0);\n* spring(); // Returns 0 if the generator returns undefined\n* ```\n* @param generator\n* @param defaultValue\n* @returns\n*/\nfunction yieldNumber(generator, defaultValue) {\n\treturn () => {\n\t\tconst v = generator.next().value;\n\t\tif (v === void 0) return defaultValue;\n\t\treturn v;\n\t};\n}\n/**\n* Return first value from an iterable, or _undefined_ if\n* no values are generated\n* @param it\n* @returns\n*/\nfunction first(it) {\n\tfor (const value of it) return value;\n}\n/**\n* Returns last value from an iterable, or _undefined_\n* if no values are generated\n* @param it\n*/\nfunction last(it) {\n\tlet returnValue;\n\tfor (const value of it) returnValue = value;\n\treturn returnValue;\n}\n/**\n* Yields chunks of the iterable `it` such that the end of a chunk is the\n* start of the next chunk.\n*\n* Eg, with the input [1,2,3,4,5] and a size of 2, we would get back\n* [1,2], [2,3], [3,4], [4,5].\n*\n*\n* @param it\n* @param size\n* @returns\n*/\nfunction* chunksOverlapping(it, size) {\n\tif (size <= 1) throw new Error(`Size should be at least 2`);\n\tlet buffer = [];\n\tfor (const v of it) {\n\t\tbuffer.push(v);\n\t\tif (buffer.length === size) {\n\t\t\tyield buffer;\n\t\t\tbuffer = [buffer.at(-1)];\n\t\t}\n\t}\n\tif (buffer.length <= 1) return;\n\tif (buffer.length > 0) yield buffer;\n}\nfunction* chunks(it, size) {\n\tlet buffer = [];\n\tfor (const v of it) {\n\t\tbuffer.push(v);\n\t\tif (buffer.length === size) {\n\t\t\tyield buffer;\n\t\t\tbuffer = [];\n\t\t}\n\t}\n\tif (buffer.length > 0) yield buffer;\n}\nfunction* concat(...its) {\n\tfor (const it of its) yield* it;\n}\nfunction* dropWhile(it, f) {\n\tfor (const v of it) if (!f(v)) yield v;\n}\n/**\n* Loops over a generator until it finishes, calling `callback`.\n* Useful if you don't care about the value generator produces, just the number of loops.\n* \n* ```js\n* until(count(5), () => {\n* // do something 5 times\n* });\n* ```\n* \n* If you want the value from the generator, use a `for of` loop as usual.\n* If `callback` explicitly returns _false_, the generator is aborted.\n* @param it Generator to run\n* @param callback Code to call for each iteration\n*/\nconst until = (it, callback) => {\n\tfor (const _ of it) {\n\t\tconst value = callback();\n\t\tif (typeof value === `boolean` && !value) break;\n\t}\n};\nconst next = (it) => {\n\treturn () => {\n\t\tconst r = it.next();\n\t\tif (r.done) return;\n\t\treturn r.value;\n\t};\n};\n/**\n* Returns true if items in two iterables are equal, by value and order\n* \n* By default uses === comparison\n* @param it1\n* @param it2\n* @param comparerOrKey Function to produce a key for value or compare two values\n* @returns\n*/\nfunction equals(it1, it2, comparerOrKey = isEqualDefault) {\n\tlet isUnknownFunction = true;\n\tlet eqFunction;\n\tlet keyFunction;\n\twhile (true) {\n\t\tconst index1 = it1.next();\n\t\tconst index2 = it2.next();\n\t\tconst v1 = index1.value;\n\t\tconst v2 = index2.value;\n\t\tif (isUnknownFunction) {\n\t\t\tif (typeof comparerOrKey(v1, v2) === `string`) keyFunction = comparerOrKey;\n\t\t\telse eqFunction = comparerOrKey;\n\t\t\tisUnknownFunction = false;\n\t\t}\n\t\tif (keyFunction) {\n\t\t\tif (keyFunction(v1) !== keyFunction(v2)) return false;\n\t\t} else if (eqFunction) {\n\t\t\tif (!eqFunction(v1, v2)) return false;\n\t\t} else throw new Error(`Something wrong with comparer function?`);\n\t\tif (index1.done ?? index2.done) return index1.done && index2.done;\n\t}\n}\nfunction every(it, f) {\n\tfor (const v of it) if (!f(v)) return false;\n\treturn true;\n}\nfunction* fill(it, v) {\n\tfor (const _ of it) yield v;\n}\n/**\n* Iterates over `iterator` (iterable/array), calling `fn` for each value.\n* If `fn` returns _false_, iterator cancels.\n*\n* Over the default JS `forEach` function, this one allows you to exit the\n* iteration early.\n*\n* @example\n* ```js\n* import { Sync } from \"@ixfx/iterables.js\"\n* Sync.forEach(count(5), () => console.log(`Hi`)); // Prints `Hi` 5x\n* Sync.forEach(count(5), i => console.log(i)); // Prints 0 1 2 3 4\n* Sync.forEach([0,1,2,3,4], i => console.log(i)); // Prints 0 1 2 3 4\n* ```\n*\n* Use {@link forEach} if you want to use an async `iterator` and async `fn`.\n* \n* Alternatives:\n* * {@link https://api.ixfx.fun/_ixfx/flow/repeat/ @ixfx/flow.repeat}/{@link https://api.ixfx.fun/_ixfx/flow/repeatSync/ @ixfx/flow.repeatSync}: if you want to call something a given number of times and get the result\n* @param iterator Iterable or array\n* @typeParam T Type of iterable's values\n* @param fn Function to call for each item. If function returns _false_, iteration cancels\n*/\nfunction forEach(iterator, fn) {\n\tfor (const v of iterator) {\n\t\tconst result = fn(v);\n\t\tif (typeof result === `boolean` && !result) break;\n\t}\n}\n/**\n* ```js\n* filter([1, 2, 3, 4], e => e % 2 == 0);\n* returns [2, 4]\n* ```\n* @param it\n* @param f\n*/\nfunction* filter(it, f) {\n\tfor (const v of it) {\n\t\tif (!f(v)) continue;\n\t\tyield v;\n\t}\n}\nfunction find(it, f) {\n\tfor (const v of it) if (f(v)) return v;\n}\nfunction* flatten(it) {\n\tfor (const v of it) if (typeof v === `object`) {\n\t\tif (Array.isArray(v)) for (const vv of v) yield vv;\n\t\telse if (isIterable(v)) for (const vv of v) yield vv;\n\t} else yield v;\n}\n/**\n* Maps an iterable of type `V` to type `X`.\n* ```js\n* map([1, 2, 3], e => e*e)\n* returns [1, 4, 9]\n* ```\n* @param it\n* @param f\n*/\nfunction* map(it, f) {\n\tfor (const v of it) yield f(v);\n}\nfunction* max(it, gt = (a, b) => a > b) {\n\tlet max;\n\tfor (const v of it) {\n\t\tif (max === void 0) {\n\t\t\tmax = v;\n\t\t\tyield max;\n\t\t\tcontinue;\n\t\t}\n\t\tif (gt(v, max)) {\n\t\t\tmax = v;\n\t\t\tyield max;\n\t\t}\n\t}\n\treturn max;\n}\nfunction* min(it, gt = (a, b) => a > b) {\n\tlet min;\n\tfor (const v of it) {\n\t\tif (min === void 0) {\n\t\t\tmin = v;\n\t\t\tyield min;\n\t\t}\n\t\tif (gt(min, v)) {\n\t\t\tmin = v;\n\t\t\tyield min;\n\t\t}\n\t}\n}\nfunction some(it, f) {\n\tfor (const v of it) if (f(v)) return true;\n\treturn false;\n}\nfunction* repeat(genCreator, repeatsOrSignal) {\n\tconst repeats = typeof repeatsOrSignal === `number` ? repeatsOrSignal : Number.POSITIVE_INFINITY;\n\tconst signal = typeof repeatsOrSignal === `number` ? void 0 : repeatsOrSignal;\n\tlet count = repeats;\n\twhile (true) {\n\t\tfor (const v of genCreator()) {\n\t\t\tyield v;\n\t\t\tif (signal?.aborted) break;\n\t\t}\n\t\tif (Number.isFinite(repeats)) {\n\t\t\tcount--;\n\t\t\tif (count === 0) break;\n\t\t}\n\t\tif (signal?.aborted) break;\n\t}\n}\nfunction* unique(iterable) {\n\tconst buffer = [];\n\tlet itera = [];\n\titera = Array.isArray(iterable) ? iterable : [iterable];\n\tfor (const it of itera) for (const v of it) {\n\t\tif (buffer.includes(v)) continue;\n\t\tbuffer.push(v);\n\t\tyield v;\n\t}\n}\n/**\n* Combine same-positioned items from several iterables\n* ```js\n* zip( [1, 2, 3], [4, 5, 6], [7, 8, 9] );\n* Yields: [ [1, 4, 7], [2, 5, 8], [3, 6, 9] ]\n* ```\n* @param its\n* @returns\n*/\nfunction* zip(...its) {\n\tconst iits = its.map((it) => it[Symbol.iterator]());\n\twhile (true) {\n\t\tconst vs = iits.map((it) => it.next());\n\t\tif (vs.some((v) => v.done)) return;\n\t\tyield vs.map((v) => v.value);\n\t}\n}\nfunction* fromIterable(iterable) {\n\tfor (const v of iterable) yield v;\n}\n/**\n* Returns an array of values from an iterator.\n*\n* ```js\n* const data = await toArray(adsrIterable(opts, 10));\n* ```\n*\n* Note: If the iterator is infinite, be sure to provide a limit via the options or the function\n* will never return.\n*\n* @param it Asynchronous iterable\n* @param options Options when converting to array.\n* @returns\n*/\nfunction toArray(it, options = {}) {\n\tconst result = [];\n\tconst started = Date.now();\n\tconst whileFunction = options.while;\n\tconst maxItems = options.limit ?? Number.POSITIVE_INFINITY;\n\tconst maxElapsed = intervalToMs(options.elapsed, Number.POSITIVE_INFINITY);\n\tfor (const v of it) {\n\t\tif (whileFunction) {\n\t\t\tif (!whileFunction(result.length)) break;\n\t\t}\n\t\tif (result.length >= maxItems) break;\n\t\tif (Date.now() - started > maxElapsed) break;\n\t\tresult.push(v);\n\t}\n\treturn result;\n}\n/**\n* Yield values from `array`, one at a time.\n* Use `interval` to add time between each item.\n* The first item is yielded without delay.\n* @param array Array of values\n*/\nfunction* fromArray(array) {\n\tfor (const v of array) yield v;\n}\n//#endregion\nexport { reduce as A, sync_exports as C, until as D, uniqueByValue as E, yieldNumber as O, some as S, unique as T, map as _, dropWhile as a, next as b, fill as c, first as d, flatten as f, last as g, fromIterable as h, concat as i, slice as j, zip as k, filter as l, fromArray as m, chunks as n, equals as o, forEach as p, chunksOverlapping as r, every as s, asCallback as t, find as u, max as v, toArray as w, repeat as x, min as y };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { n as isIterable, t as isAsyncIterable } from \"./guard-COHp1bP0.js\";\nimport { intervalToMs, isEqualDefault, sleep, toStringDefault } from \"@ixfx/core\";\n//#region src/async.ts\nvar async_exports = /* @__PURE__ */ __exportAll({\n\tasCallback: () => asCallback,\n\tchunks: () => chunks,\n\tconcat: () => concat,\n\tdropWhile: () => dropWhile,\n\tequals: () => equals,\n\tevery: () => every,\n\tfill: () => fill,\n\tfilter: () => filter,\n\tfind: () => find,\n\tflatten: () => flatten,\n\tforEach: () => forEach,\n\tfromArray: () => fromArray,\n\tfromIterable: () => fromIterable,\n\tlast: () => last,\n\tmap: () => map,\n\tmax: () => max,\n\tmin: () => min,\n\tnextWithTimeout: () => nextWithTimeout,\n\treduce: () => reduce,\n\trepeat: () => repeat,\n\tslice: () => slice,\n\tsome: () => some,\n\ttoArray: () => toArray,\n\tunique: () => unique,\n\tuniqueByValue: () => uniqueByValue,\n\tuntil: () => until,\n\twithDelay: () => withDelay,\n\tzip: () => zip\n});\n/**\n* Yield values from `array`, one at a time.\n* Use `interval` to add time between each item.\n* The first item is yielded without delay.\n* \n* @param array Array of values\n* @param interval Interval (defaults: 1ms)\n*/\nasync function* fromArray(array, interval = 1) {\n\tfor (const v of array) {\n\t\tyield v;\n\t\tawait sleep(interval);\n\t}\n}\n/**\n* Yield values from `iterable`, one at a time.\n* Use `interval` to add time between each item.\n* The first item is yielded without delay.\n* @param iterable Iterable or AsyncIterable\n* @param [interval=1] Interval to wait between yield\n*/\nasync function* fromIterable(iterable, interval = 1) {\n\tfor await (const v of iterable) {\n\t\tyield v;\n\t\tawait sleep(interval);\n\t}\n}\nasync function* chunks(it, size) {\n\tlet buffer = [];\n\tfor await (const v of it) {\n\t\tbuffer.push(v);\n\t\tif (buffer.length === size) {\n\t\t\tyield buffer;\n\t\t\tbuffer = [];\n\t\t}\n\t}\n\tif (buffer.length > 0) yield buffer;\n}\nasync function* concat(...its) {\n\tfor await (const it of its) yield* it;\n}\nasync function* dropWhile(it, f) {\n\tfor await (const v of it) if (!f(v)) yield v;\n}\n/**\n* Loops over a generator until it finishes, calling `callback`.\n* Useful if you don't care about the value generator produces, just the number of loops.\n* \n* In this version, we do a `for await of` over `gen`, and also `await callback()`. \n\n* ```js\n* await until(count(5), () => {\n* // do something 5 times\n* });\n* ```\n* \n* If you want the value from the generator, use a `for of` loop as usual.\n* \n* If `callback` explicitly returns _false_, the generator is aborted.\n* @param it Generator to run\n* @param callback Code to call for each iteration\n*/\nconst until = async (it, callback) => {\n\tfor await (const _ of it) {\n\t\tconst value = await callback();\n\t\tif (typeof value === `boolean` && !value) break;\n\t}\n};\n/**\n* This generator will repeat another generator up until some condition. This is the version\n* that can handle async generators.\n* \n* For example, {@link https://api.ixfx.fun/_ixfx/numbers/count/ @ixfx/numbers.count} will count from 0..number and then finish:\n* ```js\n* import { count } from '@ixfx/numbers'\n* for (const v of count(5)) {\n* // v: 0, 1, 2, 3, 4\n* }\n* ```\n* \n* But what if we want to repeat the count? We have to provide a function to create the generator,\n* rather than using the generator directly, since it's \"one time use\"\n* ```js\n* for await (const v of repeat(() => count(5))) {\n* // v: 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, ...\n* // warning: never ends\n* }\n* ```\n* \n* Limiting the number of repeats can be done by passing in extra parameters\n* ```js\n* repeat(generator, { count: 5} ); // Iterate over `generator` five times\n* ```\n* \n* ```js\n* const ac = new AbortController();\n* repeat(generator, { signal: ac.signal }); // Pass in signal\n* ...\n* ac.abort(); // Trigger signal at some point\n* ```\n* @param genCreator \n* @param repeatsOrSignal \n*/\nconst repeat = async function* (genCreator, repeatsOrSignal) {\n\tconst repeats = typeof repeatsOrSignal === `number` ? repeatsOrSignal : Number.POSITIVE_INFINITY;\n\tconst signal = typeof repeatsOrSignal === `number` ? void 0 : repeatsOrSignal;\n\tlet count = repeats;\n\twhile (true) {\n\t\tfor await (const v of genCreator()) {\n\t\t\tyield v;\n\t\t\tif (signal?.aborted) break;\n\t\t}\n\t\tif (Number.isFinite(repeats)) {\n\t\t\tcount--;\n\t\t\tif (count === 0) break;\n\t\t}\n\t\tif (signal?.aborted) break;\n\t}\n};\n/**\n* Returns true if items in two iterables are equal, and in the same order.\n* \n* Uses === semantics by default.\n* @param it1\n* @param it2\n* @param equality\n* @returns\n*/\nasync function equals(it1, it2, comparerOrKey = isEqualDefault) {\n\tconst iit1 = it1[Symbol.asyncIterator]();\n\tconst iit2 = it2[Symbol.asyncIterator]();\n\tlet isUnknownFunction = true;\n\tlet eqFunction;\n\tlet keyFunction;\n\twhile (true) {\n\t\tconst index1 = await iit1.next();\n\t\tconst index2 = await iit2.next();\n\t\tconst v1 = index1.value;\n\t\tconst v2 = index2.value;\n\t\tif (isUnknownFunction) {\n\t\t\tif (typeof comparerOrKey(v1, v2) === `string`) keyFunction = comparerOrKey;\n\t\t\telse eqFunction = comparerOrKey;\n\t\t\tisUnknownFunction = false;\n\t\t}\n\t\tif (keyFunction) {\n\t\t\tif (keyFunction(v1) !== keyFunction(v2)) return false;\n\t\t} else if (eqFunction) {\n\t\t\tif (!eqFunction(v1, v2)) return false;\n\t\t} else throw new Error(`Something wrong with comparer function?`);\n\t\tif (index1.done ?? index2.done) return index1.done && index2.done;\n\t}\n}\nasync function every(it, f) {\n\tfor await (const v of it) if (!await f(v)) return false;\n\treturn true;\n}\nasync function* fill(it, v) {\n\tfor await (const _ of it) yield v;\n}\n/**\n* Filters an iterable, only yielding items which match `f`.\n*\n* ```js\n* filter([1, 2, 3, 4], e => e % 2 == 0);\n* returns [2, 4]\n* ```\n* @param it\n* @param f\n*/\nasync function* filter(it, f) {\n\tfor await (const v of it) {\n\t\tif (!await f(v)) continue;\n\t\tyield v;\n\t}\n}\nasync function find(it, f) {\n\tfor await (const v of it) if (await f(v)) return v;\n}\nasync function* flatten(it) {\n\tfor await (const v of it) if (typeof v === `object`) {\n\t\tif (Array.isArray(v)) for (const vv of v) yield vv;\n\t\telse if (isAsyncIterable(v)) for await (const vv of v) yield vv;\n\t\telse if (isIterable(v)) for (const vv of v) yield vv;\n\t} else yield v;\n}\n/**\n* Iterates over an async iterable or array, calling `fn` for each value, with optional\n* interval between each loop. If the async `fn` returns _false_, iterator cancels.\n*\n* ```\n* import { forEach } from \"@ixfx/flow.js\"\n* // Prints items from array every second\n* await forEach([0,1,2,3], i => console.log(i), 1000);\n* ```\n*\n* ```\n* // Retry up to five times, with 5 seconds between each attempt\n* await forEach(count(5), i=> {\n* try {\n* await doSomething();\n* return false; // Succeeded, exit early\n* } catch (ex) {\n* console.log(ex);\n* return true; // Keep trying\n* }\n* }, 5000);\n* ```\n* @param iterator Iterable thing to loop over\n* @param fn Function to invoke on each item. If it returns _false_ loop ends.\n* @param options Options\n* @typeParam V Type of iterable\n*/\nconst forEach = async function(iterator, fn, options = {}) {\n\tconst interval = options.interval;\n\tif (Array.isArray(iterator)) for (const x of iterator) {\n\t\tconst r = await fn(x);\n\t\tif (typeof r === `boolean` && !r) break;\n\t\tif (interval) await sleep(interval);\n\t}\n\telse for await (const x of iterator) {\n\t\tconst r = await fn(x);\n\t\tif (typeof r === `boolean` && !r) break;\n\t\tif (interval) await sleep(interval);\n\t}\n};\n/**\n* Returns last value from an iterable, or _undefined_\n* if no values are generated\n* @param it\n*/\nasync function last(it, opts = {}) {\n\tconst abort = opts.abort;\n\tlet returnValue;\n\tfor await (const value of it) {\n\t\tif (abort?.aborted) return void 0;\n\t\treturnValue = value;\n\t}\n\treturn returnValue;\n}\n/**\n* Maps an iterable through function `f`\n* ```js\n* // For every input value, multiply it by itself\n* map([1, 2, 3], e => e*e)\n* // Yields: 1, 4, 9\n* ```\n* \n* It can also be used to transform types:\n* ```js\n* map([1, 2, 3], e => { value: e });\n* // Yields: { value: 1 }, { value: 2 }, { value: 3 }\n* ```\n* @param it\n* @param f\n*/\nasync function* map(it, f) {\n\tfor await (const v of it) yield f(v);\n}\nasync function* max(it, gt = ((a, b) => a > b)) {\n\tlet max;\n\tfor await (const v of it) {\n\t\tif (max === void 0) {\n\t\t\tmax = v;\n\t\t\tyield max;\n\t\t\tcontinue;\n\t\t}\n\t\tif (gt(v, max)) {\n\t\t\tmax = v;\n\t\t\tyield v;\n\t\t}\n\t}\n}\n/**\n* Returns the minimum seen of an iterable as it changes.\n* Streaming result: works with endless iterables.\n* \n* Note that `gt` function returns true if A is _greater_ than B, even\n* though we're looking for the minimum.\n* \n* ```js\n* // Rank objects based on 'v' value\n* const rank = (a,b) => a.v > b.v;\n* min([\n* {i:0,v:1},\n* {i:1,v:9},\n* {i:2,v:-2}\n* ], rank);\n* // Yields: {i:2, v:1}, {i:2,v:-2}\n* ```\n* @param it Iterable\n* @param gt Should return _true_ if `a` is greater than `b`.\n* @returns\n*/\nasync function* min(it, gt = (a, b) => a > b) {\n\tlet min;\n\tfor await (const v of it) {\n\t\tif (min === void 0) {\n\t\t\tmin = v;\n\t\t\tyield min;\n\t\t\tcontinue;\n\t\t}\n\t\tif (gt(min, v)) {\n\t\t\tmin = v;\n\t\t\tyield v;\n\t\t}\n\t}\n\treturn min;\n}\nasync function reduce(it, f, start) {\n\tfor await (const v of it) start = f(start, v);\n\treturn start;\n}\n/**\n* Calls `callback` whenever the async generator produces a value.\n* \n* When using `asCallback`, call it with `await` to let generator \n* run its course before continuing:\n* ```js\n* await asCallback(tick({ interval:1000, loops:5 }), x => {\n* // Gets called 5 times, with 1000ms interval\n* });\n* console.log(`Hi`); // Prints after 5 seconds\n* ```\n* \n* Or if you skip the `await`, code continues and callback will still run:\n* ```js\n* asCallback(tick({ interval: 1000, loops: 5}), x => {\n* // Gets called 5 times, with 1000ms interval\n* });\n* console.log(`Hi`); // Prints immediately\n* ```\n* @param input \n* @param callback \n*/\nasync function asCallback(input, callback, onDone) {\n\tfor await (const value of input) callback(value);\n\tif (onDone) onDone();\n}\nasync function* slice(it, start = 0, end = Number.POSITIVE_INFINITY) {\n\tconst iit = it[Symbol.asyncIterator]();\n\tif (end < start) throw new Error(`Param 'end' should be more than 'start'`);\n\tfor (; start > 0; start--, end--) await iit.next();\n\tfor await (const v of it) if (end-- > 0) yield v;\n\telse break;\n}\n/**\n* Enumerates over an input iterable, with a delay between items.\n* @param it \n* @param delay \n*/\nasync function* withDelay(it, delay) {\n\tfor (const v of it) {\n\t\tawait sleep(delay);\n\t\tyield v;\n\t}\n}\n/***\n* Returns the next IteratorResult,\n* throwing an error if it does not happen\n* within `interval` (default: 1s)\n*/\nasync function nextWithTimeout(it, options) {\n\tconst ms = intervalToMs(options, 1e3);\n\tconst value = await Promise.race([(async () => {\n\t\tawait sleep({\n\t\t\tmillis: ms,\n\t\t\tsignal: options.signal\n\t\t});\n\t})(), (async () => {\n\t\treturn await it.next();\n\t})()]);\n\tif (value === void 0) throw new Error(`Timeout`);\n\treturn value;\n}\nasync function some(it, f) {\n\tfor await (const v of it) if (await f(v)) return true;\n\treturn false;\n}\n/**\n* Returns an array of values from an iterator.\n*\n* ```js\n* const data = await toArray(adsrIterable(opts, 10));\n* ```\n*\n* Note: If the iterator is infinite, be sure to provide limits via the options.\n* ```js\n* // Return maximum five items\n* const data = await toArray(iterable, { limit: 5 });\n* // Return results for a maximum of 5 seconds\n* const data = await toArray(iterable, { elapsed: 5000 });\n* ```\n* Note that limits are ORed, `toArray` will finish if either of them is true.\n* \n* @param it Asynchronous iterable\n* @param options Options when converting to array\n* @returns\n*/\nasync function toArray(it, options = {}) {\n\tconst result = [];\n\tconst iterator = it[Symbol.asyncIterator]();\n\tconst started = Date.now();\n\tconst maxItems = options.limit ?? Number.POSITIVE_INFINITY;\n\tconst whileFunction = options.while;\n\tconst maxElapsed = intervalToMs(options.elapsed, Number.POSITIVE_INFINITY);\n\twhile (result.length < maxItems && Date.now() - started < maxElapsed) {\n\t\tif (whileFunction) {\n\t\t\tif (!whileFunction(result.length)) break;\n\t\t}\n\t\tconst r = await iterator.next();\n\t\tif (r.done) break;\n\t\tresult.push(r.value);\n\t}\n\treturn result;\n}\nasync function* unique(iterable) {\n\tconst buffer = [];\n\tconst itera = Array.isArray(iterable) ? iterable : [iterable];\n\tfor await (const it of itera) for await (const v of it) {\n\t\tif (buffer.includes(v)) continue;\n\t\tbuffer.push(v);\n\t\tyield v;\n\t}\n}\nasync function* uniqueByValue(input, toString = toStringDefault, seen = /* @__PURE__ */ new Set()) {\n\tfor await (const v of input) {\n\t\tconst key = toString(v);\n\t\tif (seen.has(key)) continue;\n\t\tseen.add(key);\n\t\tyield v;\n\t}\n}\n/**\n* Returns unique items from iterables, given a particular key function\n* ```js\n* unique([{i:0,v:2},{i:1,v:3},{i:2,v:2}], e => e.v);\n* Yields: [{i:0,v:2},{i:1,v:3}]\n* @param it\n* @param f\n*/\n/**\n* Combine same-positioned items from several iterables\n* ```js\n* zip( [1, 2, 3], [4, 5, 6], [7, 8, 9] );\n* Yields: [ [1, 4, 7], [2, 5, 8], [3, 6, 9] ]\n* ```\n* @param its\n* @returns\n*/\nasync function* zip(...its) {\n\tconst iits = its.map((it) => it[Symbol.asyncIterator]());\n\twhile (true) {\n\t\tconst vs = await Promise.all(iits.map((it) => it.next()));\n\t\tif (vs.some((v) => v.done)) return;\n\t\tyield vs.map((v) => v.value);\n\t}\n}\n//#endregion\nexport { asCallback, chunks, concat, dropWhile, equals, every, fill, filter, find, flatten, forEach, fromArray, fromIterable, last, map, max, min, nextWithTimeout, reduce, repeat, slice, some, async_exports as t, toArray, unique, uniqueByValue, until, withDelay, zip };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { n as isIterable, t as isAsyncIterable } from \"./guard-COHp1bP0.js\";\nimport { A as reduce$2, C as sync_exports, D as until$1, E as uniqueByValue$1, S as some$1, T as unique$1, _ as map$1, a as dropWhile$1, c as fill$1, f as flatten$1, g as last$1, h as fromIterable$1, i as concat$1, j as slice$1, k as zip$1, l as filter$2, m as fromArray$1, n as chunks$1, o as equals$1, p as forEach$1, s as every$1, t as asCallback$2, u as find$1, v as max$2, w as toArray$1, y as min$2 } from \"./sync-CP_0yIYe.js\";\nimport { asCallback as asCallback$3, chunks as chunks$2, concat as concat$2, dropWhile as dropWhile$2, equals as equals$2, every as every$2, fill as fill$2, filter as filter$3, find as find$2, flatten as flatten$2, forEach as forEach$2, fromArray as fromArray$2, fromIterable as fromIterable$2, last as last$2, map as map$2, max as max$3, min as min$3, nextWithTimeout, reduce as reduce$3, slice as slice$2, some as some$2, t as async_exports, toArray as toArray$2, unique as unique$2, uniqueByValue as uniqueByValue$2, until as until$2, zip as zip$2 } from \"./async.js\";\nimport { compareIterableValuesShallow, elapsedSince, intervalToMs, isEqualValueIgnoreOrder, promiseFromEvent, sleep, toStringDefault } from \"@ixfx/core\";\nimport { integerTest, resultThrow } from \"@ixfx/guards\";\nimport * as BasicProcessors from \"@ixfx/process/basic\";\nimport { isEqual } from \"@ixfx/arrays\";\nimport * as MapFns from \"@ixfx/core/maps\";\nimport { continuously } from \"@ixfx/core/continuously\";\nimport { numberArrayCompute } from \"@ixfx/numbers\";\n//#region src/chain/utility.ts\nfunction isGenFactoryNoInput(c) {\n\tif (typeof c !== `object` || c === null) return false;\n\tif (!(`_type` in c)) return false;\n\tif (c._type === `GenFactoryNoInput`) return true;\n\treturn false;\n}\n/**\n* Wrap the primitive value as generator\n* @param value \n*/\nfunction* primitiveToGenerator(value) {\n\tyield value;\n}\n/**\n* Wrap the primitive value as an async generator\n* @param value \n*/\nasync function* primitiveToAsyncGenerator(value) {\n\tyield value;\n\tawait sleep(1);\n}\n/**\n* Resolve the array, data or function to a Generator\n* @param input \n* @returns \n*/\nfunction resolveToGen(input) {\n\tif (Array.isArray(input)) {\n\t\tconst a = input.values();\n\t\ta._name = `arrayInput`;\n\t\treturn a;\n\t} else if (typeof input === `number` || typeof input === `boolean` || typeof input === `string`) return primitiveToGenerator(input);\n\telse if (typeof input === `function`) return input();\n\treturn input;\n}\n/**\n* Resolve the data, primitive or function to an AsyncGenerator\n* @param input \n* @returns \n*/\nfunction resolveToAsyncGen(input) {\n\tif (input === void 0) return;\n\tif (Array.isArray(input)) return fromArray$2(input);\n\telse if (typeof input === `number` || typeof input === `boolean` || typeof input === `string`) return primitiveToAsyncGenerator(input);\n\telse if (typeof input === `function`) return input();\n\telse if (isAsyncIterable(input)) return input;\n\treturn fromIterable$2(input);\n}\n//#endregion\n//#region src/util/dom.ts\nfunction resolveEl(elOrQuery) {\n\tif (typeof elOrQuery === `string`) {\n\t\tconst el = document.querySelector(elOrQuery);\n\t\tif (!el) throw new Error(`Element not found '${elOrQuery}'`);\n\t\treturn el;\n\t}\n\treturn elOrQuery;\n}\n//#endregion\n//#region src/chain/dom.ts\nvar dom_exports = /* @__PURE__ */ __exportAll({\n\tperValue: () => perValue,\n\tquery: () => query\n});\nconst createMap = (key) => {\n\tconst keyFunction = key ?? ((value) => value);\n\tconst map = /* @__PURE__ */ new Map();\n\treturn {\n\t\thas(key) {\n\t\t\treturn map.has(keyFunction(key));\n\t\t},\n\t\tget(key) {\n\t\t\treturn map.get(keyFunction(key));\n\t\t},\n\t\tset(key, value) {\n\t\t\tmap.set(keyFunction(key), value);\n\t\t},\n\t\tentries() {\n\t\t\treturn map.entries();\n\t\t},\n\t\tdelete(key) {\n\t\t\tmap.delete(key);\n\t\t}\n\t};\n};\n/**\n* Creates a HTML element per value. By default compares\n* values by `JSON.stringify`. Set `byReference:true` to\n* compare values based on reference. Or provide a toString\n* function via `key`.\n* \n* ```js\n* // Generate a random number between 0...4 every second\n* const looper = Generators.interval(() => Math.floor(Math.random()*5), 1000);\n* \n* // Make a chain\n* const ch = Chains.run(\n* looper,\n* Chains.Links.delay({before:1000}),\n* Chains.Dom.perValue()\n* );\n*\n* setTimeout(async () => {\n* for await (const v of ch) {\n* const {el,value} = v;\n* el.textContent = `${value} - ${Date.now().toString()}`;\n* }\n* console.log(`ch iteration done`);\n* });\n* ```\n*/\nfunction perValue(options = {}) {\n\tconst byReference = options.byReference;\n\tconst tagName = options.tagName ?? `div`;\n\tif (byReference && options.key) throw new Error(`byReference and key options are mutually exclusive`);\n\tconst map = createMap(byReference ? void 0 : options.key ?? toStringDefault);\n\tconst parentEl = resolveEl(options.parentEl ?? document.body);\n\tconst usedElements = /* @__PURE__ */ new Set();\n\tasync function* perValue(input) {\n\t\tfor await (const value of resolveToGen(input)) {\n\t\t\tlet el = map.get(value);\n\t\t\tif (!el) {\n\t\t\t\tel = document.createElement(tagName);\n\t\t\t\tmap.set(value, el);\n\t\t\t\tif (options.beforeInsert) options.beforeInsert(el);\n\t\t\t\tparentEl.append(el);\n\t\t\t\tif (options.afterInsert) options.afterInsert(el);\n\t\t\t}\n\t\t\tusedElements.add(el);\n\t\t\tyield {\n\t\t\t\tel,\n\t\t\t\tvalue\n\t\t\t};\n\t\t}\n\t\tfor (const [id, el] of map.entries()) {\n\t\t\tif (usedElements.has(el)) continue;\n\t\t\tif (options.beforeRemove) options.beforeRemove(el);\n\t\t\tel.remove();\n\t\t\tmap.delete(id);\n\t\t}\n\t}\n\tperValue._name = `dom.perValue`;\n\treturn perValue;\n}\n/**\n* From an input stream of strings, yields an output of HTMLElememnts\n* @param options \n* @returns \n*/\nfunction query(options = {}) {\n\tconst baseElement = options.baseElement ?? document;\n\tasync function* query(input) {\n\t\tconst gen = resolveToGen(input);\n\t\tfor await (const value of gen) for (const element of baseElement.querySelectorAll(value)) yield element;\n\t}\n\tquery._name = `dom.query`;\n\treturn query;\n}\n//#endregion\n//#region src/chain/links.ts\nvar links_exports = /* @__PURE__ */ __exportAll({\n\taverage: () => average,\n\tchunk: () => chunk,\n\tdebounce: () => debounce,\n\tdelay: () => delay,\n\tdrop: () => drop,\n\tduration: () => duration,\n\tfilter: () => filter$1,\n\tmax: () => max$1,\n\tmin: () => min$1,\n\trank: () => rank,\n\trankArray: () => rankArray,\n\treduce: () => reduce$1,\n\tsum: () => sum,\n\ttake: () => take,\n\ttally: () => tally,\n\ttransform: () => transform\n});\n/**\n* Transform values from one type to another. Just like a map function.\n* @param transformer \n* @returns \n*/\nfunction transform(transformer) {\n\tasync function* transform(input) {\n\t\tinput = resolveToGen(input);\n\t\tfor await (const value of input) yield transformer(value);\n\t}\n\ttransform._name = `transform`;\n\treturn transform;\n}\n/**\n* Take `limit` number of results from the stream, before closing\n* @param limit \n* @returns \n*/\nfunction take(limit) {\n\tasync function* take(input) {\n\t\tinput = resolveToGen(input);\n\t\tlet yielded = 0;\n\t\tfor await (const value of input) {\n\t\t\tif (++yielded > limit) break;\n\t\t\tyield value;\n\t\t}\n\t}\n\ttake._name = `take`;\n\treturn take;\n}\n/**\n* Takes an array of values, flattening to a single one\n* using the provided `reducer` function.\n* \n* ```js\n* // Create a chain that flattens values\n* const reduce = Chains.reduce(values => Math.max(...values));\n* // Feed it a single input (an array), get a single output back:\n* const result = await Chains.single(reduce, [ 1, 2, 3]); // 3\n* ```\n* @param reducer Function to reduce array of values to a single value\n* @returns \n*/\nfunction reduce$1(reducer) {\n\tasync function* reduce(input) {\n\t\tinput = resolveToGen(input);\n\t\tfor await (const value of input) yield reducer(value);\n\t}\n\treduce._name = `reduce`;\n\treturn reduce;\n}\n/**\n* Allow values through until a duration has elapsed. After\n* that, the chain stops.\n* @param elapsed \n* @returns \n*/\nfunction duration(elapsed) {\n\tconst durationMs = intervalToMs(elapsed, 0);\n\tasync function* duration(input) {\n\t\tinput = resolveToGen(input);\n\t\tconst elapsed = elapsedSince();\n\t\tfor await (const value of input) {\n\t\t\tif (elapsed() > durationMs) break;\n\t\t\tyield value;\n\t\t}\n\t}\n\tduration._name = `duration`;\n\treturn duration;\n}\n/**\n* Add delay before/after values are emitted from the input stream.\n* @param options \n* @returns \n*/\nfunction delay(options) {\n\tconst before = intervalToMs(options.before, 0);\n\tconst after = intervalToMs(options.after, 0);\n\tasync function* delay(input) {\n\t\tinput = resolveToGen(input);\n\t\tfor await (const value of input) {\n\t\t\tif (before > 0) await sleep(before);\n\t\t\tyield value;\n\t\t\tif (after > 0) await sleep(after);\n\t\t}\n\t}\n\tdelay._name = `delay`;\n\treturn delay;\n}\n/**\n* Ensure a minimum length of time between values.\n* Values being produced too quickly are dropped.\n* \n* In the following example, only three values will be let through.\n* ```js\n* const chain = Chains.run(\n* // Produce values every 10ms for 350ms\n* Chains.From.timestamp({ interval: 10, elapsed: 350 }),\n* // Only let a value through every 100ms\n* Chains.Links.debounce(100)\n* );\n* ```\n* @param rate \n* @returns \n*/\nfunction debounce(rate) {\n\tconst rateMs = intervalToMs(rate, 0);\n\tasync function* debounce(input) {\n\t\tinput = resolveToGen(input);\n\t\tlet elapsed = elapsedSince();\n\t\tfor await (const value of input) {\n\t\t\tif (elapsed() < rateMs) continue;\n\t\t\tyield value;\n\t\t\telapsed = elapsedSince();\n\t\t}\n\t}\n\tdebounce._name = `debounce`;\n\treturn debounce;\n}\n/**\n* Returns a running tally of how many items have been\n* emitted from the input source.\n* ```js\n* const ch = Chains.run(\n* Chains.From.timestamp({ interval: 100 }),\n* Chains.Links.tally()\n* );\n* \n* for await (const v of ch) {\n* // Produces: 1, 2, 3 ... every 100ms\n* }\n* ```\n* This is different than {@link sum} which adds up numeric values.\n* By default it adds up individual array items\n* @returns \n*/\nfunction tally(countArrayItems = true) {\n\tasync function* tally(input) {\n\t\tinput = resolveToGen(input);\n\t\tconst p = BasicProcessors.tally(countArrayItems);\n\t\tfor await (const v of input) yield p(v);\n\t}\n\ttally._name = `tally`;\n\treturn tally;\n}\n/**\n* Returns the smallest value from the input.\n* Can work with numbers or number[] as input.\n* Non-numeric data is filtered out.\n* @returns \n*/\nfunction min$1() {\n\tasync function* min(input) {\n\t\tinput = resolveToGen(input);\n\t\tconst p = BasicProcessors.min();\n\t\tfor await (const value of input) {\n\t\t\tconst x = p(value);\n\t\t\tif (x === void 0) continue;\n\t\t\tyield x;\n\t\t}\n\t}\n\tmin._name = `min`;\n\treturn min;\n}\n/**\n* Returns the largest value from the input.\n* - Non-numeric data is filtered out.\n* - Looks inside of numeric arrays.\n* @returns \n*/\nfunction max$1() {\n\tasync function* max(input) {\n\t\tinput = resolveToGen(input);\n\t\tconst p = BasicProcessors.max();\n\t\tfor await (const value of input) {\n\t\t\tconst x = p(value);\n\t\t\tif (x === void 0) continue;\n\t\t\tyield x;\n\t\t}\n\t}\n\tmax._name = `max`;\n\treturn max;\n}\n/**\n* Emits the currently ranked 'highest' value from a stream. Only\n* values exceeding the current highest are emitted.\n* \n* eg, if we are ranking on numerical value, an input stream of:\n* ```\n* 4, 1, 6, 10, 2, 4\n* ```\n* \n* Results in the output stream of:\n* ```\n* 4, 6, 10\n* ```\n* \n* @example \n* ```js\n* // Rank based on a field\n* Chains.Links.rank((a,b) => {\n* if (a.size > b.size) return `a`; // Signals the first param is highest\n* if (a.size < b.size) return `b`; // Signals the second param is highest\n* return `eq`;\n* });\n* ```\n* @param options \n* @returns \n*/\nfunction rank(r, options = {}) {\n\tasync function* rank(input) {\n\t\tinput = resolveToGen(input);\n\t\tconst p = BasicProcessors.rank(r, options);\n\t\tfor await (const value of input) {\n\t\t\tconst x = p(value);\n\t\t\tif (x === void 0) continue;\n\t\t\tyield x;\n\t\t}\n\t}\n\trank._name = `rank`;\n\treturn rank;\n}\n/**\n* Emits the highest-ranked value from amongst an array of values.\n* \n* By default, it tracks the highest-ranked _between_ arrays.\n* \n* For example:\n* ```js\n* // Input\n* [ [4,5,6], [1,2,3] ]\n* // Outputs:\n* [ 6 ]\n* ```\n* \n* This behaviour can be modified with an option to only compare _within_ arrays.\n* ```\n* // Input\n* [ [4,5,6], [1,2,3] ]\n* // Output:\n* [ 6, 3 ]\n* ```\n* \n* Uses the `rank` option to determine which is more highly ranked.\n* ```js\n* Chains.Links.rankArray(\n* (a, b) => {\n* if (a > b) return `a`; // a is higher\n* else if (b > a) return `b`; // b is higher\n* return `eq`; // same\n* }\n* )\n* ```\n* @param options \n* @returns \n*/\nfunction rankArray(r, options = {}) {\n\tconst includeType = options.includeType;\n\tconst emitEqualRanked = options.emitEqualRanked ?? false;\n\tconst emitRepeatHighest = options.emitRepeatHighest ?? false;\n\tconst withinArrays = options.withinArrays ?? false;\n\tasync function* rankArray(input) {\n\t\tinput = resolveToGen(input);\n\t\tlet best;\n\t\tfor await (const value of input) {\n\t\t\tlet emit = false;\n\t\t\tif (withinArrays) best = void 0;\n\t\t\tfor (const subValue of value) {\n\t\t\t\tif (includeType && typeof subValue !== includeType) continue;\n\t\t\t\tif (best === void 0) {\n\t\t\t\t\tbest = subValue;\n\t\t\t\t\temit = true;\n\t\t\t\t} else {\n\t\t\t\t\tconst result = r(subValue, best);\n\t\t\t\t\tif (result == `a`) {\n\t\t\t\t\t\tbest = subValue;\n\t\t\t\t\t\temit = true;\n\t\t\t\t\t} else if (result === `eq` && emitEqualRanked) emit = true;\n\t\t\t\t\telse if (emitRepeatHighest) emit = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (emit && best) yield best;\n\t\t}\n\t}\n\trankArray._name = `rankArray`;\n\treturn rankArray;\n}\n/**\n* Returns the average from the input.\n* Non-numeric values are filtered out.\n* @returns \n*/\nfunction average() {\n\tasync function* average(input) {\n\t\tinput = resolveToGen(input);\n\t\tconst p = BasicProcessors.average();\n\t\tfor await (const value of input) {\n\t\t\tconst x = p(value);\n\t\t\tif (x === void 0) continue;\n\t\t\tyield x;\n\t\t}\n\t}\n\taverage._name = `average`;\n\treturn average;\n}\n/**\n* Returns the total of the numeric values.\n* Non-numeric values are filtered out.\n* @returns \n*/\nfunction sum() {\n\tasync function* total(input) {\n\t\tinput = resolveToGen(input);\n\t\tconst p = BasicProcessors.sum();\n\t\tfor await (const value of input) {\n\t\t\tconst x = p(value);\n\t\t\tif (x === void 0) continue;\n\t\t\tyield x;\n\t\t}\n\t}\n\ttotal._name = `total`;\n\treturn total;\n}\n/**\n* Chunks an input stream into `size` chunks.\n* \n* Eg, with a chunk size of 3, the input stream of:\n* 1, 2, 3, 4, 5, 6\n* Yields:\n* [ 1, 2, 3 ], [ 4, 5, 6 ]\n* \n* If `returnRemainders` is _true_ (default), any left over values are returned even if\n* it's less than `size`.\n* @param size \n* @param returnRemainders If true (default) left over data that didn't make a full chunk is also returned\n* @returns \n*/\nfunction chunk(size, returnRemainders = true) {\n\tresultThrow(integerTest(size, `aboveZero`, `size`));\n\tasync function* chunk(input) {\n\t\tinput = resolveToGen(input);\n\t\tlet buffer = [];\n\t\tfor await (const value of input) {\n\t\t\tbuffer.push(value);\n\t\t\tif (buffer.length >= size) {\n\t\t\t\tyield buffer;\n\t\t\t\tbuffer = [];\n\t\t\t}\n\t\t}\n\t\tif (returnRemainders && buffer.length > 0) yield buffer;\n\t}\n\tchunk._name = `chunk`;\n\treturn chunk;\n}\n/**\n* Filters the input source, only allowing through\n* data for which `predicate` returns _true_\n* \n* {@link drop}, on the other hand excludes values for which predicate is _true_\n* @param predicate \n* @returns \n*/\nfunction filter$1(predicate) {\n\tasync function* filter(input) {\n\t\tinput = resolveToGen(input);\n\t\tfor await (const value of input) if (predicate(value)) yield value;\n\t}\n\tfilter._name = `filter`;\n\treturn filter;\n}\n/**\n* Drops all values from input stream for which `predicate` returns _true_\n* \n* {@link filter}, on the other hand includes values where the predicate is _true_\n* @param predicate \n* @returns \n*/\nfunction drop(predicate) {\n\tasync function* drop(input) {\n\t\tinput = resolveToGen(input);\n\t\tfor await (const value of input) if (!predicate(value)) yield value;\n\t}\n\tdrop._name = `drop`;\n\treturn drop;\n}\n//#endregion\n//#region src/chain/from/array.ts\n/**\n* Creates a chain from an array, reading values at a given interval\n* @param it \n* @param delay \n* @returns \n*/\nfunction array(it, delay = 5) {\n\tasync function* fromArray() {\n\t\tfor (const v of it) {\n\t\t\tawait sleep(delay);\n\t\t\tyield v;\n\t\t}\n\t}\n\tfromArray._name = `fromArray`;\n\tfromArray._type = `GenFactoryNoInput`;\n\treturn fromArray;\n}\n//#endregion\n//#region src/chain/from/event.ts\n/**\n* Create an iterable from an event\n* @param target Event source (eg HTML element)\n* @param name Name of event (eg. 'pointermove')\n* @returns \n*/\nfunction event(target, name) {\n\tasync function* event() {\n\t\twhile (true) yield await promiseFromEvent(target, name);\n\t}\n\tevent._name = `event`;\n\tevent._type = `GenFactoryNoInput`;\n\treturn event;\n}\n//#endregion\n//#region src/chain/from/function.ts\n/**\n* Produce a value from a callback. When\n* the callback returns _undefined_ it is considered done.\n* \n* ```js\n* const callback = () => Math.random();\n* \n* const f = Chains.From.func(callback);\n* for await (const v of f) {\n* // v is a new random number\n* }\n* ```\n* \n* In the context of a chain:\n* ```js\n* let produced = 0;\n* const chain = Chains.chain<number, string>(\n* // Produce incrementing numbers\n* Chains.From.func(() => produced++),\n* // Convert to `x:0`, `x:1` ...\n* Chains.transform(v => `x:${ v }`),\n* // Take first 5 results\n* Chains.cap(5)\n* );\n* const data = await Chains.asArray(chain);\n* ```\n* @param callback \n* @returns \n*/\nfunction func(callback) {\n\tasync function* fromFunction() {\n\t\twhile (true) {\n\t\t\tconst v = await callback();\n\t\t\tif (typeof v === `undefined`) break;\n\t\t\tyield v;\n\t\t}\n\t}\n\tfromFunction._name = `fromFunction`;\n\tfromFunction._type = `GenFactoryNoInput`;\n\treturn fromFunction;\n}\n//#endregion\n//#region src/chain/from/iterable.ts\n/**\n* Creates a chain from an interable\n* @param it \n* @returns \n*/\nfunction iterable(it) {\n\tasync function* fromIterable() {\n\t\tfor await (const v of it) yield v;\n\t}\n\tfromIterable._name = `fromIterable`;\n\tfromIterable._type = `GenFactoryNoInput`;\n\treturn fromIterable;\n}\n//#endregion\n//#region src/chain/from/ticks.ts\n/**\n* Generate timestamp values at `interval` rate. By default it runs forever. \n* Use `loops` or `elapsed` to set upper limit on how long it should run.\n* \n* ```js\n* const c = Chains.From.timestamp({ interval: 1000 });\n* ```\n* Options:\n* - `asClockTime`: If _true_, yielded value will be clock time rather than elapsed milliseconds\n* @param options \n* @returns \n*/\nfunction timestamp(options) {\n\tconst intervalMs = intervalToMs(options.interval, 0);\n\tconst asClockTime = options.asClockTime ?? false;\n\tconst loops = options.loops ?? Number.MAX_SAFE_INTEGER;\n\tlet looped = 0;\n\tconst durationTime = intervalToMs(options.elapsed, Number.MAX_SAFE_INTEGER);\n\tasync function* ts() {\n\t\tconst elapsed = elapsedSince();\n\t\twhile (looped < loops && elapsed() < durationTime) {\n\t\t\tyield asClockTime ? Date.now() : elapsed();\n\t\t\tconst expectedTimeDiff = looped * intervalMs - elapsed();\n\t\t\tawait sleep(Math.max(0, intervalMs + expectedTimeDiff));\n\t\t\tlooped++;\n\t\t}\n\t}\n\tts._name = `timestamp`;\n\tts._type = `GenFactoryNoInput`;\n\treturn ts;\n}\n//#endregion\n//#region src/chain/from/index.ts\nvar from_exports = /* @__PURE__ */ __exportAll({\n\tarray: () => array,\n\tevent: () => event,\n\tfunc: () => func,\n\titerable: () => iterable,\n\ttimestamp: () => timestamp\n});\n//#endregion\n//#region src/chain/add-to-array.ts\n/**\n* Adds values to the provided array as they are produced,\n* mutating array.\n* \n* ```js\n* const data = [];\n* addToArray(data, tick({ interval: 1000, loops: 5 }));\n* // Execution continues immediately, with `data` mutated over time\n* ```\n* @param valueToWrap \n* @param array \n*/\nasync function addToArray(array, valueToWrap) {\n\tconst outputType = typeof valueToWrap === `function` ? valueToWrap() : valueToWrap;\n\tfor await (const value of outputType) array.push(value);\n}\n//#endregion\n//#region src/chain/as-array.ts\n/**\n* Async function that returns the chain as an array of values\n* ```js\n* const values = await asArray(tick( { interval: 1000, loops: 5 }));\n* // After 5 seconds, values will be a set of timestamps.\n* ```\n* \n* If the chain is infinite, be sure to specify limits:\n* ```js\n* // Stop after we have five items\n* const values = await asArray(chain, { limit: 5 });\n* // Stop after 5 seconds has elapsed\n* const values = await asArray(chain, { elapsed: 5000 });\n* ```\n* @param valueToWrap \n* @returns \n*/\nasync function asArray(valueToWrap, options = {}) {\n\treturn toArray$2(typeof valueToWrap === `function` ? valueToWrap() : valueToWrap, options);\n}\n//#endregion\n//#region src/chain/as-callback.ts\n/**\n* Calls `callback` whenever the chain/generator produces a value.\n* \n* When using `asCallback`, call it with `await` to let generator \n* run its course before continuing:\n* ```js\n* await asCallback(tick({ interval:1000, loops:5 }), x => {\n* // Gets called 5 times, with 1000ms interval\n* });\n* console.log(`Hi`); // Prints after 5 seconds\n* ```\n* \n* Or if you skip the `await`, code continues and callback will still run:\n* ```js\n* asCallback(tick({ interval: 1000, loops: 5}), x => {\n* // Gets called 5 times, with 1000ms interval\n* });\n* console.log(`Hi`); // Prints immediately\n* ```\n* @param valueToWrap \n* @param callback \n*/\nasync function asCallback$1(valueToWrap, callback, onDone) {\n\tconst outputType = typeof valueToWrap === `function` ? valueToWrap() : valueToWrap;\n\tfor await (const value of outputType) callback(value);\n\tif (onDone) onDone();\n}\n//#endregion\n//#region src/chain/as-promise.ts\n/**\n* Treats the chain/generator as a promise\n* \n* ```js\n* const ticker = asPromise(tick({ interval: 1000 }));\n* const x = await ticker(); // Waits for 1000ms before giving a value\n* ```\n* \n* This will only ever return one value. To return multiple values, it's necessary\n* to call `asPromise` and `await` the result in a loop.\n* @param valueToWrap \n* @returns \n*/\nfunction asPromise(valueToWrap) {\n\tlet lastValue;\n\tconst outputType = typeof valueToWrap === `function` ? valueToWrap() : valueToWrap;\n\tasync function asPromise() {\n\t\tconst v = await outputType.next();\n\t\tif (v.done) return;\n\t\tlastValue = v.value;\n\t\treturn lastValue;\n\t}\n\treturn asPromise;\n}\n//#endregion\n//#region src/chain/as-value.ts\n/**\n* Returns the most recent value from the chain/generator, or\n* `initialValue` (defaulting to _undefined_) if no value\n* has been emitted yet.\n* \n* ```js\n* const ticker = asValue(tick({ interval: 1000 }));\n* x = ticker(); // Get the most recent value\n* ```\n* \n* Every time it's called, it fetches a new value from the generator, assuming\n* it isn't already awaiting a result.\n* \n* In the meantime, the last value (or `initialValue`) is returned.\n* @param valueToWrap Value to wrap\n* @param initialValue Initial value\n* @returns \n*/\nfunction asValue(valueToWrap, initialValue) {\n\tlet lastValue = initialValue;\n\tlet awaiting = false;\n\tconst outputType = typeof valueToWrap === `function` ? valueToWrap() : valueToWrap;\n\tfunction asValue() {\n\t\tif (!awaiting) {\n\t\t\tawaiting = true;\n\t\t\toutputType.next().then((v) => {\n\t\t\t\tlastValue = v.value;\n\t\t\t\tawaiting = false;\n\t\t\t}).catch((error) => {\n\t\t\t\tawaiting = false;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t}\n\t\treturn lastValue;\n\t}\n\treturn asValue;\n}\n//#endregion\n//#region src/chain/combine-latest-to-array.ts\n/**\n* Monitors sources, storing as they happen to an array.\n* Whenever a new value is emitted, the whole array is sent out, containing current\n* values from each source, or _undefined_ if not yet emitted.\n* \n* The tempo of this stream will be set by the fastest source stream.\n* See {@link syncToArray} to have pace determined by slowest source, and only\n* send when each source has produce a new value compared to last time.\n* \n* Set `onSourceDone` to choose behaviour if a source stops. The default is\n* 'break', meaning the whole combined stream stops.\n* \n* If a source completes and onSourceDone = 'allow', the option\n* 'finalValue' sets the logic for what values get returned for the source.\n* By default the setting is 'undefined', thus _undefined_ results. 'last' will be the last (old) value\n* from that source.\n*/\nasync function* combineLatestToArray(sources, options = {}) {\n\tconst onSourceDone = options.onSourceDone ?? `break`;\n\tconst finalValue = options.finalValue ?? `undefined`;\n\tconst afterEmit = options.afterEmit ?? `last`;\n\tconst inputs = sources.map((source, index) => ({\n\t\twaiting: void 0,\n\t\tindex,\n\t\tgen: resolveToGen(source),\n\t\tdone: false,\n\t\tlastValue: void 0\n\t}));\n\tconst isDone = () => !inputs.some((v) => !v.done);\n\tconst isWaiting = () => inputs.some((v) => v.waiting !== void 0);\n\tconst allEmpty = (d) => !d.some((v) => v !== void 0);\n\tlet lastEmitted = [];\n\twhile (true) {\n\t\tconst promises = [];\n\t\tfor (const input of inputs) {\n\t\t\tif (input.done) continue;\n\t\t\tif (input.waiting !== void 0) {\n\t\t\t\tpromises.push(input.waiting);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst p = Promise.resolve((async () => {\n\t\t\t\tif (input.done) return input;\n\t\t\t\tconst v = await input.gen.next();\n\t\t\t\tinput.waiting = void 0;\n\t\t\t\tif (v.done) {\n\t\t\t\t\tinput.done = true;\n\t\t\t\t\tif (finalValue === `undefined`) input.lastValue = void 0;\n\t\t\t\t} else input.lastValue = v.value;\n\t\t\t\treturn input;\n\t\t\t})());\n\t\t\tinput.waiting = p;\n\t\t\tpromises.push(p);\n\t\t}\n\t\tconst won = await Promise.race(promises);\n\t\tif (`done` in won) {\n\t\t\tif (won.done && onSourceDone === `break`) break;\n\t\t} else throw new Error(`Missing 'done' property`);\n\t\tconst d = inputs.map((v) => v.lastValue);\n\t\tif (d.length === 0) return;\n\t\tconst dataEmpty = allEmpty(d);\n\t\tif (dataEmpty && !isWaiting()) return;\n\t\tif (!isEqual(lastEmitted, d) && !dataEmpty) {\n\t\t\tlastEmitted = d;\n\t\t\tyield d;\n\t\t}\n\t\tif (afterEmit === `undefined`) for (const input of inputs) {\n\t\t\tif (input.waiting !== void 0) continue;\n\t\t\tinput.lastValue = void 0;\n\t\t}\n\t\tif (isDone()) break;\n\t}\n}\n//#endregion\n//#region src/chain/combine-latest-to-object.ts\n/**\n* Monitors sources, storing as they happen to an object.\n* Whenever a new value is emitted, the object is sent out, containing current\n* values from each source, or _undefined_ if not yet emitted.\n* \n* The tempo of this stream will be set by the fastest source stream.\n* See {@link syncToObject} to have pace determined by slowest source, and only\n* send when each source has produce a new value compared to last time.\n* \n* Set `onSourceDone` to choose behaviour if a source stops. By default it\n* is 'break', meaning the whole merged stream stops.\n* \n* If a source completes and onSourceDone = 'allow', the option\n* 'finalValue' sets the logic for what values get returned for the source.\n* By default the setting is 'undefined', thus _undefined_ results. 'last' will be the last (old) value\n* from that source.\n*/\nasync function* combineLatestToObject(sources, options = {}) {\n\tconst onSourceDone = options.onSourceDone ?? `break`;\n\tconst finalValue = options.finalValue ?? `undefined`;\n\tconst afterEmit = options.afterEmit ?? `last`;\n\tconst states = /* @__PURE__ */ new Map();\n\tfor (const [key, value] of Object.entries(sources)) states.set(key, {\n\t\tgen: resolveToGen(value),\n\t\tdone: false,\n\t\tlastValue: void 0,\n\t\twaiting: void 0,\n\t\tkey\n\t});\n\tconst isDone = () => !MapFns.some(states, (v) => !v.done);\n\tconst isWaiting = () => MapFns.some(states, (v) => v.waiting !== void 0);\n\tconst allEmpty = (d) => {\n\t\tfor (const v of Object.values(d)) if (v !== void 0) return false;\n\t\treturn true;\n\t};\n\tconst getData = () => {\n\t\tconst r = {};\n\t\tfor (const [key, state] of states) r[key] = state.lastValue;\n\t\treturn r;\n\t};\n\tlet lastEmitted;\n\twhile (true) {\n\t\tconst promises = [];\n\t\tfor (const input of states.values()) {\n\t\t\tif (input.done) continue;\n\t\t\tif (input.waiting !== void 0) {\n\t\t\t\tpromises.push(input.waiting);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst p = Promise.resolve((async () => {\n\t\t\t\tif (input.done) return input;\n\t\t\t\tconst v = await input.gen.next();\n\t\t\t\tinput.waiting = void 0;\n\t\t\t\tif (v.done) {\n\t\t\t\t\tinput.done = true;\n\t\t\t\t\tif (finalValue === `undefined`) input.lastValue = void 0;\n\t\t\t\t} else input.lastValue = v.value;\n\t\t\t\treturn input;\n\t\t\t})());\n\t\t\tinput.waiting = p;\n\t\t\tpromises.push(p);\n\t\t}\n\t\tconst won = await Promise.race(promises);\n\t\tif (`done` in won) {\n\t\t\tif (won.done && onSourceDone === `break`) break;\n\t\t} else throw new Error(`Result missing 'done' property`);\n\t\tconst d = getData();\n\t\tconst dataEmpty = allEmpty(d);\n\t\tif (dataEmpty && !isWaiting()) return;\n\t\tif (!isEqualValueIgnoreOrder(lastEmitted, d) && !dataEmpty) {\n\t\t\tlastEmitted = d;\n\t\t\tyield d;\n\t\t}\n\t\tif (afterEmit === `undefined`) for (const input of states.values()) {\n\t\t\tif (input.waiting !== void 0) continue;\n\t\t\tinput.lastValue = void 0;\n\t\t}\n\t\tif (isDone()) break;\n\t}\n}\n//#endregion\n//#region src/chain/lazy.ts\nconst getLinkName = (c) => {\n\treturn c._name ?? c.name;\n};\nfunction lazy() {\n\tconst chained = [];\n\tlet dataToUse;\n\tconst asGenerator = (data) => {\n\t\tif (data === void 0) data = dataToUse;\n\t\tlet d = resolveToAsyncGen(data);\n\t\tfor (const c of chained) if (d === void 0) if (isGenFactoryNoInput(c)) d = c();\n\t\telse throw new Error(`Function '${getLinkName(c)}' requires input. Provide it to the function, or call 'input' earlier.`);\n\t\telse d = c(d);\n\t\treturn d;\n\t};\n\tconst w = {\n\t\trankArray: (r, options) => {\n\t\t\tchained.push(rankArray(r, options));\n\t\t\treturn w;\n\t\t},\n\t\trank: (r, options) => {\n\t\t\tchained.push(rank(r, options));\n\t\t\treturn w;\n\t\t},\n\t\ttransform: (transformer) => {\n\t\t\tchained.push(transform(transformer));\n\t\t\treturn w;\n\t\t},\n\t\treduce: (reducer) => {\n\t\t\tchained.push(reduce$1(reducer));\n\t\t\treturn w;\n\t\t},\n\t\tdrop: (predicate) => {\n\t\t\tchained.push(drop(predicate));\n\t\t\treturn w;\n\t\t},\n\t\tdelay: (options) => {\n\t\t\tchained.push(delay(options));\n\t\t\treturn w;\n\t\t},\n\t\tduration: (elapsed) => {\n\t\t\tchained.push(duration(elapsed));\n\t\t\treturn w;\n\t\t},\n\t\tdebounce: (rate) => {\n\t\t\tchained.push(debounce(rate));\n\t\t\treturn w;\n\t\t},\n\t\tfromFunction: (callback) => {\n\t\t\tchained.push(func(callback));\n\t\t\treturn w;\n\t\t},\n\t\ttake: (limit) => {\n\t\t\tchained.push(take(limit));\n\t\t\treturn w;\n\t\t},\n\t\tchunk: (size, returnRemainders = true) => {\n\t\t\tchained.push(chunk(size, returnRemainders));\n\t\t\treturn w;\n\t\t},\n\t\tfilter: (predicate) => {\n\t\t\tchained.push(filter$1((v) => predicate(v)));\n\t\t\treturn w;\n\t\t},\n\t\tmin: () => {\n\t\t\tchained.push(min$1());\n\t\t\treturn w;\n\t\t},\n\t\tmax: () => {\n\t\t\tchained.push(max$1());\n\t\t\treturn w;\n\t\t},\n\t\taverage: () => {\n\t\t\tchained.push(average());\n\t\t\treturn w;\n\t\t},\n\t\tsum: () => {\n\t\t\tchained.push(sum());\n\t\t\treturn w;\n\t\t},\n\t\ttally: (countArrayItems) => {\n\t\t\tchained.push(tally(countArrayItems));\n\t\t\treturn w;\n\t\t},\n\t\tinput(data) {\n\t\t\tdataToUse = data;\n\t\t\treturn w;\n\t\t},\n\t\tasGenerator,\n\t\tasAsync(data) {\n\t\t\tlet d = data ?? dataToUse;\n\t\t\tfor (const c of chained) if (d === void 0 && isGenFactoryNoInput(c)) d = c();\n\t\t\telse if (d === void 0) throw new Error(`Function '${getLinkName(c)}' needs input. Pass in data calling 'asAsync', or call 'input' earlier`);\n\t\t\telse d = c(d);\n\t\t\treturn w;\n\t\t},\n\t\tasArray: async (data) => {\n\t\t\treturn await toArray$2(asGenerator(data));\n\t\t},\n\t\tfirstOutput: async (data) => {\n\t\t\treturn (await asGenerator(data).next()).value;\n\t\t},\n\t\tlastOutput: async (data) => {\n\t\t\tconst g = asGenerator(data);\n\t\t\tlet lastValue;\n\t\t\tfor await (const v of g) lastValue = v;\n\t\t\treturn lastValue;\n\t\t}\n\t};\n\treturn w;\n}\n//#endregion\n//#region src/util/queueMutable.ts\nvar QueueMutable = class {\n\t#store = [];\n\tenqueue(data) {\n\t\tthis.#store.push(data);\n\t}\n\tdequeue() {\n\t\treturn this.#store.shift();\n\t}\n};\n//#endregion\n//#region src/chain/merge-flat.ts\n/**\n* Merge values from several sources into one stream, interleaving values.\n* When all streams are complete it finishes.\n* \n* Alternatively:\n* - {@link combineLatestToArray}/{@link combineLatestToObject} emits snapshots of all the generators, as quickly as the fastest one\n* - {@link syncToArray}/{@link syncToObject} which releases a set of results when all inputs have emitted a value\n* @param sources \n*/\nasync function* mergeFlat(...sources) {\n\tconst sourcesInput = sources.map((source) => resolveToAsyncGen(source));\n\tconst buffer = new QueueMutable();\n\tlet completed = 0;\n\tconst schedule = async (source) => {\n\t\tif (source === void 0) {\n\t\t\tcompleted++;\n\t\t\treturn;\n\t\t}\n\t\tconst x = await source.next();\n\t\tif (x.done) completed++;\n\t\telse {\n\t\t\tbuffer.enqueue(x.value);\n\t\t\tsetTimeout(() => schedule(source), 1);\n\t\t}\n\t};\n\tfor (const source of sourcesInput) setTimeout(() => schedule(source), 1);\n\tconst loopSpeed = 10;\n\tlet loopFactor = 1;\n\twhile (completed < sourcesInput.length) {\n\t\tconst d = buffer.dequeue();\n\t\tif (d === void 0) loopFactor = Math.min(loopFactor + 1, 10);\n\t\telse {\n\t\t\tyield d;\n\t\t\tloopFactor = 1;\n\t\t}\n\t\tawait sleep(loopSpeed * loopFactor);\n\t}\n}\n//#endregion\n//#region src/chain/run.ts\n/**\n* Chain functions together. First argument is the source.\n* `runN` takes any number of chain functions. Use {@link run} if\n* possible, because it has improved type hinting.\n* \n* @example Process an array of strings. Transforming into\n* integers, and then filtering only even numbers.\n* ```js\n* const ch = Chains.runN(\n* [ `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10` ],\n* Chains.transform<string, number>(v => Number.parseInt(v)),\n* Chains.filter(v => v % 2 === 0)\n*);\n* const output = await Async.toArray(ch2);\n* // [ 2, 4, 6, 8, 10 ]\n* ```\n* \n* @example Grab the x/y coordinate from pointermove\n* ```js\n* const c1 = Chains.run(\n* Chains.fromEvent(window, `pointermove`),\n* Chains.Links.transform(event => ({ x: event.x, y: event.y }))\n* );\n* \n* // Eg: print out data as it comes in\n* Iterables.forEach(c1, coord => {\n* console.log(coord);\n* });\n* // Execution continues immediately\n* ```\n* @param functions \n* @returns \n*/\nasync function* runN(...functions) {\n\tlet input;\n\tfor (const fnOrData of functions) input = typeof fnOrData === `function` ? fnOrData(input ?? []) : resolveToGen(fnOrData);\n\tif (input === void 0) return;\n\tfor await (const v of input) yield v;\n}\n/**\n* Chain functions together. First argument is the source.\n* Use {@link runN} if you want to chain more links than is possible here,\n* at the cost of poorer type hinting.\n* \n* @example Process an array of strings. Transforming into\n* integers, and then filtering only even numbers.\n* ```js\n* const ch = Chains.run(\n* [ `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10` ],\n* Chains.transform(v => Number.parseInt(v)),\n* Chains.filter(v => v % 2 === 0)\n*);\n* const output = await Async.toArray(ch2);\n* // [ 2, 4, 6, 8, 10 ]\n* ```\n* \n* @example Grab the x/y coordinate from pointermove\n* ```js\n* const c1 = Chains.run(\n* Chains.fromEvent(window, `pointermove`),\n* Chains.Links.transform(event => ({ x: event.x, y: event.y }))\n* );\n* \n* // Eg: print out data as it comes in\n* Iterables.forEach(c1, coord => {\n* console.log(coord);\n* });\n* // Execution continues immediately\n* ```\n* @param gen \n* @param l0 \n* @param l1 \n* @param l2 \n* @param l3 \n* @returns \n*/\nasync function* run(gen, l0, l1, l2, l3, l4, l5) {\n\tlet input;\n\tconst functions = arguments;\n\tfor (const fnOrData of functions) if (typeof fnOrData === `function`) input = fnOrData(input ?? []);\n\telse input = resolveToGen(fnOrData);\n\tif (input === void 0) return;\n\tfor await (const v of input) yield v;\n}\n//#endregion\n//#region src/chain/prepare.ts\n/**\n* Prepare a chain, allowing you to provide a source at execution time.\n* ```js\n* const chain = Chains.prepare(\n* Chains.transform<string,number>( v => Number.parseInt(v) ),\n* Chains.filter<number>(v => v % 2 === 0)\n* );\n*\n* // Run it with provided source\n* for await (const v of chain([`1`, `2`, `3`])) {\n*\n* }\n* ```\n* @param functions\n* @returns\n*/\nfunction prepare(...functions) {\n\tconst r = (source) => {\n\t\treturn runN(source, ...functions);\n\t};\n\treturn r;\n}\n//#endregion\n//#region src/chain/single.ts\n/**\n* Input a single value to the chain, return a single result\n* \n* \n* ```js\n* // Create chain link\n* const f = Chains.Links.flatten<string, string>(data => data.join(`-`));\n* // Input a single value (an array)\n* const r1 = await Chains.single(f, [ `a`, `b`, `c` ]);\n* // r1 = `a-b-c`\n* ```\n* @param f \n* @param input \n* @returns \n*/\nasync function single(f, input) {\n\treturn (await f([input]).next()).value;\n}\n//#endregion\n//#region src/chain/sync.ts\n/**\n* Waits for all sources to produce a value, sending the combined results as an array.\n* After sending, it waits again for each source to send at least one value.\n* \n* Use {@link syncToObject} to output objects based on labelled sources rather than an array of values.\n* \n* Pace will be set by the slowest source. Alternatively, use {@link combineLatestToArray} where the rate is determined by fastest source.\n* \n* Only complete results are sent. For example if source A & B finish and \n* source C is still producing values, synchronisation is not possible \n* because A & B stopped producing values. Thus the stream will terminate\n* after `maximumWait` (2 seconds). Newer values from C are lost.\n*/\nasync function* syncToArray(sources, options = {}) {\n\tconst onSourceDone = options.onSourceDone ?? `break`;\n\tconst maximumWaitMs = intervalToMs(options.maximumWait, 2e3);\n\tconst finalValue = options.finalValue ?? `undefined`;\n\tconst inputs = sources.map((source) => ({\n\t\tseq: 0,\n\t\tlastValue: void 0,\n\t\tgen: resolveToGen(source),\n\t\tdone: false\n\t}));\n\tconst nextWithTimeoutOpts = { millis: maximumWaitMs };\n\tlet seq = 0;\n\tconst isAllDone = () => !inputs.some((v) => !v.done);\n\tlet go = true;\n\twhile (go) {\n\t\tseq++;\n\t\tfor (const input of inputs) {\n\t\t\tif (input.done) {\n\t\t\t\tinput.seq = seq;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst v = await nextWithTimeout(input.gen, nextWithTimeoutOpts);\n\t\t\tif (v.done) {\n\t\t\t\tinput.done = true;\n\t\t\t\tinput.seq = seq;\n\t\t\t\tif (finalValue === `undefined`) input.lastValue = void 0;\n\t\t\t\tif (onSourceDone === `break`) return;\n\t\t\t} else {\n\t\t\t\tinput.lastValue = v.value;\n\t\t\t\tinput.seq = seq;\n\t\t\t}\n\t\t}\n\t\tif (go) {\n\t\t\tconst d = inputs.filter((v) => v.seq === seq).map((v) => v.lastValue);\n\t\t\tif (d.length === 0) return;\n\t\t\tif (!d.some((v) => typeof v !== `undefined`)) return;\n\t\t\tyield d;\n\t\t}\n\t\tif (isAllDone()) go = false;\n\t}\n}\n//#endregion\n//#region src/chain/index.ts\nvar chain_exports = /* @__PURE__ */ __exportAll({\n\tDom: () => dom_exports,\n\tFrom: () => from_exports,\n\tLinks: () => links_exports,\n\taddToArray: () => addToArray,\n\tasArray: () => asArray,\n\tasCallback: () => asCallback$1,\n\tasPromise: () => asPromise,\n\tasValue: () => asValue,\n\tcombineLatestToArray: () => combineLatestToArray,\n\tcombineLatestToObject: () => combineLatestToObject,\n\tisGenFactoryNoInput: () => isGenFactoryNoInput,\n\tlazy: () => lazy,\n\tmergeFlat: () => mergeFlat,\n\tprepare: () => prepare,\n\tresolveToAsyncGen: () => resolveToAsyncGen,\n\tresolveToGen: () => resolveToGen,\n\trun: () => run,\n\trunN: () => runN,\n\tsingle: () => single,\n\tsyncToArray: () => syncToArray\n});\n//#endregion\n//#region src/compare-values.ts\n/**\n* Returns the 'max' of some iterable using the provided scoring function.\n* It only yields a value when iterator finishes.\n* @param iterable\n* @param scorer \n* @returns \n*/\nconst maxScore = (iterable, scorer) => {\n\tlet highestValue;\n\tlet highestScore = Number.MIN_SAFE_INTEGER;\n\tfor (const value of iterable) {\n\t\tconst score = scorer(value);\n\t\tif (score >= highestScore) {\n\t\t\thighestScore = score;\n\t\t\thighestValue = value;\n\t\t}\n\t}\n\treturn highestValue;\n};\n/**\n* Returns the 'min' of some iterable using the provided scoring function.\n* It only yields a value when iterator finishes.\n* @param iterable \n* @param scorer \n* @returns \n*/\nconst minScore = (iterable, scorer) => {\n\tlet lowestValue;\n\tlet lowestScore = Number.MAX_SAFE_INTEGER;\n\tfor (const value of iterable) {\n\t\tconst score = scorer(value);\n\t\tif (score <= lowestScore) {\n\t\t\tlowestScore = score;\n\t\t\tlowestValue = value;\n\t\t}\n\t}\n\treturn lowestValue;\n};\n/**\n* Returns _true_ if all values in iterables are equal, regardless\n* of their position. Uses === equality semantics by default.\n* \n* Is NOT recursive.\n* \n* @example Default equality checking\n* ```js\n* const a = ['apples','oranges','pears'];\n* const b = ['pears','oranges','apples'];\n* hasEqualValuesShallow(a, b); // True\n* ```\n*\n* @example Custom equality checking\n* ```js\n* const a = [ { name: 'John' }];\n* const b = [ { name: 'John' }];\n* // False, since object identies are different\n* hasEqualValuesShallow(a, b); \n* // True, since now we're comparing by value\n* hasEqualValuesShallow(a, b, (aa,bb) => aa.name === bb.name);\n* ```\n* @param iterableA First iterable to check\n* @param iterableB Iterable to compare against\n* @param eq Equality function, uses === by default\n*/\nconst hasEqualValuesShallow = (iterableA, iterableB, eq) => {\n\tconst returnValue = compareIterableValuesShallow(iterableA, iterableB, eq);\n\treturn returnValue.a.length === 0 && returnValue.b.length === 0;\n};\n//#endregion\n//#region src/controller.ts\n/**\n* Retrieve values from an iterator, passing them to a callback.\n* Allows iterator to be started, paused, or restarted and an optional delay between reading items from iterator.\n* @param options \n* @returns \n*/\nconst iteratorController = (options) => {\n\tconst delayMs = intervalToMs(options.delay, 10);\n\tlet gen;\n\tconst onValue = options.onValue;\n\tlet state = `stopped`;\n\tconst loop = continuously(async () => {\n\t\tif (gen) {\n\t\t\tconst r = await gen.next();\n\t\t\tif (r.done) {\n\t\t\t\tstate = `stopped`;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst r2 = onValue(r.value);\n\t\t\tif (typeof r2 === `boolean`) {\n\t\t\t\tif (!r2) state = `stopped`;\n\t\t\t\treturn r2;\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tstate = `stopped`;\n\t\t\treturn false;\n\t\t}\n\t}, delayMs);\n\tconst cancel = () => {\n\t\tif (state === `stopped`) return;\n\t\tgen = void 0;\n\t\tloop.cancel();\n\t\tstate = `stopped`;\n\t};\n\tconst pause = () => {\n\t\tif (state === `paused`) return;\n\t\tloop.cancel();\n\t\tstate = `paused`;\n\t};\n\tconst start = () => {\n\t\tif (state === `running`) return;\n\t\tif (!gen) remake();\n\t\tstate = `running`;\n\t\tloop.start();\n\t};\n\tconst remake = () => {\n\t\tif (options.iterator) gen = options.iterator();\n\t\telse throw new Error(`No source iterator`);\n\t};\n\tconst restart = () => {\n\t\tremake();\n\t\tstart();\n\t};\n\treturn {\n\t\tstart,\n\t\tcancel,\n\t\trestart,\n\t\tpause,\n\t\tget state() {\n\t\t\treturn state;\n\t\t}\n\t};\n};\n//#endregion\n//#region src/from-event.ts\nconst fromEvent = (eventSource, eventType) => {\n\tconst pullQueue = [];\n\tconst pushQueue = [];\n\tlet done = false;\n\tconst pushValue = (args) => {\n\t\tif (pullQueue.length > 0) pullQueue.shift()(...args);\n\t\telse pushQueue.push(args);\n\t};\n\tconst pullValue = () => new Promise((resolve) => {\n\t\tif (pushQueue.length > 0) resolve(...pushQueue.shift());\n\t\telse pullQueue.push(resolve);\n\t});\n\tconst handler = (...arguments_) => {\n\t\tpushValue(arguments_);\n\t};\n\teventSource.addEventListener(eventType, handler);\n\treturn {\n\t\tnext: async () => {\n\t\t\tif (done) return {\n\t\t\t\tdone: true,\n\t\t\t\tvalue: void 0\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tdone: false,\n\t\t\t\tvalue: await pullValue()\n\t\t\t};\n\t\t},\n\t\treturn: async () => {\n\t\t\tdone = true;\n\t\t\teventSource.removeEventListener(eventType, handler);\n\t\t\treturn {\n\t\t\t\tdone: true,\n\t\t\t\tvalue: void 0\n\t\t\t};\n\t\t},\n\t\tthrow: async (error) => {\n\t\t\tdone = true;\n\t\t\treturn {\n\t\t\t\tdone: true,\n\t\t\t\tvalue: Promise.reject(new Error(error))\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\n//#region src/numbers-compute.ts\n/**\n* Returns the min, max, avg and total of the array or iterable.\n* Any values that are invalid are silently skipped over.\n*\n* ```js\n* const v = [ 10, 2, 4.2, 99 ];\n* const mma = numbersCompute(v);\n* // Yields: { min: 2, max: 99, total: 115.2, avg: 28.8 }\n* ```\n*\n* Use {@link https://api.ixfx.fun/_ixfx/numbers/average/ @ixfx/numbers.average}, {@link https://api.ixfx.fun/_ixfx/numbers/max/ @ixfx/numbers.max}, {@link https://api.ixfx.fun/_ixfx/numbers/min/ @ixfx/numbers.min} or {@link https://api.ixfx.fun/_ixfx/numbers/total/ @ixfx/numers.total} if you only need one of these.\n*\n* A start and end range can be provided if the calculation should be restricted to a part\n* of the input array. By default the whole array is used.\n*\n* It's also possible to use an iterable as input.\n* ```js\n* import { count } from '@ixfx/numbers';\n* numbersCompute(count(5,1)); // Averages 1,2,3,4,5\n* ```\n* \n* Returns `NaN` if the input data is empty.\n* @param data\n* @param options Allows restriction of range that is examined\n* @returns `{min, max, avg, total}`\n*/\nconst numbersCompute = (data, options = {}) => {\n\tif (typeof data === `undefined`) throw new Error(`Param 'data' is undefined`);\n\tif (Array.isArray(data)) return numberArrayCompute(data, options);\n\tif (isIterable(data)) return numbersComputeIterable(data, options);\n\tthrow new Error(`Param 'data' is neither an array nor iterable`);\n};\nfunction numbersComputeIterable(data, options = {}) {\n\tlet total = 0;\n\tconst nonNumbers = options.nonNumbers ?? `ignore`;\n\tlet min = Number.MAX_SAFE_INTEGER;\n\tlet max = Number.MIN_SAFE_INTEGER;\n\tlet count = 0;\n\tfor (let v of data) {\n\t\tif (typeof v !== `number` || Number.isNaN(v)) {\n\t\t\tif (nonNumbers === `throw`) throw new TypeError(`Data contains something not a number. Got type '${typeof v}'`);\n\t\t\tif (nonNumbers === `nan`) v = NaN;\n\t\t\tif (nonNumbers === `ignore`) continue;\n\t\t}\n\t\ttotal += v;\n\t\tcount++;\n\t\tmin = Math.min(min, v);\n\t\tmax = Math.max(max, v);\n\t}\n\treturn {\n\t\tavg: total / count,\n\t\ttotal,\n\t\tmax,\n\t\tmin,\n\t\tcount\n\t};\n}\nfunction computeAverage(data, options = {}) {\n\tlet count = 0;\n\tlet total = 0;\n\tconst nonNumbers = options.nonNumbers ?? `ignore`;\n\tfor (let d of data) {\n\t\tif (typeof d !== `number` || Number.isNaN(d)) {\n\t\t\tif (nonNumbers === `throw`) throw new TypeError(`Data contains something not a number. Got type '${typeof d}'`);\n\t\t\tif (nonNumbers === `nan`) d = NaN;\n\t\t\tif (nonNumbers === `ignore`) continue;\n\t\t}\n\t\ttotal += d;\n\t\tcount++;\n\t}\n\treturn total / count;\n}\n//#endregion\n//#region src/index.ts\n/**\n* Returns a stream of minimum values.\n* \n* Streaming result: works with endless iterables.\n* \n* ```js\n* min([\n* {i:0,v:1},\n* {i:1,v:9},\n* {i:2,v:-2}\n* ], (a, b) => a.v > b.v);\n* // Yields: {i:2, v:1}, {i:2,v:-2}\n* ```\n* @param it Iterable\n* @param gt Should return _true_ if `a` is greater than `b`.\n* @returns Yields minimum values\n*/\nfunction min(it, gt = (a, b) => a > b) {\n\treturn isAsyncIterable(it) ? min$3(it, gt) : min$2(it, gt);\n}\n/**\n* Returns the maximum value of an iterable as it changes.\n* Streaming result: works with endless iterables.\n* \n* ```js\n* // Rank values by their 'v' field\n* const rank = (a,b) => a.v > b.v;\n* \n* min([\n* {i:0,v:1},\n* {i:1,v:9},\n* {i:2,v:-2}\n* ], rank);\n* // Yields: {i:0,v:1}, {i:1,v:9}\n* ```\n* @param it Iterable\n* @param gt Should return _true_ if `a` is greater than `b`.\n* @returns Iterable of maximum values\n*/\nfunction max(it, gt = (a, b) => a > b) {\n\treturn isAsyncIterable(it) ? max$3(it, gt) : max$2(it, gt);\n}\n/**\n* Drops elements that do not meet the predicate `f`.\n* Streaming result: works with endless iterables.\n* \n* ```js\n* dropWhile([1, 2, 3, 4], e => e < 3);\n* returns [3, 4]\n* ```\n* @param it\n* @param f\n*/\nfunction dropWhile(it, f) {\n\treturn isAsyncIterable(it) ? dropWhile$2(it, f) : dropWhile$1(it, f);\n}\n/**\n* Loops over a generator until it finishes, calling `callback`.\n* Useful if you don't care about the value generator produces, just the number of loops.\n* \n* ```js\n* until(count(5), () => {\n* // do something 5 times\n* });\n* ```\n* \n* If you want the value from the generator, use a `for of` loop as usual.\n* If `callback` explicitly returns _false_, the generator is aborted.\n* \n* This does not work for infinite generators, `callback` will never be called.\n* @param it Generator to run\n* @param callback Code to call for each iteration\n*/\nfunction until(it, callback) {\n\tif (isAsyncIterable(it)) return until$2(it, callback);\n\telse until$1(it, callback);\n}\n/**\n* Breaks an iterable into array chunks\n* \n* Streaming: works with infinite iterables.\n* \n* ```js\n* chunks([1,2,3,4,5,6,7,8,9,10], 3);\n* // Yields [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]\n* ```\n* @param it\n* @param size\n*/\nfunction chunks(it, size) {\n\treturn isAsyncIterable(it) ? chunks$2(it, size) : chunks$1(it, size);\n}\n/**\n* Filters an iterable, only yielding items which match `f`.\n*\n* ```js\n* filter([1, 2, 3, 4], e => e % 2 == 0);\n* returns [2, 4]\n* ```\n* \n* When using async iterables, `f` can be async as well.\n* @param it\n* @param f\n*/\nfunction filter(it, f) {\n\treturn isAsyncIterable(it) ? filter$3(it, f) : filter$2(it, f);\n}\n/**\n* Yields `v` for each item within `it`.\n*\n* ```js\n* fill([1, 2, 3], 0);\n* // Yields: [0, 0, 0]\n* ```\n* \n* This is like a `map` where we return a fixed value, ignoring the input.\n* @param it\n* @param v\n*/\nfunction fill(it, v) {\n\treturn isAsyncIterable(it) ? fill$2(it, v) : fill$1(it, v);\n}\n/**\n* Return concatenation of iterators.\n* \n* Non-streaming: If one of the input iterables is endless, the other ones won't\n* be processed.\n* @param its\n*/\nfunction concat(...its) {\n\treturn isAsyncIterable(its[0]) ? concat$2(...its) : concat$1(...its);\n}\n/**\n* Returns first item from iterable `it` that matches predicate `f`\n* ```js\n* find([1, 2, 3, 4], e => e > 2);\n* // Yields: 3\n* ```\n* \n* When using async iterables, `f` can be async as well.\n* @param it\n* @param f\n* @returns\n*/\nfunction find(it, f) {\n\treturn isAsyncIterable(it) ? find$2(it, f) : find$1(it, f);\n}\n/**\n* Execute function `f` for each item in iterable.\n* If `f` returns _false_, iteration stops.\n* ```js\n* forEach(iterable, v => {\n* // do something with value\n* });\n* ```\n* \n* When using an async iterable, `fn` can also be async.\n* @param it Iterable or array\n* @param fn Function to execute\n*/\nfunction forEach(it, fn, options = {}) {\n\tif (isAsyncIterable(it)) return forEach$2(it, fn, options);\n\telse forEach$1(it, fn);\n}\n/**\n* Maps an iterable through function `f`\n* ```js\n* // For every input value, multiply it by itself\n* map([1, 2, 3], e => e*e)\n* // Yields: 1, 4, 9\n* ```\n* \n* It can also be used to transform types:\n* ```js\n* map([1, 2, 3], e => { value: e });\n* // Yields: { value: 1 }, { value: 2 }, { value: 3 }\n* ```\n* @param it\n* @param f\n*/\nfunction map(it, f) {\n\treturn isAsyncIterable(it) ? map$2(it, f) : map$1(it, f);\n}\n/**\n* Yield values from `array`, one at a time.\n* Use `interval` to add time between each item.\n* The first item is yielded without delay.\n* \n* @param array Array of values\n* @param interval Interval (defaults: 1ms)\n*/\nfunction fromArray(array, interval) {\n\treturn interval === void 0 ? fromArray$1(array) : fromArray$2(array, interval);\n}\n/**\n* Returns a 'flattened' copy of array, un-nesting arrays one level.\n* Streaming: works with unlimited iterables.\n* ```js\n* flatten([1, [2, 3], [[4]]]);\n* // Yields: [1, 2, 3, [4]];\n* ```\n* @param it\n*/\nfunction flatten(it) {\n\treturn isAsyncIterable(it) ? flatten$2(it) : flatten$1(it);\n}\n/**\n* Returns true the first time `f` returns true. Useful for spotting any occurrence of\n* data, and exiting quickly\n* ```js\n* some([1, 2, 3, 4], e => e % 3 === 0);\n* // Yields: true\n* ```\n* @param it Iterable\n* @param f Filter function\n* @returns\n*/\nfunction some(it, f) {\n\treturn isAsyncIterable(it) ? some$2(it, f) : some$1(it, f);\n}\n/**\n* Returns the last item of an iterable, or _undefined_ if it yields no results.\n* @param it \n* @returns \n*/\nfunction last(it) {\n\treturn isAsyncIterable(it) ? last$2(it) : last$1(it);\n}\n/**\n* Reduce for iterables\n* ```js\n* reduce([1, 2, 3], (acc, cur) => acc + cur, 0);\n* // Yields: 6\n* ```\n* @param it Iterable\n* @param f Function\n* @param start Start value\n* @returns\n*/\nfunction reduce(it, f, start) {\n\treturn isAsyncIterable(it) ? reduce$3(it, f, start) : reduce$2(it, f, start);\n}\n/**\n* Returns a section from an iterable.\n* \n* 'end' is the end index, not the number of items.\n* \n* ```js\n* // Return five items from step 10\n* slice(it, 10, 15);\n* ```\n* @param it Iterable\n* @param start Start step\n* @param end Exclusive end step (or until completion)\n*/\nfunction slice(it, start = 0, end = Number.POSITIVE_INFINITY) {\n\treturn isAsyncIterable(it) ? slice$2(it, start, end) : slice$1(it, start, end);\n}\n/**\n* Returns unique items from an iterable or\n* array of iterables.\n*\n* ```js\n* const data = [ 'apples', 'oranges' ]\n* const data2 = [ 'oranges', 'pears' ]\n* const unique = [...unique([data,data2]];\n* // Yields: [ 'apples', 'oranges', 'pears' ]\n* ```\n*\n* Uses object reference to compare values.\n* Use {@link uniqueByValue} if this doesn't suffice.\n* @param iterable Iterable, or array of iterables\n*/\nfunction unique(iterable) {\n\tif (Array.isArray(iterable)) {\n\t\tif (iterable.length === 0) return fromArray$1([]);\n\t\treturn isAsyncIterable(iterable[0]) ? unique$2(iterable) : unique$1(iterable);\n\t} else if (isAsyncIterable(iterable)) return unique$2(iterable);\n\telse return unique$1(iterable);\n}\n/**\n* Filters the `input` iterable, only yielding unique values. Use {@link unique} to compare\n* by object reference instead.\n* \n* Streaming: Works with unbounded iterables.\n* \n* ```js\n* const d = ['a', 'b', 'c', 'b', 'd' ];\n* for (const v of uniqueByValue(d)) {\n* // Yields: 'a', 'b', 'c', 'd'\n* // (extra 'b' is skipped)\n* }\n* ```\n* \n* By default, JSON.stringify is used to create a string representing value. These are added\n* to a Set of strings, which is how we keep track of uniqueness. If the value is already a string it is used as-is.\n* \n* This allows you to have custom logic for what determines uniqueness. Eg, using a single field\n* of an object as an identifier:\n* \n* ```js\n* const people = [\n* { name: `Mary`, size: 20 }, { name: `Abdul`, size: 19 }, { name: `Mary`, size: 5 }\n* ]\n* for (const v of uniqueByValue(d, v=>v.name)) {\n* // Yields: { name: `Mary`, size: 20 }, { name: `Abdul`, size: 19 }\n* // Second 'Mary' is skipped because name is the same, even though size field is different.\n* }\n* ```\n* \n* If you want to keep track of the set of keys, or prime it with some existing data, provide a Set instance:\n* ```js\n* const unique = new Set();\n* unique.add(`b`);\n* const d = [`a`, `b`, `c`];\n* for (const v of uniqueByValue(d, toStringDefault, unique)) {\n* // Yields: `a`, `c`\n* // `b` is skipped because it was already in set\n* }\n* // After completion, `unique` contains `a`, `b` and `c`.\n* ```\n* \n* Creating your own Set is useful for tracking unique values across several calls to `uniqueByValue`.\n* @param input \n* @param seen \n* @param toString \n*/\nfunction* uniqueByValue(input, toString = toStringDefault, seen = /* @__PURE__ */ new Set()) {\n\tyield* isAsyncIterable(input) ? uniqueByValue$2(input, toString, seen) : uniqueByValue$1(input, toString, seen);\n}\n/**\n* Returns an array of values from an iterator.\n*\n* ```js\n* const data = await toArray(adsrIterable(opts, 10));\n* ```\n*\n* Note: If the iterator is infinite, be sure to provide a `count` or the function\n* will never return.\n*\n* @param it Asynchronous iterable\n* @param count Number of items to return, by default all.\n* @returns\n*/\nfunction toArray(it, options = {}) {\n\treturn isAsyncIterable(it) ? toArray$2(it, options) : toArray$1(it, options);\n}\n/**\n* Returns _true_ if `f` returns _true_ for\n* every item in iterable.\n* \n* Streaming: If an infinite iterable is used, function will never return value.\n* @param it\n* @param f\n* @returns\n*/\nfunction every(it, f) {\n\treturn isAsyncIterable(it) ? every$2(it, f) : every$1(it, f);\n}\n/**\n* Returns _true_ if items in two iterables are equal, and in same order.\n* \n* By default uses === semantics\n* @param it1\n* @param it2\n* @param comparerOrKey\n* @returns\n*/\nfunction equals(it1, it2, comparerOrKey) {\n\treturn isAsyncIterable(it1) && isAsyncIterable(it2) ? equals$2(it1, it2, comparerOrKey) : equals$1(it1, it2, comparerOrKey);\n}\n/**\n* Combine same-positioned items from several iterables\n* ```js\n* zip( [1, 2, 3], [4, 5, 6], [7, 8, 9] );\n* Yields: [ [1, 4, 7], [2, 5, 8], [3, 6, 9] ]\n* ```\n* @param its\n* @returns\n*/\nfunction zip(...its) {\n\tif (its.length === 0) return fromArray$1([]);\n\treturn isAsyncIterable(its[0]) ? zip$2(...its) : zip$1(...its);\n}\n/**\n* Yield values from `iterable`, one at a time.\n* Use `interval` to add time between each item.\n* The first item is yielded without delay.\n* @param iterable Iterable or AsyncIterable\n* @param [interval=1] Interval to wait between yield \n*/\nfunction fromIterable(iterable, interval) {\n\tif (isAsyncIterable(iterable) || interval !== void 0) return fromIterable$2(iterable, interval);\n\treturn fromIterable$1(iterable);\n}\n/**\n* Access `callback` as an iterable:\n* ```js\n* const fn = () => Math.random();\n* for (const v of fromFunction(fn)) {\n* // Generate infinite random numbers\n* }\n* ```\n* \n* Use {@link fromFunctionAwaited} to await `callback`.\n* @param callback Function that generates a value\n*/\nfunction* fromFunction(callback) {\n\twhile (true) yield callback();\n}\n/**\n* Access awaited `callback` as an iterable:\n* ```js\n* const fn = () => Math.random();\n* for await (const v of fromFunctionAwaited(fn)) {\n* // Generate infinite random numbers\n* }\n* ```\n* \n* `callback` can be async, result is awaited.\n* This requires the use of `for await`.\n* Use {@link fromFunction} otherwise;\n* @param callback \n*/\nasync function* fromFunctionAwaited(callback) {\n\twhile (true) yield await callback();\n}\n/**\n* Calls `callback` whenever the generator produces a value.\n* \n* When using `asCallback`, call it with `await` to let generator \n* run its course before continuing:\n* ```js\n* await asCallback(tick({ interval:1000, loops:5 }), x => {\n* // Gets called 5 times, with 1000ms interval\n* });\n* console.log(`Hi`); // Prints after 5 seconds\n* ```\n* \n* Or if you skip the `await`, code continues and callback will still run:\n* ```js\n* asCallback(tick({ interval: 1000, loops: 5}), x => {\n* // Gets called 5 times, with 1000ms interval\n* });\n* console.log(`Hi`); // Prints immediately\n* ```\n* @param input \n* @param callback \n*/\nfunction asCallback(input, callback, onDone) {\n\tif (isAsyncIterable(input)) return asCallback$3(input, callback);\n\telse {\n\t\tasCallback$2(input, callback);\n\t\treturn;\n\t}\n}\n//#endregion\nexport { async_exports as Async, chain_exports as Chains, sync_exports as Sync, asCallback, chunks, combineLatestToArray, combineLatestToObject, computeAverage, concat, dropWhile, equals, every, fill, filter, find, flatten, forEach, fromArray, fromEvent, fromFunction, fromFunctionAwaited, fromIterable, hasEqualValuesShallow, isAsyncIterable, isIterable, iteratorController, last, map, max, maxScore, min, minScore, numbersCompute, reduce, slice, some, toArray, unique, uniqueByValue, until, zip };\n","import { t as QueueMutable } from \"./queue-mutable-lrZyCqgq.js\";\nimport { isEqualDefault } from \"@ixfx/core\";\nimport { numberTest, resultThrow } from \"@ixfx/guards\";\nimport { last, max, min } from \"@ixfx/iterables\";\n//#region src/queue/priority-mutable.ts\n/**\n* Simple priority queue implementation.\n* Higher numbers mean higher priority.\n* \n* ```js\n* const pm = new PriorityMutable();\n* \n* // Add items with a priority (higher numeric value = higher value)\n* pm.enqueueWithPriority(`hello`, 4);\n* pm.enqueueWithPriotity(`there`, 1);\n* \n* ```\n*/\nvar PriorityMutable = class extends QueueMutable {\n\tconstructor(opts = {}) {\n\t\tif (opts.eq === void 0) opts = {\n\t\t\t...opts,\n\t\t\teq: (a, b) => {\n\t\t\t\treturn isEqualDefault(a.item, b.item);\n\t\t\t}\n\t\t};\n\t\tsuper(opts);\n\t}\n\t/**\n\t* Adds an item with a given priority\n\t* @param item Item\n\t* @param priority Priority (higher numeric value means higher priority)\n\t*/\n\tenqueueWithPriority(item, priority) {\n\t\tresultThrow(numberTest(priority, `positive`));\n\t\tsuper.enqueue({\n\t\t\titem,\n\t\t\tpriority\n\t\t});\n\t}\n\tchangePriority(item, priority, addIfMissing = false, eq) {\n\t\tif (item === void 0) throw new Error(`Item cannot be undefined`);\n\t\tlet toDelete;\n\t\tfor (const d of this.data) if (eq) {\n\t\t\tif (eq(d.item, item)) {\n\t\t\t\ttoDelete = d;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if (this.eq(d, {\n\t\t\titem,\n\t\t\tpriority: 0\n\t\t})) {\n\t\t\ttoDelete = d;\n\t\t\tbreak;\n\t\t}\n\t\tif (toDelete === void 0 && !addIfMissing) throw new Error(`Item not found in priority queue. Item: ${JSON.stringify(item)}`);\n\t\tif (toDelete !== void 0) this.removeWhere((item) => toDelete === item);\n\t\tthis.enqueueWithPriority(item, priority);\n\t}\n\tdequeueMax() {\n\t\tconst m = last(max(this.data, (a, b) => a.priority >= b.priority));\n\t\tif (m === void 0) return;\n\t\tthis.removeWhere((item) => item === m);\n\t\treturn m.item;\n\t}\n\tdequeueMin() {\n\t\tconst m = last(max(this.data, (a, b) => a.priority >= b.priority));\n\t\tif (m === void 0) return;\n\t\tthis.removeWhere((item) => item.item === m);\n\t\treturn m.item;\n\t}\n\tpeekMax() {\n\t\tconst m = last(max(this.data, (a, b) => a.priority >= b.priority));\n\t\tif (m === void 0) return;\n\t\treturn m.item;\n\t}\n\tpeekMin() {\n\t\tconst m = last(min(this.data, (a, b) => a.priority >= b.priority));\n\t\tif (m === void 0) return;\n\t\treturn m.item;\n\t}\n};\n/**\n* Creates a {@link PriorityMutable} queue.\n* \n* Options:\n* * eq: Equality function\n* * capacity: limit on number of items\n* * discardPolicy: what to do if capacity is reached\n* @param opts \n* @returns \n*/\nfunction priority(opts = {}) {\n\treturn new PriorityMutable(opts);\n}\n//#endregion\nexport { priority as n, PriorityMutable as t };\n","import { t as __exportAll } from \"./chunk-ZRW5x4aP.js\";\nimport { a as enqueue, c as peek, i as dequeue, l as trimQueue, n as mutable, o as isEmpty, r as debug, s as isFull, t as QueueMutable } from \"./queue-mutable-lrZyCqgq.js\";\nimport { n as priority, t as PriorityMutable } from \"./priority-mutable-C9pMxKNT.js\";\n//#region src/queue/queue-immutable.ts\nvar QueueImmutable = class QueueImmutable {\n\topts;\n\t#data;\n\t/**\n\t* Creates an instance of Queue.\n\t* @param {QueueOpts} opts Options foor queue\n\t* @param {V[]} data Initial data. Index 0 is front of queue\n\t*/\n\tconstructor(opts = {}, data = []) {\n\t\tif (opts === void 0) throw new Error(`opts parameter undefined`);\n\t\tthis.opts = opts;\n\t\tthis.#data = data;\n\t}\n\tforEach(fn) {\n\t\tfor (let index = this.#data.length - 1; index >= 0; index--) fn(this.#data[index]);\n\t}\n\tforEachFromFront(fn) {\n\t\tthis.#data.forEach((item) => {\n\t\t\tfn(item);\n\t\t});\n\t}\n\tenqueue(...toAdd) {\n\t\treturn new QueueImmutable(this.opts, enqueue(this.opts, this.#data, ...toAdd));\n\t}\n\tdequeue() {\n\t\treturn new QueueImmutable(this.opts, dequeue(this.opts, this.#data));\n\t}\n\tget isEmpty() {\n\t\treturn isEmpty(this.opts, this.#data);\n\t}\n\tget isFull() {\n\t\treturn isFull(this.opts, this.#data);\n\t}\n\tget length() {\n\t\treturn this.#data.length;\n\t}\n\tget peek() {\n\t\treturn peek(this.opts, this.#data);\n\t}\n\ttoArray() {\n\t\treturn [...this.#data];\n\t}\n};\n/**\n* Returns an immutable queue. Queues are useful if you want to treat 'older' or 'newer'\n* items differently. _Enqueing_ adds items at the back of the queue, while\n* _dequeing_ removes items from the front (ie. the oldest).\n*\n* ```js\n* let q = Queues.immutable(); // Create\n* q = q.enqueue(`a`, `b`); // Add two strings\n* const front = q.peek(); // `a` is at the front of queue (oldest)\n* q = q.dequeue(); // q now just consists of `b`\n* ```\n* @example Cap size to 5 items, throwing away newest items already in queue.\n* ```js\n* const q = Queues.immutable({capacity: 5, discardPolicy: `newer`});\n* ```\n*\n* @typeParam V - Type of values stored\n* @param options\n* @param startingItems Index 0 is the front of the queue\n* @returns A new queue\n*/\nconst immutable = (options = {}, ...startingItems) => {\n\toptions = { ...options };\n\treturn new QueueImmutable(options, [...startingItems]);\n};\n//#endregion\n//#region src/queue/index.ts\nvar queue_exports = /* @__PURE__ */ __exportAll({\n\tPriorityMutable: () => PriorityMutable,\n\tQueueImmutable: () => QueueImmutable,\n\tQueueMutable: () => QueueMutable,\n\tdebug: () => debug,\n\tdequeue: () => dequeue,\n\tenqueue: () => enqueue,\n\timmutable: () => immutable,\n\tisEmpty: () => isEmpty,\n\tisFull: () => isFull,\n\tmutable: () => mutable,\n\tpeek: () => peek,\n\tpriority: () => priority,\n\ttrimQueue: () => trimQueue\n});\n//#endregion\nexport { QueueImmutable as n, immutable as r, queue_exports as t };\n","import { t as state_machine_exports, v as run, y as runSingle } from \"./state-machine-DveEdO4G.js\";\nimport { continuously, elapsedSince, elapsedToHumanString, intervalToMs, resolve, resolveSync, sleep, sleep as sleep$1 } from \"@ixfx/core\";\nimport { integerTest, numberTest, resultIsError, resultThrow, resultToError } from \"@ixfx/guards\";\nimport { clamp, movingAverageLight } from \"@ixfx/numbers\";\nimport { SimpleEventEmitter } from \"@ixfx/events\";\nimport * as Debug from \"@ixfx/debug\";\nimport { getErrorMessage, resolveLogOption } from \"@ixfx/debug\";\nimport { Queues } from \"@ixfx/collections\";\nexport * from \"@ixfx/core/continuously\";\n//#region src/behaviour-tree.ts\nconst getName = (t, defaultValue = ``) => {\n\tif (typeof t === `object` && `name` in t && t.name !== void 0) return t.name;\n\treturn defaultValue;\n};\nfunction* iterateBreadth(t, pathPrefix) {\n\tif (typeof pathPrefix === `undefined`) pathPrefix = getName(t);\n\tfor (const [index, n] of entries(t)) yield [n, pathPrefix];\n\tfor (const [index, n] of entries(t)) {\n\t\tconst name = getName(n, `?`);\n\t\tyield* iterateBreadth(n, pathPrefix.length > 0 ? pathPrefix + `.` + name : name);\n\t}\n}\nfunction* iterateDepth(t, pathPrefix) {\n\tif (typeof pathPrefix === `undefined`) pathPrefix = getName(t);\n\tfor (const [index, n] of entries(t)) {\n\t\tlet prefix;\n\t\tif (typeof n === `string`) prefix = pathPrefix;\n\t\telse {\n\t\t\tconst name = getName(n, `?`);\n\t\t\tprefix = pathPrefix.length > 0 ? pathPrefix + `.` + name : name;\n\t\t}\n\t\tyield [n, prefix];\n\t\tyield* iterateDepth(n, prefix);\n\t}\n}\nfunction isSeqNode(n) {\n\treturn n.seq !== void 0;\n}\nfunction isSelNode(n) {\n\treturn n.sel !== void 0;\n}\nfunction* entries(n) {\n\tif (isSeqNode(n)) yield* n.seq.entries();\n\telse if (isSelNode(n)) yield* n.sel.entries();\n\telse if (typeof n === `string`) {} else throw new TypeError(`Unexpected shape of node. seq/sel missing`);\n}\n//#endregion\n//#region src/delay.ts\n/**\n* Pauses execution for interval after which the asynchronous `callback` is executed and awaited.\n* Must be called with `await` if you want the pause effect.\n*\n* @example Pause and wait for function\n* ```js\n* const result = await delay(async () => Math.random(), 1000);\n* console.log(result); // Prints out result after one second\n* ```\n*\n* If the `interval` option is a number its treated as milliseconds. {@link Interval} can also be used:\n* ```js\n* const result = await delay(async () => Math.random(), { mins: 1 });\n* ```\n*\n* If `await` is omitted, the function will run after the provided timeout, and code will continue to run.\n*\n* @example Schedule a function without waiting\n* ```js\n* await delay(async () => {\n* console.log(Math.random())\n* }, 1000);\n* // Prints out a random number after 1 second.\n* ```\n*\n* {@link delay} and {@link sleep} are similar. `delay()` takes a parameter of what code to execute after the timeout, while `sleep()` just resolves after the timeout.\n*\n* Optionally takes an AbortSignal to cancel delay.\n* ```js\n* const ac = new AbortController();\n* // Super long wait\n* await delay(someFn, { signal: ac.signal, hours: 1 }}\n* ...\n* ac.abort(); // Cancels long delay\n* ```\n*\n* It also allows choice of when delay should happen.\n* If you want to be able to cancel or re-run a delayed function, consider using\n* {@link timeout} instead.\n*\n* @typeParam V - Type of callback return value\n* @param callback What to run after interval\n* @param optsOrMillis Options for delay, or millisecond delay. By default delay is before `callback` is executed.\n* @return Returns result of `callback`.\n*/\nconst delay = async (callback, optsOrMillis) => {\n\tconst opts = typeof optsOrMillis === `number` ? { millis: optsOrMillis } : optsOrMillis;\n\tconst delayWhen = opts.delay ?? `before`;\n\tif (delayWhen === `before` || delayWhen === `both`) await sleep$1(opts);\n\tconst r = Promise.resolve(await callback());\n\tif (delayWhen === `after` || delayWhen === `both`) await sleep$1(opts);\n\treturn r;\n};\n/**\n* Iterate over a source iterable with some delay between results.\n* Delay can be before, after or both before and after each result from the\n* source iterable.\n*\n* Since it's an async iterable, `for await ... of` is needed.\n*\n* ```js\n* const opts = { intervalMs: 1000, delay: 'before' };\n* const iterable = count(10);\n* for await (const i of delayIterable(iterable, opts)) {\n* // Prints 0..9 with one second between\n* }\n* ```\n*\n* Use {@link delay} to return a result after some delay\n*\n* @param iter\n* @param opts\n*/\n/**\n* Async generator that loops via `requestAnimationFrame`.\n*\n* We can use `for await of` to run code:\n* ```js\n* const loop = delayAnimationLoop();\n* for await (const o of loop) {\n* // Do something...\n* // Warning: loops forever\n* }\n* // Warning: execution doesn't continue to this point\n* // unless there is a 'break' in loop.\n* ```\n* \n* Or use the generator in manually:\n* ```js\n* // Loop forever\n* (async () => {\n* const loop = delayAnimationLoop();\n* while (true) {\n* await loop.next();\n*\n* // Do something...\n* // Warning: loops forever\n* }\n* })();\n* ```\n* \n* Practically, these approaches are not so useful\n* because execution blocks until the loop finishes.\n* \n* Instead, we might want to continually loop a bit\n* of code while other bits of code continue to run.\n* \n* The below example shows how to do this.\n* \n* ```js\n* setTimeout(async () => {\n* for await (const _ of delayAnimationLoop()) {\n* // Do soething at animation speed\n* }\n* });\n* \n* // Execution continues while loop also runs\n* ```\n*\n*/\nasync function* delayAnimationLoop() {\n\tlet resolve;\n\tlet p = new Promise((r) => resolve = r);\n\tlet timer = 0;\n\tconst callback = () => {\n\t\tif (resolve) resolve();\n\t\tp = new Promise((r) => resolve = r);\n\t};\n\ttry {\n\t\twhile (true) {\n\t\t\ttimer = globalThis.requestAnimationFrame(callback);\n\t\t\tyield await p;\n\t\t}\n\t} finally {\n\t\tif (resolve) resolve();\n\t\tglobalThis.cancelAnimationFrame(timer);\n\t}\n}\n/**\n* Async generator that loops at a given interval.\n* \n* @example \n* For Await loop every second\n* ```js\n* const loop = delayLoop(1000);\n* // Or: const loop = delayLoop({ secs: 1 });\n* for await (const o of loop) {\n* // Do something...\n* // Warning: loops forever\n* }\n* ```\n* \n* @example \n* Loop runs every second\n* ```js\n* (async () => {\n* const loop = delayLoop(1000);\n* // or: loop = delayLoop({ secs: 1 });\n* while (true) {\n* await loop.next();\n*\n* // Do something...\n* // Warning: loops forever\n* }\n* })();\n* ```\n* \n* Alternatives:\n* * {@link delay} to run a single function after a delay\n* * {@link sleep} pause execution\n* * {@link continuously} to start/stop/adjust a constantly running loop\n*\n* @param timeout Delay. If 0 is given, `requestAnimationFrame` is used over `setTimeout`.\n*/\nasync function* delayLoop(timeout) {\n\tconst timeoutMs = intervalToMs(timeout);\n\tif (typeof timeoutMs === `undefined`) throw new Error(`timeout is undefined`);\n\tif (timeoutMs < 0) throw new Error(`Timeout is less than zero`);\n\tif (timeoutMs === 0) return yield* delayAnimationLoop();\n\tlet resolve;\n\tlet p = new Promise((r) => resolve = r);\n\tlet timer;\n\tconst callback = () => {\n\t\tif (resolve) resolve();\n\t\tp = new Promise((r) => resolve = r);\n\t};\n\ttry {\n\t\twhile (true) {\n\t\t\ttimer = globalThis.setTimeout(callback, timeoutMs);\n\t\t\tyield await p;\n\t\t}\n\t} finally {\n\t\tif (resolve) resolve();\n\t\tif (timer !== void 0) globalThis.clearTimeout(timer);\n\t\ttimer = void 0;\n\t}\n}\n//#endregion\n//#region src/debounce.ts\n/**\n* Returns a debounce function which acts to filter calls to a given function `fn`.\n*\n* Eg, Let's create a debounced wrapped for a function:\n* ```js\n* const fn = () => console.log('Hello');\n* const debouncedFn = debounce(fn, 1000);\n* ```\n*\n* Now we can call `debouncedFn()` as often as we like, but it will only execute\n* `fn()` after 1 second has elapsed since the last invocation. It essentially filters\n* many calls to fewer calls. Each time `debounceFn()` is called, the timeout is\n* reset, so potentially `fn` could never be called if the rate of `debounceFn` being called\n* is faster than the provided timeout.\n*\n* Remember that to benefit from `debounce`, you must call the debounced wrapper, not the original function.\n*\n* ```js\n* // Create\n* const d = debounce(fn, 1000);\n*\n* // Don't do this if we want to benefit from the debounce\n* fn();\n*\n* // Use the debounced wrapper\n* d(); // Only calls fn after 1000s\n* ```\n*\n* A practical use for this is handling high-frequency streams of data, where we don't really\n* care about processing every event, only last event after a period. Debouncing is commonly\n* used on microcontrollers to prevent button presses being counted twice.\n*\n* @example Handle most recent pointermove event after 1000ms\n* ```js\n* // Set up debounced handler\n* const moveDebounced = debounce((evt) => {\n* // Handle event\n* }, 500);\n*\n* // Wire up event\n* el.addEventListener(`pointermove`, moveDebounced);\n* ```\n*\n* Arguments can be passed to the debounced function:\n*\n* ```js\n* const fn = (x) => console.log(x);\n* const d = debounce(fn, 1000);\n* d(10);\n* ```\n*\n* If the provided function is asynchronous, it's possible to await the debounced\n* version as well. If the invocation was filtered, it returns instantly.\n*\n* If you want the result of a debounced function when it finally executes, pass\n* in the `onResult` parameter:\n* ```js\n* const isRed = (colour) => colour === `red`;\n* const onResult = (result) => {\n* if (result.success) {\n* console.log(`Value: ${result.value}`);\n* }\n* }\n* const d = debounce(fn, 1000, onResult);\n* ```\n*\n* If the debounced function throws an error, this will be reported as well:\n* ```js\n* if (!result.success) {\n* console.error(result.error);\n* }\n* ```\n* @param callback Function to filter access to\n* @param interval Minimum time between invocations\n* @param onResult Callback when the result from the wrapped function is available\n* @returns Debounce function\n*/\nfunction debounce(callback, interval, onResult) {\n\tlet timer;\n\treturn (...args) => {\n\t\tif (timer) clearTimeout(timer);\n\t\ttimer = setTimeout(() => {\n\t\t\ttry {\n\t\t\t\tconst result = callback(...args);\n\t\t\t\tif (onResult) onResult({\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tvalue: result\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (onResult) onResult({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror\n\t\t\t\t});\n\t\t\t}\n\t\t}, intervalToMs(interval));\n\t};\n}\n//#endregion\n//#region src/dispatch-list.ts\n/**\n* Maintains a list of listeners to receive data.\n* \n* Type parameter is the type of events sent.\n* \n* ```js\n* const d = new DispatchList();\n* \n* // Eg: add a listener\n* d.add(v => {\n* // Handle a value\n* });\n* \n* // Eg. send a value to all listeners\n* d.notify(`some value`);\n* ```\n* \n* If event handler returns true, additional handlers are not called.\n*/\nvar DispatchList = class {\n\t#handlers;\n\t#counter = 0;\n\t#id = Math.floor(Math.random() * 100);\n\tconstructor() {\n\t\tthis.#handlers = [];\n\t}\n\t/**\n\t* Returns _true_ if list is empty\n\t* @returns \n\t*/\n\tisEmpty() {\n\t\treturn this.#handlers.length === 0;\n\t}\n\t/**\n\t* Adds a handler. You get back an id which can be used\n\t* to remove the handler later.\n\t* \n\t* Handlers can be added with 'once' flag set to _true_. This will\n\t* automatically remove them after the first value is sent to them.\n\t* \n\t* If handler returns _true_, subsequent handlers are not invoked.\n\t* @param handler \n\t* @param options \n\t* @returns \n\t*/\n\tadd(handler, options = {}) {\n\t\tthis.#counter++;\n\t\tconst once = options.once ?? false;\n\t\tconst wrap = {\n\t\t\tid: `${this.#id} - ${this.#counter}`,\n\t\t\thandler,\n\t\t\tonce\n\t\t};\n\t\tthis.#handlers.push(wrap);\n\t\treturn wrap.id;\n\t}\n\t/**\n\t* Remove a handler by its id.\n\t* @param id \n\t* @returns _True_ if handler was removed, _false_ if not found.\n\t*/\n\tremove(id) {\n\t\tconst length = this.#handlers.length;\n\t\tthis.#handlers = this.#handlers.filter((handler) => handler.id !== id);\n\t\treturn this.#handlers.length !== length;\n\t}\n\t/**\n\t* Emit a value to all handlers\n\t* Returns _true_ if at least one handler reported 'true' as a response.\n\t* Also returns true\n\t* @param value \n\t*/\n\tnotify(value) {\n\t\tfor (const handler of this.#handlers) {\n\t\t\tconst r = handler.handler(value);\n\t\t\tif (typeof r === `boolean`) {\n\t\t\t\tif (r) {\n\t\t\t\t\tif (handler.once) this.remove(handler.id);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else if (handler.once) this.remove(handler.id);\n\t\t}\n\t\treturn false;\n\t}\n\t/**\n\t* Remove all handlers\n\t*/\n\tclear() {\n\t\tthis.#handlers = [];\n\t}\n};\n//#endregion\n//#region src/every.ts\n/**\n* Returns true for every _n_th call, eg 2 for every second call.\n*\n* If `nth` is 1, returns true for everything. 0 will be false for everything.\n*\n* Usage:\n* ```js\n* const tenth = everyNth(10);\n* window.addEventListener(`pointermove`, evt => {\n* if (!tenth(evt)) return; // Filter out\n* // Continue processing, it is the 10th thing.\n*\n* });\n* ```\n*\n* Alternative:\n* ```js\n* window.addEventListener(`pointermove`, everyNth(10, evt => {\n* // Do something with tenth item...\n* });\n* ```\n* @param nth Every nth item\n* @param callback\n* @returns Function which in turn returns true if nth call has been hit, false otherwise\n*/\nconst everyNth = (nth, callback) => {\n\tresultThrow(integerTest(nth, `positive`, `nth`));\n\tlet counter = 0;\n\treturn (data) => {\n\t\tcounter++;\n\t\tif (counter === nth) {\n\t\t\tcounter = 0;\n\t\t\tif (callback) callback(data);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n};\n//#endregion\n//#region src/event-race.ts\n/**\n* Subscribes to events on `target`, returning the event data\n* from the first event that fires.\n* \n* By default waits a maximum of 1 minute.\n* \n* Automatically unsubscribes on success or failure (ie. timeout)\n* \n* ```js\n* // Event will be data from either event, whichever fires first\n* // Exception is thrown if neither fires within 1 second\n* const event = await eventRace(document.body, [`pointermove`, `pointerdown`], { timeout: 1000 });\n* ```\n* @param target Event source\n* @param eventNames Event name(s)\n* @param options Options\n* @returns \n*/\nconst eventRace = (target, eventNames, options = {}) => {\n\tconst intervalMs = options.timeoutMs ?? 601e3;\n\tconst signal = options.signal;\n\tlet triggered = false;\n\tlet disposed = false;\n\tlet timeout;\n\treturn new Promise((resolve, reject) => {\n\t\tconst onEvent = (event) => {\n\t\t\tif (`type` in event) if (eventNames.includes(event.type)) {\n\t\t\t\ttriggered = true;\n\t\t\t\tresolve(event);\n\t\t\t\tdispose();\n\t\t\t} else console.warn(`eventRace: Got event '${event.type}' that is not in race list`);\n\t\t\telse {\n\t\t\t\tconsole.warn(`eventRace: Event data does not have expected 'type' field`);\n\t\t\t\tconsole.log(event);\n\t\t\t}\n\t\t};\n\t\tfor (const name of eventNames) target.addEventListener(name, onEvent);\n\t\tconst dispose = () => {\n\t\t\tif (disposed) return;\n\t\t\tif (timeout !== void 0) clearTimeout(timeout);\n\t\t\ttimeout = void 0;\n\t\t\tdisposed = true;\n\t\t\tfor (const name of eventNames) target.removeEventListener(name, onEvent);\n\t\t};\n\t\ttimeout = setTimeout(() => {\n\t\t\tif (triggered || disposed) return;\n\t\t\tdispose();\n\t\t\treject(/* @__PURE__ */ new Error(`eventRace: Events not fired within interval. Events: ${JSON.stringify(eventNames)} Interval: ${intervalMs}`));\n\t\t}, intervalMs);\n\t\tsignal?.addEventListener(`abort`, () => {\n\t\t\tif (triggered || disposed) return;\n\t\t\tdispose();\n\t\t\treject(/* @__PURE__ */ new Error(`Abort signal received ${signal.reason}`));\n\t\t});\n\t});\n};\n//#endregion\n//#region src/moving-average.ts\n/**\n* Uses the same algorithm as {@link movingAverageLight}, but adds values automatically if\n* nothing has been manually added.\n*\n* ```js\n* // By default, 0 is added if interval elapses\n* const mat = movingAverageTimed({ interval: 1000 });\n* mat(10); // Add value of 10, returns latest average\n* \n* mat(); // Get current average\n* ```\n* \n* This is useful if you are averaging something based on events. For example calculating the\n* average speed of the pointer. If there is no speed, there is no pointer move event. Using\n* this function, `value` is added at a rate of `updateRateMs`. This timer is reset\n* every time a value is added, a bit like the `debounce` function.\n* \n* Use an AbortSignal to cancel the timer associated with the `movingAverageTimed` function.\n* @param options\n* @returns\n*/\nconst movingAverageTimed = (options) => {\n\tconst average = movingAverageLight();\n\tconst rm = rateMinimum({\n\t\t...options,\n\t\twhatToCall: (distance) => {\n\t\t\taverage(distance);\n\t\t},\n\t\tfallback() {\n\t\t\treturn options.default ?? 0;\n\t\t}\n\t});\n\treturn (v) => {\n\t\trm(v);\n\t\treturn average();\n\t};\n};\n//#endregion\n//#region src/pool.ts\n/**\n* A use of a pool resource\n*\n* Has two events, _disposed_ and _released_.\n*/\nvar PoolUser = class extends SimpleEventEmitter {\n\t_lastUpdate;\n\t_pool;\n\t_state;\n\t_userExpireAfterMs;\n\t/**\n\t* Constructor\n\t* @param key User key\n\t* @param resource Resource being used\n\t*/\n\tconstructor(key, resource) {\n\t\tsuper();\n\t\tthis.key = key;\n\t\tthis.resource = resource;\n\t\tthis._lastUpdate = performance.now();\n\t\tthis._pool = resource.pool;\n\t\tthis._userExpireAfterMs = this._pool.userExpireAfterMs;\n\t\tthis._state = `idle`;\n\t\tthis._pool.log.log(`PoolUser ctor key: ${this.key}`);\n\t}\n\t/**\n\t* Returns a human readable debug string\n\t* @returns\n\t*/\n\ttoString() {\n\t\tif (this.isDisposed) return `PoolUser. State: disposed`;\n\t\treturn `PoolUser. State: ${this._state} Elapsed: ${performance.now() - this._lastUpdate} Data: ${JSON.stringify(this.resource.data)}`;\n\t}\n\t/**\n\t* Resets countdown for instance expiry.\n\t* Throws an error if instance is disposed.\n\t*/\n\tkeepAlive() {\n\t\tif (this._state === `disposed`) throw new Error(`PoolItem disposed`);\n\t\tthis._lastUpdate = performance.now();\n\t}\n\t/**\n\t* @internal\n\t* @param reason\n\t* @returns\n\t*/\n\t_dispose(reason, data) {\n\t\tif (this._state === `disposed`) return;\n\t\tconst resource = this.resource;\n\t\tthis._state = `disposed`;\n\t\tresource._release(this);\n\t\tthis._pool.log.log(`PoolUser dispose key: ${this.key} reason: ${reason}`);\n\t\tthis.fireEvent(`disposed`, {\n\t\t\tdata,\n\t\t\treason\n\t\t});\n\t\tsuper.clearEventListeners();\n\t}\n\t/**\n\t* Release this instance\n\t* @param reason\n\t*/\n\trelease(reason) {\n\t\tif (this.isDisposed) throw new Error(`User disposed`);\n\t\tconst data = this.resource.data;\n\t\tthis._pool.log.log(`PoolUser release key: ${this.key} reason: ${reason}`);\n\t\tthis.fireEvent(`released`, {\n\t\t\tdata,\n\t\t\treason\n\t\t});\n\t\tthis._dispose(`release-${reason}`, data);\n\t}\n\tget data() {\n\t\tif (this.isDisposed) throw new Error(`User disposed`);\n\t\treturn this.resource.data;\n\t}\n\t/**\n\t* Returns true if this instance has expired.\n\t* Expiry counts if elapsed time is greater than `userExpireAfterMs`\n\t*/\n\tget isExpired() {\n\t\tif (this._userExpireAfterMs > 0) return performance.now() > this._lastUpdate + this._userExpireAfterMs;\n\t\treturn false;\n\t}\n\t/**\n\t* Returns elapsed time since last 'update'\n\t*/\n\tget elapsed() {\n\t\treturn performance.now() - this._lastUpdate;\n\t}\n\t/**\n\t* Returns true if instance is disposed\n\t*/\n\tget isDisposed() {\n\t\treturn this._state === `disposed`;\n\t}\n\t/**\n\t* Returns true if instance is neither disposed nor expired\n\t*/\n\tget isValid() {\n\t\tif (this.isDisposed || this.isExpired) return false;\n\t\tif (this.resource.isDisposed) return false;\n\t\treturn true;\n\t}\n};\n/**\n* A resource allocated in the Pool\n*/\nvar Resource = class {\n\t#state;\n\t#data;\n\t#users;\n\t#capacityPerResource;\n\t#resourcesWithoutUserExpireAfterMs;\n\t#lastUsersChange;\n\t/**\n\t* Constructor.\n\t* @param pool Pool\n\t* @param data Data\n\t*/\n\tconstructor(pool, data) {\n\t\tthis.pool = pool;\n\t\tif (data === void 0) throw new Error(`Parameter 'data' is undefined`);\n\t\tif (pool === void 0) throw new Error(`Parameter 'pool' is undefined`);\n\t\tthis.#data = data;\n\t\tthis.#lastUsersChange = 0;\n\t\tthis.#resourcesWithoutUserExpireAfterMs = pool.resourcesWithoutUserExpireAfterMs;\n\t\tthis.#capacityPerResource = pool.capacityPerResource;\n\t\tthis.#users = [];\n\t\tthis.#state = `idle`;\n\t}\n\t/**\n\t* Gets data associated with resource.\n\t* Throws an error if disposed\n\t*/\n\tget data() {\n\t\tif (this.#state === `disposed`) throw new Error(`Resource disposed`);\n\t\treturn this.#data;\n\t}\n\t/**\n\t* Changes the data associated with this resource.\n\t* Throws an error if disposed or `data` is undefined.\n\t* @param data\n\t*/\n\tupdateData(data) {\n\t\tif (this.#state === `disposed`) throw new Error(`Resource disposed`);\n\t\tif (data === void 0) throw new Error(`Parameter 'data' is undefined`);\n\t\tthis.#data = data;\n\t}\n\t/**\n\t* Returns a human-readable debug string for resource\n\t* @returns\n\t*/\n\ttoString() {\n\t\treturn `Resource (expired: ${this.isExpiredFromUsers} users: ${this.#users.length}, state: ${this.#state}) data: ${JSON.stringify(this.data)}`;\n\t}\n\t/**\n\t* Assigns a user to this resource.\n\t* @internal\n\t* @param user\n\t*/\n\t_assign(user) {\n\t\tif (this.#users.find((u) => u === user || u.key === user.key)) throw new Error(`User instance already assigned to resource`);\n\t\tthis.#users.push(user);\n\t\tthis.#lastUsersChange = performance.now();\n\t}\n\t/**\n\t* Releases a user from this resource\n\t* @internal\n\t* @param user\n\t*/\n\t_release(user) {\n\t\tthis.#users = this.#users.filter((u) => u !== user);\n\t\tthis.pool._release(user);\n\t\tthis.#lastUsersChange = performance.now();\n\t}\n\t/**\n\t* Returns true if resource can have additional users allocated\n\t*/\n\tget hasUserCapacity() {\n\t\treturn this.usersCount < this.#capacityPerResource;\n\t}\n\t/**\n\t* Returns number of uses of the resource\n\t*/\n\tget usersCount() {\n\t\treturn this.#users.length;\n\t}\n\t/**\n\t* Returns true if automatic expiry is enabled, and that interval\n\t* has elapsed since the users list has changed for this resource\n\t*/\n\tget isExpiredFromUsers() {\n\t\tif (this.#resourcesWithoutUserExpireAfterMs <= 0) return false;\n\t\tif (this.#users.length > 0) return false;\n\t\treturn performance.now() > this.#resourcesWithoutUserExpireAfterMs + this.#lastUsersChange;\n\t}\n\t/**\n\t* Returns true if instance is disposed\n\t*/\n\tget isDisposed() {\n\t\treturn this.#state === `disposed`;\n\t}\n\t/**\n\t* Disposes the resource.\n\t* If it is already disposed, it does nothing.\n\t* @param reason\n\t* @returns\n\t*/\n\tdispose(reason) {\n\t\tif (this.#state === `disposed`) return;\n\t\tconst data = this.#data;\n\t\tthis.#state = `disposed`;\n\t\tthis.pool.log.log(`Resource disposed (${reason})`);\n\t\tfor (const u of this.#users) u._dispose(`resource-${reason}`, data);\n\t\tthis.#users = [];\n\t\tthis.#lastUsersChange = performance.now();\n\t\tthis.pool._releaseResource(this, reason);\n\t\tif (this.pool.freeResource) this.pool.freeResource(data);\n\t}\n};\n/**\n* Resource pool\n* It does the housekeeping of managing a limited set of resources which are shared by 'users'. \n* All resources in the Pool are meant to be the same kind of object.\n* \n* An example is an audio sketch driven by TensorFlow. We might want to allocate a sound oscillator per detected human body. A naive implementation would be to make an oscillator for each detected body. However, because poses appear/disappear unpredictably, it's a lot of extra work to maintain the binding between pose and oscillator.\n* \n* Instead, we might use the Pool to allocate oscillators to poses. This will allow us to limit resources and clean up automatically if they haven't been used for a while.\n* \n* Resources can be added manually with `addResource()`, or automatically by providing a `generate()` function in the Pool options. They can then be accessed via a _user key_. This is meant to associated with a single 'user' of a resource. For example, if we are associating oscillators with TensorFlow poses, the 'user key' might be the id of the pose.\n*/\nvar Pool = class {\n\t_resources;\n\t_users;\n\tcapacity;\n\tuserExpireAfterMs;\n\tresourcesWithoutUserExpireAfterMs;\n\tcapacityPerResource;\n\tfullPolicy;\n\tgenerateResource;\n\tfreeResource;\n\tlog = Debug.logSet(`Pool`);\n\t/**\n\t* Constructor.\n\t*\n\t* By default, no capacity limit, one user per resource\n\t* @param options Pool options\n\t*/\n\tconstructor(options = {}) {\n\t\tthis.capacity = options.capacity ?? -1;\n\t\tthis.fullPolicy = options.fullPolicy ?? `error`;\n\t\tthis.capacityPerResource = options.capacityPerResource ?? 1;\n\t\tthis.userExpireAfterMs = options.userExpireAfterMs ?? -1;\n\t\tthis.resourcesWithoutUserExpireAfterMs = options.resourcesWithoutUserExpireAfterMs ?? -1;\n\t\tthis.generateResource = options.generate;\n\t\tthis.freeResource = options.free;\n\t\tthis._users = /* @__PURE__ */ new Map();\n\t\tthis._resources = [];\n\t\tthis.log = Debug.logSet(`Pool`, options.debug ?? false);\n\t\tconst timer = Math.max(this.userExpireAfterMs, this.resourcesWithoutUserExpireAfterMs);\n\t\tif (timer > 0) setInterval(() => {\n\t\t\tthis.maintain();\n\t\t}, timer * 1.1);\n\t}\n\t/**\n\t* Returns a debug string of Pool state\n\t* @returns\n\t*/\n\tdumpToString() {\n\t\tlet r = `Pool\n capacity: ${this.capacity} userExpireAfterMs: ${this.userExpireAfterMs} capacityPerResource: ${this.capacityPerResource}\n resources count: ${this._resources.length}`;\n\t\tconst resource = this._resources.map((r) => r.toString()).join(`\\r\\n\\t`);\n\t\tr += `\\r\\nResources:\\r\\n\\t` + resource;\n\t\tr += `\\r\\nUsers: \\r\\n`;\n\t\tfor (const [k, v] of this._users.entries()) r += `\\tk: ${k} v: ${v.toString()}\\r\\n`;\n\t\treturn r;\n\t}\n\t/**\n\t* Sorts users by longest elapsed time since update\n\t* @returns\n\t*/\n\tgetUsersByLongestElapsed() {\n\t\treturn [...this._users.values()].sort((a, b) => {\n\t\t\tconst aa = a.elapsed;\n\t\t\tconst bb = b.elapsed;\n\t\t\tif (aa === bb) return 0;\n\t\t\tif (aa < bb) return 1;\n\t\t\treturn -1;\n\t\t});\n\t}\n\t/**\n\t* Returns resources sorted with least used first\n\t* @returns\n\t*/\n\tgetResourcesSortedByUse() {\n\t\treturn [...this._resources].sort((a, b) => {\n\t\t\tif (a.usersCount === b.usersCount) return 0;\n\t\t\tif (a.usersCount < b.usersCount) return -1;\n\t\t\treturn 1;\n\t\t});\n\t}\n\t/**\n\t* Adds a shared resource to the pool\n\t* @throws Error if the capacity limit is reached or resource is null\n\t* @param resource\n\t* @returns\n\t*/\n\taddResource(resource) {\n\t\tif (resource === void 0) throw new Error(`Cannot add undefined resource`);\n\t\tif (resource === null) throw new TypeError(`Cannot add null resource`);\n\t\tif (this.capacity > 0 && this._resources.length === this.capacity) throw new Error(`Capacity limit (${this.capacity}) reached. Cannot add more.`);\n\t\tthis.log.log(`Adding resource: ${JSON.stringify(resource)}`);\n\t\tconst pi = new Resource(this, resource);\n\t\tthis._resources.push(pi);\n\t\treturn pi;\n\t}\n\t/**\n\t* Performs maintenance, removing disposed/expired resources & users.\n\t* This is called automatically when using a resource.\n\t*/\n\tmaintain() {\n\t\tlet changed = false;\n\t\tconst nuke = [];\n\t\tfor (const p of this._resources) if (p.isDisposed) {\n\t\t\tthis.log.log(`Maintain, disposed resource: ${JSON.stringify(p.data)}`);\n\t\t\tnuke.push(p);\n\t\t} else if (p.isExpiredFromUsers) {\n\t\t\tthis.log.log(`Maintain, expired resource: ${JSON.stringify(p.data)}`);\n\t\t\tnuke.push(p);\n\t\t}\n\t\tif (nuke.length > 0) {\n\t\t\tfor (const resource of nuke) resource.dispose(`diposed/expired`);\n\t\t\tchanged = true;\n\t\t}\n\t\tconst userKeysToRemove = [];\n\t\tfor (const [key, user] of this._users.entries()) if (!user.isValid) {\n\t\t\tthis.log.log(`Maintain. Invalid user: ${user.key} (Disposed: ${user.isDisposed} Expired: ${user.isExpired} Resource disposed: ${user.resource.isDisposed})`);\n\t\t\tuserKeysToRemove.push(key);\n\t\t\tuser._dispose(`invalid`, user.data);\n\t\t}\n\t\tfor (const userKey of userKeysToRemove) {\n\t\t\tthis._users.delete(userKey);\n\t\t\tchanged = true;\n\t\t}\n\t\tif (changed) this.log.log(`End: resource len: ${this._resources.length} users: ${this.usersLength}`);\n\t}\n\t/**\n\t* Iterate over resources in the pool.\n\t* To iterate over the data associated with each resource, use\n\t* `values`.\n\t*/\n\t*resources() {\n\t\tconst resource = [...this._resources];\n\t\tfor (const r of resource) yield r;\n\t}\n\t/**\n\t* Iterate over resource values in the pool.\n\t* to iterate over the resources, use `resources`.\n\t*\n\t* Note that values may be returned even though there is no\n\t* active user.\n\t*/\n\t*values() {\n\t\tconst resource = [...this._resources];\n\t\tfor (const r of resource) yield r.data;\n\t}\n\t/**\n\t* Unassociate a key with a pool item\n\t* @param userKey\n\t*/\n\trelease(userKey, reason) {\n\t\tconst pi = this._users.get(userKey);\n\t\tif (!pi) return;\n\t\tpi.release(reason ?? `Pool.release`);\n\t}\n\t/**\n\t* @internal\n\t* @param user\n\t*/\n\t_release(user) {\n\t\tthis._users.delete(user.key);\n\t}\n\t/**\n\t* @internal\n\t* @param resource\n\t* @param _\n\t*/\n\t_releaseResource(resource, _) {\n\t\tthis._resources = this._resources.filter((v) => v !== resource);\n\t}\n\t/**\n\t* Returns true if `v` has an associted resource in the pool\n\t* @param resource\n\t* @returns\n\t*/\n\thasResource(resource) {\n\t\treturn this._resources.find((v) => v.data === resource) !== void 0;\n\t}\n\t/**\n\t* Returns true if a given `userKey` is in use.\n\t* @param userKey\n\t* @returns\n\t*/\n\thasUser(userKey) {\n\t\treturn this._users.has(userKey);\n\t}\n\t/**\n\t* @internal\n\t* @param key\n\t* @param resource\n\t* @returns\n\t*/\n\t_assign(key, resource) {\n\t\tconst u = new PoolUser(key, resource);\n\t\tthis._users.set(key, u);\n\t\tresource._assign(u);\n\t\treturn u;\n\t}\n\t/**\n\t* Allocates a resource for `userKey`\n\t* @internal\n\t* @param userKey\n\t* @returns\n\t*/\n\t#allocateResource(userKey) {\n\t\tconst sorted = this.getResourcesSortedByUse();\n\t\tif (sorted.length > 0 && sorted[0].hasUserCapacity) return this._assign(userKey, sorted[0]);\n\t\tif (this.generateResource && (this.capacity < 0 || this._resources.length < this.capacity)) {\n\t\t\tthis.log.log(`capacity: ${this.capacity} resources: ${this._resources.length}`);\n\t\t\tconst resourceGenerated = this.addResource(this.generateResource());\n\t\t\treturn this._assign(userKey, resourceGenerated);\n\t\t}\n\t}\n\t/**\n\t* Return the number of users\n\t*/\n\tget usersLength() {\n\t\treturn [...this._users.values()].length;\n\t}\n\t/**\n\t* 'Uses' a resource, returning the value\n\t* @param userKey\n\t* @returns\n\t*/\n\tuseValue(userKey) {\n\t\treturn this.use(userKey).resource.data;\n\t}\n\t/**\n\t* Gets a pool item based on a 'user' key.\n\t* \n\t* The same key should return the same pool item,\n\t* for as long as it still exists.\n\t* \n\t* If a 'user' already has a resource, it will 'keep alive' their use.\n\t* If a 'user' does not already have resource\n\t* - if there is capacity, a resource is allocated to user\n\t* - if pool is full\n\t* - fullPolicy = 'error': an error is thrown\n\t* - fullPolicy = 'evictOldestUser': evicts an older user\n\t* - Throw error\n\t* @param userKey\n\t* @throws Error If all resources are used and fullPolicy = 'error'\n\t* @returns\n\t*/\n\tuse(userKey) {\n\t\tconst pi = this._users.get(userKey);\n\t\tif (pi) {\n\t\t\tpi.keepAlive();\n\t\t\treturn pi;\n\t\t}\n\t\tthis.maintain();\n\t\tconst match = this.#allocateResource(userKey);\n\t\tif (match) return match;\n\t\tif (this.fullPolicy === `error`) throw new Error(`Pool is fully used (fullPolicy: ${this.fullPolicy}, capacity: ${this.capacity})`);\n\t\tif (this.fullPolicy === `evictOldestUser`) {\n\t\t\tconst users = this.getUsersByLongestElapsed();\n\t\t\tif (users.length > 0) {\n\t\t\t\tthis.release(users[0].key, `evictedOldestUser`);\n\t\t\t\tconst match2 = this.#allocateResource(userKey);\n\t\t\t\tif (match2) return match2;\n\t\t\t}\n\t\t}\n\t\tthrow new Error(`Pool is fully used (${this.fullPolicy})`);\n\t}\n};\n/**\n* Creates an instance of a Pool\n* @param options\n* @returns\n*/\nconst create = (options = {}) => new Pool(options);\n//#endregion\n//#region src/promise-with-resolvers.ts\n/**\n* Creates a new Promise, returning the promise\n* along with its resolve and reject functions.\n* \n* ```js\n* const { promise, resolve, reject } = promiseWithResolvers();\n* \n* setTimeout(() => {\n* resolve();\n* }, 1000);\n* \n* await promise;\n* ```\n* \n* Promise would be passed somewhere that expects a promise,\n* and you're free to call `resolve` or `reject` when needed.\n* @returns \n*/\nfunction promiseWithResolvers() {\n\tlet resolve;\n\tlet reject;\n\treturn {\n\t\tpromise: new Promise((_resolve, _reject) => {\n\t\t\tresolve = _resolve;\n\t\t\treject = _reject;\n\t\t}),\n\t\tresolve,\n\t\treject\n\t};\n}\n//#endregion\n//#region src/timeout.ts\n/**\n* Returns a {@link Timeout} that can be triggered, cancelled and reset. Use {@link continuously} for interval-\n* based loops.\n*\n* Once `start()` is called, `callback` will be scheduled to execute after `interval`.\n* If `start()` is called again, the waiting period will be reset to `interval`.\n*\n* @example Essential functionality\n* ```js\n* const fn = () => {\n* console.log(`Executed`);\n* };\n* const t = timeout(fn, 60*1000);\n* t.start(); // After 1 minute `fn` will run, printing to the console\n* ```\n*\n* @example Control execution functionality\n* ```\n* t.cancel(); // Cancel it from running\n* t.start(); // Schedule again after 1 minute\n* t.start(30*1000); // Cancel that, and now scheduled after 30s\n* \n* // Get the current state of timeout\n* t.runState; // \"idle\", \"scheduled\" or \"running\"\n* ```\n*\n* Callback function receives any additional parameters passed in from start. This can be useful for passing through event data:\n*\n* @example\n* ```js\n* const t = timeout( (elapsedMs, ...args) => {\n* // args contains event data\n* }, 1000);\n* el.addEventListener(`click`, t.start);\n* ```\n*\n* Asynchronous callbacks can be used as well:\n* ```js\n* timeout(async () => {...}, 100);\n* ```\n*\n* If you don't expect to need to control the timeout, consider using {@link delay},\n* which can run a given function after a specified delay.\n* @param callback\n* @param interval\n* @returns {@link Timeout}\n*/\nconst timeout = (callback, interval) => {\n\tif (callback === void 0) throw new Error(`callback parameter is undefined`);\n\tresultThrow(integerTest(intervalToMs(interval), `aboveZero`, `interval`));\n\tlet timer;\n\tlet startedAt = 0;\n\tlet startCount = 0;\n\tlet startCountTotal = 0;\n\tlet state = `idle`;\n\tconst clear = () => {\n\t\tstartedAt = 0;\n\t\tglobalThis.clearTimeout(timer);\n\t\tstate = `idle`;\n\t};\n\tconst start = async (altInterval = interval, args) => {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tstartedAt = performance.now();\n\t\t\tconst altTimeoutMs = intervalToMs(altInterval);\n\t\t\tconst it = integerTest(altTimeoutMs, `aboveZero`, `altTimeoutMs`);\n\t\t\tif (resultIsError(it)) {\n\t\t\t\treject(resultToError(it));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tswitch (state) {\n\t\t\t\tcase `scheduled`:\n\t\t\t\t\tcancel();\n\t\t\t\t\tbreak;\n\t\t\t\tcase `running`: break;\n\t\t\t}\n\t\t\tstate = `scheduled`;\n\t\t\ttimer = globalThis.setTimeout(async () => {\n\t\t\t\tif (state !== `scheduled`) {\n\t\t\t\t\tconsole.warn(`Timeout skipping execution since state is not 'scheduled'`);\n\t\t\t\t\tclear();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst args_ = args ?? [];\n\t\t\t\tstartCount++;\n\t\t\t\tstartCountTotal++;\n\t\t\t\tstate = `running`;\n\t\t\t\tawait callback(performance.now() - startedAt, ...args_);\n\t\t\t\tstate = `idle`;\n\t\t\t\tclear();\n\t\t\t\tresolve();\n\t\t\t}, altTimeoutMs);\n\t\t});\n\t};\n\tconst cancel = () => {\n\t\tif (state === `idle`) return;\n\t\tclear();\n\t};\n\treturn {\n\t\tstart,\n\t\tcancel,\n\t\tget runState() {\n\t\t\treturn state;\n\t\t},\n\t\tget startCount() {\n\t\t\treturn startCount;\n\t\t},\n\t\tget startCountTotal() {\n\t\t\treturn startCountTotal;\n\t\t}\n\t};\n};\n//#endregion\n//#region src/rate-minimum.ts\n/**\n* Ensures that `whatToCall` is executed with a given tempo.\n* \n* ```js\n* const rm = rateMinimum({\n* fallback: () => {\n* return Math.random();\n* },\n* whatToCall: (value:number) => {\n* console.log(value);\n* },\n* interval: { secs: 10 }\n* });\n* \n* // Invokes `whatToCall`, resetting timeout\n* rm(10);\n* \n* // If we don't call rm() before 'interval' has elapsed,\n* // 'fallback' will be invoked\n* ``` \n* \n* A practical use for this is to update calculations based on firing of events\n* as well as when they don't fire. For example user input.\n* \n* ```js\n* // Average distances\n* const average = movingAverageLight();\n* const rm = rateMinimum({\n* interval: { secs: 1 },\n* whatToCall: (distance: number) => {\n* average(distance);\n* },\n* // If there are no pointermove events, distance is 0\n* fallback() {\n* return 0;\n* }\n* })\n* \n* // Report total movemeent\n* document.addEventListener(`pointermove`, event => {\n* rm(event.movementX + event.movementY);\n* });\n* ```\n* \n* @param options \n* @returns \n*/\nconst rateMinimum = (options) => {\n\tlet disposed = false;\n\tconst t = timeout(() => {\n\t\tif (disposed) return;\n\t\tt.start();\n\t\toptions.whatToCall(options.fallback());\n\t}, options.interval);\n\tif (options.abort) options.abort.addEventListener(`abort`, (_) => {\n\t\tdisposed = true;\n\t\tt.cancel();\n\t});\n\tt.start();\n\treturn (args) => {\n\t\tif (disposed) throw new Error(`AbortSignal has been fired`);\n\t\tt.start();\n\t\toptions.whatToCall(args);\n\t};\n};\n//#endregion\n//#region src/repeat.ts\n/**\n* Generates values from `produce` with a time delay.\n* `produce` can be a simple function that returns a value, an async function, or a generator.\n* If `produce` returns _undefined_, generator exits.\n* \n* @example\n* Produce a random number every 500ms\n* ```js\n* const randomGenerator = repeat(() => Math.random(), 500);\n* for await (const r of randomGenerator) {\n* // Random value every 1 second\n* // Warning: does not end by itself, a `break` statement is needed\n* }\n* ```\n*\n* @example\n* Return values from a generator every 500ms\n* ```js\n* import { repeat } from '@ixfx/flow.js'\n* import { count } from '@ixfx/numbers.js'\n* for await (const v of repeat(count(10), { fixed: 1000 })) {\n* // Do something with `v`\n* }\n* ```\n*\n* Options allow either fixed interval (wait this long between iterations), or a minimum interval (wait at least this long). The latter is useful if `produce` takes some time - it will only wait the remaining time or not at all.\n*\n* If the AbortSignal is triggered, an exception will be thrown, stopping iteration.\n* \n* @see {@link continuously}: loop that runs at a constant speed. Able to be started and stopped\n* @see {@link repeat}: run a function a certain number of times, collecting results\n*\n* @param produce Function/generator to use\n* @param opts\n* @typeParam T - Data type\n* @returns Returns value of `produce` function\n*/\nasync function* repeat(produce, opts) {\n\tconst signal = opts.signal ?? void 0;\n\tconst delayWhen = opts.delayWhen ?? `before`;\n\tconst count = opts.count ?? void 0;\n\tconst allowUndefined = opts.allowUndefined ?? false;\n\tconst minIntervalMs = opts.delayMinimum ? intervalToMs(opts.delayMinimum) : void 0;\n\tconst whileFunction = opts.while;\n\tlet cancelled = false;\n\tlet sleepMs = intervalToMs(opts.delay, intervalToMs(opts.delayMinimum, 0));\n\tlet started = performance.now();\n\tconst doDelay = async () => {\n\t\tconst elapsed = performance.now() - started;\n\t\tif (typeof minIntervalMs !== `undefined`) sleepMs = Math.max(0, minIntervalMs - elapsed);\n\t\tif (sleepMs) await sleep$1({\n\t\t\tmillis: sleepMs,\n\t\t\tsignal\n\t\t});\n\t\tstarted = performance.now();\n\t\tif (signal?.aborted) throw new Error(`Signal aborted ${signal.reason}`);\n\t};\n\tif (Array.isArray(produce)) produce = produce.values();\n\tif (opts.onStart) opts.onStart();\n\tlet errored = true;\n\tlet loopedTimes = 0;\n\ttry {\n\t\twhile (!cancelled) {\n\t\t\tloopedTimes++;\n\t\t\tif (delayWhen === `before` || delayWhen === `both`) await doDelay();\n\t\t\tconst result = await resolve(produce);\n\t\t\tif (typeof result === `undefined` && !allowUndefined) cancelled = true;\n\t\t\telse {\n\t\t\t\tyield result;\n\t\t\t\tif (delayWhen === `after` || delayWhen === `both`) await doDelay();\n\t\t\t\tif (count !== void 0 && loopedTimes >= count) cancelled = true;\n\t\t\t}\n\t\t\tif (whileFunction) {\n\t\t\t\tif (!whileFunction(loopedTimes)) cancelled = true;\n\t\t\t}\n\t\t}\n\t\terrored = false;\n\t} finally {\n\t\tcancelled = true;\n\t\tif (opts.onComplete) opts.onComplete(errored);\n\t}\n}\n/**\n* Generates values from `produce` with a time delay.\n* `produce` can be a simple function that returns a value, an function, or a generator.\n* If `produce` returns _undefined_, generator exits.\n* \n* This is the synchronous version. {@link repeat} allows for delays between loops\n* as well as asynchronous callbacks. \n*\n* If the AbortSignal is triggered, an exception will be thrown, stopping iteration.\n* \n* @param produce Function/generator to use\n* @param opts Options\n* @typeParam T - Data type\n* @returns Returns value of `produce` function\n*/\nfunction* repeatSync(produce, opts) {\n\tconst signal = opts.signal ?? void 0;\n\tconst count = opts.count ?? void 0;\n\tconst allowUndefined = opts.allowUndefined ?? false;\n\tlet cancelled = false;\n\tif (Array.isArray(produce)) produce = produce.values();\n\tif (opts.onStart) opts.onStart();\n\tlet errored = true;\n\tlet loopedTimes = 0;\n\ttry {\n\t\twhile (!cancelled) {\n\t\t\tloopedTimes++;\n\t\t\tconst result = resolveSync(produce);\n\t\t\tif (typeof result === `undefined` && !allowUndefined) cancelled = true;\n\t\t\telse {\n\t\t\t\tyield result;\n\t\t\t\tif (count !== void 0 && loopedTimes >= count) cancelled = true;\n\t\t\t\tif (signal?.aborted) cancelled = true;\n\t\t\t}\n\t\t}\n\t\terrored = false;\n\t} finally {\n\t\tcancelled = true;\n\t\tif (opts.onComplete) opts.onComplete(errored);\n\t}\n}\n/**\n* Logic for continuing repeats\n*/\n/**\n* Calls and waits for the async function `fn` repeatedly, yielding each result asynchronously.\n* Use {@link repeat} if `fn` does not need to be awaited.\n*\n* ```js\n* // Eg. iterate\n* const r = Flow.repeat(5, async () => Math.random());\n* for await (const v of r) {\n*\n* }\n* // Eg read into array\n* const results = await Array.fromAsync(Flow.repeatAwait(5, async () => Math.random()));\n* ```\n*\n* The number of repeats is determined by the first parameter. If it's a:\n* - number: how many times to repeat\n* - function: it gets called before each repeat, if it returns _false_ repeating stops.\n*\n* Using a fixed number of repeats:\n* ```js\n* // Calls - and waits - for Flow.sleep(1) 5 times\n* await Flow.repeatAwait(5, async () => {\n* // some kind of async function where we can use await\n* // eg. sleep for 1s\n* await Flow.sleep(1);\n* });\n* ```\n*\n* Using a function to dynamically determine number of repeats. The function gets\n* passed the number of repeats so far as well as the number of values produced. This\n* is count of non-undefined results from `cb` that is being repeated.\n*\n* ```js\n* async function task() {\n* // do something\n* }\n*\n* await Flow.repeatAwait(\n* (repeats, valuesProduced) => {\n* // Logic for deciding whether to repeat or not\n* if (repeats > 5) return false; // Stop repeating\n* },\n* task\n* );\n* ```\n*\n* In the above cases we're not using the return value from `fn`. This would look like:\n* ```js\n* const g = Flow.repeatAwait(5, async () => Math.random);\n* for await (const v of g) {\n* // Loops 5 times, v is the return value of calling `fn` (Math.random)\n* }\n* ```\n* @param countOrPredicate Number of times to repeat, or a function that returns _false_ to stop the loop.\n* @param fn Function to execute. Asynchronous functions will be awited\n* @typeParam V - Return type of repeating function\n* @returns Asynchronous generator of `fn` results.\n*/\n/**\n* Calls `fn` repeatedly, yielding each result.\n* Use {@link repeatAwait} if `fn` is asynchronous and you want to wait for it.\n*\n* The number of repeats is determined by the first parameter. If it's a:\n* - number: how many times to repeat\n* - function: it gets called before each repeat, if it returns _false_ repeating stops.\n*\n* Example: using a fixed number of repeats\n* ```js\n* // Results will be an array with five random numbers\n* const results = [...repeat(5, () => Math.random())];\n*\n* // Or as an generator (note also the simpler expression form)\n* for (const result of repeat(5, Math.random)) {\n* }\n* ```\n*\n* Example: Using a function to dynamically determine number of repeats\n* ```js\n* function task() {\n* }\n*\n* Flow.repeat(\n* (repeats, valuesProduced) => {\n* if (repeats > 5) return false; // Stop repeating\n* },\n* task\n* );\n* ```\n*\n* In the above cases we're not using the return value from `fn`. To do so,\n* this would look like:\n* ```js\n* const g = Flow.repeat(5, () => Math.random);\n* for (const v of g) {\n* // Loops 5 times, v is the return value of calling `fn` (Math.random)\n* }\n* ```\n*\n* Alternatives:\n* * {@link Flow.forEach | Flow.forEach} - if you don't need return values\n* * {@link Flow.interval} - if you want to repeatedly call something with an interval between\n* @param countOrPredicate Numnber of repeats, or a function that returns _false_ for when to stop.\n* @param fn Function to execute. Asynchronous functions will be awited\n* @typeParam V - Return type of repeating function\n* @returns Asynchronous generator of `fn` results.\n*/\n/**\n* Calls `fn` until `predicate` returns _false_. Awaits result of `fn` each time.\n* Yields result of `fn` asynchronously\n* @param predicate\n* @param fn\n* @typeParam V - Return type of repeating function\n*/\n/**\n* Calls `fn` until `predicate` returns _false_. Yields result of `fn`.\n* @param predicate Determiner for whether repeating continues\n* @param fn Function to call\n* @typeParam V - Return type of repeating function\n*/\n/**\n* Calls `fn`, `count` number of times, waiting for the result of `fn`.\n* Yields result of `fn` asynchronously\n* @param count Number of times to run\n* @param fn Function to run\n* @typeParam V - Return type of repeating function\n*/\n/**\n* Calls `fn`, `count` times. Assumes a synchronous function. Yields result of `fn`.\n*\n* Note that if `fn` returns _undefined_ repeats will stop.\n* @typeParam V - Return type of repeating function\n* @param count Number of times to run\n* @param fn Function to run\n*/\n/**\n* Repeatedly calls `fn`, reducing via `reduce`.\n*\n* ```js\n* repeatReduce(10, () => 1, (acc, v) => acc + v);\n* // Yields: 10\n*\n* // Multiplies random values against each other 10 times\n* repeatReduce(10, Math.random, (acc, v) => acc * v);\n* // Yields a single number\n* ```\n* @param countOrPredicate Number of times to run, or function to keep running\n* @param fn Function to call\n* @param initial Initial value\n* @param reduce Function to reduce value\n* @typeParam V - Return type of repeating function\n* @returns Final result\n*/\n//#endregion\n//#region src/req-resp-match.ts\n/**\n* Matches responses with requests, expiring requests if they do not get a response in a timely manner.\n* \n* Basic usage:\n* ```js\n* const m = new RequestResponseMatch(options);\n* // Listen for when a response matches a request\n* m.addEventListener(`match`, event => {\n* // event: { request:Req, response:Resp}\n* });\n* // Or alternatively, listen for success and failures\n* m.addEventListener(`completed`, event => {\n* // { request:Resp, response:Req|undefined, success:boolean }\n* // 'response' will be data or a string error message\n* });\n* m.request(req); // Note that some request was sent\n* ...\n* m.response(resp); // Call when a response is received\n* ```\n* \n* It's also possible to wait for specific replies:\n* ```js\n* // With a promise\n* const resp = await m.requestAwait(req);\n* // With a callback\n* m.requestCallback(req, (success, resp) => {\n* // Runs on success or failure\n* })\n* ```\n* \n* It relies on creating an id of a request/response for them to be matched up. Use the `key`\n* option if the function can generate a key from either request or response. \n* Or alternatively set both `keyRequest` and `keyResponse` for two functions that can generate a key for request and response respectively.\n* \n* \n* The easy case is if req & resp both have the same field:\n* ```js\n* const m = new RequestResponseMatch({\n* key: (reqOrResp) => {\n* // Requests has an 'id' field\n* // Response also has an 'id' field that corresponds to the request id\n* return reqOrResp.id; \n* }\n* });\n* ```\n* \n* A more complicated case:\n* ```js\n* const m = new RequestResponseMatch({\n* keyRequest: (req) => {\n* // Requests have an 'id' field\n* return req.id; \n* },\n* keyResponse: (resp) => {\n* // Responses have id under a different field\n* return resp.reply_to\n* }\n* })\n* ```\n* \n* By default, error will be thrown if a response is received that doesn't match up to any request.\n*/\nvar RequestResponseMatch = class extends SimpleEventEmitter {\n\ttimeoutMs;\n\twhenUnmatchedResponse;\n\tkeyRequest;\n\tkeyResponse;\n\t#outgoing = /* @__PURE__ */ new Map();\n\t#maintainLoop;\n\tconstructor(options = {}) {\n\t\tsuper();\n\t\tif (typeof window === `undefined`) globalThis.window = {\n\t\t\tsetTimeout,\n\t\t\tclearTimeout\n\t\t};\n\t\tthis.timeoutMs = options.timeoutMs ?? 1e3;\n\t\tthis.whenUnmatchedResponse = options.whenUnmatchedResponse ?? `throw`;\n\t\tthis.#maintainLoop = continuously(() => this.#maintain(), Math.floor(this.timeoutMs * 1.2));\n\t\tif (options.key) {\n\t\t\tif (options.keyRequest) throw new Error(`Cannot set 'keyRequest' when 'key' is set `);\n\t\t\tif (options.keyResponse) throw new Error(`Cannot set 'keyResponse' when 'key' is set `);\n\t\t\tthis.keyRequest = options.key;\n\t\t\tthis.keyResponse = options.key;\n\t\t} else {\n\t\t\tif (!options.keyRequest || !options.keyResponse) throw new Error(`Expects 'keyRequest' & 'keyResponse' fields to be set if 'key' is not set`);\n\t\t\tthis.keyRequest = options.keyRequest;\n\t\t\tthis.keyResponse = options.keyResponse;\n\t\t}\n\t}\n\t/**\n\t* Stops the maintenance loop and cleans up resources.\n\t* Should be called when done using the matcher.\n\t*/\n\tdispose() {\n\t\tthis.#maintainLoop.cancel();\n\t\tfor (const v of this.#outgoing.values()) if (v.promiseReject) v.promiseReject(`Request timeout`);\n\t\tthis.#outgoing.clear();\n\t}\n\t#maintain() {\n\t\tconst values = [...this.#outgoing.values()];\n\t\tconst now = Date.now();\n\t\tfor (const v of values) if (v.expiresAt <= now) {\n\t\t\tif (v.promiseReject) v.promiseReject(`Request timeout`);\n\t\t\tconst callback = v.callback;\n\t\t\tif (callback) callback(true, `Request timeout`);\n\t\t\tthis.fireEvent(`completed`, {\n\t\t\t\trequest: v.req,\n\t\t\t\tresponse: `Request timeout`,\n\t\t\t\tsuccess: false\n\t\t\t});\n\t\t\tthis.#outgoing.delete(v.id);\n\t\t}\n\t\treturn this.#outgoing.size > 0;\n\t}\n\t/**\n\t* For debugging, logs all pending requests and their time to expiry\n\t*/\n\tdebugDump() {\n\t\tconst values = [...this.#outgoing.values()];\n\t\tconst now = Date.now();\n\t\tfor (const v of values) {\n\t\t\tconst expire = now - v.expiresAt;\n\t\t\tconsole.log(`${v.id} Expires in: ${Math.floor(expire / 1e3).toString()}s`);\n\t\t}\n\t}\n\t/**\n\t* Makes a request.\n\t* If `callback` is set, it's equivalent to calling `requestCallback`.\n\t* If `callback` is not set, a promise is returned\n\t* @param request \n\t* @param callback \n\t* @returns \n\t*/\n\trequest(request, callback) {\n\t\tif (callback !== void 0) {\n\t\t\tthis.#requestCallback(request, callback);\n\t\t\treturn;\n\t\t}\n\t\tconst id = this.keyRequest(request);\n\t\tif (this.#outgoing.has(id)) throw new Error(`Already a request pending with id '${id}'`);\n\t\treturn this.#requestAwait(id, request);\n\t}\n\t/**\n\t* Make a request and don't wait for the outcome.\n\t* @param request \n\t*/\n\trequestAndForget(request) {\n\t\tconst id = this.keyRequest(request);\n\t\tif (this.#outgoing.has(id)) throw new Error(`Already a request pending with id '${id}'`);\n\t\tconst r = {\n\t\t\texpiresAt: Date.now() + this.timeoutMs,\n\t\t\tid,\n\t\t\treq: request\n\t\t};\n\t\tthis.#outgoing.set(id, r);\n\t\tthis.#maintainLoop.start();\n\t}\n\t/**\n\t* Make a request, returning a Promise for the outcome.\n\t* Errors will throw an exception.\n\t* \n\t* @param request \n\t* @returns \n\t*/\n\t#requestAwait(id, request) {\n\t\tif (this.#outgoing.has(id)) throw new Error(`Already a request pending with id '${id}'`);\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst r = {\n\t\t\t\texpiresAt: Date.now() + this.timeoutMs,\n\t\t\t\tid,\n\t\t\t\treq: request,\n\t\t\t\tpromiseResolve: resolve,\n\t\t\t\tpromiseReject: reject\n\t\t\t};\n\t\t\tthis.#outgoing.set(id, r);\n\t\t\tthis.#maintainLoop.start();\n\t\t});\n\t}\n\t/**\n\t* Make a request, and get notified of outcome with a callback\n\t* @param request \n\t* @param callback \n\t*/\n\t#requestCallback(request, callback) {\n\t\tconst id = this.keyRequest(request);\n\t\tif (this.#outgoing.has(id)) throw new Error(`Already a request pending with id '${id}'`);\n\t\tconst r = {\n\t\t\texpiresAt: Date.now() + this.timeoutMs,\n\t\t\tid,\n\t\t\treq: request,\n\t\t\tcallback\n\t\t};\n\t\tthis.#outgoing.set(id, r);\n\t\tthis.#maintainLoop.start();\n\t}\n\t/**\n\t* Response has been received\n\t* @param response Response\n\t* @returns _True_ if response matched a request \n\t*/\n\tresponse(response, keepAlive) {\n\t\tconst id = this.keyResponse(response);\n\t\tconst request = this.#outgoing.get(id);\n\t\tif (!request) {\n\t\t\tif (this.whenUnmatchedResponse === `throw`) throw new Error(`Unmatched response with id: '${id}'`, { cause: response });\n\t\t\treturn false;\n\t\t}\n\t\tif (keepAlive) request.expiresAt = Date.now() + this.timeoutMs;\n\t\telse this.#outgoing.delete(id);\n\t\tif (request.promiseResolve) request.promiseResolve(response);\n\t\tif (request.callback) request.callback(false, response);\n\t\tthis.fireEvent(`match`, {\n\t\t\trequest: request.req,\n\t\t\tresponse\n\t\t});\n\t\tif (!keepAlive) this.fireEvent(`completed`, {\n\t\t\trequest: request.req,\n\t\t\tresponse,\n\t\t\tsuccess: true\n\t\t});\n\t\treturn true;\n\t}\n};\n//#endregion\n//#region src/retry.ts\n/**\n* Generates an expoential backoff series of values\n* ```js\n* // Default: start at 1, power 1.1\n* for (const v of backoffGenerator()) {\n* // v: numeric value\n* }\n* ```\n*\n* By default the generator runs forever. Use either\n* `limitAttempts` or `limitValue` to stop it when it produces a\n* given quantity of values, or when the value itself reaches a threshold.\n*\n* For example:\n* ```js\n* // `values` will have five values in it\n* const values = [...backoffGenerator({ limitAttempts: 5 })];\n* // Keep generating values until max is reached\n* const values = [...backoffGenerator({ limitValue: 1000 })];\n* ```\n*\n* Options:\n* startAt: start value\n* limitAttempts: cap the number of values to generate\n* limitValue: cap the maximum calculated value\n* power: power value (default 1.1)\n*\n* @param options\n* @returns\n*/\nfunction* backoffGenerator(options = {}) {\n\tconst startAt = options.startAt ?? 1;\n\tlet limitAttempts = options.limitAttempts ?? Number.MAX_SAFE_INTEGER;\n\tconst limitValue = options.limitValue;\n\tconst power = options.power ?? 1.1;\n\tlet value = startAt;\n\tresultThrow(integerTest(limitAttempts, `aboveZero`, `limitAttempts`), numberTest(startAt, ``, `startAt`), numberTest(limitAttempts, ``, `limitAttempts`), () => limitValue !== void 0 ? numberTest(limitValue, ``, `limitValue`) : void 0, numberTest(power, ``, `power`));\n\twhile (limitAttempts > 0) {\n\t\tif (limitValue && value >= limitValue) return;\n\t\tlimitAttempts--;\n\t\tyield value;\n\t\tvalue += value ** power;\n\t}\n}\n/**\n* Keeps calling `callback` until it returns something other than _undefined_.\n* There is an exponentially-increasing delay between each retry attempt.\n*\n* If `callback` throws an exception, the retry is cancelled, bubbling the exception.\n*\n* ```js\n* // A function that only works some of the time\n* const flakyFn = async () => {\n* // do the thing\n* if (Math.random() > 0.9) return true; // success\n* return; // fake failure\n* };\n*\n* // Retry it up to five times,\n* // starting with 1000ms interval\n* const result = await retryFunction(flakyFn, {\n* limitAttempts: 5\n* });\n*\n* if (result.success) {\n* // Yay\n* } else {\n* console.log(`Failed after ${result.attempts} attempts. Elapsed: ${result.elapsed}`);\n* console.log(result.message);\n* }\n* ```\n*\n* An `AbortSignal` can be used to cancel process.\n* ```js\n* const abort = new AbortController();\n* const result = await retryFunction(cb, { signal: abort.signal });\n*\n* // Somewhere else...\n* abort('Cancel!'); // Trigger abort\n* ```\n* @param callback Function to run\n* @param options Options\n*/\nfunction retryFunction(callback, options = {}) {\n\treturn retryTask({ async probe() {\n\t\ttry {\n\t\t\tconst v = await callback();\n\t\t\tif (v === void 0) return {\n\t\t\t\tvalue: options.taskValueFallback,\n\t\t\t\terror: `Fallback`,\n\t\t\t\tsuccess: false\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tvalue: v,\n\t\t\t\tsuccess: true\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror\n\t\t\t};\n\t\t}\n\t} }, options);\n}\n/**\n* Keeps calling a 'probe' function until it returns success.\n* If you just want to call a function until it returns a value, use {@link retryFunction} instead.\n*\n* ```js\n* const task = {\n* probe:(attempts) => {\n* // attempts is number of times it has been retried\n* if (Math.random() > 0.5) {\n* // Return a succesful result\n* return { success: true }\n* } else {\n* return { success: false }\n* }\n* }\n*\n* // Run with retry\n* const t = await retryTask(task, opts);\n*\n* // Handle result\n* if (t.success) {\n* // Use the value:\n* console.log(t.value);\n* } else {\n* // Handle failure case\n* console.log(t.message);\n* }\n* ```\n*\n* What you get back is a {@link RetryResult} object, which includes:\n* `success`: _true_ if task succeeded, _false_ if it failed or was aborted\n* `attempts`: number of times task was attempted\n* `elapsed`: milliseconds elapsed since initial call to `retryTask`\n* `value`: value returned by task, fallback value if it failed, or _undefined_.\n* `message`: message describing outcome. If retry was aborted, message will be abort reason.\n* @param task\n* @param opts\n*/\nasync function retryTask(task, opts = {}) {\n\tconst signal = opts.abort;\n\tconst log = resolveLogOption(opts.log);\n\tconst predelayMs = opts.predelayMs ?? 0;\n\tconst startedAt = elapsedSince();\n\tlet attempts = 0;\n\tconst initialValue = opts.startAt ?? 1e3;\n\tconst limitAttempts = opts.limitAttempts ?? Number.MAX_SAFE_INTEGER;\n\tconst backoffGen = backoffGenerator({\n\t\t...opts,\n\t\tstartAt: initialValue,\n\t\tlimitAttempts\n\t});\n\tif (initialValue <= 0) throw new Error(`Param 'initialValue' must be above zero`);\n\tif (predelayMs > 0) try {\n\t\tawait sleep$1({\n\t\t\tmillis: predelayMs,\n\t\t\tsignal\n\t\t});\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tattempts,\n\t\t\tvalue: opts.taskValueFallback,\n\t\t\telapsed: startedAt(),\n\t\t\tmessage: getErrorMessage(error)\n\t\t};\n\t}\n\tfor (const t of backoffGen) {\n\t\tattempts++;\n\t\tconst result = await task.probe(attempts);\n\t\tif (result.success) return {\n\t\t\tsuccess: result.success,\n\t\t\tvalue: result.value,\n\t\t\tattempts,\n\t\t\telapsed: startedAt()\n\t\t};\n\t\tlog({ msg: `retry attempts: ${attempts.toString()} t: ${elapsedToHumanString(t)}` });\n\t\tif (attempts >= limitAttempts) break;\n\t\ttry {\n\t\t\tawait sleep$1({\n\t\t\t\tmillis: t,\n\t\t\t\tsignal\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tattempts,\n\t\t\t\tvalue: opts.taskValueFallback,\n\t\t\t\tmessage: getErrorMessage(error),\n\t\t\t\telapsed: startedAt()\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tmessage: `Giving up after ${attempts.toString()} attempts.`,\n\t\tsuccess: false,\n\t\tattempts,\n\t\tvalue: opts.taskValueFallback,\n\t\telapsed: startedAt()\n\t};\n}\n//#endregion\n//#region src/run-once.ts\n/**\n* Runs a function once\n*\n* ```js\n* const init = runOnce(() => {\n* // do some initialisation\n* });\n*\n* init(); // Runs once\n* init(); // no-op\n* ```\n* @param onRun\n* @returns\n*/\nconst runOnce = (onRun) => {\n\tlet run = false;\n\tlet success = false;\n\treturn () => {\n\t\tif (run) return success;\n\t\trun = true;\n\t\tsuccess = onRun();\n\t\treturn success;\n\t};\n};\n//#endregion\n//#region src/sync-wait.ts\n/**\n* Simple synchronisation. Supports only a single signal/waiter.\n* Expects one or more calls to .signal() for .forSignal() to resolve\n* \n* ```js\n* const sw = new SyncWait();\n* obj.addEventListener(`click`, () => {\n* sw.signal();\n* });\n* \n* // Wait until click event\n* await sw.forSignal();\n* ```\n* \n* `forSignal` can also take a maximum time to wait. If the\n* time elapses, an exception is thrown.\n* \n* {@link didSignal} returns _true_/_false_ if signal happened rather\n* than throwing an exception.\n* \n*/\nvar SyncWait = class {\n\t#resolve;\n\t#reject;\n\t#promise;\n\tsignal() {\n\t\tif (this.#resolve) {\n\t\t\tthis.#resolve();\n\t\t\tthis.#resolve = void 0;\n\t\t}\n\t\tthis.#promise = Promise.resolve();\n\t}\n\t/**\n\t* Throw away any previous signalled state.\n\t* This will cause any currently waiters to throw\n\t*/\n\tflush() {\n\t\tif (this.#reject) {\n\t\t\tthis.#reject(`Flushed`);\n\t\t\tthis.#reject = void 0;\n\t\t}\n\t\tthis.#resolve = void 0;\n\t\tthis.#promise = void 0;\n\t}\n\t#initPromise() {\n\t\tconst p = new Promise((resolve, reject) => {\n\t\t\tthis.#resolve = resolve;\n\t\t\tthis.#reject = reject;\n\t\t});\n\t\tthis.#promise = p;\n\t\treturn p;\n\t}\n\t/**\n\t* Call with `await` to wait until .signal() happens.\n\t* If a wait period is specified, an exception is thrown if signal does not happen within this time.\n\t* @param maximumWaitMs \n\t*/\n\tasync forSignal(maximumWaitMs) {\n\t\tlet p = this.#promise;\n\t\tp ??= this.#initPromise();\n\t\tif (maximumWaitMs) {\n\t\t\tconst reject = this.#reject;\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (reject) reject(`Timeout elapsed ${maximumWaitMs.toString()}`);\n\t\t\t}, maximumWaitMs);\n\t\t}\n\t\tawait p;\n\t\tthis.#promise = void 0;\n\t\tthis.#resolve = void 0;\n\t\tthis.#reject = void 0;\n\t}\n\t/**\n\t* An alternative to {@link forSignal}, returning _true_\n\t* if signalled, or _false_ if wait period was exceeded \n\t* \n\t* ```js\n\t* const s = await sw.didSignal(5000);\n\t* ```\n\t* @param maximumWaitMs \n\t* @returns \n\t*/\n\tasync didSignal(maximumWaitMs) {\n\t\ttry {\n\t\t\tawait this.forSignal(maximumWaitMs);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n};\n//#endregion\n//#region src/task-queue-mutable.ts\n/**\n* Simple task queue. Each task is awaited and run\n* in turn.\n* \n* The TaskQueueMutable is shared across your code,\n* so you don't create it directly. Rather, use:\n* \n* ```js\n* const queue = TaskQueueMutable.shared;\n* ```\n*\n* @example Usage\n* ```js\n* const queue = TaskQueueMutable.shared;\n* q.enqueue(async () => {\n* // Takes one second to run\n* await sleep(1000);\n* });\n* ```\n* \n* You can listen to events from the TaskQueue:\n* ```js\n* TaskQueueMutable.shared.addEventListener(`started`, () => {\n* // Queue was empty, now started processing\n* });\n* \n* TaskQueueMutable.shared.addEventListener(`empty`, () => {\n* // Queue has finished processing all items\n* });\n* \n* TaskQueueMutable.shared.addEventListener(`error`, ({error,task}) => {\n* // Reports if a task threw an exception\n* });\n* \n* ```\n*/\nvar TaskQueueMutable = class TaskQueueMutable extends SimpleEventEmitter {\n\tstatic shared = new TaskQueueMutable();\n\t_loop;\n\t_queue;\n\tconstructor() {\n\t\tsuper();\n\t\tthis._queue = Queues.mutable();\n\t\tthis._loop = continuously(() => {\n\t\t\treturn this.processQueue();\n\t\t}, 100);\n\t}\n\t/**\n\t* Adds a task. This triggers processing loop if not already started.\n\t*\n\t* ```js\n\t* queue.add(async () => {\n\t* await sleep(1000);\n\t* });\n\t* ```\n\t* @param task Task to run\n\t*/\n\tenqueue(task) {\n\t\tconst length = this._queue.enqueue(task);\n\t\tif (this._loop.runState === `idle`) {\n\t\t\tthis.fireEvent(`started`, {});\n\t\t\tthis._loop.start();\n\t\t}\n\t\treturn length;\n\t}\n\tasync processQueue() {\n\t\tconst task = this._queue.dequeue();\n\t\tif (typeof task === `undefined`) {\n\t\t\tthis.fireEvent(`empty`, {});\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst result = await task();\n\t\t\tthis.fireEvent(`progress`, {\n\t\t\t\ttask,\n\t\t\t\tremaining: this._queue.length,\n\t\t\t\tresult\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.fireEvent(`error`, {\n\t\t\t\terror,\n\t\t\t\ttask\n\t\t\t});\n\t\t}\n\t\treturn true;\n\t}\n\t/**\n\t* Clears all tasks, and stops any scheduled processing.\n\t* Currently running tasks will continue.\n\t* Fires: `empty` event if queue was not already empty\n\t* @returns \n\t*/\n\tclear() {\n\t\tif (this._queue.length === 0) return;\n\t\tthis._queue.clear();\n\t\tthis._loop.cancel();\n\t\tthis.fireEvent(`empty`, {});\n\t}\n\t/**\n\t* Returns _true_ if queue is empty\n\t*/\n\tget isEmpty() {\n\t\treturn this._queue.isEmpty;\n\t}\n\t/**\n\t* Number of items in queue\n\t*/\n\tget length() {\n\t\treturn this._queue.length;\n\t}\n\t/**\n\t* Returns the run state of the procesing loop. This is `idle` when no processing is scheduled, `scheduled` when processing is scheduled, and `running` when actively running a task.\n\t*/\n\tget runState() {\n\t\treturn this._loop.runState;\n\t}\n};\n//#endregion\n//#region src/throttle.ts\n/***\n* Throttles a function. Callback only allowed to run after minimum of `intervalMinMs`.\n*\n* @example Only handle move event every 500ms\n* ```js\n* const moveThrottled = throttle( (elapsedMs, args) => {\n* // Handle ar\n* }, 500);\n* el.addEventListener(`pointermove`, moveThrottled)\n* ```\n*\n* Note that `throttle` does not schedule invocations, but rather acts as a filter that\n* sometimes allows follow-through to `callback`, sometimes not. There is an expectation then\n* that the return function from `throttle` is repeatedly called, such as the case for handling\n* a stream of data/events.\n*\n* @example Manual trigger\n* ```js\n* // Set up once\n* const t = throttle( (elapsedMs, args) => { ... }, 5000);\n*\n* // Later, trigger throttle. Sometimes the callback will run,\n* // with data passed in to args[0]\n* t(data);\n* ```\n*/\nconst throttle = (callback, intervalMinMs) => {\n\tlet trigger = 0;\n\treturn async (...args) => {\n\t\tconst elapsed = performance.now() - trigger;\n\t\tif (elapsed >= intervalMinMs) {\n\t\t\tconst r = callback(elapsed, ...args);\n\t\t\tif (typeof r === `object`) await r;\n\t\t\ttrigger = performance.now();\n\t\t}\n\t};\n};\n//#endregion\n//#region src/timer.ts\n/**\n* A function that returns _true_ when an interval has elapsed\n*\n* ```js\n* const oneSecond = hasElapsed(1000);\n* \n* // Keep calling to check if time has elapsed.\n* // Will return _true_ when it has\n* oneSecond();\n* ```\n* \n* @param elapsed\n* @returns\n*/\nfunction hasElapsed(elapsed) {\n\tconst t = relative(intervalToMs(elapsed, 0), {\n\t\ttimer: elapsedMillisecondsAbsolute(),\n\t\tclampValue: true\n\t});\n\treturn () => t.isDone;\n}\n/**\n* Returns a function that returns the percentage of timer completion.\n* Starts when return function is first invoked.\n*\n* ```js\n* const timer = Flow.ofTotal(1000);\n* \n* // Call timer() to find out the completion\n* timer(); // Returns 0..1\n* ```\n*\n* Note that timer can exceed 1 (100%). To cap it:\n* ```js\n* Flow.ofTotal(1000, { clampValue: true });\n* ```\n*\n* Takes an {@link Interval} for more expressive time:\n* ```js\n* const timer = Flow.ofTotal({ mins: 4 });\n* ```\n* \n* Is a simple wrapper around {@link relative}.\n* @param duration\n* @see {@link ofTotalTicks} - Use ticks instead of time\n* @see {@link hasElapsed} - Simple _true/false_ if interval has elapsed\n* @returns\n*/\nfunction ofTotal(duration, opts = {}) {\n\tconst totalMs = intervalToMs(duration);\n\tif (!totalMs) throw new Error(`Param 'duration' not valid`);\n\tconst timerOpts = {\n\t\tclampValue: opts.clampValue,\n\t\twrapValue: opts.wrapValue,\n\t\ttimer: opts.timer ?? elapsedMillisecondsAbsolute()\n\t};\n\tlet t;\n\treturn () => {\n\t\tt ??= relative(totalMs, timerOpts);\n\t\treturn t.elapsed;\n\t};\n}\n/**\n* Returns a function that returns the percentage (0..1) of timer completion.\n* Uses 'ticks' as a measure. Use {@link ofTotal} if you want time-based.\n*\n* ```js\n* const timer = Flow.ofTotalTicks(1000);\n* timer(); // Returns 0..1\n* ```\n*\n* Note that timer can exceed 1 (100%). To cap it:\n* ```js\n* Flow.ofTotalTicks(1000, { clampValue: true });\n* ```\n*\n* This is a a simple wrapper around {@link relative}.\n* @see {@link ofTotal}\n* @see {@link hasElapsed}: Simple _true/false_ if interval has elapsed\n* @param totalTicks\n* @returns\n*/\nfunction ofTotalTicks(totalTicks, opts = {}) {\n\tconst timerOpts = {\n\t\t...opts,\n\t\ttimer: elapsedTicksAbsolute()\n\t};\n\tlet t;\n\treturn () => {\n\t\tt ??= relative(totalTicks, timerOpts);\n\t\treturn t.elapsed;\n\t};\n}\n/**\n* Returns a {@link ModulationTimer} that is always at 100%.\n* Opposite: {@link timerNeverDone}.\n* @returns \n*/\nconst timerAlwaysDone = () => ({\n\telapsed: 1,\n\tisDone: true,\n\treset() {},\n\tmod(amt) {}\n});\n/**\n* Returns a {@link ModulationTimer} that is always at 0%.\n* Opposite: {@link timerAlwaysDone}.\n* @returns \n*/\nconst timerNeverDone = () => ({\n\telapsed: 0,\n\tisDone: false,\n\treset() {},\n\tmod() {}\n});\n/**\n* Wraps a timer, returning a relative elapsed value based on\n* a given total. ie. percentage complete toward a total value.\n* This is useful because other parts of code don't need to know\n* about the absolute time values, you get a nice relative completion number.\n*\n* If no timer is specified, a milliseconds-based timer is used.\n*\n* ```js\n* const t = relative(1000);\n* t.elapsed; // returns % completion (0...1)\n* ```\n* It can also use a tick based timer\n* ```js\n* // Timer that is 'done' at 100 ticks\n* const t = relative(100, { timer: ticksElapsedTimer() });\n* ```\n* \n* Additional fields/methods on the timer instance\n* ```js\n* t.isDone; // _true_ if .elapsed has reached (or exceeded) 1\n* t.reset(); // start from zero again\n* ```\n*\n* Options:\n* * timer: timer to use. If not specified, `elapsedMillisecondsAbsolute()` is used.\n* * clampValue: if _true_, return value is clamped to 0..1 (default: _false_)\n* * wrapValue: if _true_, return value wraps around continously from 0..1..0 etc. (default: _false_)\n* \n* Note that `clampValue` and `wrapValue` are mutually exclusive: only one can be _true_, but both can be _false_.\n* \n* With options\n* ```js\n* // Total duration of 1000 ticks\n* const t = Timer.relative(1000, { timer: ticksElapsedTimer(); clampValue:true });\n* ```\n*\n* If `total` is Infinity, a 'always completed; timer is returned. Use a value of `NaN` for a\n* timer that always returns 0.\n* @private\n* @param total Total (of milliseconds or ticks, depending on timer source)\n* @param options Options\n* @returns Timer\n*/\nconst relative = (total, options = {}) => {\n\tif (!Number.isFinite(total)) return timerAlwaysDone();\n\telse if (Number.isNaN(total)) return timerNeverDone();\n\tconst clampValue = options.clampValue ?? false;\n\tconst wrapValue = options.wrapValue ?? false;\n\tif (clampValue && wrapValue) throw new Error(`clampValue and wrapValue cannot both be enabled`);\n\tlet modulationAmount = 1;\n\tconst timer = options.timer ?? elapsedMillisecondsAbsolute();\n\tlet lastValue = 0;\n\tconst computeElapsed = (value) => {\n\t\tlastValue = value;\n\t\tlet v = value / (total * modulationAmount);\n\t\tif (clampValue) v = clamp(v);\n\t\telse if (wrapValue && v >= 1) v = v % 1;\n\t\treturn v;\n\t};\n\treturn {\n\t\tmod(amt) {\n\t\t\tmodulationAmount = amt;\n\t\t},\n\t\tget isDone() {\n\t\t\treturn computeElapsed(lastValue) >= 1;\n\t\t},\n\t\tget elapsed() {\n\t\t\treturn computeElapsed(timer.elapsed);\n\t\t},\n\t\treset: () => {\n\t\t\ttimer.reset();\n\t\t}\n\t};\n};\n/**\n* A timer based on frequency: cycles per unit of time. These timers return a number from\n* 0..1 indicating position with a cycle.\n*\n* In practice, timers are used to 'drive' something like an Oscillator.\n*\n* By default it uses elapsed clock time as a basis for frequency. ie., cycles per second.\n*\n* It returns a `ModulationTimer`, which allows for a modulation amount to be continually applied\n* to the calculation of the 'position' within a cycle.\n*\n* @example Prints around 0/0.5 each second, as timer is half a cycle per second\n* ```js\n* const t = frequencyTimer(0.5);\n* setInterval(() => {\n* console.log(t.elapsed);\n* }, 1000);\n* ```\n* @param frequency Cycles\n* @param options Options for timer\n* @returns\n*/\nconst frequencyTimer = (frequency, options = {}) => {\n\tconst timer = options.timer ?? elapsedMillisecondsAbsolute();\n\tconst cyclesPerSecond = frequency / 1e3;\n\tlet modulationAmount = 1;\n\tconst computeElapsed = () => {\n\t\tconst v = timer.elapsed * (cyclesPerSecond * modulationAmount);\n\t\tconst f = v - Math.floor(v);\n\t\tif (f < 0) throw new Error(`Unexpected cycle fraction less than 0. Elapsed: ${v} f: ${f}`);\n\t\tif (f > 1) throw new Error(`Unexpected cycle fraction more than 1. Elapsed: ${v} f: ${f}`);\n\t\treturn f;\n\t};\n\treturn {\n\t\tmod: (amt) => {\n\t\t\tmodulationAmount = amt;\n\t\t},\n\t\treset: () => {\n\t\t\ttimer.reset();\n\t\t},\n\t\tget isDone() {\n\t\t\treturn computeElapsed() >= 1;\n\t\t},\n\t\tget elapsed() {\n\t\t\treturn computeElapsed();\n\t\t}\n\t};\n};\n/**\n* A timer that uses clock time. Start time is from the point of invocation.\n*\n* ```js\n* const t = elapsedMillisecondsAbsolute();\n* t.reset(); // reset start\n* t.elapsed; // milliseconds since start\n* ```\n* @returns {Timer}\n* @see {ticksElapsedTimer}\n*/\nconst elapsedMillisecondsAbsolute = () => {\n\tlet start = performance.now();\n\treturn {\n\t\treset: () => {\n\t\t\tstart = performance.now();\n\t\t},\n\t\tget elapsed() {\n\t\t\treturn performance.now() - start;\n\t\t}\n\t};\n};\n/**\n* A timer that progresses with each call to `elapsed`.\n*\n* The first call to elapsed will return 1.\n*\n* ```js\n* const timer = elapsedTicksAbsolute();\n* timer.reset(); // Reset to 0\n* timer.elapsed; // Number of ticks (and also increment ticks)\n* timer.peek; // Number of ticks (without incrementing)\n* ```\n* \n* Like other {@link Timer} functions, returns with a `isDone` field,\n* but this will always return _true_.\n* @returns {Timer}\n* @see {elapsedMillisecondsAbsolute}\n*/\nconst elapsedTicksAbsolute = () => {\n\tlet start = 0;\n\treturn {\n\t\treset: () => {\n\t\t\tstart = 0;\n\t\t},\n\t\tget peek() {\n\t\t\treturn start;\n\t\t},\n\t\tget elapsed() {\n\t\t\treturn ++start;\n\t\t}\n\t};\n};\n/**\n* Wraps `timer`, computing a value based on its elapsed value.\n* `fn` creates this value.\n* \n* ```js\n* const t = timerWithFunction(v=>v/2, relativeTimer(1000));\n* t.compute();\n* ```\n* \n* In the above case, `relativeTimer(1000)` creates a timer that goes\n* from 0..1 over one second. `fn` will divide that value by 2, so\n* `t.compute()` will yield values 0..0.5.\n* \n* @param fn \n* @param timer \n* @returns \n*/\nconst timerWithFunction = (fn, timer) => {\n\tif (typeof fn !== `function`) throw new Error(`Param 'fn' should be a function. Got: ${typeof fn}`);\n\tlet startCount = 1;\n\treturn {\n\t\tget elapsed() {\n\t\t\treturn timer.elapsed;\n\t\t},\n\t\tget isDone() {\n\t\t\treturn timer.isDone;\n\t\t},\n\t\tget runState() {\n\t\t\tif (timer.isDone) return `idle`;\n\t\t\treturn `scheduled`;\n\t\t},\n\t\tget startCount() {\n\t\t\treturn startCount;\n\t\t},\n\t\tget startCountTotal() {\n\t\t\treturn startCount;\n\t\t},\n\t\tcompute: () => {\n\t\t\tconst elapsed = timer.elapsed;\n\t\t\treturn fn(elapsed);\n\t\t},\n\t\treset: () => {\n\t\t\ttimer.reset();\n\t\t\tstartCount++;\n\t\t}\n\t};\n};\n//#endregion\n//#region src/update-outdated.ts\n/**\n* Calls the async `fn` to generate a value if there is no prior value or\n* `interval` has elapsed since value was last generated.\n* @example\n* ```js\n* const f = updateOutdated(async () => {\n* const r = await fetch(`blah`);\n* return await r.json();\n* }, 60*1000);\n*\n* // Result will be JSON from fetch. If fetch happened already in the\n* // last 60s, return cached result. Otherwise it will fetch data\n* const result = await f();\n* ```\n*\n* Callback `fn` is passed how many milliseconds have elapsed since last update. Its minimum value will be `interval`.\n*\n* ```js\n* const f = updateOutdated(async elapsedMs => {\n* // Do something with elapsedMs?\n* }, 60*1000;\n* ```\n*\n* There are different policies for what to happen if `fn` fails. `slow` is the default.\n* * `fast`: Invocation will happen immediately on next attempt\n* * `slow`: Next invocation will wait `interval` as if it was successful\n* * `backoff`: Attempts will get slower and slower until next success. Interval is multipled by 1.2 each time.\n*\n* @param fn Async function to call. Must return a value.\n* @param interval Maximum age of cached result\n* @param updateFail `slow` by default\n* @typeParam V - Return type of `fn`\n* @returns Value\n*/\nconst updateOutdated = (fn, interval, updateFail = `slow`) => {\n\tlet lastRun = 0;\n\tlet lastValue;\n\tlet intervalMsCurrent = intervalToMs(interval, 1e3);\n\treturn () => new Promise(async (resolve, reject) => {\n\t\tconst elapsed = performance.now() - lastRun;\n\t\tif (lastValue === void 0 || elapsed > intervalMsCurrent) try {\n\t\t\tlastRun = performance.now();\n\t\t\tlastValue = await fn(elapsed);\n\t\t\tintervalMsCurrent = intervalToMs(interval, 1e3);\n\t\t} catch (error) {\n\t\t\tif (updateFail === `fast`) {\n\t\t\t\tlastValue = void 0;\n\t\t\t\tlastRun = 0;\n\t\t\t} else if (updateFail === `backoff`) intervalMsCurrent = Math.floor(intervalMsCurrent * 1.2);\n\t\t\treject(error);\n\t\t\treturn;\n\t\t}\n\t\tresolve(lastValue);\n\t});\n};\n//#endregion\n//#region src/wait-for-value.ts\n/**\n* Queue of a single item, only once, allows for simple synchronisation.\n* \n* It has a 'first write wins' behaviour\n* \n* ```js\n* const q = new WaitForValue(); // or singleItem();\n* \n* // In some part of the code add a value\n* const value = q.add(`some-val`);\n* \n* // Somewhere else, wait for value\n* await q.get(value);\n* ```\n* \n* It is not possible to `add` a second item (an exception will throw), however\n* it is possible to call `get` as many times as you need.\n* \n* The `.isUsed` property allows you to to check if a value\n* has been already added to the queue.\n* \n* Based on: https://2ality.com/2024/05/proposal-promise-with-resolvers.html\n*/\nvar WaitForValue = class {\n\t#promise;\n\t#resolve;\n\t#written = false;\n\tconstructor() {\n\t\tconst { promise, resolve } = promiseWithResolvers();\n\t\tthis.#promise = promise;\n\t\tthis.#resolve = resolve;\n\t}\n\t/**\n\t* Gets the promise\n\t* ```js\n\t* const wv = new WaitForValue();\n\t* \n\t* await wv.get();\n\t* ```\n\t* @returns\n\t*/\n\tget() {\n\t\treturn this.#promise;\n\t}\n\t/**\n\t* Adds a value, triggering promise resolution.\n\t* \n\t* Throws an exception if queue has already been used. Use {@link isUsed} to check.\n\t* @param value \n\t*/\n\tadd(value) {\n\t\tif (this.#written) throw new Error(`QueueSingleUse has already been used`);\n\t\tthis.#written = true;\n\t\tthis.#resolve(value);\n\t}\n\t/**\n\t* Returns _true_ if a value has been added\n\t* and therefore no more values can be written\n\t*/\n\tget isUsed() {\n\t\treturn this.#written;\n\t}\n};\n/**\n* {@inheritDoc WaitForValue}\n*/\nconst singleItem = () => new WaitForValue();\n//#endregion\n//#region src/wait-for.ts\n/**\n* Helper function for calling code that should fail after a timeout.\n* In short, it allows you to signal when the function succeeded, to cancel it, or\n* to be notified if it was canceled or completes.\n*\n* It does not execute or track the outcome of execution itself. Rather it's a bit\n* of machinery that needs to be steered by your own logic.\n* \n* `waitFor` takes a timeout, and two lifecycle functions, `onAborted` and `onComplete`.\n* `onAborted` is called if the timeout has elapsed. `onComplete` will run on either success or failure.\n* \n* ```js\n* waitFor(1000, \n* (error) => {\n* // Failed\n* },\n* (success) => {\n* if (success) {\n* // Succeeded\n* }\n* });\n* ```\n* \n* When calling `waitFor` you get back a function to signal success or failure:\n* ```js\n* const done = waitFor(1000, onAborted, onComplete);\n* done(); // No parameters signals success\n* done('failed'); // A string parameter indicates failure\n* ```\n* \n* @example Compact\n* ```js\n* const done = waitFor(1000,\n* (reason) => {\n* console.log(`Aborted: ${reason}`);\n* });\n*\n* try {\n* runSomethingThatMightScrewUp();\n* done(); // Signal it succeeded\n* } catch (e) {\n* done(e); // Signal there was an error\n* }\n* ```\n* \n* @example Verbose\n* ```js\n* // This function is called by `waitFor` if it was cancelled\n* const onAborted = (reason:string) => {\n* // 'reason' is a string describing why it has aborted.\n* // ie: due to timeout or because done() was called with an error\n* };\n*\n* // This function is called by `waitFor` if it completed\n* const onComplete = (success:boolean) => {\n* // Called if we were aborted or finished succesfully.\n* // onComplete will be called after onAborted, if it was an error case\n* }\n*\n* // If done() is not called after 1000, onAborted will be called\n* // if done() is called or there was a timeout, onComplete is called\n* const done = waitFor(1000, onAborted, onComplete);\n*\n* // Signal completed successfully (thus calling onComplete(true))\n* done();\n*\n* // Signal there was an error (thus calling onAborted and onComplete(false))\n* done(`Some error`);\n* ```\n*\n* The completion handler is useful for removing event handlers.\n*\n\n* @param timeoutMs\n* @param onAborted\n* @param onComplete\n* @returns\n*/\nconst waitFor = (timeoutMs, onAborted, onComplete) => {\n\tlet t;\n\tlet success = false;\n\tconst done = (error) => {\n\t\tif (t !== void 0) {\n\t\t\tglobalThis.clearTimeout(t);\n\t\t\tt = void 0;\n\t\t}\n\t\tif (error) onAborted(error);\n\t\telse success = true;\n\t\tif (onComplete !== void 0) onComplete(success);\n\t};\n\tt = globalThis.setTimeout(() => {\n\t\tt = void 0;\n\t\ttry {\n\t\t\tonAborted(`Timeout after ${timeoutMs}ms`);\n\t\t} finally {\n\t\t\tif (onComplete !== void 0) onComplete(success);\n\t\t}\n\t}, timeoutMs);\n\treturn done;\n};\n//#endregion\nexport { DispatchList, Pool, PoolUser, RequestResponseMatch, Resource, state_machine_exports as StateMachine, SyncWait, TaskQueueMutable, WaitForValue, backoffGenerator, create, debounce, delay, delayLoop, elapsedMillisecondsAbsolute, elapsedTicksAbsolute, eventRace, everyNth, frequencyTimer, hasElapsed, iterateBreadth, iterateDepth, movingAverageTimed, ofTotal, ofTotalTicks, promiseWithResolvers, rateMinimum, relative, repeat, repeatSync, retryFunction, retryTask, run, runOnce, runSingle, singleItem, sleep, throttle, timeout, timerAlwaysDone, timerNeverDone, timerWithFunction, updateOutdated, waitFor };\n","import { keyValueSorter } from \"@ixfx/core\";\nimport { SimpleEventEmitter } from \"@ixfx/events\";\nimport { maxFast, minFast, numberArrayCompute, totalFast } from \"@ixfx/numbers\";\nimport { timeout } from \"@ixfx/flow\";\nimport { getOrGenerateSync } from \"@ixfx/core/maps\";\n//#region src/changes.ts\n/**\n* Run a function if a value changes\n* ```js\n* const r = handleChangeResult(trackNumberChange, (value) => {\n* // Called when value changes\n* });\n* r(10);\n* ```\n* @param monitor \n* @param onChanged \n* @param onNotChanged \n* @returns \n*/\nfunction handleChangeResult(monitor, onChanged, onNotChanged) {\n\treturn (v) => {\n\t\tconst r = monitor(v);\n\t\tif (r.changed) onChanged(v, r.changes, r.total);\n\t\telse if (typeof onNotChanged !== `undefined`) onNotChanged(v, r.identicalRun, r.total);\n\t};\n}\n/**\n* Returns a function to monitor value changes.\n* ```js\n* const f = trackNumberChange(true);\n* f(10); // { changed: true, changesCount: 1 }\n* f(10); // { changed: false, changesCount: 1 }\n* ```\n* \n* Default options:\n* * nanHandling: error\n* * includeFirstValueInCount: false\n* \n* NaN handling:\n* * allow: use NaN value as a legal value and report a change\n* * skip: ignore NaN values, reporting back no change and use the same changes count\n* * error: throw an error if a NaN value is received\n* \n* \n* @returns \n*/\nfunction trackNumberChange(options = {}) {\n\tconst nanHandling = options.nanHandling ?? `error`;\n\tconst includeFirstValueInCount = options.includeFirstValueInCount ?? false;\n\tlet lastValue = options.initial;\n\tlet changes = 0;\n\tlet total = 0;\n\tlet identicalRun = 0;\n\treturn (v) => {\n\t\tif (typeof v !== `number`) throw new TypeError(`Parameter should be number. Got type: ${typeof v}`);\n\t\tif (Number.isNaN(v)) switch (nanHandling) {\n\t\t\tcase `error`: throw new Error(`Parameter is NaN`);\n\t\t\tcase `skip`: return {\n\t\t\t\tchanged: false,\n\t\t\t\tchanges,\n\t\t\t\ttotal,\n\t\t\t\tidenticalRun\n\t\t\t};\n\t\t}\n\t\ttotal++;\n\t\tlet eq = lastValue === v;\n\t\tif (Number.isNaN(lastValue) && Number.isNaN(v)) eq = true;\n\t\tif (!eq) {\n\t\t\tidenticalRun = 0;\n\t\t\tif (lastValue !== void 0 || includeFirstValueInCount) changes++;\n\t\t\tlastValue = v;\n\t\t\treturn {\n\t\t\t\tchanged: true,\n\t\t\t\tchanges,\n\t\t\t\ttotal,\n\t\t\t\tidenticalRun\n\t\t\t};\n\t\t} else identicalRun++;\n\t\treturn {\n\t\t\tchanged: false,\n\t\t\tchanges,\n\t\t\ttotal,\n\t\t\tidenticalRun\n\t\t};\n\t};\n}\n/**\n* Returns a function to track changes in a boolean value\n* ```js\n* const t = trackBooleanChange();\n* t(true); // { changed:false }\n* t(true); // { changed:false }\n* t(false); // { changed: true }\n* ```\n* \n* Default options:\n* * includeFirstValueInCount: false\n* @param options \n* @returns \n*/\nfunction trackBooleanChange(options = {}) {\n\tconst includeFirstValueInCount = options.includeFirstValueInCount ?? false;\n\tlet lastValue = options.initial;\n\tlet changes = 0;\n\tlet total = 0;\n\tlet identicalRun = 0;\n\treturn (v) => {\n\t\tif (typeof v !== `boolean`) throw new TypeError(`Parameter should be boolean. Got type: ${typeof v}`);\n\t\ttotal++;\n\t\tif (lastValue !== v) {\n\t\t\tidenticalRun = 0;\n\t\t\tif (lastValue !== void 0 || includeFirstValueInCount) changes++;\n\t\t\tlastValue = v;\n\t\t\treturn {\n\t\t\t\tchanged: true,\n\t\t\t\tchanges,\n\t\t\t\ttotal,\n\t\t\t\tidenticalRun\n\t\t\t};\n\t\t} else identicalRun++;\n\t\treturn {\n\t\t\tchanged: false,\n\t\t\tchanges,\n\t\t\ttotal,\n\t\t\tidenticalRun\n\t\t};\n\t};\n}\n//#endregion\n//#region src/frequency-mutable.ts\n/**\n* Wraps a {@link FrequencyTracker}, but ignores values that come from the same source.\n*/\nvar GatedFrequencyTracker = class {\n\tft;\n\tsources = /* @__PURE__ */ new Set();\n\tconstructor(keyString) {\n\t\tthis.ft = new FrequencyTracker(keyString);\n\t}\n\tadd(value, source) {\n\t\tif (this.sources.has(source)) return;\n\t\tthis.sources.add(source);\n\t\tthis.ft.add(value);\n\t}\n\tclear() {\n\t\tthis.ft.clear();\n\t\tthis.sources.clear();\n\t}\n};\n/**\n* Frequency keeps track of how many times a particular value is seen, but\n* unlike a Map it does not store the data. By default compares\n* items by value (via JSON.stringify).\n*\n* Fires `change` event when items are added or it is cleared.\n*\n* Overview\n* ```\n* const fh = new FrequencyTracker();\n* fh.add(value); // adds a value\n* fh.clear(); // clears all data\n* fh.keys() / .values() // returns an iterator for keys and values\n* fh.toArray(); // returns an array of data in the shape [[key,freq],[key,freq]...]\n* ```\n*\n* Usage\n* ```\n* const fh = new FrequencyTracker();\n* fh.add(`apples`); // Count an occurence of `apples`\n* fh.add(`oranges)`;\n* fh.add(`apples`);\n*\n* const fhData = fh.toArray(); // Expect result [[`apples`, 2], [`oranges`, 1]]\n* fhData.forEach((d) => {\n* const [key,freq] = d;\n* console.log(`Key '${key}' occurred ${freq} time(s).`);\n* })\n* ```\n*\n* Custom key string\n* ```\n* const fh = frequency( person => person.name);\n* // All people with name `Samantha` will be counted in same group\n* fh.add({name:`Samantha`, city:`Brisbane`});\n* ```\n* @typeParam V - Type of items\n*/\nvar FrequencyTracker = class extends SimpleEventEmitter {\n\t#store;\n\t#keyString;\n\t#cachedResults;\n\t/**\n\t* Constructor\n\t* @param keyString Function to key items. Uses JSON.stringify by default\n\t*/\n\tconstructor(keyString) {\n\t\tsuper();\n\t\tthis.#store = /* @__PURE__ */ new Map();\n\t\tif (typeof keyString === `undefined`) keyString = (a) => {\n\t\t\tif (a === void 0) throw new Error(`Cannot create key for undefined`);\n\t\t\treturn typeof a === `string` ? a : JSON.stringify(a);\n\t\t};\n\t\tthis.#keyString = keyString;\n\t}\n\t/**\n\t* Clear data. Fires `change` event\n\t*/\n\tclear() {\n\t\tthis.#store.clear();\n\t\tthis.#cachedResults = void 0;\n\t\tthis.fireEvent(`change`, { context: this });\n\t}\n\t/**\n\t* @returns Iterator over keys (ie. groups)\n\t*/\n\tkeys() {\n\t\treturn this.#store.keys();\n\t}\n\t/**\n\t* @returns Iterator over frequency counts\n\t*/\n\tvalues() {\n\t\treturn this.#store.values();\n\t}\n\t/**\n\t* @returns Copy of entries as an array of `[key, count]`\n\t*/\n\ttoArray() {\n\t\treturn [...this.#store.entries()];\n\t}\n\t/**\n\t* Returns a string with keys and counts, useful for debugging.\n\t* @returns\n\t*/\n\tdebugString() {\n\t\tlet t = ``;\n\t\tfor (const [key, count] of this.#store.entries()) t += `${key}: ${count.toString()}, `;\n\t\tif (t.endsWith(`, `)) return t.slice(0, Math.max(0, t.length - 2));\n\t\treturn t;\n\t}\n\t/**\n\t*\n\t* @param value Value to count\n\t* @returns Frequency of value, or _undefined_ if it does not exist\n\t*/\n\tfrequencyOf(value) {\n\t\tif (typeof value === `string`) return this.#store.get(value);\n\t\tconst key = this.#keyString(value);\n\t\treturn this.#store.get(key);\n\t}\n\t/**\n\t* Gets the relative frequency of `value`.\n\t* @param value Value to count\n\t* @returns Relative frequency of `value`, or _undefined_ if it does not exist\n\t*/\n\trelativeFrequencyOf(value) {\n\t\tlet freq;\n\t\tif (typeof value === `string`) freq = this.#store.get(value);\n\t\telse {\n\t\t\tconst key = this.#keyString(value);\n\t\t\tfreq = this.#store.get(key);\n\t\t}\n\t\tif (freq === void 0) return;\n\t\tconst mma = this.computeValues();\n\t\treturn freq / mma.total;\n\t}\n\t/**\n\t* Returns copy of entries as an array\n\t* @returns Copy of entries as an array\n\t*/\n\t*entries() {\n\t\tyield* this.#store.entries();\n\t}\n\t/**\n\t* Yields key-value pairs, passing through the filter predicate\n\t* @param predicate \n\t*/\n\t*filterByTally(predicate) {\n\t\tfor (const kv of this.#store.entries()) if (predicate(kv[1])) yield kv;\n\t}\n\t/**\n\t* Yields key-value pairs, passing through the filter predicate.\n\t* \n\t* Passes a relative tally amount\n\t* ```js\n\t* // Get all key-value pairs where tally is 10% of total\n\t* for (const kv of fm.filterByRelativeTally(t=>t>0.1)) {\n\t* }\n\t* ```\n\t* @param predicate \n\t*/\n\t*filterByRelativeTally(predicate) {\n\t\tconst total = this.computeValues().total;\n\t\tfor (const kv of this.#store.entries()) if (predicate(kv[1] / total)) yield kv;\n\t}\n\t/**\n\t* Calculate min,max,avg,total & count from values\n\t* @returns Returns `{min,max,avg,total}`\n\t*/\n\tcomputeValues() {\n\t\tif (!this.#cachedResults) this.#cachedResults = numberArrayCompute([...this.values()]);\n\t\treturn this.#cachedResults;\n\t}\n\t/**\n\t* Return entries sorted\n\t* @param sortStyle Sorting style (default: _value_, ie. count)\n\t* @returns Sorted array of [key,frequency]\n\t*/\n\tentriesSorted(sortStyle = `value`) {\n\t\treturn keyValueSorter(sortStyle)([...this.entries()]);\n\t}\n\t/**\n\t* Add one or more values, firing _change_ event.\n\t* @param values Values to add. Fires _change_ event after adding item(s)\n\t*/\n\tadd(...values) {\n\t\tif (typeof values === `undefined`) throw new Error(`Param 'values' undefined`);\n\t\tthis.#cachedResults = void 0;\n\t\tconst keys = values.map((v) => this.#keyString(v));\n\t\tfor (const key of keys) {\n\t\t\tconst score = this.#store.get(key) ?? 0;\n\t\t\tthis.#store.set(key, score + 1);\n\t\t}\n\t\tthis.fireEvent(`change`, { context: this });\n\t}\n};\nconst frequency = (keyString) => new FrequencyTracker(keyString);\n//#endregion\n//#region src/tracker-base.ts\n/**\n* Base tracker class\n*/\nvar TrackerBase = class {\n\t/**\n\t* @ignore\n\t*/\n\tseenCount;\n\t/**\n\t* @ignore\n\t*/\n\tstoreIntermediate;\n\t/**\n\t* @ignore\n\t*/\n\tresetAfterSamples;\n\t/**\n\t* @ignore\n\t*/\n\tsampleLimit;\n\tid;\n\tdebug;\n\tconstructor(opts = {}) {\n\t\tthis.id = opts.id ?? `tracker`;\n\t\tthis.debug = opts.debug ?? false;\n\t\tthis.sampleLimit = opts.sampleLimit ?? -1;\n\t\tthis.resetAfterSamples = opts.resetAfterSamples ?? -1;\n\t\tthis.storeIntermediate = opts.storeIntermediate ?? (this.sampleLimit > -1 || this.resetAfterSamples > -1);\n\t\tthis.seenCount = 0;\n\t\tif (this.debug) console.log(`TrackerBase: sampleLimit: ${this.sampleLimit} resetAfter: ${this.resetAfterSamples} store: ${this.storeIntermediate}`);\n\t}\n\t/**\n\t* Reset tracker\n\t*/\n\treset() {\n\t\tthis.seenCount = 0;\n\t\tthis.onReset();\n\t}\n\t/**\n\t* Adds a value, returning computed result.\n\t* \n\t* At this point, we check if the buffer is larger than `resetAfterSamples`. If so, `reset()` is called.\n\t* If not, we check `sampleLimit`. If the buffer is twice as large as sample limit, `trimStore()` is\n\t* called to take it down to sample limit, and `onTrimmed()` is called.\n\t* @param p \n\t* @returns \n\t*/\n\tseen(...p) {\n\t\tif (this.resetAfterSamples > 0 && this.seenCount > this.resetAfterSamples) this.reset();\n\t\telse if (this.sampleLimit > 0 && this.seenCount > this.sampleLimit * 2) {\n\t\t\tthis.seenCount = this.trimStore(this.sampleLimit);\n\t\t\tthis.onTrimmed(`resize`);\n\t\t}\n\t\tthis.seenCount += p.length;\n\t\tconst t = this.filterData(p);\n\t\treturn this.computeResults(t);\n\t}\n};\n//#endregion\n//#region src/primitive-tracker.ts\nvar PrimitiveTracker = class extends TrackerBase {\n\tvalues;\n\ttimestamps;\n\tconstructor(opts) {\n\t\tsuper(opts);\n\t\tthis.values = [];\n\t\tthis.timestamps = [];\n\t}\n\t/**\n\t* Reduces size of value store to `limit`. Returns\n\t* number of remaining items\n\t* @param limit\n\t*/\n\ttrimStore(limit) {\n\t\tif (limit >= this.values.length) return this.values.length;\n\t\tthis.values = this.values.slice(-limit);\n\t\tthis.timestamps = this.timestamps.slice(-limit);\n\t\treturn this.values.length;\n\t}\n\tonTrimmed(reason) {}\n\tget last() {\n\t\treturn this.values.at(-1);\n\t}\n\tget initial() {\n\t\treturn this.values.at(0);\n\t}\n\t/**\n\t* Returns number of recorded values (this can include the initial value)\n\t*/\n\tget size() {\n\t\treturn this.values.length;\n\t}\n\t/**\n\t* Returns the elapsed time, in milliseconds since the instance was created\n\t*/\n\tget elapsed() {\n\t\tif (this.values.length === 0) throw new Error(`No values seen yet`);\n\t\treturn Date.now() - this.timestamps[0];\n\t}\n\t/**\n\t* Returns the time, in milliseconds, covering the initial and last values.\n\t* Returns NaN if either of these is missing.\n\t*/\n\tget timespan() {\n\t\tconst oldest = this.timestamps.at(0);\n\t\tconst newest = this.timestamps.at(-1);\n\t\tif (oldest === void 0) return NaN;\n\t\tif (newest === void 0) return NaN;\n\t\treturn newest - oldest;\n\t}\n\tonReset() {\n\t\tthis.values = [];\n\t\tthis.timestamps = [];\n\t}\n\t/**\n\t* Tracks a value\n\t*/\n\tfilterData(rawValues) {\n\t\tconst last = {\n\t\t\tvalue: rawValues.at(-1),\n\t\t\tat: performance.now()\n\t\t};\n\t\tconst values = rawValues.map((value) => ({\n\t\t\tat: performance.now(),\n\t\t\tvalue\n\t\t}));\n\t\tif (this.storeIntermediate) {\n\t\t\tthis.values.push(...rawValues);\n\t\t\tthis.timestamps.push(...values.map((v) => v.at));\n\t\t} else switch (this.values.length) {\n\t\t\tcase 0:\n\t\t\t\tthis.values.push(last.value);\n\t\t\t\tthis.timestamps.push(last.at);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tthis.values[1] = last.value;\n\t\t\t\tthis.timestamps[1] = last.at;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tthis.values.push(last.value);\n\t\t\t\tthis.timestamps.push(last.at);\n\t\t\t\tbreak;\n\t\t}\n\t\treturn values;\n\t}\n};\n//#endregion\n//#region src/number-tracker.ts\nvar NumberTracker = class extends PrimitiveTracker {\n\t#total = 0;\n\t#min = Number.MAX_SAFE_INTEGER;\n\t#max = Number.MIN_SAFE_INTEGER;\n\t/**\n\t* Difference between last value and initial.\n\t* Eg. if last value was 10 and initial value was 5, 5 is returned (10 - 5)\n\t* If either of those is missing, undefined is returned\n\t*/\n\tdifference() {\n\t\tif (this.last === void 0) return;\n\t\tif (this.initial === void 0) return;\n\t\treturn this.last - this.initial;\n\t}\n\t/**\n\t* Relative difference between last value and initial.\n\t* Eg if last value was 10 and initial value was 5, 2 is returned (200%)\n\t*/\n\trelativeDifference() {\n\t\tif (this.last === void 0) return;\n\t\tif (this.initial === void 0) return;\n\t\treturn this.last / this.initial;\n\t}\n\tonReset() {\n\t\tthis.#min = Number.MAX_SAFE_INTEGER;\n\t\tthis.#max = Number.MIN_SAFE_INTEGER;\n\t\tthis.#total = 0;\n\t\tsuper.onReset();\n\t}\n\t/**\n\t* When trimmed, recomputes to set total/min/max to be based on\n\t* current values.\n\t* @param reason \n\t*/\n\tonTrimmed(reason) {\n\t\tthis.#min = minFast(this.values);\n\t\tthis.#max = maxFast(this.values);\n\t\tthis.#total = totalFast(this.values);\n\t}\n\tcomputeResults(values) {\n\t\tif (values.some((v) => Number.isNaN(v.value))) throw new Error(`Cannot add NaN`);\n\t\tconst numbers = values.map((value) => value.value);\n\t\tthis.#total = numbers.reduce((accumulator, v) => accumulator + v, this.#total);\n\t\tthis.#min = Math.min(...numbers, this.#min);\n\t\tthis.#max = Math.max(...numbers, this.#max);\n\t\treturn {\n\t\t\tmax: this.#max,\n\t\t\tmin: this.#min,\n\t\t\ttotal: this.#total,\n\t\t\tavg: this.avg\n\t\t};\n\t}\n\tgetMinMaxAvg() {\n\t\treturn {\n\t\t\tmin: this.#min,\n\t\t\tmax: this.#max,\n\t\t\tavg: this.avg\n\t\t};\n\t}\n\tget max() {\n\t\treturn this.#max;\n\t}\n\tget total() {\n\t\treturn this.#total;\n\t}\n\tget min() {\n\t\treturn this.#min;\n\t}\n\tget avg() {\n\t\treturn this.#total / this.seenCount;\n\t}\n};\n/**\n* Keeps track of the total, min, max and avg in a stream of values. By default values\n* are not stored.\n*\n* Usage:\n*\n* ```js\n* import { number } from '@ixfx/trackers.js';\n*\n* const t = number();\n* t.seen(10);\n*\n* t.avg / t.min/ t.max\n* t.initial; // initial value\n* t.size; // number of seen values\n* t.elapsed; // milliseconds since intialisation\n* t.last; // last value\n* ```\n*\n* To get `{ avg, min, max, total }`\n* ```\n* t.getMinMax()\n* ```\n*\n* Use `t.reset()` to clear everything.\n*\n* Trackers can automatically reset after a given number of samples\n* ```\n* // reset after 100 samples\n* const t = number({ resetAfterSamples: 100 });\n* ```\n*\n* To store values, use the `storeIntermediate` option:\n*\n* ```js\n* const t = number({ storeIntermediate: true });\n* ```\n*\n* Difference between last value and initial value:\n* ```js\n* t.relativeDifference();\n* ```\n*\n* Get raw data (if it is being stored):\n* ```js\n* t.values; // array of numbers\n* t.timestampes; // array of millisecond times, indexes correspond to t.values\n* ```\n*/\nconst number = (opts = {}) => new NumberTracker(opts);\n//#endregion\n//#region src/interval-tracker.ts\n/**\n* A `Tracker` that tracks interval between calls to `mark()`\n*/\nvar IntervalTracker = class extends NumberTracker {\n\tlastMark = 0;\n\tmark() {\n\t\tif (this.lastMark > 0) this.seen(performance.now() - this.lastMark);\n\t\tthis.lastMark = performance.now();\n\t}\n\tonReset() {\n\t\tsuper.onReset();\n\t\tthis.lastMark = 0;\n\t}\n};\n/**\n* Returns a new {@link IntervalTracker} instance. IntervalTracker\n* records the interval between each call to `mark`.\n*\n* ```js\n* import { interval } from '@ixfx/trackers.js';\n*\n* const t = interval();\n*\n* // Call `mark` to record an interval\n* t.mark();\n* ...\n* t.mark();\n*\n* // Get average time in milliseconds between calls to `mark`\n* t.avg;\n*\n* // Longest and shortest times are available too...\n* t.min / t.max\n* ```\n*\n* Interval tracker can automatically reset after a given number of samples:\n*\n* ```\n* // Reset after 100 samples\n* const t = interval({ resetAfterSamples: 100} );\n* ```\n* @param options Options for tracker\n* @returns New interval tracker\n*/\nconst interval = (options) => new IntervalTracker(options);\n//#endregion\n//#region src/rate-tracker.ts\n/**\n* Tracks the rate of events.\n* It's also able to compute the min,max and average interval between events.\n* \n* @example\n* ```js\n* const clicks = Trackers.rate();\n* \n* // Mark when a click happens\n* document.addEventListener(`click`, () => clicks.mark());\n* \n* // Get details\n* clicks.perSecond; // How many clicks per second\n* clicks.perMinute; // How many clicks per minute\n* ```\n* \n* `timeoutInterval` is a useful option to make the tracker reset\n* after some period without `mark()` being called.\n* \n* Another useful option is `sampleLimit`, which sets an upper bound\n* for how many events to track. A smaller value means the results\n* will more accurately track, but it might be less smooth.\n* \n* ```js\n* // Eg reset tracker after 5 seconds of inactivity\n* const clicks = Trackers.rate({ \n* sampleLimit: 10,\n* timeoutInterval: { secs: 5 }\n* });\n* ```\n*/\nvar RateTracker = class {\n\t#events = [];\n\t#fromTime;\n\t#resetAfterSamples;\n\t#sampleLimit;\n\t#resetTimer;\n\tconstructor(opts = {}) {\n\t\tthis.#resetAfterSamples = opts.resetAfterSamples ?? Number.MAX_SAFE_INTEGER;\n\t\tthis.#sampleLimit = opts.sampleLimit ?? Number.MAX_SAFE_INTEGER;\n\t\tif (opts.timeoutInterval) this.#resetTimer = timeout(() => {\n\t\t\tthis.reset();\n\t\t}, opts.timeoutInterval);\n\t\tthis.#fromTime = performance.now();\n\t}\n\t/**\n\t* Mark that an event has happened\n\t*/\n\tmark() {\n\t\tif (this.#events.length >= this.#resetAfterSamples) this.reset();\n\t\telse if (this.#events.length >= this.#sampleLimit) {\n\t\t\tthis.#events = this.#events.slice(1);\n\t\t\tthis.#fromTime = this.#events[0];\n\t\t}\n\t\tthis.#events.push(performance.now());\n\t\tif (this.#resetTimer) this.#resetTimer.start();\n\t}\n\t/**\n\t* Compute {min,max,avg} for the interval _between_ events.\n\t* @returns \n\t*/\n\tcomputeIntervals() {\n\t\tconst intervals = [];\n\t\tlet min = Number.MAX_SAFE_INTEGER;\n\t\tlet max = Number.MIN_SAFE_INTEGER;\n\t\tlet total = 0;\n\t\tlet count = 0;\n\t\tlet start = 0;\n\t\tfor (const event of this.#events) {\n\t\t\tif (count > 0) {\n\t\t\t\tconst index = event - start;\n\t\t\t\tmin = Math.min(index, min);\n\t\t\t\tmax = Math.max(index, max);\n\t\t\t\ttotal += index;\n\t\t\t\tintervals.push(index);\n\t\t\t}\n\t\t\tstart = event;\n\t\t\tcount++;\n\t\t}\n\t\tconst avg = intervals.length > 0 ? total / intervals.length : 0;\n\t\treturn {\n\t\t\tmin,\n\t\t\tmax,\n\t\t\tavg\n\t\t};\n\t}\n\t/**\n\t* Returns the time period (in milliseconds) that encompasses\n\t* the data set. Eg, a result of 1000 means there's data that\n\t* covers a one second period.\n\t*/\n\tget elapsed() {\n\t\treturn performance.now() - this.#fromTime;\n\t}\n\t/**\n\t* Resets the tracker.\n\t*/\n\treset() {\n\t\tthis.#events = [];\n\t\tthis.#fromTime = performance.now();\n\t}\n\t/**\n\t* Get the number of events per second\n\t*/\n\tget perSecond() {\n\t\treturn this.#events.length / (this.elapsed / 1e3);\n\t}\n\t/**\n\t* Get the number of events per minute\n\t*/\n\tget perMinute() {\n\t\treturn this.#events.length / (this.elapsed / 1e3 / 60);\n\t}\n};\n/**\n* @inheritdoc RateTracker\n* @param opts \n* @returns \n*/\nconst rate = (opts = {}) => new RateTracker(opts);\n//#endregion\n//#region src/object-tracker.ts\n/**\n* A tracked value of type `V`.\n*/\nvar ObjectTracker = class extends TrackerBase {\n\tvalues;\n\tconstructor(opts = {}) {\n\t\tsuper(opts);\n\t\tthis.values = [];\n\t}\n\tonTrimmed(reason) {}\n\t/**\n\t* Reduces size of value store to `limit`. \n\t* Returns number of remaining items\n\t* @param limit\n\t*/\n\ttrimStore(limit) {\n\t\tif (limit >= this.values.length) return this.values.length;\n\t\tthis.values = this.values.slice(-limit);\n\t\treturn this.values.length;\n\t}\n\t/**\n\t* Allows sub-classes to be notified when a reset happens\n\t* @ignore\n\t*/\n\tonReset() {\n\t\tthis.values = [];\n\t}\n\t/**\n\t* Tracks a value\n\t* @ignore\n\t*/\n\tfilterData(p) {\n\t\tconst ts = p.map((v) => `at` in v ? v : {\n\t\t\t...v,\n\t\t\tat: Date.now()\n\t\t});\n\t\tconst last = ts.at(-1);\n\t\tif (this.storeIntermediate) this.values.push(...ts);\n\t\telse switch (this.values.length) {\n\t\t\tcase 0:\n\t\t\t\tthis.values.push(last);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tthis.values.push(last);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tthis.values[1] = last;\n\t\t\t\tbreak;\n\t\t}\n\t\treturn ts;\n\t}\n\t/**\n\t* Last seen value. If no values have been added, it will return the initial value\n\t*/\n\tget last() {\n\t\tif (this.values.length === 1) return this.values[0];\n\t\treturn this.values.at(-1);\n\t}\n\t/**\n\t* Returns the oldest value in the buffer\n\t*/\n\tget initial() {\n\t\treturn this.values.at(0);\n\t}\n\t/**\n\t* Returns number of recorded values (includes the initial value in the count)\n\t*/\n\tget size() {\n\t\treturn this.values.length;\n\t}\n\t/**\n\t* Returns the elapsed time, in milliseconds since the initial value\n\t*/\n\tget elapsed() {\n\t\tif (this.values.length === 0) throw new Error(`No values seen yet`);\n\t\treturn Date.now() - this.values[0].at;\n\t}\n\t/**\n\t* Returns the time, in milliseconds, covering the initial and last values.\n\t* Returns NaN if either of these is missing.\n\t*/\n\tget timespan() {\n\t\tconst oldest = this.initial;\n\t\tconst newest = this.last;\n\t\tif (!oldest) return NaN;\n\t\tif (!newest) return NaN;\n\t\treturn newest.at - oldest.at;\n\t}\n};\n//#endregion\n//#region src/tracked-value.ts\n/**\n* Keeps track of keyed values of type `V` (eg Point). It stores occurences in type `T`, which\n* must extend from `TrackerBase<V>`, eg `PointTracker`.\n*\n* The `creator` function passed in to the constructor is responsible for instantiating\n* the appropriate `TrackerBase` sub-class.\n*\n* @example Sub-class\n* ```js\n* export class PointsTracker extends TrackedValueMap<Points.Point> {\n* constructor(opts:TrackOpts = {}) {\n* super((key, start) => {\n* if (start === undefined) throw new Error(`Requires start point`);\n* const p = new PointTracker(key, opts);\n* p.seen(start);\n* return p;\n* });\n* }\n* }\n* ```\n*\n*/\nvar TrackedValueMap = class {\n\tstore;\n\tgog;\n\tconstructor(creator) {\n\t\tthis.store = /* @__PURE__ */ new Map();\n\t\tthis.gog = getOrGenerateSync(this.store, creator);\n\t}\n\t/**\n\t* Number of named values being tracked\n\t*/\n\tget size() {\n\t\treturn this.store.size;\n\t}\n\t/**\n\t* Returns _true_ if `id` is stored\n\t* @param id\n\t* @returns\n\t*/\n\thas(id) {\n\t\treturn this.store.has(id);\n\t}\n\t/**\n\t* For a given id, note that we have seen one or more values.\n\t* @param id Id\n\t* @param values Values(s)\n\t* @returns Information about start to last value\n\t*/\n\tseen(id, ...values) {\n\t\treturn this.getTrackedValue(id, ...values).seen(...values);\n\t}\n\t/**\n\t* Creates or returns a TrackedValue instance for `id`.\n\t* @param id\n\t* @param values\n\t* @returns\n\t*/\n\tgetTrackedValue(id, ...values) {\n\t\tif (id === null) throw new Error(`id parameter cannot be null`);\n\t\tif (id === void 0) throw new Error(`id parameter cannot be undefined`);\n\t\treturn this.gog(id, values[0]);\n\t}\n\t/**\n\t* Remove a tracked value by id.\n\t* Use {@link reset} to clear them all.\n\t* @param id\n\t*/\n\tdelete(id) {\n\t\tthis.store.delete(id);\n\t}\n\t/**\n\t* Remove all tracked values.\n\t* Use {@link delete} to remove a single value by id.\n\t*/\n\treset() {\n\t\tthis.store = /* @__PURE__ */ new Map();\n\t}\n\t/**\n\t* Enumerate ids\n\t*/\n\t*ids() {\n\t\tyield* this.store.keys();\n\t}\n\t/**\n\t* Enumerate tracked values\n\t*/\n\t*tracked() {\n\t\tyield* this.store.values();\n\t}\n\t/**\n\t* Iterates TrackedValues ordered with oldest first\n\t* @returns\n\t*/\n\t*trackedByAge() {\n\t\tconst tp = [...this.store.values()];\n\t\ttp.sort((a, b) => {\n\t\t\tconst aa = a.elapsed;\n\t\t\tconst bb = b.elapsed;\n\t\t\tif (aa === bb) return 0;\n\t\t\tif (aa > bb) return -1;\n\t\t\treturn 1;\n\t\t});\n\t\tfor (const t of tp) yield t;\n\t}\n\t/**\n\t* Iterates underlying values, ordered by age (oldest first)\n\t* First the named values are sorted by their `elapsed` value, and then\n\t* we return the last value for that group.\n\t*/\n\t*valuesByAge() {\n\t\tfor (const tb of this.trackedByAge()) yield tb.last;\n\t}\n\t/**\n\t* Enumerate last received values\n\t*\n\t* @example Calculate centroid of latest-received values\n\t* ```js\n\t* const pointers = pointTracker();\n\t* const c = Points.centroid(...Array.from(pointers.lastPoints()));\n\t* ```\n\t*/\n\t*last() {\n\t\tfor (const p of this.store.values()) yield p.last;\n\t}\n\t/**\n\t* Enumerate starting values\n\t*/\n\t*initialValues() {\n\t\tfor (const p of this.store.values()) yield p.initial;\n\t}\n\t/**\n\t* Returns a tracked value by id, or undefined if not found\n\t* @param id\n\t* @returns\n\t*/\n\tget(id) {\n\t\treturn this.store.get(id);\n\t}\n};\n//#endregion\nexport { FrequencyTracker, GatedFrequencyTracker, IntervalTracker, NumberTracker, ObjectTracker, PrimitiveTracker, RateTracker, TrackedValueMap, TrackerBase, frequency, handleChangeResult, interval, number, rate, trackBooleanChange, trackNumberChange };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { O as average, h as radianInvert, k as averager } from \"./angles-BkBEzlEN.js\";\nimport { a as isNull, c as isPoint3d, i as isNaN, l as pointTest, n as guardNonZeroPoint, o as isPlaceholder$1, r as isEmpty$1, s as isPoint, t as guard } from \"./guard-hlhkAOMZ.js\";\nimport { t as fromPoints } from \"./from-points-hWl1SWEr.js\";\nimport { n as bbox3d, r as findMinimum, t as bbox$1 } from \"./bbox-BH5rnhlc.js\";\nimport { a as subtract$2, c as getPointParameter, i as toString$2, l as getTwoPointParameters, n as to3d, o as distance$1, r as toIntegerValues, s as distance2d, t as to2d } from \"./to-oKNQeMO-.js\";\nimport { C as toString$3, D as Unit3d, E as Unit, F as isPolarCoord, M as rotate$2, T as Empty3d, c as angleRadianCircle, d as clampMagnitude$2, g as fromCartesian, h as normalise$2, l as angleRadianThreePoint, p as dotProduct$3, s as angleRadian$1, w as Empty$1, x as toPoint, y as toCartesian$1 } from \"./polar-ZdU4ci-4.js\";\nimport { n as isPolyLine, r as lineTest, t as isLine } from \"./guard-Bg57Xzmd.js\";\nimport { n as getPointParameter$1, t as length$1 } from \"./length-ChosppvJ.js\";\nimport { i as reverse, n as interpolator$1, r as pointAtDistance, t as interpolate$1 } from \"./interpolate-DhLKNStN.js\";\nimport { c as isRect, l as isRectPositioned } from \"./guard-C2opUnGy.js\";\nimport { a as sum$2, u as isCirclePositioned } from \"./intersects-BOuj4lnQ.js\";\nimport { n as multiplyScalar, r as distanceFromExterior, t as multiply$2 } from \"./multiply-CwzF4Hcr.js\";\nimport { t as isEqual$1 } from \"./is-equal-BS9hk_L_.js\";\nimport { a as compareRowwise, i as compareByZ, n as compareByX, o as getAsBounds, r as compareByY, t as compare } from \"./compare-DzZYeaAF.js\";\nimport { i as distanceFromExterior$1, n as polyLineToPoints, t as joinPointsToLines } from \"./join-points-to-lines-CEdHRF9i.js\";\nimport { clamp, dotProduct, minFast, minIndex, quantiseEvery, round, wrap } from \"@ixfx/numbers\";\nimport { numberTest, resultThrow } from \"@ixfx/guards\";\nimport { ObjectTracker, TrackedValueMap } from \"@ixfx/trackers\";\n//#region src/point/normalise-by-rect.ts\n/**\n* Normalises a point so it is on a 0..1 scale\n* \n* ```js\n* normaliseByRect({ x: 10, y: 10, width: 20, height: 40 }); \n* normaliseByRect({ x: 10, y: 10 }, 20, 40); \n* normaliseByRect(10, 10, 20, 40);\n* ```\n* @param a Point, or x\n* @param b y coord or width\n* @param c height or width\n* @param d height\n* @returns Point\n*/\nfunction normaliseByRect$1(a, b, c, d) {\n\tif (isPoint(a)) {\n\t\tif (typeof b === `number` && c !== void 0) resultThrow(numberTest(b, `positive`, `width`), numberTest(c, `positive`, `height`));\n\t\telse {\n\t\t\tif (!isRect(b)) throw new Error(`Expected second parameter to be a rect`);\n\t\t\tc = b.height;\n\t\t\tb = b.width;\n\t\t}\n\t\treturn Object.freeze({\n\t\t\tx: a.x / b,\n\t\t\ty: a.y / c\n\t\t});\n\t} else {\n\t\tresultThrow(numberTest(a, `positive`, `x`));\n\t\tif (typeof b !== `number`) throw new TypeError(`Expecting second parameter to be a number (width)`);\n\t\tif (typeof c !== `number`) throw new TypeError(`Expecting third parameter to be a number (height)`);\n\t\tresultThrow(numberTest(b, `positive`, `y`));\n\t\tresultThrow(numberTest(c, `positive`, `width`));\n\t\tif (d === void 0) throw new Error(`Expected height parameter`);\n\t\tresultThrow(numberTest(d, `positive`, `height`));\n\t\treturn Object.freeze({\n\t\t\tx: a / c,\n\t\t\ty: b / d\n\t\t});\n\t}\n}\n//#endregion\n//#region src/line/nearest.ts\n/**\n* Returns the nearest point on line(s) closest to `point`.\n* \n* ```js\n* const pt = Lines.nearest(line, {x:10,y:10});\n* ```\n* \n* If an array of lines is provided, it will be the closest point amongst all the lines\n* @param lineOrLines Line or array of lines\n* @param point Point to check\n* @returns Point `{ x, y }`\n*/\nconst nearest = (lineOrLines, point) => {\n\tconst nearestImpl = (line) => {\n\t\tconst { a, b } = line;\n\t\tconst atob = {\n\t\t\tx: b.x - a.x,\n\t\t\ty: b.y - a.y\n\t\t};\n\t\tconst atop = {\n\t\t\tx: point.x - a.x,\n\t\t\ty: point.y - a.y\n\t\t};\n\t\tconst length = atob.x * atob.x + atob.y * atob.y;\n\t\tlet dot = atop.x * atob.x + atop.y * atob.y;\n\t\tconst t = Math.min(1, Math.max(0, dot / length));\n\t\tdot = (b.x - a.x) * (point.y - a.y) - (b.y - a.y) * (point.x - a.x);\n\t\treturn {\n\t\t\tx: a.x + atob.x * t,\n\t\t\ty: a.y + atob.y * t\n\t\t};\n\t};\n\tif (Array.isArray(lineOrLines)) {\n\t\tconst pts = lineOrLines.map((line) => nearestImpl(line));\n\t\tconst dists = pts.map((p) => distance$1(p, point));\n\t\treturn Object.freeze(pts[minIndex(dists)]);\n\t} else return Object.freeze(nearestImpl(lineOrLines));\n};\n//#endregion\n//#region src/line/distance-single-line.ts\n/**\n* Returns the distance of `point` to the nearest point on `line`\n*\n* ```js\n* const distance = Lines.distanceSingleLine(line, pt);\n* ```\n* @param line Line\n* @param point Target point\n* @returns\n*/\nfunction distanceSingleLine(line, point) {\n\tresultThrow(lineTest(line, `line`), pointTest(point, `point`));\n\tif (length$1(line) === 0) return length$1(line.a, point);\n\treturn length$1(nearest(line, point), point);\n}\n//#endregion\n//#region src/line/angles.ts\nconst directionVector = (line) => ({\n\tx: line.b.x - line.a.x,\n\ty: line.b.y - line.a.y\n});\nconst directionVectorNormalised = (line) => {\n\tconst l = length$1(line);\n\tconst v = directionVector(line);\n\treturn {\n\t\tx: v.x / l,\n\t\ty: v.y / l\n\t};\n};\n/**\n* Returns a parallel line to `line` at `distance`.\n* \n* ```js\n* const l = Lines.parallel(line, 10);\n* ```\n* @param line\n* @param distance \n*/\nconst parallel = (line, distance) => {\n\tconst dv = directionVector(line);\n\tconst dvn = directionVectorNormalised(line);\n\tconst a = {\n\t\tx: line.a.x - dvn.y * distance,\n\t\ty: line.a.y + dvn.x * distance\n\t};\n\treturn {\n\t\ta,\n\t\tb: {\n\t\t\tx: a.x + dv.x,\n\t\t\ty: a.y + dv.y\n\t\t}\n\t};\n};\n/**\n* Returns a point perpendicular to `line` at a specified `distance`. Use negative\n* distances for the other side of line.\n* ```\n* // Project a point 100 units away from line, at its midpoint.\n* const pt = Lines.perpendicularPoint(line, 100, 0.5);\n* ```\n* @param line Line\n* @param distance Distance from line. Use negatives to flip side\n* @param amount Relative place on line to project point from. 0 projects from A, 0.5 from the middle, 1 from B.\n*/\nconst perpendicularPoint = (line, distance, amount = 0) => {\n\tconst origin = interpolate$1(amount, line);\n\tconst dvn = directionVectorNormalised(line);\n\treturn {\n\t\tx: origin.x - dvn.y * distance,\n\t\ty: origin.y + dvn.x * distance\n\t};\n};\n//#endregion\n//#region src/line/bbox.ts\n/**\n* Returns a rectangle that encompasses dimension of line\n* \n* ```js\n* const rect = Lines.bbox(line);\n* ```\n*/\nconst bbox = (line) => bbox$1(line.a, line.b);\n//#endregion\n//#region src/point/divider.ts\n/**\n* Returns a Point with the x,y,z values of two points divide (a/b).\n* \n* `z` parameter is used, if present. Uses a default value of 0 for 'z' when dividing a 2D point with a 3D one.\n*\n* Examples:\n*\n* ```js\n* divide(ptA, ptB);\n* divide(x1, y1, x2, y2);\n* divide(ptA, x2, y2);\n* ```\n*/\nfunction divide$2(a1, ab2, ab3, ab4, ab5, ab6) {\n\tconst [ptA, ptB] = getTwoPointParameters(a1, ab2, ab3, ab4, ab5, ab6);\n\tguard(ptA, `a`);\n\tguard(ptB, `b`);\n\tif (ptB.x === 0) throw new TypeError(\"Cannot divide by zero (b.x is 0)\");\n\tif (ptB.y === 0) throw new TypeError(\"Cannot divide by zero (b.y is 0)\");\n\tconst pt = {\n\t\tx: ptA.x / ptB.x,\n\t\ty: ptA.y / ptB.y\n\t};\n\tif (isPoint3d(ptA) || isPoint3d(ptB)) {\n\t\tif (ptB.z === 0) throw new TypeError(\"Cannot divide by zero (b.z is 0)\");\n\t\tpt.z = (ptA.z ?? 0) / (ptB.z ?? 0);\n\t}\n\treturn Object.freeze(pt);\n}\n/**\n* Returns a function that divides a point:\n* ```js\n* const f = divider(100, 200);\n* f(50,100); // Yields: { x: 0.5, y: 0.5 }\n* ```\n*\n* Input values can be Point, separate x,y and optional z values or an array:\n* ```js\n* const f = divider({ x: 100, y: 100 });\n* const f = divider( 100, 100 );\n* const f = divider([ 100, 100 ]);\n* ```\n*\n* Likewise the returned function an take these as inputs:\n* ```js\n* f({ x: 100, y: 100});\n* f( 100, 100 );\n* f([ 100, 100 ]);\n* ```\n*\n* Function throws if divisor has 0 for any coordinate (since we can't divide by 0)\n* @param a Divisor point, array of points or x\n* @param b Divisor y value\n* @param c Divisor z value\n* @returns\n*/\nfunction divider(a, b, c) {\n\tconst divisor = getPointParameter(a, b, c);\n\tguardNonZeroPoint(divisor, `divisor`);\n\treturn (aa, bb, cc) => {\n\t\tconst dividend = getPointParameter(aa, bb, cc);\n\t\treturn typeof dividend.z === `undefined` ? Object.freeze({\n\t\t\tx: dividend.x / divisor.x,\n\t\t\ty: dividend.y / divisor.y\n\t\t}) : Object.freeze({\n\t\t\tx: dividend.x / divisor.x,\n\t\t\ty: dividend.y / divisor.y,\n\t\t\tz: dividend.z / (divisor.z ?? 1)\n\t\t});\n\t};\n}\n//#endregion\n//#region src/line/divide.ts\n/**\n* Divides both start and end points by given x,y\n* ```js\n* // Line 1,1 -> 10,10\n* const l = Lines.fromNumbers(1,1,10,10);\n* const ll = Lines.divide(l, {x:2, y:4});\n* // Yields: 0.5,0.25 -> 5,2.5\n* ```\n* \n* Dividing by zero will give Infinity for that dimension.\n* @param line \n* @param point \n* @returns \n*/\nconst divide$1 = (line, point) => Object.freeze({\n\t...line,\n\ta: divide$2(line.a, point),\n\tb: divide$2(line.b, point)\n});\n//#endregion\n//#region src/line/from-numbers.ts\n/**\n* Returns a line from a basis of coordinates (x1, y1, x2, y2)\n* \n* ```js\n* // Line from 0,1 -> 10,15\n* Lines.fromNumbers(0, 1, 10, 15);\n* ```\n* @param x1 \n* @param y1 \n* @param x2 \n* @param y2 \n* @returns \n*/\nconst fromNumbers$1 = (x1, y1, x2, y2) => {\n\tif (Number.isNaN(x1)) throw new Error(`x1 is NaN`);\n\tif (Number.isNaN(x2)) throw new Error(`x2 is NaN`);\n\tif (Number.isNaN(y1)) throw new Error(`y1 is NaN`);\n\tif (Number.isNaN(y2)) throw new Error(`y2 is NaN`);\n\treturn fromPoints({\n\t\tx: x1,\n\t\ty: y1\n\t}, {\n\t\tx: x2,\n\t\ty: y2\n\t});\n};\n//#endregion\n//#region src/line/from-flat-array.ts\n/**\n* Returns a line from four numbers [x1,y1,x2,y2].\n* \n* See {@link toFlatArray} to create an array from a line.\n* \n* ```js\n* const line = Lines.fromFlatArray(...[0, 0, 100, 100]);\n* // line is {a: { x:0, y:0 }, b: { x: 100, y: 100 } }\n* ```\n* @param array Array in the form [x1,y1,x2,y2]\n* @returns Line\n*/\nconst fromFlatArray = (array) => {\n\tif (!Array.isArray(array)) throw new Error(`arr parameter is not an array`);\n\tif (array.length !== 4) throw new Error(`array is expected to have length four`);\n\treturn fromNumbers$1(array[0], array[1], array[2], array[3]);\n};\n//#endregion\n//#region src/line/from-pivot.ts\n/**\n* Creates a line from an origin point.\n* ```js\n* // Line of length 0.2 with middle at 0.5,0.5\n* fromPivot({ x:0.5, y:0.5 }, 0.2);\n* // Same line, but on an angle\n* fromPivot({ x:0.5, y:0.5 }, 0.2, degreesToRadian(45));\n* \n* // ...now with pivot point at 20%, rather than center\n* fromPivot({ x:0.5, y:0.5 }, 0.2, degreesToRadian(45), 0.2);\n* ```\n* \n* Examples:\n* * Angle of 0 (deg/rad) results in a horizontal line,\n* * Angle of 90deg in a vertical line. \n* * Angle of 45deg will be angled downwards.\n* \n* @param origin Origin to pivot around\n* @param length Total length of line\n* @param angleRadian Angle of line, in radians\n* @param balance Percentage of where origin ought to be on line. Default: 0.5, meaning the middle of line\n*/\nconst fromPivot = (origin = {\n\tx: .5,\n\ty: .5\n}, length = 1, angleRadian = 0, balance = .5) => {\n\tconst left = length * balance;\n\tconst right = length * (1 - balance);\n\tconst a = toCartesian$1(left, radianInvert(angleRadian), origin);\n\tconst b = toCartesian$1(right, angleRadian, origin);\n\treturn Object.freeze({\n\t\ta,\n\t\tb\n\t});\n};\n//#endregion\n//#region src/line/midpoint.ts\n/**\n* Returns the mid-point of a line (same as `interpolate` with an amount of 0.5)\n* \n* ```js\n* Lines.midpoint(line); // Returns {x, y}\n* ```\n* @param aOrLine \n* @param pointB \n* @returns \n*/\nconst midpoint = (aOrLine, pointB) => {\n\tconst [a, b] = getPointParameter$1(aOrLine, pointB);\n\treturn interpolate$1(.5, a, b);\n};\n//#endregion\n//#region src/line/relative-position.ts\n/**\n* Returns the relative position of `pt` along `line`.\n* Warning: assumes `pt` is actually on `line`. Results may be bogus if not.\n* @param line \n* @param pt \n*/\nconst relativePosition = (line, pt) => {\n\treturn distance$1(line.a, pt) / length$1(line);\n};\n//#endregion\n//#region src/line/sum.ts\n/**\n* Adds both start and end points by given x,y\n* ```js\n* \n* // Line 1,1 -> 10,10\n* const l = Lines.fromNumbers(1,1,10,10);\n* const ll = Lines.sum(l, {x:2, y:4});\n* // Yields: 3,5 -> 12,14\n* ```\n* @param line \n* @param point \n* @returns \n*/\nconst sum$1 = (line, point) => Object.freeze({\n\t...line,\n\ta: sum$2(line.a, point),\n\tb: sum$2(line.b, point)\n});\n//#endregion\n//#region src/point/abs.ts\n/**\n* Returns a point with Math.abs applied to x,y and z if present.\n* ```js\n* Points.abs({ x:1, y:1 }); // { x: 1, y: 1 }\n* Points.abs({ x:-1, y:1 }); // { x: 1, y: 1 }\n* Points.abs({ x:-1, y:-1 }); // { x: 1, y: 1 }\n* ```\n* @param pt\n* @returns\n*/\nfunction abs(pt) {\n\tif (isPoint3d(pt)) return Object.freeze({\n\t\t...pt,\n\t\tx: Math.abs(pt.x),\n\t\ty: Math.abs(pt.y),\n\t\tz: Math.abs(pt.z)\n\t});\n\telse if (isPoint(pt)) return Object.freeze({\n\t\t...pt,\n\t\tx: Math.abs(pt.x),\n\t\ty: Math.abs(pt.y)\n\t});\n\telse throw new TypeError(`Param 'pt' is not a point`);\n}\n//#endregion\n//#region src/point/apply.ts\n/**\n* Applies `fn` on x,y & z (if present) fields, returning all other fields as well\n* ```js\n* const p = {x:1.234, y:4.9};\n* const p2 = Points.apply(p, Math.round);\n* // Yields: {x:1, y:5}\n* ```\n*\n* The name of the field is provided as well. Here we only round the `x` field:\n*\n* ```js\n* const p = {x:1.234, y:4.9};\n* const p2 = Points.apply(p, (v, field) => {\n* if (field === `x`) return Math.round(v);\n* return v;\n* });\n* ```\n* @param pt\n* @param fn\n* @returns\n*/\nfunction apply$1(pt, fn) {\n\tguard(pt, `pt`);\n\tif (isPoint3d(pt)) return Object.freeze({\n\t\t...pt,\n\t\tx: fn(pt.x, `x`),\n\t\ty: fn(pt.y, `y`),\n\t\tz: fn(pt.z, `z`)\n\t});\n\treturn Object.freeze({\n\t\t...pt,\n\t\tx: fn(pt.x, `x`),\n\t\ty: fn(pt.y, `y`)\n\t});\n}\n//#endregion\n//#region src/point/centroid.ts\n/**\n* Calculates the [centroid](https://en.wikipedia.org/wiki/Centroid#Of_a_finite_set_of_points) of a set of points\n* Undefined values are skipped over. Calculation and return value is 2D.\n*\n* ```js\n* // Find centroid of a list of points\n* const c1 = centroid(p1, p2, p3, ...);\n*\n* // Find centroid of an array of points\n* const c2 = centroid(...pointsArray);\n* ```\n* @param points\n* @returns A single point\n*/\nconst centroid = (...points) => {\n\tif (!Array.isArray(points)) throw new Error(`Expected list of points`);\n\tconst sum = points.reduce((previous, p) => {\n\t\tif (p === void 0) return previous;\n\t\tif (Array.isArray(p)) throw new TypeError(`'points' list contains an array. Did you mean: centroid(...myPoints)?`);\n\t\tif (!isPoint(p)) throw new Error(`'points' contains something which is not a point: ${JSON.stringify(p)}`);\n\t\treturn {\n\t\t\tx: previous.x + p.x,\n\t\t\ty: previous.y + p.y\n\t\t};\n\t}, {\n\t\tx: 0,\n\t\ty: 0\n\t});\n\treturn Object.freeze({\n\t\tx: sum.x / points.length,\n\t\ty: sum.y / points.length\n\t});\n};\n//#endregion\n//#region src/point/clamp.ts\n/**\n* Clamps a point to be between `min` and `max` (0 & 1 by default)\n* @param pt Point\n* @param min Minimum value (0 by default)\n* @param max Maximum value (1 by default)\n*/\nfunction clamp$1(a, min = 0, max = 1) {\n\tif (isPoint3d(a)) return Object.freeze({\n\t\tx: clamp(a.x, min, max),\n\t\ty: clamp(a.y, min, max),\n\t\tz: clamp(a.z, min, max)\n\t});\n\telse return Object.freeze({\n\t\tx: clamp(a.x, min, max),\n\t\ty: clamp(a.y, min, max)\n\t});\n}\n//#endregion\n//#region src/point/convex-hull.ts\n/**\n* Simple convex hull impementation. Returns a set of points which\n* enclose `pts`.\n*\n* For more power, see something like [Hull.js](https://github.com/AndriiHeonia/hull)\n* @param pts\n* @returns\n*/\nconst convexHull = (...pts) => {\n\tconst sorted = [...pts].sort(compareByX);\n\tif (sorted.length === 1) return sorted;\n\tconst x = (points) => {\n\t\tconst v = [];\n\t\tfor (const p of points) {\n\t\t\twhile (v.length >= 2) {\n\t\t\t\tconst q = v.at(-1);\n\t\t\t\tconst r = v.at(-2);\n\t\t\t\tif ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) v.pop();\n\t\t\t\telse break;\n\t\t\t}\n\t\t\tv.push(p);\n\t\t}\n\t\tv.pop();\n\t\treturn v;\n\t};\n\tconst upper = x(sorted);\n\tconst lower = x(sorted.reverse());\n\tif (upper.length === 1 && lower.length === 1 && isEqual$1(lower[0], upper[0])) return upper;\n\treturn [...upper, ...lower];\n};\n//#endregion\n//#region src/point/distance-to-center.ts\n/**\n* Returns the distance from point `a` to the center of `shape`.\n* @param a Point\n* @param shape Point, or a positioned Rect or Circle.\n* @returns\n*/\nconst distanceToCenter = (a, shape) => {\n\tif (isRectPositioned(shape)) return distanceFromExterior$1(shape, a);\n\tif (isCirclePositioned(shape)) return distanceFromExterior(shape, a);\n\tif (isPoint(shape)) return distance$1(a, shape);\n\tthrow new Error(`Unknown shape`);\n};\n//#endregion\n//#region src/point/distance-to-exterior.ts\n/**\n* Returns the distance from point `a` to the exterior of `shape`.\n*\n* @example Distance from point to rectangle\n* ```\n* const distance = distanceToExterior(\n* {x: 50, y: 50},\n* {x: 100, y: 100, width: 20, height: 20}\n* );\n* ```\n*\n* @example Find closest shape to point\n* ```\n* import {minIndex} from '../data/arrays.js';\n* const shapes = [ some shapes... ]; // Shapes to compare against\n* const pt = { x: 10, y: 10 }; // Comparison point\n* const distances = shapes.map(v => distanceToExterior(pt, v));\n* const closest = shapes[minIndex(...distances)];\n* ```\n* @param a Point\n* @param shape Point, or a positioned Rect or Circle.\n* @returns\n*/\nconst distanceToExterior = (a, shape) => {\n\tif (isRectPositioned(shape)) return distanceFromExterior$1(shape, a);\n\tif (isCirclePositioned(shape)) return distanceFromExterior(shape, a);\n\tif (isPoint(shape)) return distance$1(a, shape);\n\tthrow new Error(`Unknown shape`);\n};\n//#endregion\n//#region src/point/to-array.ts\n/**\n* Returns point as an array in the form [x,y]. This can be useful for some libraries\n* that expect points in array form.\n*\n* ```\n* const p = {x: 10, y:5};\n* const p2 = toArray(p); // yields [10,5]\n* ```\n* @param p\n* @returns\n*/\nconst toArray = (p) => [p.x, p.y];\n//#endregion\n//#region src/point/dot-product.ts\nconst dotProduct$2 = (...pts) => {\n\treturn dotProduct(pts.map((p) => toArray(p)));\n};\n/**\n* Returns the cross-product:\n* ```\n* ax * by - ay * bx\n* ```\n* @param a \n* @param b\n* @returns \n*/\nfunction cross(a, b) {\n\treturn a.x * b.y - a.y * b.x;\n}\n/**\n* Returns the cross-product:\n* ```\n* ax * by - ay * bx\n* ```\n* @param ax \n* @param ay \n* @param bx \n* @param by \n* @returns \n*/\nfunction crossProductRaw(ax, ay, bx, by) {\n\treturn ax * by - ay * bx;\n}\n//#endregion\n//#region src/point/from.ts\n/**\n* Returns a point from two or three coordinates or an array of [x,y] or [x,y,z].\n* @example\n* ```js\n* let p = from([10, 5]); // yields {x:10, y:5}\n* let p = from([10, 5, 2]); // yields: {x:10, y:5, z:2}\n* let p = from(10, 5); // yields {x:10, y:5}\n* let p = from(10, 5, 2); // yields: {x:10, y:5, z:2}\n* ```\n* @param xOrArray\n* @param [y]\n* @returns Point\n*/\nfunction from(xOrArray, y, z) {\n\tif (Array.isArray(xOrArray)) if (xOrArray.length === 3) return Object.freeze({\n\t\tx: xOrArray[0],\n\t\ty: xOrArray[1],\n\t\tz: xOrArray[2]\n\t});\n\telse if (xOrArray.length === 2) return Object.freeze({\n\t\tx: xOrArray[0],\n\t\ty: xOrArray[1]\n\t});\n\telse throw new Error(`Expected array of length two or three, got ${xOrArray.length}`);\n\telse {\n\t\tif (xOrArray === void 0) throw new Error(`Requires an array of [x,y] or x,y parameters at least`);\n\t\telse if (Number.isNaN(xOrArray)) throw new Error(`x is NaN`);\n\t\tif (y === void 0) throw new Error(`Param 'y' is missing`);\n\t\telse if (Number.isNaN(y)) throw new Error(`y is NaN`);\n\t\tif (z === void 0) return Object.freeze({\n\t\t\tx: xOrArray,\n\t\t\ty\n\t\t});\n\t\telse return Object.freeze({\n\t\t\tx: xOrArray,\n\t\t\ty,\n\t\t\tz\n\t\t});\n\t}\n}\n/**\n* Parses a point as a string, in the form 'x,y' or 'x,y,z'.\n* eg '10,15' will be returned as `{ x: 10, y: 15 }`.\n* \n* Throws an error if `str` is not a string.\n* \n* ```js\n* Points.fromString(`10,15`); // { x:10, y:15 }\n* Points.fromString(`a,10`); // { x:NaN, y:10 }\n* ```\n* \n* Use {@link Points.isNaN} to check if returned point has NaN for either coordinate.\n* @param string_ \n*/\nconst fromString = (string_) => {\n\tif (typeof string_ !== `string`) throw new TypeError(`Param 'str' ought to be a string. Got: ${typeof string_}`);\n\tconst comma = string_.indexOf(`,`);\n\tconst x = Number.parseFloat(string_.substring(0, comma));\n\tconst nextComma = string_.indexOf(\",\", comma + 1);\n\tif (nextComma > 0) return {\n\t\tx,\n\t\ty: Number.parseFloat(string_.substring(comma + 1, nextComma - comma + 2)),\n\t\tz: Number.parseFloat(string_.substring(nextComma + 1))\n\t};\n\telse return {\n\t\tx,\n\t\ty: Number.parseFloat(string_.substring(comma + 1))\n\t};\n};\n/**\n* Returns an array of points from an array of numbers.\n*\n* Array can be a continuous series of x, y values:\n* ```\n* [1,2,3,4] would yield: [{x:1, y:2}, {x:3, y:4}]\n* ```\n*\n* Or it can be an array of arrays:\n* ```\n* [[1,2], [3,4]] would yield: [{x:1, y:2}, {x:3, y:4}]\n* ```\n* @param coords\n* @returns\n*/\nconst fromNumbers = (...coords) => {\n\tconst pts = [];\n\tif (Array.isArray(coords[0])) for (const coord of coords) {\n\t\tif (!(coord.length % 2 === 0)) throw new Error(`coords array should be even-numbered`);\n\t\tpts.push(Object.freeze({\n\t\t\tx: coord[0],\n\t\t\ty: coord[1]\n\t\t}));\n\t}\n\telse {\n\t\tif (coords.length % 2 !== 0) throw new Error(`Expected even number of elements: [x,y,x,y...]`);\n\t\tfor (let index = 0; index < coords.length; index += 2) pts.push(Object.freeze({\n\t\t\tx: coords[index],\n\t\t\ty: coords[index + 1]\n\t\t}));\n\t}\n\treturn pts;\n};\n//#endregion\n//#region src/point/interpolate.ts\n/**\n* Returns a relative point between two points.\n*\n* ```js\n* interpolate(0.5, { x:0, y:0 }, { x:10, y:10 }); // Halfway { x, y }\n* ```\n*\n* Alias for Lines.interpolate(amount, a, b);\n*\n* If you find yourself calling `interpolate` repeatedly with the same points, consider using {@link interpolator} to create a function that bakes in the points.\n* @param amount Relative amount, 0-1\n* @param a\n* @param b\n* @param allowOverflow If true, length of line can be exceeded for `amount` of below 0 and above `1`.\n* @returns {@link Point} Point\n*/\nfunction interpolate(amount, a, b, allowOverflow = false) {\n\treturn interpolate$1(amount, a, b, allowOverflow);\n}\n/**\n* Returns a function that interpolates between two points. If you just want to interpolate between two points, use {@link interpolate}.\n*\n* ```js\n* const i = interpolator({ x:0, y:0 }, { x:10, y:10 });\n* i(0.5); // Halfway { x, y }\n* ```\n*\n* If you find yourself not needing to reuse the function because you're always calling `interpolator` with different point values all the time, use {@link interpolate} instead.\n* @param a\n* @param b\n* @param allowOverflow\n* @returns Function to interpolate\n*/\nconst interpolator = (a, b, allowOverflow = false) => interpolator$1({\n\ta,\n\tb\n}, allowOverflow);\n//#endregion\n//#region src/point/invert.ts\n/**\n* Inverts one or more axis of a point\n* ```js\n* invert({x:10, y:10}); // Yields: {x:-10, y:-10}\n* invert({x:10, y:10}, `x`); // Yields: {x:-10, y:10}\n* ```\n* @param pt Point to invert\n* @param what Which axis. If unspecified, both axies are inverted\n* @returns\n*/\nconst invert = (pt, what = `both`) => {\n\tswitch (what) {\n\t\tcase `both`: return isPoint3d(pt) ? Object.freeze({\n\t\t\t...pt,\n\t\t\tx: pt.x * -1,\n\t\t\ty: pt.y * -1,\n\t\t\tz: pt.z * -1\n\t\t}) : Object.freeze({\n\t\t\t...pt,\n\t\t\tx: pt.x * -1,\n\t\t\ty: pt.y * -1\n\t\t});\n\t\tcase `x`: return Object.freeze({\n\t\t\t...pt,\n\t\t\tx: pt.x * -1\n\t\t});\n\t\tcase `y`: return Object.freeze({\n\t\t\t...pt,\n\t\t\ty: pt.y * -1\n\t\t});\n\t\tcase `z`: if (isPoint3d(pt)) return Object.freeze({\n\t\t\t...pt,\n\t\t\tz: pt.z * -1\n\t\t});\n\t\telse throw new Error(`pt parameter is missing z`);\n\t\tdefault: throw new Error(`Unknown what parameter. Expecting 'both', 'x' or 'y'`);\n\t}\n};\n//#endregion\n//#region src/point/magnitude.ts\n/**\n* Clamps the magnitude of a point.\n* This is useful when using a Point as a vector, to limit forces.\n* @param pt\n* @param max Maximum magnitude (1 by default)\n* @param min Minimum magnitude (0 by default)\n* @returns\n*/\nconst clampMagnitude$1 = (pt, max = 1, min = 0) => {\n\tconst length = distance$1(pt);\n\tlet ratio = 1;\n\tif (length > max) ratio = max / length;\n\telse if (length < min) ratio = min / length;\n\treturn ratio === 1 ? pt : multiply$2(pt, ratio, ratio);\n};\n//#endregion\n//#region src/point/most.ts\n/**\n* Returns the left-most of the provided points.\n*\n* Same as:\n* ```js\n* findMinimum((a, b) => {\n* if (a.x <= b.x) return a;\n* return b;\n*}, ...points)\n* ```\n*\n* @param points\n* @returns\n*/\nconst leftmost = (...points) => findMinimum((a, b) => a.x <= b.x ? a : b, ...points);\n/**\n* Returns the right-most of the provided points.\n*\n* Same as:\n* ```js\n* findMinimum((a, b) => {\n* if (a.x >= b.x) return a;\n* return b;\n*}, ...points)\n* ```\n*\n* @param points\n* @returns\n*/\nconst rightmost = (...points) => findMinimum((a, b) => a.x >= b.x ? a : b, ...points);\n//#endregion\n//#region src/point/normalise.ts\nconst length = (ptOrX, y) => {\n\tif (isPoint(ptOrX)) {\n\t\ty = ptOrX.y;\n\t\tptOrX = ptOrX.x;\n\t}\n\tif (y === void 0) throw new Error(`Expected y`);\n\treturn Math.hypot(ptOrX, y);\n};\n/**\n* Normalise point as a unit vector.\n*\n* ```js\n* normalise({x:10, y:20});\n* normalise(10, 20);\n* ```\n* @param ptOrX Point, or x value\n* @param y y value if first param is x\n* @returns\n*/\nconst normalise$1 = (ptOrX, y) => {\n\tconst pt = getPointParameter(ptOrX, y);\n\tconst l = length(pt);\n\tif (l === 0) return Empty$1;\n\treturn Object.freeze({\n\t\t...pt,\n\t\tx: pt.x / l,\n\t\ty: pt.y / l\n\t});\n};\n//#endregion\n//#region src/point/pipeline.ts\n/**\n* Runs a sequential series of functions on `pt`. The output from one feeding into the next.\n* \n* ```js\n* const p = Points.pipelineApply(somePoint, Points.normalise, Points.invert);\n* ```\n*\n* If you want to make a reusable pipeline of functions, consider {@link pipeline} instead.\n* @param point\n* @param pipelineFns\n* @returns\n*/\nconst pipelineApply = (point, ...pipelineFns) => pipeline(...pipelineFns)(point);\n/**\n* Returns a pipeline function that takes a point to be transformed through a series of functions\n* ```js\n* // Create pipeline\n* const p = Points.pipeline(Points.normalise, Points.invert);\n*\n* // Now run it on `somePoint`.\n* // First we normalised, and then invert\n* const changedPoint = p(somePoint);\n* ```\n*\n* If you don't want to create a pipeline, use {@link pipelineApply}.\n* @param pipeline Pipeline of functions\n* @returns\n*/\nconst pipeline = (...pipeline) => (pt) => pipeline.reduce((previous, current) => current(previous), pt);\n//#endregion\n//#region src/vector.ts\nvar vector_exports = /* @__PURE__ */ __exportAll({\n\tclampMagnitude: () => clampMagnitude,\n\tdivide: () => divide,\n\tdotProduct: () => dotProduct$1,\n\tfromLineCartesian: () => fromLineCartesian,\n\tfromLinePolar: () => fromLinePolar,\n\tfromPointPolar: () => fromPointPolar,\n\tfromRadians: () => fromRadians,\n\tmultiply: () => multiply$1,\n\tnormalise: () => normalise,\n\tquadrantOffsetAngle: () => quadrantOffsetAngle,\n\tsubtract: () => subtract$1,\n\tsum: () => sum,\n\ttoCartesian: () => toCartesian,\n\ttoPolar: () => toPolar,\n\ttoRadians: () => toRadians,\n\ttoString: () => toString$1\n});\nconst EmptyCartesian = Object.freeze({\n\tx: 0,\n\ty: 0\n});\nconst piPi = Math.PI * 2;\nconst pi = Math.PI;\nfunction fromRadians(radians) {\n\treturn Object.freeze({\n\t\tx: Math.cos(radians),\n\t\ty: Math.sin(radians)\n\t});\n}\nfunction toRadians(point) {\n\treturn Math.atan2(point.y, point.x);\n}\n/**\n* Create a vector from a point\n*\n* If `unipolar` normalisation is used, direction will be fixed to 0..2π\n* if `bipolar` normalisation is used, direction will be fixed to -π...π\n* @param pt Point\n* @param angleNormalisation Technique to normalise angle\n* @param origin Origin to calculate vector from or 0,0 if left empty\n* @returns\n*/\nfunction fromPointPolar(pt, angleNormalisation = ``, origin = EmptyCartesian) {\n\tpt = subtract$2(pt, origin);\n\tlet direction = Math.atan2(pt.y, pt.x);\n\tif (angleNormalisation === `unipolar` && direction < 0) direction += piPi;\n\telse if (angleNormalisation === `bipolar`) {\n\t\tif (direction > pi) direction -= piPi;\n\t\telse if (direction <= -pi) direction += piPi;\n\t}\n\treturn Object.freeze({\n\t\tdistance: distance$1(pt),\n\t\tangleRadian: direction\n\t});\n}\n/**\n* Returns a Cartesian-coordinate vector from a line a -> b\n* @param line\n* @returns\n*/\nfunction fromLineCartesian(line) {\n\treturn subtract$2(line.b, line.a);\n}\n/**\n* Returns a polar-coordinate vector from a line a -> b\n* @param line\n* @returns\n*/\nfunction fromLinePolar(line) {\n\tresultThrow(lineTest(line, `line`));\n\treturn fromPointPolar(subtract$2(line.b, line.a));\n}\nfunction isPolar(v) {\n\tif (isPolarCoord(v)) return true;\n\treturn false;\n}\nfunction isCartesian(v) {\n\tif (isPoint(v)) return true;\n\treturn false;\n}\n/**\n* Returns the normalised vector (aka unit vector). This is where\n* direction is kept, but magnitude set to 1. This then just\n* suggests direction.\n* @param v\n* @returns\n*/\nfunction normalise(v) {\n\tif (isPolar(v)) return normalise$2(v);\n\telse if (isCartesian(v)) return normalise$1(v);\n\tthrow new Error(`Expected polar/cartesian vector. Got: ${v}`);\n}\nfunction quadrantOffsetAngle(p) {\n\tif (p.x >= 0 && p.y >= 0) return 0;\n\tif (p.x < 0 && p.y >= 0) return pi;\n\tif (p.x < 0 && p.y < 0) return pi;\n\treturn piPi;\n}\n/**\n* Converts a vector to a polar coordinate. If the provided\n* value is already Polar, it is returned.\n* @param v\n* @param origin\n* @returns Polar vector\n*/\nfunction toPolar(v, origin = Empty$1) {\n\tif (isPolar(v)) return v;\n\telse if (isCartesian(v)) return fromCartesian(v, origin);\n\tthrow new Error(`Expected polar/cartesian vector. Got: ${v}`);\n}\n/**\n* Converts a Vector to a Cartesian coordinate. If the provided\n* value is already Cartesian, it is returned.\n* @param v\n* @returns Cartestian vector\n*/\nfunction toCartesian(v) {\n\tif (isPolar(v)) return toPoint(v);\n\telse if (isCartesian(v)) return v;\n\tthrow new Error(`Expected polar/cartesian vector. Got: ${v}`);\n}\n/**\n* Return a human-friendly representation of vector\n* @param v\n* @param digits\n* @returns\n*/\nfunction toString$1(v, digits) {\n\tif (isPolar(v)) return toString$3(v, digits);\n\telse if (isCartesian(v)) return toString$2(v, digits);\n\tthrow new Error(`Expected polar/cartesian vector. Got: ${v}`);\n}\n/**\n* Calculate dot product of a vector\n* @param a\n* @param b\n* @returns\n*/\nfunction dotProduct$1(a, b) {\n\tif (isPolar(a) && isPolar(b)) return dotProduct$3(a, b);\n\telse if (isCartesian(a) && isCartesian(b)) return dotProduct$2(a, b);\n\tthrow new Error(`Expected two polar/Cartesian vectors.`);\n}\n/**\n* Clamps the magnitude of a vector\n* @param v Vector to clamp\n* @param max Maximum magnitude\n* @param min Minium magnitude\n* @returns\n*/\nfunction clampMagnitude(v, max = 1, min = 0) {\n\tif (isPolar(v)) return clampMagnitude$2(v, max, min);\n\telse if (isCartesian(v)) return clampMagnitude$1(v, max, min);\n\tthrow new Error(`Expected either polar or Cartesian vector`);\n}\n/**\n* Returns `a + b`.\n*\n* Vector is returned in the same type as `a`.\n* @param a\n* @param b\n* @returns\n*/\nfunction sum(a, b) {\n\tconst polar = isPolar(a);\n\ta = toCartesian(a);\n\tb = toCartesian(b);\n\tconst c = sum$2(a, b);\n\treturn polar ? toPolar(c) : c;\n}\n/**\n* Returns `a - b`.\n*\n* Vector is returned in the same type as `a`\n* @param a\n* @param b\n*/\nfunction subtract$1(a, b) {\n\tconst polar = isPolar(a);\n\ta = toCartesian(a);\n\tb = toCartesian(b);\n\tconst c = subtract$2(a, b);\n\treturn polar ? toPolar(c) : c;\n}\n/**\n* Returns `a * b`.\n*\n* Vector is returned in the same type `a`.\n* @param a\n* @param b\n*/\nfunction multiply$1(a, b) {\n\tconst polar = isPolar(a);\n\ta = toCartesian(a);\n\tb = toCartesian(b);\n\tconst c = multiply$2(a, b);\n\treturn polar ? toPolar(c) : c;\n}\n/**\n* Returns `a / b`.\n*\n* Vector is returned in the same type `a`.\n* @param a\n* @param b\n*/\nfunction divide(a, b) {\n\tconst polar = isPolar(a);\n\ta = toCartesian(a);\n\tb = toCartesian(b);\n\tconst c = divide$2(a, b);\n\treturn polar ? toPolar(c) : c;\n}\n//#endregion\n//#region src/point/relation.ts\n/**\n* Tracks the relation between two points.\n* \n* 1. Call `Points.relation` with the initial reference point\n* 2. You get back a function\n* 3. Call the function with a new point to compute relational information.\n* \n* It computes angle, average, centroid, distance and speed.\n* \n* ```js\n* // Reference point: 50,50\n* const t = Points.relation({x:50,y:50}); // t is a function\n*\n* // Invoke the returned function with a point\n* const relation = t({ x:0, y:0 }); // Juicy relational data\n* ```\n* \n* Or with destructuring:\n* \n* ```js\n* const { angle, distanceFromStart, distanceFromLast, average, centroid, speed } = t({ x:0,y:0 });\n* ```\n*\n* x & y coordinates can also be used as parameters:\n* ```js\n* const t = Points.relation(50, 50);\n* const result = t(0, 0);\n* // result.speed, result.angle ...\n* ```\n*\n* Note that intermediate values are not stored. It keeps the initial\n* and most-recent point. If you want to compute something over a set\n* of prior points, you may want to use {@link PointsTracker}\n* @param a Initial point, or x value\n* @param b y value, if first option is a number.\n* @returns\n*/\nconst relation = (a, b) => {\n\tconst start = getPointParameter(a, b);\n\tlet totalX = 0;\n\tlet totalY = 0;\n\tlet count = 0;\n\tlet lastUpdate = performance.now();\n\tlet lastPoint = start;\n\tconst update = (aa, bb) => {\n\t\tconst p = getPointParameter(aa, bb);\n\t\ttotalX += p.x;\n\t\ttotalY += p.y;\n\t\tcount++;\n\t\tconst distanceFromStart = distance$1(p, start);\n\t\tconst distanceFromLast = distance$1(p, lastPoint);\n\t\tconst now = performance.now();\n\t\tconst speed = distanceFromLast / (now - lastUpdate);\n\t\tlastUpdate = now;\n\t\tlastPoint = p;\n\t\treturn Object.freeze({\n\t\t\tangle: angleRadian$1(p, start),\n\t\t\tdistanceFromStart,\n\t\t\tdistanceFromLast,\n\t\t\tspeed,\n\t\t\tcentroid: centroid(p, start),\n\t\t\taverage: {\n\t\t\t\tx: totalX / count,\n\t\t\t\ty: totalY / count\n\t\t\t}\n\t\t});\n\t};\n\treturn update;\n};\n//#endregion\n//#region src/point/point-type.ts\n/**\n* Placeholder point: `{ x: NaN, y: NaN }`\n* Use `isPlaceholder` to check if a point is a placeholder.\n* Use `Placeholder3d` get a point with `z` property.\n*/\nconst Placeholder$1 = Object.freeze({\n\tx: NaN,\n\ty: NaN\n});\n/**\n* Placeholder point: `{x: NaN, y:NaN, z:NaN }`\n* Use `isPlaceholder` to check if a point is a placeholder.\n* Use `Placeholder` to get a point without `z` property.\n*/\nconst Placeholder3d = Object.freeze({\n\tx: NaN,\n\ty: NaN,\n\tz: NaN\n});\n//#endregion\n//#region src/point/point-tracker.ts\n/**\n* A tracked point. Mutable. Useful for monitoring how\n* it changes over time. Eg. when a pointerdown event happens, to record the start position and then\n* track the pointer as it moves until pointerup.\n*\n* See also\n* * [Playground](https://clinth.github.io/ixfx-play/data/point-tracker/index.html)\n* * {@link PointsTracker}: Track several points, useful for multi-touch.\n* * [ixfx Guide to Point Tracker](https://ixfx.fun/geometry/tracking/)\n* \n* ```js\n* // Create a tracker on a pointerdown\n* const t = new PointTracker();\n*\n* // ...and later, tell it when a point is seen (eg. pointermove)\n* const nfo = t.seen({x: evt.x, y:evt.y});\n* // nfo gives us some details on the relation between the seen point, the start, and points inbetween\n* // nfo.angle, nfo.centroid, nfo.speed etc.\n* ```\n*\n* Compute based on last seen point\n* ```js\n* t.angleFromStart();\n* t.distanceFromStart();\n* t.x / t.y\n* t.length; // Total length of accumulated points\n* t.elapsed; // Total duration since start\n* t.lastResult; // The PointSeenInfo for last seen point\n* ```\n*\n* Housekeeping\n* ```js\n* t.reset(); // Reset tracker\n* ```\n*\n* By default, the tracker only keeps track of the initial point and\n* does not store intermediate 'seen' points. To use the tracker as a buffer,\n* set `storeIntermediate` option to _true_.\n*\n* ```js\n* // Keep only the last 10 points\n* const t = new PointTracker({\n* sampleLimit: 10\n* });\n*\n* // Store all 'seen' points\n* const t = new PointTracker({\n* storeIntermediate: true\n* });\n*\n* // In this case, the whole tracker is automatically\n* // reset after 10 samples\n* const t = new PointTracker({\n* resetAfterSamples: 10\n* })\n* ```\n*\n* When using a buffer limited by `sampleLimit`, the 'initial' point will be the oldest in the\n* buffer, not actually the very first point seen.\n*/\nvar PointTracker = class extends ObjectTracker {\n\tinitialRelation;\n\tmarkRelation;\n\tlastResult;\n\tconstructor(opts = {}) {\n\t\tsuper(opts);\n\t}\n\t/**\n\t* Notification that buffer has been knocked down to `sampleLimit`.\n\t* \n\t* This will reset the `initialRelation`, which will use the new oldest value.\n\t*/\n\tonTrimmed(_reason) {\n\t\tthis.initialRelation = void 0;\n\t}\n\t/**\n\t* @ignore\n\t*/\n\tonReset() {\n\t\tsuper.onReset();\n\t\tthis.lastResult = void 0;\n\t\tthis.initialRelation = void 0;\n\t\tthis.markRelation = void 0;\n\t}\n\t/**\n\t* Makes a 'mark' in the tracker, allowing you to compare values\n\t* to this point.\n\t*/\n\tmark() {\n\t\tthis.markRelation = relation(this.last);\n\t}\n\t/**\n\t* Tracks a point, returning data on its relation to the\n\t* initial point and the last received point.\n\t* \n\t* @param _p Point\n\t*/\n\tcomputeResults(_p) {\n\t\tconst currentLast = this.last;\n\t\tconst previousLast = this.values.at(-2);\n\t\tif (this.initialRelation === void 0 && this.initial) this.initialRelation = relation(this.initial);\n\t\telse if (this.initialRelation === void 0) throw new Error(`Bug: No initialRelation, and this.inital is undefined?`);\n\t\tconst lastRelation = previousLast === void 0 ? relation(currentLast) : relation(previousLast);\n\t\tconst initialRel = this.initialRelation(currentLast);\n\t\tconst markRel = this.markRelation !== void 0 ? this.markRelation(currentLast) : void 0;\n\t\tconst speed = previousLast === void 0 ? 0 : length$1(previousLast, currentLast, true) / (currentLast.at - previousLast.at);\n\t\tconst r = {\n\t\t\tfromInitial: initialRel,\n\t\t\tfromLast: {\n\t\t\t\t...lastRelation(currentLast),\n\t\t\t\tspeed\n\t\t\t},\n\t\t\tfromMark: markRel,\n\t\t\tvalues: [...this.values]\n\t\t};\n\t\tthis.lastResult = r;\n\t\treturn r;\n\t}\n\t/**\n\t* Returns a polyline representation of stored points.\n\t* Returns an empty array if points were not saved, or there's only one.\n\t*/\n\tget line() {\n\t\tif (this.values.length === 1) return [];\n\t\treturn joinPointsToLines(...this.values);\n\t}\n\t/**\n\t* Returns a vector of the initial/last points of the tracker.\n\t* Returns as a polar coordinate\n\t*/\n\tget vectorPolar() {\n\t\treturn fromLinePolar(this.lineStartEnd);\n\t}\n\t/**\n\t* Returns a vector of the initial/last points of the tracker.\n\t* Returns as a Cartesian coordinate\n\t*/\n\tget vectorCartesian() {\n\t\treturn fromLineCartesian(this.lineStartEnd);\n\t}\n\t/**\n\t* Returns a line from initial point to last point.\n\t*\n\t* If there are less than two points, Lines.Empty is returned\n\t*/\n\tget lineStartEnd() {\n\t\tconst initial = this.initial;\n\t\tif (this.values.length < 2 || !initial) return Empty;\n\t\treturn {\n\t\t\ta: initial,\n\t\t\tb: this.last\n\t\t};\n\t}\n\t/**\n\t* Returns distance from latest point to initial point.\n\t* If there are less than two points, zero is returned.\n\t*\n\t* This is the direct distance from initial to last,\n\t* not the accumulated length. Use {@link lengthTotal} for that.\n\t* @param force2d If _true_ distance is calculated only in 2d\n\t* @returns Distance\n\t*/\n\tdistanceFromStart(force2d = false) {\n\t\tconst initial = this.initial;\n\t\treturn this.values.length >= 2 && initial !== void 0 ? force2d ? distance2d(initial, this.last) : distance$1(initial, this.last) : 0;\n\t}\n\t/**\n\t* Returns the speed (over milliseconds) based on accumulated travel distance.\n\t* \n\t* If there's no initial point, 0 is returned.\n\t* @param force2d If _true_, speed is calculated with x,y only\n\t* @returns \n\t*/\n\tspeedFromStart(force2d = false) {\n\t\tconst d = this.lengthTotal(force2d);\n\t\tconst t = this.timespan;\n\t\tif (Number.isNaN(t)) return 0;\n\t\tif (d === 0) return 0;\n\t\treturn Math.abs(d) / t;\n\t}\n\tspeedFromLast(force2d = false) {\n\t\tconst l = this.lastResult;\n\t\tif (!l) return 0;\n\t\treturn l.fromLast.speed;\n\t}\n\t/**\n\t* Difference between last point and the initial point, calculated\n\t* as a simple subtraction of x,y & z.\n\t*\n\t* `Points.Placeholder` is returned if there's only one point so far.\n\t*/\n\tdifference() {\n\t\tconst initial = this.initial;\n\t\treturn this.values.length >= 2 && initial !== void 0 ? subtract$2(this.last, initial) : Placeholder$1;\n\t}\n\t/**\n\t* Returns angle (in radians) from latest point to the initial point\n\t* If there are less than two points, undefined is return.\n\t* @returns Angle in radians\n\t*/\n\tangleFromStart() {\n\t\tconst initial = this.initial;\n\t\tif (initial !== void 0 && this.values.length > 2) return angleRadian$1(initial, this.last);\n\t}\n\t/**\n\t* Returns the total distance from accumulated points.\n\t* Returns 0 if points were not saved, or there's only one.\n\t* \n\t* Use {@link lengthAverage} to get the average length for all segments\n\t* @param force2d If _true_ length is calculated using x&y only\n\t*/\n\tlengthTotal(force2d = false) {\n\t\tif (this.values.length === 1) return 0;\n\t\tconst l = this.line;\n\t\treturn length$1(l, force2d);\n\t}\n\t/**\n\t* Adds up the accumulated length of all points (using {@link lengthTotal})\n\t* dividing by the total number of points.\n\t* @param force2d \n\t* @returns \n\t*/\n\tlengthAverage(force2d = false) {\n\t\treturn this.lengthTotal(force2d) / this.values.length;\n\t}\n\t/**\n\t* Returns the last x coord\n\t*/\n\tget x() {\n\t\treturn this.last.x;\n\t}\n\t/**\n\t* Returns the last y coord\n\t*/\n\tget y() {\n\t\treturn this.last.y;\n\t}\n\t/**\n\t* Returns the last z coord (or _undefined_ if not available)\n\t*/\n\tget z() {\n\t\treturn this.last.z;\n\t}\n};\n/**\n* A {@link TrackedValueMap} for points. Uses {@link PointTracker} to\n* track added values.\n*/\nvar PointsTracker = class extends TrackedValueMap {\n\tconstructor(opts = {}) {\n\t\tsuper((key, start) => {\n\t\t\tif (start === void 0) throw new Error(`Requires start point`);\n\t\t\tconst p = new PointTracker({\n\t\t\t\t...opts,\n\t\t\t\tid: key\n\t\t\t});\n\t\t\tp.seen(start);\n\t\t\treturn p;\n\t\t});\n\t}\n\tget(id) {\n\t\treturn super.get(id);\n\t}\n};\nvar UserPointerTracker = class extends PointTracker {\n\t/**\n\t* Adds a PointerEvent along with its\n\t* coalesced events, if available.\n\t* @param p \n\t* @returns \n\t*/\n\tseenEvent(p) {\n\t\tif (`getCoalescedEvents` in p) {\n\t\t\tconst asPoints = p.getCoalescedEvents().map((event) => ({\n\t\t\t\tx: event.clientX,\n\t\t\t\ty: event.clientY\n\t\t\t}));\n\t\t\treturn this.seen(...asPoints);\n\t\t} else return this.seen({\n\t\t\tx: p.clientX,\n\t\t\ty: p.clientY\n\t\t});\n\t}\n};\nvar UserPointersTracker = class extends TrackedValueMap {\n\tconstructor(opts = {}) {\n\t\tsuper((key, start) => {\n\t\t\tif (start === void 0) throw new Error(`Requires start point`);\n\t\t\tconst p = new UserPointerTracker({\n\t\t\t\t...opts,\n\t\t\t\tid: key\n\t\t\t});\n\t\t\tp.seen(start);\n\t\t\treturn p;\n\t\t});\n\t}\n\tget(id) {\n\t\treturn super.get(id);\n\t}\n\t/**\n\t* Track a PointerEvent\n\t* @param event\n\t*/\n\tseenEvent(event) {\n\t\tif (`getCoalescedEvents` in event) {\n\t\t\tconst seens = event.getCoalescedEvents().map((subEvent) => super.seen(subEvent.pointerId.toString(), subEvent));\n\t\t\treturn Promise.all(seens);\n\t\t} else return Promise.all([super.seen(event.pointerId.toString(), event)]);\n\t}\n};\n//#endregion\n//#region src/point/progress-between.ts\n/**\n* Computes the progress between two waypoints, given `position`.\n* \n* [Source](https://www.habrador.com/tutorials/math/2-passed-waypoint/?s=09)\n* @param position Current position\n* @param waypointA Start\n* @param waypointB End\n* @returns \n*/\nconst progressBetween = (position, waypointA, waypointB) => {\n\tconst a = subtract$2(position, waypointA);\n\tconst b = subtract$2(waypointB, waypointA);\n\treturn isPoint3d(a) && isPoint3d(b) ? (a.x * b.x + a.y * b.y + a.z * b.z) / (b.x * b.x + b.y * b.y + b.z * b.z) : (a.x * b.x + a.y * b.y) / (b.x * b.x + b.y * b.y);\n};\n//#endregion\n//#region src/point/project.ts\n/**\n* Project `origin` by `distance` and `angle` (radians).\n*\n* To figure out rotation, imagine a horizontal line running through `origin`.\n* * Rotation = 0 deg puts the point on the right of origin, on same y-axis\n* * Rotation = 90 deg/3:00 puts the point below origin, on the same x-axis\n* * Rotation = 180 deg/6:00 puts the point on the left of origin on the same y-axis\n* * Rotation = 270 deg/12:00 puts the point above the origin, on the same x-axis\n*\n* ```js\n* // Yields a point 100 units away from 10,20 with 10 degrees rotation (ie slightly down)\n* const a = Points.project({x:10, y:20}, 100, degreeToRadian(10));\n* ```\n* @param origin\n* @param distance\n* @param angle\n* @returns\n*/\nconst project = (origin, distance, angle) => {\n\treturn {\n\t\tx: Math.cos(angle) * distance + origin.x,\n\t\ty: Math.sin(angle) * distance + origin.y\n\t};\n};\n//#endregion\n//#region src/point/quantise.ts\n/**\n* Quantises a point.\n* @param pt \n* @param snap \n* @param middleRoundsUp \n* @returns \n*/\nfunction quantiseEvery$1(pt, snap, middleRoundsUp = true) {\n\tguard(pt, `pt`);\n\tguard(snap, `snap`);\n\tif (isPoint3d(pt)) {\n\t\tif (!isPoint3d(snap)) throw new TypeError(`Param 'snap' is missing 'z' field`);\n\t\treturn Object.freeze({\n\t\t\tx: quantiseEvery(pt.x, snap.x, middleRoundsUp),\n\t\t\ty: quantiseEvery(pt.y, snap.y, middleRoundsUp),\n\t\t\tz: quantiseEvery(pt.z, snap.z, middleRoundsUp)\n\t\t});\n\t}\n\treturn Object.freeze({\n\t\tx: quantiseEvery(pt.x, snap.x, middleRoundsUp),\n\t\ty: quantiseEvery(pt.y, snap.y, middleRoundsUp)\n\t});\n}\n//#endregion\n//#region src/point/random.ts\n/**\n* Returns a random 2D point on a 0..1 scale.\n* ```js\n* import { Points } from \"@ixfx/geometry.js\";\n* const pt = Points.random(); // eg {x: 0.2549012, y:0.859301}\n* ```\n*\n* A custom source of randomness can be provided:\n* ```js\n* import { Points } from \"@ixfx/geometry.js\";\n* import { weightedSource } from \"@ixfx/random.js\"\n* const pt = Points.random(weightedSource(`quadIn`));\n* ```\n* @param rando\n* @returns\n*/\nconst random = (rando) => {\n\tif (typeof rando === `undefined`) rando = Math.random;\n\treturn Object.freeze({\n\t\tx: rando(),\n\t\ty: rando()\n\t});\n};\n/**\n* Returns a random 3D point on a 0..1 scale.\n* ```js\n* import { Points } from \"@ixfx/geometry\";\n* const pt = Points.random(); // eg {x: 0.2549012, y:0.859301}\n* ```\n*\n* A custom source of randomness can be provided:\n* ```js\n* import { Points } from \"@ixfx/geometry\";\n* import { weightedSource } from \"@ixfx/random.js\"\n* const pt = Points.random(weightedSource(`quadIn`));\n* ```\n* @param rando\n* @returns\n*/\nconst random3d = (rando) => {\n\tif (typeof rando === `undefined`) rando = Math.random;\n\treturn Object.freeze({\n\t\tx: rando(),\n\t\ty: rando(),\n\t\tz: rando()\n\t});\n};\n//#endregion\n//#region src/point/reduce.ts\n/**\n* Reduces over points, treating _x_ and _y_ separately.\n*\n* ```\n* // Sum x and y values\n* const total = Points.reduce(points, (p, acc) => {\n* return {x: p.x + acc.x, y: p.y + acc.y}\n* });\n* ```\n* @param pts Points to reduce\n* @param fn Reducer\n* @param initial Initial value, uses `{ x:0, y:0 }` by default\n* @returns\n*/\nconst reduce = (pts, fn, initial) => {\n\tif (initial === void 0) initial = {\n\t\tx: 0,\n\t\ty: 0\n\t};\n\tlet accumulator = initial;\n\tfor (const p of pts) accumulator = fn(p, accumulator);\n\treturn accumulator;\n};\n//#endregion\n//#region src/point/rotate.ts\nfunction rotate$1(pt, amountRadian, origin) {\n\tif (typeof origin === `undefined`) origin = {\n\t\tx: 0,\n\t\ty: 0\n\t};\n\tguard(origin, `origin`);\n\tresultThrow(numberTest(amountRadian, ``, `amountRadian`));\n\tconst arrayInput = Array.isArray(pt);\n\tif (amountRadian === 0) return pt;\n\tif (!arrayInput) pt = [pt];\n\tconst ptAr = pt;\n\tfor (const [index, p] of ptAr.entries()) guard(p, `pt[${index}]`);\n\tconst asCartesisan = ptAr.map((p) => fromCartesian(p, origin)).map((p) => rotate$2(p, amountRadian)).map((p) => toCartesian$1(p, origin));\n\treturn arrayInput ? asCartesisan : asCartesisan[0];\n}\n//#endregion\n//#region src/point/rotate-point-array.ts\nconst rotatePointArray = (v, amountRadian) => {\n\tconst mat = [[Math.cos(amountRadian), -Math.sin(amountRadian)], [Math.sin(amountRadian), Math.cos(amountRadian)]];\n\tconst result = [];\n\tfor (const [index, element] of v.entries()) result[index] = [mat[0][0] * element[0] + mat[0][1] * element[1], mat[1][0] * element[0] + mat[1][1] * element[1]];\n\treturn result;\n};\n//#endregion\n//#region src/point/round.ts\n/**\n* Round the point's _x_ and _y_ to given number of digits\n* @param ptOrX \n* @param yOrDigits \n* @param digits \n* @returns \n*/\nconst round$1 = (ptOrX, yOrDigits, digits) => {\n\tconst pt = getPointParameter(ptOrX, yOrDigits);\n\tdigits = digits ?? yOrDigits;\n\tdigits = digits ?? 2;\n\treturn Object.freeze({\n\t\t...pt,\n\t\tx: round(digits, pt.x),\n\t\ty: round(digits, pt.y)\n\t});\n};\n//#endregion\n//#region src/point/within-range.ts\n/**\n* Returns true if two points are within a specified range on both axes.\n* \n* Provide a point for the range to set different x/y range, or pass a number\n* to use the same range for both axis.\n*\n* Note this simply compares x,y values it does not calcuate distance.\n*\n* @example\n* ```js\n* withinRange({x:100,y:100}, {x:101, y:101}, 1); // True\n* withinRange({x:100,y:100}, {x:105, y:101}, {x:5, y:1}); // True\n* withinRange({x:100,y:100}, {x:105, y:105}, {x:5, y:1}); // False - y axis too far\n* ```\n* @param a\n* @param b\n* @param maxRange\n* @returns\n*/\nconst withinRange$1 = (a, b, maxRange) => {\n\tguard(a, `a`);\n\tguard(b, `b`);\n\tif (typeof maxRange === `number`) {\n\t\tresultThrow(numberTest(maxRange, `positive`, `maxRange`));\n\t\tmaxRange = {\n\t\t\tx: maxRange,\n\t\t\ty: maxRange\n\t\t};\n\t} else guard(maxRange, `maxRange`);\n\tconst x = Math.abs(b.x - a.x);\n\tconst y = Math.abs(b.y - a.y);\n\treturn x <= maxRange.x && y <= maxRange.y;\n};\n//#endregion\n//#region src/point/wrap.ts\n/**\n* Wraps a point to be within `ptMin` and `ptMax`.\n* Note that max values are _exclusive_, meaning the return value will always be one less.\n*\n* Eg, if a view port is 100x100 pixels, wrapping the point 150,100 yields 50,99.\n*\n* ```js\n* // Wraps 150,100 to on 0,0 -100,100 range\n* wrap({x:150,y:100}, {x:100,y:100});\n* ```\n*\n* Wrap normalised point:\n* ```js\n* wrap({x:1.2, y:1.5}); // Yields: {x:0.2, y:0.5}\n* ```\n* @param pt Point to wrap\n* @param ptMax Maximum value, or `{ x:1, y:1 }` by default\n* @param ptMin Minimum value, or `{ x:0, y:0 }` by default\n* @returns Wrapped point\n*/\nconst wrap$1 = (pt, ptMax, ptMin) => {\n\tif (ptMax === void 0) ptMax = {\n\t\tx: 1,\n\t\ty: 1\n\t};\n\tif (ptMin === void 0) ptMin = {\n\t\tx: 0,\n\t\ty: 0\n\t};\n\tguard(pt, `pt`);\n\tguard(ptMax, `ptMax`);\n\tguard(ptMin, `ptMin`);\n\treturn Object.freeze({\n\t\tx: wrap(pt.x, ptMin.x, ptMax.x),\n\t\ty: wrap(pt.y, ptMin.y, ptMax.y)\n\t});\n};\n//#endregion\n//#region src/point/index.ts\nvar point_exports = /* @__PURE__ */ __exportAll({\n\tEmpty: () => Empty$1,\n\tEmpty3d: () => Empty3d,\n\tPlaceholder: () => Placeholder$1,\n\tPlaceholder3d: () => Placeholder3d,\n\tPointTracker: () => PointTracker,\n\tPointsTracker: () => PointsTracker,\n\tUnit: () => Unit,\n\tUnit3d: () => Unit3d,\n\tUserPointerTracker: () => UserPointerTracker,\n\tUserPointersTracker: () => UserPointersTracker,\n\tabs: () => abs,\n\tangleRadian: () => angleRadian$1,\n\tangleRadianCircle: () => angleRadianCircle,\n\tangleRadianThreePoint: () => angleRadianThreePoint,\n\tapply: () => apply$1,\n\taverage: () => average,\n\taverager: () => averager,\n\tbbox: () => bbox$1,\n\tbbox3d: () => bbox3d,\n\tcentroid: () => centroid,\n\tclamp: () => clamp$1,\n\tclampMagnitude: () => clampMagnitude$1,\n\tcompare: () => compare,\n\tcompareByX: () => compareByX,\n\tcompareByY: () => compareByY,\n\tcompareByZ: () => compareByZ,\n\tcompareRowwise: () => compareRowwise,\n\tconvexHull: () => convexHull,\n\tcross: () => cross,\n\tcrossProductRaw: () => crossProductRaw,\n\tdistance: () => distance$1,\n\tdistance2d: () => distance2d,\n\tdistanceToCenter: () => distanceToCenter,\n\tdistanceToExterior: () => distanceToExterior,\n\tdivide: () => divide$2,\n\tdivider: () => divider,\n\tdotProduct: () => dotProduct$2,\n\tfindMinimum: () => findMinimum,\n\tfrom: () => from,\n\tfromNumbers: () => fromNumbers,\n\tfromString: () => fromString,\n\tgetAsBounds: () => getAsBounds,\n\tgetPointParameter: () => getPointParameter,\n\tgetTwoPointParameters: () => getTwoPointParameters,\n\tguard: () => guard,\n\tguardNonZeroPoint: () => guardNonZeroPoint,\n\tinterpolate: () => interpolate,\n\tinterpolator: () => interpolator,\n\tinvert: () => invert,\n\tisEmpty: () => isEmpty$1,\n\tisEqual: () => isEqual$1,\n\tisNaN: () => isNaN,\n\tisNull: () => isNull,\n\tisPlaceholder: () => isPlaceholder$1,\n\tisPoint: () => isPoint,\n\tisPoint3d: () => isPoint3d,\n\tleftmost: () => leftmost,\n\tmultiply: () => multiply$2,\n\tmultiplyScalar: () => multiplyScalar,\n\tnormalise: () => normalise$1,\n\tnormaliseByRect: () => normaliseByRect$1,\n\tpipeline: () => pipeline,\n\tpipelineApply: () => pipelineApply,\n\tpointTest: () => pointTest,\n\tprogressBetween: () => progressBetween,\n\tproject: () => project,\n\tquantiseEvery: () => quantiseEvery$1,\n\trandom: () => random,\n\trandom3d: () => random3d,\n\treduce: () => reduce,\n\trelation: () => relation,\n\trightmost: () => rightmost,\n\trotate: () => rotate$1,\n\trotatePointArray: () => rotatePointArray,\n\tround: () => round$1,\n\tsubtract: () => subtract$2,\n\tsum: () => sum$2,\n\tto2d: () => to2d,\n\tto3d: () => to3d,\n\ttoArray: () => toArray,\n\ttoIntegerValues: () => toIntegerValues,\n\ttoString: () => toString$2,\n\twithinRange: () => withinRange$1,\n\twrap: () => wrap$1\n});\n//#endregion\n//#region src/line/rotate.ts\n/**\n* Returns a line that is rotated by `angleRad`. By default it rotates\n* around its center, but an arbitrary `origin` point can be provided.\n* If `origin` is a number, it's presumed to be a 0..1 percentage of the line.\n* \n* ```js\n* // Rotates line by 0.1 radians around point 10,10\n* const r = Lines.rotate(line, 0.1, {x:10,y:10});\n* \n* // Rotate line by 5 degrees around its center\n* const r = Lines.rotate(line, degreeToRadian(5));\n* \n* // Rotate line by 5 degres around its end point\n* const r = Lines.rotate(line, degreeToRadian(5), line.b);\n* \n* // Rotate by 90 degrees at the 80% position\n* const r = Lines.rotated = rotate(line, Math.PI / 2, 0.8);\n* ```\n* @param line Line to rotate\n* @param amountRadian Angle in radians to rotate by\n* @param origin Point to rotate around. If undefined, middle of line will be used\n* @returns \n*/\nconst rotate = (line, amountRadian, origin) => {\n\tif (typeof amountRadian === `undefined` || amountRadian === 0) return line;\n\tif (typeof origin === `undefined`) origin = .5;\n\tif (typeof origin === `number`) origin = interpolate$1(origin, line.a, line.b);\n\treturn Object.freeze({\n\t\t...line,\n\t\ta: rotate$1(line.a, amountRadian, origin),\n\t\tb: rotate$1(line.b, amountRadian, origin)\n\t});\n};\n//#endregion\n//#region src/line/is-equal.ts\n/**\n* Returns true if the lines have the same value. Note that only\n* the line start and end points are compared. So the lines might\n* be different in other properties, and `isEqual` will still return\n* true.\n* \n* ```js\n* const a = { a: {x:0, y: 10 }, b: { x: 20, y: 20 }};\n* const b = { a: {x:0, y: 10 }, b: { x: 20, y: 20 }};\n* a === b; // false, because they are different objects\n* Lines.isEqual(a, b); // true, because they have the same value\n* ```\n* @param {Line} a\n* @param {Line} b\n* @returns {boolean}\n*/\nconst isEqual = (a, b) => isEqual$1(a.a, b.a) && isEqual$1(a.b, b.b);\n//#endregion\n//#region src/line/multiply.ts\n/**\n* Multiplies start and end of line by point.x, point.y.\n* \n* ```js\n* \n* // Line 1,1 -> 10,10\n* const l = Lines.fromNumbers(1, 1, 10, 10);\n* const ll = Lines.multiply(l, {x:2, y:3});\n* // Yields: 2,20 -> 3,30\n* ```\n* @param line \n* @param point \n* @returns \n*/\nconst multiply = (line, point) => Object.freeze({\n\t...line,\n\ta: multiply$2(line.a, point),\n\tb: multiply$2(line.b, point)\n});\n//#endregion\n//#region src/line/subtract.ts\n/**\n* Subtracts both start and end points by given x,y\n* ```js\n* // Line 1,1 -> 10,10\n* const l = Lines.fromNumbers(1,1,10,10);\n* const ll = Lines.subtract(l, {x:2, y:4});\n* // Yields: -1,-3 -> 8,6\n* ```\n* @param line \n* @param point \n* @returns \n*/\nconst subtract = (line, point) => Object.freeze({\n\t...line,\n\ta: subtract$2(line.a, point),\n\tb: subtract$2(line.b, point)\n});\n//#endregion\n//#region src/line/to-string.ts\n/**\n* Returns a string representation of a line or two points.\n* @param a\n* @param b\n* @returns String representation of a line or two points\n*/\nfunction toString(a, b) {\n\tif (isLine(a)) {\n\t\tresultThrow(lineTest(a, `line`));\n\t\tb = a.b;\n\t\ta = a.a;\n\t} else if (b === void 0) throw new Error(`Expect second point if first is a point`);\n\treturn `${toString$2(a)}-${toString$2(b)}`;\n}\n//#endregion\n//#region src/line/to-path.ts\n/**\n* Returns a path wrapper around a line instance. This is useful if there are a series\n* of operations you want to do with the same line because you don't have to pass it\n* in as an argument to each function.\n* \n* Note that the line is immutable, so a function like `sum` returns a new LinePath,\n* wrapping the result of `sum`.\n* \n* ```js\n* // Create a path\n* const l = Lines.toPath(fromNumbers(0,0,10,10));\n* \n* // Now we can use it...\n* l.length();\n* \n* // Mutate functions return a new path\n* const ll = l.sum({x:10,y:10});\n* ll.length();\n* ```\n* @param line \n* @returns \n*/\nconst toPath = (line) => {\n\tconst { a, b } = line;\n\treturn Object.freeze({\n\t\t...line,\n\t\tlength: () => length$1(a, b),\n\t\tinterpolate: (amount) => interpolate$1(amount, a, b),\n\t\trelativePosition: (point) => relativePosition(line, point),\n\t\tbbox: () => bbox(line),\n\t\ttoString: () => toString(a, b),\n\t\ttoFlatArray: () => toFlatArray(a, b),\n\t\ttoSvgString: () => toSvgString(a, b),\n\t\ttoPoints: () => [a, b],\n\t\trotate: (amountRadian, origin) => toPath(rotate(line, amountRadian, origin)),\n\t\tnearest: (point) => nearest(line, point),\n\t\tsum: (point) => toPath(sum$1(line, point)),\n\t\tdivide: (point) => toPath(divide$1(line, point)),\n\t\tmultiply: (point) => toPath(multiply(line, point)),\n\t\tsubtract: (point) => toPath(subtract(line, point)),\n\t\tmidpoint: () => midpoint(a, b),\n\t\tdistanceToPoint: (point) => distanceSingleLine(line, point),\n\t\tparallel: (distance) => parallel(line, distance),\n\t\tperpendicularPoint: (distance, amount) => perpendicularPoint(line, distance, amount),\n\t\tslope: () => slope(line),\n\t\twithinRange: (point, maxRange) => withinRange(line, point, maxRange),\n\t\tisEqual: (otherLine) => isEqual(line, otherLine),\n\t\tapply: (fn) => toPath(apply(line, fn)),\n\t\tkind: `line`\n\t});\n};\n//#endregion\n//#region src/line/from-points-to-path.ts\n/**\n* Returns a {@link LinePath} from two points\n* \n* ```js\n* const path = Lines.fromPointsToPath(ptA, ptB);\n* ```\n* @param a \n* @param b \n* @returns \n*/\nconst fromPointsToPath = (a, b) => toPath(fromPoints(a, b));\n//#endregion\n//#region src/line/index.ts\nvar line_exports = /* @__PURE__ */ __exportAll({\n\tEmpty: () => Empty,\n\tPlaceholder: () => Placeholder,\n\tangleRadian: () => angleRadian,\n\tapply: () => apply,\n\tasPoints: () => asPoints,\n\tbbox: () => bbox,\n\tdistance: () => distance,\n\tdistanceSingleLine: () => distanceSingleLine,\n\tdivide: () => divide$1,\n\textendFromA: () => extendFromA,\n\tfromFlatArray: () => fromFlatArray,\n\tfromNumbers: () => fromNumbers$1,\n\tfromPivot: () => fromPivot,\n\tfromPoints: () => fromPoints,\n\tfromPointsToPath: () => fromPointsToPath,\n\tgetPointParameter: () => getPointParameter$1,\n\tinterpolate: () => interpolate$1,\n\tinterpolator: () => interpolator$1,\n\tisEmpty: () => isEmpty,\n\tisEqual: () => isEqual,\n\tisLine: () => isLine,\n\tisPlaceholder: () => isPlaceholder,\n\tisPolyLine: () => isPolyLine,\n\tjoinPointsToLines: () => joinPointsToLines,\n\tlength: () => length$1,\n\tlineTest: () => lineTest,\n\tmidpoint: () => midpoint,\n\tmultiply: () => multiply,\n\tnearest: () => nearest,\n\tnormaliseByRect: () => normaliseByRect,\n\tparallel: () => parallel,\n\tperpendicularPoint: () => perpendicularPoint,\n\tpointAtDistance: () => pointAtDistance,\n\tpointAtX: () => pointAtX,\n\tpointsOf: () => pointsOf,\n\tpolyLineToPoints: () => polyLineToPoints,\n\trelativePosition: () => relativePosition,\n\treverse: () => reverse,\n\trotate: () => rotate,\n\tscaleFromMidpoint: () => scaleFromMidpoint,\n\tslope: () => slope,\n\tsubtract: () => subtract,\n\tsum: () => sum$1,\n\ttoFlatArray: () => toFlatArray,\n\ttoPath: () => toPath,\n\ttoString: () => toString,\n\ttoSvgString: () => toSvgString,\n\twithinRange: () => withinRange\n});\nconst Empty = Object.freeze({\n\ta: Object.freeze({\n\t\tx: 0,\n\t\ty: 0\n\t}),\n\tb: Object.freeze({\n\t\tx: 0,\n\t\ty: 0\n\t})\n});\nconst Placeholder = Object.freeze({\n\ta: Object.freeze({\n\t\tx: NaN,\n\t\ty: NaN\n\t}),\n\tb: Object.freeze({\n\t\tx: NaN,\n\t\ty: NaN\n\t})\n});\n/**\n* Returns true if `l` is the same as Line.Empty, that is\n* the `a` and `b` points are Points.Empty.\n* @param l \n* @returns \n*/\nconst isEmpty = (l) => isEmpty$1(l.a) && isEmpty$1(l.b);\nconst isPlaceholder = (l) => isPlaceholder$1(l.a) && isPlaceholder$1(l.b);\n/**\n* Applies `fn` to both start and end points.\n* \n* ```js\n* // Line 10,10 -> 20,20\n* const line = Lines.fromNumbers(10,10, 20,20);\n* \n* // Applies randomisation to both x and y.\n* const rand = (p) => ({\n* x: p.x * Math.random(),\n* y: p.y * Math.random()\n* });\n* \n* // Applies our randomisation function\n* const line2 = apply(line, rand);\n* ```\n* @param line Line\n* @param fn Function that takes a point and returns a point\n* @returns \n*/\nconst apply = (line, fn) => Object.freeze({\n\t...line,\n\ta: fn(line.a),\n\tb: fn(line.b)\n});\n/**\n* Returns the angle in radians of a line, or two points\n* ```js\n* Lines.angleRadian(line);\n* Lines.angleRadian(ptA, ptB);\n* ```\n* @param lineOrPoint \n* @param b \n* @returns \n*/\nconst angleRadian = (lineOrPoint, b) => {\n\tlet a;\n\tif (isLine(lineOrPoint)) {\n\t\ta = lineOrPoint.a;\n\t\tb = lineOrPoint.b;\n\t} else {\n\t\ta = lineOrPoint;\n\t\tif (b === void 0) throw new Error(`b point must be provided`);\n\t}\n\treturn Math.atan2(b.y - a.y, b.x - a.x);\n};\n/**\n* Normalises start and end points by given width and height. Useful\n* for converting an absolutely-defined line to a relative one.\n* \n* ```js\n* \n* // Line 1,1 -> 10,10\n* const l = Lines.fromNumbers(1,1,10,10);\n* const ll = Lines.normaliseByRect(l, 10, 10);\n* // Yields: 0.1,0.1 -> 1,1\n* ```\n* @param line \n* @param width\n* @param height \n* @returns \n*/\nconst normaliseByRect = (line, width, height) => Object.freeze({\n\t...line,\n\ta: normaliseByRect$1(line.a, width, height),\n\tb: normaliseByRect$1(line.b, width, height)\n});\n/**\n* Returns true if `point` is within `maxRange` of `line`.\n* \n* ```js\n* const line = Lines.fromNumbers(0,20,20,20);\n* Lines.withinRange(line, {x:0,y:21}, 1); // True\n* ```\n* @param line\n* @param point\n* @param maxRange \n* @returns True if point is within range\n*/\nconst withinRange = (line, point, maxRange) => {\n\treturn distance(line, point) <= maxRange;\n};\n/**\n* Calculates [slope](https://en.wikipedia.org/wiki/Slope) of line.\n* \n* @example\n* ```js\n* Lines.slope(line);\n* Lines.slope(ptA, ptB)\n* ```\n* @param lineOrPoint Line or point. If point is provided, second point must be given too\n* @param b Second point if needed\n* @returns \n*/\nconst slope = (lineOrPoint, b) => {\n\tlet a;\n\tif (isLine(lineOrPoint)) {\n\t\ta = lineOrPoint.a;\n\t\tb = lineOrPoint.b;\n\t} else {\n\t\ta = lineOrPoint;\n\t\tif (b === void 0) throw new Error(`b parameter required`);\n\t}\n\tif (b === void 0) throw new TypeError(`Second point missing`);\n\telse return (b.y - a.y) / (b.x - a.x);\n};\n/**\n* Scales a line from its midpoint\n* \n* @example Shorten by 50%, anchored at the midpoint\n* ```js\n* const l = {\n* a: {x:50, y:50}, b: {x: 100, y: 90}\n* }\n* const l2 = Lines.scaleFromMidpoint(l, 0.5);\n* ```\n* @param line\n* @param factor \n*/\nconst scaleFromMidpoint = (line, factor) => {\n\treturn {\n\t\ta: interpolate$1(factor / 2, line),\n\t\tb: interpolate$1(.5 + factor / 2, line)\n\t};\n};\n/**\n* Calculates `y` where `line` intersects `x`.\n* @param line Line to extend\n* @param x Intersection of x-axis.\n*/\nconst pointAtX = (line, x) => {\n\tconst y = line.a.y + (x - line.a.x) * slope(line);\n\treturn Object.freeze({\n\t\tx,\n\t\ty\n\t});\n};\n/**\n* Returns a line extended from its `a` point by a specified distance\n*\n* ```js\n* const line = {a: {x: 0, y:0}, b: {x:10, y:10} }\n* const extended = Lines.extendFromA(line, 2);\n* ```\n* @param line\n* @param distance\n* @return Newly extended line\n*/\nconst extendFromA = (line, distance) => {\n\tconst calculatedLength = length$1(line);\n\treturn Object.freeze({\n\t\t...line,\n\t\ta: line.a,\n\t\tb: Object.freeze({\n\t\t\tx: line.b.x + (line.b.x - line.a.x) / calculatedLength * distance,\n\t\t\ty: line.b.y + (line.b.y - line.a.y) / calculatedLength * distance\n\t\t})\n\t});\n};\n/**\n* Yields every integer point along `line`. \n* \n* @example Basic usage\n* ```js\n* const l = { a: {x: 0, y: 0}, b: {x: 100, y: 100} };\n* for (const p of Lines.pointsOf(l)) {\n* // Do something with point `p`...\n* }\n* ```\n* \n* Some precision is lost as start and end\n* point is also returned as an integer.\n* \n* Uses [Bresenham's line algorithm](https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm)\n* @param line Line\n*/\nfunction* pointsOf(line) {\n\tconst { a, b } = line;\n\tlet x0 = Math.floor(a.x);\n\tlet y0 = Math.floor(a.y);\n\tconst x1 = Math.floor(b.x);\n\tconst y1 = Math.floor(b.y);\n\tconst dx = Math.abs(x1 - x0);\n\tconst dy = -Math.abs(y1 - y0);\n\tconst sx = x0 < x1 ? 1 : -1;\n\tconst sy = y0 < y1 ? 1 : -1;\n\tlet err = dx + dy;\n\twhile (true) {\n\t\tyield {\n\t\t\tx: x0,\n\t\t\ty: y0\n\t\t};\n\t\tif (x0 === x1 && y0 === y1) break;\n\t\tconst e2 = 2 * err;\n\t\tif (e2 >= dy) {\n\t\t\terr += dy;\n\t\t\tx0 += sx;\n\t\t}\n\t\tif (e2 <= dx) {\n\t\t\terr += dx;\n\t\t\ty0 += sy;\n\t\t}\n\t}\n}\n/**\n* Returns the distance of `point` to the \n* nearest point on `line`.\n* \n* ```js\n* const d = Lines.distance(line, {x:10,y:10});\n* ```\n* \n* If an array of lines is provided, the shortest distance is returned.\n* @param line Line (or array of lines)\n* @param point Point to check against\n* @returns Distance\n*/\nconst distance = (line, point) => {\n\tif (Array.isArray(line)) return minFast(line.map((l) => distanceSingleLine(l, point)));\n\telse return distanceSingleLine(line, point);\n};\n/**\n* Returns an array representation of line: [a.x, a.y, b.x, b.y]\n* \n* See {@link fromFlatArray} to create a line _from_ this representation.\n*\n* ```js\n* Lines.toFlatArray(line);\n* Lines.toFlatArray(pointA, pointB);\n* ```\n* @param {Point} a\n* @param {Point} b\n* @returns {number[]}\n*/\nconst toFlatArray = (a, b) => {\n\tif (isLine(a)) return [\n\t\ta.a.x,\n\t\ta.a.y,\n\t\ta.b.x,\n\t\ta.b.y\n\t];\n\telse if (isPoint(a) && isPoint(b)) return [\n\t\ta.x,\n\t\ta.y,\n\t\tb.x,\n\t\tb.y\n\t];\n\telse throw new Error(`Expected single line parameter, or a and b points`);\n};\n/**\n* Yields all the points of all the lines.\n* \n* ```js\n* const lines = [ ..some array of lines.. ];\n* for (const pt of Lines.asPoints(lines)) {\n* // Yields a and then b of each point sequentially\n* }\n* ```\n* @param lines \n*/\nfunction* asPoints(lines) {\n\tfor (const l of lines) {\n\t\tyield l.a;\n\t\tyield l.b;\n\t}\n}\n/**\n* Returns an SVG description of line\n* ```\n* Lines.toSvgString(ptA, ptB);\n* ```\n* @param a \n* @param b \n* @returns \n*/\nconst toSvgString = (a, b) => [`M${a.x} ${a.y} L ${b.x} ${b.y}`];\n//#endregion\nexport { interpolate as $, rotatePointArray as A, UserPointerTracker as B, multiply as C, divider as Ct, wrap$1 as D, distanceSingleLine as Dt, point_exports as E, perpendicularPoint as Et, quantiseEvery$1 as F, vector_exports as G, Placeholder$1 as H, project as I, normalise$1 as J, pipeline as K, progressBetween as L, reduce as M, random as N, withinRange$1 as O, nearest as Ot, random3d as P, invert as Q, PointTracker as R, subtract as S, divide$2 as St, rotate as T, parallel as Tt, Placeholder3d as U, UserPointersTracker as V, relation as W, rightmost as X, leftmost as Y, clampMagnitude$1 as Z, toSvgString as _, midpoint as _t, asPoints as a, crossProductRaw as at, toPath as b, fromNumbers$1 as bt, isEmpty as c, distanceToExterior as ct, normaliseByRect as d, clamp$1 as dt, interpolator as et, pointAtX as f, centroid as ft, toFlatArray as g, relativePosition as gt, slope as h, sum$1 as ht, apply as i, cross as it, rotate$1 as j, round$1 as k, normaliseByRect$1 as kt, isPlaceholder as l, distanceToCenter as lt, scaleFromMidpoint as m, abs as mt, Placeholder as n, fromNumbers as nt, distance as o, dotProduct$2 as ot, pointsOf as p, apply$1 as pt, pipelineApply as q, angleRadian as r, fromString as rt, extendFromA as s, toArray as st, Empty as t, from as tt, line_exports as u, convexHull as ut, withinRange as v, fromPivot as vt, isEqual as w, bbox as wt, toString as x, divide$1 as xt, fromPointsToPath as y, fromFlatArray as yt, PointsTracker as z };\n","//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __exportAll = (all, no_symbols) => {\n\tlet target = {};\n\tfor (var name in all) __defProp(target, name, {\n\t\tget: all[name],\n\t\tenumerable: true\n\t});\n\tif (!no_symbols) __defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\treturn target;\n};\n//#endregion\nexport { __exportAll as t };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { functionTest, resultThrow, stringTest } from \"@ixfx/guards\";\nimport { Beziers, Points } from \"@ixfx/geometry\";\nimport { scale } from \"@ixfx/numbers\";\nimport { intervalToMs } from \"@ixfx/core\";\nimport * as Flow from \"@ixfx/flow\";\n//#region src/gaussian.ts\nconst pow$1 = Math.pow;\nconst gaussianA = 1 / Math.sqrt(2 * Math.PI);\n/**\n* Returns a roughly gaussian easing function\n* ```js\n* const fn = Easings.gaussian();\n* ```\n*\n* Try different positive and negative values for `stdDev` to pinch\n* or flatten the bell shape.\n* @param standardDeviation\n* @returns\n*/\nconst gaussian = (standardDeviation = .4) => {\n\tconst mean = .5;\n\treturn (t) => {\n\t\tconst f = gaussianA / standardDeviation;\n\t\tlet p = -2.5;\n\t\tlet c = (t - mean) / standardDeviation;\n\t\tc *= c;\n\t\tp *= c;\n\t\tconst v = f * pow$1(Math.E, p);\n\t\tif (v > 1) return 1;\n\t\tif (v < 0) return 0;\n\t\treturn v;\n\t};\n};\n//#endregion\n//#region src/easing/easings-named.ts\nvar easings_named_exports = /* @__PURE__ */ __exportAll({\n\tarch: () => arch,\n\tbackIn: () => backIn,\n\tbackInOut: () => backInOut,\n\tbackOut: () => backOut,\n\tbell: () => bell,\n\tbounceIn: () => bounceIn,\n\tbounceInOut: () => bounceInOut,\n\tbounceOut: () => bounceOut,\n\tcircIn: () => circIn,\n\tcircInOut: () => circInOut,\n\tcircOut: () => circOut,\n\tcubicIn: () => cubicIn,\n\tcubicOut: () => cubicOut,\n\telasticIn: () => elasticIn,\n\telasticInOut: () => elasticInOut,\n\telasticOut: () => elasticOut,\n\texpoIn: () => expoIn,\n\texpoInOut: () => expoInOut,\n\texpoOut: () => expoOut,\n\tquadIn: () => quadIn,\n\tquadInOut: () => quadInOut,\n\tquadOut: () => quadOut,\n\tquartIn: () => quartIn,\n\tquartOut: () => quartOut,\n\tquintIn: () => quintIn,\n\tquintInOut: () => quintInOut,\n\tquintOut: () => quintOut,\n\tsineIn: () => sineIn,\n\tsineInOut: () => sineInOut,\n\tsineOut: () => sineOut,\n\tsmootherstep: () => smootherstep,\n\tsmoothstep: () => smoothstep\n});\nconst sqrt = Math.sqrt;\nconst pow = Math.pow;\nconst cos = Math.cos;\nconst pi = Math.PI;\nconst sin = Math.sin;\nconst bounceOut = (x) => {\n\tconst n1 = 7.5625;\n\tconst d1 = 2.75;\n\tif (x < 1 / d1) return n1 * x * x;\n\telse if (x < 2 / d1) return n1 * (x -= 1.5 / d1) * x + .75;\n\telse if (x < 2.5 / d1) return n1 * (x -= 2.25 / d1) * x + .9375;\n\telse return n1 * (x -= 2.625 / d1) * x + .984375;\n};\nconst quintIn = (x) => x * x * x * x * x;\nconst quintOut = (x) => 1 - pow(1 - x, 5);\nconst arch = (x) => x * (1 - x) * 4;\nconst smoothstep = (x) => x * x * (3 - 2 * x);\nconst smootherstep = (x) => (x * (x * 6 - 15) + 10) * x * x * x;\nconst sineIn = (x) => 1 - cos(x * pi / 2);\nconst sineOut = (x) => sin(x * pi / 2);\nconst quadIn = (x) => x * x;\nconst quadOut = (x) => 1 - (1 - x) * (1 - x);\nconst sineInOut = (x) => -(cos(pi * x) - 1) / 2;\nconst quadInOut = (x) => x < .5 ? 2 * x * x : 1 - pow(-2 * x + 2, 2) / 2;\nconst cubicIn = (x) => x * x * x;\nconst cubicOut = (x) => 1 - pow(1 - x, 3);\nconst quartIn = (x) => x * x * x * x;\nconst quartOut = (x) => 1 - pow(1 - x, 4);\nconst expoIn = (x) => x === 0 ? 0 : pow(2, 10 * x - 10);\nconst expoOut = (x) => x === 1 ? 1 : 1 - pow(2, -10 * x);\nconst quintInOut = (x) => x < .5 ? 16 * x * x * x * x * x : 1 - pow(-2 * x + 2, 5) / 2;\nconst expoInOut = (x) => x === 0 ? 0 : x === 1 ? 1 : x < .5 ? pow(2, 20 * x - 10) / 2 : (2 - pow(2, -20 * x + 10)) / 2;\nconst circIn = (x) => 1 - sqrt(1 - pow(x, 2));\nconst circOut = (x) => sqrt(1 - pow(x - 1, 2));\nconst backIn = (x) => {\n\tconst c1 = 1.70158;\n\treturn (c1 + 1) * x * x * x - c1 * x * x;\n};\nconst backOut = (x) => {\n\tconst c1 = 1.70158;\n\treturn 1 + (c1 + 1) * pow(x - 1, 3) + c1 * pow(x - 1, 2);\n};\nconst circInOut = (x) => x < .5 ? (1 - sqrt(1 - pow(2 * x, 2))) / 2 : (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2;\nconst backInOut = (x) => {\n\tconst c2 = 1.70158 * 1.525;\n\treturn x < .5 ? pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2) / 2 : (pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;\n};\nconst elasticIn = (x) => {\n\tconst c4 = 2 * pi / 3;\n\treturn x === 0 ? 0 : x === 1 ? 1 : -pow(2, 10 * x - 10) * sin((x * 10 - 10.75) * c4);\n};\nconst elasticOut = (x) => {\n\tconst c4 = 2 * pi / 3;\n\treturn x === 0 ? 0 : x === 1 ? 1 : pow(2, -10 * x) * sin((x * 10 - .75) * c4) + 1;\n};\nconst bounceIn = (x) => 1 - bounceOut(1 - x);\nconst bell = gaussian();\nconst elasticInOut = (x) => {\n\tconst c5 = 2 * pi / 4.5;\n\treturn x === 0 ? 0 : x === 1 ? 1 : x < .5 ? -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2 : pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5) / 2 + 1;\n};\nconst bounceInOut = (x) => x < .5 ? (1 - bounceOut(1 - 2 * x)) / 2 : (1 + bounceOut(2 * x - 1)) / 2;\n//#endregion\n//#region src/easing/line.ts\n/**\n* Interpolates points along a line.\n* By default it's a straight line, so use `bend` to make a non-linear curve.\n* @param bend -1...1. -1 will pull line up, 1 will push it down.\n* @returns \n*/\nconst line = (bend = 0, warp = 0) => {\n\tconst max = 1;\n\tconst cubicB = {\n\t\tx: scale(bend, -1, 1, 0, max),\n\t\ty: scale(bend, -1, 1, max, 0)\n\t};\n\tlet cubicA = Points.interpolate(Math.abs(bend), Points.Empty, cubicB);\n\tif (bend !== 0 && warp > 0) if (bend > 0) cubicA = Points.interpolate(warp, cubicA, {\n\t\tx: 0,\n\t\ty: cubicB.x * 2\n\t});\n\telse cubicA = Points.interpolate(warp, cubicA, {\n\t\tx: cubicB.y * 2,\n\t\ty: 0\n\t});\n\tconst bzr = Beziers.cubic(Points.Empty, Points.Unit, cubicA, cubicB);\n\tconst inter = Beziers.interpolator(bzr);\n\treturn (value) => inter(value);\n};\n//#endregion\n//#region src/modulator-timed.ts\n/**\n* Produce values over time. When the modulate function is complete, the final\n* value continues to return. Timer starts when return function is first invoked.\n* \n* ```js\n* const fn = (t) => {\n* // 't' will be values 0..1 where 1 represents end of time period.\n* // Return some computed value based on 't'\n* return t*Math.random();\n* }\n* const e = Modulate.time(fn, 1000);\n* \n* // Keep calling e() to get the current value\n* e();\n* ```\n* @param fn Modulate function\n* @param duration Duration\n* @returns \n*/\nconst time$1 = (fn, duration) => {\n\tresultThrow(functionTest(fn, `fn`));\n\tlet relative;\n\treturn () => {\n\t\tif (typeof relative === `undefined`) relative = Flow.ofTotal(duration, { clampValue: true });\n\t\treturn fn(relative());\n\t};\n};\n/**\n* Creates an modulator based on clock time. Time\n* starts being counted when modulate function is created.\n* \n* `timeModulator` allows you to reset and check for completion.\n* Alternatively, use {@link time} which is a simple function that just returns a value.\n*\n* @example Time based easing\n* ```\n* import { timeModulator } from \"@ixfx/modulation.js\";\n* const fn = (t) => {\n* // 't' will be a value 0..1 representing time elapsed. 1 being end of period.\n* return t*Math.random();\n* }\n* const t = timeModulator(fn, 5*1000); // Will take 5 seconds to complete\n* ...\n* t.compute(); // Get current value of modulator\n* t.reset(); // Reset to 0\n* t.isDone; // _True_ if finished\n* ```\n* @param fn Modulator\n* @param duration Duration\n* @returns ModulatorTimed\n*/\nconst timeModulator = (fn, duration) => {\n\tresultThrow(functionTest(fn, `fn`));\n\tconst timer = Flow.elapsedMillisecondsAbsolute();\n\tconst durationMs = intervalToMs(duration);\n\tif (durationMs === void 0) throw new Error(`Param 'duration' not provided`);\n\tconst relativeTimer = Flow.relative(durationMs, {\n\t\ttimer,\n\t\tclampValue: true\n\t});\n\treturn Flow.timerWithFunction(fn, relativeTimer);\n};\n/**\n* Produce modulate values with each invocation. When the time is complete, the final\n* value continues to return. Timer starts when return function is first invoked.\n* \n* If you need to check if a modulator is done or reset it, consider {@link tickModulator}.\n* \n* ```js\n* const fn = (t) => {\n* // 't' will be values 0..1 representing elapsed ticks toward totwal\n* }\n* const e = ticks(fn, 100);\n* \n* // Keep calling e() to get the current value\n* e();\n* ```\n* @param fn Function that produces 0..1 scale\n* @param totalTicks Total length of ticks\n* @returns \n*/\nconst ticks$1 = (fn, totalTicks) => {\n\tresultThrow(functionTest(fn, `fn`));\n\tlet relative;\n\treturn () => {\n\t\tif (typeof relative === `undefined`) relative = Flow.ofTotalTicks(totalTicks, { clampValue: true });\n\t\treturn fn(relative());\n\t};\n};\n/**\n* Creates an modulator based on ticks. \n* \n* `tickModulator` allows you to reset and check for completion.\n* Alternatively, use {@link ticks} which is a simple function that just returns a value.\n*\n* @example Tick-based modulator\n* ```\n* import { tickModulator } from \"@ixfx/modulation.js\";\n* const fn = (t) => {\n* // 't' will be values 0..1 based on completion\n* return Math.random() * t;\n* }\n* const t = tickModulator(fn, 1000); // Will take 1000 ticks to complete\n* t.compute(); // Each call to `compute` progresses the tick count\n* t.reset(); // Reset to 0\n* t.isDone; // _True_ if finished\n* ```\n* @param fn Modulate function that returns 0..1\n* @param durationTicks Duration in ticks\n* @returns ModulatorTimed\n*/\nconst tickModulator = (fn, durationTicks) => {\n\tresultThrow(functionTest(fn, `fn`));\n\tconst timer = Flow.elapsedTicksAbsolute();\n\tconst relativeTimer = Flow.relative(durationTicks, {\n\t\ttimer,\n\t\tclampValue: true\n\t});\n\treturn Flow.timerWithFunction(fn, relativeTimer);\n};\n//#endregion\n//#region src/easing.ts\nvar easing_exports = /* @__PURE__ */ __exportAll({\n\tNamed: () => easings_named_exports,\n\tcreate: () => create,\n\tget: () => get,\n\tgetEasingNames: () => getEasingNames,\n\tline: () => line,\n\ttickEasing: () => tickEasing,\n\tticks: () => ticks,\n\ttime: () => time,\n\ttimeEasing: () => timeEasing\n});\n/**\n* Creates an easing function\n* ```js\n* const e = Easings.create({ duration: 1000, name: `quadIn` });\n* const e = Easings.create({ ticks: 100, name: `sineOut` });\n* const e = Easings.create({ \n* duration: 1000, \n* fn: (v) => {\n* // v will be 0..1 based on time\n* return Math.random() * v\n* }\n* });\n* ```\n* @param options \n* @returns \n*/\nconst create = (options) => {\n\tconst fn = resolveEasingName(options.name ?? `quintIn`) ?? options.fn;\n\tif (typeof fn === `undefined`) throw new Error(`Either 'name' or 'fn' must be set`);\n\tif (`duration` in options) return time(fn, options.duration);\n\telse if (`ticks` in options) return ticks(fn, options.ticks);\n\telse throw new Error(`Expected 'duration' or 'ticks' in options`);\n};\n/**\n* Creates an easing based on clock time. Time\n* starts being counted when easing function is created.\n* \n* `timeEasing` allows you to reset and check for completion.\n* Alternatively, use {@link time} which is a simple function that just returns a value.\n*\n* \n* @example Time based easing\n* ```\n* const t = Easings.timeEasing(`quintIn`, 5*1000); // Will take 5 seconds to complete\n* ...\n* t.compute(); // Get current value of easing\n* t.reset(); // Reset to 0\n* t.isDone; // _True_ if finished\n* ```\n* \n* Thisi function is just a wrapper around Modulator.timedModulator.\n* @param nameOrFunction Name of easing, or an easing function\n* @param duration Duration\n* @returns Easing\n*/\nconst timeEasing = (nameOrFunction, duration) => {\n\treturn timeModulator(resolveEasingName(nameOrFunction), duration);\n};\n/**\n* Produce easing values over time. When the easing is complete, the final\n* value continues to return. Timer starts when return function is first invoked.\n* \n* If you need to check if an easing is done or reset it, consider {@link timeEasing}.\n* \n* ```js\n* // Quad-in easing over one second\n* const e = Easings.time(`quadIn`, 1000);\n* \n* // Keep calling e() to get the current value\n* e();\n* ```\n* \n* This function is just a wrapper around Modulate.time\n* @param nameOrFunction Easing name or a function that produces 0..1 scale\n* @param duration Duration\n* @returns \n*/\nconst time = (nameOrFunction, duration) => {\n\treturn time$1(resolveEasingName(nameOrFunction), duration);\n};\n/**\n* Produce easing values with each invocation. When the easing is complete, the final\n* value continues to return. Timer starts when return function is first invoked.\n* \n* If you need to check if an easing is done or reset it, consider {@link tickEasing}.\n* \n* ```js\n* // Quad-in easing over 100 ticks\n* const e = Easings.ticks(`quadIn`, 100);\n* \n* // Keep calling e() to get the current value\n* e();\n* ```\n* \n* This is just a wrapper around Modulator.ticks\n* @param nameOrFunction Easing name or a function that produces 0..1 scale\n* @param totalTicks Total length of ticks\n* @returns \n*/\nconst ticks = (nameOrFunction, totalTicks) => {\n\treturn ticks$1(resolveEasingName(nameOrFunction), totalTicks);\n};\n/**\n* Creates an easing based on ticks. \n* \n* `tickEasing` allows you to reset and check for completion.\n* Alternatively, use {@link ticks} which is a simple function that just returns a value.\n*\n* @example Tick-based easing\n* ```\n* const t = Easings.tickEasing(`sineIn`, 1000); // Will take 1000 ticks to complete\n* t.compute(); // Each call to `compute` progresses the tick count\n* t.reset(); // Reset to 0\n* t.isDone; // _True_ if finished\n* ```\n* @param nameOrFunction Name of easing, or an easing function\n* @param durationTicks Duration in ticks\n* @returns Easing\n*/\nconst tickEasing = (nameOrFunction, durationTicks) => {\n\treturn tickModulator(resolveEasingName(nameOrFunction), durationTicks);\n};\nconst resolveEasingName = (nameOrFunction) => {\n\tconst fn = typeof nameOrFunction === `function` ? nameOrFunction : get(nameOrFunction);\n\tif (typeof fn === `undefined`) throw typeof nameOrFunction === `string` ? /* @__PURE__ */ new Error(`Easing function not found: '${nameOrFunction}'`) : /* @__PURE__ */ new Error(`Easing function not found`);\n\treturn fn;\n};\n/**\n* Creates a new easing by name\n*\n* ```js\n* const e = Easings.create(`circInOut`, 1000, elapsedMillisecondsAbsolute);\n* ```\n* @param nameOrFunction Name of easing, or an easing function\n* @param duration Duration (meaning depends on timer source)\n* @param timerSource Timer source\n* @returns\n*/\nlet easingsMap;\n/**\n* Returns an easing function by name. Throws an error if\n* easing is not found.\n*\n* ```js\n* const fn = Easings.get(`sineIn`);\n* // Returns 'eased' transformation of 0.5\n* fn(0.5);\n* ```\n* @param easingName eg `sineIn`\n* @returns Easing function\n*/\nconst get = function(easingName) {\n\tresultThrow(stringTest(easingName, `non-empty`, `easingName`));\n\tconst found = cacheEasings().get(easingName.toLowerCase());\n\tif (found === void 0) throw new Error(`Easing not found: '${easingName}'`);\n\treturn found;\n};\nfunction cacheEasings() {\n\tif (easingsMap === void 0) {\n\t\teasingsMap = /* @__PURE__ */ new Map();\n\t\tfor (const [k, v] of Object.entries(easings_named_exports)) easingsMap.set(k.toLowerCase(), v);\n\t\treturn easingsMap;\n\t} else return easingsMap;\n}\n/**\n* Iterate over available easings.\n* @private\n* @returns Returns list of available easing names\n*/\nfunction* getEasingNames() {\n\tyield* cacheEasings().keys();\n}\n//#endregion\nexport { tickEasing as a, timeEasing as c, time$1 as d, timeModulator as f, gaussian as h, getEasingNames as i, tickModulator as l, easings_named_exports as m, easing_exports as n, ticks as o, line as p, get as r, time as s, create as t, ticks$1 as u };\n","/**\n * Colour mapping for plot components.\n *\n * Pipeline:\n * scaledValue (0..1)\n * → applyMapping (easing / custom fn)\n * → computeColour (mode → ColourResult)\n * → applyAgeModification (xy-axis only, compounds age-style on top)\n */\nimport type { EasingName } from '@ixfx/modulation';\nimport { Easings } from '@ixfx/modulation';\nimport { Colour } from '@ixfx/visual';\n\n// --- Types ---\n\nexport type ColourMode = `fixed` | `opacity` | `hue` | `saturation` | `lightness` | `scale`;\n\nexport type ColourMapConfig = {\n mode: ColourMode;\n /** Parsed colours for 'scale' mode. Must have ≥ 2 entries. */\n palette: string[];\n /** ixfx easing name — applied before the colour mode mapping. Takes precedence over valueMap. */\n easingName: string;\n /** Custom value mapping fn (0..1 → 0..1). Used when easingName is empty. */\n valueMap: ((v: number) => number) | null;\n};\n\nexport type ColourResult = { fill: string; opacity: number };\n\n// --- Defaults ---\n\nconst DEFAULT_BASE = `oklch(60% 0.15 140)`;\nconst DEFAULT_PALETTE = [`green`, `yellow`, `red`];\n\n// --- Scale cache: keyed by palette string to avoid recomputing colour steps every render ---\n\nconst _scaleCache = new Map<string, string[]>();\n\nfunction getScaleSteps(palette: string[]): string[] {\n const key = palette.join(`\\x00`);\n if (!_scaleCache.has(key)) {\n _scaleCache.set(key, Colour.scale(palette as Parameters<typeof Colour.scale>[0], { stepsBetween: 99 }));\n }\n return _scaleCache.get(key)!;\n}\n\n// --- Helpers ---\n\n/** Resolve a CSS custom property to its final value, handling var() references. */\nfunction resolveCssVariable(el: Element, prop: string): string {\n const style = getComputedStyle(el);\n let value = style.getPropertyValue(prop).trim();\n\n // Handle var() references - resolve up to 5 levels deep\n const varRegex = /var\\((--[\\w-]+)(?:,\\s*(.*))?\\)/g;\n for (let i = 0; i < 5 && value.includes(`var(`); i++) {\n value = value.replace(varRegex, (_, varName, fallback) => {\n const resolved = style.getPropertyValue(varName).trim();\n if (resolved)\n return resolved;\n if (fallback)\n return fallback.trim();\n return ``;\n });\n }\n\n return value;\n}\n\n/** Read the resolved --plot-color CSS variable from an element. */\nexport function readBaseColour(el: Element): string {\n const v = resolveCssVariable(el, `--plot-color`);\n return v || DEFAULT_BASE;\n}\n\n/** Parse a comma-separated colour string attribute into an array. Falls back to default palette. */\nexport function parseColourScaleAttr(attr: string): string[] {\n if (!attr.trim())\n return DEFAULT_PALETTE;\n const parsed = attr.split(`,`).map(s => s.trim()).filter(Boolean);\n return parsed.length >= 2 ? parsed : DEFAULT_PALETTE;\n}\n\n/** Parse any CSS colour string to HSL scalars (h, s, l all 0..1). */\nfunction toHslScalar(css: string): { h: number; s: number; l: number } {\n try {\n const hsl = Colour.HslSpace.fromCss(css, { scalar: true });\n return { h: hsl.h, s: hsl.s, l: hsl.l };\n } catch {\n return { h: 0.39, s: 0.5, l: 0.55 }; // ~green fallback\n }\n}\n\n/** Apply easing or custom mapping to a 0..1 value. Returns clamped 0..1. */\nfunction applyMapping(v: number, config: ColourMapConfig): number {\n const clamped = Math.max(0, Math.min(1, v));\n if (config.easingName) {\n try {\n return Math.max(0, Math.min(1, Easings.get(config.easingName as EasingName)(clamped)));\n } catch { /* invalid easing name — fall through */ }\n }\n if (config.valueMap) {\n return Math.max(0, Math.min(1, config.valueMap(clamped)));\n }\n return clamped;\n}\n\n// --- Main colour computation ---\n\n/**\n * Compute the fill colour and opacity for a single data point.\n * @param scaledValue Normalised value in 0..1 (data range for single-axis; age fraction for xy).\n * @param baseColour Resolved base colour string (from --plot-color).\n * @param config Colour map configuration.\n */\nexport function computeColour(scaledValue: number, baseColour: string, config: ColourMapConfig): ColourResult {\n const mapped = applyMapping(scaledValue, config);\n\n switch (config.mode) {\n case `fixed`:\n return { fill: baseColour, opacity: 1 };\n\n case `opacity`:\n return { fill: baseColour, opacity: Math.max(0.04, mapped) };\n\n case `hue`: {\n const hsl = toHslScalar(baseColour);\n return {\n fill: `hsl(${Math.round(mapped * 360)}deg ${Math.round(hsl.s * 100)}% ${Math.round(hsl.l * 100)}%)`,\n opacity: 1,\n };\n }\n\n case `saturation`: {\n const hsl = toHslScalar(baseColour);\n return {\n fill: `hsl(${Math.round(hsl.h * 360)}deg ${Math.round(mapped * 100)}% ${Math.round(hsl.l * 100)}%)`,\n opacity: 1,\n };\n }\n\n case `lightness`: {\n const hsl = toHslScalar(baseColour);\n return {\n fill: `hsl(${Math.round(hsl.h * 360)}deg ${Math.round(hsl.s * 100)}% ${Math.round(mapped * 100)}%)`,\n opacity: 1,\n };\n }\n\n case `scale`: {\n const palette = config.palette.length >= 2 ? config.palette : DEFAULT_PALETTE;\n const steps = getScaleSteps(palette);\n const idx = Math.min(steps.length - 1, Math.floor(mapped * steps.length));\n return { fill: steps[idx], opacity: 1 };\n }\n\n default:\n return { fill: baseColour, opacity: 1 };\n }\n}\n\n/**\n * Apply xy-axis age-style modification on top of a base ColourResult.\n * 'size' is not handled here — the caller adjusts the radius separately.\n */\nexport function applyAgeModification(base: ColourResult, ageFraction: number, ageStyle: string): ColourResult {\n if (ageStyle === `opacity`) {\n return { ...base, opacity: base.opacity * Math.max(0.08, ageFraction ** 0.6) };\n }\n if (ageStyle === `desaturation`) {\n const hsl = toHslScalar(base.fill);\n const sFaded = hsl.s * ageFraction; // older → less saturation\n return {\n fill: `hsl(${Math.round(hsl.h * 360)}deg ${Math.round(sFaded * 100)}% ${Math.round(hsl.l * 100)}%)`,\n opacity: base.opacity,\n };\n }\n return base;\n}\n","import { rangeStream } from \"@ixfx/numbers\";\n\nexport type PlotDataSeriesOptions = {\n /**\n * Limit of how many data points to store.\n * Default: 100\n */\n capacityLimit: number;\n /**\n * If _true_, it maintains the same scale over its lifetime.\n * If _false_, scale adjusts based on items in its cache.\n *\n * Default: true\n */\n persistentScaling: boolean;\n};\n\n/**\n * A data series\n */\nexport class PlotDataSeries {\n values: number[] = [];\n #rangeStream = rangeStream();\n range: { min: number; max: number } = { min: 0, max: 0 };\n\n #options: PlotDataSeriesOptions;\n\n /**\n * Constructor.\n *\n * Default options:\n * - `capacityLimit`: 100\n * - `persistentScaling`: true\n * @param options\n */\n constructor(options: Partial<PlotDataSeriesOptions> = {}) {\n this.#options = {\n capacityLimit: 100,\n persistentScaling: true,\n ...options,\n };\n }\n\n /**\n * Adds a single value\n * @param valueOrValues Value to add\n */\n add(valueOrValues: number | number[]) {\n if (typeof valueOrValues === `number`) {\n this.values.push(valueOrValues);\n this.range = this.#rangeStream.seen(valueOrValues);\n } else {\n this.values.push(...valueOrValues);\n for (const v of valueOrValues) {\n this.range = this.#rangeStream.seen(v);\n }\n }\n if (this.values.length > this.#options.capacityLimit) {\n this.values = this.values.slice(this.values.length - this.#options.capacityLimit);\n if (!this.#options.persistentScaling) {\n this.#recompute();\n }\n }\n }\n\n #recompute() {\n if (!this.#options.persistentScaling) {\n this.#rangeStream = rangeStream();\n }\n for (let i = 0; i < this.values.length; i++) {\n this.range = this.#rangeStream.seen(this.values[i]);\n }\n }\n\n /**\n * Sets the entire data series at once, replacing any existing data. If the number of values exceeds the `capacityLimit`, only the most recent values up to the limit are kept.\n * @param values\n */\n set(values: number[]) {\n if (values.length > this.#options.capacityLimit) {\n values = values.slice(values.length - this.#options.capacityLimit);\n }\n this.values = values;\n this.#recompute();\n }\n\n /**\n * Clear all data and reset range. If `persistentScaling` is _false_, also resets scaling to initial state.\n * @returns _true_ if there was data to clear\n */\n clear(): boolean {\n const empty = this.values.length === 0;\n this.values = [];\n if (!this.#options.persistentScaling) {\n this.#recompute();\n }\n return !empty;\n }\n}","/**\n * Shared utilities for SVG-based plot components.\n */\n\n// --- Tooltip singleton ---\n\nlet _tooltipEl: HTMLDivElement | null = null;\nlet _tooltipOwner: Element | null = null;\n\nfunction ensureTooltip(): HTMLDivElement {\n if (_tooltipEl)\n return _tooltipEl;\n const el = document.createElement(`div`);\n el.style.cssText = `\n position: fixed;\n pointer-events: none;\n z-index: 9999;\n background: var(--surface-5);\n color: var(--surface-5-text);\n border: var(--border);\n border-radius: var(--radius-l, 6px);\n box-shadow: var(--shadow-m);\n padding: 2px 6px;\n font-size: 10px;\n font-family: ui-monospace, monospace;\n opacity: 0;\n transition: opacity 0.1s ease;\n `;\n document.body.appendChild(el);\n _tooltipEl = el;\n return el;\n}\n\nexport function showTooltip(owner: Element, clientX: number, clientY: number, text: string): void {\n const el = ensureTooltip();\n _tooltipOwner = owner;\n el.textContent = text;\n el.style.whiteSpace = `nowrap`;\n el.style.left = `${clientX + 14}px`;\n el.style.top = `${clientY + 14}px`;\n el.style.opacity = `1`;\n}\n\nexport function showTooltipHTML(owner: Element, clientX: number, clientY: number, html: string): void {\n const el = ensureTooltip();\n _tooltipOwner = owner;\n el.innerHTML = html;\n el.style.whiteSpace = `normal`;\n el.style.left = `${clientX + 14}px`;\n el.style.top = `${clientY + 14}px`;\n el.style.opacity = `1`;\n}\n\nexport function hideTooltip(owner: Element): void {\n if (_tooltipOwner !== owner)\n return;\n const el = ensureTooltip();\n el.style.opacity = `0`;\n _tooltipOwner = null;\n}\n\n// --- Sizing helpers ---\n\n/** Stroke width proportional to the smaller dimension of the viewport. */\nexport function adaptiveStroke(width: number, height: number): number {\n return Math.max(1, Math.min(width, height) / 25);\n}\n\n/** Dot radius based on available space per data point and viewport height. */\nexport function adaptiveRadius(width: number, height: number, dataLength: number): number {\n if (dataLength === 0)\n return 3;\n const widthPerPoint = width / dataLength;\n return Math.max(1.5, Math.min(widthPerPoint * 0.45, height * 0.2, 8));\n}\n\n// --- Value scaling ---\n\n/** Normalize a value from [min, max] to [0, 1]. Returns 0.5 if range is zero. */\nexport function scaleValue(v: number, min: number, max: number): number {\n const range = max - min;\n return range === 0 ? 0.5 : (v - min) / range;\n}\n","import type { PlotSingleAxis, PlotSingleAxisPointerMoveDetail } from './single-axis.js';\nimport { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { hideTooltip, showTooltipHTML } from './svg-utils.js';\n\nexport type PlotMultiAxisLayout = `overlap` | `horizontal` | `vertical` | `grid`;\n\nexport type PlotMultiAxisDataPointClickDetail = {\n readonly value: number;\n readonly index: number;\n readonly series: string;\n};\n\nexport type PlotMultiAxisDataPointClickEvent = CustomEvent<PlotMultiAxisDataPointClickDetail>;\n\nexport interface PlotMultiAxisElementEventMap {\n 'plot-datapoint-click': PlotMultiAxisDataPointClickEvent;\n}\n\nconst PLOT_PALETTE = [\n `oklch(60% 0.15 30)`,\n `oklch(60% 0.15 90)`,\n `oklch(60% 0.15 150)`,\n `oklch(60% 0.15 210)`,\n `oklch(60% 0.15 270)`,\n `oklch(60% 0.15 330)`,\n `oklch(60% 0.15 60)`,\n `oklch(60% 0.15 180)`,\n];\n\n@customElement(`ixfx-plot-multi-axis`)\n// eslint-disable-next-line ts/no-unsafe-declaration-merging\nexport class PlotMultiAxis extends LitElement {\n @property() layout: PlotMultiAxisLayout = `overlap`;\n\n @property({ attribute: `grid-min-width`, type: Number })\n gridMinWidth = 200;\n\n /** Override to customize tooltip value display. */\n valueFormat: (v: number | undefined) => string = v => v ? v.toFixed(2) : ``;\n\n #instances = new Map<string, PlotSingleAxis>();\n #seriesOrder: string[] = [];\n #seriesSet = new Set<string>();\n #pendingStyles = new Map<string, Record<string, string>>();\n\n /**\n * Adds a single data point\n * @param name Series name\n * @param value Value\n * @param witholdRedraw If _false_ (default) plot is automatically redrawn\n */\n addData(name: string, value: number, witholdRedraw = false): PlotSingleAxis {\n const el = this.#addToSeries(name, value, witholdRedraw);\n // if (witholdRedraw)\n // return el;\n // this.requestUpdate();\n // this.redraw();\n return el;\n }\n\n setData(name: string, values: number[], witholdRedraw = false): PlotSingleAxis {\n const [el, created] = this.#ensurePlot(name);\n if (!this.#seriesSet.has(name)) {\n this.#seriesSet.add(name);\n this.#seriesOrder.push(name);\n }\n el.set(values, witholdRedraw);\n // if (witholdRedraw)\n // return el;\n if (created)\n this.requestUpdate();\n return el;\n }\n\n setObjects(data: Record<string, number[]>, witholdRedraw = false): void {\n const entries = Object.entries(data);\n for (const [name, vals] of entries) {\n this.setData(name, vals, true);\n }\n if (witholdRedraw)\n return;\n // this.requestUpdate();\n this.redraw();\n }\n\n /**\n * Calls redraw() on all subplots.\n */\n redraw(): void {\n for (const el of this.#instances.values()) {\n el.redraw();\n }\n }\n\n /**\n * Adds a record of data points to the plot. Each key in the record corresponds to a series name, and its value is added as a data point to that series. If a series does not exist for a given key, it will be created.\n * @param data Data to add\n * @param witholdRedraw If _false_ (default) plot is automatically redrawn after adding the data. If _true_, plot is not redrawn automatically, and you need to call `redraw()` manually to update the plot after adding the data.\n */\n addObject(data: Record<string, number | number[]>, witholdRedraw = false): void {\n const entries = Object.entries(data);\n for (const [name, val] of entries) {\n this.#addToSeries(name, val, true);\n }\n if (witholdRedraw)\n return;\n // this.requestUpdate();\n this.redraw();\n }\n\n /**\n * Styles a series by setting CSS variables on the subplot.\n * @param name Name of series\n * @param styles Styles to apply\n */\n styleSeries(name: string, styles: Record<string, string>): void {\n const normalised: Record<string, string> = {};\n for (const [key, val] of Object.entries(styles)) {\n normalised[key.startsWith(`--`) ? key : `--${key}`] = val;\n }\n\n const el = this.#instances.get(name);\n if (!el) {\n this.#pendingStyles.set(name, normalised);\n return;\n }\n for (const [key, val] of Object.entries(normalised)) {\n el.style.setProperty(key, val);\n }\n }\n\n /**\n * Clears data from all sub-plots\n * @returns _True_ if there was data to clear\n */\n clear(): boolean {\n let cleared = false;\n for (const el of this.#instances.values()) {\n cleared = cleared || el.clear();\n }\n return cleared;\n }\n\n /**\n * Clears data from a given series\n * @param name Series name\n * @returns _True_ if series was found and had data\n */\n clearSeries(name: string): boolean {\n const el = this.#instances.get(name);\n if (el) {\n el.clear();\n return true;\n }\n return false;\n }\n\n /**\n * Returns a copy of the series names\n */\n get series(): string[] {\n return [...this.#seriesOrder];\n }\n\n #addToSeries(name: string, valueOrValues: number[] | number, withholdRedraw = false): PlotSingleAxis {\n const [el, created] = this.#ensurePlot(name);\n\n if (!this.#seriesSet.has(name)) {\n this.#seriesSet.add(name);\n this.#seriesOrder.push(name);\n }\n\n el.add(valueOrValues, withholdRedraw);\n if (created)\n this.requestUpdate();\n return el;\n }\n\n #ensurePlot(name: string): [el: PlotSingleAxis, created: boolean] {\n let el = this.#instances.get(name);\n if (el)\n return [el, false];\n\n el = document.createElement(`ixfx-plot-single-axis`) as PlotSingleAxis;\n el.tooltips = false;\n this.#instances.set(name, el);\n\n const colorIndex = this.#instances.size % PLOT_PALETTE.length;\n el.style.setProperty(`--plot-color`, PLOT_PALETTE[colorIndex]);\n\n const pending = this.#pendingStyles.get(name);\n if (pending) {\n for (const [key, val] of Object.entries(pending)) {\n el.style.setProperty(key, val);\n }\n this.#pendingStyles.delete(name);\n }\n\n el.addEventListener(`plot-datapoint-click`, (e: Event) => {\n const ce = e as CustomEvent<{ value: number; index: number }>;\n this.dispatchEvent(\n new CustomEvent<PlotMultiAxisDataPointClickDetail>(`plot-datapoint-click`, {\n detail: { ...ce.detail, series: name },\n bubbles: true,\n composed: true,\n }),\n );\n });\n\n el.addEventListener(`plot-pointer-move`, (e: Event) => {\n const ce = e as CustomEvent<PlotSingleAxisPointerMoveDetail>;\n this.#onSubPlotPointerMove(ce.detail.clientX, ce.detail.clientY, ce.detail.index);\n });\n\n el.addEventListener(`plot-pointer-leave`, () => {\n this.#onSubPlotPointerLeave();\n });\n\n return [el, true];\n }\n\n #onSubPlotPointerMove(clientX: number, clientY: number, index: number): void {\n if (index < 0) {\n hideTooltip(this);\n return;\n }\n\n const parts: string[] = [];\n for (const [name, inst] of this.#instances) {\n const val = inst.getValueAt(index);\n if (val === undefined)\n continue;\n const color = getComputedStyle(inst).getPropertyValue(`--plot-color`).trim();\n parts.push(`<span style=\"color:${color}\">${this.#escapeHTML(name)}</span> ${this.valueFormat(val)}`);\n }\n\n if (parts.length === 0) {\n hideTooltip(this);\n return;\n }\n\n showTooltipHTML(this, clientX, clientY, parts.join(`<br>`));\n }\n\n #onSubPlotPointerLeave(): void {\n hideTooltip(this);\n }\n\n #escapeHTML(s: string): string {\n return s.replace(/&/g, `&`).replace(/</g, `<`).replace(/>/g, `>`).replace(/\"/g, `"`);\n }\n\n protected override render() {\n const gridStyle = this.layout === `grid` ? `--grid-min-width: ${this.gridMinWidth}px` : ``;\n\n return html`\n <div\n id=\"container\"\n class=\"layout layout-${this.layout}\"\n part=\"container\"\n style=${gridStyle}\n >\n ${repeat(\n this.#seriesOrder,\n name => name,\n name => this.#ensurePlot(name)[0],\n )}\n </div>\n `;\n }\n\n static override styles = css`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n min-height: 40px;\n --plot-color: var(--accent);\n }\n\n #container {\n width: 100%;\n height: 100%;\n }\n\n #container.layout-overlap {\n display: grid;\n }\n #container.layout-overlap > * {\n grid-area: 1 / 1;\n background: transparent;\n }\n\n #container.layout-horizontal {\n display: flex;\n flex-direction: row;\n gap: var(--space-s, 4px);\n }\n #container.layout-horizontal > * {\n flex: 1;\n min-width: 0;\n }\n\n #container.layout-vertical {\n display: flex;\n flex-direction: column;\n gap: var(--space-s, 4px);\n }\n #container.layout-vertical > * {\n flex: 1;\n min-height: 0;\n }\n\n #container.layout-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(var(--grid-min-width, 200px), 1fr));\n gap: var(--space-s, 4px);\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-plot-multi-axis': PlotMultiAxis;\n }\n}\n\n// eslint-disable-next-line ts/no-unsafe-declaration-merging\nexport interface PlotMultiAxis {\n addEventListener: {\n <K extends keyof PlotMultiAxisElementEventMap>(\n type: K,\n listener: (this: PlotMultiAxis, event: PlotMultiAxisElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n (\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n };\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues } from 'lit';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { PlotDataSeries } from './data.js';\n\nexport type PlotHistogramOrientation = `horizontal` | `vertical`;\n\nexport type PlotHistogramBucketClickDetail = {\n readonly bucketIndex: number;\n readonly valueMin: number;\n readonly valueMax: number;\n readonly relativeValue: number;\n};\n\nexport type PlotHistogramBucketClickEvent = CustomEvent<PlotHistogramBucketClickDetail>;\n\nexport interface PlotHistogramElementEventMap {\n 'plot-bucket-click': PlotHistogramBucketClickEvent;\n}\n\n@customElement(`ixfx-plot-histogram`)\nexport class PlotHistogram extends LitElement {\n @property({ attribute: `orientation` })\n orientation: PlotHistogramOrientation = `horizontal`;\n\n @property({ type: Number })\n resolution = 0.1;\n\n @property({ type: Number })\n min?: number;\n\n @property({ type: Number })\n max?: number;\n\n @property({ type: Number })\n capacity = 100;\n\n @property()\n title = ``;\n\n @property({ type: Boolean, reflect: true })\n paused = false;\n\n @state() private _width = 100;\n @state() private _height = 40;\n\n #series = new PlotDataSeries({ capacityLimit: 100, persistentScaling: true });\n #hasProgrammaticData = false;\n\n #parseDeclarativeData(text: string): number[] {\n if (!text)\n return [];\n const tokens = text.trim().split(/[,\\s;]+/);\n return tokens.map(t => Number.parseFloat(t)).filter(n => !Number.isNaN(n));\n }\n\n add(v: number): void {\n this.#hasProgrammaticData = true;\n this.#series.add(v);\n if (this.paused)\n return;\n this.requestUpdate();\n }\n\n set(values: number[]): void {\n this.#hasProgrammaticData = true;\n this.#series.set(values);\n if (this.paused)\n return;\n this.requestUpdate();\n }\n\n clear(): void {\n this.#series.clear();\n this.requestUpdate();\n }\n\n protected override firstUpdated(_changed: PropertyValues): void {\n this._width = this.clientWidth || 100;\n this._height = this.clientHeight || 40;\n const ro = new ResizeObserver((entries) => {\n const e = entries[0];\n this._width = e.contentRect.width;\n this._height = e.contentRect.height;\n });\n ro.observe(this);\n\n if (!this.#hasProgrammaticData) {\n const data = this.#parseDeclarativeData(this.textContent ?? ``);\n if (data.length > 0) {\n this.#series.set(data);\n }\n }\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(`capacity`)) {\n const old = [...this.#series.values];\n this.#series = new PlotDataSeries({\n capacityLimit: this.capacity,\n persistentScaling: true,\n });\n if (old.length > 0)\n this.#series.set(old);\n }\n }\n\n #readCssVar(name: string): string {\n return getComputedStyle(this).getPropertyValue(name).trim();\n }\n\n #getGapPx(): number {\n const val = this.#readCssVar(`--plot-histogram-gap`);\n if (val === ``)\n return 1;\n const parsed = Number.parseFloat(val);\n return Number.isFinite(parsed) ? Math.max(0, parsed) : 1;\n }\n\n #getBarLengthOverride(): number | null {\n const val = this.#readCssVar(`--plot-histogram-bar-length`);\n if (val === `` || val === `auto`)\n return null;\n const parsed = Number.parseFloat(val);\n return Number.isFinite(parsed) ? Math.max(0, Math.min(1, parsed)) : null;\n }\n\n #emitClick(i: number, valueMin: number, valueMax: number, relativeValue: number): void {\n this.dispatchEvent(\n new CustomEvent<PlotHistogramBucketClickDetail>(`plot-bucket-click`, {\n detail: { bucketIndex: i, valueMin, valueMax, relativeValue },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n override render() {\n const { values, range } = this.#series;\n const w = this._width;\n const h = this._height;\n const isHorizontal = this.orientation === `horizontal`;\n const padding = Math.min(4, (isHorizontal ? h : w) * 0.05);\n\n const dataMin = this.min ?? range.min;\n const dataMax = this.max ?? range.max;\n const dataSpan = dataMax - dataMin || 1;\n\n const bucketCount = Math.max(1, Math.floor(1 / this.resolution));\n\n const availableMain = (isHorizontal ? w : h) - padding * 2;\n const availableCross = (isHorizontal ? h : w) - padding * 2;\n\n const bucketSize = availableMain / bucketCount;\n const gap = this.#getGapPx();\n const barLengthOverride = this.#getBarLengthOverride();\n\n const buckets = Array.from<any>({ length: bucketCount }).fill(0);\n for (const v of values) {\n const normalized = (v - dataMin) / dataSpan;\n const index = Math.min(bucketCount - 1, Math.max(0, Math.floor(normalized * bucketCount)));\n buckets[index]++;\n }\n const maxCount = Math.max(1, ...buckets);\n\n const bars = buckets.map((count, i) => {\n const relativeValue = count / maxCount;\n const barLen = barLengthOverride !== null\n ? barLengthOverride * availableCross\n : relativeValue * availableCross;\n\n const valueMin = dataMin + (i / bucketCount) * dataSpan;\n const valueMax = dataMin + ((i + 1) / bucketCount) * dataSpan;\n\n if (isHorizontal) {\n const x = padding + i * bucketSize;\n const bw = i === bucketCount - 1\n ? Math.max(0, padding + availableMain - x)\n : Math.max(0, bucketSize - gap);\n const y = padding + availableCross - barLen;\n return svg`\n <rect class=\"bar\" x=${x} y=${y} width=${bw} height=${barLen}\n style=\"--value: ${relativeValue}\"\n @click=${() => this.#emitClick(i, valueMin, valueMax, relativeValue)} />\n `;\n } else {\n const y = padding + i * bucketSize;\n const bh = i === bucketCount - 1\n ? Math.max(0, padding + availableMain - y)\n : Math.max(0, bucketSize - gap);\n return svg`\n <rect class=\"bar\" x=${padding} y=${y} width=${barLen} height=${bh}\n style=\"--value: ${relativeValue}\"\n @click=${() => this.#emitClick(i, valueMin, valueMax, relativeValue)} />\n `;\n }\n });\n\n const textColor = `var(--plot-text, var(--surface-2-text, #fff))`;\n const titleContent = this.title\n ? svg`<text x=${padding + 2} y=${padding + Math.min(10, h * 0.6)}\n class=\"overlay-text\" fill=${textColor}\n style=\"opacity: 0.6\">${this.title}</text>`\n : svg``;\n\n return html`\n <svg width=${w} height=${h} viewBox=\"0 0 ${w} ${h}\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=${w} height=${h} fill=\"transparent\" />\n ${bars}\n ${titleContent}\n </svg>\n `;\n }\n\n static override styles = css`\n :host {\n display: inline-block;\n width: 100%;\n height: 100%;\n min-width: 20px;\n min-height: 20px;\n\n --plot-histogram-fill: currentColor;\n --plot-histogram-gap: 1px;\n --plot-histogram-border-radius: 0;\n --plot-histogram-bar-length: auto;\n }\n\n svg {\n display: block;\n cursor: crosshair;\n overflow: visible;\n }\n\n rect.bar {\n fill: var(--plot-histogram-fill, currentColor);\n rx: var(--plot-histogram-border-radius, 0);\n opacity: calc(0.15 + var(--value) * 0.85);\n }\n\n .overlay-text {\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: 9px;\n dominant-baseline: hanging;\n pointer-events: none;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-plot-histogram': PlotHistogram;\n }\n}\n\nexport interface PlotHistogram {\n addEventListener: (<K extends keyof PlotHistogramElementEventMap>(\n type: K,\n listener: (this: PlotHistogram, event: PlotHistogramElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","import type { PropertyValues, SVGTemplateResult } from 'lit';\nimport type { ColourMode, ColourResult } from './colour-map.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { applyAgeModification, computeColour, parseColourScaleAttr, readBaseColour } from './colour-map.js';\nimport { PlotDataSeries } from './data.js';\nimport { adaptiveRadius, adaptiveStroke, hideTooltip, scaleValue, showTooltip } from './svg-utils.js';\n\nexport type SingleAxisDrawStyle\n = | `line-sharp`\n | `line-round`\n | `circles`\n | `squares`\n | `vbar`\n | `hbar`\n | `hist-bottom`\n | `hist-top`\n | `hist-middle`;\n\nexport type SingleAxisAgeStyle = `none` | `opacity` | `desaturation` | `size`;\n\ntype PlotPoint = { x: number; y: number; value: number; scaledValue: number; index: number; ageFraction: number };\n\n// --- Pure SVG fragment renderers ---\n// Lines use a single ColourResult (the last / most-recent point's colour).\n// Per-point styles use a ColourResult[] aligned with the points array.\n\nfunction buildLinePath(points: PlotPoint[]): string {\n if (points.length === 0)\n return ``;\n let d = `M ${points[0].x},${points[0].y}`;\n for (let i = 1; i < points.length; i++) {\n d += ` L ${points[i].x},${points[i].y}`;\n }\n return d;\n}\n\nfunction renderLine(points: PlotPoint[], cr: ColourResult, strokeW: number, round: boolean) {\n return svg`<path\n d=${buildLinePath(points)}\n fill=\"none\"\n stroke=${cr.fill}\n stroke-width=${strokeW}\n opacity=${cr.opacity}\n stroke-linecap=${round ? `round` : `butt`}\n stroke-linejoin=${round ? `round` : `miter`}\n />`;\n}\n\nfunction renderArea(points: PlotPoint[], cr: ColourResult, bottom: number, areaColor?: string): SVGTemplateResult {\n if (points.length < 2)\n return svg``;\n const lineD = buildLinePath(points);\n const fillColor = areaColor || cr.fill;\n const areaD = `${lineD} L ${points[points.length - 1].x},${bottom} L ${points[0].x},${bottom} Z`;\n return svg`<path d=${areaD} fill=${fillColor} opacity=${cr.opacity * 0.2} />`;\n}\n\nfunction renderCircles(points: PlotPoint[], crs: ColourResult[], radius: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const r = ageStyle === `size` ? radius * Math.max(0.2, p.ageFraction) : radius;\n return svg`<circle cx=${p.x} cy=${p.y} r=${r} fill=${crs[i].fill} opacity=${crs[i].opacity} />`;\n });\n}\n\nfunction renderSquares(points: PlotPoint[], crs: ColourResult[], size: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const s = ageStyle === `size` ? size * Math.max(0.2, p.ageFraction) : size;\n return svg`<rect\n x=${p.x - s / 2} y=${p.y - s / 2}\n width=${s} height=${s}\n fill=${crs[i].fill} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderVbars(points: PlotPoint[], crs: ColourResult[], strokeW: number, bottom: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const sw = ageStyle === `size` ? strokeW * Math.max(0.2, p.ageFraction) : strokeW;\n return svg`<line\n x1=${p.x} y1=${bottom} x2=${p.x} y2=${p.y}\n stroke=${crs[i].fill} stroke-width=${sw} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderHbars(points: PlotPoint[], crs: ColourResult[], strokeW: number, tickLen: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const tl = ageStyle === `size` ? tickLen * Math.max(0.2, p.ageFraction) : tickLen;\n return svg`<line\n x1=${p.x - tl / 2} y1=${p.y} x2=${p.x + tl / 2} y2=${p.y}\n stroke=${crs[i].fill} stroke-width=${strokeW} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderHistBottom(points: PlotPoint[], crs: ColourResult[], barW: number, bottom: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const w = ageStyle === `size` ? barW * Math.max(0.2, p.ageFraction) : barW;\n return svg`<rect\n x=${p.x - w / 2} y=${p.y}\n width=${w} height=${Math.max(1, bottom - p.y)}\n fill=${crs[i].fill} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderHistTop(points: PlotPoint[], crs: ColourResult[], barW: number, top: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const w = ageStyle === `size` ? barW * Math.max(0.2, p.ageFraction) : barW;\n return svg`<rect\n x=${p.x - w / 2} y=${top}\n width=${w} height=${Math.max(1, p.y - top)}\n fill=${crs[i].fill} opacity=${crs[i].opacity}\n />`;\n });\n}\n\nfunction renderHistMiddle(points: PlotPoint[], crs: ColourResult[], barW: number, mid: number, ageStyle: SingleAxisAgeStyle) {\n return points.map((p, i) => {\n const w = ageStyle === `size` ? barW * Math.max(0.2, p.ageFraction) : barW;\n return svg`<rect\n x=${p.x - w / 2} y=${Math.min(p.y, mid)}\n width=${w} height=${Math.max(1, Math.abs(p.y - mid))}\n fill=${crs[i].fill} opacity=${crs[i].opacity}\n />`;\n });\n}\n\n// --- Component ---\n\n/**\n * PlotSingleAxis\n *\n * Adding data:\n * - add(value: number): adds a single value to the end of the data series.\n * - set(values: number[]): replaces the entire data series at once.\n */\n@customElement(`ixfx-plot-single-axis`)\n// eslint-disable-next-line ts/no-unsafe-declaration-merging\nexport class PlotSingleAxis extends LitElement {\n @property({ attribute: `draw-style` })\n drawStyle: SingleAxisDrawStyle = `line-sharp`;\n\n @property({ attribute: `age-style` })\n ageStyle: SingleAxisAgeStyle = `none`;\n\n @property() title = ``;\n\n @property({ type: Boolean }) precise = false;\n @property({ type: Boolean }) tooltips = true;\n @property({ type: Number }) capacity = 100;\n\n @property({ type: Boolean, attribute: `persistent-scale` })\n persistentScale = true;\n\n @property({ type: Boolean, reflect: true }) paused = false;\n @property({ type: Boolean, attribute: `click-pauses` }) clickPauses = false;\n\n @property({ type: Boolean, attribute: `shaded` })\n shaded = false;\n\n @property({ attribute: `area-color` })\n areaColor = ``;\n\n // --- Colour mapping ---\n @property({ attribute: `color-mode` }) colorMode: ColourMode = `fixed`;\n @property({ attribute: `color-easing` }) colorEasing = ``;\n @property({ attribute: `color-scale` }) colorScale = ``;\n /** Custom value-mapping function (0..1 → 0..1). Ignored when color-easing is set. */\n colorValueMap: ((v: number) => number) | null = null;\n\n @state() private _width = 100;\n @state() private _height = 40;\n\n #series = new PlotDataSeries({ capacityLimit: 100, persistentScaling: true });\n #hasProgrammaticData = false;\n #lastClientX: number | null = null;\n #lastClientY: number | null = null;\n\n #parseDeclarativeData(text: string): number[] {\n if (!text)\n return [];\n const tokens = text.trim().split(/[,\\s;]+/);\n return tokens\n .map(t => Number.parseFloat(t))\n .filter(n => !Number.isNaN(n));\n }\n\n /** Override to customize tooltip label. */\n valueFormat: (v: number | undefined) => string = v => v ? v.toFixed(2) : ``;\n\n /**\n * Get all values in the data series as a readonly array.\n */\n get values(): readonly number[] {\n return this.#series.values;\n }\n\n /**\n * Get length of data series\n */\n get dataCount(): number {\n return this.#series.values.length;\n }\n\n /**\n * Get value at specific index of data series\n * @param index\n */\n getValueAt(index: number): number | undefined {\n return this.#series.values[index];\n }\n\n /**\n * Get value index based on client X position\n * @param clientX\n */\n getIndexFromClientX(clientX: number): number {\n return this.#getIndexFromX(clientX, this.getBoundingClientRect());\n }\n\n /**\n * Adds a value to the data series.\n *\n * Pass `withholdRedraw = true` to prevent automatic redraw after adding the value. In this case, call `redraw()` manually after adding all values to update the plot.\n *\n * Use {@link set} to replace the entire data series at once.\n * @param valueOrValues Single value, or several values\n * @param withholdRedraw If _false_ (default) plot is automatically redrawn\n */\n add(valueOrValues: number | number[], withholdRedraw = false): void {\n this.#hasProgrammaticData = true;\n this.#series.add(valueOrValues);\n if (this.paused)\n return;\n if (withholdRedraw)\n return;\n this.redraw();\n }\n\n /**\n * Redraws the plot.\n * Normally not needed, unless add() is called with withholdRedraw = true, or styleSeries() is used to update series styles.\n */\n redraw() {\n this.requestUpdate();\n this.#updateTooltipAtLastPos();\n }\n\n /**\n * Sets the entire data for a series at once, replacing contents.\n *\n * Use add() to add values one by one.\n *\n * Pass `withholdRedraw = true` to prevent automatic redraw after setting the values. In this case, call `redraw()` manually after setting the values to update the plot.\n * @param values Values\n * @param withholdRedraw If _false_ (default) plot is automatically redrawn\n */\n set(values: number[], withholdRedraw = false): void {\n this.#hasProgrammaticData = true;\n this.#series.set(values);\n if (this.paused)\n return;\n if (withholdRedraw)\n return;\n this.redraw();\n }\n\n /**\n * Clears all data and redraws\n */\n clear(): boolean {\n const result = this.#series.clear();\n this.requestUpdate();\n return result;\n }\n\n protected override firstUpdated(_changed: PropertyValues): void {\n this._width = this.clientWidth || 100;\n this._height = this.clientHeight || 40;\n const ro = new ResizeObserver((entries) => {\n const e = entries[0];\n this._width = e.contentRect.width;\n this._height = e.contentRect.height;\n });\n ro.observe(this);\n\n if (!this.#hasProgrammaticData) {\n const data = this.#parseDeclarativeData(this.textContent ?? ``);\n if (data.length > 0) {\n this.#series.set(data);\n }\n }\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(`capacity`) || changed.has(`persistentScale`)) {\n const old = [...this.#series.values];\n this.#series = new PlotDataSeries({\n capacityLimit: this.capacity,\n persistentScaling: this.persistentScale,\n });\n if (old.length > 0)\n this.#series.set(old);\n }\n }\n\n #getIndexFromX(clientX: number, rect: DOMRect): number {\n const n = this.#series.values.length;\n if (n === 0)\n return -1;\n const x = clientX - rect.left;\n if (x < 0 || x > rect.width)\n return -1;\n const padding = rect.height < 20 ? 0 : Math.min(4, rect.height * 0.05);\n const plotW = rect.width - padding * 2;\n const index = Math.floor((x - padding) / (plotW / n));\n return index >= 0 && index < n ? index : -1;\n }\n\n #updateTooltip(clientX: number, clientY: number): void {\n if (!this.tooltips)\n return;\n const rect = this.getBoundingClientRect();\n const index = this.#getIndexFromX(clientX, rect);\n if (index < 0) {\n hideTooltip(this); return;\n }\n showTooltip(this, clientX, clientY, this.valueFormat(this.#series.values[index]));\n }\n\n #updateTooltipAtLastPos(): void {\n if (this.#lastClientX === null || this.#lastClientY === null)\n return;\n this.#updateTooltip(this.#lastClientX, this.#lastClientY);\n }\n\n #onPointerMove = (e: PointerEvent): void => {\n this.#lastClientX = e.clientX;\n this.#lastClientY = e.clientY;\n this.#updateTooltip(e.clientX, e.clientY);\n const index = this.#getIndexFromX(e.clientX, this.getBoundingClientRect());\n this.dispatchEvent(new CustomEvent(`plot-pointer-move`, {\n detail: { clientX: e.clientX, clientY: e.clientY, index },\n bubbles: true,\n composed: true,\n }));\n };\n\n #onPointerLeave = (): void => {\n this.#lastClientX = null;\n this.#lastClientY = null;\n hideTooltip(this);\n this.dispatchEvent(new CustomEvent(`plot-pointer-leave`, {\n bubbles: true,\n composed: true,\n }));\n };\n\n #onClick = (e: MouseEvent): void => {\n if (this.clickPauses)\n this.paused = !this.paused;\n const index = this.#getIndexFromX(e.clientX, this.getBoundingClientRect());\n if (index < 0)\n return;\n this.dispatchEvent(new CustomEvent(`plot-datapoint-click`, {\n detail: { value: this.#series.values[index], index },\n bubbles: true,\n composed: true,\n }));\n };\n\n #computePoints(values: number[], min: number, max: number, padding: number, plotW: number, plotH: number): PlotPoint[] {\n const n = values.length;\n const widthPerPoint = n > 0 ? plotW / n : plotW;\n const scaleX = (i: number) => padding + (i + 0.5) * widthPerPoint;\n return values.map((value, index) => {\n const sv = scaleValue(value, min, max);\n const ageFraction = n > 1 ? index / (n - 1) : 1;\n return { x: scaleX(index), y: padding + (1 - sv) * plotH, value, scaledValue: sv, index, ageFraction };\n });\n }\n\n #renderByStyle(\n points: PlotPoint[],\n crs: ColourResult[],\n strokeW: number,\n radius: number,\n barW: number,\n bottom: number,\n top: number,\n mid: number,\n ): SVGTemplateResult[] {\n const lineCr = crs.at(-1) ?? { fill: `currentColor`, opacity: 1 };\n const isLine = this.drawStyle === `line-sharp` || this.drawStyle === `line-round`;\n const needsArea = isLine && this.shaded;\n const areaColor = this.areaColor || undefined;\n\n if (needsArea) {\n const area = renderArea(points, lineCr, bottom, areaColor);\n const line = this.drawStyle === `line-sharp`\n ? renderLine(points, lineCr, strokeW, false)\n : renderLine(points, lineCr, strokeW, true);\n return [area, line];\n }\n\n switch (this.drawStyle) {\n case `line-sharp`: return [renderLine(points, lineCr, strokeW, false)];\n case `line-round`: return [renderLine(points, lineCr, strokeW, true)];\n case `circles`: return renderCircles(points, crs, radius, this.ageStyle);\n case `squares`: return renderSquares(points, crs, radius * 2, this.ageStyle);\n case `vbar`: return renderVbars(points, crs, strokeW, bottom, this.ageStyle);\n case `hbar`: return renderHbars(points, crs, strokeW, barW, this.ageStyle);\n case `hist-bottom`: return renderHistBottom(points, crs, barW, bottom, this.ageStyle);\n case `hist-top`: return renderHistTop(points, crs, barW, top, this.ageStyle);\n case `hist-middle`: return renderHistMiddle(points, crs, barW, mid, this.ageStyle);\n default: return [];\n }\n }\n\n override render() {\n const { values, range } = this.#series;\n const w = this._width;\n const h = this._height;\n const padding = h < 20 ? 0 : Math.min(4, h * 0.05);\n const plotW = Math.max(1, w - padding * 2);\n const plotH = Math.max(1, h - padding * 2);\n const bottom = padding + plotH;\n const top = padding;\n const mid = padding + plotH / 2;\n\n const strokeW = adaptiveStroke(w, h);\n const radius = adaptiveRadius(w, h, values.length);\n const barW = values.length > 0\n ? Math.max(1, (plotW / values.length) * 0.85)\n : plotW;\n\n const textColor = `var(--plot-text, var(--surface-2-text, #fff))`;\n\n const points = values.length > 0\n ? this.#computePoints(values, range.min, range.max, padding, plotW, plotH)\n : [];\n\n // Colour mapping\n const baseColour = points.length > 0 ? readBaseColour(this) : ``;\n const colourConfig = {\n mode: this.colorMode,\n palette: parseColourScaleAttr(this.colorScale),\n easingName: this.colorEasing,\n valueMap: this.colorValueMap,\n };\n const isDiscrete = this.drawStyle !== `line-sharp` && this.drawStyle !== `line-round`;\n const crs: ColourResult[] = points.map((p) => {\n const base = computeColour(p.scaledValue, baseColour, colourConfig);\n return isDiscrete ? applyAgeModification(base, p.ageFraction, this.ageStyle) : base;\n });\n\n const dataContent = points.length > 0\n ? this.#renderByStyle(points, crs, strokeW, radius, barW, bottom, top, mid)\n : [];\n\n const titleContent = this.title\n ? svg`<text\n x=${padding + 2} y=${top + Math.min(10, h * 0.6)}\n class=\"overlay-text\"\n fill=${textColor}\n style=\"opacity: 0.6\"\n >${this.title}</text>`\n : svg``;\n\n const latestValue = values.length > 0 ? values.at(-1) : null;\n const preciseContent = this.precise && latestValue !== null\n ? svg`<text\n x=${w - padding - 2} y=${top + Math.min(10, h * 0.6)}\n class=\"overlay-text\"\n text-anchor=\"end\"\n fill=${textColor}\n style=\"opacity: 0.8\"\n >${this.valueFormat(latestValue)}</text>`\n : svg``;\n\n return html`\n <svg\n width=${w} height=${h}\n viewBox=\"0 0 ${w} ${h}\"\n xmlns=\"http://www.w3.org/2000/svg\"\n @pointermove=${this.#onPointerMove}\n @pointerleave=${this.#onPointerLeave}\n @click=${this.#onClick}\n >\n <rect width=${w} height=${h} fill=\"transparent\" />\n ${dataContent.map(c => c)}\n ${titleContent}\n ${preciseContent}\n </svg>\n `;\n }\n\n static override styles = css`\n :host {\n display: inline-block;\n width: 100%;\n height: 100%;\n min-width: 20px;\n min-height: 4px;\n }\n\n svg {\n display: block;\n cursor: crosshair;\n overflow: visible;\n }\n\n .overlay-text {\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: 9px;\n dominant-baseline: hanging;\n pointer-events: none;\n }\n `;\n}\n\nexport type PlotSingleAxisPointerMoveDetail = {\n readonly clientX: number;\n readonly clientY: number;\n readonly index: number;\n};\n\nexport type PlotSingleAxisPointerMoveEvent = CustomEvent<PlotSingleAxisPointerMoveDetail>;\n\nexport interface PlotSingleAxisElementEventMap {\n 'plot-pointer-move': PlotSingleAxisPointerMoveEvent;\n 'plot-pointer-leave': Event;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-plot-single-axis': PlotSingleAxis;\n }\n}\n\n// eslint-disable-next-line ts/no-unsafe-declaration-merging\nexport interface PlotSingleAxis {\n addEventListener: {\n <K extends keyof PlotSingleAxisElementEventMap>(\n type: K,\n listener: (this: PlotSingleAxis, event: PlotSingleAxisElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n (\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n };\n}\n","import type { PropertyValues } from 'lit';\nimport type { ColourMode, ColourResult } from './colour-map.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { applyAgeModification, computeColour, parseColourScaleAttr, readBaseColour } from './colour-map.js';\nimport { PlotDataSeries } from './data.js';\nimport { adaptiveRadius, hideTooltip, scaleValue, showTooltip } from './svg-utils.js';\n\nexport type XyDrawStyle = `circles` | `squares`;\nexport type XyAgeStyle = `none` | `opacity` | `desaturation` | `size`;\n\ntype XyPoint = { x: number; y: number; xVal: number; yVal: number; index: number; ageFraction: number };\n\n// --- Component ---\n\n@customElement(`ixfx-plot-xy-axis`)\nexport class PlotXyAxis extends LitElement {\n @property({ attribute: `draw-style` })\n drawStyle: XyDrawStyle = `circles`;\n\n @property({ attribute: `age-style` })\n ageStyle: XyAgeStyle = `none`;\n\n @property() title = ``;\n @property({ type: Boolean }) precise = false;\n @property({ type: Boolean }) tooltips = true;\n @property({ type: Number }) capacity = 100;\n\n @property({ type: Boolean, attribute: `persistent-scale` })\n persistentScale = true;\n\n @property({ type: Boolean, reflect: true }) paused = false;\n @property({ type: Boolean, attribute: `click-pauses` }) clickPauses = false;\n\n // --- Colour mapping ---\n @property({ attribute: `color-mode` }) colorMode: ColourMode = `fixed`;\n @property({ attribute: `color-easing` }) colorEasing = ``;\n @property({ attribute: `color-scale` }) colorScale = ``;\n /**\n * Custom value-mapping fn (0..1 → 0..1). For xy-axis the input is the point's ageFraction\n * (0 = oldest, 1 = newest). Ignored when color-easing is set.\n */\n colorValueMap: ((v: number) => number) | null = null;\n\n @state() private _width = 100;\n @state() private _height = 100;\n\n #xSeries = new PlotDataSeries({ capacityLimit: 100, persistentScaling: true });\n #ySeries = new PlotDataSeries({ capacityLimit: 100, persistentScaling: true });\n\n /** Override to customize tooltip label. */\n valueFormat: (x: number, y: number) => string = (x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`;\n\n add(x: number, y: number): void {\n this.#xSeries.add(x);\n this.#ySeries.add(y);\n if (this.paused)\n return;\n this.requestUpdate();\n this.#updateTooltipAtLastPos();\n }\n\n setXY(xs: number[], ys: number[]): void {\n this.#xSeries.set(xs);\n this.#ySeries.set(ys);\n if (this.paused)\n return;\n this.requestUpdate();\n this.#updateTooltipAtLastPos();\n }\n\n clear(): void {\n this.#xSeries.clear();\n this.#ySeries.clear();\n this.requestUpdate();\n }\n\n protected override firstUpdated(_changed: PropertyValues): void {\n this._width = this.clientWidth || 100;\n this._height = this.clientHeight || 100;\n const ro = new ResizeObserver((entries) => {\n const e = entries[0];\n this._width = e.contentRect.width;\n this._height = e.contentRect.height;\n });\n ro.observe(this);\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(`capacity`) || changed.has(`persistentScale`)) {\n const opts = { capacityLimit: this.capacity, persistentScaling: this.persistentScale };\n const oldX = [...this.#xSeries.values];\n const oldY = [...this.#ySeries.values];\n this.#xSeries = new PlotDataSeries(opts);\n this.#ySeries = new PlotDataSeries(opts);\n if (oldX.length > 0) {\n this.#xSeries.set(oldX); this.#ySeries.set(oldY);\n }\n }\n }\n\n #computePoints(padding: number, plotW: number, plotH: number): XyPoint[] {\n const xs = this.#xSeries.values;\n const ys = this.#ySeries.values;\n const n = Math.min(xs.length, ys.length);\n if (n === 0)\n return [];\n\n const { min: xMin, max: xMax } = this.#xSeries.range;\n const { min: yMin, max: yMax } = this.#ySeries.range;\n\n return Array.from({ length: n }, (_, i) => ({\n x: padding + scaleValue(xs[i], xMin, xMax) * plotW,\n y: padding + (1 - scaleValue(ys[i], yMin, yMax)) * plotH,\n xVal: xs[i],\n yVal: ys[i],\n index: i,\n ageFraction: n > 1 ? i / (n - 1) : 1,\n }));\n }\n\n /** Compute the final ColourResult for each xy point: base colour → age modification. */\n #computeColours(points: XyPoint[], baseColour: string): ColourResult[] {\n const config = {\n mode: this.colorMode,\n palette: parseColourScaleAttr(this.colorScale),\n easingName: this.colorEasing,\n valueMap: this.colorValueMap,\n };\n return points.map((p) => {\n const base = computeColour(p.ageFraction, baseColour, config);\n return applyAgeModification(base, p.ageFraction, this.ageStyle);\n });\n }\n\n #findNearestPoint(clientX: number, clientY: number, points: XyPoint[], rect: DOMRect): XyPoint | null {\n const x = clientX - rect.left;\n const y = clientY - rect.top;\n let best: XyPoint | null = null;\n let bestDist = Infinity;\n for (const p of points) {\n const dx = p.x - x;\n const dy = p.y - y;\n const d = dx * dx + dy * dy;\n if (d < bestDist) {\n bestDist = d; best = p;\n }\n }\n return best && Math.sqrt(bestDist) < 30 ? best : null;\n }\n\n #lastPoints: XyPoint[] = [];\n #lastClientX: number | null = null;\n #lastClientY: number | null = null;\n\n #updateTooltip(clientX: number, clientY: number): void {\n if (!this.tooltips)\n return;\n const rect = this.getBoundingClientRect();\n const nearest = this.#findNearestPoint(clientX, clientY, this.#lastPoints, rect);\n if (!nearest) {\n hideTooltip(this); return;\n }\n showTooltip(this, clientX, clientY, this.valueFormat(nearest.xVal, nearest.yVal));\n }\n\n #updateTooltipAtLastPos(): void {\n if (this.#lastClientX === null || this.#lastClientY === null)\n return;\n this.#updateTooltip(this.#lastClientX, this.#lastClientY);\n }\n\n #onPointerMove = (e: PointerEvent): void => {\n this.#lastClientX = e.clientX;\n this.#lastClientY = e.clientY;\n this.#updateTooltip(e.clientX, e.clientY);\n };\n\n #onPointerLeave = (): void => {\n this.#lastClientX = null;\n this.#lastClientY = null;\n hideTooltip(this);\n };\n\n #onClick = (e: MouseEvent): void => {\n if (this.clickPauses)\n this.paused = !this.paused;\n const rect = (e.currentTarget as SVGElement).getBoundingClientRect();\n const nearest = this.#findNearestPoint(e.clientX, e.clientY, this.#lastPoints, rect);\n if (!nearest)\n return;\n this.dispatchEvent(new CustomEvent(`plot-datapoint-click`, {\n detail: { x: nearest.xVal, y: nearest.yVal, index: nearest.index },\n bubbles: true,\n composed: true,\n }));\n };\n\n override render() {\n const w = this._width;\n const h = this._height;\n const padding = Math.min(6, Math.min(w, h) * 0.06);\n const plotW = Math.max(1, w - padding * 2);\n const plotH = Math.max(1, h - padding * 2);\n\n const points = this.#computePoints(padding, plotW, plotH);\n this.#lastPoints = points;\n\n const baseColour = points.length > 0 ? readBaseColour(this) : ``;\n const colours = this.#computeColours(points, baseColour);\n\n const radius = adaptiveRadius(w, h, points.length);\n const textColor = `var(--plot-text, var(--surface-2-text, #fff))`;\n\n const dataContent = points.map((p, i) => {\n const cr = colours[i];\n const sizeFactor = this.ageStyle === `size` ? Math.max(0.2, p.ageFraction) : 1;\n if (this.drawStyle === `circles`) {\n const r = radius * sizeFactor;\n return svg`<circle cx=${p.x} cy=${p.y} r=${r} fill=${cr.fill} opacity=${cr.opacity} />`;\n }\n const s = radius * 2 * sizeFactor;\n return svg`<rect x=${p.x - s / 2} y=${p.y - s / 2} width=${s} height=${s} fill=${cr.fill} opacity=${cr.opacity} />`;\n });\n\n const titleContent = this.title\n ? svg`<text\n x=${padding + 2} y=${padding + 2}\n class=\"overlay-text\"\n fill=${textColor}\n style=\"opacity: 0.6\"\n >${this.title}</text>`\n : svg``;\n\n const n = Math.min(this.#xSeries.values.length, this.#ySeries.values.length);\n const latestX = n > 0 ? this.#xSeries.values[n - 1] : null;\n const latestY = n > 0 ? this.#ySeries.values[n - 1] : null;\n const preciseContent = this.precise && latestX !== null && latestY !== null\n ? svg`<text\n x=${w - padding - 2} y=${padding + 2}\n class=\"overlay-text\"\n text-anchor=\"end\"\n fill=${textColor}\n style=\"opacity: 0.8\"\n >${this.valueFormat(latestX, latestY)}</text>`\n : svg``;\n\n return html`\n <svg\n width=${w} height=${h}\n viewBox=\"0 0 ${w} ${h}\"\n xmlns=\"http://www.w3.org/2000/svg\"\n @pointermove=${this.#onPointerMove}\n @pointerleave=${this.#onPointerLeave}\n @click=${this.#onClick}\n >\n <rect width=${w} height=${h} fill=\"transparent\" />\n ${dataContent}\n ${titleContent}\n ${preciseContent}\n </svg>\n `;\n }\n\n static override styles = css`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n min-width: 40px;\n min-height: 40px;\n }\n\n svg {\n display: block;\n cursor: crosshair;\n }\n\n .overlay-text {\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: 9px;\n dominant-baseline: hanging;\n pointer-events: none;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-plot-xy-axis': PlotXyAxis;\n }\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"mappings":"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"}
|