UNPKG

arquero

Version:

Query processing and transformation of array-backed data tables.

1,651 lines (1,491 loc) 756 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.aq = {})); })(this, (function (exports) { 'use strict'; const ONE = 0x80000000; const ALL = 0xFFFFFFFF; /** * Represent an indexable set of bits. */ class BitSet { /** * Instantiate a new BitSet instance. * @param {number} size The number of bits. */ constructor(size) { this._size = size; this._bits = new Uint32Array(Math.ceil(size / 32)); } /** * The number of bits. * @return {number} */ get length() { return this._size; } /** * The number of bits set to one. * https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan * @return {number} */ count() { const n = this._bits.length; let count = 0; for (let i = 0; i < n; ++i) { for (let b = this._bits[i]; b; ++count) { b &= b - 1; } } return count; } /** * Get the bit at a given index. * @param {number} i The bit index. */ get(i) { return this._bits[i >> 5] & (ONE >>> i); } /** * Set the bit at a given index to one. * @param {number} i The bit index. */ set(i) { this._bits[i >> 5] |= (ONE >>> i); } /** * Clear the bit at a given index to zero. * @param {number} i The bit index. */ clear(i) { this._bits[i >> 5] &= ~(ONE >>> i); } /** * Scan the bits, invoking a callback function with the index of * each non-zero bit. * @param {(i: number) => void} fn A callback function. */ scan(fn) { for (let i = this.next(0); i >= 0; i = this.next(i + 1)) { fn(i); } } /** * Get the next non-zero bit starting from a given index. * @param {number} i The bit index. */ next(i) { const bits = this._bits; const n = bits.length; let index = i >> 5; let curr = bits[index] & (ALL >>> i); for (; index < n; curr = bits[++index]) { if (curr !== 0) { return (index << 5) + Math.clz32(curr); } } return -1; } /** * Return the index of the nth non-zero bit. * @param {number} n The number of non-zero bits to advance. * @return {number} The index of the nth non-zero bit. */ nth(n) { let i = this.next(0); while (n-- && i >= 0) i = this.next(i + 1); return i; } /** * Negate all bits in this bitset. * Modifies this BitSet in place. * @return {this} */ not() { const bits = this._bits; const n = bits.length; // invert all bits for (let i = 0; i < n; ++i) { bits[i] = ~bits[i]; } // unset extraneous trailing bits const tail = this._size % 32; if (tail) { bits[n - 1] &= ONE >> (tail - 1); } return this; } /** * Compute the logical AND of this BitSet and another. * @param {BitSet} bitset The BitSet to combine with. * @return {BitSet} This BitSet updated with the logical AND. */ and(bitset) { if (bitset) { const a = this._bits; const b = bitset._bits; const n = a.length; for (let i = 0; i < n; ++i) { a[i] &= b[i]; } } return this; } /** * Compute the logical OR of this BitSet and another. * @param {BitSet} bitset The BitSet to combine with. * @return {BitSet} This BitSet updated with the logical OR. */ or(bitset) { if (bitset) { const a = this._bits; const b = bitset._bits; const n = a.length; for (let i = 0; i < n; ++i) { a[i] |= b[i]; } } return this; } } /** * Truncate a value to a bin boundary. * Useful for creating equal-width histograms. * Values outside the [min, max] range will be mapped to * -Infinity (< min) or +Infinity (> max). * @param {number} value The value to bin. * @param {number} min The minimum bin boundary. * @param {number} max The maximum bin boundary. * @param {number} step The step size between bin boundaries. * @param {number} [offset=0] Offset in steps by which to adjust * the bin value. An offset of 1 will return the next boundary. */ function bin$1(value, min, max, step, offset) { return value == null ? null : value < min ? -Infinity : value > max ? +Infinity : ( value = Math.max(min, Math.min(value, max)), min + step * Math.floor(1e-14 + (value - min) / step + (offset || 0)) ); } /** * @param {*} value * @returns {value is Date} */ function isDate$1(value) { return value instanceof Date; } /** * @param {*} value * @returns {value is RegExp} */ function isRegExp(value) { return value instanceof RegExp; } function isObject(value) { return value === Object(value); } /** * Compare two values for equality, using join semantics in which null * !== null. If the inputs are object-valued, a deep equality check * of array entries or object key-value pairs is performed. * @param {*} a The first input. * @param {*} b The second input. * @return {boolean} True if equal, false if not. */ function equal(a, b) { return (a == null || b == null || a !== a || b !== b) ? false : a === b ? true : (isDate$1(a) || isDate$1(b)) ? +a === +b : (isRegExp(a) && isRegExp(b)) ? a + '' === b + '' : (isObject(a) && isObject(b)) ? deepEqual(a, b) : false; } function deepEqual(a, b) { if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) { return false; } if (a.length || b.length) { return arrayEqual(a, b); } const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) { return false; } keysA.sort(); keysB.sort(); if (!arrayEqual(keysA, keysB, (a, b) => a === b)) { return false; } const n = keysA.length; for (let i = 0; i < n; ++i) { const k = keysA[i]; if (!equal(a[k], b[k])) { return false; } } return true; } function arrayEqual(a, b, test = equal) { const n = a.length; if (n !== b.length) return false; for (let i = 0; i < n; ++i) { if (!test(a[i], b[i])) { return false; } } return true; } /** * Recodes an input value to an alternative value, based on a provided * value map. If a fallback value is specified, it will be returned when * a matching value is not found in the map; otherwise, the input value * is returned unchanged. * @template T * @param {T} value The value to recode. The value must be safely * coercible to a string for lookup against the value map. * @param {Map|Record<string,any>} map An object or Map with input values * for keys and output recoded values as values. If a non-Map object, only * the object's own properties will be considered. * @param {T} [fallback] A default fallback value to use if the input * value is not found in the value map. * @return {T} The recoded value. */ function recode(value, map, fallback) { if (map instanceof Map) { if (map.has(value)) return map.get(value); } else { const key = `${value}`; if (Object.hasOwn(map, key)) return map[key]; } return fallback !== undefined ? fallback : value; } /** * Returns an array containing an arithmetic sequence from the start value * to the stop value, in step increments. If step is positive, the last * element is the largest start + i * step less than stop; if step is * negative, the last element is the smallest start + i * step greater * than stop. If the returned array would contain an infinite number of * values, an empty range is returned. * @param {number} [start=0] The starting value of the sequence. * @param {number} [stop] The stopping value of the sequence. * The stop value is exclusive; it is not included in the result. * @param {number} [step=1] The step increment between sequence values. * @return {number[]} The generated sequence. */ function sequence(start, stop, step) { let n = arguments.length; start = +start; stop = +stop; step = n < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; n = Math.max(0, Math.ceil((stop - start) / step)) | 0; const seq = new Array(n); for (let i = 0; i < n; ++i) { seq[i] = start + i * step; } return seq; } /** * Default NULL (missing) value to use. */ const NULL = undefined; /** * @param {*} value * @returns {value is Array} */ function isArray$2(value) { return Array.isArray(value); } const TypedArray$1 = Object.getPrototypeOf(Int8Array); /** * @param {*} value * @return {value is import("../table/types.js").TypedArray} */ function isTypedArray$1(value) { return value instanceof TypedArray$1; } /** * @param {*} value * @return {value is (any[] | import('../table/types.js').TypedArray)} */ function isArrayType(value) { return isArray$2(value) || isTypedArray$1(value); } /** * @param {*} value * @return {value is String} */ function isString(value) { return typeof value === 'string'; } function isValid(value) { return value != null && value === value; } const isSeq = (seq) => isArrayType(seq) || isString(seq); /** * Returns a new compacted array with invalid values * (`null`, `undefined`, `NaN`) removed. * @template T * @param {T[]} array The input array. * @return {T[]} A compacted array. */ function compact(array) { return isArrayType(array) ? array.filter(v => isValid(v)) : array; } /** * Merges two or more arrays in sequence, returning a new array. * @template T * @param {...(T|T[])} values The arrays to merge. * @return {T[]} The merged array. */ function concat$2(...values) { return [].concat(...values); } /** * Determines whether an *array* includes a certain *value* among its * entries, returning `true` or `false` as appropriate. * @template T * @param {T[]} sequence The input array value. * @param {T} value The value to search for. * @param {number} [index=0] The integer index to start searching * from (default `0`). * @return {boolean} True if the value is included, false otherwise. */ function includes(sequence, value, index) { return isSeq(sequence) ? sequence.includes(value, index) : false; } /** * Returns the first index at which a given *value* can be found in the * *sequence* (array or string), or -1 if it is not present. * @template T * @param {T[]|string} sequence The input array or string value. * @param {T} value The value to search for. * @return {number} The index of the value, or -1 if not present. */ function indexof(sequence, value) { return isSeq(sequence) // @ts-ignore ? sequence.indexOf(value) : -1; } /** * Creates and returns a new string by concatenating all of the elements * in an *array* (or an array-like object), separated by commas or a * specified *delimiter* string. If the *array* has only one item, then * that item will be returned without using the delimiter. * @template T * @param {T[]} array The input array value. * @param {string} delim The delimiter string (default `','`). * @return {string} The joined string. */ function join$1(array, delim) { return isArrayType(array) ? array.join(delim) : NULL; } /** * Returns the last index at which a given *value* can be found in the * *sequence* (array or string), or -1 if it is not present. * @template T * @param {T[]|string} sequence The input array or string value. * @param {T} value The value to search for. * @return {number} The last index of the value, or -1 if not present. */ function lastindexof(sequence, value) { return isSeq(sequence) // @ts-ignore ? sequence.lastIndexOf(value) : -1; } /** * Returns the length of the input *sequence* (array or string). * @param {Array|string} sequence The input array or string value. * @return {number} The length of the sequence. */ function length(sequence) { return isSeq(sequence) ? sequence.length : 0; } /** * Returns a new array in which the given *property* has been extracted * for each element in the input *array*. * @param {Array} array The input array value. * @param {string} property The property name string to extract. Nested * properties are not supported: the input `"a.b"` will indicates a * property with that exact name, *not* a nested property `"b"` of * the object `"a"`. * @return {Array} An array of plucked properties. */ function pluck(array, property) { return isArrayType(array) ? array.map(v => isValid(v) ? v[property] : NULL) : NULL; } /** * Returns a new array or string with the element order reversed: the first * *sequence* element becomes the last, and the last *sequence* element * becomes the first. The input *sequence* is unchanged. * @template T * @param {T[]|string} sequence The input array or string value. * @return {T[]|string} The reversed sequence. */ function reverse(sequence) { return isArrayType(sequence) ? sequence.slice().reverse() : isString(sequence) ? sequence.split('').reverse().join('') : NULL; } /** * Returns a copy of a portion of the input *sequence* (array or string) * selected from *start* to *end* (*end* not included) where *start* and * *end* represent the index of items in the sequence. * @template T * @param {T[]|string} sequence The input array or string value. * @param {number} [start=0] The starting integer index to copy from * (inclusive, default `0`). * @param {number} [end] The ending integer index to copy from (exclusive, * default `sequence.length`). * @return {T[]|string} The sliced sequence. */ function slice$2(sequence, start, end) { return isSeq(sequence) ? sequence.slice(start, end) : NULL; } var array$1 = /*#__PURE__*/Object.freeze({ __proto__: null, compact: compact, concat: concat$2, includes: includes, indexof: indexof, join: join$1, lastindexof: lastindexof, length: length, pluck: pluck, reverse: reverse, slice: slice$2 }); function pad(value, width, char = '0') { const s = value + ''; const len = s.length; return len < width ? Array(width - len + 1).join(char) + s : s; } const pad2 = v => (v < 10 ? '0' : '') + v; const formatYear = year => year < 0 ? '-' + pad(-year, 6) : year > 9999 ? '+' + pad(year, 6) : pad(year, 4); function formatISO(year, month, date, hours, min, sec, ms, utc, short) { const suffix = utc ? 'Z' : ''; return formatYear(year) + '-' + pad2(month + 1) + '-' + pad2(date) + ( !short || ms ? 'T' + pad2(hours) + ':' + pad2(min) + ':' + pad2(sec) + '.' + pad(ms, 3) + suffix : sec ? 'T' + pad2(hours) + ':' + pad2(min) + ':' + pad2(sec) + suffix : min || hours || !utc ? 'T' + pad2(hours) + ':' + pad2(min) + suffix : '' ); } function formatDate(d, short) { return isNaN(d) ? 'Invalid Date' : formatISO( d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds(), false, short ); } function formatUTCDate(d, short) { return isNaN(d) ? 'Invalid Date' : formatISO( d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds(), true, short ); } const iso_re = /^([-+]\d{2})?\d{4}(-\d{2}(-\d{2})?)?(T\d{2}:\d{2}(:\d{2}(\.\d{3})?)?(Z|[-+]\d{2}:\d{2})?)?$/; /** * @param {string} value * @returns {boolean} */ function isISODateString(value) { return value.match(iso_re) && !isNaN(Date.parse(value)); } function parseISODate(value, parse = Date.parse) { return isISODateString(value) ? parse(value) : value; } const msMinute = 6e4; const msDay = 864e5; const msWeek = 6048e5; const t0 = new Date(); const t1 = new Date(); const t = d => ( t0.setTime(typeof d === 'string' ? parseISODate(d) : d), t0 ); /** * Returns an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) formatted * string for the given *date* in local timezone. The resulting string is * compatible with *parse_date* and JavaScript's built-in *Date.parse*. * @param {Date | number} date The input Date or timestamp value. * @param {boolean} [shorten=false] A boolean flag (default `false`) * indicating if the formatted string should be shortened if possible. * For example, the local date `2001-01-01` will shorten from * `"2001-01-01T00:00:00.000"` to `"2001-01-01T00:00"`. * @return {string} The formatted date string in local time. */ function format_date(date, shorten) { return formatDate(t(date), !shorten); } /** * Returns an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) formatted * string for the given *date* in Coordinated Universal Time (UTC). The * resulting string is compatible with *parse_date* and JavaScript's * built-in *Date.parse*. * @param {Date | number} date The input Date or timestamp value. * @param {boolean} [shorten=false] A boolean flag (default `false`) * indicating if the formatted string should be shortened if possible. * For example, the the UTC date `2001-01-01` will shorten from * `"2001-01-01T00:00:00.000Z"` to `"2001-01-01"` * @return {string} The formatted date string in UTC time. */ function format_utcdate(date, shorten){ return formatUTCDate(t(date), !shorten); } /** * Returns the number of milliseconds elapsed since midnight, January 1, * 1970 Universal Coordinated Time (UTC). * @return {number} The timestamp for now. */ function now() { return Date.now(); } /** * Returns the timestamp for a *date* as the number of milliseconds elapsed * since January 1, 1970 00:00:00 UTC. * @param {Date | number} date The input Date value. * @return {number} The timestamp value. */ function timestamp$1(date) { return +t(date); } /** * Creates and returns a new Date value. If no arguments are provided, * the current date and time are used. * @param {number} [year] The year. * @param {number} [month=0] The (zero-based) month. * @param {number} [date=1] The date within the month. * @param {number} [hours=0] The hour within the day. * @param {number} [minutes=0] The minute within the hour. * @param {number} [seconds=0] The second within the minute. * @param {number} [milliseconds=0] The milliseconds within the second. * @return {Date} The Date value. */ function datetime(year, month, date, hours, minutes, seconds, milliseconds) { return !arguments.length ? new Date(Date.now()) : new Date( year, month || 0, date == null ? 1 : date, hours || 0, minutes || 0, seconds || 0, milliseconds || 0 ); } /** * Returns the year of the specified *date* according to local time. * @param {Date | number} date The input Date or timestamp value. * @return {number} The year value in local time. */ function year(date) { return t(date).getFullYear(); } /** * Returns the zero-based quarter of the specified *date* according to * local time. * @param {Date | number} date The input Date or timestamp value. * @return {number} The quarter value in local time. */ function quarter(date) { return Math.floor(t(date).getMonth() / 3); } /** * Returns the zero-based month of the specified *date* according to local * time. A value of `0` indicates January, `1` indicates February, and so on. * @param {Date | number} date The input Date or timestamp value. * @return {number} The month value in local time. */ function month(date) { return t(date).getMonth(); } /** * Returns the week number of the year (0-53) for the specified *date* * according to local time. By default, Sunday is used as the first day * of the week. All days in a new year preceding the first Sunday are * considered to be in week 0. * @param {Date | number} date The input Date or timestamp value. * @param {number} firstday The number of first day of the week (default * `0` for Sunday, `1` for Monday and so on). * @return {number} The week of the year in local time. */ function week(date, firstday) { const i = firstday || 0; t1.setTime(+date); t1.setDate(t1.getDate() - (t1.getDay() + 7 - i) % 7); t1.setHours(0, 0, 0, 0); t0.setTime(+date); t0.setMonth(0); t0.setDate(1); t0.setDate(1 - (t0.getDay() + 7 - i) % 7); t0.setHours(0, 0, 0, 0); const tz = (t1.getTimezoneOffset() - t0.getTimezoneOffset()) * msMinute; return Math.floor((1 + (+t1 - +t0) - tz) / msWeek); } /** * Returns the date (day of month) of the specified *date* according * to local time. * @param {Date | number} date The input Date or timestamp value. * @return {number} The date (day of month) value. */ function date$1(date) { return t(date).getDate(); } /** * Returns the day of the year (1-366) of the specified *date* according * to local time. * @param {Date | number} date A date or timestamp. * @return {number} The day of the year in local time. */ function dayofyear(date) { t1.setTime(+date); t1.setHours(0, 0, 0, 0); t0.setTime(+t1); t0.setMonth(0); t0.setDate(1); const tz = (t1.getTimezoneOffset() - t0.getTimezoneOffset()) * msMinute; return Math.floor(1 + ((+t1 - +t0) - tz) / msDay); } /** * Returns the Sunday-based day of the week (0-6) of the specified *date* * according to local time. A value of `0` indicates Sunday, `1` indicates * Monday, and so on. * @param {Date | number} date The input Date or timestamp value. * @return {number} The day of the week value in local time. */ function dayofweek(date) { return t(date).getDay(); } /** * Returns the hour of the day for the specified *date* according * to local time. * @param {Date | number} date The input Date or timestamp value. * @return {number} The hour value in local time. */ function hours(date) { return t(date).getHours(); } /** * Returns the minute of the hour for the specified *date* according * to local time. * @param {Date | number} date The input Date or timestamp value. * @return {number} The minutes value in local time. */ function minutes(date) { return t(date).getMinutes(); } /** * Returns the seconds of the minute for the specified *date* according * to local time. * @param {Date | number} date The input Date or timestamp value. * @return {number} The seconds value in local time. */ function seconds(date) { return t(date).getSeconds(); } /** * Returns the milliseconds of the second for the specified *date* according * to local time. * @param {Date | number} date The input Date or timestamp value. * @return {number} The milliseconds value in local time. */ function milliseconds(date) { return t(date).getMilliseconds(); } /** * Creates and returns a new Date value using Coordinated Universal Time * (UTC). If no arguments are provided, the current date and time are used. * @param {number} [year] The year. * @param {number} [month=0] The (zero-based) month. * @param {number} [date=1] The date within the month. * @param {number} [hours=0] The hour within the day. * @param {number} [minutes=0] The minute within the hour. * @param {number} [seconds=0] The second within the minute. * @param {number} [milliseconds=0] The milliseconds within the second. * @return {Date} The Date value. */ function utcdatetime(year, month, date, hours, minutes, seconds, milliseconds) { return !arguments.length ? new Date(Date.now()) : new Date(Date.UTC( year, month || 0, date == null ? 1 : date, hours || 0, minutes || 0, seconds || 0, milliseconds || 0 )); } /** * Returns the year of the specified *date* according to Coordinated * Universal Time (UTC). * @param {Date | number} date The input Date or timestamp value. * @return {number} The year value in UTC time. */ function utcyear(date) { return t(date).getUTCFullYear(); } /** * Returns the zero-based quarter of the specified *date* according to * Coordinated Universal Time (UTC) * @param {Date | number} date The input Date or timestamp value. * @return {number} The quarter value in UTC time. */ function utcquarter(date) { return Math.floor(t(date).getUTCMonth() / 3); } /** * Returns the zero-based month of the specified *date* according to * Coordinated Universal Time (UTC). A value of `0` indicates January, * `1` indicates February, and so on. * @param {Date | number} date The input Date or timestamp value. * @return {number} The month value in UTC time. */ function utcmonth(date) { return t(date).getUTCMonth(); } /** * Returns the week number of the year (0-53) for the specified *date* * according to Coordinated Universal Time (UTC). By default, Sunday is * used as the first day of the week. All days in a new year preceding the * first Sunday are considered to be in week 0. * @param {Date | number} date The input Date or timestamp value. * @param {number} firstday The number of first day of the week (default * `0` for Sunday, `1` for Monday and so on). * @return {number} The week of the year in UTC time. */ function utcweek(date, firstday) { const i = firstday || 0; t1.setTime(+date); t1.setUTCDate(t1.getUTCDate() - (t1.getUTCDay() + 7 - i) % 7); t1.setUTCHours(0, 0, 0, 0); t0.setTime(+date); t0.setUTCMonth(0); t0.setUTCDate(1); t0.setUTCDate(1 - (t0.getUTCDay() + 7 - i) % 7); t0.setUTCHours(0, 0, 0, 0); return Math.floor((1 + (+t1 - +t0)) / msWeek); } /** * Returns the date (day of month) of the specified *date* according to * Coordinated Universal Time (UTC). * @param {Date | number} date The input Date or timestamp value. * @return {number} The date (day of month) value in UTC time. */ function utcdate(date) { return t(date).getUTCDate(); } /** * Returns the day of the year (1-366) of the specified *date* according * to Coordinated Universal Time (UTC). * @param {Date | number} date The input Date or timestamp value. * @return {number} The day of the year in UTC time. */ function utcdayofyear(date) { t1.setTime(+date); t1.setUTCHours(0, 0, 0, 0); const t0 = Date.UTC(t1.getUTCFullYear(), 0, 1); return Math.floor(1 + (+t1 - t0) / msDay); } /** * Returns the Sunday-based day of the week (0-6) of the specified *date* * according to Coordinated Universal Time (UTC). A value of `0` indicates * Sunday, `1` indicates Monday, and so on. * @param {Date | number} date The input Date or timestamp value. * @return {number} The day of the week in UTC time. */ function utcdayofweek(date) { return t(date).getUTCDay(); } /** * Returns the hour of the day for the specified *date* according to * Coordinated Universal Time (UTC). * @param {Date | number} date The input Date or timestamp value. * @return {number} The hours value in UTC time. */ function utchours(date) { return t(date).getUTCHours(); } /** * Returns the minute of the hour for the specified *date* according to * Coordinated Universal Time (UTC). * @param {Date | number} date The input Date or timestamp value. * @return {number} The minutes value in UTC time. */ function utcminutes(date) { return t(date).getUTCMinutes(); } /** * Returns the seconds of the minute for the specified *date* according to * Coordinated Universal Time (UTC). * @param {Date | number} date The input Date or timestamp value. * @return {number} The seconds value in UTC time. */ function utcseconds(date) { return t(date).getUTCSeconds(); } /** * Returns the milliseconds of the second for the specified *date* according to * Coordinated Universal Time (UTC). * @param {Date | number} date The input Date or timestamp value. * @return {number} The milliseconds value in UTC time. */ function utcmilliseconds(date) { return t(date).getUTCMilliseconds(); } var date$2 = /*#__PURE__*/Object.freeze({ __proto__: null, date: date$1, datetime: datetime, dayofweek: dayofweek, dayofyear: dayofyear, format_date: format_date, format_utcdate: format_utcdate, hours: hours, milliseconds: milliseconds, minutes: minutes, month: month, now: now, quarter: quarter, seconds: seconds, timestamp: timestamp$1, utcdate: utcdate, utcdatetime: utcdatetime, utcdayofweek: utcdayofweek, utcdayofyear: utcdayofyear, utchours: utchours, utcmilliseconds: utcmilliseconds, utcminutes: utcminutes, utcmonth: utcmonth, utcquarter: utcquarter, utcseconds: utcseconds, utcweek: utcweek, utcyear: utcyear, week: week, year: year }); /** * Parses a string *value* in JSON format, constructing the JavaScript * value or object described by the string. * @param {string} value The input string value. * @return {any} The parsed JSON. */ function parse_json(value) { return JSON.parse(value); } /** * Converts a JavaScript object or value to a JSON string. * @param {*} value The value to convert to a JSON string. * @return {string} The JSON string. */ function to_json(value) { return JSON.stringify(value); } var json = /*#__PURE__*/Object.freeze({ __proto__: null, parse_json: parse_json, to_json: to_json }); let source = Math.random; function random$1() { return source(); } /** * Set a seed value for random number generation. * If the seed is a valid number, a 32-bit linear congruential generator * with the given seed will be used to generate random values. * If the seed is null, undefined, or not a valid number, the random * number generator will revert to Math.random. * @param {number} seed The random seed value. Should either be an * integer or a fraction between 0 and 1. */ function seed(seed) { source = isValid(seed) && isFinite(seed = +seed) ? lcg(seed) : Math.random; } function lcg(seed) { const a = 0x19660D; const c = 0x3C6EF35F; const m = 1 / 0x100000000; seed = (0 <= seed && seed < 1 ? seed / m : Math.abs(seed)) | 0; // Random numbers using a Linear Congruential Generator with seed value // https://en.wikipedia.org/wiki/Linear_congruential_generator return () => (seed = a * seed + c | 0, m * (seed >>> 0)); } /** * Return a random floating point number between 0 (inclusive) and 1 * (exclusive). By default uses *Math.random*. Use the *seed* method * to instead use a seeded random number generator. * @return {number} A pseudorandom number between 0 and 1. */ function random() { return random$1(); } /** * Tests if the input *value* is not a number (`NaN`); equivalent * to *Number.isNaN*. * @param {*} value The value to test. * @return {boolean} True if the value is not a number, false otherwise. */ function is_nan(value) { return Number.isNaN(value); } /** * Tests if the input *value* is finite; equivalent to *Number.isFinite*. * @param {*} value The value to test. * @return {boolean} True if the value is finite, false otherwise. */ function is_finite(value) { return Number.isFinite(value); } /** * Returns the absolute value of the input *value*; equivalent to *Math.abs*. * @param {number} value The input number value. * @return {number} The absolute value. */ function abs(value) { return Math.abs(value); } /** * Returns the cube root value of the input *value*; equivalent to * *Math.cbrt*. * @param {number} value The input number value. * @return {number} The cube root value. */ function cbrt(value) { return Math.cbrt(value); } /** * Returns the ceiling of the input *value*, the nearest integer equal to * or greater than the input; equivalent to *Math.ceil*. * @param {number} value The input number value. * @return {number} The ceiling value. */ function ceil(value) { return Math.ceil(value); } /** * Returns the number of leading zero bits in the 32-bit binary * representation of a number *value*; equivalent to *Math.clz32*. * @param {number} value The input number value. * @return {number} The leading zero bits value. */ function clz32(value) { return Math.clz32(value); } /** * Returns *e<sup>value</sup>*, where *e* is Euler's number, the base of the * natural logarithm; equivalent to *Math.exp*. * @param {number} value The input number value. * @return {number} The base-e exponentiated value. */ function exp(value) { return Math.exp(value); } /** * Returns *e<sup>value</sup> - 1*, where *e* is Euler's number, the base of * the natural logarithm; equivalent to *Math.expm1*. * @param {number} value The input number value. * @return {number} The base-e exponentiated value minus 1. */ function expm1(value) { return Math.expm1(value); } /** * Returns the floor of the input *value*, the nearest integer equal to or * less than the input; equivalent to *Math.floor*. * @param {number} value The input number value. * @return {number} The floor value. */ function floor(value) { return Math.floor(value); } /** * Returns the nearest 32-bit single precision float representation of the * input number *value*; equivalent to *Math.fround*. Useful for translating * between 64-bit `Number` values and values from a `Float32Array`. * @param {number} value The input number value. * @return {number} The rounded value. */ function fround(value) { return Math.fround(value); } /** * Returns the greatest (maximum) value among the input *values*; equivalent * to *Math.max*. This is _not_ an aggregate function, see *op.max* to * compute a maximum value across multiple rows. * @param {...number} values The input number values. * @return {number} The greatest (maximum) value among the inputs. */ function greatest(...values) { return Math.max(...values); } /** * Returns the least (minimum) value among the input *values*; equivalent * to *Math.min*. This is _not_ an aggregate function, see *op.min* to * compute a minimum value across multiple rows. * @param {...number} values The input number values. * @return {number} The least (minimum) value among the inputs. */ function least(...values) { return Math.min(...values); } /** * Returns the natural logarithm (base *e*) of a number *value*; equivalent * to *Math.log*. * @param {number} value The input number value. * @return {number} The base-e log value. */ function log(value) { return Math.log(value); } /** * Returns the base 10 logarithm of a number *value*; equivalent * to *Math.log10*. * @param {number} value The input number value. * @return {number} The base-10 log value. */ function log10(value) { return Math.log10(value); } /** * Returns the natural logarithm (base *e*) of 1 + a number *value*; * equivalent to *Math.log1p*. * @param {number} value The input number value. * @return {number} The base-e log of value + 1. */ function log1p(value) { return Math.log1p(value); } /** * Returns the base 2 logarithm of a number *value*; equivalent * to *Math.log2*. * @param {number} value The input number value. * @return {number} The base-2 log value. */ function log2(value) { return Math.log2(value); } /** * Returns the *base* raised to the *exponent* power, that is, * *base*<sup>*exponent*</sup>; equivalent to *Math.pow*. * @param {number} base The base number value. * @param {number} exponent The exponent number value. * @return {number} The exponentiated value. */ function pow(base, exponent) { return Math.pow(base, exponent); } /** * Returns the value of a number rounded to the nearest integer; * equivalent to *Math.round*. * @param {number} value The input number value. * @return {number} The rounded value. */ function round(value) { return Math.round(value); } /** * Returns either a positive or negative +/- 1, indicating the sign of the * input *value*; equivalent to *Math.sign*. * @param {number} value The input number value. * @return {number} The sign of the value. */ function sign(value) { return Math.sign(value); } /** * Returns the square root of the input *value*; equivalent to *Math.sqrt*. * @param {number} value The input number value. * @return {number} The square root value. */ function sqrt(value) { return Math.sqrt(value); } /** * Returns the integer part of a number by removing any fractional digits; * equivalent to *Math.trunc*. * @param {number} value The input number value. * @return {number} The truncated value. */ function trunc(value) { return Math.trunc(value); } /** * Converts the input *radians* value to degrees. * @param {number} radians The input radians value. * @return {number} The value in degrees */ function degrees(radians) { return 180 * radians / Math.PI; } /** * Converts the input *degrees* value to radians. * @param {number} degrees The input degrees value. * @return {number} The value in radians. */ function radians(degrees) { return Math.PI * degrees / 180; } /** * Returns the arc-cosine (in radians) of a number *value*; * equivalent to *Math.acos*. * @param {number} value The input number value. * @return {number} The arc-cosine value. */ function acos(value) { return Math.acos(value); } /** * Returns the hyperbolic arc-cosine of a number *value*; * equivalent to *Math.acosh*. * @param {number} value The input number value. * @return {number} The hyperbolic arc-cosine value. */ function acosh(value) { return Math.acosh(value); } /** * Returns the arc-sine (in radians) of a number *value*; * equivalent to *Math.asin*. * @param {number} value The input number value. * @return {number} The arc-sine value. */ function asin(value) { return Math.asin(value); } /** * Returns the hyperbolic arc-sine of a number *value*; * equivalent to *Math.asinh*. * @param {number} value The input number value. * @return {number} The hyperbolic arc-sine value. */ function asinh(value) { return Math.asinh(value); } /** * Returns the arc-tangent (in radians) of a number *value*; * equivalent to *Math.atan*. * @param {number} value The input number value. * @return {number} The arc-tangent value. */ function atan(value) { return Math.atan(value); } /** * Returns the angle in the plane (in radians) between the positive x-axis * and the ray from (0, 0) to the point (*x*, *y*); * equivalent to *Math.atan2*. * @param {number} y The y coordinate of the point. * @param {number} x The x coordinate of the point. * @return {number} The arc-tangent angle. */ function atan2(y, x) { return Math.atan2(y, x); } /** * Returns the hyperbolic arc-tangent of a number *value*; * equivalent to *Math.atanh*. * @param {number} value The input number value. * @return {number} The hyperbolic arc-tangent value. */ function atanh(value) { return Math.atanh(value); } /** * Returns the cosine (in radians) of a number *value*; * equivalent to *Math.cos*. * @param {number} value The input number value. * @return {number} The cosine value. */ function cos(value) { return Math.cos(value); } /** * Returns the hyperbolic cosine (in radians) of a number *value*; * equivalent to *Math.cosh*. * @param {number} value The input number value. * @return {number} The hyperbolic cosine value. */ function cosh(value) { return Math.cosh(value); } /** * Returns the sine (in radians) of a number *value*; * equivalent to *Math.sin*. * @param {number} value The input number value. * @return {number} The sine value. */ function sin(value) { return Math.sin(value); } /** * Returns the hyperbolic sine (in radians) of a number *value*; * equivalent to *Math.sinh*. * @param {number} value The input number value. * @return {number} The hyperbolic sine value. */ function sinh(value) { return Math.sinh(value); } /** * Returns the tangent (in radians) of a number *value*; * equivalent to *Math.tan*. * @param {number} value The input number value. * @return {number} The tangent value. */ function tan(value) { return Math.tan(value); } /** * Returns the hyperbolic tangent (in radians) of a number *value*; * equivalent to *Math.tanh*. * @param {number} value The input number value. * @return {number} The hyperbolic tangent value. */ function tanh(value) { return Math.tanh(value); } var math = /*#__PURE__*/Object.freeze({ __proto__: null, abs: abs, acos: acos, acosh: acosh, asin: asin, asinh: asinh, atan: atan, atan2: atan2, atanh: atanh, cbrt: cbrt, ceil: ceil, clz32: clz32, cos: cos, cosh: cosh, degrees: degrees, exp: exp, expm1: expm1, floor: floor, fround: fround, greatest: greatest, is_finite: is_finite, is_nan: is_nan, least: least, log: log, log10: log10, log1p: log1p, log2: log2, pow: pow, radians: radians, random: random, round: round, sign: sign, sin: sin, sinh: sinh, sqrt: sqrt, tan: tan, tanh: tanh, trunc: trunc }); /** * @param {*} value * @return {value is Map} */ function isMap(value) { return value instanceof Map; } /** * @param {*} value * @return {value is Set} */ function isSet(value) { return value instanceof Set; } /** * @param {*} value * @return {value is Map | Set} */ function isMapOrSet(value) { return isMap(value) || isSet(value); } function array(iter) { return Array.from(iter); } /** * Returns a boolean indicating whether the *object* has the specified *key* * as its own property (as opposed to inheriting it). If the *object* is a * *Map* or *Set* instance, the *has* method will be invoked directly on the * object, otherwise *Object.hasOwnProperty* is used. * @template {string | number} K * @template V * @param {Map<K, V>|Set<K>|Record<K, V>} object The object, Map, or Set to * test for property membership. * @param {K} key The property key to test for. * @return {boolean} True if the object has the given key, false otherwise. */ function has(object, key) { return isMapOrSet(object) ? object.has(key) : object != null ? Object.hasOwn(object, `${key}`) : false; } /** * Returns an array of a given *object*'s own enumerable property names. If * the *object* is a *Map* instance, the *keys* method will be invoked * directly on the object, otherwise *Object.keys* is used. * @template {string | number} K * @template V * @param {Map<K, V>|Record<K, V>} object The input object or Map value. * @return {K[]} An array of property key name strings. */ function keys(object) { return isMap(object) ? array(object.keys()) : object != null ? Object.keys(object) : []; } /** * Returns an array of a given *object*'s own enumerable property values. If * the *object* is a *Map* or *Set* instance, the *values* method will be * invoked directly on the object, otherwise *Object.values* is used. * @template {string | number} K * @template V * @param {Map<K, V> | Set<V> | Record<K, V>} object The input object, Map, * or Set value. * @return {V[]} An array of property values. */ function values$1(object) { return isMapOrSet(object) ? array(object.values()) : object != null ? Object.values(object) : []; } /** * Returns an array of a given *object*'s own enumerable keyed property * `[key, value]` pairs. If the *object* is a *Map* or *Set* instance, the * *entries* method will be invoked directly on the object, otherwise * *Object.entries* is used. * @template {string | number} K * @template V * @param {Map<K, V> | Set<V> | Record<K, V>} object The input object, Map, * or Set value. * @return {[K, V][]} An array of property values. */ function entries$1(object) { return isMapOrSet(object) ? array(object.entries()) : object != null ? Object.entries(object) : []; } /** * Returns a new object given iterable *entries* of `[key, value]` pairs. * This method is Arquero's version of the *Object.fromEntries* method. * @template {string | number} K * @template V * @param {Iterable<[K, V]>} entries An iterable collection of `[key, value]` * pairs, such as an array of two-element arrays or a *Map*. * @return {Record<K, V>} An object of consolidated key-value pairs. */ function object(entries) { return entries ? Object.fromEntries(entries) : NULL; } var object$1 = /*#__PURE__*/Object.freeze({ __proto__: null, entries: entries$1, has: has, keys: keys, object: object, values: values$1 }); /** * Parses a string *value* and returns a Date instance. Beware: this method * uses JavaScript's *Date.parse()* functionality, which is inconsistently * implemented across browsers. That said, * [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) formatted strings such * as those produced by *op.format_date* and *op.format_utcdate* should be * supported across platforms. Note that "bare" ISO date strings such as * `"2001-01-01"` are interpreted by JavaScript as indicating midnight of * that day in Coordinated Universal Time (UTC), *not* local time. To * indicate the local timezone, an ISO string can include additional time * components and no `Z` suffix: `"2001-01-01T00:00"`. * @param {*} value The input value. * @return {Date} The parsed date value. */ function parse_date(value) { return value == null ? value : new Date(value); } /** * Parses a string *value* and returns a floating point number. * @param {*} value The input value. * @return {number} The parsed number value. */ function parse_float(value) { return value == null ? value : Number.parseFloat(value); } /** * Parses a string *value* and returns an integer of the specified radix * (the base in mathematical numeral systems). * @param {*} value The input value. * @param {number} [radix] An integer between 2 and 36 that represents the * radix (the base in mathematical numeral systems) of the string. Be * careful: this does not default to 10! If *radix* is `undefined`, `0`, * or unspecified, JavaScript assumes the following: If the input string * begins with `"0x"` or `"0X"` (a zero, followed by lowercase or * uppercase X), the radix is assumed to be 16 and the rest of the string * is parsed as a hexidecimal number. If the input string begins with `"0"` * (a zero), the radix is assumed to be 8 (octal) or 10 (decimal). Exactly * which radix is chosen is implementation-dependent. If the input string * begins with any other value, the radix is 10 (decimal). * @return {number} The parsed integer value. */ function parse_int(value, radix) { return value == null ? value : Number.parseInt(value, radix); } /** * Determines whether a string *value* ends with the characters of a * specified *search* string, returning `true` or `false` as appropriate. * @param {any} value The input string value. * @param {string} search The search string to test for. * @param {number} [length] If provided, used as the length of *value* * (default `value.length`). * @return {boolean} True if the value ends with the search string, * false otherwise. */ function endswith$1(value, search, length) { return value == null ? false : String(value).endsWith(search, length); } /** * Retrieves the result of matching a string *value* against a regular * expression *regexp*. If no *index* is specified, returns an array * whose contents depend on the presence or absence of the regular * expression global (`g`) flag, or `null` if no matches are found. If the * `g` flag is used, all results matching the complete regular expression * will be returned, but capturing groups wi