import type { IDeref } from "@thi.ng/api";
import { type Dimensions, type MaybeUnit, type NamedUnit, type Prefix, type Unit } from "./api.js";
/**
 * Cache/registry for all units defined via {@link defUnit}.
 */
export declare const UNITS: Record<string, NamedUnit>;
/**
 * Defines a "raw" (anonymous) unit using given dimension(s), scale factor, zero
 * offset and `coherent` flag indicating if the unit is the coherent one for
 * given dimensions and can later be used for deriving prefixed versions (see
 * {@link coherent}).
 *
 * @param dim
 * @param scale
 * @param offset
 * @param coherent
 */
export declare const unit: (dim: Dimensions | number, scale: number, offset?: number, coherent?: boolean) => Unit;
/**
 * Syntax sugar for defining coherent SI base units. See {@link unit}.
 *
 * @param dim
 */
export declare const coherent: (dim: Dimensions | number) => Unit;
/**
 * Returns a new dimensionless unit (i.e. all SI dimensions are zero) with given
 * `scale` factor.
 *
 * @param scale
 * @param offset
 * @param coherent
 */
export declare const dimensionless: (scale: number, offset?: number, coherent?: boolean) => Unit;
/**
 * Takes a unit symbol, full unit name and pre-defined {@link Unit} impl and
 * registers it in the {@link UNITS} cache for further lookups by symbol name.
 *
 * @remarks
 * By default throws an error if attempting to register a unit with an existing
 * symbol. If `force` is true, the existing unit will be overwritten.
 *
 * @param sym
 * @param name
 * @param unit
 * @param force
 */
export declare const defUnit: (sym: string, name: string, unit: Unit, force?: boolean) => NamedUnit;
/**
 * Attempts to find a unit by given symbol ID/name. Throws error if unit is
 * unknown.
 *
 * @param id
 */
export declare const asUnit: (id: string) => Unit;
/**
 * Creates a new re-scaled version of given unit (only coherent ones are
 * allowed), using the scale factor associated with given standard metric prefix
 * (see {@link PREFIXES}). If `coherent` is true (default: false), the new unit
 * itself is considered coherent and can be prefixed later.
 *
 * @example
 * ```ts
 * import { prefix, M } from "@thi.ng/units";
 *
 * // create kilometer unit from (builtin) meter
 * const KM = prefix("k", M);
 * ```
 *
 * @param id
 * @param unit
 * @param coherent
 */
export declare const prefix: (id: Prefix, unit: MaybeUnit, coherent?: boolean) => Unit;
export type QUnit<T extends number | number[]> = T extends number ? Unit : Unit[];
/**
 * Wrapper for scalar or vector quantities. See {@link quantity}.
 */
export declare class Quantity<T extends number | number[]> implements IDeref<T> {
    readonly value: QUnit<T>;
    constructor(value: QUnit<T>);
    deref(): T;
}
/**
 * Creates a new {@link Quantity}, i.e. a certain finite amount of a given unit.
 * `value` can be a number or vector.
 *
 * @remarks
 * The quantities can then be used for calculations & conversions using the
 * polymorphic functions: {@link div}, {@link mul}, {@link reciprocal} and
 * {@link convert}.
 *
 * The {@link Quantity} class also implements the standard
 * [`IDeref`](https://docs.thi.ng/umbrella/api/interfaces/IDeref.html) interface
 * to obtain unwrapped amount (though only should be used for dimensionless
 * quantities). Use {@link convert} otherwise!
 *
 * @example
 * ```ts tangle:../export/quantity.ts
 * import { convert, div, mul, quantity, NONE } from "@thi.ng/units";
 *
 * const speedOfLight = quantity(299792458, "m/s");
 *
 * // compute wavelength of a WiFi signal in millimeters
 * console.log(
 *   convert(div(speedOfLight, quantity(2.4,"GHz")), "mm")
 * );
 * // 124.9135
 *
 * // DIN A4 paper size
 * const A4 = quantity([210, 297], "mm");
 *
 * // convert paper size to inches
 * console.log(
 *   convert(A4, "in")
 * );
 * // [ 8.2677, 11.6929 ]
 *
 * // or calculate pixel dimensions @ 300 dpi
 * // the result of the product is dimensionless so we use NONE as target unit
 * console.log(
 *   convert(mul(A4, quantity(300, "dpi")), NONE)
 * );
 * // [ 2480.314960629921, 3507.8740157480315 ]
 *
 * // alternatively dimensionless units can be deref'd directly
 * console.log(
 *   mul(A4, quantity(300, "dpi")).deref()
 * );
 * // [ 2480.314960629921, 3507.8740157480315 ]
 * ```
 *
 * @param value
 * @param unit
 */
