import type { RandomFn } from "./random.js";
/**
 * Common configuration options for all parameter types. See {@link Param}.
 */
export interface ParamOpts {
    /**
     * Human readable name/label for this parameter for external GUIs or other
     * display purposes. If omitted, the parameter ID should be used by default.
     */
    name: string;
    /**
     * Brief description/documentation for external GUIs or other display
     * purposes.
     */
    desc: string;
    /**
     * Optional, additional documentation/hints about this param, its role,
     * intended usage etc. How this information is used is left to external
     * tooling.
     */
    doc?: string;
    /**
     * Optional group name/key provided as hint for 3rd party tooling (e.g.
     * editor UIs) to group param controls.
     *
     * @defaultValue "main"
     */
    group: string;
    /**
     * Optional param ordering index provided as hint for 3rd party tooling
     * (e.g. editor UIs) to sort parameters (in ascending order).
     *
     * @remarks
     * If {@link ParamOpts.group} is used, the ordering given here only applies
     * to establish the param order in that group.
     *
     * **IMPORTANT**: It's highly recommended to specify this value to avoid
     * later confusion when an artwork is published on platforms which don't
     * support param names and/or not display their labels (e.g.
     * [editart.xyz](https://editart.xyz)). In these cases, the order of
     * parameters can only be deduced from the ordering specified here.
     *
     * @defaultValue 0
     */
    order: number;
    /**
     * Update mode/behavior when this param is being updated. See
     * {@link ParamUpdateBehavior} for details.
     *
     * @defaultValue "event"
     */
    update: ParamUpdateBehavior;
    /**
     * Defines which party or agent should be able to edit this parameter.
     *
     * @remarks
     * The interpretation of this value is platform specific, but generally
     * should be honored by a platform and align with:
     *
     * - `private`: artist-only modifications
     * - `protected`: artists and trusted parties (curator/gallery)
     * - `public`: collectors/viewers
     *
     * @defaultValue "protected"
     */
    edit: "private" | "protected" | "public";
    /**
     * If true (default), this param's value can be randomized (but also needs
     * to be supported by corresponding {@link ParamImpl})
     *
     * @defaultValue true
     */
    randomize: boolean;
    /**
     * Optional, non-binding hint for param editors to customize which GUI
     * widget to use for this param. (e.g. a {@link RangeParam} might be
     * represented as a slider by default, but offer a numeric input field for
     * more precise inputs as alternative, esp. if the number range is very
     * large)
     *
     * @defaultValue "default"
     */
    widget: ParamWidgetType;
}
/**
 * Declarative data-only description of a single parameter declared by the art
 * work and registered via {@link GenArtAPI.setParams}.
 *
 * @remarks
 * These param objects are forming the basis for much of {@link GenArtAPI}'s
 * core features and are designed to be sendable via {@link GenArtAPI.emit}
 * messages (aka `window.postMessage()`) between different windows.
 */
export interface Param<T> extends ParamOpts {
    type: string;
    /**
     * Default value. If omitted, a randomized default value will be generated,
     * iff the param type DOES provide a {@link ParamImpl.randomize} function.
     * Otherwise, {@link GenArtAPI.setParams} will throw an error if no default is
     * given and the param type ISN'T randomizable.
     *
     * @remarks
     * Randomization of default values will use the {@link GenArtAPI.random}
     * PRNG to ensure deterministic behavior.
     */
    default?: T;
    /**
     * Current param value, potentially randomized, or provided/customized via
     * external, platform specific means (e.g. param editors, stored variations).
     */
    value?: T;
    /**
     * This value is only for information purposes and initialized during
     * {@link GenArtAPI.setParams} and {@link GenArtAPI.updateParams}. See
     * {@link ParamState} for meaning of the possible values.
     */
    state: ParamState;
}
/**
 * Possible states a parameter can be in:
 *
 * - `custom`: The param value has been customized/overridden (by whatever
 *   means, e.g. via platform adapter)
 * - `default`: The param uses an artist provided default value
 * - `dynamic`: The param value will only be determined via the
 *   {@link ParamImpl.read} method.
 * - `random`: The param uses a randomized default value (because the artist
 *   hasn't provided one, also see note below)
 * - `void`: The param has only been declared but not yet initialized (internal use only)
 *
 * **Note:** Artists can omit defaults only for randomizable parameter types.
 */
