/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { k as __spreadArray, n as __read, o as __extends, _ as __assign, s as __awaiter, t as __generator, u as __asyncValues } from './bundle-DfdVaPrt.js';
import { g as getDefaultExportFromCjs } from './_commonjsHelpers-CG9AChtV.js';

var fastDeepEqual;
var hasRequiredFastDeepEqual;

function requireFastDeepEqual () {
	if (hasRequiredFastDeepEqual) return fastDeepEqual;
	hasRequiredFastDeepEqual = 1;

	// do not edit .js files directly - edit src/index.jst



	fastDeepEqual = function equal(a, b) {
	  if (a === b) return true;

	  if (a && b && typeof a == 'object' && typeof b == 'object') {
	    if (a.constructor !== b.constructor) return false;

	    var length, i, keys;
	    if (Array.isArray(a)) {
	      length = a.length;
	      if (length != b.length) return false;
	      for (i = length; i-- !== 0;)
	        if (!equal(a[i], b[i])) return false;
	      return true;
	    }



	    if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
	    if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
	    if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();

	    keys = Object.keys(a);
	    length = keys.length;
	    if (length !== Object.keys(b).length) return false;

	    for (i = length; i-- !== 0;)
	      if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;

	    for (i = length; i-- !== 0;) {
	      var key = keys[i];

	      if (!equal(a[key], b[key])) return false;
	    }

	    return true;
	  }

	  // true if both NaN, false otherwise
	  return a!==a && b!==b;
	};
	return fastDeepEqual;
}

var fastDeepEqualExports = requireFastDeepEqual();
var deepEqual = /*@__PURE__*/getDefaultExportFromCjs(fastDeepEqualExports);

/**
 * Adds a listener to the given `target`, and returns a promise that
 * resolves with the first event emitted of the given `type`.
 *
 * @param target The target to add an event listener to.
 * @param type The event type to listen for.
 * @param opts Options to pass to `addEventListener`.
 * @returns A promise that resolves with the first event emitted of `type`.
 */
function once(target, type, opts) {
    return __awaiter(this, void 0, Promise, function () {
        return __generator(this, function (_a) {
            return [2 /*return*/, new Promise(function (resolve) {
                    function handler(event) {
                        target.removeEventListener(type, handler);
                        resolve(event);
                    }
                    target.addEventListener(type, handler, opts);
                })];
        });
    });
}

/**
 * Converts an async generator to an array of results.
 *
 * @param generator The generator to convert.
 * @returns A promise that resolves with an array of results yielded by the
 *  generator.
 */
function asArray(generator) {
    return __awaiter(this, void 0, Promise, function () {
        var res, next, e_1_1;
        var _a, generator_1, generator_1_1;
        var _b, e_1, _c, _d;
        return __generator(this, function (_e) {
            switch (_e.label) {
                case 0:
                    res = [];
                    _e.label = 1;
                case 1:
                    _e.trys.push([1, 6, 7, 12]);
                    _a = true, generator_1 = __asyncValues(generator);
                    _e.label = 2;
                case 2: return [4 /*yield*/, generator_1.next()];
                case 3:
                    if (!(generator_1_1 = _e.sent(), _b = generator_1_1.done, !_b)) return [3 /*break*/, 5];
                    _d = generator_1_1.value;
                    _a = false;
                    next = _d;
                    res.push(next);
                    _e.label = 4;
                case 4:
                    _a = true;
                    return [3 /*break*/, 2];
                case 5: return [3 /*break*/, 12];
                case 6:
                    e_1_1 = _e.sent();
                    e_1 = { error: e_1_1 };
                    return [3 /*break*/, 12];
                case 7:
                    _e.trys.push([7, , 10, 11]);
                    if (!(!_a && !_b && (_c = generator_1.return))) return [3 /*break*/, 9];
                    return [4 /*yield*/, _c.call(generator_1)];
                case 8:
                    _e.sent();
                    _e.label = 9;
                case 9: return [3 /*break*/, 11];
                case 10:
                    if (e_1) throw e_1.error;
                    return [7 /*endfinally*/];
                case 11: return [7 /*endfinally*/];
                case 12: return [2 /*return*/, res];
            }
        });
    });
}
function delay() {
    var args = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        args[_i] = arguments[_i];
    }
    return __awaiter(this, void 0, Promise, function () {
        var ms, promise, delay_1;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    ms = args[0];
                    if (!(typeof ms === 'number')) return [3 /*break*/, 4];
                    promise = args[1];
                    delay_1 = new Promise(function (resolve) { return setTimeout(resolve, ms); });
                    if (!(promise != null)) return [3 /*break*/, 2];
                    return [4 /*yield*/, delay_1];
                case 1:
                    _a.sent();
                    return [2 /*return*/, promise];
                case 2: return [2 /*return*/, delay_1];
                case 3: return [3 /*break*/, 5];
                case 4: return [2 /*return*/, Promise.reject(new TypeError('First argument to `delay` must be a number'))];
                case 5: return [2 /*return*/];
            }
        });
    });
}
function timeout() {
    var args = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        args[_i] = arguments[_i];
    }
    return __awaiter(this, void 0, Promise, function () {
        var ms, promise, timer_1, timeout_1, res;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    ms = args[0];
                    if (!(typeof ms === 'number')) return [3 /*break*/, 4];
                    promise = args[1];
                    timeout_1 = new Promise(function (_, reject) {
                        timer_1 = setTimeout(function () { return reject(new Error("Promise timed out after ".concat(ms, "ms"))); }, ms);
                    });
                    if (!(promise != null)) return [3 /*break*/, 2];
                    return [4 /*yield*/, Promise.race([promise, timeout_1])];
                case 1:
                    res = _a.sent();
                    clearTimeout(timer_1);
                    return [2 /*return*/, res];
                case 2: return [2 /*return*/, timeout_1];
                case 3: return [3 /*break*/, 5];
                case 4: return [2 /*return*/, Promise.reject('First argument to `timeout` must be a number')];
                case 5: return [2 /*return*/];
            }
        });
    });
}
/**
 * Executes and reattempts execution of an asynchronous function if it throws an
 * error. By default, this function will only retry once and reexecute
 * immediately after the previous execution throws. You can configure the number
 * of retry attempts and delays with the `maxRetries` and `delaysInMs` options.
 *
 * The `delaysInMs` is an array of delays in milliseconds for each retry
 * attempt. If there are more retry attempts than delays, the last delay will be
 * used.
 *
 * @param process The process to execute.
 * @param opts Options to configure retry behavior.
 * @returns A promise that resolves with a successful value, or the original
 *  rejected value if the process fails.
 */
