import { Unit, Geometric1, Spacetime1, Geometric2, Spacetime2, Geometric3 } from '@geometryzen/multivectors';
export { Dimensions, Geometric1, Geometric2, Geometric3, Matrix1, Matrix3, QQ, Spacetime1, Spacetime2, Unit, setDimensionsChecking } from '@geometryzen/multivectors';

/**
 * @hidden
 */
declare class Newton {
    /**
     * The GitHub URL of the repository.
     */
    GITHUB: string;
    /**
     * The last modification date in YYYY-MM-DD format.
     */
    LAST_MODIFIED: string;
    /**
     * The namespace used for traditional JavaScript module loading.
     */
    NAMESPACE: string;
    /**
     * The semantic version number of this library, i.e., (major.minor.patch) format.
     */
    VERSION: string;
    /**
     *
     */
    constructor();
}
/**
 * @hidden
 */
declare const config: Newton;

/**
 * @hidden
 * 0 = LOCAL, 1 = WORLD.
 */
type CoordType = 0 | 1;
/**
 * The coordinate frame that is fixed in relation to the rigid body.
 * @hidden
 */
declare const LOCAL = 0;
/**
 * The coordinate frame used as the basis for position and attitude of all bodies.
 * @hidden
 */
declare const WORLD = 1;

/**
 * @hidden
 */
interface SimObject {
    /**
     *
     */
    expireTime: number;
}

/**
 * @hidden
 */
declare class AbstractSimObject implements SimObject {
    /**
     *
     */
    private expireTime_;
    /**
     *
     */
    constructor();
    /**
     *
     */
    get expireTime(): number;
    set expireTime(expireTime: number);
}

/**
 * @hidden
 */
interface MatrixLike {
    readonly dimensions: number;
    /**
     * The unit of measure (shared by each element of the matrix).
     */
    uom?: Unit;
    getElement(row: number, column: number): number;
}

/**
 * @hidden
 */
declare abstract class Torque<T> extends AbstractSimObject {
    private readonly body;
    readonly bivector: T;
    /**
     *
     */
    bivectorCoordType: CoordType;
    private readonly $temp1;
    constructor(body: ForceBody<T>);
    /**
     *
     */
    getBody(): ForceBody<T>;
    /**
     *
     * @param torque
     */
    computeTorque(torque: T): void;
}

/**
 * A handle-body pattern abstraction of the multivector used by the Physics Engine.
 * The multivector encodes the metric in the multiplication of its basis vectors.
 */
interface Metric<T> {
    /**
     * Returns the time direction for relativistic metrics.
     * The returned vector is locked.
     * Non-relativistic metrics should return undefined.
     */
    readonly e0: T;
    /**
     * Returns the scalar component of the multivector.
     * @param mv The multivector for which the scalar component is required.
     */
    a(mv: T): number;
    add(lhs: T, rhs: T): T;
    addScalar(lhs: T, a: number, uom?: Unit): T;
    addVector(lhs: T, rhs: T): T;
    /**
     * TODO: Describe semantics of how this is expected to change the multivector argument.
     * @param mv
     * @param matrix
     */
    applyMatrix(mv: T, matrix: MatrixLike): T;
    clone(source: T): T;
    /**
     * Modifies the target to have the same property values as the source.
     * @param source
     * @param target
     * @returns the target.
     */
    copy(source: T, target: T): T;
    copyBivector(source: T, target: T): T;
    copyMatrix(m: MatrixLike): MatrixLike;
    copyScalar(a: number, uom: Unit, target: T): T;
    copyVector(source: T, target: T): T;
    /**
     * Create a non-generic instance derived from Force; Force is to be considered an abstract base type.
     * This will make it easier for clients; after instanceof Force2 or Force3, the properties of the
     * force application (F, and x) will have non-generic types.
     *
     * @param body The body that the force will be applied to.
     */
    createForce(body: ForceBody<T>): Force<T>;
    /**
     *
     * @param body The body that the torque will be applied to.
     */
    createTorque(body: ForceBody<T>): Torque<T>;
    direction(mv: T): T;
    divByScalar(lhs: T, a: number, uom?: Unit): T;
    ext(lhs: T, rhs: T): T;
    identityMatrix(): MatrixLike;
    /**
     *
     * @param matrix The matrix to be inverted.
     * @returns A new matrix which is the inverse of the specified matrix.
     */
    invertMatrix(matrix: MatrixLike): MatrixLike;
    isBivector(mv: T): boolean;
    isOne(mv: T): boolean;
    isScalar(mv: T): boolean;
    isSpinor(mv: T): boolean;
    isVector(mv: T): boolean;
    isZero(mv: T): boolean;
    lco(lhs: T, rhs: T): T;
    /**
     * Used to change the mutability of the multivector from mutable to immutable.
     * An immutable multivector is also described as locked. The number returned is
     * a token that may be used to unlock the multivector, making it mutable again.
     * @param mv The multivector to be locked.
     * @returns A token that may be used to unlock the multivector.
     */
    lock(mv: T): number;
    norm(mv: T): T;
    mul(lhs: T, rhs: T): T;
    mulByNumber(lhs: T, alpha: number): T;
    mulByScalar(lhs: T, a: number, uom?: Unit): T;
    mulByVector(lhs: T, rhs: T): T;
    neg(mv: T): T;
    /**
     * squared norm: |A| * |A| = A * rev(A)
     */
    squaredNorm(A: T): T;
    rco(lhs: T, rhs: T): T;
    rev(mv: T): T;
    rotate(mv: T, spinor: T): T;
    /**
     * Creates a grade 0 (scalar) multivector with value `a * uom`.
     * The scalar returned is in the unlocked (mutable) state.
     * @param a The scaling factor for the unit of measure.
     * @param uom The optional unit of measure. Equivalent to 1 if omitted.
     */
    scalar(a: number, uom?: Unit): T;
    scp(lhs: T, rhs: T): T;
    setUom(mv: T, uom: Unit): void;
    sub(lhs: T, rhs: T): T;
    subScalar(lhs: T, a: number, uom?: Unit): T;
    subVector(lhs: T, rhs: T): T;
    unlock(mv: T, token: number): void;
    uom(mv: T): Unit;
    write(source: T, target: T): void;
    /**
     * TODO: This looks a lot like copyVector. Is there any difference?
     * @param source
     * @param target
     */
    writeVector(source: T, target: T): void;
    writeBivector(source: T, target: T): void;
}

/**
 *
 */
interface ForceBody<T> extends SimObject {
    /**
     * The metric must be known in order to compute the energies and angular velocity.
     */
    metric: Metric<T>;
    /**
     * A placeholder for applications to define a unique identifier.
     */
    uuid: string;
    /**
     * mass (scalar). In the case of relativistic systems, this is the rest mass.
     */
    M: T;
    /**
     * position (vector)
     */
    X: T;
    /**
     * attitude (spinor)
     */
    R: T;
    /**
     * momentum (vector)
     */
    P: T;
    /**
     * angular momentum (bivector)
     */
    L: T;
    /**
     * angular velocity (bivector)
     */
    Ω: T;
    /**
     * offset into state array
     */
    varsIndex: number;
    /**
     * computes the rotational kinetic energy.
     */
    rotationalEnergy(): T;
    /**
     * computes the translational kinetic energy.
     */
    translationalEnergy(): T;
    /**
     * updates the angular velocity from the angular momentum.
     */
    updateAngularVelocity(): void;
}

/**
 * @hidden
 */
declare class Force<T> extends AbstractSimObject {
    private readonly body;
    /**
     * The point of application of the force.
     */
    readonly location: T;
    /**
     *
     */
    private $locationCoordType;
    /**
     * The force vector, may be in local or world coordinates.
     */
    readonly vector: T;
    /**
     *
     */
    private $vectorCoordType;
    private readonly $temp1;
    private readonly $temp2;
    /**
     *
     */
    constructor(body: ForceBody<T>);
    /**
     *
     */
    get locationCoordType(): CoordType;
    set locationCoordType(locationCoordType: CoordType);
    /**
     *
     */
    get vectorCoordType(): CoordType;
    set vectorCoordType(vectorCoordType: CoordType);
    /**
     *
     */
    getBody(): ForceBody<T>;
    /**
     * Computes the point of application of the force in world coordinates.
     *
     * @param position (output)
     */
    computePosition(position: T): void;
    /**
     * Computes the force being applied (vector) in WORLD coordinates.
     *
     * @param force (output)
     */
    computeForce(force: T): void;
    /**
     * Computes the torque, i.e. moment of the force about the center of mass (bivector).
     * Torque = (x - X) ^ F, so the torque is being computed with center of mass as origin.
     * Torque = r ^ F because r = x - X
     *
     * @param torque (output)
     */
    computeTorque(torque: T): void;
    get F(): T;
    get x(): T;
}

/**
 * A force law computes the forces on one or more bodies in the system.
 */
interface ForceLaw<T> extends SimObject {
    /**
     * The forces that were computed the last time that the  `updateForces()` method was called.
     */
    readonly forces: Force<T>[];
    /**
     * Updates the forces based upon the current state of the bodies.
     */
    updateForces(): Force<T>[];
    /**
     * TODO: This does not do anything in the existing implementations of ForceLaw.
     */
    disconnect(): void;
    /**
     * Computes the potential energy associated with the interaction of the bodies.
     */
    potentialEnergy(): T;
}

/**
 *
 */
declare class ConstantForceLaw<T> extends AbstractSimObject implements ForceLaw<T> {
    private body;
    /**
     * The attachment point to the body in body coordinates.
     */
    private readonly $force;
    private readonly $forces;
    private readonly $potentialEnergy;
    private $potentialEnergyLock;
    /**
     *
     * @param body the body that the force acts upon.
     * @param vector the force vector.
     * @param vectorCoordType 0 => LOCAL, 1 => WORLD.
     */
    constructor(body: ForceBody<T>, vector: T, vectorCoordType?: CoordType);
    get forces(): Force<T>[];
    get location(): T;
    set location(location: T);
    get vector(): T;
    set vector(vector: T);
    /**
     *
     */
    updateForces(): Force<T>[];
    /**
     *
     */
    disconnect(): void;
    /**
     *
     */
    potentialEnergy(): T;
}

/**
 *
 */
interface TorqueLaw<T> extends SimObject {
    /**
     *
     */
    readonly torques: Torque<T>[];
    /**
     *
     */
    updateTorques(): Torque<T>[];
    /**
     *
     */
    disconnect(): void;
    /**
     *
     */
    potentialEnergy(): T;
}

/**
 *
 */
declare class ConstantTorqueLaw<T> extends AbstractSimObject implements TorqueLaw<T> {
    private $body;
    private readonly $torque;
    private readonly $torques;
    constructor($body: ForceBody<T>, value: T, valueCoordType: CoordType);
    get torques(): Torque<T>[];
    updateTorques(): Torque<T>[];
    disconnect(): void;
    potentialEnergy(): T;
}

/**
 * @hidden
 */
interface Charged<T> extends ForceBody<T> {
    Q: T;
}

/**
 * The Electric Force (Coulomb's Law)
 */
declare class CoulombLaw<T> extends AbstractSimObject implements ForceLaw<T> {
    private readonly body1;
    private readonly body2;
    /**
     * The constant of proportionality.
     */
    private readonly $k;
    private readonly F1;
    private readonly F2;
    private readonly $forces;
    /**
     * Scratch variable for computing potential energy.
     */
    private readonly potentialEnergy_;
    private potentialEnergyLock_;
    private readonly metric;
    /**
     *
     */
    constructor(body1: Charged<T>, body2: Charged<T>, k?: T);
    /**
     * The proportionality constant, Coulomb's constant.
     * The approximate value in SI units is 9 x 10<sup>9</sup> N·m<sup>2</sup>/C<sup>2</sup>.
     * The default value is one (1).
     */
    get k(): T;
    set k(k: T);
    get forces(): Force<T>[];
    /**
     * Computes the forces due to the Coulomb interaction.
     * F = k * q1 * q2 * direction(r2 - r1) / quadrance(r2 - r1)
     */
    updateForces(): Force<T>[];
    /**
     *
     */
    disconnect(): void;
    /**
     * Computes the potential energy of the gravitational interaction.
     * U = k q1 q2 / r, where
     * r is the center to center separation of m1 and m2.
     */
    potentialEnergy(): T;
}

/**
 *
 */
interface GeometricConstraint<T> {
    /**
     *
     */
    getBody(): ForceBody<T>;
    /**
     * Computes the radius of the curve.
     * @param x (input) The location at which the radius is required.
     * @param radius (output) The radius (scalar).
     */
    computeRadius(x: T, radius: T): void;
    /**
     * Computes the plane containing the rotation.
     * The orientation is ambiguous.
     * However tangent * rotation should give the direction towards the center of curvature.
     * @param x (input) The position (vector) at which the rotation is required.
     * @param plane (output) The rotation (bivector).
     */
    computeRotation(x: T, plane: T): void;
    /**
     * Computes the tangent to the wire.
     * The orientation is ambiguous.
     * However tangent * rotation should give the direction towards the center of curvature.
     * @param x (input) The position (vector) at which the tangent is required.
     * @param tangent (output) The tangent (vector).
     */
    computeTangent(x: T, tangent: T): void;
    /**
     *
     * @param N
     */
    setForce(N: T): void;
}

/**
 * @hidden
 */
interface Parameter extends SubjectEvent {
    /**
     * Sets whether the value is being automatically computed.
     * @param computed whether the value is being automatically computed.
     */
    setComputed(computed: boolean): void;
}

/**
 * @hidden
 */
declare class ParameterBoolean implements Parameter {
    private subject_;
    private name_;
    constructor(subject: Subject, name: string, getter: () => boolean, setter: (value: boolean) => unknown, choices?: string[], values?: boolean[]);
    get name(): string;
    getSubject(): Subject;
    nameEquals(name: string): boolean;
    setComputed(value: boolean): void;
}

/**
 * @hidden
 */
declare class ParameterNumber implements Parameter {
    /**
     * the Subject which provides notification of changes in this Parameter
     */
    private subject_;
    private name_;
    private getter_;
    /**
     * Fixed number of fractional decimal places to show, or -1 if variable.
     */
    private upperLimit_;
    constructor(subject: Subject, name: string, getter: () => number, setter: (value: number) => unknown, choices?: string[], values?: number[]);
    get name(): string;
    getSubject(): Subject;
    getValue(): number;
    nameEquals(name: string): boolean;
    setComputed(value: boolean): void;
    /**
     * Sets the lower limit; the Parameter value is not allowed to be less than this,
     * {@link #setValue} will throw an Error in that case.
     * @param lowerLimit the lower limit of the Parameter value
     * @return this Parameter for chaining setters
     * @throws {Error} if the value is currently less than the lower limit, or the lower limit is not a number
     */
    setLowerLimit(lowerLimit: number): this;
    /**
     * Sets suggested number of significant digits to show. This affects the number of
     * decimal places that are displayed. Examples: if significant digits is 3, then we would
     * show numbers as: 12345, 1234, 123, 12.3, 1.23, 0.123, 0.0123, 0.00123.
     * @param signifDigits suggested number of significant digits to show
     * @return this Parameter for chaining setters
     */
    setSignifDigits(signifDigits: number): this;
}

/**
 * @hidden
 */
declare class ParameterString implements Parameter {
    private subject_;
    private name_;
    private getter_;
    /**
     * suggested length of string for making a control
     */
    /**
     * maximum length of string
     */
    constructor(subject: Subject, name: string, getter: () => string, setter: (value: string) => unknown, choices?: string[], values?: string[]);
    get name(): string;
    getSubject(): Subject;
    getValue(): string;
    nameEquals(name: string): boolean;
    setComputed(value: boolean): void;
}

/**
 * @hidden
 */
interface Subject {
    /**
     * Adds the given Observer to the Subject's list of Observers, so that the
     * Observer will be notified of changes in this Subject. Does nothing if the Observer
     * is already on the list. An Observer may call `Subject.addObserver` during its
     * `observe` method.
     * @param observer the Observer to add to list of Observers
     */
    addObserver(observer: Observer): void;
    /**
     * Notifies all Observers that the Subject has changed by calling `observe` on each Observer.
     * An Observer may call `Subject.addObserver` or `Subject.removeObserver` during its `observe` method.
     * @param event a SubjectEvent with information relating to the change.
     */
    broadcast(event: SubjectEvent): void;
    /**
     * Notifies all Observers that the Parameter with the given `name` has changed by
     * calling {@link myphysicslab.lab.util.Observer#observe} on each Observer.
     * @param name the universal or English name of the Parameter that has changed
     * @throws if there is no Parameter with the given name
     */
    broadcastParameter(name: string): void;
    /**
     * Returns a copy of the list of Observers of this Subject.
     * @return a copy of the list of Observers of this Subject.
     */
    getObservers(): Observer[];
    /**
     * Returns the Parameter with the given name.
     * @param name the language-independent or English name of the Parameter
     * @return the Parameter with the given name
     * @throws {Error} if there is no Parameter with the given name
     */
    getParameter(name: string): Parameter;
    /**
     * Returns a copy of the list of this Subject's available Parameters.
     * @return a copy of the list of available Parameters for this Subject
     */
    getParameters(): Parameter[];
    /**
     * Returns the ParameterBoolean with the given name.
     * @param name the universal or English name of the ParameterBoolean
     * @return the ParameterBoolean with the given name
     * @throws if there is no ParameterBoolean with the given name
     */
    getParameterBoolean(name: string): ParameterBoolean;
    /**
     * Returns the ParameterNumber with the given name.
     * @param name the universal or English name of the ParameterNumber
     * @return the ParameterNumber with the given name
     * @throws if there is no ParameterNumber with the given name
     */
    getParameterNumber(name: string): ParameterNumber;
    /**
     * Returns the ParameterString with the given name.
     * @param name the universal or English name of the ParameterString
     * @return the ParameterString with the given name
     * @throws if there is no ParameterString with the given name
     */
    getParameterString(name: string): ParameterString;
    /**
     * Removes the Observer from the Subject's list of Observers. An Observer may
     * call `Subject.removeObserver` during its `observe` method.
     * @param observer the Observer to detach from list of Observers
     */
    removeObserver(observer: Observer): void;
}

/**
 * @hidden
 */
interface SubjectEvent {
    /**
     *
     */
    readonly name: string;
    /**
     * Returns the Subject to which this SubjectEvent refers.
     */
    getSubject(): Subject;
    /**
     *
     */
    nameEquals(name: string): boolean;
}

/**
 * @hidden
 */
interface Observer {
    observe(event: SubjectEvent): void;
}

/**
 * @hidden
 */
interface GraphVarsList {
    /**
     * Adds the given Observer to the Subject's list of Observers, so that the
     * Observer will be notified of changes in this Subject. Does nothing if the Observer
     * is already on the list. An Observer may call `Subject.addObserver` during its
     * `observe` method.
     * @param observer the Observer to add to list of Observers
     */
    addObserver(observer: Observer): void;
    /**
     *
     */
    getName(index: number): string;
    /**
     *
     */
    getValue(index: number): number;
    /**
     *
     */
    getSequence(index: number): number;
    /**
     *
     */
    numVariables(): number;
    /**
     * Removes the Observer from the Subject's list of Observers. An Observer may
     * call `Subject.removeObserver` during its `observe` method.
     * @param observer the Observer to detach from list of Observers
     */
    removeObserver(observer: Observer): void;
    /**
     *
     */
    timeIndex(): number;
}

/**
 * Represents a variable with a numeric value; usually stored in a VarsList.
 * @hidden
 */
interface Variable extends Parameter {
    /**
     * Returns whether the Variable is broadcast when it changes discontinuously.
     * @return whether the Variable is broadcast when it changes discontinuously
     */
    getBroadcast(): boolean;
    /**
     * Returns the sequence number of this Variable. The sequence number is incremented
     * whenever a discontinuity occurs in the value of the variable. For example, when the
     * variables are set back to initial conditions that is a discontinuous change. Then a
     * graph knows to not draw a connecting line between the points with the discontinuity.
     *
     * Another example of a discontinuity: if the value of an angle is kept within `0` to
     * `2*Pi` (by just adding or subtracting `2*pi` to keep it in that range), when the angle
     * crosses that boundary the sequence number should be incremented to indicate a
     * discontinuity occurred.
     * @return {number} the sequence number of this Variable.
     */
    getSequence(): number;
    /**
     * Returns the value of this variable.
     */
    getValue(): number;
    /**
     * Returns the unit of measure of this variable.
     */
    getUnit(): Unit;
    /**
     * Increments the sequence number of this Variable, which indicates that a
     * discontinuity has occurred in the value of this variable.
     *  This information is used in a graph to prevent drawing a line between points that have a discontinuity.
     */
    incrSequence(): void;
    /**
     * Sets whether the Variable is broadcast when it changes discontinuously
     * @param {boolean} value whether the Variable is broadcast when it changes discontinuously
     */
    setBroadcast(broadcast: boolean): void;
    /**
     * Sets the value of this Variable and increases the sequence number.
     */
    setValueJump(value: number): void;
    /**
     * Sets the value of this Variable without changing the sequence number which means
     * it is a 'smooth' continuous change to the variable.
     */
    setValueContinuous(value: number): void;
    /**
     * Sets the unit of measure of this variable.
     */
    setUnit(unit: Unit): void;
}