export type ParamState = "custom" | "default" | "dynamic" | "random" | "void";
/**
 * Value type for {@link ParamOpts.widget}.
 */
export type ParamWidgetType = "default" | "alt" | "precise";
/**
 * Value type for {@link ParamOpts.update}. Defines the update mode/behavior
 * when a param is being updated. Platform providers are responsible to honor &
 * implement this setting (if possible).
 *
 * - `reload`: the piece should be reloaded/relaunched with new param value (a
 *   manual or externally triggered reload might be required for some
 *   platforms).
 * - `event`: the API will trigger a {@link ParamChangeMessage} via
 *   {@link GenArtAPI.emit}.
 */
export type ParamUpdateBehavior = "reload" | "event";
/**
 * {@link ParamOpts} field names which are optional in {@link BaseParam} and
 * param factory functions.
 */
export type BaseParamOptionals = "desc" | "edit" | "group" | "order" | "randomize" | "update" | "widget";
export type BaseParam<T extends Param<any>, EXCLUDE extends string = ""> = Omit<T, "type" | "state" | BaseParamOptionals | EXCLUDE> & Partial<Omit<Pick<ParamOpts, BaseParamOptionals>, EXCLUDE>>;
/**
 * Parameter type for big integer values. Randomizable by default. Factory
 * function: {@link ParamFactories.bigint}.
 */
export interface BigIntParam extends Param<bigint> {
    type: "bigint";
    /**
     * Min value.
     *
     * @default 0n
     */
    min: bigint;
    /**
     * Max value.
     *
     * @default 0xffff_ffff_ffff_ffffn
     */
    max: bigint;
}
/**
 * Parameter type for binary data (byte arrays). Non-randomizable. Factory
 * function: {@link ParamFactories.binary}.
 */
export interface BinaryParam extends Param<Uint8Array> {
    type: "binary";
    /**
     * Min number of bytes.
     *
     * @defaultValue 0
     */
    minLength: number;
    /**
     * Max number of bytes.
     *
     * @defaultValue 1024
     */
    maxLength: number;
}
/**
 * Choice/enum parameter for string-based values/options. Randomizable by
 * default. Factory function: {@link ParamFactories.choice}.
 *
 * @remarks
 * Also see {@link WeightedChoiceParam} for alternative.
 */
export interface ChoiceParam<T extends string> extends Param<T> {
    type: "choice";
    /**
     * List of possible choices/options, each given either as string or as
     * 2-tuple of `[value, label]`. If no label is specified for an option, it's
     * value will be used instead.
     */
    options: (T | [T, string])[];
}
/**
 * CSS hex color parameter. Randomizable. Factory function:
 * {@link ParamFactories.color}
 *
 * @remarks
 * CSS hex color value (6 digits only). Other/newer color types (e.g. `oklch()`)
 * might be supported later, but currently omitted due to lack of native browser
 * widgets for editing these colors...
 */
export interface ColorParam extends Param<string> {
    type: "color";
}
/**
 * Date parameter providing JS `Date` values (UTC) at the resolution of full
 * days. Not randomizable by default. Factory function:
 * {@link ParamFactories.date}
 *
 * @remarks
 * Intended for long running artworks to configure an important date for state
 * or behavior changes etc.
 *
 * Also see {@link DateTimeParam} and {@link TimeParam}.
 */
export interface DateParam extends Param<Date> {
    type: "date";
}
/**
 * Date-time parameter providing JS `Date` values (UTC). Not randomizable by
 * default. Factory function: {@link ParamFactories.datetime}
 *
 * @remarks
 * Intended for long running artworks to configure an important moments for
 * state or behavior changes etc.
 *
 * Also see {@link DateParam} and {@link TimeParam}.
 */