function retry(process_1) {
    return __awaiter(this, arguments, Promise, function (process, opts) {
        function execute(attempt, process, opts) {
            return __awaiter(this, void 0, Promise, function () {
                var _a, delaysInMs, _b, maxRetries, delayInMs, e_2;
                return __generator(this, function (_c) {
                    switch (_c.label) {
                        case 0:
                            _a = opts.delaysInMs, delaysInMs = _a === void 0 ? [] : _a, _b = opts.maxRetries, maxRetries = _b === void 0 ? 1 : _b;
                            _c.label = 1;
                        case 1:
                            _c.trys.push([1, 4, , 8]);
                            delayInMs = attempt === 0 || delaysInMs.length === 0
                                ? 0
                                : delaysInMs[Math.min(attempt - 1, delaysInMs.length - 1)];
                            return [4 /*yield*/, delay(delayInMs)];
                        case 2:
                            _c.sent();
                            return [4 /*yield*/, process()];
                        case 3: return [2 /*return*/, _c.sent()];
                        case 4:
                            e_2 = _c.sent();
                            if (!(attempt < maxRetries)) return [3 /*break*/, 6];
                            return [4 /*yield*/, execute(attempt + 1, process, opts)];
                        case 5: return [2 /*return*/, _c.sent()];
                        case 6: throw e_2;
                        case 7: return [3 /*break*/, 8];
                        case 8: return [2 /*return*/];
                    }
                });
            });
        }
        if (opts === void 0) { opts = {}; }
        return __generator(this, function (_a) {
            return [2 /*return*/, execute(0, process, opts)];
        });
    });
}
/**
 * Returns a promise that either resolves with the result of `promise`, or a
 * value that indicates the execution was aborted.
 *
 * **Note:** Because Promises in JS cannot be canceled, an abort signal will not
 * cancel the execution of the promise.
 *
 * @param signal A signal that communicates the process should be aborted.
 * @param promise A promise who's value will be returned if not aborted.
 * @returns A value indicating if the process was aborted, or the value of
 * `promise`.
 */
function abort(signal, promise) {
    return __awaiter(this, void 0, Promise, function () {
        var controller, pendingAbort, result;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    controller = new AbortController();
                    pendingAbort = once(signal, 'abort', { signal: controller.signal });
                    return [4 /*yield*/, Promise.race([promise, pendingAbort])];
                case 1:
                    result = _a.sent();
                    if (isAbortEvent(result)) {
                        return [2 /*return*/, { aborted: true }];
                    }
                    else {
                        controller.abort();
                        return [2 /*return*/, { aborted: false, result: result }];
                    }
            }
        });
    });
}
function isAbortEvent(obj) {
    if (obj instanceof Event) {
        return obj.type === 'abort';
    }
    else
        return false;
}

var async = /*#__PURE__*/Object.freeze({
  __proto__: null,
  asArray: asArray,
  delay: delay,
  timeout: timeout,
  retry: retry,
  abort: abort
});