/**
 * @hidden
 */
declare class AbstractSubject implements Subject {
    /**
     *
     */
    private doBroadcast_;
    /**
     *
     */
    private observers_;
    /**
     *
     */
    private paramList_;
    /**
     * @hidden
     * @param observer
     */
    addObserver(observer: Observer): void;
    /**
     * @hidden
     * @param observer
     */
    removeObserver(observer: Observer): void;
    /**
     * Adds the Parameter to the list of this Subject's available Parameters.
     * @param parameter the Parameter to add
     * @hidden
     */
    addParameter(parameter: Parameter): void;
    /**
     * Returns the Parameter with the given name, or null if not found
     * @param name name of parameter to search for
     * @return the Parameter with the given name, or null if not found
     */
    private getParam;
    /**
     *
     * @param name
     * @returns
     * @hidden
     */
    getParameter(name: string): Parameter;
    /**
     *
     * @param name
     * @returns
     * @hidden
     */
    getParameterBoolean(name: string): ParameterBoolean;
    /**
     *
     * @param name
     * @returns
     * @hidden
     */
    getParameterNumber(name: string): ParameterNumber;
    /**
     *
     * @param name
     * @returns
     * @hidden
     */
    getParameterString(name: string): ParameterString;
    /**
     *
     * @returns
     * @hidden
     */
    getParameters(): Parameter[];
    /**
     *
     * @param event
     * @hidden
     */
    broadcast(event: SubjectEvent): void;
    /**
     *
     * @param name
     * @hidden
     */
    broadcastParameter(name: string): void;
    /**
     * Returns whether this Subject is broadcasting events.
     * @return {boolean} whether this Subject is broadcasting events
     * @hidden
     */
    protected getBroadcast(): boolean;
    /**
     * @hidden
     */
    getObservers(): Observer[];
}

declare class VarsList extends AbstractSubject implements GraphVarsList {
    /**
     * This name cannot be used as a variable name.
     */
    private static readonly DELETED;
    /**
     * This name is the reserved name for the time variable.
     */
    static readonly TIME = "TIME";
    /**
     *
     */
    private static readonly VARS_MODIFIED;
    /**
     * The zero-based index of the time variable.
     */
    private $timeIdx;
    /**
     * The variables that provide the data for this wrapper.
     */
    private $variables;
    /**
     * A lazy cache of variable values to minimize creation of temporary objects.
     * This is only synchronized when the state is requested.
     */
    private readonly $values;
    private readonly $units;
    /**
     * Whether to save simulation state history.
     */
    private history_;
    /**
     * Recent history of the simulation state for debugging.
     * An array of copies of the vars array.
     */
    private histArray_;
    /**
     * Initializes the list of variables. The names argument must contain the reserved, case-insensitive, 'time' variable.
     * @param names  array of language-independent variable names;
     * these will be underscorized so the English names can be passed in here.
     */
    constructor(names: string[]);
    /**
     * Returns index to put a contiguous group of variables.  Expands the set of variables
     * if necessary.
     * @param quantity number of contiguous variables to allocate
     * @return index of first variable
     */
    private findOpenSlot_;
    /**
     * Add a contiguous block of variables.
     * @param names language-independent names of variables; these will be
     * underscorized so the English name can be passed in here.
     * @return index index of first Variable that was added
     * @throws if any of the variable names is 'DELETED', or array of names is empty
     */
    addVariables(names: string[]): number;
    /**
     * Deletes a contiguous block of variables.
     * Delete several variables, but leaves those places in the array as empty spots that
     * can be allocated in future with `addVariables`. Until an empty spot is
     * reallocated, the name of the variable at that spot has the reserved name 'DELETED' and
     * should not be used.
     * @param index index of first variable to delete
     * @param howMany number of variables to delete
     */
    deleteVariables(index: number, howMany: number): void;
    /**
     * Increments the sequence number for the specified variable(s), which indicates a
     * discontinuity has occurred in the value of this variable. This information is used in a
     * graph to prevent drawing a line between points that have a discontinuity.
     * @param indexes  the indexes of the variables;
     * if no index given then all variable's sequence numbers are incremented
     */
    incrSequence(...indexes: number[]): void;
    /**
     * Returns the current value of the variable with the given index.
     * @param index the index of the variable of interest
     * @return the current value of the variable of interest
     */
    getValue(index: number): number;
    getName(index: number): string;
    getSequence(index: number): number;
    /**
     * Returns an array with the current value of each variable.
     * The returned array is a copy of the variable values; changing the array will not change the variable values.
     * However, for performance, the array is maintained between invocations.
     */
    getValues(): number[];
    /**
     * Sets the value of each variable from the given list of values. When the length of
     * `vars` is less than length of VarsList then the remaining variables are not modified.
     * Assumes this is a discontinous change, so the sequence number is incremented
     * unless you specify that this is a continuous change in the variable.
     * @param vars array of state variables
     * @param continuous `true` means this new value is continuous with
     * previous values; `false` (the default) means the new value is discontinuous with
     * previous values, so the sequence number for the variable is incremented
     * @throws if length of `vars` exceeds length of VarsList
     */
    setValues(vars: number[], continuous?: boolean): void;
    /**
     * @hidden
     */
    setValuesContinuous(vars: number[]): void;
    /**
     * Sets the specified variable to the given value. Variables are numbered starting at
     * zero. Assumes this is a discontinous change, so the sequence number is incremented
     * unless you specify that this is a continuous change in the variable.
     * @param index  the index of the variable within the array of variables
     * @param value  the value to set the variable to
     * @param continuous `true` means this new value is continuous with
     * previous values; `false` (the default) means the new value is discontinuous with
     * previous values, so the sequence number for the variable is incremented
     * @throws if value is `NaN`
     */
    setValue(index: number, value: number, continuous?: boolean): void;
    /**
     * @hidden
     */
    setValueContinuous(index: number, value: number): void;
    /**
     * @hidden
     */
    setValueJump(index: number, value: number): void;
    getUnits(): Unit[];
    setUnits(units: Unit[]): void;
    setUnit(index: number, unit: Unit): void;
    /**
     *
     */
    private checkIndex_;
    /**
     * Whether recent history is being stored, see `saveHistory`.
     * @return true if recent history is being stored
     */
    getHistory(): boolean;
    getParameter(name: string): Variable;
    getParameters(): Variable[];
    /**
     * Returns the value of the time variable, or throws an exception if there is no time variable.
     *
     * There are no explicit units for the time, so you can regard a time unit as any length
     * of time, as long as it is consistent with other units.
     * @return the current simulation time
     * @throws if there is no time variable
     */
    getTime(): number;
    /**
     * Returns the Variable object at the given index or with the given name
     * @param id the index or name of the variable; the name can be the
     * English or language independent version of the name
     * @return the Variable object at the given index or with the given name
     */
    getVariable(id: number | string): Variable;
    /**
     * Returns the number of variables available. This includes any deleted
     * variables (which are not being used and should be ignored).
     * @return the number of variables in this VarsList
     */
    numVariables(): number;
    /**
     * Saves the current variables in a 'history' set, for debugging, to be able to
     * reproduce an error condition. See `printHistory`.
     */
    saveHistory(): void;
    /**
     * Indicates the specified Variables are being automatically computed.
     * @param indexes  the indexes of the variables
     */
    setComputed(...indexes: number[]): void;
    /**
     * Sets whether to store recent history, see {@link #saveHistory}.
     * @param value true means recent history should be stored
     */
    setHistory(value: boolean): void;
    /**
     * Sets the current simulation time.
     * @param time the current simulation time.
     * @throws {Error} if there is no time variable
     */
    setTime(time: number): void;
    /**
     * Returns the index of the time variable, or -1 if there is no time variable.
     */
    timeIndex(): number;
    /**
     * Returns the set of Variable objects in this VarsList, in their correct ordering.
     */
    toArray(): Variable[];
}

/**
 * A handle-body pattern abstraction of the conversion of the multivector to the system state vector.
 * An implementation of this interface provides the mapping from a specific multivector implementation to a vector of state variables.
 * Each state variable is a pair consisting of (number, Unit). This decomposition allows the solvers (integrators) to treat the whole
 * system as a single particle in a large vector space.
 */
interface Kinematics<T> {
    /**
     *
     */
    speedOfLight: T;
    /**
     * The rate of change of position is the velocity (non-relativistic).
     * dX/dt = V = P / M
     * In the relativistic case,
     * dX/dt = P / sqrt(M * M + P * P), where P is the spatial part of the energy-momentum spacetime vector, M is the rest mass.
     *
     * @param rateOfChangeVals (output)
     * @param rateOfChangeUoms (output)
     * @param idx (input)
     * @param body (input)
     * @param uomTime (input)
     */
    setPositionRateOfChangeVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<T>, uomTime: Unit): void;
    /**
     * Let Ω(t) be the (bivector) angular velocity.
     * Let R(t) be the (spinor) attitude of the rigid body.
     * The rate of change of attitude is given by: dR/dt = -(1/2) Ω R,
     * requiring the geometric product of Ω and R.
     * Ω and R are auxiliary and primary variables that have already been computed.
     *
     * @param rateOfChangeVals (output)
     * @param rateOfChangeUoms (output)
     * @param idx (input)
     * @param body (input)
     * @param uomTime (input)
     */
    setAttitudeRateOfChangeVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<T>, uomTime: Unit): void;
    /**
     *
     * @param rateOfChangeVals (output)
     * @param rateOfChangeUoms (output)
     * @param idx (input)
     * @param body (input)
     * @param uomTime (input)
     */
    zeroLinearMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<T>, uomTime: Unit): void;
    /**
     *
     * @param rateOfChangeVals (output)
     * @param rateOfChangeUoms (output)
     * @param idx (input)
     * @param body (input)
     * @param uomTime (input)
     */
    zeroAngularMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<T>, uomTime: Unit): void;
    /**
     *
     * @param stateVals (input)
     * @param stateUoms (input)
     * @param idx (input)
     * @param body (output)
     * @param uomTime (input)
     */
    updateBodyFromVars(stateVals: number[], stateUoms: Unit[], idx: number, body: ForceBody<T>, uomTime: Unit): void;
    /**
     *
     * @param body (input)
     * @param idx (input)
     * @param vars (output)
     */
    updateVarsFromBody(body: ForceBody<T>, idx: number, vars: VarsList): void;
    /**
     * Adds the specified force to the rateOfChange variables for Linear Momentum.
     * @param rateOfChangeVals (input/output)
     * @param rateOfChangeUoms (input/output)
     * @param idx (input)
     * @param force (input)
     * @param uomTime (input)
     */
    addForceToRateOfChangeLinearMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: T, uomTime: Unit): void;
    /**
     * Use when applying geometric constraints.
     * @param rateOfChangeVals (input)
     * @param rateOfChangeUoms (input)
     * @param idx (input)
     * @param force (output)
     */
    getForce(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: T): void;
    /**
     * Used when applying geometric constraints.
     * @param rateOfChangeVals (output)
     * @param rateOfChangeUoms (output)
     * @param idx (input)
     * @param force (input)
     */
    setForce(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: T): void;
    /**
     * Adds the specified torque to the rateOfChange variables for AngularMomentum.
     * @param rateOfChangeVals (input/output)
     * @param rateOfChangeUoms (input/output)
     * @param idx (input)
     * @param torque (input)
     * @param uomTime (input)
     */
    addTorqueToRateOfChangeAngularMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, torque: T, uomTime: Unit): void;
    /**
     * Called by the Physics Engine during the epilog.
     * @param bodies (input) Provides intrinsic kinetic energy.
     * @param forceLaws (input) Provides potential energy.
     * @param potentialOffset  (input) Provides a an offset in the potential energy.
     * @param vars (output) The list of variables containing the summary variables to be updated.
     */
    epilog(bodies: ForceBody<T>[], forceLaws: ForceLaw<T>[], potentialOffset: T, vars: VarsList): void;
    /**
     * Called by the Physics Engine to determine the indices of all the variables that are affected by a
     * discontinuous change to the energy of the system. i.e., an "intervention" where the bodies in the
     * system are changed independently of the differential equations that are implemented by the Physics Engine.
     * @returns The indices into the variables list.
     */
    discontinuousEnergyVars(): number[];
    /**
     * Used by the Physics engine when adding a body to the system.
     * Returns the name of the kinematic variable at the specified index which
     * ranges over [0, numVarsPerBody - 1].
     *
     * The name must be valid (isValidName) after having being munged (toName).
     */
    getOffsetName(offset: number): string;
    /**
     * Used by the Physics class constructor to create a list of variables.
     * One of the names returned must be the (case-sensitive) "TIME" variable.
     */
    getVarNames(): string[];
    /**
     * Use by the Physics engine to add the correct number of variables for each body added.
     * The number of variables must be at least one.
     */
    numVarsPerBody(): number;
}

/**
 * @hidden
 */
declare class SimList extends AbstractSubject {
    /**
     *
     */
    static OBJECT_ADDED: string;
    /**
     *
     */
    static OBJECT_REMOVED: string;
    /**
     *
     */
    private $elements;
    /**
     *
     */
    constructor();
    /**
     *
     */
    add(element: SimObject): void;
    /**
     *
     */
    forEach(callBack: (simObject: SimObject, index: number) => unknown): void;
    /**
     *
     */
    remove(simObject: SimObject): void;
    /**
     * Removes SimObjects from this SimList whose *expiration time* is less than the given time.
     * Notifies Observers by broadcasting the `OBJECT_REMOVED` event for each SimObject removed.
     * @param time the current simulation time
     */
    removeTemporary(time: number): void;
}

/**
 *
 */
interface EngineOptions {
    method?: 'rk4';
}
/**
 * A generic Physics Engine that may be specialized to a metric.
 */
declare class Engine<T> {
    private readonly kinematics;
    private readonly physics;
    private readonly strategy;
    /**
     *
     * @param metric
     * @param kinematics
     * @param options
     */
    constructor(metric: Metric<T>, kinematics: Kinematics<T>, options?: Partial<EngineOptions>);
    /**
     * The speed of light.
     * For dimensionless simulations this will default to 1.
     * For S.I. Units, the speed of light may be set.
     */
    get speedOfLight(): T;
    set speedOfLight(speedOfLight: T);
    get bodies(): ForceBody<T>[];
    /**
     * Returns the state variables of the system.
     */
    get varsList(): VarsList;
    get simList(): SimList;
    /**
     * Adds a body to the system.
     * The state variables of the body will become part of the state vector of the system.
     * The state variables of the body will be updated each time the system is advanced in time.
     * @param body The body to be added to the system
     */
    addBody(body: ForceBody<T>): void;
    /**
     * Removes a body from the system.
     * @param body The body to be removed from the system.
     */
    removeBody(body: ForceBody<T>): void;
    /**
     * Adds a force law to the system.
     * @param forceLaw The force law to be added to the system.
     */
    addForceLaw(forceLaw: ForceLaw<T>): void;
    /**
     * Removes a force law from the system.
     * @param forceLaw The force law to be removed.
     */
    removeForceLaw(forceLaw: ForceLaw<T>): void;
    /**
     * Adds a torque law to the system.
     * @param torqueLaw The torque law to be added to the system.
     */
    addTorqueLaw(torqueLaw: TorqueLaw<T>): void;
    /**
     * Removes a torque law from the system.
     * @param torqueLaw The torque law to be removed from the system.
     */
    removeTorqueLaw(torqueLaw: TorqueLaw<T>): void;
    /**
     * Adds a geometric constraint to the system.
     * Geometric constraints are applied after the force and torques have been computed and before drift forces and torques.
     * @param geometry The geometric constraint to be added to the system.
     */
    addConstraint(geometry: GeometricConstraint<T>): void;
    /**
     * Removes a geometric constraint from the system.
     * @param geometry The geometric constraint to be removed from the system.
     */
    removeConstraint(geometry: GeometricConstraint<T>): void;
    /**
     * Adds a force law that is designed to compensate for numerical drift in the system.
     * A drift law is usually small and may take the form of a spring and/or damping force.
     * The drift laws are applied after any geometric constraints have been applied.
     * @param driftLaw The drift force law to be applied.
     */
    addDriftLaw(driftLaw: ForceLaw<T>): void;
    /**
     * Removes a force law that is designed to compensate for numerical drift in the system.
     * @param driftLaw The drift force law to be removed.
     */
    removeDriftLaw(driftLaw: ForceLaw<T>): void;
    /**
     * Advances the Physics model by the specified time interval, Δt * uomTime.
     * @param Δt The time interval.
     * @param uomTime The optional unit of measure for the time interval.
     */
    advance(Δt: number, uomTime?: Unit): void;
    /**
     * Updates the state vector of the simulation from the states of the bodies in the system.
     * It is necessary to call this method after an intervention which changes the state of
     * a body in the system.
     */
    updateFromBodies(): void;
    /**
     *
     * @returns The total energy (kinetic and potential) of the system.
     */
    totalEnergy(): T;
    get showForces(): boolean;
    set showForces(showForces: boolean);
    get showTorques(): boolean;
    set showTorques(showTorques: boolean);
}

declare class FaradayLaw<T> extends AbstractSimObject implements ForceLaw<T> {
    private body;
    private field;
    private readonly force;
    private readonly $forces;
    /**
     * force = Q * (v << F), where Q is the body charge, v is the ordinary spacetime velocity, F is the Faraday field at the body location.
     * @param body the body upon which the field acts.
     * @param field the Faraday field. This field that has a bivector value.
     */
    constructor(body: Charged<T>, field: (position: T) => T);
    get forces(): Force<T>[];
    updateForces(): Force<T>[];
    disconnect(): void;
    potentialEnergy(): T;
}

/**
 * A ForceBody with a mass property, M.
 */
interface Massive<T> extends ForceBody<T> {
    M: T;
}

/**
 *
 */
declare class GravitationLaw<T> extends AbstractSimObject implements ForceLaw<T> {
    private body1;
    private body2;
    /**
     * The proportionality constant, Universal gravitational constant or Newton's constant.
     * The default value is one (1).
     */
    private readonly $G;
    private readonly F1;
    private readonly F2;
    private readonly $forces;
    /**
     * Scratch variable for computing potential energy.
     */
    private readonly potentialEnergy_;
    private potentialEnergyLock_;
    private readonly metric;
    /**
     *
     */
    constructor(body1: Massive<T>, body2: Massive<T>);
    get G(): T;
    set G(G: T);
    get forces(): Force<T>[];
    /**
     * Computes the forces due to the gravitational interaction.
     * F = G * m1 * m2 * direction(r2 - r1) / quadrance(r2 - r1)
     */
    updateForces(): Force<T>[];
    /**
     *
     */
    disconnect(): void;
    /**
     * Computes the potential energy of the gravitational interaction.
     * U = -G m1 m2 / r, where
     * r is the center-of-mass to center-of-mass separation of m1 and m2.
     */
    potentialEnergy(): T;
}

/**
 *
 */
declare class LinearDamper<T> extends AbstractSimObject implements ForceLaw<T> {
    private readonly body1;
    private readonly body2;
    /**
     * Friction Coefficient.
     */
    private $frictionCoefficient;
    /**
     * The force information on body1 due to body2.
     */
    private readonly F1;
    /**
     * The force information on body2 due to body1.
     */
    private readonly F2;
    /**
     *
     */
    private readonly $forces;
    /**
     *
     * @param body1
     * @param body2
     */
    constructor(body1: ForceBody<T>, body2: ForceBody<T>);
    get forces(): Force<T>[];
    get b(): T;
    set b(b: T);
    get frictionCoefficient(): T;
    set frictionCoefficient(frictionCoefficient: T);
    updateForces(): Force<T>[];
    disconnect(): void;
    potentialEnergy(): T;
}

/**
 *
 */