export interface DateTimeParam extends Param<Date> {
    type: "datetime";
}
/**
 * Image parameter, i.e. an integer based pixel buffer (in different formats),
 * intended for obtaining spatially varied parameters (e.g. gradient maps).
 * Non-randomizable.
 */
export interface ImageParam extends Param<Uint8Array | Uint8ClampedArray | Uint32Array> {
    type: "image";
    /** Image width */
    width: number;
    /** Height width */
    height: number;
    /**
     * Image mode:
     *
     * - `gray` (requires `Uint8Array` or `Uint8ClampedArray`)
     * - `rgba` (requires `Uint32Array`)
     */
    format: "gray" | "rgba";
}
/**
 * List parameter, holding a number of string-based values and optionally
 * supports min/max list sizes. Not randomizable by default.
 */
export interface StringListParam<T extends string> extends Param<T[]> {
    type: "strlist";
    /** Minimum list size */
    minLength: number;
    /** Maximum list size */
    maxLength: number;
    /** Regexp or string-encoded regexp pattern */
    match?: string | RegExp;
}
/**
 * List parameter, holding a number of numeric values and optionally supports
 * min/max list sizes. Not randomizable by default.
 */
export interface NumListParam extends Param<number[]> {
    type: "numlist";
    /** Minimum list size */
    minLength: number;
    /** Maximum list size */
    maxLength: number;
}
/**
 * Ramp parameter, a curve defined by stops/keyframes in the closed [0,1]
 * interval (each a `[pos,value]`-tuple). Unlike other built-in param types, the
 * actual value of a ramp will be dynamically sampled from its curve by
 * providing a `time` arg (clamped to the [0,1] range) to the getter function
 * returned by {@link GenArtAPI.setParams}) (or when calling
 * {@link GenArtAPI.getParamValue} or {@link GenArtAPI.paramValueGetter}
 * directly). Not randomizable by default.
 *
 * Factory function: {@link ParamFactories.ramp}
 */
export interface RampParam extends Param<number> {
    type: "ramp";
    /**
     * Ramp curve control points. A flat array of alternating `time`, `value`
     * pairs, where `time` is normalized in [0,1] range.
     */
    stops: number[];
    /**
     * Ramp interpolation mode to obtain curve values between stops/keyframes.
     *
     * @defaultValue "linear"
     */
    mode?: "linear" | "smooth" | "exp";
}
/**
 * Numeric param within a defined min/max range and optional step size.
 * Randomizable by default. Factory function: {@link ParamFactories.range}
 */
export interface RangeParam extends Param<number> {
    type: "range";
    /**
     * Minimum value (should be a multiple of {@link RangeParam.step}).
     *
     * @defaultValue 0
     */
    min: number;
    /**
     * Maximum value (should be a multiple of {@link RangeParam.step}).
     *
     * @defaultValue 100
     */
    max: number;
    /**
     * Step value, i.e. the final param value will be:
     * `value = clamp(round(value, step), min, max)`
     *
     * @defaultValue 1
     */
    step: number;
    /**
     * Optional exponent for hinting GUI param editors to use an exponential
     * slider/controller (if available) to adjust the param value.
     *
     * @remarks
     * If this option is respected, a GUI controller should internally model its
     * value in the [0,1] range and then use the following formula to compute
     * the actual param value:
     *
     * ```
     * paramValue = min + (max - min) * (sliderValue ** exponent)
     * ```
     *
     * Using this formula, exponents > 1 will cause an "ease-in"
     * behavior/mapping, whilst exponents in the (0,1) range will cause
     * "ease-out" curvature. If not given, a default exponent of 1 is assumed,
     * resulting in linear mapping.
     *
     * @defaultValue 1
     */
    exponent?: number;
}
/**
 * Text/string param with optional min/max length and/or regexp validation
 * pattern. Not randomizable by default. Factory function:
 * {@link ParamFactories.text}
 */