var rgbRegex = /rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/;
var rgbaRegex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(.+)\s*\)/;
var hexRegex = /^(#|0x)?([A-Fa-f0-9]{6})$/;
/**
 * Constructs a new color with the given red, green, blue and alpha values. If
 * alpha is undefined, defaults to 1.
 */
var create$2 = function (r, g, b, a) {
    if (a === void 0) { a = 255; }
    return { r: r, g: g, b: b, a: a };
};
/**
 * Converts a numeric color value containing red, green and blue values to a
 * `Color`. The alpha channel will default to fully opaque.
 */
var fromNumber = function (num) {
    // tslint:disable:no-bitwise
    var normalized = num & 0xffffff;
    return create$2((normalized >> 16) & 0xff, (normalized >> 8) & 0xff, normalized & 0xff);
    // tslint:enable:no-bitwise
};
/**
 * Returns a `Color` from a hex string, or undefined if the color string cannot
 * be parsed. Supports hex strings in the format of `"#00FF00"`, `"0x00FF00"` or
 * `"00FF00"`.
 */
var fromHexString = function (str) {
    var match = hexRegex.exec(str);
    if (match != null) {
        return fromNumber(parseInt(match[2], 16));
    }
};
/**
 * Creates a `Color` from a CSS color value. This function currently only
 * supports `rgb(255, 255, 255)`, `rgba(255, 255, 255, 0.5)` or `"#FFFFFF"`.
 * Returns `undefined` if the color cannot be parsed.
 */
var fromCss = function (css) {
    var rgbMatch = rgbRegex.exec(css);
    if (rgbMatch != null) {
        return create$2(parseInt(rgbMatch[1]), parseInt(rgbMatch[2]), parseInt(rgbMatch[3]));
    }
    var rgbaMatch = rgbaRegex.exec(css);
    if (rgbaMatch != null) {
        return create$2(parseInt(rgbaMatch[1]), parseInt(rgbaMatch[2]), parseInt(rgbaMatch[3]), Math.floor(parseFloat(rgbaMatch[4]) * 255));
    }
    if (hexRegex.test(css)) {
        return fromHexString(css);
    }
};
/**
 * Converts an array of four values to a `Color`. The sequence of the array is
 * expected to be `[r, g, b]` or `[r, g, b, a]`.
 */
var fromArray = function (rgba) {
    return create$2(rgba[0], rgba[1], rgba[2], rgba[3]);
};
/**
 * Returns `true` if the color's alpha channel is 0.
 */
var isInvisible = function (color) {
    return color.a === 0;
};
/**
 * Returns `true` if the alpha channel of this color is fully opaque (255).
 */
var isOpaque = function (color) {
    return color.a === 255;
};
/**
 * Converts a `Color` to a hex string. The returned string will be prefixed with
 * `#`.
 */
var toHexString = function (color) {
    return "#".concat(componentToHex(color.r)).concat(componentToHex(color.g)).concat(componentToHex(color.b));
};
var componentToHex = function (num) {
    var hex = num.toString(16);
    return hex.length === 1 ? '0' + hex : hex;
};

var color = /*#__PURE__*/Object.freeze({
  __proto__: null,
  create: create$2,
  fromNumber: fromNumber,
  fromHexString: fromHexString,
  fromCss: fromCss,
  fromArray: fromArray,
  isInvisible: isInvisible,
  isOpaque: isOpaque,
  toHexString: toHexString
});

/**
 * A module for defining functional schemas to map between different types. This
 * module is useful for parsing to or from JSON/protobufs to domain types.
 *
 * Mappers support greedy validation, so all validation errors are aggregated
 * and reported vs failing on the first invalid input.
 *
 * @example
 *
 * ```ts
 * import { Mapper as M } from '@vertexvis/utils';
 *
 * interface Address {
 *   address: string;
 *   city: string;
 *   state: string;
 *   zip: string;
 * }
 *
 * interface Person {
 *   name: string;
 *   addresses: Address[];
 * }
 *
 * type AddressJson = Partial<Address>;
 * type PersonJson = {
 *   name?: string;
 *   addresses?: AddressJson[];
 * }
 *
 * const mapAddress: M.Func<AddressJson, Address> = M.defineMapper(
 *   M.read(
 *     M.requireProp('address'),
 *     M.requireProp('city'),
 *     M.requireProp('state'),
 *     M.requireProp('zip')
 *   ),
 *   ([address, city, state, zip]) => ({
 *     address, city, state, zip
 *   })
 * );
 *
 * const mapPerson: M.Func<PersonJson, Person> = M.defineMapper(
 *   M.read(
 *     M.requireProp('name'),
 *     M.mapProp(
 *       'addresses',
 *       M.compose(M.required('addresses'), M.mapArray(mapAddress))
 *     )
 *   ),
 *   ([name, addresses]) => ({ name, addresses })
 * );
 *
 * const person = mapPerson({
 *   name: 'John',
 *   addresses: [{ address: '123', city: 'Ames', state: 'IA', zip: '50010' }]
 * });
 *
 * const invalidPerson = mapPerson({
 *   addresses: [{ city: 'Ames', state: 'IA', zip: '50010' }]
 * });
 * ```
 * // {
 * //   errors: ["Name is required.", "Address is required."]
 * // }
 *
 * @module
 */
/**
 * An error that is thrown when validation of a schema fails.
 *
 * @see {@link ifInvalidThrow} - for throwing errors on invalid input.
 */
var MapperValidationError = /** @class */ (function (_super) {
    __extends(MapperValidationError, _super);
    function MapperValidationError(errors) {
        var _this = _super.call(this, 'Validation error mapping object.') || this;
        _this.errors = errors;
        Object.setPrototypeOf(_this, MapperValidationError.prototype);
        return _this;
    }
    return MapperValidationError;
}(Error));
/**
 * Returns a mapper that asserts the input is not null or not undefined.
 *
 * @param name A name to report when invalid.
 */
function required(name) {
    return function (input) {
        if (input != null) {
            return input;
        }
        else {
            return { errors: ["".concat(name, " is required.")] };
        }
    };
}
/**
 * Returns a mapper that asserts a property on the input is not null or not
 * defined.
 *
 * @param prop The prop to assert.
 * @returns A mapper that returns the property's value.
 */
function requiredProp(prop) {
    return function (obj) {
        var value = obj[prop];
        if (value != null) {
            return value;
        }
        else {
            return { errors: ["".concat(String(prop), " is required")] };
        }
    };
}
/**
 * Returns a mapper that invokes a function if the input is not null or not
 * undefined.
 *
 * @param mapper A mapping function.
 */
function ifDefined(mapper) {
    return function (input) {
        if (input != null) {
            return mapper(input);
        }
        else {
            return input;
        }
    };
}
/**
 * Returns a mapper that extracts a property's value.
 *
 * @param prop The property to extract.
 */
function getProp(prop) {
    return function (input) {
        return input[prop];
    };
}
/**
 * Returns a mapper that will invoke a mapping function on an input's property.
 *
 * @param prop The name of the property to map over.
 * @param mapper A function that will be invoked with the property's value.
 */
function mapProp(prop, mapper) {
    return function (input) {
        var value = input[prop];
        return mapper(value);
    };
}
/**
 * Returns a mapper that will check if the given property is defined, and if so
 * invoke the given mapping function.
 *
 * @param prop The name of the property to map over.
 * @param mapper A function that will be invoked with the property's value if
 *   the property is defined.
 */
function mapRequiredProp(prop, mapper) {
    return mapProp(prop, compose(required(prop.toString()), mapper));
}
/**
 * Returns a mapper that will invoke a mapper over each value in the input
 * array. Returns `Invalid` containing errors for all invalid values in the
 * array.
 *
 * @param mapper A function that will be invoked with each array value.
 * @returns
 */
function mapArray(mapper) {
    return function (inputs) {
        if (inputs.length > 0) {
            var _a = __read(inputs), head = _a[0], tail = _a.slice(1);
            var first = mapper(head);
            return tail.reduce(function (res, input) {
                var value = mapper(input);
                if (isInvalid(value)) {
                    return isInvalid(res)
                        ? { errors: __spreadArray(__spreadArray([], __read(res.errors), false), __read(value.errors), false) }
                        : value;
                }
                else if (isInvalid(res)) {
                    return res;
                }
                else {
                    return __spreadArray(__spreadArray([], __read(res), false), [value], false);
                }
            }, isInvalid(first) ? first : [first]);
        }
        else {
            return [];
        }
    };
}
/**
 * A type guard that checks if the object is an `Invalid` type.
 */
function isInvalid(obj) {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return obj != null && obj.hasOwnProperty('errors');
}
/**
 * Returns a function that throws an error if the input is invalid. Otherwise,
 * returns the result.
 *
 * @param mapper A mapper that will be invoked with the input.
 * @throws {@link MapperValidationError} If the input is invalid.
 */
function ifInvalidThrow(mapper) {
    return function (input) {
        var value = mapper(input);
        if (isInvalid(value)) {
            throw new MapperValidationError(value.errors);
        }
        else
            return value;
    };
}
function ifValidThen(obj, f) {
    if (isInvalid(obj)) {
        return obj;
    }
    else {
        return f(obj);
    }
}
function read() {
    var mappers = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        mappers[_i] = arguments[_i];
    }
    return function (input) {
        return mappers.reduce(function (res, decoder) {
            var value = decoder(input);
            if (isInvalid(value)) {
                return isInvalid(res)
                    ? { errors: __spreadArray(__spreadArray([], __read(res.errors), false), __read(value.errors), false) }
                    : value;
            }
            else if (isInvalid(res)) {
                return res;
            }
            else {
                return __spreadArray(__spreadArray([], __read(res), false), [value], false);
            }
        }, []);
    };
}
/* eslint-enable padding-line-between-statements */
/**
 * Defines a mapper that reads the values from an input and invokes a builder to
 * transform data from one schema to another.
 *
 * @example
 *
 * ```ts
 * import { Mapper as M } from '@vertexvis/utils';
 *
 * interface Address {
 *   address: string;
 *   city: string;
 *   state: string;
 *   zip: string;
 * }
 *
 * interface Person {
 *   name: string;
 *   addresses: Address[];
 * }
 *
 * type AddressJson = Partial<Address>;
 * type PersonJson = {
 *   name?: string;
 *   addresses?: AddressJson[];
 * }
 *
 * const mapAddress: M.Func<AddressJson, Address> = M.defineMapper(
 *   M.read(
 *     M.requireProp('address'),
 *     M.requireProp('city'),
 *     M.requireProp('state'),
 *     M.requireProp('zip')
 *   ),
 *   ([address, city, state, zip]) => ({
 *     address, city, state, zip
 *   })
 * );
 *
 * const mapPerson: M.Func<PersonJson, Person> = M.defineMapper(
 *   M.read(
 *     M.requireProp('name'),
 *     M.mapProp(
 *       'addresses',
 *       M.compose(M.required('addresses'), M.mapArray(mapAddress))
 *     )
 *   ),
 *   ([name, addresses]) => ({ name, addresses })
 * )
 *
 * const person = mapPerson({
 *   name: 'John',
 *   addresses: [{ address: '123', city: 'Ames', state: 'IA', zip: '50010' }]
 * })
 * ```
 *
 * @param reader The mapper that reads values from the input an creates an
 *   intermediate format that will be passed to the `builder`.
 * @param builder A mapper that takes the output of `reader` and constructs the
 *   output format.
 * @see {@link read} - a helper function to read and validate input values.
 */