declare class RigidBody<T> extends AbstractSimObject implements ForceBody<T>, Massive<T>, Charged<T> {
    readonly metric: Metric<T>;
    /**
     * A uniquie identifier assigned by applications.
     * This is not used internally.
     */
    uuid: string;
    /**
     * Mass, M. Default is one (1).
     * Changing the mass requires an update to the inertia tensor,
     * so we want to control the mutability. The mass is locked by default
     */
    private readonly $mass;
    /**
     * Charge, Q. Default is zero (0).
     */
    private readonly $charge;
    /**
     * Inverse of the Inertia tensor in body coordinates.
     */
    private $inertiaTensorInverse;
    /**
     * the index into the variables array for this rigid body, or -1 if not in vars array.
     */
    private varsIndex_;
    /**
     * The position (vector).
     */
    private readonly $X;
    /**
     * The attitude (spinor).
     */
    private readonly $R;
    /**
     * The linear momentum (vector).
     */
    private readonly $P;
    /**
     * The angular momentum (bivector).
     */
    private readonly $L;
    /**
     * Scratch member variable used only during updateAngularVelocity.
     * The purpose is to avoid temporary object creation.
     */
    private Ω_scratch;
    /**
     * Angular velocity (bivector).
     * The angular velocity is initially created in the unlocked state.
     */
    private $Ω;
    /**
     * center of mass in local coordinates.
     */
    private $centerOfMassLocal;
    /**
     * Scratch variable for rotational energy.
     */
    private $rotationalEnergy;
    /**
     * Scratch variable for translational energy.
     */
    private $translationalEnergy;
    /**
     * Scratch variable for calculation worldPoint.
     */
    private readonly $worldPoint;
    /**
     * @param metric
     */
    constructor(metric: Metric<T>);
    /**
     * The center of mass position vector in local coordinates.
     */
    get centerOfMassLocal(): T;
    set centerOfMassLocal(centerOfMassLocal: T);
    /**
     * Mass (scalar). Default is one (1).
     * If dimensioned units are used, they must be compatible with the unit of mass.
     * M is immutable but the property may be reassigned.
     */
    get M(): T;
    set M(M: T);
    /**
     * Charge (scalar). Default is zero (0).
     * If dimensioned units are used, they must be compatible with the unit of electric charge.
     * Q is immutable but the property may be reassigned.
     */
    get Q(): T;
    set Q(Q: T);
    /**
     * Updates the angular velocity, Ω, bivector based upon the angular momentum.
     * Derived classes may override to provide more efficient implementations based upon symmetry.
     */
    updateAngularVelocity(): void;
    /**
     * Derived classes should override.
     */
    protected updateInertiaTensor(): void;
    /**
     * Inertia Tensor (in body coordinates) (3x3 matrix).
     * The returned matrix is a copy.
     * TODO: This copy should be locked.
     */
    get I(): MatrixLike;
    /**
     * Sets the Inertia Tensor (in local coordinates) (3x3 matrix), and computes the inverse.
     */
    set I(I: MatrixLike);
    /**
     * Inertia Tensor (in body coordinates) inverse (3x3 matrix).
     */
    get Iinv(): MatrixLike;
    set Iinv(source: MatrixLike);
    /**
     * Position (vector).
     * If dimensioned units are used, they must be compatible with the unit of length.
     * X is mutable with copy-on-set.
     */
    get X(): T;
    set X(position: T);
    /**
     * Attitude (spinor).
     * Effects a rotation from local coordinates to world coordinates.
     * R is mutable with copy-on-set.
     */
    get R(): T;
    set R(attitude: T);
    /**
     * Linear momentum (vector).
     * If dimensioned units are used, they must be compatible with the unit of momentum.
     * P is mutable with copy-on-set.
     */
    get P(): T;
    set P(linearMomentum: T);
    /**
     * Angular momentum (bivector) in world coordinates.
     * If dimensioned units are used, they must be compatible with the unit of angular momentum.
     * L is mutable with copy-on-set.
     */
    get L(): T;
    set L(angularMomentum: T);
    /**
     * Angular velocity (bivector).
     * If dimensioned units are used, they must be compatible with the unit of angular velocity.
     * Ω is mutable with copy-on-set.
     */
    get Ω(): T;
    set Ω(angularVelocity: T);
    /**
     *
     */
    get expireTime(): number;
    /**
     * @hidden
     */
    get varsIndex(): number;
    set varsIndex(index: number);
    /**
     * In the following formula, notice the reversion on either Ω or L.
     * Geometrically, this means we depend on the cosine of the angle between the bivectors, since
     * A * ~B = |A||B|cos(...).
     * (1/2) Ω * ~L(Ω) = (1/2) ~Ω * L(Ω) = (1/2) ω * J(ω), where * means scalar product (equals dot product for vectors).
     */
    rotationalEnergy(): T;
    /**
     * (1/2) (P * P) / M
     */
    translationalEnergy(): T;
    /**
     * Converts a point in local coordinates to the same point in world coordinates.
     * x = R (localPoint - centerOfMassLocal) * ~R + X
     *
     * @param localPoint (input)
     * @param worldPoint (output)
     */
    localPointToWorldPoint(localPoint: T, worldPoint: T): void;
}

/**
 * An object with no internal structure.
 * @hidden
 */
declare class Particle<T> extends RigidBody<T> {
    /**
     * @param M The mass of the particle. The mass is copied into the `M` property. Default is 1 (dimensionless).
     * @param Q The electric charge of the particle. The charge is copied into the `Q` property. Default is 1 (dimensionless).
     */
    constructor(M: T | undefined, Q: T | undefined, metric: Metric<T>);
    /**
     *
     */
    updateAngularVelocity(): void;
    /**
     *
     */
    protected updateInertiaTensor(): void;
}

/**
 * @hidden
 */
interface EnergySystem<T> {
    readonly metric: Metric<T>;
    totalEnergy(): T;
}

/**
 * @hidden
 */
interface DiffEqSolverSystem {
    /**
     * Gets the state vector, Y(t). This method will be the first method called by the solver.
     */
    getState(): number[];
    getUnits(): Unit[];
    /**
     * Computes the derivatives of the state variables based upon the specified state.
     * This will be the second method called by the solver.
     * @param state (input) The configuration estimated by the solver as a state vector, Y(t + Δt * uomTime).
     * @param stateUnits (input)
     * @param rateOfChange (output) The computed derivatives of the state variables.
     * @param rateOfChangeUnits (output) The units of measure of the derivatives of the state variables.
     * @param Δt (input) The displacement from the start of the step.
     * @param uomTime (input) The unit of measure for Δt.
     */
    evaluate(state: number[], stateUnits: Unit[], rateOfChange: number[], rateOfChangeUnits: Unit[], Δt: number, uomTime?: Unit): void;
    /**
     * Sets the state vector, Y(t).
     * This method will be the third method called by the solver.
     */
    setState(state: number[]): void;
    setUnits(units: Unit[]): void;
    /**
     * Enables the solver to report errors in terms of the variable name.
     * @param idx
     */
    getVariableName(idx: number): string;
}

/**
 * @hidden
 */
interface Simulation extends DiffEqSolverSystem {
    /**
     *
     */
    readonly time: number;
    /**
     * Handler for actions to be performed before getState and the evaluate calls.
     * A simulation may remove temporary simulation objects, such as forces, from
     * the list of simulation objects. This method will normally be called by the strategy.
     */
    prolog(stepSize: number, uomStep?: Unit): void;
    /**
     * Handler for actions to be performed after the evaluate calls and setState.
     * Computes the system energy, linear momentum and angular momentum.
     * This method will normally be called by the strategy.
     */
    epilog(stepSize: number, uomStep?: Unit): void;
}

/**
 * The Physics engine computes the derivatives of the kinematic variables X, R, P, J for each body,
 * based upon the state of the system and the known forces, torques, masses, and moments of inertia.
 * @hidden
 */
declare class Physics<T> extends AbstractSubject implements Simulation, EnergySystem<T> {
    readonly metric: Metric<T>;
    private readonly kinematics;
    /**
     *
     */
    private readonly $simList;
    /**
     * The list of variables represents the current state of the simulation.
     */
    private readonly $varsList;
    /**
     * The RigidBody(s) in this simulation.
     */
    private readonly $bodies;
    /**
     *
     */
    private readonly $forceLaws;
    /**
     *
     */
    private readonly $torqueLaws;
    /**
     *
     */
    private readonly $constraints;
    /**
     *
     */
    private readonly $driftLaws;
    /**
     *
     */
    private $showForces;
    /**
     *
     */
    private $showTorques;
    /**
     * Scratch variavle for computing a potential energy offset.
     */
    private readonly $potentialOffset;
    /**
     * Scratch variable for computing force.
     */
    private readonly $force;
    /**
     * Scratch variable for computing torque.
     */
    private readonly $torque;
    /**
     * Scratch variable for computing total energy.
     */
    private readonly $totalEnergy;
    private $totalEnergyLock;
    /**
     * We should be able to calculate this from the dimensionality?
     */
    private readonly $numVariablesPerBody;
    /**
     * Constructs a Physics engine for 3D simulations.
     */
    constructor(metric: Metric<T>, kinematics: Kinematics<T>);
    getVariableName(idx: number): string;
    /**
     * Determines whether calculated forces will be added to the simulation list.
     */
    get showForces(): boolean;
    set showForces(showForces: boolean);
    /**
     * Determines whether calculated torques will be added to the simulation list.
     */
    get showTorques(): boolean;
    set showTorques(showTorques: boolean);
    /**
     *
     */
    addBody(body: ForceBody<T>): void;
    /**
     *
     */
    removeBody(body: ForceBody<T>): void;
    /**
     *
     */
    addForceLaw(forceLaw: ForceLaw<T>): void;
    /**
     *
     */
    removeForceLaw(forceLaw: ForceLaw<T>): void;
    /**
     *
     */
    addTorqueLaw(torqueLaw: TorqueLaw<T>): void;
    /**
     *
     */
    removeTorqueLaw(torqueLaw: TorqueLaw<T>): void;
    /**
     *
     */
    addConstraint(geometry: GeometricConstraint<T>): void;
    /**
     *
     * @param geometry
     */
    removeConstraint(geometry: GeometricConstraint<T>): void;
    /**
     *
     */
    addDriftLaw(driftLaw: ForceLaw<T>): void;
    /**
     *
     */
    removeDriftLaw(driftLaw: ForceLaw<T>): void;
    private discontinuousChangeToEnergy;
    /**
     * Transfer state vector back to the rigid bodies.
     * Also takes care of updating auxiliary variables, which are also mutable.
     */
    private updateBodiesFromStateVariables;
    /**
     * Handler for actions to be performed before the evaluate calls.
     * The physics engine removes objects that were temporarily added to the simulation
     * list but have expired.
     * @hidden
     */
    prolog(): void;
    /**
     * Gets the state vector, Y(t).
     * The returned array is a copy of the state vector variable values.
     * However, for performance, the array is maintained between invocations.
     * @hidden
     */
    getState(): number[];
    /**
     * Sets the state vector, Y(t).
     * @hidden
     */
    setState(state: number[]): void;
    getUnits(): Unit[];
    setUnits(units: Unit[]): void;
    /**
     * The time value is not being used because the DiffEqSolver has updated the vars?
     * This will move the objects and forces will be recalculated.u
     * @hidden
     */
    evaluate(state: number[], stateUnits: Unit[], rateOfChangeVals: number[], rateOfChangeUoms: Unit[], Δt: number, uomTime?: Unit): void;
    /**
     *
     * @param rateOfChange (output)
     * @param rateOfChangeUnits (output)
     * @param Δt
     * @param uomTime
     */
    private applyForceLaws;
    private applyDriftLaws;
    /**
     * Applying forces gives rise to linear and angular momentum.
     * @param rateOfChangeVals (output)
     * @param rateOfChangeUoms (output)
     * @param forceApp The force application which results in a rate of change of linear and angular momentum
     */
    private applyForce;
    private applyTorqueLaws;
    /**
     *
     * @param rateOfChangeVals (input/output)
     * @param rateOfChangeUoms (input/output)
     * @param torqueApp
     * @param Δt
     * @param uomTime
     * @returns
     */
    private applyTorque;
    private applyConstraints;
    private applyConstraint;
    /**
     *
     */
    get time(): number;
    /**
     *
     */
    updateFromBodies(): void;
    /**
     *
     */
    private updateVarsFromBody;
    /**
     * Handler for actions to be performed after the evaluate calls and setState.
     * Computes the system energy, linear momentum and angular momentum.
     * @hidden
     */
    epilog(stepSize: number, uomTime?: Unit): void;
    /**
     * Provides a reference to the bodies in the simulation.
     */
    get bodies(): ForceBody<T>[];
    /**
     * @hidden
     */
    get simList(): SimList;
    /**
     * @hidden
     */
    get varsList(): VarsList;
    /**
     * Computes the sum of the translational and rotational kinetic energy of all bodies,
     * and the potential energy due to body interactions for the force laws.
     */
    totalEnergy(): T;
}

/**
 *
 */
declare class Spring<T> extends AbstractSimObject implements ForceLaw<T> {
    private readonly body1;
    private readonly body2;
    /**
     *
     */
    private $restLength;
    private $restLengthLock;
    /**
     * Spring Constant.
     */
    private readonly $springConstant;
    /**
     * The attachment point to body1 in the local coordinates frame of body 1.
     */
    private attach1_;
    private attach1Lock;
    /**
     * The attachment point to body2 in the local coordinates frame of body 2.
     */
    private attach2_;
    private attach2Lock;
    /**
     * The force information on body1 due to body2.
     */
    private readonly F1;
    /**
     * The force information on body2 due to body1.
     */
    private readonly F2;
    /**
     *
     */
    private readonly $forces;
    /**
     * Scratch variable for computing endpoint in world coordinates.
     */
    private readonly end1_;
    private end1Lock_;
    /**
     * Scratch variable for computing endpoint in world coordinates.
     */
    private readonly end2_;
    private end2Lock_;
    /**
     * Scratch variable for computing potential energy.
     */
    private readonly potentialEnergy_;
    private potentialEnergyLock_;
    readonly metric: Metric<T>;
    /**
     *
     */
    constructor(body1: RigidBody<T>, body2: RigidBody<T>);
    get forces(): Force<T>[];
    get restLength(): T;
    set restLength(restLength: T);
    get k(): T;
    set k(k: T);
    get springConstant(): T;
    set springConstant(springConstant: T);
    get stiffness(): T;
    set stiffness(stiffness: T);
    /**
     * @param x (output)
     */
    private computeBody1AttachPointInWorldCoords;
    private computeBody2AttachPointInWorldCoords;
    get attach1(): T;
    set attach1(attach1: T);
    get attach2(): T;
    set attach2(attach2: T);
    get end1(): T;
    get end2(): T;
    /**
     *
     */
    updateForces(): Force<T>[];
    /**
     *
     */
    disconnect(): void;
    /**
     *
     */
    potentialEnergy(): T;
}

declare class RigidBody1 extends RigidBody<Geometric1> {
    constructor();
}

declare class Block1 extends RigidBody1 {
    private readonly $width;
    constructor(width: Geometric1);
    get width(): Geometric1;
    set width(width: Geometric1);
}

/**
 * @deprecated Use ConstantForceLaw.
 * @hidden
 */
declare class ConstantForceLaw1 extends ConstantForceLaw<Geometric1> {
    constructor(body: ForceBody<Geometric1>, vector: Geometric1, vectorCoordType?: CoordType);
}

/**
 * @deprecated Use ConstantTorqueLaw.
 * @hidden
 */
declare class ConstantTorqueLaw1 extends ConstantTorqueLaw<Geometric1> {
    constructor(body: ForceBody<Geometric1>, value: Geometric1);
}

/**
 * The Physics Engine specialized to 1 dimension with a Euclidean metric.
 */
declare class Engine1 extends Engine<Geometric1> {
    constructor(options?: EngineOptions);
}

/**
 *
 */
declare class Force1 extends Force<Geometric1> {
    constructor(body: ForceBody<Geometric1>);
}

/**
 * @hidden
 */
declare class KinematicsG10 implements Kinematics<Geometric1> {
    private $speedOfLight;
    get speedOfLight(): Geometric1;
    set speedOfLight(speedOfLight: Geometric1);
    setPositionRateOfChangeVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric1>, uomTime: Unit): void;
    setAttitudeRateOfChangeVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric1>, uomTime: Unit): void;
    zeroLinearMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric1>, uomTime: Unit): void;
    zeroAngularMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric1>, uomTime: Unit): void;
    updateBodyFromVars(vars: number[], units: Unit[], idx: number, body: ForceBody<Geometric1>, uomTime: Unit): void;
    updateVarsFromBody(body: ForceBody<Geometric1>, idx: number, vars: VarsList): void;
    addForceToRateOfChangeLinearMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric1, uomTime: Unit): void;
    getForce(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric1): void;
    setForce(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric1): void;
    addTorqueToRateOfChangeAngularMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, torque: Geometric1, uomTime: Unit): void;
    epilog(bodies: ForceBody<Geometric1>[], forceLaws: ForceLaw<Geometric1>[], potentialOffset: Geometric1, vars: VarsList): void;
    discontinuousEnergyVars(): number[];
    getOffsetName(offset: number): string;
    getVarNames(): string[];
    numVarsPerBody(): number;
}

/**
 * @deprecated Use LinearDamper.
 * @hidden
 */
declare class LinearDamper1 extends LinearDamper<Geometric1> {
    constructor(body1: RigidBody<Geometric1>, body2: RigidBody<Geometric1>);
}

/**
 * @hidden
 */
declare class MetricG10 implements Metric<Geometric1> {
    get e0(): Geometric1;
    a(mv: Geometric1): number;
    add(lhs: Geometric1, rhs: Geometric1): Geometric1;
    addScalar(lhs: Geometric1, a: number, uom?: Unit): Geometric1;
    addVector(lhs: Geometric1, rhs: Geometric1): Geometric1;
    applyMatrix(mv: Geometric1, matrix: MatrixLike): Geometric1;
    clone(source: Geometric1): Geometric1;
    copy(source: Geometric1, target: Geometric1): Geometric1;
    copyBivector(source: Geometric1, target: Geometric1): Geometric1;
    copyMatrix(m: MatrixLike): MatrixLike;
    copyScalar(a: number, uom: Unit, target: Geometric1): Geometric1;
    copyVector(source: Geometric1, target: Geometric1): Geometric1;
    createForce(body: ForceBody<Geometric1>): Force<Geometric1>;
    createTorque(body: ForceBody<Geometric1>): Torque<Geometric1>;
    direction(mv: Geometric1): Geometric1;
    divByScalar(lhs: Geometric1, a: number, uom?: Unit): Geometric1;
    ext(lhs: Geometric1, rhs: Geometric1): Geometric1;
    identityMatrix(): MatrixLike;
    invertMatrix(m: MatrixLike): MatrixLike;
    isBivector(mv: Geometric1): boolean;
    isOne(mv: Geometric1): boolean;
    isScalar(mv: Geometric1): boolean;
    isSpinor(mv: Geometric1): boolean;
    isVector(mv: Geometric1): boolean;
    isZero(mv: Geometric1): boolean;
    lco(lhs: Geometric1, rhs: Geometric1): Geometric1;
    lock(mv: Geometric1): number;
    norm(mv: Geometric1): Geometric1;
    mul(lhs: Geometric1, rhs: Geometric1): Geometric1;
    mulByNumber(lhs: Geometric1, alpha: number): Geometric1;
    mulByScalar(lhs: Geometric1, a: number, uom?: Unit): Geometric1;
    mulByVector(lhs: Geometric1, rhs: Geometric1): Geometric1;
    neg(mv: Geometric1): Geometric1;
    squaredNorm(mv: Geometric1): Geometric1;
    rco(lhs: Geometric1, rhs: Geometric1): Geometric1;
    rev(mv: Geometric1): Geometric1;
    rotate(mv: Geometric1, spinor: Geometric1): Geometric1;
    scalar(a: number, uom?: Unit): Geometric1;
    scp(lhs: Geometric1, rhs: Geometric1): Geometric1;
    setUom(mv: Geometric1, uom: Unit): void;
    sub(lhs: Geometric1, rhs: Geometric1): Geometric1;
    subScalar(lhs: Geometric1, a: number, uom?: Unit): Geometric1;
    subVector(lhs: Geometric1, rhs: Geometric1): Geometric1;
    unlock(mv: Geometric1, token: number): void;
    uom(mv: Geometric1): Unit;
    write(source: Geometric1, target: Geometric1): void;
    writeVector(source: Geometric1, target: Geometric1): void;
    /**
     * This doesn't happen in 1D because there are no bivectors.
     */
    writeBivector(source: Geometric1, target: Geometric1): void;
}

declare class Particle1 extends Particle<Geometric1> {
    /**
     * Constructs a particle in 1 Euclidean dimension.
     * @param M The mass of the particle. Default is 1 (dimensionless).
     * @param Q The charge of the particle. Default is 1 (dimensionless).
     */
    constructor(M?: Geometric1, Q?: Geometric1);
}

/**
 * @hidden
 */
declare class Physics1 extends Physics<Geometric1> implements EnergySystem<Geometric1> {
    constructor();
}

/**
 * @deprecated Use Spring.
 * @hidden
 */
declare class Spring1 extends Spring<Geometric1> {
    constructor(body1: RigidBody<Geometric1>, body2: RigidBody<Geometric1>);
}

/**
 * The Physics Engine specialized to 1+1 dimensions with a Spacetime metric.
 */
declare class EngineG11 extends Engine<Spacetime1> {
    constructor(options?: EngineOptions);
}

/**
 *
 */
declare class ForceG11 extends Force<Spacetime1> {
    constructor(body: ForceBody<Spacetime1>);
}

declare class ParticleG11 extends Particle<Spacetime1> {
    /**
     * Constructs a particle in 2 Euclidean dimensions.
     * @param M The mass of the particle. Default is 1 (dimensionless).
     * @param Q The charge of the particle. Default is 1 (dimensionless).
     */
    constructor(M?: Spacetime1, Q?: Spacetime1);
}

/**
 *
 */
declare class RigidBody2 extends RigidBody<Geometric2> {
    constructor();
    /**
     *
     */
    updateAngularVelocity(): void;
}

/**
 * A rectangular block of constant surface density.
 */
declare class Block2 extends RigidBody2 {
    /**
     * The dimension corresponding to the width.
     */
    private readonly width_;
    private widthLock_;
    /**
     * The dimension corresponding to the height.
     */
    private readonly height_;
    private heightLock_;
    /**
     *
     */
    constructor(width?: Geometric2, height?: Geometric2);
    get width(): Geometric2;
    set width(width: Geometric2);
    get height(): Geometric2;
    set height(height: Geometric2);
    /**
     * The angular velocity is updated from the angular momentum.
     * Ω = 12 * L * (1/M) * 1 / (h^2+w^2)
     */
    updateAngularVelocity(): void;
    /**
     * Whenever the mass or the dimensions change, we must update the inertia tensor.
     * L = J(Ω) = (1/12) * M * (h^2 + w^2) * Ω
     */
    protected updateInertiaTensor(): void;
}