export declare const quantity: <T extends number | number[]>(value: T, unit: MaybeUnit) => Quantity<T>;
/**
 * Polymorphic function. Derives a new quantity or unit as the product of the
 * given quantities/units.
 *
 * @remarks
 * If given units and if `coherent` is true (default: false), the new unit
 * itself is considered coherent and can be prefixed later.
 *
 * @param a
 * @param b
 */
export declare function mul(a: Quantity<number>, b: Quantity<number>): Quantity<number>;
export declare function mul(a: Quantity<number>, b: Quantity<number[]>): Quantity<number[]>;
export declare function mul(a: Quantity<number[]>, b: Quantity<number>): Quantity<number[]>;
export declare function mul(a: Quantity<number[]>, b: Quantity<number[]>): Quantity<number[]>;
export declare function mul(a: MaybeUnit, b: MaybeUnit | number, coherent?: boolean): Unit;
/**
 * Polymorphic function. Derives a new quantity or unit via the division of the
 * given quantities/units.
 *
 * @remarks
 * If given units and if `coherent` is true (default: false), the new unit
 * itself is considered coherent and can be prefixed later.
 *
 * @param a
 * @param b
 */
export declare function div(a: Quantity<number>, b: Quantity<number>): Quantity<number>;
export declare function div(a: Quantity<number>, b: Quantity<number[]>): Quantity<number[]>;
export declare function div(a: Quantity<number[]>, b: Quantity<number>): Quantity<number[]>;
export declare function div(a: Quantity<number[]>, b: Quantity<number[]>): Quantity<number[]>;
export declare function div(a: MaybeUnit, b: MaybeUnit | number, coherent?: boolean): Unit;
/**
 * Polymorphic function. Creates the reciprocal version of given quantity or
 * unit (i.e. all SI dimensions will flip sign) and the scale factor of the new
 * unit will be `1/scale`.
 *
 * @remarks
 * If given a unit and if `coherent` is true (default: false), the new unit
 * itself is considered coherent and can be prefixed later.
 *
 * @example
 * ```ts
 * import { reciprocal, S } from "@thi.ng/units";
 *
 * const HZ = reciprocal(S, true);
 * ```
 *
 * @param u
 */
export declare function reciprocal(u: Quantity<number>): Quantity<number>;
export declare function reciprocal(u: Quantity<number[]>): Quantity<number[]>;
export declare function reciprocal(u: MaybeUnit, coherent?: boolean): Unit;
/**
 * Raises given unit to power `k`. If `coherent` is true (default: false), the
 * new unit itself is considered coherent and can be prefixed later.
 *
 * ```ts
 * import { div, pow, M, S } from "@thi.ng/units";
 *
 * // create kilometer unit from (builtin) meter
 * const SQ_METER = pow(M, 2);
 *
 * // acceleration aka m/s^2
 * const M_S2 = div(M, pow(S, 2));
 * ```
 *
 * @param u
 * @param k
 * @param coherent
 */
export declare const pow: (u: MaybeUnit, k: number, coherent?: boolean) => Unit;
/**
 * Polymorphic function. If given a {@link Quantity}, attempts to convert it to
 * given `dest` unit and returns result as raw/unwrapped value (or vector).
 * Otherwise, attempts to convert `x` amount from `src` unit into `dest` unit
 * and returns result. In all cases an error is thrown if units are
 * incompatible.
 *
 * @remarks
 * Units can only be converted if their SI dimensions are compatible. See
 * {@link isConvertible}.
 *
 * @param x
 * @param dest
 */
export declare function convert<T extends number | number[]>(x: Quantity<T>, dest: MaybeUnit): T;
export declare function convert(x: number, src: MaybeUnit, dest: MaybeUnit): number;
/**
 * Returns true if `src` quantity or unit is convertible to `dest` unit.
 *
 * @param src
 * @param dest
 */
export declare const isConvertible: (src: Quantity<any> | MaybeUnit, dest: MaybeUnit) => boolean;
/**
 * Returns true, if `u` is a dimensionless quantity or unit.
 *
 * @param u
 */
export declare const isDimensionless: (u: Quantity<any> | MaybeUnit) => boolean;
/**
 * Returns true if the two given units are reciprocal to each other (and
 * therefore can be used for conversion).
 *
 * @param a
 * @param b
 */
export declare const isReciprocal: (a: MaybeUnit, b: MaybeUnit) => boolean;
/**
 * Polymorphic function. Returns formatted version of given quantity's or unit's
 * SI dimension vector.
 *
 * @param u
 */
export declare const formatSI: (u: Quantity<any> | MaybeUnit) => string;
//# sourceMappingURL=unit.d.ts.map