import { numeric } from '../../numeric'; import { Bounds, boundsZ, NumberCouple } from '../base'; export { type Bounds, boundsZ }; export type Crude = Bounds | NumberCouple; /** Options for the `construct` function. */ interface ConstructOptions { /** * If true (default), automatically swaps the lower and upper bounds if the lower bound * is greater than the upper bound. This ensures the resulting bounds are valid. * * @example * // With makeValid: true (default) * construct(10, 0) // => { lower: 0, upper: 10 } * * @example * // With makeValid: false * construct(10, 0, { makeValid: false }) // => { lower: 10, upper: 0 } */ makeValid?: boolean; } export interface Construct { /** * Constructs a bounds object from various input formats. The function supports multiple * overloads to handle different input types: * * 1. From a crude bounds object or array: * ```typescript * construct({ lower: 0, upper: 10 }) // => { lower: 0, upper: 10 } * construct([0, 10]) // => { lower: 0, upper: 10 } * ``` * * 2. From separate lower and upper values: * ```typescript * construct(0, 10) // => { lower: 0, upper: 10 } * construct(10) // => { lower: 0, upper: 10 } * ``` * * The function supports both number and bigint types through the generic parameter T. * By default, T is number. * * Options: * - makeValid: If true (default), swaps lower and upper bounds if lower > upper * * @param bounds - The input bounds to construct from. Can be: * - A bounds object with lower and upper properties * - An array of length 2 [lower, upper] * - A single number/bigint (treated as upper bound, with lower = 0) * - Two numbers/bigints (lower and upper bounds) * @param options - Optional configuration for bounds construction * @returns A bounds object with lower and upper properties * * @example * // From bounds object * construct({ lower: 0, upper: 10 }) * // => { lower: 0, upper: 10 } * * @example * // From array * construct([0, 10]) * // => { lower: 0, upper: 10 } * * @example * // From separate values * construct(0, 10) * // => { lower: 0, upper: 10 } * * @example * // Single value (upper bound only) * construct(10) * // => { lower: 0, upper: 10 } * * @example * // With bigint * construct(0n, 10n) * // => { lower: 0n, upper: 10n } * * @example * // Invalid bounds (lower > upper) * construct(10, 0) * // => { lower: 0, upper: 10 } (bounds are swapped) */ (bounds: Crude, options?: ConstructOptions): Bounds; /** * Constructs a bounds object from separate lower and upper values. * * @param lower - The lower bound value * @param upper - The upper bound value. If omitted, lower is used as the upper bound * and 0 is used as the lower bound * @returns A bounds object with lower and upper properties */ (lower: T, upper?: T | ConstructOptions): Bounds; (lower: T | Crude, upper?: T | ConstructOptions, options?: ConstructOptions): Bounds; } export declare const construct: (lower: T | Crude, upper?: T | ConstructOptions, options?: ConstructOptions) => Bounds; /** A lower and upper bound of 0. */ export declare const ZERO: Bounds; /** A lower bound of -Infinity and an upper bound of Infinity. */ export declare const INFINITE: Bounds; /** A lower bound of 0 and an upper bound of 1. */ export declare const DECIMAL: Bounds; /** Clip space bounds i.e. a lower bound of -1 and an upper bound of 1. */ export declare const CLIP: Readonly<{ lower: -1; upper: 1; }>; /** * Checks whether the given bounds are equal. * * @param _a - The first bounds to compare. * @param _b - The second bounds to compare. * @returns True if the bounds are equal, false otherwise. */ export declare const equals: (_a?: Crude, _b?: Crude) => boolean; /** * Makes the given bounds valid by swapping the lower and upper bounds if the lower bound * is greater than the upper bound. * @param a - The bounds to make valid. * @returns The valid bounds. */ export declare const makeValid: (a: Bounds) => Bounds; /** * Clamps the given target value to the given bounds. If the target is less than the lower * bound, the lower bound is returned. If the target is greater than or equal to the upper * bound, the upper bound minus 1 is returned. Otherwise, the target is returned. * * @param bounds - The bounds to clamp the target to. * @param target - The target value to clamp. * @returns The clamped target value. */ export declare const clamp: (bounds: Crude, target: T) => T; /** * Checks whether the given target value or bounds are within the given bounds. * * @param bounds - The bounds to check against. * @param target - The target value to check. Can either be a number or a bounds object. * @returns True if the target is within the bounds, false otherwise. */ export declare const contains: (bounds: Crude, target: T | Crude) => boolean; /** * Checks whether the given bounds overlap with each other. * * @param a - The first bounds to check. * @param b - The second bounds to check. * @returns True if the bounds overlap, false otherwise. */ export declare const overlapsWith: (a: Crude, b: Crude) => boolean; /** @returns the span of the given bounds i.e. upper - lower. */ export declare const span: (a: Crude) => T; /** @returns true if both the lower and upper bounds are 0, false otherwise. */ export declare const isZero: (a: Crude) => boolean; /** * @returns true if the difference between the lower and upper bounds is 0, * false otherwise. */ export declare const spanIsZero: (a: Crude) => boolean; /** * @returns true if both the upper and lower bounds are not Infinity or -Infinity, * false otherwise. */ export declare const isFinite: (a: Crude) => boolean; /** * Returns the mean value between the lower and upper bounds. * * @param a - The bounds to find the mean of. Can be either a strict bounds object * with 'lower' and 'upper' properties or an array of length 2. * @returns The mean value between the lower and upper bounds. * * @example * bounds.mean([0, 10]) // => 5 * bounds.mean({ lower: 0, upper: 10 }) // => 5 */ export declare const mean: (a: Crude) => number; /** * @returns bounds that have the maximum span of the given bounds i.e. the min of all * of the lower bounds and the max of all of the upper bounds. */ export declare const max: (bounds: Crude[]) => Bounds; /** * @returns bounds that have the minimum span of the given bounds i.e. the max of all * of the lower bounds and the min of all of the upper bounds. Note that this function * may create invalid bounds if the highest lower bound is greater than the lowest upper * bound. */ export declare const min: (bounds: Crude[]) => Bounds; /** * @returns an array of integers from the lower bound to the upper bound of the given * bounds. */ export declare const linspace: (bounds: Crude) => T[]; /** * Finds the index and position where a target value should be inserted into an array * of bounds. * * Crucially, this function assumes that the bounds are ORDERED and NON-OVERLAPPING. * * @template T * @param {Array>} bounds - An array of crude bounds. Each bound can either be * an array of length 2 or an object with `lower` and `upper` properties. * @param {T} target - The target value to insert. * * @returns {{ index: number, position: number }} An object containing: * - `index`: The index in the bounds array where the target belongs. * - `position`: The position within the bound where the target fits. If the target is * outside all bounds, the index will be where a new bound can be inserted. * * @example * // Target within an existing bound * const bounds = [[0, 10], [20, 30]]; * const target = 5; * const result = findInsertPosition(bounds, target); * // { index: 0, position: 5 } * * @example * // Target greater than all bounds * const bounds = [[0, 10], [20, 30]]; * const target = 35; * const result = findInsertPosition(bounds, target); * // { index: 2, position: 0 } * * @example * // Target less than all bounds * const bounds = [[10, 20], [30, 40]]; * const target = 5; * const result = findInsertPosition(bounds, target); * // { index: 0, position: 0 } * * @example * // Target overlaps between bounds * const bounds = [[0, 10], [20, 30]]; * const target = 15; * const result = findInsertPosition(bounds, target); * // { index: 1, position: 0 } * * @example * // Empty bounds array * const bounds = []; * const target = 5; * const result = findInsertPosition(bounds, target); * // { index: 0, position: 0 } * * @example * // Target exactly at lower bound * const bounds = [[0, 10], [20, 30]]; * const target = 10; * const result = findInsertPosition(bounds, target); * // { index: 1, position: 0 } * * @example * // Target exactly at upper bound * const bounds = [[0, 10], [20, 30]]; * const target = 30; * const result = findInsertPosition(bounds, target); * // { index: 2, position: 0 } * * @example * // Target inside bounds with exact fit * const bounds = [[0, 5], [5, 10]]; * const target = 5; * const result = findInsertPosition(bounds, target); * // { index: 1, position: 0 } * * @throws {Error} If invalid bounds are provided, such as bounds arrays not being of * length 2. * * See {@link construct} for constructing valid bounds. */ export declare const findInsertPosition: (bounds: Array>, target: T) => { index: number; position: number; }; /** * A plan for inserting a new bound into an ordered array of bounds. */ export interface InsertionPlan { /** How much to increase the lower bound of the new bound or decrease the upper bound * of the previous bound. */ removeBefore: number; /** How much to decrease the upper bound of the new bound or increase the lower bound * of the next bound. */ removeAfter: number; /** The index at which to insert the new bound. */ insertInto: number; /** The number of bounds to remove from the array. */ deleteInBetween: number; } /** * Build a plan for inserting a new bound into an ordered array of bounds. This function * is particularly useful for inserting a new array into a sorted array of array of arrays * that may overlap. The plan is used to determine how to splice the new array into the * existing array. The following are important constraints: * * Crucially, this function assumes that the bounds are ORDERED and NON-OVERLAPPING. * * 1. If the new bound is entirely contained within an existing bound, the new bound * is not inserted and the plan is null. * * @param bounds - An ordered array of bounds, where each bound is valid (i.e., lower <= upper) * and the lower bound of each bound is less than the upper bound of the next bound. * @param value - The new bound to insert. * @returns A plan for inserting the new bound into the array of bounds, or null if the * new bound is entirely contained within an existing bound. See the {@link InsertionPlan} * type for more details. */ export declare const buildInsertionPlan: (bounds: Array>, value: Crude) => InsertionPlan | null; /** * Traverse the given bounds by the specified distance, starting from a given point, and * return the end point of the traversal. The traversal 'skips' over integers that are * not within the array of bounds, moving only within the defined bounds. Traversing * across multiple bounds is handled smoothly, with direction determined by the sign of * the distance. * * Crucially, this function assumes that the bounds are ORDERED and NON-OVERLAPPING. * * If the distance takes the traversal beyond the bounds, it returns the last valid point * within the bounds or the first valid point depending on direction. * * @template T * @param {Array>} bounds - An array of crude bounds (array of length 2 or * objects with `lower` and `upper` properties). * @param {T} start - The starting point of the traversal. * @param {T} dist - The distance to traverse. Positive values move forwards, and * negative values move backwards. * * Edge Cases: * * 1. **Traversal beyond the last bound**: If the traversal moves beyond the last * bound (in either direction), the traversal ends at the last valid position within * the bounds. * - Example: `traverse([[0, 10], [20, 30]], 25, 10); // => 30` * (stops at the upper limit of the last bound) * * 2. **Traversal from a point outside the bounds**: If the starting point is outside * the bounds and the traversal distance would move within bounds, it finds the * closest bound and continues traversal from there. * - Example: `traverse([[0, 10], [20, 30]], 15, 5); // => 25` (enters the second bound) * * 3. **Distance of 0**: If the distance is `0`, the traversal will return the starting * point without moving. * - Example: `traverse([[0, 10], [20, 30]], 5, 0); // => 5` * * @returns {T} The end point of the traversal within the bounds. * * @example * // Traversing 5 units forward from 5, ending exactly at the upper bound of the first * range. * traverse([[0, 10], [20, 30]], 5, 5); * // => 10 * * @example * // Traversing 10 units forward from 5, crossing from the first range to the second. * traverse([[0, 10], [20, 30]], 5, 10); * // => 25 * * @example * // Traversing 5 units forward starting outside the bounds, the traversal enters the * // second bound. * traverse([[0, 10], [20, 30]], 15, 5); * // => 25 * * @example * // Traversing 30 units forward, stopping at the upper end of the second bound. * traverse([[0, 10], [20, 30]], 15, 30); * // => 30 * * @example * // Traversing 7 units backward starting from 17, moving into the first bound. * traverse([[0, 5], [5, 10], [15, 20]], 17, -7); * // => 5 * * @example * // Traversing beyond the last bound in a positive direction. * traverse([[0, 10], [20, 30]], 25, 10); * // => 30 (stops at the upper limit of the last bound) * * @example * // Traversing backward from a point not within any bound. * traverse([[0, 5], [10, 15]], 20, -10); * // => 15 (stops at the upper limit of the nearest previous bound) * * @example * // Traversing a distance of 0 from a point returns the starting point. * traverse([[0, 10], [20, 30]], 5, 0); * // => 5 * * @throws {Error} If invalid bounds are provided, such as bounds arrays not being of * length 2. * * See {@link construct} for constructing valid bounds. * */ export declare const traverse: (bounds: Array>, start: T, dist: T) => T; /** * Returns the number of values within the given bounds, 'skip'ing over values that are * not within the bounds. * * Crucially, this function assumes that the bounds are ORDERED and NON-OVERLAPPING. * * @example * bounds.distance( * [[0, 10], [20, 30]] * 5, * 5, * ) // => 0 * * @example * bounds.distance( * [[0, 10], [20, 30]] * 5, * 25, * ) // => 10 * * @example * bounds.distance( * [[0, 10], [20, 30]] * 15, * 25, * ) // => 5 * * @example * bounds.distance( * [[0, 10], [20, 30]] * 15, * 5, * ) // => 5 * * @param bounds * @param a - The start value. * @param b - The end value. */ export declare const distance: (bounds: Array>, a: T, b: T) => T; //# sourceMappingURL=bounds.d.ts.map