function defineMapper(reader, builder) {
    return function (input) {
        var values = reader(input);
        return ifValidThen(values, builder);
    };
}
function compose() {
    var decoders = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        decoders[_i] = arguments[_i];
    }
    return function (input) {
        return decoders.reduce(function (last, decoder) {
            if (isInvalid(last)) {
                return last;
            }
            else {
                return decoder(last);
            }
        }, input);
    };
}
function pickFirst() {
    var decoders = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        decoders[_i] = arguments[_i];
    }
    return function (input) {
        return decoders.reduce(function (value, decoder) {
            if (value === undefined) {
                return decoder(input);
            }
            else {
                return value;
            }
        }, undefined);
    };
}
/* eslint-enable padding-line-between-statements */

var mapper = /*#__PURE__*/Object.freeze({
  __proto__: null,
  MapperValidationError: MapperValidationError,
  required: required,
  requiredProp: requiredProp,
  ifDefined: ifDefined,
  getProp: getProp,
  mapProp: mapProp,
  mapRequiredProp: mapRequiredProp,
  mapArray: mapArray,
  isInvalid: isInvalid,
  ifInvalidThrow: ifInvalidThrow,
  read: read,
  defineMapper: defineMapper,
  compose: compose,
  pickFirst: pickFirst
});

function defaults() {
    var objects = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        objects[_i] = arguments[_i];
    }
    var _a = __read(objects), a = _a[0], other = _a.slice(1);
    var result = __assign({}, a);
    if (other.length === 0) {
        return result;
    }
    else if (other.length === 1) {
        var b = other[0];
        for (var key in b) {
            if (result[key] == null) {
                result[key] = b[key];
            }
            else if (isPlainObject(result[key])) {
                result[key] = defaults(result[key], b[key]);
            }
        }
        return result;
    }
    else {
        return other.reduce(function (result, next) { return defaults(result, next); }, a);
    }
}
/**
 * Returns `true` if this is a plain object, which is defined by a type created
 * by the `Object` constructor. Returns `false` otherwise.
 *
 * @example
 * ```
 * isPlainObject(Object.create({})); //=> true
 * isPlainObject(Object.create(Object.prototype)); //=> true
 * isPlainObject({foo: 'bar'}); //=> true
 * isPlainObject({}); //=> true
 *
 * isPlainObject(1); //=> false
 * isPlainObject(['foo', 'bar']); //=> false
 * isPlainObject([]); //=> false
 * isPlainObject(new Foo); //=> false
 * isPlainObject(null); //=> false
 * isPlainObject(Object.create(null)); //=> false
 * ```
 */