/**
 * @deprecated Use ConstantForceLaw.
 * @hidden
 */
declare class ConstantForceLaw2 extends ConstantForceLaw<Geometric2> {
    constructor(body: ForceBody<Geometric2>, vector: Geometric2, vectorCoordType?: CoordType);
}

/**
 * @deprecated Use ConstantTorqueLaw.
 * @hidden
 */
declare class ConstantTorqueLaw2 extends ConstantTorqueLaw<Geometric2> {
    constructor(body: ForceBody<Geometric2>, value: Geometric2);
}

/**
 * A solid disk of uniform surface density.
 */
declare class Disc2 extends RigidBody2 {
    /**
     * The dimension corresponding to the width.
     */
    private readonly radius_;
    private radiusLock_;
    /**
     *
     */
    constructor(radius?: Geometric2);
    get radius(): Geometric2;
    set radius(radius: Geometric2);
    /**
     * L = J(Ω) = (1/2) M R^2 Ω => Ω = 2 * L * (1/M) * (1/R)^2
     */
    updateAngularVelocity(): void;
    /**
     * Whenever the mass or the dimensions change, we must update the inertia tensor.
     * I = (1/2) M * R^2
     */
    protected updateInertiaTensor(): void;
}

/**
 * The Physics Engine specialized to 2 dimensions with a Euclidean metric.
 */
declare class Engine2 extends Engine<Geometric2> {
    constructor(options?: EngineOptions);
}

/**
 * @hidden
 */
declare class Euclidean2 implements Metric<Geometric2> {
    get e0(): Geometric2;
    a(mv: Geometric2): number;
    add(lhs: Geometric2, rhs: Geometric2): Geometric2;
    addScalar(lhs: Geometric2, a: number, uom?: Unit): Geometric2;
    addVector(lhs: Geometric2, rhs: Geometric2): Geometric2;
    applyMatrix(mv: Geometric2, matrix: MatrixLike): Geometric2;
    clone(source: Geometric2): Geometric2;
    copy(source: Geometric2, target: Geometric2): Geometric2;
    copyBivector(source: Geometric2, target: Geometric2): Geometric2;
    copyMatrix(m: MatrixLike): MatrixLike;
    copyVector(source: Geometric2, target: Geometric2): Geometric2;
    copyScalar(a: number, uom: Unit, target: Geometric2): Geometric2;
    createForce(body: ForceBody<Geometric2>): Force<Geometric2>;
    createTorque(body: ForceBody<Geometric2>): Torque<Geometric2>;
    direction(mv: Geometric2): Geometric2;
    divByScalar(lhs: Geometric2, a: number, uom?: Unit): Geometric2;
    identityMatrix(): MatrixLike;
    invertMatrix(m: MatrixLike): MatrixLike;
    isBivector(mv: Geometric2): boolean;
    isOne(mv: Geometric2): boolean;
    isScalar(mv: Geometric2): boolean;
    isSpinor(mv: Geometric2): boolean;
    isVector(mv: Geometric2): boolean;
    isZero(mv: Geometric2): boolean;
    lco(lhs: Geometric2, rhs: Geometric2): Geometric2;
    lock(mv: Geometric2): number;
    norm(mv: Geometric2): Geometric2;
    mul(lhs: Geometric2, rhs: Geometric2): Geometric2;
    mulByNumber(lhs: Geometric2, alpha: number): Geometric2;
    mulByScalar(lhs: Geometric2, a: number, uom: Unit): Geometric2;
    mulByVector(lhs: Geometric2, rhs: Geometric2): Geometric2;
    neg(mv: Geometric2): Geometric2;
    squaredNorm(mv: Geometric2): Geometric2;
    rco(lhs: Geometric2, rhs: Geometric2): Geometric2;
    rev(mv: Geometric2): Geometric2;
    rotate(mv: Geometric2, spinor: Geometric2): Geometric2;
    scalar(a: number, uom?: Unit): Geometric2;
    scp(lhs: Geometric2, rhs: Geometric2): Geometric2;
    setUom(mv: Geometric2, uom: Unit): void;
    sub(lhs: Geometric2, rhs: Geometric2): Geometric2;
    subScalar(lhs: Geometric2, a: number, uom?: Unit): Geometric2;
    subVector(lhs: Geometric2, rhs: Geometric2): Geometric2;
    unlock(mv: Geometric2, token: number): void;
    uom(mv: Geometric2): Unit;
    ext(lhs: Geometric2, rhs: Geometric2): Geometric2;
    write(source: Geometric2, target: Geometric2): void;
    writeVector(source: Geometric2, target: Geometric2): void;
    writeBivector(source: Geometric2, target: Geometric2): void;
}

/**
 *
 */
declare class Force2 extends Force<Geometric2> {
    constructor(body: ForceBody<Geometric2>);
}

/**
 * @deprecated Use GravitationLaw.
 * @hidden
 */
declare class GravitationForceLaw2 extends GravitationLaw<Geometric2> {
    constructor(body1: Massive<Geometric2>, body2: Massive<Geometric2>);
}

/**
 * @hidden
 */
declare class KinematicsG20 implements Kinematics<Geometric2> {
    private $speedOfLight;
    get speedOfLight(): Geometric2;
    set speedOfLight(speedOfLight: Geometric2);
    numVarsPerBody(): number;
    getVarNames(): string[];
    getOffsetName(offset: number): string;
    discontinuousEnergyVars(): number[];
    epilog(bodies: ForceBody<Geometric2>[], forceLaws: ForceLaw<Geometric2>[], potentialOffset: Geometric2, varsList: VarsList): void;
    updateBodyFromVars(vars: number[], uoms: Unit[], idx: number, body: ForceBody<Geometric2>, uomTime: Unit): void;
    updateVarsFromBody(body: ForceBody<Geometric2>, idx: number, vars: VarsList): void;
    addForceToRateOfChangeLinearMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric2, uomTime: Unit): void;
    getForce(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric2): void;
    setForce(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric2): void;
    addTorqueToRateOfChangeAngularMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, torque: Geometric2, uomTime: Unit): void;
    setPositionRateOfChangeVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric2>): void;
    setAttitudeRateOfChangeVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric2>): void;
    zeroLinearMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric2>, uomTime: Unit): void;
    zeroAngularMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric2>, uomTime: Unit): void;
}

/**
 * @deprecated Use LinearDamper.
 * @hidden
 */
declare class LinearDamper2 extends LinearDamper<Geometric2> {
    constructor(body1: RigidBody<Geometric2>, body2: RigidBody<Geometric2>);
}

declare class Particle2 extends Particle<Geometric2> {
    /**
     * Constructs a particle in 2 Euclidean dimensions.
     * @param M The mass of the particle. Default is 1 (dimensionless).
     * @param Q The charge of the particle. Default is 1 (dimensionless).
     */
    constructor(M?: Geometric2, Q?: Geometric2);
}

/**
 * @hidden
 */
declare class Physics2 extends Physics<Geometric2> implements EnergySystem<Geometric2> {
    constructor();
}

declare class Polygon2 extends RigidBody2 {
    /**
     * The position of the polygon point relative to the center of mass.
     *
     * r = x - X, where x is the world position, X is the center of mass.
     */
    readonly rs: Geometric2[];
    constructor(points: Geometric2[]);
    /**
     * The inertia tensor matrix must be updated any time the geometry changes.
     * The geometry is defined by the total mass, M, and the positions of the vertices.
     */
    updateInertiaTensor(): void;
}

declare class Rod2 extends RigidBody2 {
    readonly a: Geometric2;
    constructor(a: Geometric2);
    updateInertiaTensor(): void;
}

/**
 * @deprecated Use Spring.
 * @hidden
 */
declare class Spring2 extends Spring<Geometric2> {
    constructor(body1: RigidBody<Geometric2>, body2: RigidBody<Geometric2>);
}

/**
 * @hidden
 */
declare class SurfaceConstraint<T> implements GeometricConstraint<T> {
    private readonly body;
    private readonly radiusFn;
    private readonly rotationFn;
    private readonly tangentFn;
    readonly N: T;
    constructor(body: ForceBody<T>, radiusFn: (x: T, radius: T) => void, rotationFn: (x: T, plane: T) => void, tangentFn: (x: T, tangent: T) => void);
    getBody(): ForceBody<T>;
    computeRadius(x: T, radius: T): void;
    computeRotation(x: T, plane: T): void;
    computeTangent(x: T, tangent: T): void;
    setForce(N: T): void;
}

declare class SurfaceConstraint2 extends SurfaceConstraint<Geometric2> {
    constructor(body: ForceBody<Geometric2>, radiusFn: (x: Geometric2, radius: Geometric2) => void, rotationFn: (x: Geometric2, plane: Geometric2) => void, tangentFn: (x: Geometric2, tangent: Geometric2) => void);
}

/**
 *
 */
declare class Torque2 extends Torque<Geometric2> {
    constructor(body: ForceBody<Geometric2>);
}

/**
 * The Physics Engine specialized to 2+1 dimensions with a Spacetime metric.
 */
declare class EngineG21 extends Engine<Spacetime2> {
    constructor(options?: EngineOptions);
}

/**
 *
 */
declare class ForceG21 extends Force<Spacetime2> {
    constructor(body: ForceBody<Spacetime2>);
}

/**
 * A rectangular block of constant density.
 */
declare class Block3 extends RigidBody<Geometric3> {
    /**
     * The dimension corresponding to the width.
     */
    private readonly width_;
    private widthLock_;
    /**
     * The dimension corresponding to the height.
     */
    private readonly height_;
    private heightLock_;
    /**
     * The dimension corresponding to the depth.
     */
    private readonly depth_;
    private depthLock_;
    /**
     *
     */
    constructor(width?: Geometric3, height?: Geometric3, depth?: Geometric3);
    get width(): Geometric3;
    set width(width: Geometric3);
    get height(): Geometric3;
    set height(height: Geometric3);
    get depth(): Geometric3;
    set depth(depth: Geometric3);
    /**
     * The angular velocity is updated from the angular momentum.
     */
    updateAngularVelocity(): void;
    /**
     * Whenever the mass or the dimensions change, we must update the inertia tensor.
     */
    protected updateInertiaTensor(): void;
}

/**
 * @deprecated Use ConstantForceLaw.
 * @hidden
 */
declare class ConstantForceLaw3 extends ConstantForceLaw<Geometric3> {
    constructor(body: ForceBody<Geometric3>, vector: Geometric3, vectorCoordType?: CoordType);
}

/**
 * @deprecated Use ConstantTorqueLaw.
 * @hidden
 */
declare class ConstantTorqueLaw3 extends ConstantTorqueLaw<Geometric3> {
    constructor(body: ForceBody<Geometric3>, value: Geometric3, valueCoordType: CoordType);
}

/**
 * A solid cylinder of uniform density.
 */
declare class Cylinder3 extends RigidBody<Geometric3> {
    /**
     * The dimension corresponding to the radius.
     */
    private readonly radius_;
    private radiusLock_;
    /**
     * The dimension corresponding to the height.
     */
    private readonly height_;
    private heightLock_;
    /**
     *
     */
    constructor(radius?: Geometric3, height?: Geometric3);
    get radius(): Geometric3;
    set radius(radius: Geometric3);
    get height(): Geometric3;
    set height(height: Geometric3);
    /**
     * Whenever the mass or the dimensions change, we must update the inertia tensor.
     */
    protected updateInertiaTensor(): void;
}

/**
 * The Physics Engine specialized to 3 dimensions with a Euclidean metric.
 */
declare class Engine3 extends Engine<Geometric3> {
    constructor(options?: EngineOptions);
}

/**
 *
 */
declare class Force3 extends Force<Geometric3> {
    constructor(body: ForceBody<Geometric3>);
}

/**
 * @deprecated Use GravitationLaw.
 * @hidden
 */
declare class GravitationForceLaw3 extends GravitationLaw<Geometric3> {
    constructor(body1: Massive<Geometric3>, body2: Massive<Geometric3>);
}

/**
 * @hidden
 */
declare class KinematicsG30 implements Kinematics<Geometric3> {
    private $speedOfLight;
    get speedOfLight(): Geometric3;
    set speedOfLight(speedOfLight: Geometric3);
    numVarsPerBody(): number;
    getVarNames(): string[];
    getOffsetName(offset: number): string;
    discontinuousEnergyVars(): number[];
    epilog(bodies: ForceBody<Geometric3>[], forceLaws: ForceLaw<Geometric3>[], potentialOffset: Geometric3, varsList: VarsList): void;
    updateVarsFromBody(body: ForceBody<Geometric3>, idx: number, vars: VarsList): void;
    addForceToRateOfChangeLinearMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric3, uomTime: Unit): void;
    getForce(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric3): void;
    setForce(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, force: Geometric3): void;
    addTorqueToRateOfChangeAngularMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, torque: Geometric3, uomTime: Unit): void;
    updateBodyFromVars(vars: number[], units: Unit[], idx: number, body: ForceBody<Geometric3>, uomTime: Unit): void;
    setPositionRateOfChangeVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric3>): void;
    setAttitudeRateOfChangeVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric3>): void;
    zeroLinearMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric3>, uomTime: Unit): void;
    zeroAngularMomentumVars(rateOfChangeVals: number[], rateOfChangeUoms: Unit[], idx: number, body: ForceBody<Geometric3>, uomTime: Unit): void;
}

/**
 * @deprecated Use LinearDamper.
 * @hidden
 */
declare class LinearDamper3 extends LinearDamper<Geometric3> {
    constructor(body1: RigidBody<Geometric3>, body2: RigidBody<Geometric3>);
}

/**
 * @hidden
 */
declare class MetricG30 implements Metric<Geometric3> {
    get e0(): Geometric3;
    a(mv: Geometric3): number;
    add(lhs: Geometric3, rhs: Geometric3): Geometric3;
    addScalar(lhs: Geometric3, a: number, uom?: Unit): Geometric3;
    addVector(lhs: Geometric3, rhs: Geometric3): Geometric3;
    applyMatrix(mv: Geometric3, matrix: MatrixLike): Geometric3;
    clone(source: Geometric3): Geometric3;
    copy(source: Geometric3, target: Geometric3): Geometric3;
    copyBivector(source: Geometric3, target: Geometric3): Geometric3;
    copyMatrix(m: MatrixLike): MatrixLike;
    copyVector(source: Geometric3, target: Geometric3): Geometric3;
    copyScalar(a: number, uom: Unit, target: Geometric3): Geometric3;
    createForce(body: ForceBody<Geometric3>): Force<Geometric3>;
    createTorque(body: ForceBody<Geometric3>): Torque<Geometric3>;
    direction(mv: Geometric3): Geometric3;
    divByScalar(lhs: Geometric3, a: number, uom?: Unit): Geometric3;
    identityMatrix(): MatrixLike;
    invertMatrix(m: MatrixLike): MatrixLike;
    isBivector(mv: Geometric3): boolean;
    isOne(mv: Geometric3): boolean;
    isScalar(mv: Geometric3): boolean;
    isSpinor(mv: Geometric3): boolean;
    isVector(mv: Geometric3): boolean;
    isZero(mv: Geometric3): boolean;
    lco(lhs: Geometric3, rhs: Geometric3): Geometric3;
    lock(mv: Geometric3): number;
    norm(mv: Geometric3): Geometric3;
    mul(lhs: Geometric3, rhs: Geometric3): Geometric3;
    mulByNumber(lhs: Geometric3, alpha: number): Geometric3;
    mulByScalar(lhs: Geometric3, a: number, uom: Unit): Geometric3;
    mulByVector(lhs: Geometric3, rhs: Geometric3): Geometric3;
    neg(mv: Geometric3): Geometric3;
    squaredNorm(mv: Geometric3): Geometric3;
    rco(lhs: Geometric3, rhs: Geometric3): Geometric3;
    rev(mv: Geometric3): Geometric3;
    rotate(mv: Geometric3, spinor: Geometric3): Geometric3;
    scalar(a: number, uom?: Unit): Geometric3;
    scp(lhs: Geometric3, rhs: Geometric3): Geometric3;
    setUom(mv: Geometric3, uom: Unit): void;
    sub(lhs: Geometric3, rhs: Geometric3): Geometric3;
    subScalar(lhs: Geometric3, a: number, uom?: Unit): Geometric3;
    subVector(lhs: Geometric3, rhs: Geometric3): Geometric3;
    unlock(mv: Geometric3, token: number): void;
    uom(mv: Geometric3): Unit;
    ext(lhs: Geometric3, rhs: Geometric3): Geometric3;
    write(source: Geometric3, target: Geometric3): void;
    writeVector(source: Geometric3, target: Geometric3): void;
    writeBivector(source: Geometric3, target: Geometric3): void;
}

declare class Particle3 extends Particle<Geometric3> {
    /**
     * Constructs a particle in 2 Euclidean dimensions.
     * @param M The mass of the particle. Default is 1 (dimensionless).
     * @param Q The charge of the particle. Default is 1 (dimensionless).
     */
    constructor(M: Geometric3, Q: Geometric3);
}

/**
 * @hidden
 */
declare class Physics3 extends Physics<Geometric3> implements EnergySystem<Geometric3> {
    constructor();
}

/**
 *
 */
declare class RigidBody3 extends RigidBody<Geometric3> {
    constructor();
}

/**
 * A solid sphere of constant density.
 */
declare class Sphere3 extends RigidBody<Geometric3> {
    /**
     * The dimension corresponding to the width.
     */
    private readonly radius_;
    private radiusLock_;
    /**
     *
     */
    constructor(radius?: Geometric3);
    get radius(): Geometric3;
    set radius(radius: Geometric3);
    /**
     * L(Ω) = (2 M r r / 5) Ω => Ω = (5 / 2 M r r) L(Ω)
     */
    updateAngularVelocity(): void;
    /**
     * Whenever the mass or the dimensions change, we must update the inertia tensor.
     */
    protected updateInertiaTensor(): void;
}

/**
 * @deprecated Use Spring.
 * @hidden
 */
declare class Spring3 extends Spring<Geometric3> {
    constructor(body1: RigidBody<Geometric3>, body2: RigidBody<Geometric3>);
}

declare class SurfaceConstraint3 extends SurfaceConstraint<Geometric3> {
    constructor(body: ForceBody<Geometric3>, radiusFn: (x: Geometric3, radius: Geometric3) => void, rotationFn: (x: Geometric3, plane: Geometric3) => void, tangentFn: (x: Geometric3, tangent: Geometric3) => void);
}

/**
 *
 */
declare class Torque3 extends Torque<Geometric3> {
    constructor(body: ForceBody<Geometric3>);
}

/**
 * @hidden
 */
declare enum AxisChoice {
    HORIZONTAL = 1,
    VERTICAL = 2,
    BOTH = 3
}

/**
 * Immutable point coordinates in two dimensions.
 * @hidden
 */
declare class Point {
    private x_;
    private y_;
    constructor(x_: number, y_: number);
    get x(): number;
    get y(): number;
}

/**
 * @hidden
 * Specifies an immutable 2D affine transform.
 *
 * The affine transform of a point `(x, y)` is given by:
 *
 *  [  m11  m21  dx  ] [ x ]   [ m11 x + m21 y + dx ]
 *  [  m12  m22  dy  ] [ y ] = [ m12 x + m22 y + dy ]
 *  [   0    0    1  ] [ 1 ]   [          1         ]
 *
 * Rotation clockwise by theta radians:
 *
 *  [ cos(theta)  -sin(theta)   0 ]
 *  [ sin(theta)   cos(theta)   0 ]
 *  [     0            0        1 ]
 *
 * Scale:
 *
 *  [  sx   0    0  ]
 *  [  0   sy    0  ]
 *  [  0    0    1  ]
 *
 * Translate:
 *
 *  [  1    0   dx  ]
 *  [  0    1   dy  ]
 *  [  0    0    1  ]
 */