export interface TextParam extends Param<string> {
    type: "text";
    /**
     * Minimum length
     *
     * @defaultValue 0
     */
    minLength: number;
    /**
     * Maximum length
     *
     * @defaultValue 32
     */
    maxLength: number;
    /**
     * Hint for param editors to provide multiline input
     *
     * @defaultValue false
     */
    multiline?: boolean;
    /** Regexp or string-encoded regexp pattern */
    match?: RegExp | string;
}
/**
 * Parameter providing time-of-day values (local time at the deployment
 * target/client) in the form of a 3-tuple: `[hour, minute, second]` (24h format
 * only). Randomizable by default.
 *
 * @remarks
 * Intended for long running artworks to configure an important time in the day
 * for state or behavior changes etc. (e.g. scheduling daily sleep mode)
 *
 * Also see {@link DateParam} and {@link DateTimeParam}.
 */
export interface TimeParam extends Param<[number, number, number]> {
    type: "time";
}
/**
 * On/off switch/toggle (boolean) parameter type. Randomizable by default.
 * Factory function: {@link ParamFactories.toggle}
 */
export interface ToggleParam extends Param<boolean> {
    type: "toggle";
}
/**
 * n-dimensional vector parameter type. Randomizable by default. Factory
 * function: {@link ParamFactories.vector}
 *
 * @remarks
 * Also see {@link XYParam} for alternative.
 */
export interface VectorParam extends Param<number[]> {
    type: "vector";
    /**
     * Vector dimensions/size. Required.
     */
    size: number;
    /**
     * Minimum vector value. Each vector component should be a multiple of
     * {@link VectorParam.step}.
     *
     * @defaultValue 0
     */
    min: number[];
    /**
     * Maximum vector value. Each vector component should be a multiple of
     * {@link VectorParam.step}.
     *
     * @defaultValue 1
     */
    max: number[];
    /**
     * Step vector value.
     *
     * @defaultValue 0.01
     */
    step: number[];
    /**
     * Semi-optional array of labels for the different vector components. If not
     * given, the following label sets are used:
     *
     * - 2d: ["X", "Y"]
     * - 3d: ["X", "Y", "Z"]
     * - 4d: ["X", "Y", "Z", "W"]
     * - nd: must be defined by artist (error, if missing)
     */
    labels: string[];
}
/**
 * Choice/enum parameter for string-based values/options with associated weights
 * to control randomization behavior. Randomizable by default. Factory function:
 * {@link ParamFactories.weighted}
 *
 * @remarks
 * Also see {@link ChoiceParam} for alternative.
 *
 * This param type is identical to {@link ChoiceParam} excluding the case when
 * this param is evaluated with an optional {@link RandomFn} given to
 * {@link GenArtAPI.getParamValue} (aka the param accessor function returned by
 * {@link GenArtAPI.setParams}). In that case a random parameter value is
 * produced with a probability distribution defined by the relative weights
 * given to each option.
 */
export interface WeightedChoiceParam<T extends string> extends Param<T> {
    type: "weighted";
    /**
     * List of possible choices/options, each with associated weight. Each
     * option is defined as 3-tuple of `[weight, value, label]` (labels are
     * optional).
     */
    options: [number, T, string?][];
    /**
     * Total sum of weights (will be precomputed by factory function).
     *
     * @internal
     */
    total: number;
}
/**
 * 2D dimensional vector param with values in the closed [0,1] interval. Useful
 * to control two co-dependent parameters using an XY controller/touchpad (the
 * recommended UI widget for this param type). Randomizable by default. Factory
 * function: {@link ParamFactories.xy}
 */
export interface XYParam extends Param<[number, number]> {
    type: "xy";
}
export type ParamSpecs = Record<string, Param<any>>;
export type NestedParamSpecs = Record<string, NestedParam>;
export type NestedParam = Param<any> & {
    __params?: NestedParamSpecs;
};
export type ParamValues<T extends ParamSpecs> = {
    [id in keyof T]: ParamValue<T[id]>;
};
export type ParamValue<T extends Param<any>> = NonNullable<T["value"]>;
/**
 * Set of functions used to implement a parameter type.
 */