function isPlainObject(obj) {
    if (obj == null || typeof obj !== 'object') {
        return false;
    }
    var prototype = Object.getPrototypeOf(obj);
    return prototype != null && prototype.constructor === Object;
}
/**
 * Performs a deep comparison of two objects and returns `true` if they're
 * equal.
 *
 * This method supports comparing arrays, array buffers, booleans, date objects,
 * error objects, maps, numbers, Object objects, regexes, sets, strings,
 * symbols, and typed arrays. Object objects are compared by their own, not
 * inherited, enumerable properties. Functions and DOM nodes are compared by
 * strict equality, i.e. ===.
 *
 * @param a The object to compare with `b`.
 * @param b The object to compare with `a`.
 * @returns `true` if the two objects are equal. Otherwise `false`.
 */
function isEqual$1(a, b) {
    return deepEqual(a, b);
}
function toPairs(obj) {
    if (obj != null) {
        return Object.keys(obj).map(function (key) { return [key, obj[key]]; });
    }
    else {
        return [];
    }
}
function fromPairs(pairs) {
    if (Array.isArray(pairs)) {
        return pairs.reduce(function (result, pair) {
            var _a;
            if (pair != null) {
                return __assign(__assign({}, result), (_a = {}, _a[pair[0]] = pair[1], _a));
            }
            else {
                return result;
            }
        }, {});
    }
    else {
        return {};
    }
}
/* eslint-enable padding-line-between-statements */