declare class AffineTransform {
    /**
     * The identity AffineTransform, which leaves a point unchanged when it is applied.
     */
    static readonly IDENTITY: AffineTransform;
    private m11_;
    private m12_;
    private m21_;
    private m22_;
    private dx_;
    private dy_;
    /**
     *
     */
    constructor(m11: number, m12: number, m21: number, m22: number, dx: number, dy: number);
    /**
     * Multiplies the affine transform of the given context with this AffineTransform.
     * @param context the canvas context to modify
     */
    applyTransform(context: CanvasRenderingContext2D): this;
    /**
     * Right-multiply this AffineTransform by the given AffineTransform. This has the
     * effect that the given AffineTransform will be applied to the input vector before the
     * current AffineTransform.
     *
     * Concatenating a transform A to transform B is equivalent to matrix multiplication of
     * the two transforms. Note that order matters: matrices are applied in right to left order
     * when transforming a vector
     *
     * A B vector = A * (B * vector)
     *
     * We can think of the B matrix being applied first, then the A matrix.  This method
     * returns the product with the input `at` matrix on the right
     *
     * this * at
     *
     * The mathematics is as follows: this matrix is on the left, the other `at` matrix is on
     * the right:
     *
     *  [  m11  m21  dx  ]  [  a11  a21  ax  ]
     *  [  m12  m22  dy  ]  [  a12  a22  ay  ]
     *  [   0    0    1  ]  [   0    0   1   ]
     *
     * Result is:
     *
     *  [ (m11*a11 + m21*a12)  (m11*a21 + m21*a22)  (m11*ax + m21*ay + dx) ]
     *  [ (m12*a11 + m22*a12)  (m12*a21 + m22*a22)  (m12*ax + m22*ay + dy) ]
     *  [          0                    0                   1              ]
     *
     * @param at the AffineTransform matrix to right-multiply this AffineTransform matrix by
     * @return the product of this AffineTransform matrix right-multiplied by the `at` AffineTransform matrix
     */
    concatenate(at: AffineTransform): AffineTransform;
    /**
     * Draw a line to the transformed point.
     * @param x horizontal coordinate
     * @param y vertical coordinate
     * @param context the canvas context to modify
     */
    lineTo(x: number, y: number, context: CanvasRenderingContext2D): this;
    /**
     * Sets current position in context to the transformed point.
     * @param x horizontal coordinate
     * @param y vertical coordinate
     * @param context the canvas context to modify
     */
    moveTo(x: number, y: number, context: CanvasRenderingContext2D): this;
    /**
     * Concatenates a rotation transformation to this AffineTransform.
     *
     * The mathematics is as follows: this matrix is on the left, the rotation matrix is on
     * the right, and the angle is represented by `t`
     *
     *  [  m11  m21  dx  ]  [ cos(t)  -sin(t)   0 ]
     *  [  m12  m22  dy  ]  [ sin(t)   cos(t)   0 ]
     *  [   0    0    1  ]  [  0        0       1 ]
     *
     * Result is:
     *
     *  [  (m11*cos(t) + m21*sin(t))  (-m11*sin(t) + m21*cos(t))  0  ]
     *  [  (m12*cos(t) + m22*sin(t))  (-m12*sin(t) + m22*cos(t))  0  ]
     *  [              0                          0               1  ]
     *
     * @param angle angle in radians to; positive angle rotates clockwise.
     * @return a new AffineTransform equal to this AffineTransform rotated by the given angle
     */
    rotate(angle: number): AffineTransform;
    /**
     * Concatenates a scaling transformation to this AffineTransform.
     *
     * The mathematics is as follows: this matrix is on the left, the scaling matrix is on
     * the right:
     *
     *  [  m11  m21  dx  ]  [  x   0   0  ]
     *  [  m12  m22  dy  ]  [  0   y   0  ]
     *  [   0    0    1  ]  [  0   0   1  ]
     *
     * Result is:
     *
     *  [  m11*x  m21*y  dx  ]
     *  [  m12*x  m22*y  dy  ]
     *  [   0      0      1  ]
     *
     * @param x factor to scale by in horizontal direction
     * @param y factor to scale by in vertical direction
     * @return a new AffineTransform equal to this AffineTransform scaled by the given x and y factors
     */
    scale(x: number, y: number): AffineTransform;
    /**
     * Set the affine transform of the given context to match this AffineTransform.
     * @param context the canvas context to modify
     */
    setTransform(context: CanvasRenderingContext2D): this;
    /**
     * Apply this transform to the given point, returning the transformation
     * of the given point.
     *
     * The mathematics is as follows:
     *
     *  [  m11  m21  dx  ]  [ x ]
     *  [  m12  m22  dy  ]  [ y ]
     *  [   0    0    1  ]  [ 1 ]
     *
     * Result is:
     *
     *  [ m11 x + m21 y + dx ]
     *  [ m12 x + m22 y + dy ]
     *  [          1         ]
     *
     * @param x the x coordinate
     * @param y the y coordinate
     * @return the transformation of the given point.
     */
    transform(x: number, y: number): Point;
    /**
     * Concatenates a translation to this AffineTransform.
     *
     * The mathematics is as follows: this matrix is on the left, the scaling matrix is on
     * the right:
     *
     *  [  m11  m21  dx  ]  [  1    0   x  ]
     *  [  m12  m22  dy  ]  [  0    1   y  ]
     *  [   0    0    1  ]  [  0    0   1  ]
     *
     * Result is:
     *
     *  [ m11  m21  (m11*x + m21*y + dx) ]
     *  [ m12  m22  (m12*x + m22*y + dy) ]
     *  [ 0    0            1            ]
     *
     * @param the x coordinate
     * @param the y coordinate
     * @return a new AffineTransform equal to this AffineTransform  translated by the given amount
     */
    translate(x: number, y: number): AffineTransform;
}

/**
 * @hidden
 */
declare enum AlignH {
    LEFT = 0,
    MIDDLE = 1,
    RIGHT = 2,
    FULL = 3
}

/**
 * @hidden
 */
declare enum AlignV {
    TOP = 0,
    MIDDLE = 1,
    BOTTOM = 2,
    FULL = 3
}

/**
 * A rectangle whose boundaries are stored with double floating
 * point precision. This is an immutable class: once an instance is created it cannot be
 * changed.
 *
 * Note that for DoubleRect we regard the vertical coordinate as **increasing upwards**, so
 * the top coordinate is greater than the bottom coordinate. This is in contrast to HTML5
 * canvas where vertical coordinates increase downwards.
 * @hidden
 */
declare class DoubleRect {
    private left_;
    private right_;
    private bottom_;
    private top_;
    constructor(left: number, bottom: number, right: number, top: number);
    /**
     * The empty rectangle (0, 0, 0, 0).
     */
    static EMPTY_RECT: DoubleRect;
    /**
     * Returns a copy of the given DoubleRect.
     * @param rect the DoubleRect to copy
     * @return a copy of the given DoubleRect
     */
    static clone(rect: DoubleRect): DoubleRect;
    /**
     * Returns true if the object is likely a DoubleRect. Only works under simple
     * compilation, intended for interactive non-compiled code.
     * @param obj the object of interest
     * @return true if the object is likely a DoubleRect
     */
    static isDuckType(obj: unknown): obj is DoubleRect;
    /**
     * Returns a DoubleRect spanning the two given points.
     * @param point1
     * @param point2
     * @return a DoubleRect spanning the two given points
     */
    static make(point1: Point, point2: Point): DoubleRect;
    /**
     * Returns a DoubleRect centered at the given point with given height and width.
     * @param center center of the DoubleRect
     * @param width width of the DoubleRect
     * @param height height of the DoubleRect
     * @return a DoubleRect centered at the given point with given height and width
     */
    static makeCentered(center: Point, width: number, height: number): DoubleRect;
    /**
     * Returns a DoubleRect centered at the given point with given size.
     * @param center center of the DoubleRect
     * @param size width and height as a Vector
     * @return a DoubleRect centered at the given point with given size
     */
    static makeCentered2(center: Point, size: Point): DoubleRect;
    /**
     * Returns `true` if the given point is within this rectangle.
     * @param point  the point to test
     * @return `true` if the point is within this rectangle, or exactly on an edge
     */
    contains(point: {
        x: number;
        y: number;
    }): boolean;
    /**
     * Returns `true` if the object is a DoubleRect with the same coordinates.
     * @param obj the object to compare to
     * @return `true` if the object is a DoubleRect with the same coordinates.
     */
    equals(obj: unknown): boolean;
    /**
     * Returns a copy of this DoubleRect expanded by the given margin in x and y dimension.
     * @param marginX the margin to add at left and right
     * @param marginY the margin to add at top and bottom; if undefined then `marginX` is used for both x and y dimension
     * @return a DoubleRect with same center as this DoubleRect, but expanded or contracted
     */
    expand(marginX: number, marginY: number): DoubleRect;
    /**
     * Returns the smallest vertical coordinate of this DoubleRect
     * @return smallest vertical coordinate  of this DoubleRect
     */
    getBottom(): number;
    /**
     * Returns the center of this DoubleRect.
     */
    getCenter(): Point;
    /**
     * Returns the horizontal coordinate of center of this DoubleRect.
     * @return horizontal coordinate of center of this DoubleRect
     */
    getCenterX(): number;
    /**
     * Returns the vertical coordinate of center of this DoubleRect.
     * @return vertical coordinate of center of this DoubleRect
     */
    getCenterY(): number;
    /**
     * Returns the vertical height of this DoubleRect
     * @return vertical height of this DoubleRect
     */
    getHeight(): number;
    /**
     * Returns the smallest horizontal coordinate of this DoubleRect
     * @return smallest horizontal coordinate of this DoubleRect
     */
    getLeft(): number;
    /**
     * Returns the largest horizontal coordinate of this DoubleRect
     * @return largest horizontal coordinate of this DoubleRect
     */
    getRight(): number;
    /**
     * Returns the largest vertical coordinate of this DoubleRect
     * @return largest vertical coordinate of this DoubleRect
     */
    getTop(): number;
    /**
     * Returns the horizontal width of this DoubleRect
     * @return horizontal width of this DoubleRect
     */
    getWidth(): number;
    /**
     * Returns `true` if width or height of this DoubleRect are zero (within given tolerance).
     * @param tolerance optional tolerance for the test; a width or height smaller than this is regarded as zero; default is 1E-16
     * @return `true` if width or height of this DoubleRect are zero (within given tolerance)
     */
    isEmpty(tolerance?: number): boolean;
    /**
     * Returns true if the line between the two points might be visible in the rectangle.
     * @param p1 first end point of line
     * @param p2 second end point of line
     * @return true if the line between the two points might be visible in the rectangle
     */
    maybeVisible(p1: {
        x: number;
        y: number;
    }, p2: {
        x: number;
        y: number;
    }): boolean;
    /**
     * Returns `true` if this DoubleRect is nearly equal to another DoubleRect.
     * The optional tolerance value corresponds to the `epsilon`, so the actual tolerance
     * used depends on the magnitude of the numbers being compared.
     * @param rect  the DoubleRect to compare with
     * @param opt_tolerance optional tolerance for equality test
     * @return `true` if this DoubleRect is nearly equal to another DoubleRect
     */
    nearEqual(rect: DoubleRect, opt_tolerance?: number): boolean;
    /**
     * Returns a copy of this DoubleRect expanded by the given factors in both x and y
     * dimension. Expands (or contracts) about the center of this DoubleRect by the given
     * expansion factor in x and y dimensions.
     * @param factorX the factor to expand width by; 1.1 gives a 10 percent expansion; 0.9 gives a 10 percent contraction
     * @param factorY  factor to expand height by; if undefined then `factorX` is used for both x and y dimension
     * @return a DoubleRect with same center as this DoubleRect, but expanded or contracted
     */
    scale(factorX: number, factorY: number): DoubleRect;
    /**
     * Returns a copy of this rectangle translated by the given amount.
     * @param x horizontal amount to translate by.
     * @param y vertical amount to translate by.
     * @return a copy of this rectangle translated by the given amount
     */
    translate(x: number, y: number): DoubleRect;
    /**
     * Returns a rectangle that is the union of this and another rectangle.
     * @param rect the other rectangle to form the union with.
     * @return the union of this and the other rectangle
     */
    union(rect: DoubleRect): DoubleRect;
    /**
     * Returns a rectangle that is the union of this rectangle and a point
     * @param point the point to form the union with
     * @return the union of this rectangle and the point
     */
    unionPoint(point: Point): DoubleRect;
}

/**
 * An immutable rectangle corresponding to screen coordinates where the
 * vertical coordinates increase downwards.
 * @hidden
 */
declare class ScreenRect {
    private left_;
    private top_;
    private width_;
    private height_;
    /**
     *
     */
    constructor(left: number, top_: number, width: number, height: number);
    /**
     * An empty ScreenRect located at the origin.
     */
    static EMPTY_RECT: ScreenRect;
    /**
     * Returns a copy of the given ScreenRect.
     * @param rect the ScreenRect to clone
     * @return a copy of `rect`
     */
    static clone(rect: ScreenRect): ScreenRect;
    /**
     * Returns true if this ScreenRect is exactly equal to the other ScreenRect.
     * @param otherRect the ScreenRect to compare to
     * @return true if this ScreenRect is exactly equal to the other ScreenRect
     */
    equals(otherRect: ScreenRect): boolean;
    /**
     * Returns true if the object is likely a ScreenRect. Only works under simple
     * compilation, intended for interactive non-compiled code.
     * @param obj the object of interest
     * @return true if the object is likely a ScreenRect
     */
    static isDuckType(obj: unknown): obj is ScreenRect;
    /**
     * The horizontal coordinate of this ScreenRect center.
     * @return the horizontal coordinate of this ScreenRect center
     */
    getCenterX(): number;
    /**
     * The vertical coordinate of this ScreenRect center
     * @return the vertical coordinate of this ScreenRect center
     */
    getCenterY(): number;
    /**
     * The height of this ScreenRect.
     * @return the height of this ScreenRect.
     */
    getHeight(): number;
    /**
     * The left coordinate of this ScreenRect.
     * @return the left coordinate of this ScreenRect.
     */
    getLeft(): number;
    /**
     * The top coordinate of this ScreenRect.
     * @return the top coordinate of this ScreenRect
     */
    getTop(): number;
    /**
     * The width of this ScreenRect.
     * @return the width of this ScreenRect.
     */
    getWidth(): number;
    /**
     * Returns true if this ScreenRect has zero width or height, within the tolerance
     * @param tolerance tolerance for comparison, default is 1E-14;
     */
    isEmpty(tolerance?: number): boolean;
    /**
     * Creates an oval path in the Canvas context, with the size of this ScreenRect.
     * @param context the Canvas context to draw into
     */
    makeOval(context: CanvasRenderingContext2D): void;
    /**
     * Creates a rectangle path in the Canvas context, with the size of this ScreenRect.
     * @param context the Canvas context to draw into
     */
    makeRect(context: CanvasRenderingContext2D): void;
    /**
     * Returns true if this ScreenRect is nearly equal to another ScreenRect.
     * The optional tolerance value corresponds to the `epsilon`, so the actual tolerance
     * used depends on the magnitude of the numbers being compared.
     * @param otherRect  the ScreenRect to compare to
     * @param opt_tolerance optional tolerance for comparison
     * @return true if this ScreenRect is nearly equal to the other ScreenRect
     */
    nearEqual(otherRect: ScreenRect, opt_tolerance?: number): boolean;
}

/**
 * @hidden
 * Provides the mapping between screen (canvas) coordinates and simulation coordinates;
 * this is an immutable object.
 *
 * + **Screen coordinates** corresponds to pixels on an HTML canvas; the vertical
 * coordinate increases going down, with zero usually being the top of the canvas.
 *
 * + **Simulation coordinates** the vertical coordinate increases going up; units can be any size.
 *
 * To create a CoordMap you specify translation and scaling factors for going between
 * screen and simulation coordinates. The CoordMap constructor maps the bottom-left point
 * on the canvas to the given bottom-left point in simulation space and then uses the given
 * scaling factors.
 *
 * The static method {@link #make} calculates the translation and scaling factors in order
 * to fit a certain rectangle in simulation coords into another rectangle in screen coords.
 *
 * From David Flanagan, *JavaScript: The Definitive Guide, 6th Edition* page 869:
 *
 * > By default, the coordinate space for a canvas has its origin at `(0,0)` in the upper
 * left corner of the canvas, with `x` values increasing to the right and `y` values
 * increasing down. The `width` and `height` attributes of the `<canvas>` tag specify the
 * maximum X and Y coordinates, and a single unit in this coordinate space normally
 * translates to a single on-screen pixel.
 *
 * Note however that a canvas actually has
 * [two coordinate systems](http://www.ckollars.org/canvas-two-coordinate-scales.html):
 *
 * > The `<canvas...>` element is unlike almost all other HTML/HTML5 elements in using two
 * different coordinate system scales simultaneously. The *model* coordinate system scale
 * is used whenever you want to draw anything on the canvas. The *display* coordinate
 * system scale is used to control how much physical screen space is dedicated to the
 * canvas. You should explicitly specify both, the *model* coordinate size as attributes in
 * your HTML, and the *display* coordinate size in your CSS.
 *
 * Essentially the *display* coordinates can be used to stretch a canvas to fit the screen
 * as desired. Here we ignore *display* coordinates and regard *screen coordinates* to be
 * what is called *model coordinates* in the above quote.
 *
 * @param screen_left  the left edge of the canvas in screen coordinates
 * @param screen_bottom the bottom edge of the canvas in screen coordinates
 * @param sim_left  the simulation coordinate corresponding to screen_left
 * @param sim_bottom  the simulation coordinate corresponding to screen_bottom
 * @param pixel_per_unit_x  canvas pixels per simulation space unit along x axis
 * @param pixel_per_unit_y  canvas pixels per simulation space unit along y axis
 */