export interface ParamImpl<T = any> {
    /**
     * Called from {@link GenArtAPI.setParamValue} to pre-validate a given value
     * before updating a param spec. Returns true if the given value can be used
     * for updating a param spec directly or via {@link ParamImpl.coerce}.
     *
     * @remarks
     * If this validator returns false, the param update will be terminated
     * immediately and {@link GenArtAPI.setParamValue} will emit a
     * {@link ParamErrorMessage} message (by default).
     *
     * @param spec
     * @param value
     */
    validate: (spec: Readonly<Param<T>>, value: any) => boolean;
    /**
     * Called from {@link GenArtAPI.setParamValue}, this function is used to
     * coerce (or otherwise prepare) the given `value` in a type-specific,
     * undisclosed manner. The returned value is then assigned to the param
     * spec.
     *
     * @remarks
     * The `value` given will already have passed the {@link ParamImpl.validate}
     * check.
     *
     * @param spec
     * @param value
     */
    coerce?: (spec: Readonly<Param<T>>, value: any) => T;
    /**
     * If given this function is used to produce a random value based on
     * constraints of the provided param spec and MUST use the provided `rnd`
     * random function to do so.
     *
     * @param spec
     * @param rnd
     */
    randomize?: (spec: Readonly<Param<T>>, rnd: RandomFn) => T;
    /**
     * Used for param types which produce time-based values and only can provide
     * values indirectly, derived from the param's other config options (e.g. a
     * {@link RampParam}'s curve control points). If given, this function will
     * be called from {@link GenArtAPI.getParamValue} to compute a value for
     * given time `t` (where `t` is usually in the [0,1] range).
     *
     * @remarks
     * If this function is not given, {@link GenArtAPI.getParamValue} will
     * simply return {@link Param.value} or fallback to {@link Param.default}.
     *
     * @param spec
     * @param t
     */
    read?: (spec: Readonly<Param<T>>, t: number) => T;
    /**
     * Optional parameter specs for composite or nested params. These nested
     * params can be used to define constraints and possible controls for
     * aspects of the main parameter.
     *
     * @remarks
     * For example, conceptually, a {@link RampParam} is a composite of
     * {@link RampParam.stops} (a {@link NumListParam}) and
     * {@link RampParam.mode} (a {@link ChoiceParam}).
     *
     * These param specs can be used to delegate {@link ParamImpl} tasks to the
     * implementations of those embedded params.
     */
    params?: ParamSpecs;
}
export interface ParamFactories {
    /**
     * Factory function to define a {@link BigIntParam}.
     *
     * @example
     * ```ts
     * $genart.params.bigint({
     *     name: "Test",
     *     desc: "Binary data",
     *     default: 0x1234_5678_9abc_deffn,
     * });
     * ```
     *
     * @param spec
     */
    bigint(spec: BaseParam<BigIntParam, "min" | "max"> & Partial<Pick<BigIntParam, "min" | "max">>): BigIntParam;
    /**
     * Factory function to define a {@link BinaryParam}.
     *
     * @example
     * ```ts
     * $genart.params.binary({
     *     name: "Test",
     *     desc: "Binary data",
     *     default: new Uint8Array([0xde, 0xca, 0xfb, 0xad]),
     * });
     * ```
     *
     * @param spec
     */
    binary(spec: BaseParam<BinaryParam, "minLength" | "maxLength" | "randomize"> & Partial<Pick<BinaryParam, "minLength" | "maxLength">>): BinaryParam;
    /**
     * Factory function to define a {@link ChoiceParam}.
     *
     * @remarks
     * Also see {@link ParamFactories.weighted} for alternative.
     *
     * @example
     * ```ts
     * $genart.params.choice({
     *     name: "Test",
     *     desc: "Color theme",
     *     default: "dark",
     *     options: ["dark", "light", "radiant"]
     * });
     * ```
     *
     * @param spec
     */
    choice<T extends string>(spec: BaseParam<ChoiceParam<T>>): ChoiceParam<T>;
    /**
     * Factory function to define a {@link ColorParam}.
     *
     * @example
     * ```ts
     * $genart.params.color({
     *     name: "Test",
     *     desc: "Base color",
     *     default: "#aabbcc",
     * });
     * ```
     *
     * @param spec
     */
    color(spec: BaseParam<ColorParam>): ColorParam;
    /**
     * Factory function to define a {@link DateParam}.
     *
     * @remarks
     * If `default` is given as string, it must be in `yyyy-MM-dd` format.
     *
     * Also see {@link ParamFactories.datetime} and {@link ParamFactories.time}.
     *
     * @example
     * ```ts
     * $genart.params.date({
     *     name: "Test",
     *     desc: "End of license date",
     *     default: new Date(Date.UTC(2025, 0, 1)),
     * });
     * ```
     *
     * @param spec
     */
    date(spec: BaseParam<DateParam> & {
        default: Date | string;
    }): DateParam;
    /**
     * Factory function to define a {@link DateTimeParam}.
     *
     * @remarks
     * If `default` is given as string, it must be in ISO8601 format, e.g.
     * `yyyy-MM-ddTHH:mm:ssZ`.
     *
     * Also see {@link ParamFactories.date} and {@link ParamFactories.time}.
     *
     * @example
     * ```ts
     * $genart.params.datetime({
     *     name: "Test",
     *     desc: "End of license date",
     *     default: new Date(Date.UTC(2025, 0, 1)),
     * });
     * ```
     *
     * @param spec
     */
    datetime(spec: BaseParam<DateTimeParam> & {
        default: Date | string;
    }): DateTimeParam;
    /**
     * Factory function to define a {@link ImageParam}.
     *
     * $genart.params.image({
     *     name: "Test",
     *     desc: "Test gradient",
     *     width: 6,
     *     height: 1,
     *     default: new Uint8Array([0x00, 0x33, 0x66, 0x99, 0xcc, 0xff]),
     * });
     * ```
     *
     * @param spec
     */
    image(spec: BaseParam<ImageParam>): ImageParam;
    /**
     * Factory function to define a {@link NumListParam}.
     *
     * @example
     * ```ts
     * $genart.params.numlist({
     *     name: "Test",
     *     desc: "Numbers",
     *     default: [23, 42, 66],
     * });
     * ```
     *
     * @param spec
     */
    numlist(spec: BaseParam<NumListParam, "minLength" | "maxLength"> & Partial<Pick<NumListParam, "minLength" | "maxLength">>): NumListParam;
    /**
     * Factory function to define a {@link StringListParam}.
     *
     * @example
     * ```ts
     * $genart.params.strlist({
     *     name: "Test",
     *     desc: "Names",
     *     default: ["alice", "bob", "charlie"],
     * });
     * ```
     *
     * @param spec
     */
    strlist<T extends string>(spec: BaseParam<StringListParam<T>, "minLength" | "maxLength"> & Partial<Pick<StringListParam<T>, "minLength" | "maxLength">>): StringListParam<T>;
    /**
     * Factory function to define a {@link RampParam}.
     *
     * @remarks
     * If `stops` are given, at least 2 pairs need to be provided. Internally,
     * these stops are stored flattened (see {@link RampParam.stops} for
     * details), but here they must be provided as array of tuples (as shown in
     * the example below).
     *
     * @example
     * ```ts
     * // ramp parameter defining a triangular shape "/\"
     * const param = $genart.setParams({
     *     test: $genart.params.ramp({
     *         name: "Test",
     *         desc: "A simple triangle curve",
     *         stops: [[0, 0], [0.5, 1], [1, 0]]
     *     })
     * });
     *
     * // read param @ t=0.25
     * param("test", 0.25)
     * // 0.5
     *
     * // read param @ t=0.25
     * param("test", 0.6)
     * // 0.8
     * ```
     *
     * @param spec
     */
    ramp(spec: BaseParam<RampParam, "stops" | "default"> & {
        stops?: [number, number][];
    }): RampParam;
    /**
     * Factory function to define a {@link RangeParam}.
     *
     * @example
     * ```ts
     * $genart.params.range({
     *     name: "Test",
     *     desc: "Pick a number between 0-100",
     *     min: 0,
     *     max: 100,
     *     step: 5,
     * });
     * ```
     *
     * @param spec
     */
    range(spec: BaseParam<RangeParam, "min" | "max" | "step"> & Partial<Pick<RangeParam, "min" | "max" | "step">>): RangeParam;
    /**
     * Factory function to define a {@link TextParam}.
     *
     * @example
     * ```ts
     * $genart.params.text({
     *     name: "Test",
     *     desc: "Seed phrase",
     *     maxLength: 256,
     *     match: "^[a-z ]+$",
     *     multiline: true,
     * });
     * ```
     *
     * @param spec
     */
    text(spec: BaseParam<TextParam, "minLength" | "maxLength"> & Partial<Pick<TextParam, "minLength" | "maxLength">> & {
        default: string;
    }): TextParam;
    /**
     * Factory function to define a {@link TimeParam}.
     *
     * @remarks
     * Also see {@link ParamFactories.datetime} and {@link ParamFactories.date}.
     *
     * @example
     * ```ts
     * $genart.params.time({
     *     name: "Test",
     *     desc: "Sleep mode time",
     *     default: [22, 30, 0],
     * });
     * ```
     *
     * @param spec
     */
    time(spec: BaseParam<TimeParam>): TimeParam;
    /**
     * Factory function to define a {@link ToggleParam}.
     *
     * @example
     * ```ts
     * $genart.params.toggle({
     *     name: "Test",
     *     desc: "Switch",
     *     default: true,
     * });
     * ```
     *
     * @param spec
     */
    toggle(spec: BaseParam<ToggleParam>): ToggleParam;
    /**
     * Factory function to define an n-dimensional {@link VectorParam}.
     *
     * @example
     * ```ts
     * $genart.params.vector({
     *     name: "Test",
     *     desc: "3D vector",
     *     size: 3,
     *     min: -1,
     *     max: 1,
     *     step: [0.1, 0.2, 0.5],
     *     default: [0, 0, 0]
     * });
     * ```
     *
     * @param spec
     */
    vector(spec: BaseParam<VectorParam, "min" | "max" | "step" | "labels"> & {
        min?: number | number[];
        max?: number | number[];
        step?: number | number[];
        labels?: string[];
    }): VectorParam;
    /**
     * Factory function to define a {@link WeightedChoiceParam}.
     *
     * @example
     * ```ts
     * $genart.params.weighted({
     *     name: "Test",
     *     desc: "Weighted color options",
     *     options: [
     *         [8, "black"],
     *         [4, "cyan"],
     *         [2, "magenta"],
     *         [1, "yellow"],
     *     ],
     * });
     *
     * // optionally, labels can be provided for each option
     * $genart.params.weighted({
     *     name: "Test",
     *     desc: "Weighted color options with labels",
     *     options: [
     *         [8, "#000", "black"],
     *         [4, "#0ff", "cyan"],
     *         [2, "#f0f", "magenta"],
     *         [1, "#ff0", "yellow"],
     *     ],
     * });
     * ```
     *
     * @param spec
     */
    weighted<T extends string>(spec: BaseParam<WeightedChoiceParam<T>, "total">): WeightedChoiceParam<T>;
    /**
     * Factory function to define a {@link XYParam}.
     *
     * @example
     * ```ts
     * $genart.params.xy({
     *     name: "Test",
     *     desc: "Bottom-left: [dark,dry] / Top-right: [bright,wet]",
     *     default: [0.5, 0.5],
     * });
     * ```
     *
     * @param spec
     */
    xy(spec: BaseParam<XYParam>): XYParam;
}