var objects = /*#__PURE__*/Object.freeze({
  __proto__: null,
  defaults: defaults,
  isPlainObject: isPlainObject,
  isEqual: isEqual$1,
  toPairs: toPairs,
  fromPairs: fromPairs
});

/**
 * Returns a new `Range` with the given start and end points.
 */
var create$1 = function (start, end) { return ({ start: start, end: end }); };
/**
 * Returns a new `Range` with the start and end points at the given position.
 */
var at = function (position) { return ({
    start: position,
    end: position,
}); };
/**
 * Returns a new `Range` with the given start point and length.
 */
var withLength = function (start, len) { return ({
    start: start,
    end: start + len - 1,
}); };
/**
 * Returns a range with the start and end points shifted by the given distance.
 */
var add = function (distance, range) {
    return create$1(range.start + distance, range.end + distance);
};
/**
 * Returns a range such that `range` is constrained to the start and end points
 * of `to`. The function will try to maintain the length of the range, but will
 * shrink the range if its length is greater than `to`.
 */
var constrain = function (range, to) {
    if (contains(range, to)) {
        return range;
    }
    else if (length(range) > length(to)) {
        return to;
    }
    else if (range.start < to.start) {
        return create$1(to.start, to.start + length(range) - 1);
    }
    else {
        return create$1(to.end - length(range) + 1, to.end);
    }
};
/**
 * Checks if the given number or range is contained within another range.
 */
var contains = function (numOrRange, range) {
    if (typeof numOrRange === 'number') {
        return range.start <= numOrRange && numOrRange <= range.end;
    }
    else {
        return contains(numOrRange.start, range) && contains(numOrRange.end, range);
    }
};
/**
 * Returns a range that represents the overlap between `other` and `range`. If
 * the two ranges do not intersect, then `undefined` is returned.
 * @param other
 * @param range
 */
var intersection = function (other, range) {
    if (intersects(other, range)) {
        return create$1(Math.max(other.start, range.start), Math.min(other.end, range.end));
    }
};
/**
 * Returns `true` if `other` intersects with `range`.
 */
var intersects = function (other, range) {
    return ((other.start <= range.end && other.end >= range.start) ||
        (range.start <= other.end && range.end >= other.start));
};
/**
 * Checks if a range has the same starting point as another range.
 */
var isAt = function (other, range) {
    return other.start === range.start;
};
/**
 * Returns `true` if a range's start point is after the starting point of
 * another range.
 */
var isAfter = function (other, range) {
    return other.start > range.start;
};
/**
 * Returns `true` if a range start at or is after another range.
 */
var isAtOrAfter = function (other, range) {
    return isAt(other, range) || isAfter(other, range);
};
/**
 * Returns `true` if a range's starting point is before another range's starting
 * point.
 */
var isBefore = function (other, range) {
    return other.start < range.start;
};
/**
 * Returns `true` if a range's starting point is at or before another range's
 * starting point.
 */
var isAtOrBefore = function (other, range) {
    return isAt(other, range) || isBefore(other, range);
};
/**
 * Returns the length of a range.
 */
var length = function (range) {
    return range.end - range.start + 1;
};
/**
 * Returns a `Range` with its start and end points subtracted by the given
 * distance.
 */
var subtract = function (distance, range) {
    return add(distance * -1, range);
};
/**
 * Adjusts either the start or end position of a range so that its contained
 * within another range. Unlike `constrain`, this will not attempt to retain
 * the range's length.
 *
 * If `other` does not intersect with `to`, then the range cannot be truncated
 * and `undefined` is returned.
 */
var truncate = function (other, to) {
    if (intersects(to, other)) {
        return create$1(Math.max(other.start, to.start), Math.min(other.end, to.end));
    }
};

var range = /*#__PURE__*/Object.freeze({
  __proto__: null,
  create: create$1,
  at: at,
  withLength: withLength,
  add: add,
  constrain: constrain,
  contains: contains,
  intersection: intersection,
  intersects: intersects,
  isAt: isAt,
  isAfter: isAfter,
  isAtOrAfter: isAtOrAfter,
  isBefore: isBefore,
  isAtOrBefore: isAtOrBefore,
  length: length,
  subtract: subtract,
  truncate: truncate
});

/**
 * A comparator that sorts a number or string in ascending order.
 */