declare class CoordMap {
    private screen_left_;
    private screen_bottom_;
    private sim_left_;
    private sim_bottom_;
    private pixel_per_unit_x_;
    private pixel_per_unit_y_;
    private transform_;
    constructor(screen_left: number, screen_bottom: number, sim_left: number, sim_bottom: number, pixel_per_unit_x: number, pixel_per_unit_y: number);
    /**
     * Creates a CoordMap that fits a simulation coordinates rectangle inside a
     * screen coordinates rectangle in accordance with alignment options and aspect ratio.
     * Calculates the origin and scale, which define the coordinate mapping.
     *
     * The mapping is calculated so that the given simulation rectangle transforms to be
     * the largest possible rectangle that fits inside the given screen rectangle, subject to
     * various alignment options. The alignment options are similar to typical word processor
     * alignment options such as left, center, right, or full justification. In the following
     * diagrams the simulation rectangle is the smaller bold bordered rectangle, inside the
     * larger screen rectangle.
     *
     *  ┌──────────────────────────────────────────────────┐
     *  │┏━━━━━━━━━━━━━━━━┓                                │
     *  │┃                ┃                                │
     *  │┃                ┃                                │
     *  │┃    x: left     ┃                                │
     *  │┃                ┃                                │
     *  │┃                ┃                                │
     *  │┗━━━━━━━━━━━━━━━━┛                                │
     *  └──────────────────────────────────────────────────┘
     *
     *  ┌──────────────────────────────────────────────────┐
     *  │               ┏━━━━━━━━━━━━━━━━┓                 │
     *  │               ┃                ┃                 │
     *  │               ┃                ┃                 │
     *  │               ┃   x: middle    ┃                 │
     *  │               ┃                ┃                 │
     *  │               ┃                ┃                 │
     *  │               ┗━━━━━━━━━━━━━━━━┛                 │
     *  └──────────────────────────────────────────────────┘
     *
     *  ┌──────────────────────────────────────────────────┐
     *  │                                ┏━━━━━━━━━━━━━━━━┓│
     *  │                                ┃                ┃│
     *  │                                ┃                ┃│
     *  │                                ┃    x: right    ┃│
     *  │                                ┃                ┃│
     *  │                                ┃                ┃│
     *  │                                ┗━━━━━━━━━━━━━━━━┛│
     *  └──────────────────────────────────────────────────┘
     *
     * Both horizontal and vertical dimensions (x and y) have alignments. One of x or y
     * will determine the scale and will fully span the screen rectangle; the alignment
     * option only affects the other axis. In the diagrams above, the alignment of the y axis
     * is ignored; the alignment only matters for the x placement.
     *
     * Suppose the first diagram above had `LEFT` horizontal alignment and
     * `TOP` vertical alignment, but then the screen rectangle changed to be tall
     * and narrow; then we would see the first picture below. Other vertical alignment
     * options are shown as well.
     *
     *  ┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐
     *  │┏━━━━━━━━━━━━━━━━┓│     │                  │     │                  │
     *  │┃                ┃│     │                  │     │                  │
     *  │┃    x: left     ┃│     │                  │     │                  │
     *  │┃    y: top      ┃│     │                  │     │                  │
     *  │┃                ┃│     │┏━━━━━━━━━━━━━━━━┓│     │                  │
     *  │┃                ┃│     │┃                ┃│     │                  │
     *  │┗━━━━━━━━━━━━━━━━┛│     │┃    x: left     ┃│     │                  │
     *  │                  │     │┃    y: middle   ┃│     │                  │
     *  │                  │     │┃                ┃│     │                  │
     *  │                  │     │┃                ┃│     │┏━━━━━━━━━━━━━━━━┓│
     *  │                  │     │┗━━━━━━━━━━━━━━━━┛│     │┃                ┃│
     *  │                  │     │                  │     │┃    x: left     ┃│
     *  │                  │     │                  │     │┃    y: bottom   ┃│
     *  │                  │     │                  │     │┃                ┃│
     *  │                  │     │                  │     │┃                ┃│
     *  │                  │     │                  │     │┗━━━━━━━━━━━━━━━━┛│
     *  └──────────────────┘     └──────────────────┘     └──────────────────┘
     *
     * `FULL` ensures that for the chosen axis the simulation and screen rectangles
     * coincide. When both x and y have `FULL`, then the simulation and screen rectangles
     * will coincide but the aspect ratio is altered, so an image from the simulation may
     * appear squashed or stretched (see definition of aspect ratio below). For example, the
     * square simulation rectangle from our earlier examples is stretched out here:
     *
     *  ┌──────────────────────────────────────────────────┐
     *  │┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓│
     *  │┃                                                ┃│
     *  │┃                                                ┃│
     *  │┃             x:full, y:full                     ┃│
     *  │┃                                                ┃│
     *  │┃                                                ┃│
     *  │┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛│
     *  └──────────────────────────────────────────────────┘
     *
     * When only one of the axes has `FULL`, the simulation rectangle
     * might not entirely fit into the screen rectangle as the following example shows, but
     * the aspect ratio is preserved.
     *
     *   ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
     *   ┃                                                ┃
     *   ┃                                                ┃
     *   ┃                                                ┃
     *   ┃                                                ┃
     *   ┃                                                ┃
     *  ┌┃────────────────────────────────────────────────┃┐
     *  │┃                                                ┃│
     *  │┃                                                ┃│
     *  │┃            x:full, y:middle                    ┃│
     *  │┃                                                ┃│
     *  │┃                                                ┃│
     *  └┃────────────────────────────────────────────────┃┘
     *   ┃                                                ┃
     *   ┃                                                ┃
     *   ┃                                                ┃
     *   ┃                                                ┃
     *   ┃                                                ┃
     *   ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
     *
     * The aspect ratio is the ratio of 'pixels per simulation unit along y axis' divided
     * by 'pixels per simulation unit along x axis'. The default aspect ratio is 1.0, so x
     * and y are treated identically with distance being measured the same in each direction.
     * An aspect ratio other than 1.0 will squash or stretch the image.  Note that aspect
     * ratio is ignored when both x and y axes have `FULL` specified.
     *
     * The simulation rectangle, screen rectangle, alignment options, and aspect ratio are
     * only used to initially determine the coordinate transformation; they are not stored by
     * the CoordMap.
     *
     * @param screenRect  the screen space rectangle to fit the sim rect into
     * @param simRect  the simulation space rectangle to be fit into the screenRect
     * @param horizAlign  horizontal alignment option; default is `HorizAlign.MIDDLE`
     * @param verticalAlign  vertical alignment option; default is`VerticalAlign.MIDDLE`
     * @param aspectRatio  the ratio of 'pixels per simulation unit along y axis'
     * divided by 'pixels per simulation unit along x axis';  default is 1.0
     * @return the CoordMap corresponding to the given options
     */
    static make(screenRect: ScreenRect, simRect: DoubleRect, horizAlign?: AlignH, verticalAlign?: AlignV, aspectRatio?: number): CoordMap;
    /**
     * Returns true if the object is likely a CoordMap. Only works under simple
     * compilation, intended for interactive non-compiled code.
     * @param obj the object of interest
     * @return true if the object is likely a CoordMap
     */
    static isDuckType(obj: unknown): obj is CoordMap;
    /**
     * Returns an AffineTransform that maps simulation coordinates to screen coordinates
     * using the mapping defined by this CoordMap.
     * @return the AffineTransform equivalent of this CoordMap
     */
    getAffineTransform(): AffineTransform;
    /**
     * Returns the horizontal scaling factor: the screen pixels per simulation space
     * unit along x axis.
     * @return the horizontal scaling factor: screen pixels per unit of simulation
     * space in x direction
     */
    getScaleX(): number;
    /**
     * Returns the vertical scaling factor: the screen pixels per simulation space
     * unit along y axis.
     * @return the vertical scaling factor: screen pixels per unit of simulation
     * space in y direction
     */
    getScaleY(): number;
    /**
     * Translates a point in screen coordinates to simulation coordinates.
     * @param scr_x horizontal position in screen coordinates.
     * @param scr_y vertical position in screen coordinates
     */
    screenToSim(scr_x: number, scr_y: number): Point;
    /**
     * Translates the given screen coordinates rectangle into simulation coordinates.
     * @param rect the rectangle in screen coordinates
     * @return the equivalent rectangle in simulation coordinates
     */
    screenToSimRect(rect: ScreenRect): DoubleRect;
    /**
     * Returns the equivalent length in simulation coordinates of the given horizontal
     * length in screen coordinates.
     * @param scr_x a horizontal length in screen coordinates
     * @return the equivalent length in simulation coordinates
     */
    screenToSimScaleX(scr_x: number): number;
    /**
     * Returns the equivalent length in simulation coordinates of the given vertical
     * length in screen coordinates.
     * @param scr_y a vertical length in screen coordinates
     * @return the equivalent length in simulation coordinates
     */
    screenToSimScaleY(scr_y: number): number;
    /**
     * Translates a horizontal screen coordinate to simulation coordinates.
     * @param scr_x horizontal position in screen coordinates
     * @return the equivalent position in simulation coordinates
     */
    screenToSimX(scr_x: number): number;
    /**
     * Translates a vertical screen coordinate to simulation coordinates.
     * @param scr_y vertical position in screen coordinates
     * @return the equivalent position in simulation coordinates
     */
    screenToSimY(scr_y: number): number;
    /**
     * Translates a point from simulation coordinates to screen coordinates.
     * @param p_sim the point in simulation coordinates to translate
     * @return the point translated to screen coordinates
     */
    simToScreen(p_sim: Point): Point;
    /**
     * Translates the given simulation coordinates rectangle into screen coordinates.
     * @param r the rectangle in simulation coordinates
     * @return the equivalent rectangle in screen coordinates
     */
    simToScreenRect(r: DoubleRect): ScreenRect;
    /**
     * Returns the equivalent length in screen coordinates of the given horizontal length
     * in simulation coordinates.
     * @param length_x a horizontal length in simulation coordinates
     * @return the equivalent length in screen coordinates
     */
    simToScreenScaleX(length_x: number): number;
    /**
     * Returns the equivalent length in screen coordinates of the given vertical length
     * in simulation coordinates.
     * @param length_y a vertical length in simulation coordinates
     * @return the equivalent length in screen coordinates
     */
    simToScreenScaleY(length_y: number): number;
    /**
     * Translates a horizontal simulation coordinate to screen coordinates.
     * @param sim_x horizontal position in simulation coordinates
     * @return the equivalent position in screen coordinates
     */
    simToScreenX(sim_x: number): number;
    /**
     * Translates a vertical simulation coordinate to screen coordinates.
     * @param sim_y vertical position in simulation coordinate
     * @return the equivalent position in screen coordinates
     */
    simToScreenY(sim_y: number): number;
}

/**
 * @hidden
 */
interface DisplayObject {
    /**
     *
     */
    draw(context: CanvasRenderingContext2D, coordMap: CoordMap): void;
    /**
     * Sets the z-index which specifies front-to-back ordering of objects;
     * objects with a higher zIndex are drawn over (in front of) objects with a lower zIndex.
     * @return the zIndex of this DisplayObject
     */
    getZIndex(): number;
    /**
     * Sets the z-index which specifies front-to-back ordering of objects;
     * objects with a higher zIndex are drawn over objects with a lower zIndex.
     * Default is zero.
     * @param {number|undefined} zIndex the zIndex of this DisplayObject
     */
    setZIndex(zIndex?: number): void;
}

/**
 * @hidden
 */
interface HistoryIterator<T> {
    getIndex(): number;
    getValue(): T;
    hasNext(): boolean;
    hasPrevious(): boolean;
    nextValue(): T;
    previousValue(): T;
}

/**
 * An ordered list of values that can be added to but not altered; older
 * values might be forgotten. Each value has a unique unchanging index in the HistoryList,
 * but the HistoryList can have limited capacity and old values might be dropped from the
 * HistoryList to make room for new values to be added. HistoryList contains only those
 * values whose index is between {@link #getStartIndex} and {@link #getEndIndex}
 * (inclusive).
 *
 * Designed to represent a CircularList where new values are
 * written over old values. Therefore the starting index can change when writing a new
 * value to the list, because the new value might overwrite an old value.
 * @hidden
 */
interface HistoryList<T> {
    /**
     * Returns the index of the ending value in this HistoryList. The ending value is
     * the newest value in this HistoryList.
     * @return {number} the index of the ending value in this HistoryList, or -1 if nothing has
     * yet been stored
     * @throws {Error} when the index number exceeds the maximum representable integer
     */
    getEndIndex(): number;
    /**
     * Returns the last value stored in this HistoryList.
     * @return {?T} the value stored at the given index, or null if this HistoryList is empty
     */
    getEndValue(): T;
    /**
     * Returns a HistoryIterator which begins at the
     * given index in this HistoryList.
     * @param index the index to start the iterator at;  if undefined or -1, then
     * starts at beginning of this HistoryList
     * @return a HistoryIterator which begins
     * at the given index in this HistoryList.
     */
    getIterator(index?: number): HistoryIterator<T>;
    /**
     * Returns the number of points currently stored in this HistoryList (which is less
     * than or equal to the capacity of this HistoryList).
     * @return {number} the number of points currently stored in this HistoryList
     */
    getSize(): number;
    /**
     * Returns the index of the starting value in this HistoryList. The starting value is
     * the oldest value in this HistoryList.
     * @return {number} the index of the starting value in this HistoryList
     * @throws {Error} when the index number exceeds the maximum representable integer
     */
    getStartIndex(): number;
    /**
     * Returns the value stored at the given index in this HistoryList.
     * @param {number} index  the index of the point of interest
     * @return {T} the value stored at the given index
     * @throws {Error} if the index is out of range
     */
    getValue(index: number): T;
    /**
     * Clears out the memory of this HistoryList, so that there are no values stored.
     * The capacity of this HistoryList is unchanged.
     */
    reset(): void;
    /**
     * Stores the given value into this HistoryList, and advances the internal pointer to
     * the next available spot in this HistoryList.
     * @param {T} value the value to store
     * @return {number} index within HistoryList where the value was stored
     * @throws {Error} when the index number exceeds the maximum representable integer
     */
    store(value: T): number;
}

/**
 * @hidden
 */
declare class CircularList<T> implements HistoryList<T> {
    /**
     * capacity of the list, maximum size
     */
    private capacity_;
    /**
     * number of items now in memory list <= capacity
     */
    size_: number;
    /**
     * number of times the list has been overwritten
     */
    private cycles_;
    /**
     * pointer to next entry in list;  oldest entry if list has wrapped around.
     */
    private nextPtr_;
    /**
     * pointer to newest entry: index of last entry written to list or -1 if never written.
     */
    private lastPtr_;
    /**
     * values stored.
     */
    values_: Array<T>;
    /**
     * last value written to memory list
     */
    /**
     *
     */
    constructor(capacity?: number);
    /**
     * Causes the MAX_INDEX_ERROR exception to occur in near future by setting
     * the number of cycles to be near the maximum allowed, for testing.
     */
    causeMaxIntError(): void;
    /**
     *
     */
    getEndIndex(): number;
    /**
     *
     */
    getEndValue(): T;
    /**
     *
     */
    getIterator(index: number): HistoryIterator<T>;
    getSize(): number;
    getStartIndex(): number;
    getValue(index: number): T;
    /**
     * Converts an index (which includes cycles) into a pointer.
     * Pointer and index are the same until the list fills and 'wraps around'.
     * @param index the index number, which can be larger than the size of the list
     * @return the pointer to the corresponding point in the list
     */
    indexToPointer_(index: number): number;
    /**
     * Converts a pointer into the list to an index number that includes cycles.
     * Pointer and index are the same until the list fills and 'wraps around'.
     * @throws when the index number exceeds the maximum representable integer
     * @param pointer an index from 0 to size
     * @return the index number of this point including cycles
     */
    private pointerToIndex;
    reset(): void;
    store(value: T): number;
}

/**
 * An object that memorizes simulation data or performs some other function that needs
 * to happen regularly. The `memorize` method is meant to be called after each simulation
 * time step.
 * See MemoList for how to add a Memorizable
 * object to the list of those that will be called.
 * @hidden
 */
interface Memorizable {
    /**
     * Memorize the current simulation data or do some other function.
     */
    memorize(): void;
}

/**
 * @hidden
 */
declare enum DrawingMode {
    DOTS = 0,
    LINES = 1
}

/**
 * @hidden
 */
declare class GraphPoint {
    x: number;
    y: number;
    seqX: number;
    seqY: number;
    constructor(x: number, y: number, seqX: number, seqY: number);
    /**
     * Returns whether this GraphPoint is identical to another GraphPoint
     * @param other the GraphPoint to compare with
     * @return `true` if this GraphPoint is identical to the other GraphPoint
     */
    equals(other: GraphPoint): boolean;
}

/**
 * @hidden
 */
declare class GraphStyle {
    index_: number;
    drawingMode: DrawingMode;
    color_: string;
    lineWidth: number;
    /**
     *
     */
    constructor(index_: number, drawingMode: DrawingMode, color_: string, lineWidth: number);
}

/**
 * @hidden
 */
declare class GraphLine extends AbstractSubject implements Memorizable, Observer {
    static readonly PARAM_NAME_X_VARIABLE = "X variable";
    static readonly PARAM_NAME_Y_VARIABLE = "Y variable";
    static readonly PARAM_NAME_LINE_WIDTH = "line width";
    static readonly PARAM_NAME_COLOR = "color";
    static readonly PARAM_NAME_DRAWING_MODE = "drawing mode";
    /**
     * Event broadcasted when reset is called.
     */
    static readonly RESET = "RESET";
    /**
     * The VarsList whose data this graph is displaying
     */
    private readonly varsList_;
    /**
     * index of horizontal variable in simulation's variables, or -1 to not collect any X variable data
     */
    private xVar_;
    /**
     * index of vertical variable in simulation's variables, or -1 to not collect any X variable data
     */
    private yVar_;
    /**
     * Parameter that represents which variable is shown on x-axis, and the available choices of variables.
     */
    private xVarParam_;
    /**
     * Parameter that represents which variable is shown on y-axis, and the available choices of variables.
     */
    private yVarParam_;
    /**
     * Holds the most recent data points drawn, to enable redrawing when needed.
     */
    dataPoints_: CircularList<GraphPoint>;
    /**
     * The color to draw the graph with, a CSS3 color string.
     */
    private drawColor_;
    /**
     * whether to draw the graph with lines or dots
     */
    private drawingMode_;
    /**
     * Thickness to use when drawing the line, in screen coordinates, so a unit is a screen pixel.
     */
    private lineWidth_;
    /**
     * The color to draw the hot spot (most recent point) with, a CSS3 color string.
     */
    private hotspotColor_;
    /**
     * GraphStyle's for display, ordered by index in dataPoints list.
     * There can be multiple GraphStyle entries for the same index, the latest one
     * in the list takes precedence.  We ensure there is always at least one GraphStyle
     * in the list.
     */
    private styles_;
    /**
     * Function that gives the transformed the X value.
     */
    xTransform: (x: number, y: number) => number;
    /**
     * Function that gives the transformed the Y value.
     */
    yTransform: (x: number, y: number) => number;
    /**
     *
     */
    constructor(varsList: GraphVarsList, capacity?: number);
    /**
     * Adds a GraphStyle with the current color, draw mode, and line width, corresponding
     * to the current end point of the HistoryList.
     */
    private addGraphStyle;
    /**
     * Returns true if the object is likely a GraphLine. Only works under simple
     * compilation, intended for interactive non-compiled code.
     * @param obj the object of interest
     * @return true if the object is likely a GraphLine
     */
    static isDuckType(obj: unknown): obj is GraphLine;
    /**
     * Returns the color used when drawing the graph.
     * @return the color used when drawing the graph
     */
    get color(): string;
    /**
     * Sets the color to use when drawing the graph. Applies only to portions of graph
     * memorized after this time.
     * @param color the color to use when drawing the graph, a CSS3 color string.
     */
    set color(color: string);
    /**
     * Returns the drawing mode of the graph: dots or lines.
     * @return the DrawingMode to draw this graph with
     */
    get drawingMode(): DrawingMode;
    /**
     * Sets whether to draw the graph with dots or lines. Applies only to portions of graph
     * memorized after this time.
     * @param drawingMode the DrawingMode (dots or lines) to
     * draw this graph with.
     * @throws Error if the value does not represent a valid DrawingMode
     */
    set drawingMode(drawingMode: DrawingMode);
    /**
     * Returns the HistoryList of GraphPoints.
     */
    getGraphPoints(): CircularList<GraphPoint>;
    /**
     * Returns the GraphStyle corresponding to the position in the list of GraphPoints.
     * @param index  the index number in list of GraphPoints
     */
    getGraphStyle(index: number): GraphStyle;
    /**
     * Returns the color used when drawing the hot spot (most recent point).
     */
    get hotspotColor(): string;
    /**
     * Sets the color to use when drawing the hot spot (most recent point).
     * Set this to empty string to not draw the hot spot.
     */
    set hotspotColor(color: string);
    /**
     * Returns thickness to use when drawing the line, in screen coordinates, so a unit
     * is a screen pixel.
     */
    get lineWidth(): number;
    /**
     * Sets thickness to use when drawing the line, in screen coordinates, so a unit is a
     * screen pixel. Applies only to portions of graph memorized after this time.
     * @param lineWidth thickness of line in screen coordinates
     */
    set lineWidth(lineWidth: number);
    /**
     * Returns the VarsList that this GraphLine is collecting from
     */
    get varsList(): GraphVarsList;
    /**
     * Returns the index in the VarsList of the X variable being collected.
     * @return the index of X variable in the VarsList, or  -1 if no X variable
     * is being collected.
     */
    get hCoordIndex(): number;
    /**
     * Sets the variable from which to collect data for the X value of the graph.
     * Starts over with a new HistoryList.
     * Broadcasts the parameter named `X_VARIABLE`.
     */
    set hCoordIndex(xVar: number);
    /**
     * Returns localized X variable name.
     * @return variable name or empty string in case index is -1
     */
    getXVarName(): string;
    /**
     * Returns the index in the VarsList of the Y variable being collected.
     * @return the index of Y variable in the VarsList, or  -1 if no Y variable
     * is being collected.
     */
    get vCoordIndex(): number;
    /**
     * Sets the variable from which to collect data for the Y value of the graph.
     * Starts over with a new HistoryList.
     * Broadcasts the parameter named `Y_VARIABLE`.
     */
    set vCoordIndex(yVar: number);
    /**
     * Returns localized Y variable name.
     * @return variable name or empty string in case index is -1
     */
    getYVarName(): string;
    memorize(): void;
    observe(event: SubjectEvent): void;
    /**
     * Forgets any memorized data and styles, starts from scratch.
     */
    reset(): void;
    /**
     * Forgets any memorized styles, records the current color, draw mode, and line width
     * as the single starting style.
     */
    resetStyle(): void;
    private checkVarIndex;
}

/**
 * @hidden
 */
declare class DisplayGraph implements DisplayObject {
    /**
     * The GraphLines to draw.
     */
    private readonly graphLines_;
    /**
     *
     */
    private memDraw_;
    /**
     *
     */
    private offScreen_;
    /**
     * to detect when redraw needed;  when the coordmap changes, we need to redraw.
     */
    private lastMap_;
    /**
     *
     */
    private screenRect_;
    /**
     * set when the entire graph needs to be redrawn.
     */
    private needRedraw_;
    /**
     * set when the entire graph needs to be redrawn.
     */
    private useBuffer_;
    /**
     *
     */
    private zIndex;
    /**
     *
     */
    constructor();
    /**
     *
     */
    draw(context: CanvasRenderingContext2D, map: CoordMap): void;
    /**
     *
     */
    drawHotSpot(context: CanvasRenderingContext2D, coordMap: CoordMap, graphLine: GraphLine): void;
    /**
     * Draws the points starting from the specified point to the most recent point;
     * returns the index of last point drawn.
     * @param context the canvas's context to draw into
     * @param coordMap the CoordMap specifying sim to screen conversion
     * @param from the index of the the point to start from, within the datapoints
     * @param graphLine
     * @return the index of the last point drawn.
     */
    private drawPoints;
    fullDraw(context: CanvasRenderingContext2D, coordMap: CoordMap): void;
    getZIndex(): number;
    setZIndex(zIndex: number): void;
    /**
     *
     */
    incrementalDraw(context: CanvasRenderingContext2D, coordMap: CoordMap): void;
    isDragable(): boolean;
    /**
     * Add a GraphLine to be displayed.
     * @param graphLine the GraphLine to be display
     */
    addGraphLine(graphLine: GraphLine): void;
    /**
     * Remove a GraphLine from set of those to display.
     * @param graphLine the GraphLine to not display
     */
    removeGraphLine(graphLine: GraphLine): void;
    setDragable(dragable: boolean): void;
    /**
     * Sets the screen rectangle that this DisplayGraph should occupy within the
     * @param screenRect the screen coordinates of the
     * area this DisplayGraph should occupy.
     */
    setScreenRect(screenRect: ScreenRect): void;
    /**
     * Whether to draw into an offscreen buffer.  A *time graph* must redraw every
     * frame, so it saves time to *not* use an offscreen buffer in that case.
     * @param value Whether to draw into an offscreen buffer
     */
    setUseBuffer(value: boolean): void;
    /**
     * Causes entire graph to be redrawn, when `draw` is next called.
     */
    reset(): void;
}

/**
 * Displays a set of DisplayObject(s)}, which show the state of the simulation.
 * A DisplayObject typically represents a SimObject, but not always.
 *
 * zzIndex
 * ------
 * DisplayObjects with a lower `zIndex` appear underneath those with higher `zIndex`.
 * The DisplayList is sorted by `zIndex`.
 * @hidden
 */
