{"version":3,"file":"interval-Dm35Xhy4.mjs","names":["isInterval","equals","aligned","make","makeOpenStart","makeOpenEnd","makeOpen","fromSize","fromMinMax","size","contains","containsApprox","containsInterval","union","filter","clamp","toStartOpen","toStartClosed","toEndOpen","toEndClosed","toClosed","toOpen","isClosed","isOpen","isOpenStart","isOpenEnd","isOpenAtStart","isOpenAtEnd","isClosedAtStart","isClosedAtEnd","unit","unitOpen","biunit","lerp","toLerpFn","normalize","toNormalizeFn","remap","toRemapFn","scaleShift","internal.isInterval","internal.equals","internal.aligned","internal.make","internal.makeOpenStart","internal.makeOpenEnd","internal.makeOpen","internal.fromSize","internal.fromMinMax","internal.size","internal.contains","internal.containsApprox","internal.containsInterval","internal.union","internal.filter","internal.clamp","internal.toStartOpen","internal.toStartClosed","internal.toEndOpen","internal.toEndClosed","internal.toClosed","internal.toOpen","internal.isClosed","internal.isOpen","internal.isOpenStart","internal.isOpenEnd","internal.isOpenAtStart","internal.isOpenAtEnd","internal.isClosedAtStart","internal.isClosedAtEnd","internal.unit","internal.unitOpen","internal.biunit","internal.lerp","internal.toLerpFn","internal.normalize","internal.toNormalizeFn","internal.remap","internal.toRemapFn","internal.scaleShift"],"sources":["../../src/interval/interval.internal.ts","../../src/interval/interval.ts"],"sourcesContent":["import type { Bounds, Closed, Interval, Open, OpenEnd, OpenStart } from './interval.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { EPSILON, epsEquals } from '../number.ts'\n\nconst TypeId: unique symbol = Symbol.for('curvy/interval')\ntype TypeId = typeof TypeId\n\nabstract class IntervalImpl extends Pipeable {\n  readonly [TypeId]: TypeId = TypeId\n\n  abstract readonly kind: 'closed' | 'open-start' | 'open-end' | 'open'\n\n  readonly start: number\n  readonly end: number\n\n  constructor(start: number, end: number) {\n    super()\n\n    if (end < start) {\n      throw new Error('Interval end must be greater than or equal to start')\n    }\n\n    this.start = start\n    this.end = end\n  }\n\n  get [Symbol.toStringTag]() {\n    const open = this.kind === 'open-start' || this.kind === 'open' ? '(' : '['\n    const close = this.kind === 'open-end' || this.kind === 'open' ? ')' : ']'\n    return `Interval ${open}${this.start}, ${this.end}${close}`\n  }\n\n  get [Symbol.for('nodejs.util.inspect.custom')]() {\n    return this[Symbol.toStringTag]\n  }\n}\n\nclass ClosedImpl extends IntervalImpl implements Closed {\n  readonly kind = 'closed' as const\n}\n\nclass OpenStartImpl extends IntervalImpl implements OpenStart {\n  readonly kind = 'open-start' as const\n}\n\nclass OpenEndImpl extends IntervalImpl implements OpenEnd {\n  readonly kind = 'open-end' as const\n}\n\nclass OpenImpl extends IntervalImpl implements Open {\n  readonly kind = 'open' as const\n}\n\n/** @internal */\nexport const isInterval = (v: unknown): v is Interval =>\n  typeof v === 'object' && v !== null && TypeId in v\n\n/** @internal */\nexport const equals = dual<\n  (b: Interval) => (a: Interval) => boolean,\n  (a: Interval, b: Interval) => boolean\n>(\n  2,\n  (a: Interval, b: Interval) =>\n    a.kind === b.kind && epsEquals(a.start, b.start) && epsEquals(a.end, b.end),\n)\n\n/** @internal */\nexport const aligned = dual<\n  (b: Bounds) => (a: Bounds) => boolean,\n  (a: Bounds, b: Bounds) => boolean\n>(2, (a: Bounds, b: Bounds) => epsEquals(a.start, b.start) && epsEquals(a.end, b.end))\n\n/** @internal */\nexport const make = (start: number, end?: number): Closed => new ClosedImpl(start, end ?? start)\n\n/** @internal */\nexport const makeOpenStart = (start: number, end?: number): OpenStart =>\n  new OpenStartImpl(start, end ?? start)\n\n/** @internal */\nexport const makeOpenEnd = (start: number, end?: number): OpenEnd =>\n  new OpenEndImpl(start, end ?? start)\n\n/** @internal */\nexport const makeOpen = (start: number, end?: number): Open => new OpenImpl(start, end ?? start)\n\n/** @internal */\nexport const fromSize = (a: number, b?: number): Closed => {\n  if (b === undefined) {\n    return new ClosedImpl(0, a)\n  }\n  return new ClosedImpl(a, a + b)\n}\n\n/** @internal */\nexport const fromMinMax = (...values: ReadonlyArray<number>): Closed =>\n  new ClosedImpl(Math.min(...values), Math.max(...values))\n\n/** @internal */\nexport const size = (i: Bounds): number => Math.abs(i.end - i.start)\n\n/** @internal */\nexport const contains = dual<\n  (value: number) => (interval: Interval) => boolean,\n  (interval: Interval, value: number) => boolean\n>(2, (interval: Interval, value: number): boolean => {\n  switch (interval.kind) {\n    case 'closed':\n      return value >= interval.start && value <= interval.end\n    case 'open-start':\n      return value > interval.start && value <= interval.end\n    case 'open-end':\n      return value >= interval.start && value < interval.end\n    case 'open':\n      return value > interval.start && value < interval.end\n  }\n})\n\n// Approximate containment: value is in the interval *or* within eps of either\n// boundary. Endpoint inclusivity is ignored — at the EPSILON scale the\n// open/closed distinction loses meaning, and the use case is float-tolerant\n// containment checks (e.g. \"is this query in the segment's range?\"). Use\n// `contains` if you need kind-strict semantics.\n/** @internal */\nexport const containsApprox = (interval: Interval, value: number, eps = EPSILON): boolean =>\n  value >= interval.start - eps && value <= interval.end + eps\n\nconst includesStart = (i: Interval): boolean => i.kind === 'closed' || i.kind === 'open-end'\nconst includesEnd = (i: Interval): boolean => i.kind === 'closed' || i.kind === 'open-start'\n\n// Whether `outer` is a superset of `inner`. For each endpoint pair (start/start\n// and end/end), the inner endpoint must be inside outer; when the endpoints\n// are numerically equal, the outer must include that boundary or the inner\n// must exclude it. Both shapes (closed-on-closed, open-on-open with matched\n// endpoints, etc.) are handled by this kind-aware comparison.\n/** @internal */\nexport const containsInterval = dual<\n  (inner: Interval) => (outer: Interval) => boolean,\n  (outer: Interval, inner: Interval) => boolean\n>(2, (outer: Interval, inner: Interval): boolean => {\n  const outerStart = includesStart(outer)\n  const innerStart = includesStart(inner)\n  const outerEnd = includesEnd(outer)\n  const innerEnd = includesEnd(inner)\n\n  const startOk =\n    inner.start > outer.start || (inner.start === outer.start && (outerStart || !innerStart))\n  const endOk = inner.end < outer.end || (inner.end === outer.end && (outerEnd || !innerEnd))\n\n  return startOk && endOk\n})\n\n// Smallest interval enclosing both inputs. Each endpoint of the result is the\n// extremum of (a.start, b.start) / (a.end, b.end), and its inclusivity follows\n// whichever input contributed it. When endpoints tie, the result is closed at\n// that point if EITHER input includes it.\n/** @internal */\nexport const union = dual<\n  (b: Interval) => (a: Interval) => Interval,\n  (a: Interval, b: Interval) => Interval\n>(2, (a: Interval, b: Interval): Interval => {\n  let startVal: number\n  let startInc: boolean\n  if (a.start < b.start) {\n    startVal = a.start\n    startInc = includesStart(a)\n  } else if (a.start > b.start) {\n    startVal = b.start\n    startInc = includesStart(b)\n  } else {\n    startVal = a.start\n    startInc = includesStart(a) || includesStart(b)\n  }\n\n  let endVal: number\n  let endInc: boolean\n  if (a.end > b.end) {\n    endVal = a.end\n    endInc = includesEnd(a)\n  } else if (a.end < b.end) {\n    endVal = b.end\n    endInc = includesEnd(b)\n  } else {\n    endVal = a.end\n    endInc = includesEnd(a) || includesEnd(b)\n  }\n\n  if (startInc && endInc) {\n    return make(startVal, endVal)\n  }\n  if (!startInc && endInc) {\n    return makeOpenStart(startVal, endVal)\n  }\n  if (startInc && !endInc) {\n    return makeOpenEnd(startVal, endVal)\n  }\n  return makeOpen(startVal, endVal)\n})\n\n/** @internal */\nexport const filter = dual<\n  <V extends ReadonlyArray<number>>(value: V) => (interval: Interval) => V,\n  <V extends ReadonlyArray<number>>(interval: Interval, value: V) => V\n>(\n  2,\n  <V extends ReadonlyArray<number>>(interval: Interval, value: V): V =>\n    value.filter((v) => contains(interval, v)) as unknown as V,\n)\n\n/** @internal */\nexport const clamp = dual<\n  <V extends number | ReadonlyArray<number>>(value: V) => (interval: Bounds) => V,\n  <V extends number | ReadonlyArray<number>>(interval: Bounds, value: V) => V\n>(2, <V extends number | ReadonlyArray<number>>(interval: Bounds, value: V): V => {\n  if (Array.isArray(value)) {\n    return value.map((v) => clamp(interval, v)) as unknown as V\n  }\n  const v = value as number\n  if (v < interval.start) {\n    return interval.start as V\n  }\n  if (v > interval.end) {\n    return interval.end as V\n  }\n  return v as V\n})\n\n/** @internal */\nexport const toStartOpen = ((i: Interval): OpenStart | Open => {\n  switch (i.kind) {\n    case 'closed':\n      return new OpenStartImpl(i.start, i.end)\n    case 'open-end':\n      return new OpenImpl(i.start, i.end)\n    case 'open-start':\n    case 'open':\n      return i\n  }\n}) as {\n  (i: Closed | OpenStart): OpenStart\n  (i: OpenEnd | Open): Open\n}\n\n/** @internal */\nexport const toStartClosed = ((i: Interval): Closed | OpenEnd => {\n  switch (i.kind) {\n    case 'open-start':\n      return new ClosedImpl(i.start, i.end)\n    case 'open':\n      return new OpenEndImpl(i.start, i.end)\n    case 'closed':\n    case 'open-end':\n      return i\n  }\n}) as {\n  (i: Closed | OpenEnd): Closed\n  (i: OpenStart | Open): OpenEnd\n}\n\n/** @internal */\nexport const toEndOpen = ((i: Interval): OpenEnd | Open => {\n  switch (i.kind) {\n    case 'closed':\n      return new OpenEndImpl(i.start, i.end)\n    case 'open-start':\n      return new OpenImpl(i.start, i.end)\n    case 'open-end':\n    case 'open':\n      return i\n  }\n}) as {\n  (i: Closed | OpenEnd): OpenEnd\n  (i: OpenStart | Open): Open\n}\n\n/** @internal */\nexport const toEndClosed = ((i: Interval): Closed | OpenStart => {\n  switch (i.kind) {\n    case 'open-end':\n      return new ClosedImpl(i.start, i.end)\n    case 'open':\n      return new OpenStartImpl(i.start, i.end)\n    case 'closed':\n    case 'open-start':\n      return i\n  }\n}) as {\n  (i: Closed | OpenEnd): Closed\n  (i: OpenStart | Open): OpenStart\n}\n\n/** @internal */\nexport const toClosed = (i: Interval): Closed => {\n  if (i.kind === 'closed') {\n    return i\n  }\n  return new ClosedImpl(i.start, i.end)\n}\n\n/** @internal */\nexport const toOpen = (i: Interval): Open => {\n  if (i.kind === 'open') {\n    return i\n  }\n  return new OpenImpl(i.start, i.end)\n}\n\n/** @internal */\nexport const isClosed = (i: Interval): i is Closed => i.kind === 'closed'\n/** @internal */\nexport const isOpen = (i: Interval): i is Open => i.kind === 'open'\n/** @internal */\nexport const isOpenStart = (i: Interval): i is OpenStart => i.kind === 'open-start'\n/** @internal */\nexport const isOpenEnd = (i: Interval): i is OpenEnd => i.kind === 'open-end'\n\n/** @internal */\nexport const isOpenAtStart = (i: Interval): i is OpenStart | Open =>\n  i.kind === 'open-start' || i.kind === 'open'\n/** @internal */\nexport const isOpenAtEnd = (i: Interval): i is OpenEnd | Open =>\n  i.kind === 'open-end' || i.kind === 'open'\n/** @internal */\nexport const isClosedAtStart = (i: Interval): i is Closed | OpenEnd =>\n  i.kind === 'closed' || i.kind === 'open-end'\n/** @internal */\nexport const isClosedAtEnd = (i: Interval): i is Closed | OpenStart =>\n  i.kind === 'closed' || i.kind === 'open-start'\n\n/** @internal */\nexport const unit: Closed = make(0, 1)\n\n/** @internal */\nexport const unitOpen: Open = new OpenImpl(0, 1)\n\n/** @internal */\nexport const biunit: Closed = make(-1, 1)\n\n/** @internal */\nexport const lerp = (interval: Bounds, t: number): number =>\n  (1 - t) * interval.start + t * interval.end\n\n/** @internal */\nexport const toLerpFn =\n  (interval: Bounds) =>\n  (t: number): number =>\n    lerp(interval, t)\n\n/** @internal */\nexport const normalize = (interval: Bounds, x: number): number =>\n  (x - interval.start) / size(interval)\n\n/** @internal */\nexport const toNormalizeFn =\n  (interval: Bounds) =>\n  (x: number): number =>\n    normalize(interval, x)\n\n/** @internal */\nexport const remap = (source: Bounds, target: Bounds, x: number): number =>\n  target.start + ((x - source.start) * size(target)) / size(source)\n\n/** @internal */\nexport const toRemapFn =\n  (source: Bounds, target: Bounds) =>\n  (x: number): number =>\n    remap(source, target, x)\n\n/** @internal */\nexport const scaleShift = (source: Bounds, target: Bounds) => {\n  const scale = size(target) / size(source)\n\n  return {\n    scale,\n    shift: target.start - source.start * scale,\n  }\n}\n","import * as internal from './interval.internal.ts'\nimport type { Pipeable } from '../utils.ts'\n\n/**\n * The structural minimum: any value with numeric `start` and `end` fields.\n *\n * Operations that don't read endpoint inclusivity (e.g. `lerp`, `normalize`,\n * `remap`, `size`) accept `Bounds` so the signature itself documents what\n * the operation depends on.\n *\n * @since 2.0.0\n */\nexport interface Bounds {\n  readonly start: number\n  readonly end: number\n}\n\n/**\n * A mathematical interval. Discriminated union of four variants by endpoint\n * inclusivity: `Closed`, `OpenStart`, `OpenEnd`, `Open`. Operations that\n * depend on inclusivity (e.g. `contains`, `filter`, `equals`) dispatch on\n * the `kind` field; operations that don't accept the broader `Bounds` type.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * @since 1.0.0\n */\nexport type Interval = Closed | OpenStart | OpenEnd | Open\n\n/**\n * `[start, end]` — both endpoints included.\n *\n * @since 2.0.0\n */\nexport interface Closed extends Pipeable, Bounds {\n  readonly kind: 'closed'\n}\n\n/**\n * `(start, end]` — start excluded, end included.\n *\n * @since 2.0.0\n */\nexport interface OpenStart extends Pipeable, Bounds {\n  readonly kind: 'open-start'\n}\n\n/**\n * `[start, end)` — start included, end excluded.\n *\n * @since 2.0.0\n */\nexport interface OpenEnd extends Pipeable, Bounds {\n  readonly kind: 'open-end'\n}\n\n/**\n * `(start, end)` — both endpoints excluded.\n *\n * @since 2.0.0\n */\nexport interface Open extends Pipeable, Bounds {\n  readonly kind: 'open'\n}\n\n/**\n * Checks if a value is an `Interval`.\n *\n * @param v - The value to check.\n * @returns `true` if the value is an `Interval`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isInterval: (v: unknown) => v is Interval = internal.isInterval\n\nexport const equals: {\n  /**\n   * Checks if two `Interval` instances are approximately equal within the\n   * default absolute tolerance ({@link EPSILON}).\n   *\n   * Both endpoints AND the kind must match — a `Closed` and an `OpenStart` with\n   * the same numeric endpoints are not equal. Use `aligned` for the looser\n   * \"same numeric range\" check.\n   *\n   * @param a - The first interval.\n   * @param b - The second interval.\n   * @returns `true` when both intervals share a kind and both endpoints are within tolerance.\n   * @since 1.1.0\n   */\n  (a: Interval, b: Interval): boolean\n  /**\n   * Checks if two `Interval` instances are approximately equal within the\n   * default absolute tolerance ({@link EPSILON}).\n   *\n   * @param b - The second interval.\n   * @returns A function that takes the first interval and returns the comparison result.\n   * @since 1.1.0\n   */\n  (b: Interval): (a: Interval) => boolean\n} = internal.equals\n\nexport const aligned: {\n  /**\n   * Checks if two values share the same numeric range, ignoring endpoint\n   * inclusivity. Accepts any `Bounds`-shaped value.\n   *\n   * @param a - The first bounds.\n   * @param b - The second bounds.\n   * @returns `true` when both endpoints are within the default tolerance ({@link EPSILON}).\n   * @since 2.0.0\n   */\n  (a: Bounds, b: Bounds): boolean\n  /**\n   * @param b - The second bounds.\n   * @returns A function that takes the first bounds and returns the comparison result.\n   * @since 2.0.0\n   */\n  (b: Bounds): (a: Bounds) => boolean\n} = internal.aligned\n\nexport const make: {\n  /**\n   * Creates a new closed `Interval` instance.\n   *\n   * @param point - The point of the interval.\n   * @returns A new `Closed` interval `[point, point]`.\n   * @since 1.0.0\n   */\n  (point: number): Closed\n  /**\n   * Creates a new closed `Interval` instance.\n   *\n   * @param start - The start of the interval.\n   * @param end - The end of the interval.\n   * @returns A new `Closed` interval `[start, end]`.\n   * @since 1.0.0\n   */\n  (start: number, end: number): Closed\n} = internal.make\n\nexport const makeOpenStart: {\n  /**\n   * Creates a new left-open `Interval` instance.\n   *\n   * @param point - The point of the interval.\n   * @returns A new `OpenStart` interval `(point, point]` (degenerate, empty).\n   * @since 2.0.0\n   */\n  (point: number): OpenStart\n  /**\n   * Creates a new left-open `Interval` instance.\n   *\n   * @param start - The start of the interval (excluded).\n   * @param end - The end of the interval (included).\n   * @returns A new `OpenStart` interval `(start, end]`.\n   * @since 2.0.0\n   */\n  (start: number, end: number): OpenStart\n} = internal.makeOpenStart\n\nexport const makeOpenEnd: {\n  /**\n   * Creates a new right-open `Interval` instance.\n   *\n   * @param point - The point of the interval.\n   * @returns A new `OpenEnd` interval `[point, point)` (degenerate, empty).\n   * @since 2.0.0\n   */\n  (point: number): OpenEnd\n  /**\n   * Creates a new right-open `Interval` instance.\n   *\n   * @param start - The start of the interval (included).\n   * @param end - The end of the interval (excluded).\n   * @returns A new `OpenEnd` interval `[start, end)`.\n   * @since 2.0.0\n   */\n  (start: number, end: number): OpenEnd\n} = internal.makeOpenEnd\n\nexport const makeOpen: {\n  /**\n   * Creates a new fully open `Interval` instance.\n   *\n   * @param point - The point of the interval.\n   * @returns A new `Open` interval `(point, point)` (degenerate, empty).\n   * @since 2.0.0\n   */\n  (point: number): Open\n  /**\n   * Creates a new fully open `Interval` instance.\n   *\n   * @param start - The start of the interval (excluded).\n   * @param end - The end of the interval (excluded).\n   * @returns A new `Open` interval `(start, end)`.\n   * @since 2.0.0\n   */\n  (start: number, end: number): Open\n} = internal.makeOpen\n\nexport const fromSize: {\n  /**\n   * Creates a new closed `Interval` instance from a size.\n   *\n   * @param size - The size of the interval.\n   * @returns A new `Closed` interval `[0, size]`.\n   * @since 1.0.0\n   */\n  (size: number): Closed\n  /**\n   * Creates a new closed `Interval` instance from a size.\n   *\n   * @param start - The start of the interval.\n   * @param size - The size of the interval.\n   * @returns A new `Closed` interval `[start, start + size]`.\n   * @since 1.0.0\n   */\n  (start: number, size: number): Closed\n} = internal.fromSize\n\n/**\n * Creates a new closed `Interval` from a minimum and maximum value, in any order.\n *\n * @param values - The values to take the min and max of.\n * @returns A new `Closed` interval `[min(values), max(values)]`.\n * @since 1.0.0\n */\nexport const fromMinMax: (...values: ReadonlyArray<number>) => Closed = internal.fromMinMax\n\n/**\n * Calculates the size of an interval.\n *\n * Kind-agnostic — `size` of `[0, 1]` and `(0, 1)` are both `1`.\n *\n * @param i - The bounds to calculate the size of.\n * @returns The size of the bounds.\n * @since 1.0.0\n */\nexport const size: (i: Bounds) => number = internal.size\n\nexport const contains: {\n  /**\n   * Checks if a value is contained within an interval. Endpoint inclusivity\n   * follows the interval's `kind`.\n   *\n   * @param interval - The interval to check.\n   * @param value - The value to check.\n   * @returns `true` if the value is contained within the interval, `false` otherwise.\n   * @since 1.0.0\n   */\n  (interval: Interval, value: number): boolean\n  /**\n   * Checks if a value is contained within an interval. Endpoint inclusivity\n   * follows the interval's `kind`.\n   *\n   * @param value - The value to check.\n   * @returns A function that takes an interval and returns `true` if the value is contained within the interval, `false` otherwise.\n   * @since 1.0.0\n   */\n  (value: number): (interval: Interval) => boolean\n} = internal.contains\n\n/**\n * Float-tolerant containment: returns `true` if `value` is in the interval or\n * within `eps` of either boundary. Endpoint inclusivity is ignored — at the\n * `EPSILON` scale the open/closed distinction loses meaning, and the use case\n * is \"is this query approximately in this range, accounting for float drift?\".\n * Use {@link contains} if you need kind-strict semantics.\n *\n * @param interval - The interval to check against.\n * @param value - The value to check.\n * @param eps - The absolute tolerance. Defaults to {@link EPSILON}.\n * @returns `true` when `interval.start - eps <= value <= interval.end + eps`.\n * @since 2.0.0\n */\nexport const containsApprox: (interval: Interval, value: number, eps?: number) => boolean =\n  internal.containsApprox\n\nexport const containsInterval: {\n  /**\n   * Checks if `inner` is a subset of `outer` — every point of `inner` is also\n   * in `outer`. Respects endpoint inclusivity on both sides: a closed inner\n   * endpoint must be inside (or on a closed boundary of) the outer, while an\n   * open inner endpoint can sit exactly on an open outer boundary.\n   *\n   * @param outer - The enclosing interval.\n   * @param inner - The candidate inner interval.\n   * @returns `true` when `inner` is a subset of `outer`.\n   * @since 2.0.0\n   */\n  (outer: Interval, inner: Interval): boolean\n  /**\n   * @param inner - The candidate inner interval.\n   * @returns A function that takes the outer interval and returns the containment result.\n   * @since 2.0.0\n   */\n  (inner: Interval): (outer: Interval) => boolean\n} = internal.containsInterval\n\nexport const union: {\n  /**\n   * Returns the smallest interval enclosing both inputs. Each endpoint's\n   * inclusivity follows the input that contributed it; when both endpoints\n   * tie, the result is closed at that point if either input includes it.\n   *\n   * @param a - The first interval.\n   * @param b - The second interval.\n   * @returns A new interval enclosing both inputs.\n   * @since 2.0.0\n   */\n  (a: Interval, b: Interval): Interval\n  /**\n   * @param b - The second interval.\n   * @returns A function that takes the first interval and returns the union.\n   * @since 2.0.0\n   */\n  (b: Interval): (a: Interval) => Interval\n} = internal.union\n\nexport const filter: {\n  /**\n   * Filters an array of values to those contained within an interval.\n   * Endpoint inclusivity follows the interval's `kind`.\n   *\n   * @param interval - The interval to filter the values to.\n   * @param value - The values to filter.\n   * @returns The filtered values.\n   * @since 1.0.0\n   */\n  <V extends ReadonlyArray<number>>(interval: Interval, value: V): V\n  /**\n   * Filters an array of values to those contained within an interval.\n   *\n   * @param value - The values to filter.\n   * @returns A function that takes an interval and returns the filtered values.\n   * @since 1.0.0\n   */\n  <V extends ReadonlyArray<number>>(value: V): (interval: Interval) => V\n} = internal.filter\n\nexport const clamp: {\n  /**\n   * Clamps a value to be within bounds. Kind-agnostic — clamps to the numeric\n   * range regardless of endpoint inclusivity.\n   *\n   * @param interval - The bounds to clamp the value to.\n   * @param value - The value to clamp.\n   * @returns The clamped value.\n   * @since 1.0.0\n   */\n  (interval: Bounds, value: number): number\n  /**\n   * Clamps a value to be within bounds. Kind-agnostic.\n   *\n   * @param value - The value to clamp.\n   * @returns A function that takes bounds and returns the clamped value.\n   * @since 1.0.0\n   */\n  (value: number): (interval: Bounds) => number\n  /**\n   * Clamps an array of values to be within bounds. Kind-agnostic.\n   *\n   * @param interval - The bounds to clamp the values to.\n   * @param value - The values to clamp.\n   * @returns The clamped values.\n   * @since 1.0.0\n   */\n  (interval: Bounds, value: ReadonlyArray<number>): ReadonlyArray<number>\n  /**\n   * Clamps an array of values to be within bounds. Kind-agnostic.\n   *\n   * @param value - The values to clamp.\n   * @returns A function that takes bounds and returns the clamped values.\n   * @since 1.0.0\n   */\n  (value: ReadonlyArray<number>): (interval: Bounds) => ReadonlyArray<number>\n} = internal.clamp\n\n/**\n * Returns an interval with the start endpoint open. Preserves the end endpoint's inclusivity.\n *\n * @since 2.0.0\n */\nexport const toStartOpen: {\n  (i: Closed | OpenStart): OpenStart\n  (i: OpenEnd | Open): Open\n} = internal.toStartOpen\n\n/**\n * Returns an interval with the start endpoint closed. Preserves the end endpoint's inclusivity.\n *\n * @since 2.0.0\n */\nexport const toStartClosed: {\n  (i: Closed | OpenEnd): Closed\n  (i: OpenStart | Open): OpenEnd\n} = internal.toStartClosed\n\n/**\n * Returns an interval with the end endpoint open. Preserves the start endpoint's inclusivity.\n *\n * @since 2.0.0\n */\nexport const toEndOpen: {\n  (i: Closed | OpenEnd): OpenEnd\n  (i: OpenStart | Open): Open\n} = internal.toEndOpen\n\n/**\n * Returns an interval with the end endpoint closed. Preserves the start endpoint's inclusivity.\n *\n * @since 2.0.0\n */\nexport const toEndClosed: {\n  (i: Closed | OpenEnd): Closed\n  (i: OpenStart | Open): OpenStart\n} = internal.toEndClosed\n\n/**\n * Returns a closed interval over the same numeric range.\n *\n * @since 2.0.0\n */\nexport const toClosed: (i: Interval) => Closed = internal.toClosed\n\n/**\n * Returns a fully open interval over the same numeric range.\n *\n * @since 2.0.0\n */\nexport const toOpen: (i: Interval) => Open = internal.toOpen\n\n/**\n * Type-narrowing predicate: refines `Interval` to `Closed`.\n *\n * @since 2.0.0\n */\nexport const isClosed: (i: Interval) => i is Closed = internal.isClosed\n\n/**\n * Type-narrowing predicate: refines `Interval` to `Open`.\n *\n * @since 2.0.0\n */\nexport const isOpen: (i: Interval) => i is Open = internal.isOpen\n\n/**\n * Type-narrowing predicate: refines `Interval` to `OpenStart`.\n *\n * @since 2.0.0\n */\nexport const isOpenStart: (i: Interval) => i is OpenStart = internal.isOpenStart\n\n/**\n * Type-narrowing predicate: refines `Interval` to `OpenEnd`.\n *\n * @since 2.0.0\n */\nexport const isOpenEnd: (i: Interval) => i is OpenEnd = internal.isOpenEnd\n\n/**\n * Type-narrowing predicate: refines `Interval` to those with an open start endpoint.\n *\n * @since 2.0.0\n */\nexport const isOpenAtStart: (i: Interval) => i is OpenStart | Open = internal.isOpenAtStart\n\n/**\n * Type-narrowing predicate: refines `Interval` to those with an open end endpoint.\n *\n * @since 2.0.0\n */\nexport const isOpenAtEnd: (i: Interval) => i is OpenEnd | Open = internal.isOpenAtEnd\n\n/**\n * Type-narrowing predicate: refines `Interval` to those with a closed start endpoint.\n *\n * @since 2.0.0\n */\nexport const isClosedAtStart: (i: Interval) => i is Closed | OpenEnd = internal.isClosedAtStart\n\n/**\n * Type-narrowing predicate: refines `Interval` to those with a closed end endpoint.\n *\n * @since 2.0.0\n */\nexport const isClosedAtEnd: (i: Interval) => i is Closed | OpenStart = internal.isClosedAtEnd\n\n/**\n * The unit interval, `[0, 1]`.\n *\n * @since 1.0.0\n */\nexport const unit: Closed = internal.unit\n\n/**\n * The open unit interval, `(0, 1)`. The symmetric open analog of {@link unit};\n * convenient for \"strict interior\" use cases such as filtering roots that\n * must lie strictly inside the unit parameter range.\n *\n * @since 2.0.0\n */\nexport const unitOpen: Open = internal.unitOpen\n\n/**\n * The biunit interval, `[-1, 1]`.\n *\n * @since 1.0.0\n */\nexport const biunit: Closed = internal.biunit\n\n/**\n * Linearly interpolates a value within bounds.\n *\n * @param interval - The bounds to interpolate within.\n * @param t - The interpolation factor, typically between 0 and 1.\n * @returns The interpolated value.\n * @since 1.0.0\n */\nexport const lerp: (interval: Bounds, t: number) => number = internal.lerp\n\n/**\n * Creates a linear interpolation function for given bounds.\n *\n * @param interval - The bounds to create the interpolation function for.\n * @returns A function that takes a factor `t` and returns the interpolated value.\n * @since 1.0.0\n */\nexport const toLerpFn: (interval: Bounds) => (t: number) => number = internal.toLerpFn\n\n/**\n * Normalizes a value within bounds.\n *\n * @param interval - The bounds to normalize within.\n * @param x - The value to normalize.\n * @returns The normalized value.\n * @since 1.0.0\n */\nexport const normalize: (interval: Bounds, x: number) => number = internal.normalize\n\n/**\n * Creates a normalization function for given bounds.\n *\n * @param interval - The bounds to create the normalization function for.\n * @returns A function that takes a value `x` and returns the normalized value.\n * @since 1.0.0\n */\nexport const toNormalizeFn: (interval: Bounds) => (x: number) => number = internal.toNormalizeFn\n\n/**\n * Remaps a value from one bounds to another.\n *\n * @param source - The source bounds.\n * @param target - The target bounds.\n * @param x - The value to remap.\n * @returns The remapped value.\n * @since 1.0.0\n */\nexport const remap: (source: Bounds, target: Bounds, x: number) => number = internal.remap\n\n/**\n * Creates a remapping function for given bounds.\n *\n * @param source - The source bounds.\n * @param target - The target bounds.\n * @returns A function that takes a value `x` and returns the remapped value.\n * @since 1.0.0\n */\nexport const toRemapFn: (source: Bounds, target: Bounds) => (x: number) => number =\n  internal.toRemapFn\n\n/**\n * Calculates the scale and shift needed to map a source bounds to a target bounds.\n *\n * @param source - The source bounds.\n * @param target - The target bounds.\n * @returns An object containing the scale and shift values.\n * @since 1.0.0\n */\nexport const scaleShift: (source: Bounds, target: Bounds) => ScaleShift = internal.scaleShift\n\n/**\n * The scale and shift needed to map a source bounds to a target bounds.\n *\n * @since 1.0.0\n */\nexport interface ScaleShift {\n  readonly scale: number\n  readonly shift: number\n}\n"],"mappings":";;;;AAIA,MAAM,SAAwB,OAAO,IAAI,iBAAiB;AAG1D,IAAe,eAAf,cAAoC,SAAS;CAC3C,CAAU,UAAkB;CAI5B;CACA;CAEA,YAAY,OAAe,KAAa;EACtC,OAAO;EAEP,IAAI,MAAM,OACR,MAAM,IAAI,MAAM,sDAAsD;EAGxE,KAAK,QAAQ;EACb,KAAK,MAAM;;CAGb,KAAK,OAAO,eAAe;EACzB,MAAM,OAAO,KAAK,SAAS,gBAAgB,KAAK,SAAS,SAAS,MAAM;EACxE,MAAM,QAAQ,KAAK,SAAS,cAAc,KAAK,SAAS,SAAS,MAAM;EACvE,OAAO,YAAY,OAAO,KAAK,MAAM,IAAI,KAAK,MAAM;;CAGtD,KAAK,OAAO,IAAI,6BAA6B,IAAI;EAC/C,OAAO,KAAK,OAAO;;;AAIvB,IAAM,aAAN,cAAyB,aAA+B;CACtD,OAAgB;;AAGlB,IAAM,gBAAN,cAA4B,aAAkC;CAC5D,OAAgB;;AAGlB,IAAM,cAAN,cAA0B,aAAgC;CACxD,OAAgB;;AAGlB,IAAM,WAAN,cAAuB,aAA6B;CAClD,OAAgB;;;AAIlB,MAAaA,gBAAc,MACzB,OAAO,MAAM,YAAY,MAAM,QAAQ,UAAU;;AAGnD,MAAaC,WAAS,KAIpB,IACC,GAAa,MACZ,EAAE,SAAS,EAAE,QAAQ,UAAU,EAAE,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,KAAK,EAAE,IAAI,CAC9E;;AAGD,MAAaC,YAAU,KAGrB,IAAI,GAAW,MAAc,UAAU,EAAE,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC;;AAGtF,MAAaC,UAAQ,OAAe,QAAyB,IAAI,WAAW,OAAO,OAAO,MAAM;;AAGhG,MAAaC,mBAAiB,OAAe,QAC3C,IAAI,cAAc,OAAO,OAAO,MAAM;;AAGxC,MAAaC,iBAAe,OAAe,QACzC,IAAI,YAAY,OAAO,OAAO,MAAM;;AAGtC,MAAaC,cAAY,OAAe,QAAuB,IAAI,SAAS,OAAO,OAAO,MAAM;;AAGhG,MAAaC,cAAY,GAAW,MAAuB;CACzD,IAAI,MAAM,KAAA,GACR,OAAO,IAAI,WAAW,GAAG,EAAE;CAE7B,OAAO,IAAI,WAAW,GAAG,IAAI,EAAE;;;AAIjC,MAAaC,gBAAc,GAAG,WAC5B,IAAI,WAAW,KAAK,IAAI,GAAG,OAAO,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC;;AAG1D,MAAaC,UAAQ,MAAsB,KAAK,IAAI,EAAE,MAAM,EAAE,MAAM;;AAGpE,MAAaC,aAAW,KAGtB,IAAI,UAAoB,UAA2B;CACnD,QAAQ,SAAS,MAAjB;EACE,KAAK,UACH,OAAO,SAAS,SAAS,SAAS,SAAS,SAAS;EACtD,KAAK,cACH,OAAO,QAAQ,SAAS,SAAS,SAAS,SAAS;EACrD,KAAK,YACH,OAAO,SAAS,SAAS,SAAS,QAAQ,SAAS;EACrD,KAAK,QACH,OAAO,QAAQ,SAAS,SAAS,QAAQ,SAAS;;EAEtD;;AAQF,MAAaC,oBAAkB,UAAoB,OAAe,MAAM,YACtE,SAAS,SAAS,QAAQ,OAAO,SAAS,SAAS,MAAM;AAE3D,MAAM,iBAAiB,MAAyB,EAAE,SAAS,YAAY,EAAE,SAAS;AAClF,MAAM,eAAe,MAAyB,EAAE,SAAS,YAAY,EAAE,SAAS;;AAQhF,MAAaC,qBAAmB,KAG9B,IAAI,OAAiB,UAA6B;CAClD,MAAM,aAAa,cAAc,MAAM;CACvC,MAAM,aAAa,cAAc,MAAM;CACvC,MAAM,WAAW,YAAY,MAAM;CACnC,MAAM,WAAW,YAAY,MAAM;CAEnC,MAAM,UACJ,MAAM,QAAQ,MAAM,SAAU,MAAM,UAAU,MAAM,UAAU,cAAc,CAAC;CAC/E,MAAM,QAAQ,MAAM,MAAM,MAAM,OAAQ,MAAM,QAAQ,MAAM,QAAQ,YAAY,CAAC;CAEjF,OAAO,WAAW;EAClB;;AAOF,MAAaC,UAAQ,KAGnB,IAAI,GAAa,MAA0B;CAC3C,IAAI;CACJ,IAAI;CACJ,IAAI,EAAE,QAAQ,EAAE,OAAO;EACrB,WAAW,EAAE;EACb,WAAW,cAAc,EAAE;QACtB,IAAI,EAAE,QAAQ,EAAE,OAAO;EAC5B,WAAW,EAAE;EACb,WAAW,cAAc,EAAE;QACtB;EACL,WAAW,EAAE;EACb,WAAW,cAAc,EAAE,IAAI,cAAc,EAAE;;CAGjD,IAAI;CACJ,IAAI;CACJ,IAAI,EAAE,MAAM,EAAE,KAAK;EACjB,SAAS,EAAE;EACX,SAAS,YAAY,EAAE;QAClB,IAAI,EAAE,MAAM,EAAE,KAAK;EACxB,SAAS,EAAE;EACX,SAAS,YAAY,EAAE;QAClB;EACL,SAAS,EAAE;EACX,SAAS,YAAY,EAAE,IAAI,YAAY,EAAE;;CAG3C,IAAI,YAAY,QACd,OAAOV,OAAK,UAAU,OAAO;CAE/B,IAAI,CAAC,YAAY,QACf,OAAOC,gBAAc,UAAU,OAAO;CAExC,IAAI,YAAY,CAAC,QACf,OAAOC,cAAY,UAAU,OAAO;CAEtC,OAAOC,WAAS,UAAU,OAAO;EACjC;;AAGF,MAAaQ,WAAS,KAIpB,IACkC,UAAoB,UACpD,MAAM,QAAQ,MAAMJ,WAAS,UAAU,EAAE,CAAC,CAC7C;;AAGD,MAAaK,UAAQ,KAGnB,IAA8C,UAAkB,UAAgB;CAChF,IAAI,MAAM,QAAQ,MAAM,EACtB,OAAO,MAAM,KAAK,MAAMA,QAAM,UAAU,EAAE,CAAC;CAE7C,MAAM,IAAI;CACV,IAAI,IAAI,SAAS,OACf,OAAO,SAAS;CAElB,IAAI,IAAI,SAAS,KACf,OAAO,SAAS;CAElB,OAAO;EACP;;AAGF,MAAaC,kBAAgB,MAAkC;CAC7D,QAAQ,EAAE,MAAV;EACE,KAAK,UACH,OAAO,IAAI,cAAc,EAAE,OAAO,EAAE,IAAI;EAC1C,KAAK,YACH,OAAO,IAAI,SAAS,EAAE,OAAO,EAAE,IAAI;EACrC,KAAK;EACL,KAAK,QACH,OAAO;;;;AAQb,MAAaC,oBAAkB,MAAkC;CAC/D,QAAQ,EAAE,MAAV;EACE,KAAK,cACH,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,IAAI;EACvC,KAAK,QACH,OAAO,IAAI,YAAY,EAAE,OAAO,EAAE,IAAI;EACxC,KAAK;EACL,KAAK,YACH,OAAO;;;;AAQb,MAAaC,gBAAc,MAAgC;CACzD,QAAQ,EAAE,MAAV;EACE,KAAK,UACH,OAAO,IAAI,YAAY,EAAE,OAAO,EAAE,IAAI;EACxC,KAAK,cACH,OAAO,IAAI,SAAS,EAAE,OAAO,EAAE,IAAI;EACrC,KAAK;EACL,KAAK,QACH,OAAO;;;;AAQb,MAAaC,kBAAgB,MAAoC;CAC/D,QAAQ,EAAE,MAAV;EACE,KAAK,YACH,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,IAAI;EACvC,KAAK,QACH,OAAO,IAAI,cAAc,EAAE,OAAO,EAAE,IAAI;EAC1C,KAAK;EACL,KAAK,cACH,OAAO;;;;AAQb,MAAaC,cAAY,MAAwB;CAC/C,IAAI,EAAE,SAAS,UACb,OAAO;CAET,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,IAAI;;;AAIvC,MAAaC,YAAU,MAAsB;CAC3C,IAAI,EAAE,SAAS,QACb,OAAO;CAET,OAAO,IAAI,SAAS,EAAE,OAAO,EAAE,IAAI;;;AAIrC,MAAaC,cAAY,MAA6B,EAAE,SAAS;;AAEjE,MAAaC,YAAU,MAA2B,EAAE,SAAS;;AAE7D,MAAaC,iBAAe,MAAgC,EAAE,SAAS;;AAEvE,MAAaC,eAAa,MAA8B,EAAE,SAAS;;AAGnE,MAAaC,mBAAiB,MAC5B,EAAE,SAAS,gBAAgB,EAAE,SAAS;;AAExC,MAAaC,iBAAe,MAC1B,EAAE,SAAS,cAAc,EAAE,SAAS;;AAEtC,MAAaC,qBAAmB,MAC9B,EAAE,SAAS,YAAY,EAAE,SAAS;;AAEpC,MAAaC,mBAAiB,MAC5B,EAAE,SAAS,YAAY,EAAE,SAAS;;AAGpC,MAAaC,SAAe3B,OAAK,GAAG,EAAE;;AAGtC,MAAa4B,aAAiB,IAAI,SAAS,GAAG,EAAE;;AAGhD,MAAaC,WAAiB7B,OAAK,IAAI,EAAE;;AAGzC,MAAa8B,UAAQ,UAAkB,OACpC,IAAI,KAAK,SAAS,QAAQ,IAAI,SAAS;;AAG1C,MAAaC,cACV,cACA,MACCD,OAAK,UAAU,EAAE;;AAGrB,MAAaE,eAAa,UAAkB,OACzC,IAAI,SAAS,SAAS1B,OAAK,SAAS;;AAGvC,MAAa2B,mBACV,cACA,MACCD,YAAU,UAAU,EAAE;;AAG1B,MAAaE,WAAS,QAAgB,QAAgB,MACpD,OAAO,SAAU,IAAI,OAAO,SAAS5B,OAAK,OAAO,GAAIA,OAAK,OAAO;;AAGnE,MAAa6B,eACV,QAAgB,YAChB,MACCD,QAAM,QAAQ,QAAQ,EAAE;;AAG5B,MAAaE,gBAAc,QAAgB,WAAmB;CAC5D,MAAM,QAAQ9B,OAAK,OAAO,GAAGA,OAAK,OAAO;CAEzC,OAAO;EACL;EACA,OAAO,OAAO,QAAQ,OAAO,QAAQ;EACtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChTH,MAAa,aAA4C+B;AAEzD,MAAa,SAwBTC;AAEJ,MAAa,UAiBTC;AAEJ,MAAa,OAkBTC;AAEJ,MAAa,gBAkBTC;AAEJ,MAAa,cAkBTC;AAEJ,MAAa,WAkBTC;AAEJ,MAAa,WAkBTC;;;;;;;;AASJ,MAAa,aAA2DC;;;;;;;;;;AAWxE,MAAa,OAA8BC;AAE3C,MAAa,WAoBTC;;;;;;;;;;;;;;AAeJ,MAAa,iBACXC;AAEF,MAAa,mBAmBTC;AAEJ,MAAa,QAkBTC;AAEJ,MAAa,SAmBTC;AAEJ,MAAa,QAoCTC;;;;;;AAOJ,MAAa,cAGTC;;;;;;AAOJ,MAAa,gBAGTC;;;;;;AAOJ,MAAa,YAGTC;;;;;;AAOJ,MAAa,cAGTC;;;;;;AAOJ,MAAa,WAAoCC;;;;;;AAOjD,MAAa,SAAgCC;;;;;;AAO7C,MAAa,WAAyCC;;;;;;AAOtD,MAAa,SAAqCC;;;;;;AAOlD,MAAa,cAA+CC;;;;;;AAO5D,MAAa,YAA2CC;;;;;;AAOxD,MAAa,gBAAwDC;;;;;;AAOrE,MAAa,cAAoDC;;;;;;AAOjE,MAAa,kBAA0DC;;;;;;AAOvE,MAAa,gBAA0DC;;;;;;AAOvE,MAAa,OAAeC;;;;;;;;AAS5B,MAAa,WAAiBC;;;;;;AAO9B,MAAa,SAAiBC;;;;;;;;;AAU9B,MAAa,OAAgDC;;;;;;;;AAS7D,MAAa,WAAwDC;;;;;;;;;AAUrE,MAAa,YAAqDC;;;;;;;;AASlE,MAAa,gBAA6DC;;;;;;;;;;AAW1E,MAAa,QAA+DC;;;;;;;;;AAU5E,MAAa,YACXC;;;;;;;;;AAUF,MAAa,aAA6DC"}