var asc = function (a, b) {
    if (a < b) {
        return -1;
    }
    else if (a > b) {
        return 1;
    }
    else {
        return 0;
    }
};
/**
 * A comparator that plucks the first element of an array and passes that value
 * to the given comparator for sorting.
 */
var head = function (comparator) {
    return function (_a, _b) {
        var _c = __read(_a, 1), a = _c[0];
        var _d = __read(_b, 1), b = _d[0];
        return comparator(a, b);
    };
};

/**
 * Parses a URI string according to RFC 3986. If the URI is an empty string,
 * then an empty object is returned.
 *
 * See https://tools.ietf.org/html/rfc3986#appendix-B for parsing rules.
 *
 * @param uri The URI to parse.
 */
var parse = function (uri) {
    var regex = /^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
    var match = regex.exec(uri);
    if (match != null) {
        return {
            scheme: match[2],
            authority: match[4],
            path: match[5],
            query: match[7],
            fragment: match[9],
        };
    }
    else {
        return {};
    }
};
/**
 * Convenience method to create a URI from a base string and add params if present
 * @param base
 * @param params
 */
var parseAndAddParams = function (baseStr, params) {
    var base = parse(baseStr);
    return params ? addQueryParams(params, base) : base;
};
var isEqual = function (a, b) {
    var queryA = JSON.stringify(sortByQueryName(queryAsArray(a)));
    var queryB = JSON.stringify(sortByQueryName(queryAsArray(b)));
    return (a.scheme === b.scheme &&
        a.authority === b.authority &&
        a.path === b.path &&
        a.fragment === b.fragment &&
        queryA === queryB);
};
var replacePath = function (path, uri) {
    var pathWithForwardSlash = path[0] === '/' ? path : "/".concat(path);
    return __assign(__assign({}, uri), { path: pathWithForwardSlash });
};
var pathAsArray = function (uri) {
    return uri.path != null ? sanitizePath(uri.path.split('/')) : [];
};
var appendPath = function (path, uri) {
    var beforeParts = pathAsArray(uri);
    var afterParts = sanitizePath(path.split('/'));
    return replacePath(beforeParts.concat(afterParts).join('/'), uri);
};
var addQueryString = function (query, uri) {
    var queryArray = stringAsQueryArray(query);
    return addQueryEntries(queryArray, uri);
};
var addQueryEntry = function (query, uri) {
    if (query[1] != null) {
        var newQuery = __spreadArray(__spreadArray([], __read(queryAsArray(uri)), false), [query], false);
        return __assign(__assign({}, uri), { query: newQuery
                .map(function (entry) { return entry.map(encodeURIComponent).join('='); })
                .join('&') });
    }
    else {
        return uri;
    }
};
var addQueryEntries = function (entries, uri) {
    return entries.reduce(function (result, entry) { return addQueryEntry(entry, result); }, uri);
};
var addQueryParams = function (params, uri) {
    return mapAsEntries(params).reduce(function (result, entry) { return addQueryEntry(entry, result); }, uri);
};
var replaceFragment = function (fragment, uri) {
    return __assign(__assign({}, uri), { fragment: fragment });
};
/**
 * Return an array of name/value pairs representing the query string of a URI.
 * The returned names and values will be URI decoded. If the query string is
 * empty, then an empty array is returned.
 *
 * @param uri A URI to return the query string for.
 */
var queryAsArray = function (uri) {
    if (uri.query != null) {
        return stringAsQueryArray(uri.query);
    }
    else {
        return [];
    }
};
var stringAsQueryArray = function (queryString) {
    return queryString
        .split('&')
        .map(function (param) {
        return param.split('=').map(function (value) { return decodeURIComponent(value); });
    });
};
/**
 * Return a map containing a URI's query string names and their values. The
 * returned names and values will be URI decoded. If the query string contains
 * multiple instances of the same name, then the last occurrence will be used.
 *
 * If the query string is empty, an empty map is returned.
 *
 * @param uri A URI to return the query string for.
 */
var queryAsMap = function (uri) {
    return queryAsArray(uri).reduce(function (map, _a) {
        var _b;
        var _c = __read(_a, 2), name = _c[0], value = _c[1];
        return __assign(__assign({}, map), (_b = {}, _b[name] = value, _b));
    }, {});
};
var toString = function (uri) {
    var result = '';
    if (uri.scheme != null && uri.scheme.length > 0) {
        result = "".concat(uri.scheme, ":");
    }
    if (uri.authority != null && uri.authority.length > 0) {
        result += "//".concat(uri.authority);
    }
    result += uri.path;
    if (uri.query != null && uri.query.length > 0) {
        result += "?".concat(uri.query);
    }
    if (uri.fragment != null && uri.fragment.length > 0) {
        result += "#".concat(uri.fragment);
    }
    return result;
};
var sanitizePath = function (path) {
    return path.filter(function (segment) { return segment.length > 0; });
};
var mapAsEntries = function (map) {
    var entries = [];
    for (var key in map) {
        entries.push([key, map[key]]);
    }
    return entries;
};
var sortByQueryName = function (entries) {
    return entries.concat().sort(head(asc));
};
/* eslint-enable @typescript-eslint/no-explicit-any */