declare class DisplayList extends AbstractSubject {
    /**
     * Name of event broadcast when a DisplayObject is added.
     */
    static readonly OBJECT_ADDED = "OBJECT_ADDED";
    /**
     * Name of event broadcast when a DisplayObject is removed.
     */
    static readonly OBJECT_REMOVED = "OBJECT_REMOVED";
    /**
     *
     */
    private readonly drawables_;
    /**
     *
     */
    constructor();
    /**
     * Adds the DisplayObject, inserting it at the end of the group of DisplayObjects
     * with the same zIndex; the item will appear visually over objects that have
     * the same (or lower) `zIndex`.
     * @param dispObj the DisplayObject to add
     */
    add(dispObj: DisplayObject): void;
    /**
     * Draws the DisplayObjects in order, which means that DisplayObjects drawn later (at
     * the end of the list) will appear to be on top of those drawn earlier (at start of the list).
     * @param context the canvas's context to draw this object into
     * @param map the mapping to use for translating between simulation and screen coordinates
     */
    draw(context: CanvasRenderingContext2D, coordMap: CoordMap): void;
    /**
     * Adds the DisplayObject, inserting it at the front of the group of DisplayObjects
     * with the same zIndex; the item will appear visually under objects that have
     * the same (or higher) `zIndex`.
     * @param dispObj the DisplayObject to prepend
     */
    prepend(dispObj: DisplayObject): void;
    private sort;
}

/**
 * @hidden
 */
interface LabView extends Memorizable {
    /**
     * Called when this LabView becomes the focus view of the LabCanvas.
     */
    gainFocus(): void;
    /**
     * Returns the CoordMap used by this LabView.
     */
    getCoordMap(): CoordMap;
    /**
     * Returns the DisplayList of this LabView.
     */
    getDisplayList(): DisplayList;
    /**
     * Returns the screen rectangle that this LabView is occupying within the
     * LabCanvas, in screen coordinates.
     */
    getScreenRect(): ScreenRect;
    /**
     * Returns the bounding rectangle for this LabView in simulation coordinates.
     */
    getSimRect(): DoubleRect;
    /**
     * Called when this LabView is no longer the focus view of the LabCanvas.
     */
    loseFocus(): void;
    /**
     * Paints this LabView into the given CanvasRenderingContext2D.
     * @param context the canvas's context to draw into
     */
    paint(context: CanvasRenderingContext2D): void;
    /**
     * Sets the CoordMap used by this LabView.
     * @param map the CoordMap to use for this LabView
     */
    setCoordMap(map: CoordMap): void;
    /**
     * Sets the area that this LabView will occupy within the LabCanvas,
     * in screen coordinates.
     * @param sreenRect the screen coordinates of the area this LabView should occupy
     */
    setScreenRect(screenRect: ScreenRect): void;
    /**
     * Sets the bounding rectangle for this LabView, ensures this rectangle
     * is visible, and turns off auto-scaling. The result is to generate a new CoordMap for
     * this SimView so that the simulation rectangle maps to the current screen rectangle.
     * @param simRect the bounding rectangle for this
     * LabView in simulation coordinates.
     */
    setSimRect(simRect: DoubleRect): void;
}

/**
 * @hidden
 */
declare class SimView extends AbstractSubject implements LabView {
    static readonly PARAM_NAME_WIDTH = "width";
    static readonly PARAM_NAME_HEIGHT = "height";
    static readonly PARAM_NAME_CENTER_X = "center-x";
    static readonly PARAM_NAME_CENTER_Y = "center-y";
    static readonly PARAM_NAME_HORIZONTAL_ALIGN = "horizontal-align";
    static readonly PARAM_NAME_VERTICAL_ALIGN = "vertical-align";
    static readonly PARAM_NAME_ASPECT_RATIO = "aspect-ratio";
    static readonly PARAM_NAME_SCALE_TOGETHER = "scale X-Y together";
    /**
     * Name of event broadcast when the CoordMap changes, see {@link #setCoordMap}.
     */
    static readonly COORD_MAP_CHANGED = "COORD_MAP_CHANGED";
    /**
     * Name of event broadcast when the screen rectangle size changes, see
     */
    static readonly SCREEN_RECT_CHANGED = "SCREEN_RECT_CHANGED";
    /**
     * Name of event broadcast when the simulation rectangle size changes, see
     */
    static readonly SIM_RECT_CHANGED = "SIM_RECT_CHANGED";
    /**
     * when panning horizontally, this is percentage of width to move.
     */
    panX: number;
    /**
     * when panning vertically, this is percentage of height to move.
     */
    panY: number;
    /**
     * when zooming, this is percentage of size to zoom
     */
    zoom: number;
    /**
     * The boundary rectangle in simulation coordinates.
     */
    private simRect_;
    /**
     * The rectangle in screen coordinates where this SimView exists inside the LabCanvas.
     */
    private screenRect_;
    private horizAlign_;
    private verticalAlign_;
    private aspectRatio_;
    /**
     * This list of DisplayObjects that this SimView displays
     */
    private readonly displayList_;
    private scaleTogether_;
    /**
     * The CoordMap that defines the simulation coordinates for this LabView.
     */
    private coordMap_;
    /**
     * The transparency used when painting the drawables; a number between
     * 0.0 (fully transparent) and 1.0 (fully opaque).
     */
    opaqueness: number;
    private width_;
    private height_;
    private centerX_;
    private centerY_;
    /**
     * ratio of height/width, used when scaleTogether_ is true.
     */
    private ratio_;
    private readonly memorizables_;
    /**
     *
     */
    constructor(simRect: DoubleRect);
    addMemo(memorizable: Memorizable): void;
    /**
     *
     */
    gainFocus(): void;
    /**
     * Returns the ratio of 'pixels per simulation unit along y axis' divided
     * by 'pixels per simulation unit along x axis' used when displaying this LabView.
     */
    getAspectRatio(): number;
    /**
     * Returns the horizontal coordinate of simulation rectangle's center.
     */
    getCenterX(): number;
    /**
     * Returns the vertical coordinate of simulation rectangle's center.
     */
    getCenterY(): number;
    getCoordMap(): CoordMap;
    getDisplayList(): DisplayList;
    /**
     * Returns height of the simulation rectangle.
     */
    getHeight(): number;
    /**
     * Returns the horizontal alignment to use when aligning the SimView's
     * simulation rectangle within its screen rectangle.
     */
    get hAxisAlign(): AlignH;
    /**
     * Sets the horizontal alignment to use when aligning the SimView's
     * simulation rectangle within its screen rectangle.
     */
    set hAxisAlign(alignHoriz: AlignH);
    getMemos(): Memorizable[];
    /**
     * Whether the width and height of the simulation rectangle scale together; if
     * true then changing one causes the other to change proportionally.
     */
    getScaleTogether(): boolean;
    getScreenRect(): ScreenRect;
    getSimRect(): DoubleRect;
    /**
     * Returns the vertical alignment to use when aligning the SimView's
     * simulation rectangle within its screen rectangle.
     */
    get vAxisAlign(): AlignV;
    /**
     * Sets the vertical alignment to use when aligning the SimView's
     * simulation rectangle within its screen rectangle.
     */
    set vAxisAlign(alignVert: AlignV);
    /**
     * Returns the width of the simulation rectangle.
     */
    getWidth(): number;
    loseFocus(): void;
    paint(context: CanvasRenderingContext2D): void;
    setCoordMap(map: CoordMap): void;
    setScreenRect(screenRect: ScreenRect): void;
    setSimRect(simRect: DoubleRect): void;
    memorize(): void;
    private realign;
    /**
     * Modifies the simulation rectangle of the target SimView according to our
     * current settings for width, height, centerX, centerY.
     */
    private modifySimRect;
    /**
     * Moves the center of the simulation rectangle (the 'camera') down by fraction
     * {@link #panY}, which causes the image to move up.
     * Also broadcasts a {@link #SIM_RECT_CHANGED} event.
     */
    panDown(): void;
    /**
     * Moves the center of the simulation rectangle (the 'camera') left by fraction
     * {@link #panY}, which causes the image to move right.
     * Also broadcasts a {@link #SIM_RECT_CHANGED} event.
     */
    panLeft(): void;
    /**
     * Moves the center of the simulation rectangle (the 'camera') right by fraction
     * {@link #panY}, which causes the image to move left.
     * Also broadcasts a {@link #SIM_RECT_CHANGED} event.
     */
    panRight(): void;
    /**
     * Moves the center of the simulation rectangle (the 'camera') up by fraction
     * {@link #panY}, which causes the image to move down.
     * Also broadcasts a {@link #SIM_RECT_CHANGED} event.
     */
    panUp(): void;
    /**
     *
     */
    removeMemo(memorizable: Memorizable): void;
    /**
     * Sets the ratio of 'pixels per simulation unit along y axis' divided
     * by 'pixels per simulation unit along x axis' used when displaying this LabView.
     * @param {number} aspectRatio the aspect ratio used when displaying this LabView
     */
    setAspectRatio(aspectRatio: number): void;
    /**
     * Sets the horizontal coordinate of simulation rectangle's center,
     * and broadcasts a {@link #SIM_RECT_CHANGED} event.
     * @param centerX the horizontal coordinate of simulation rectangle's center.
     */
    setCenterX(centerX: number): void;
    /**
     * Sets the vertical coordinate of simulation rectangle's center,
     * and broadcasts a {@link #SIM_RECT_CHANGED} event.
     * @param {number} value the vertical coordinate of simulation rectangle's center.
     */
    setCenterY(value: number): void;
    /**
     * Sets height of the simulation rectangle, and broadcasts a {@link #SIM_RECT_CHANGED} event.
     * @param {number} value height of the simulation rectangle
     */
    setHeight(value: number): void;
    /**
     * Sets whether the width and height of the simulation rectangle scale together; if
     * true then changing one causes the other to change proportionally.
     * @param {boolean} value whether width and height scale together
     */
    setScaleTogether(value: boolean): void;
    /**
     * Sets width of the simulation rectangle, and broadcasts a {@link #SIM_RECT_CHANGED} event.
     * @param value width of the simulation rectangle
     */
    setWidth(value: number): void;
    /**
     * Makes the height of the simulation rectangle smaller by fraction 1/{@link #zoom},
     * and also the width if {@link #getScaleTogether} is true.
     * Also broadcasts a {@link #SIM_RECT_CHANGED} event.
     */
    zoomIn(): void;
    /**
     * Makes the height of the simulation rectangle bigger by fraction {@link #zoom},
     * and also the width if {@link #getScaleTogether} is true.
     * Also broadcasts a {@link #SIM_RECT_CHANGED} event.
     */
    zoomOut(): void;
}

/**
 * @hidden
 * Watches the VarsList of one or more GraphLines to calculate the range
 * rectangle that encloses the points on the graphs, and sets accordingly the simRect of a
 * SimView. The range rectangle is the smallest rectangle that contains all the points, but
 * possibly expanded by the `extraMargin` factor.
 *
 * Enabled and Active
 *
 * To entirely disable an AutoScale, see `enabled`.
 * Assuming the AutoScale is enabled, it will react to events in the SimView and GraphLines as follows:
 *
 * + AutoScale becomes **inactive** when the SimView's simRect is changed by an entity
 * other than this AutoScale. This happens when AutoScale observes a SimView event called
 * `LabView.SIM_RECT_CHANGED`.
 *
 * + AutoScale becomes **active** when one of its GraphLines broadcasts a `RESET` event.
 * This happens when a graph is cleared, or when the X or Y variable is changed.
 *
 * You can also call `active` directly to make an enabled AutoScale active or
 * inactive.
 *
 * ### Time Graph
 *
 * For a *time graph* where one variable is time, the range rectangle in the time dimension
 * has a fixed size specified by {@link #setTimeWindow}. The default time window is 10
 * seconds.
 *
 * ### Events Broadcast
 *
 * GenericEvent named {@link #AUTO_SCALE} is broadcast when the range rectangle changes.
 *
 * ### Parameters Created
 *
 * + ParameterNumber named `AutoScale.TIME_WINDOW`
 * see {@link #setTimeWindow}.
 *
 * + ParameterNumber named `AutoScale.AXIS`
 * see `axisChoice`.
 */
declare class AutoScale extends AbstractSubject implements Memorizable, Observer {
    /**
     * Event broadcasted when axis is changed.
     */
    static readonly AXIS = "AXIS";
    /**
     * Event broadcasted when time window is changed.
     */
    static readonly TIME_WINDOW = "TIME_WINDOW";
    /**
     * Name of event broadcast when the active state changes, value is whether active.
     */
    static readonly ACTIVE = "ACTIVE";
    /**
     * Name of event broadcast when a new enclosing simulation rectangle has been calculated.
     */
    static readonly AUTO_SCALE = "AUTO_SCALE";
    /**
     * Name of event broadcast when the enabled state changes, value is whether enabled.
     */
    static readonly ENABLED = "ENABLED";
    /**
     * The GraphLines to auto-scale.
     */
    private graphLines_;
    /**
     *
     */
    private simView_;
    private enabled_;
    private isActive_;
    /**
     * Indicates that the SIM_RECT_CHANGED event was generated by this AutoScale.
     */
    private ownEvent_;
    /**
     * `false` indicates that the range has never been set based on graph data
     */
    private rangeSetX_;
    /**
     * `false` indicates that the range has never been set based on graph data
     */
    private rangeSetY_;
    /**
     * the maximum horizontal value of the range, used for calculating the scale
     */
    private rangeXHi_;
    /**
     * the minimum horizontal value of the range, used for calculating the scale
     */
    private rangeXLo_;
    /**
     * the maximum vertical value of the range, used for calculating the scale
     */
    private rangeYHi_;
    /**
     * the minimum vertical value of the range, used for calculating the scale
     */
    private rangeYLo_;
    /**
     * Length of time to include in the range rectangle for a 'time graph'.
     */
    private timeWindow_;
    /**
     * How much extra margin to allocate when expanding the graph range: a fraction
     * typically between 0.0 and 1.0, adds this fraction times the current horizontal or
     * vertical range.
     * This does not guarantee a margin of this amount, it merely reduces the
     * frequency of range expansion.  You could for example expand the range, and then
     * have succeeding points come very close to the new range so that the graph goes
     * very close to the edge but stays within the range.
     */
    extraMargin: number;
    /**
     * Minimum size that range rectangle can be, for width and height.
     */
    private minSize;
    private axisChoice_;
    /**
     * Index of last point seen within GraphPoints list of each GraphLine
     */
    private lastIndex_;
    /**
     * @param simView the SimView whose simRect will be modified to the range rectangle.
     */
    constructor(simView: SimView);
    /**
     * Add a GraphLine which will be observed to calculate the range rectangle of points
     * on the line.
     * @param graphLine the GraphLine to add
     */
    addGraphLine(graphLine: GraphLine): void;
    /**
     * Clears the range rectangle, continues calculating from latest entry in HistoryList.
     */
    clearRange(): void;
    /**
     * Returns whether is AutoScale is active.
     * @return whether is AutoScale is active
     */
    get active(): boolean;
    /**
     * Sets whether this AutoScale is active.  When not active, the range rectangle
     * is not updated and the SimView's simulation rectangle is not modified. When changed
     * to be active, this will also call {@link #reset}.
     *
     * The AutoScale must be enabled in order to become active, see `enabled`.
     * If not enabled, then this method can only make the AutoScale inactive.
     * @param value whether this AutoScale should be active
     */
    set active(value: boolean);
    /**
     * Returns which axis should be auto scaled.
     */
    get axisChoice(): AxisChoice;
    /**
     * Set which axis to auto scale.
     */
    set axisChoice(value: AxisChoice);
    /**
     * Returns whether is AutoScale is enabled.  See `enabled`.
     * @return whether is AutoScale is enabled
     */
    get enabled(): boolean;
    /**
     * Sets whether this AutoScale is enabled. The AutoScale must be enabled in order
     * to be active.  See `active`.
     * @param value whether this AutoScale should be enabled
     */
    set enabled(enabled: boolean);
    /**
     * Returns the range rectangle that encloses points on the GraphLines, including any
     * extra margin. Note that this rectangle might not correspond to the SimView's simulation
     * rectangle, see `axisChoice`.
     * @return the range rectangle that encloses points on the GraphLines
     */
    getRangeRect(): DoubleRect;
    /**
     * Returns length of time to include in the range rectangle for a *time graph*.
     * @return length of time to include in the range rectangle
     */
    get timeWindow(): number;
    /**
     * Sets length of time to include in the range rectangle for a *time graph*,
     * and sets the AutoScale to be active.
     * @param timeWindow length of time to include in the range rectangle
     */
    set timeWindow(timeWindow: number);
    memorize(): void;
    observe(event: SubjectEvent): void;
    /**
     * When the range rectangle changes, this will broadcast a GenericEvent named
     * `AutoScale.AUTO_SCALE`.
     */
    private rangeCheck_;
    /**
     * Remove a GraphLine, it will no longer be observed for calculating the range
     * rectangle of points on the line.
     * @param graphLine the GraphLine to remove
     */
    removeGraphLine(graphLine: GraphLine): void;
    /**
     * Clears the range rectangle, and starts calculating from first entry in HistoryList.
     * Note that you will need to call {@link #memorize} to have the range recalculated.
     */
    reset(): void;
    /**
     * Marks the SimView's Parameters as to whether they are automatically computed
     * depending on whether this AutoScale is active.
     * @param value whether this AutoScale is computing the Parameter values
     */
    private setComputed;
    /**
     * Updates the graph range to include the given point. For time variable, limit the
     * range to the timeWindow. For non-time variable, expand the range an extra amount when
     * the range is exceeded; this helps avoid too many visually distracting updates.
     * @param line
     * @param nowX
     * @param nowY
     */
    private updateRange_;
}

/**
 * Draws linear horizontal and vertical axes within a given simulation coordinates
 * rectangle. The simulation rectangle determines where the axes are drawn, and the
 * numbering scale shown.
 *
 * Axes are drawn with numbered tick marks. Axes are labeled with
 * names which can be specified by `hAxisLabel` and `vAxisLabel`. Axes
 * are drawn using specified font and color.
 *
 * Options exist for drawing the vertical axis near the left, center, or right, and for
 * drawing the horizontal axis near the top, center, or bottom of the screen. See
 * `hAxisAlign` and `vAxisAlign`.
 *
 * To keep the DisplayAxes in sync with a LabView, when
 * doing for example pan/zoom of the LabView, you can arrange for {@link #setSimRect} to
 * be called by an Observer.
 * @hidden
 */
declare class DisplayAxes implements DisplayObject {
    /**
     * bounds rectangle of area to draw
     */
    private simRect_;
    /**
     * the font to use for drawing numbers and text on the axis
     */
    private numFont_;
    /**
     * the color to draw the axes with
     */
    private drawColor_;
    /**
     * Font descent in pixels (guesstimate).
     * @todo find a way to get this for the current font, similar to the TextMetrics object.
     * http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript
     * http://pomax.nihongoresources.com/pages/Font.js/
     */
    private fontDescent;
    /**
     * Font ascent in pixels (guesstimate).
     */
    private fontAscent;
    /**
     * location of the horizontal axis, default value is BOTTOM
     */
    private hAxisAlign_;
    /**
     * location of the vertical axis, default value is LEFT
     */
    private vAxisAlign_;
    /**
     * Number of fractional decimal places to show.
     */
    private numDecimal_;
    /**
     * set when this needs to be redrawn
     */
    private needRedraw_;
    /**
     * The label for the horizontal axis.
     */
    private hLabel_;
    /**
     * The scale factor for the horizontal axis.
     */
    private hScale_;
    /**
     *
     */
    private hLabelScaleCache_;
    /**
     * The label for the vertical axis.
     */
    private vLabel_;
    /**
     * The scale factor for the vertical axis.
     */
    private vScale_;
    /**
     *
     */
    private vLabelScaleCache_;
    /**
     *
     */
    private zIndex_;
    /**
     * @param simRect the area to draw axes for in simulation coordinates.
     * @param font the Font to draw numbers and names of axes with
     * @param color the Color to draw the axes with
     */
    constructor(simRect?: DoubleRect, font?: string, color?: string);
    draw(context: CanvasRenderingContext2D, map: CoordMap): void;
    /**
     * Draws the tick marks for the horizontal axis.
     * @param y0 the vertical placement of the horizontal axis, in screen coords
     * @param context the canvas's context to draw into
     * @param map the mapping to use for translating between simulation and screen coordinates
     * @param r the view area in simulation coords
     */
    drawHorizTicks(y0: number, context: CanvasRenderingContext2D, map: CoordMap, r: DoubleRect): void;
    /**
     * Draws the tick marks for the vertical axis.
     * @param x0 the horizontal placement of the vertical axis, in screen coords
     * @param context the canvas's context to draw into
     * @param map the mapping to use for translating between simulation and screen coordinates
     * @param r the view area in simulation coords
     */
    drawVertTicks(x0: number, context: CanvasRenderingContext2D, map: CoordMap, r: DoubleRect): void;
    /**
     * Returns the color to draw the graph axes with.
     * @return the color to draw the graph axes with
     */
    get color(): string;
    /**
     * Set the color to draw the graph axes with.
     * @param color the color to draw the graph axes with
     */
    set color(color: string);
    /**
     * Returns the font to draw the graph axes with.
     * @return the font to draw the graph axes with
     */
    getFont(): string;
    /**
     * Returns the label shown next to the horizontal axis.
     */
    get hAxisLabel(): string;
    /**
     * Sets the label shown next to the horizontal axis.
     */
    set hAxisLabel(hAxisLabel: string);
    get hAxisScale(): Unit;
    /**
     * Sets the scale used for the horizontal axis.
     */
    set hAxisScale(hAxisScale: Unit);
    /**
     * Returns an increment to use for spacing of tick marks on an axis.
     * The increment should be a 'round' number, with few fractional decimal places.
     * It should divide the given range into around 5 to 7 pieces.
     *
     * Side effect: modifies the number of fractional digits to show
     *
     * @param range the span of the axis
     * @return an increment to use for spacing of tick marks on an axis.
     */
    private getNiceIncrement;
    /**
     * Returns the starting value for the tick marks on an axis.
     * @param start  the lowest value on the axis
     * @param incr  the increment between tick marks on the axis
     * @return the starting value for the tick marks on the axis.
     */
    private static getNiceStart;
    /**
     * Returns the bounding rectangle for this DisplayAxes in simulation coordinates,
     * which determines the numbering scale shown.
     * @return DoubleRect the bounding rectangle for this DisplayAxes in simulation coordinates.
     */
    getSimRect(): DoubleRect;
    /**
     * Returns the name shown next to the vertical axis.
     */
    get vAxisLabel(): string;
    /**
     * Sets the name shown next to the vertical axis.
     */
    set vAxisLabel(vAxisLabel: string);
    get vAxisScale(): Unit;
    /**
     * Sets the scale used for the horizontal axis.
     */
    set vAxisScale(vAxisScale: Unit);
    /**
     * Returns the X-axis alignment: whether it should appear at bottom, top or middle of
     * the simulation rectangle.
     */
    get hAxisAlign(): AlignV;
    /**
     * Sets the horizontal axis alignment: whether it should appear at bottom, top or middle of the
     * simulation rectangle.
     */
    set hAxisAlign(alignment: AlignV);
    /**
     * Returns the Y-axis alignment : whether it should appear at left, right or middle of
     * the simulation rectangle.
     */
    get vAxisAlign(): AlignH;
    /**
     * Sets the vertical axis alignment: whether it should appear at left, right or middle of the
     * simulation rectangle.
     */
    set vAxisAlign(alignment: AlignH);
    getZIndex(): number;
    isDragable(): boolean;
    /**
     * Whether this DisplayAxes has changed since the last time it was drawn.
     * @return true when this DisplayAxes has changed since the last time draw was called.
     */
    needsRedraw(): boolean;
    setDragable(dragable: boolean): void;
    /**
     * Set the font to draw the graph axes with.
     * @param font the font to draw the graph axes with
     */
    setFont(font: string): void;
    /**
     * Sets the bounding rectangle for this DisplayAxes in simulation coordinates; this
     * determines the numbering scale shown.
     * @param simRect the bounding rectangle for this DisplayAxes in simulation coordinates.
     */
    setSimRect(simRect: DoubleRect): void;
    setZIndex(zIndex: number): void;
}

/**
 * Creates a single graph showing several independent GraphLines, and with a horizontal
 * time axis. Because there is a single SimView and DisplayGraph, all the GraphLines are
 * plotted in the same graph coordinates. The horizontal variable can be changed to
 * something other than time. Creates an AutoScale that ensures all of the GraphLines are
 * visible. Creates several controls to modify the graph.
 *
 * This class is a user interface control. It may manipulate the DOM, adding controls.
 * @hidden
 */
declare class Graph extends AbstractSubject {
    private varsList;
    /**
     *
     */
    private readonly view;
    /**
     *
     */
    autoScale: AutoScale;
    /**
     *
     */
    axes: DisplayAxes;
    /**
     *
     */
    private displayGraph;
    /**
     *
     */
    private labCanvas;
    /**
     * The index for the time variable in the varsList.
     */
    private timeIdx_;
    /**
     *
     */
    private subscription;
    /**
     *
     */
    constructor(canvasId: string, varsList: GraphVarsList);
    protected destructor(): void;
    /**
     *
     */
    addGraphLine(hCoordIndex: number, vCoordIndex: number, color?: string): GraphLine;
    removeGraphLine(graphLine: GraphLine): void;
    memorize(): void;
    render(): void;
    reset(): void;
}

/**
 * @hidden
 * This is currently exposed to support the existing 3D example.
 */
declare class EnergyTimeGraph extends Graph {
    /**
     *
     */
    readonly translationalEnergyGraphLine: GraphLine;
    /**
     *
     */
    readonly rotationalEnergyGraphLine: GraphLine;
    /**
     *
     */
    readonly potentialEnergyGraphLine: GraphLine;
    /**
     *
     */
    readonly totalEnergyGraphLine: GraphLine;
    /**
     *
     */
    constructor(canvasId: string, varsList: VarsList);
}

/**
 * <p>
 * The solver integrates the derivatives of the kinematic variables (usually X, R, P, and J).
 * The solver can ask the simulation for derivatives at one or more system configurations
 * between the current configuration, Y(t), and the configuration Y(t + stepSize * uomStep), where
 * Y(t) is the state "vector" for the system at time t.
 * </p>
 * <p>
 * Different solvers may manage the Local Truncation Error (LTE) in different ways.
 * </p>
 * @hidden
 */
interface DiffEqSolver {
    step(stepSize: number, uomStep: Unit): void;
}

/**
 * @hidden
 */
declare class AdaptiveStepSolver<T> implements DiffEqSolver {
    private readonly energySystem;
    private readonly metric;
    private diffEq_;
    private odeSolver_;
    private secondDiff_;
    private savedState;
    stepUBound: number;
    /**
     * The smallest time step that will executed.
     * Setting a reasonable lower bound prevents the solver from taking too long to give up.
     */
    stepLBound: number;
    /**
     * enables debug code for particular test
     */
    private tolerance_;
    constructor(diffEq: Simulation, energySystem: EnergySystem<T>, diffEqSolver: DiffEqSolver, metric: Metric<T>);
    step(stepSize: number, uomStep?: Unit): void;
    /**
     * Returns whether to use second order differences for deciding when to reduce the step
     * size. i.e. whether to use change in change in energy as the criteria for accuracy.
     */
    get secondDiff(): boolean;
    /**
     * Whether to use second order differences for deciding when to reduce the step size.
     * The first difference is the change in energy of the system over a time step.
     * We can only use first differences when the energy of the system is constant.
     * If the energy of the system changes over time, then we need to reduce the step size
     * until the change of energy over the step stabilizes.  Put another way:  we reduce
     * the step size until the change in the change in energy becomes small.
     * @param value  true means use *change in change in energy* (second derivative)
     * as the criteria for accuracy
     */
    set secondDiff(value: boolean);
    /**
     * Returns the tolerance used to decide if sufficient accuracy has been achieved.
     * Default is 1E-6.
     */
    get tolerance(): number;
    /**
     * Sets the tolerance used to decide if sufficient accuracy has been achieved.
     * Default is 1E-6.
     * @param value the tolerance value for deciding if sufficient accuracy
     * has been achieved
     */
    set tolerance(value: number);
}

/**
 * An adaptive step solver that adjusts the step size in order to
 * ensure that the energy change be less than a tolerance amount.
 * @hidden
 */
declare class ConstantEnergySolver<T> implements DiffEqSolver {
    private readonly simulation;
    private energySystem_;
    private solverMethod_;
    private savedVals;
    private savedUoms;
    stepUpperBound: number;
    /**
     * The smallest time step that will executed.
     * Setting a reasonable lower bound prevents the solver from taking too long to give up.
     */
    stepLowerBound: number;
    /**
     *
     */
    private tolerance_;
    /**
     * Constructs an adaptive step solver that adjusts the step size in order to
     * ensure that the energy change be less than a tolerance amount.
     */
    constructor(simulation: Simulation, energySystem: EnergySystem<T>, solverMethod: DiffEqSolver);
    step(Δt: number, uomTime?: Unit): void;
    /**
     * Returns the tolerance used to decide if sufficient accuracy has been achieved.
     * Default is 1E-6.
     */
    get tolerance(): number;
    /**
     * Sets the tolerance used to decide if sufficient accuracy has been achieved.
     * Default is 1E-6.
     * @param value the tolerance value for deciding if sufficient accuracy
     * has been achieved
     */
    set tolerance(value: number);
}

/**
 * The Euler algorithm uses the rate of change values at the
 * beginning of the step in order to perform the integration.
 * @hidden
 */
declare class EulerMethod implements DiffEqSolver {
    private readonly system;
    private $invals;
    private $inuoms;
    private $k1vals;
    private $k1uoms;
    /**
     *
     */
    constructor(system: DiffEqSolverSystem);
    step(stepSize: number, uomStep?: Unit): void;
}

/**
 * The modified Euler algorithm uses the rate of change values at both
 * the beginning of the step and at the end, taking an average in order
 * to perform the integration.
 * @hidden
 */
declare class ModifiedEuler implements DiffEqSolver {
    private readonly system;
    private $invals;
    private $inuoms;
    private $k1vals;
    private $k1uoms;
    private $k2vals;
    private $k2uoms;
    /**
     *
     */
    constructor(system: DiffEqSolverSystem);
    step(stepSize: number, uomStep?: Unit): void;
}

/**
 * A differential equation solver that achieves O(h cubed) Local Truncation Error (LTE),
 * where h is the step size.
 * @hidden
 */
declare class RungeKutta implements DiffEqSolver {
    private readonly system;
    private invals;
    private inuoms;
    private k1vals;
    private k1uoms;
    private k2vals;
    private k2uoms;
    private k3vals;
    private k3uoms;
    private k4vals;
    private k4uoms;
    /**
     * Constructs a differential equation solver (integrator) that uses the classical Runge-Kutta method.
     * @param system The model that provides the system state and computes rates of change.
     */
    constructor(system: DiffEqSolverSystem);
    /**
     *
     */
    step(stepSize: number, uomStep?: Unit): void;
}

/**
 * @hidden
 */
interface AdvanceStrategy {
    /**
     *
     */
    advance(stepSize: number, uomStep?: Unit): void;
}

/**
 * @hidden
 */
declare class DefaultAdvanceStrategy implements AdvanceStrategy {
    private readonly simulation;
    private readonly solver;
    /**
     *
     */
    constructor(simulation: Simulation, solver: DiffEqSolver);
    /**
     * 1. Update the state vector from bodies.
     * 2. The solver integrates the derivatives from the simulation.
     * 3. Compute system variables such as energies, linear momentum, and angular momentum.
     */
    advance(stepSize: number, uomStep?: Unit): void;
}

/**
 * @hidden
 * Manages an HTML canvas and contains a list of LabView(s)
 * which are drawn into the canvas. The LabViews are drawn overlapping so that the last
 * LabView appears on top of the others.
 *
 * Canvas Size and Shape
 *
 * The HTML canvas has a specified width and height, which determines its resolution and
 * shape. The size can be changed via setWidth, setHeight, or setSize.
 * When the size of the HTML canvas changes, the LabViews are set to have the
 * same screen rectangle as the canvas.
 *
 * Each LabView has a simulation rectangle which is placed over its screen rectangle via a
 * CoordMap. The simulation rectangle specifies the simulation coordinates,
 * and the CoordMap translates simulation coordinates to screen
 * coordinates. Pan and zoom can be accomplished by changing the simulation rectangle of a
 * LabView (which changes its CoordMap accordingly).
 *
 * Focus View
 *
 * The first LabView that is added becomes the **focus view**. The focus view is treated
 * specially by some classes.
 *
 * Background Color
 *
 * Whenever {@link #paint} is called to draw a new frame, the first step is to clear the
 * old frame from the HTML canvas.
 *
 * + If no background color is specified (an empty string) then we use the
 * JavaScript `canvas.clearRect()` method which clears to transparent black pixels.
 *
 * + If a background color is specified, then we use JavaScript
 * `canvas.fillRect()` to fill the HTML canvas with that color.
 *
 * The background color can be set with {@link #setBackground}.
 *
 * Trails Effect
 *
 * A visual effect where moving objects leave behind a smeared out trail can be done by
 * setting the background color and the *alpha* transparency, see {@link #setAlpha}.
 * Here are example settings:
 *
 * simCanvas.setBackground('black');
 * simCanvas.setAlpha(0.05);
 *
 * When `alpha` is 1.0 then there is no trails effect because the old frame is entirely
 * painted over with an opaque color.
 *
 * The trails effect happens when `alpha` is less than 1 because we paint a translucent
 * rectangle over the old frame, which gradually makes the old image disappear after
 * several iterations of painting.
 *
 * ### Parameters Created
 *
 * + ParameterNumber named `LabCanvas.en.WIDTH`
 * see {@link #setWidth}
 *
 * + ParameterNumber named `LabCanvas.en.HEIGHT`
 * see {@link #setHeight}
 *
 * ### Events Broadcast
 *
 * LabCanvas broadcasts these GenericEvent(s) to its Observers:
 *
 * + {@link #VIEW_ADDED} the value of the GenericEvent is the LabView being added
 *
 * + {@link #VIEW_REMOVED} the value of the GenericEvent is the LabView being removed
 *
 * + {@link #FOCUS_VIEW_CHANGED} the value of the GenericEvent is the LabView which is
 * the focus, or `null` if there is no focus view
 *
 * + {@link #VIEW_LIST_MODIFIED}
 *
 * + {@link #SIZE_CHANGED}
 */
declare class LabCanvas extends AbstractSubject {
    /**
     * Name of GenericEvent that is broadcast when the focus view changes.
     */
    static FOCUS_VIEW_CHANGED: string;
    /**
     * Name of GenericEvent that is broadcast when the size of the HTML canvas changes.
     */
    static SIZE_CHANGED: string;
    /**
     * Name of GenericEvent that is broadcast when the list of LabViews is modified.
     */
    static VIEW_LIST_MODIFIED: string;
    /**
     * Name of GenericEvent that is broadcast when a LabView is added.
     */
    static VIEW_ADDED: string;
    /**
     * Name of GenericEvent that is broadcast when a LabView is removed.
     */
    static VIEW_REMOVED: string;
    /**
     *
     */
    private readonly canvas_;
    /**
     *
     */
    private readonly labViews_;
    /**
     *
     */
    private readonly memorizables_;
    /**
     * The view which is the main focus and is drawn normally.
     */
    private focusView_;
    /**
     * The transparency used when painting the background color; a number between
     * 0.0 (fully transparent) and 1.0 (fully opaque).
     */
    private alpha_;
    /**
     * The background color; either a CSS3 color value or the empty string. Transparent
     * black is used if it is the empty string.
     */
    private background_;
    /**
     *
     */
    /**
     *
     */
    constructor(canvas: HTMLCanvasElement);
    addMemo(memorizable: Memorizable): void;
    /**
     * Adds the LabView to the end of the list of LabViews displayed and memorized by this
     * LabCanvas. Makes the LabView the focus view if there isn't currently a focus view.
     * Notifies any Observers by broadcasting GenericEvents named {@link #VIEW_ADDED} and
     * {@link #VIEW_LIST_MODIFIED} and possibly also {@link #FOCUS_VIEW_CHANGED}.
     * @param view the LabView to add
     */
    addView(view: LabView): void;
    /**
     * Moves the keyboard focus to the HTML canvas.
     */
    focus(): void;
    /**
     * Returns the transparency used when painting; a number between 0.0 (fully transparent)
     * and 1.0 (fully opaque). Only has an effect if the background color is non-empty string.
     * @return transparency used when painting, between 0 and 1.
     */
    getAlpha(): number;
    /**
     * Returns the background color; either a CSS3 color value or the empty string. Empty
     * string means that background is cleared to transparent black.
     * @return the background color; either a CSS3 color value or the empty string.
     */
    getBackground(): string;
    /**
     * Returns the HTML canvas being managed by this LabCanvas.
     * @return the HTML canvas being managed by this LabCanvas
     */
    getCanvas(): HTMLCanvasElement;
    /**
     * Returns the CanvasRenderingContext2D used for drawing into the HTML canvas being
     * managed by this LabCanvas.
     * @return the CanvasRenderingContext2D used for drawing into the HTML canvas
     */
    getContext(): CanvasRenderingContext2D;
    /**
     * Returns the focus LabView which is the main focus of the LabCanvas.
     * @return the focus LabView, or `null` when there is no focus LabView
     */
    getFocusView(): LabView;
    /**
     * Returns the height of the HTML canvas, in screen coords (pixels).
     */
    getHeight(): number;
    getMemos(): Memorizable[];
    /**
     * Returns the ScreenRect corresponding to the area of the HTML canvas.
     * The top-left coordinate is always (0,0).  This does not represent the location
     * of the canvas within the document or window.
     */
    getScreenRect(): ScreenRect;
    /**
     * Returns list of the LabViews in this LabCanvas.
     */
    getViews(): LabView[];
    /**
     * Returns the width of the HTML canvas, in screen coords (pixels).
     */
    getWidth(): number;
    memorize(): void;
    notifySizeChanged(): void;
    /**
     * Clears the canvas to the background color; then paints each LabView.
     */
    paint(): void;
    removeMemo(memorizable: Memorizable): void;
    /**
     * Removes the LabView from the list of LabViews displayed and memorized by this
     * LabCanvas. Sets the focus view to be the first view in remaining list of LabViews.
     * Notifies any Observers by broadcasting GenericEvents named VIEW_LIST_MODIFIED
     * and IEW_REMOVED and possibly also FOCUS_VIEW_CHANGED.
     * @param view the LabView to remove
     */
    removeView(view: LabView): void;
    /**
     * Sets the transparency used when painting; a number between 0.0 (fully transparent)
     * and 1.0 (fully opaque). Only has an effect if the background color is non-empty string.
     * @param value transparency used when painting, between 0 and 1
     */
    setAlpha(value: number): void;
    /**
     * Sets the background color; either a CSS3 color value or the empty string. Empty
     * string means that background is cleared to transparent black.
     * @param value the background color; either a CSS3 color value or the empty string
     */
    setBackground(value: string): void;
    /**
     * Sets the focus LabView which is the main focus of the LabCanvas. Notifies any
     * observers that the focus has changed by broadcasting the GenericEvent named FOCUS_VIEW_CHANGED.
     * @param view the view that should be the focus; can be `null` when no LabView has the focus.
     * @throws Error if `view` is not contained by this LabCanvas
     */
    setFocusView(view: LabView): void;
    /**
     * Sets the height of the HTML canvas, and sets the screen rectangle of all the
     * LabViews. Notifies any Observers by broadcasting a GenericEvent named SIZE_CHANGED.
     * @param value  the height of the canvas, in screen coords (pixels).
     */
    setHeight(value: number): void;
    /**
     * Sets the size of this LabCanvas to the given ScreenRect by calling {@link #setSize}.
     *  @param sr  specifies the width and height; the top-left must be (0,0).
     *  @throws if the top-left of the given ScreenRect is not (0,0).
     */
    setScreenRect(sr: ScreenRect): void;
    /**
     * Sets the size of the HTML canvas. All LabViews are set to have the
     * same screen rectangle as this LabCanvas by calling setScreenRect.
     * Notifies any Observers by broadcasting a GenericEvent named SIZE_CHANGED.
     * @param width  the width of the canvas, in screen coords (pixels)
     * @param height  the height of the canvas, in screen coords (pixels)
     */
    setSize(width: number, height: number): void;
    /**
     * Sets the width of the HTML canvas, and sets the screen rectangle of all the
     * LabViews. Notifies any Observers by broadcasting a GenericEvent named SIZE_CHANGED.
     * @param value  the width of the canvas, in screen coords (pixels).
     */
    setWidth(value: number): void;
}

export { AdaptiveStepSolver, AlignH, AlignV, AxisChoice, Block1, Block2, Block3, CircularList, ConstantEnergySolver, ConstantForceLaw, ConstantForceLaw1, ConstantForceLaw2, ConstantForceLaw3, ConstantTorqueLaw, ConstantTorqueLaw1, ConstantTorqueLaw2, ConstantTorqueLaw3, CoulombLaw, Cylinder3, DefaultAdvanceStrategy, Disc2, DisplayGraph, DrawingMode, EnergyTimeGraph, Engine, Engine1, Engine2, Engine3, EngineG11, EngineG21, Euclidean2, MetricG30 as Euclidean3, EulerMethod, FaradayLaw, Force, Force1, Force2, Force3, ForceG11, ForceG21, type ForceLaw, Graph, GraphLine, GravitationForceLaw2, GravitationForceLaw3, GravitationLaw, KinematicsG10, KinematicsG20, KinematicsG30, LOCAL, LabCanvas, LinearDamper, LinearDamper1, LinearDamper2, LinearDamper3, MetricG10, ModifiedEuler, Particle, Particle1, Particle2, Particle3, ParticleG11, Physics, Physics1, Physics2, Physics3, Polygon2, RigidBody, RigidBody1, RigidBody2, RigidBody3, Rod2, RungeKutta, SimList, SimView, Sphere3, Spring, Spring1, Spring2, Spring3, SurfaceConstraint2, SurfaceConstraint3, Torque, Torque2, Torque3, VarsList, WORLD, config };