var uri = /*#__PURE__*/Object.freeze({
  __proto__: null,
  parse: parse,
  parseAndAddParams: parseAndAddParams,
  isEqual: isEqual,
  replacePath: replacePath,
  pathAsArray: pathAsArray,
  appendPath: appendPath,
  addQueryString: addQueryString,
  addQueryEntry: addQueryEntry,
  addQueryEntries: addQueryEntries,
  addQueryParams: addQueryParams,
  replaceFragment: replaceFragment,
  queryAsArray: queryAsArray,
  queryAsMap: queryAsMap,
  toString: toString
});

function create() {
    return globalThis.crypto.randomUUID(); // synonomys with uuid.v4()
}
function fromMsbLsb(msb, lsb) {
    function digits(val, ds) {
        var hi = BigInt(1) << (ds * BigInt(4));
        return (hi | (val & (hi - BigInt(1)))).toString(16).substring(1);
    }
    var msbB = typeof msb === 'string' ? BigInt(msb) : msb;
    var lsbB = typeof lsb === 'string' ? BigInt(lsb) : lsb;
    var sec1 = digits(msbB >> BigInt(32), BigInt(8));
    var sec2 = digits(msbB >> BigInt(16), BigInt(4));
    var sec3 = digits(msbB, BigInt(4));
    var sec4 = digits(lsbB >> BigInt(48), BigInt(4));
    var sec5 = digits(lsbB, BigInt(12));
    return "".concat(sec1, "-").concat(sec2, "-").concat(sec3, "-").concat(sec4, "-").concat(sec5);
}
function toMsbLsb(id) {
    var _a = __read(id.split('-'), 5), c1 = _a[0], c2 = _a[1], c3 = _a[2], c4 = _a[3], c5 = _a[4];
    if (c1 == null || c2 == null || c3 == null || c4 == null || c5 == null) {
        throw new Error("Invalid UUID string ".concat(id));
    }
    var msb = BigInt.asIntN(64, BigInt("0x".concat(c1 + c2 + c3)));
    var lsb = BigInt.asIntN(64, BigInt("0x".concat(c4 + c5)));
    return { msb: msb.toString(), lsb: lsb.toString() };
}

var uuid = /*#__PURE__*/Object.freeze({
  __proto__: null,
  create: create,
  fromMsbLsb: fromMsbLsb,
  toMsbLsb: toMsbLsb
});

var EventDispatcher = /** @class */ (function () {
    function EventDispatcher() {
        this.listeners = [];
    }
    EventDispatcher.prototype.on = function (listener, opts) {
        var _this = this;
        var _a;
        if (opts === void 0) { opts = {}; }
        this.listeners.push(listener);
        var controller = new AbortController();
        controller.signal.addEventListener('abort', function () { return _this.off(listener); });
        (_a = opts.abort) === null || _a === void 0 ? void 0 : _a.addEventListener('abort', function () { return controller.abort(); });
        return { dispose: function () { return controller.abort(); } };
    };
    EventDispatcher.prototype.once = function (opts) {
        var _this = this;
        if (opts === void 0) { opts = {}; }
        return new Promise(function (resolve) {
            var subscription = _this.on(function (event) {
                subscription.dispose();
                resolve(event);
            }, opts);
        });
    };
    EventDispatcher.prototype.onceWhen = function (predicate_1) {
        return __awaiter(this, arguments, Promise, function (predicate, opts) {
            var controller;
            var _this = this;
            var _a;
            if (opts === void 0) { opts = {}; }
            return __generator(this, function (_b) {
                controller = new AbortController();
                (_a = opts.abort) === null || _a === void 0 ? void 0 : _a.addEventListener('abort', function () { return controller.abort(); });
                return [2 /*return*/, new Promise(function (resolve) {
                        _this.when(predicate, function (event) {
                            if (predicate(event)) {
                                controller.abort();
                                resolve(event);
                            }
                        }, __assign(__assign({}, opts), { abort: controller.signal }));
                    })];
            });
        });
    };
    EventDispatcher.prototype.when = function (predicate, listener, opts) {
        if (opts === void 0) { opts = {}; }
        return this.on(function (event) {
            if (predicate(event)) {
                listener(event);
            }
        }, opts);
    };
    EventDispatcher.prototype.off = function (listener) {
        var index = this.listeners.indexOf(listener);
        if (index !== -1) {
            this.listeners.splice(index, 1);
        }
    };
    EventDispatcher.prototype.emit = function (event) {
        this.listeners.forEach(function (listener) { return listener(event); });
    };
    return EventDispatcher;
}());

export { EventDispatcher as E, async as a, uuid as b, color as c, deepEqual as d, mapper as m, objects as o, range as r, uri as u };
//# sourceMappingURL=bundle-DLfw87TV.js.map

//# sourceMappingURL=bundle-DLfw87TV.js.map