@react-querybuilder/core
Version:
React Query Builder component for constructing queries and filters, with utilities for executing them in various database and evaluation contexts
1,368 lines (1,367 loc) • 220 kB
JavaScript
const require_isRuleGroup = require('./isRuleGroup-DqAs2x4E.js');
require('./optGroupUtils-B0hTpodo.js');
const require_prepareQueryObjects = require('./prepareQueryObjects-BOUWfel5.js');
//#region ../../node_modules/jsonata/jsonata.js
var require_jsonata = /* @__PURE__ */ require_isRuleGroup.__commonJS({ "../../node_modules/jsonata/jsonata.js": ((exports, module) => {
(function(f) {
if (typeof exports === "object" && typeof module !== "undefined") module.exports = f();
else if (typeof define === "function" && define.amd) define([], f);
else {
var g;
if (typeof window !== "undefined") g = window;
else if (typeof global !== "undefined") g = global;
else if (typeof self !== "undefined") g = self;
else g = this;
g.jsonata = f();
}
})(function() {
return (function() {
function r(e, n, t) {
function o(i$1, f) {
if (!n[i$1]) {
if (!e[i$1]) {
var c = "function" == typeof require && require;
if (!f && c) return c(i$1, !0);
if (u) return u(i$1, !0);
var a = /* @__PURE__ */ new Error("Cannot find module '" + i$1 + "'");
throw a.code = "MODULE_NOT_FOUND", a;
}
var p = n[i$1] = { exports: {} };
e[i$1][0].call(p.exports, function(r$1) {
var n$1 = e[i$1][1][r$1];
return o(n$1 || r$1);
}, p, p.exports, r, e, n, t);
}
return n[i$1].exports;
}
for (var u = "function" == typeof require && require, i = 0; i < t.length; i++) o(t[i]);
return o;
}
return r;
})()({
1: [function(require$1, module$1, exports$1) {
/**
* © Copyright IBM Corp. 2018 All Rights Reserved
* Project name: JSONata
* This project is licensed under the MIT License, see LICENSE
*/
const utils = require$1("./utils");
module$1.exports = (function() {
const stringToArray = utils.stringToArray;
const few = [
"Zero",
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
"Eleven",
"Twelve",
"Thirteen",
"Fourteen",
"Fifteen",
"Sixteen",
"Seventeen",
"Eighteen",
"Nineteen"
];
const ordinals = [
"Zeroth",
"First",
"Second",
"Third",
"Fourth",
"Fifth",
"Sixth",
"Seventh",
"Eighth",
"Ninth",
"Tenth",
"Eleventh",
"Twelfth",
"Thirteenth",
"Fourteenth",
"Fifteenth",
"Sixteenth",
"Seventeenth",
"Eighteenth",
"Nineteenth"
];
const decades = [
"Twenty",
"Thirty",
"Forty",
"Fifty",
"Sixty",
"Seventy",
"Eighty",
"Ninety",
"Hundred"
];
const magnitudes = [
"Thousand",
"Million",
"Billion",
"Trillion"
];
/**
* converts a number into english words
* @param {string} value - the value to format
* @param {boolean} ordinal - ordinal or cardinal form
* @returns {string} - representation in words
*/
function numberToWords(value, ordinal) {
var lookup = function(num, prev, ord) {
var words = "";
if (num <= 19) words = (prev ? " and " : "") + (ord ? ordinals[num] : few[num]);
else if (num < 100) {
const tens = Math.floor(num / 10);
const remainder = num % 10;
words = (prev ? " and " : "") + decades[tens - 2];
if (remainder > 0) words += "-" + lookup(remainder, false, ord);
else if (ord) words = words.substring(0, words.length - 1) + "ieth";
} else if (num < 1e3) {
const hundreds = Math.floor(num / 100);
const remainder = num % 100;
words = (prev ? ", " : "") + few[hundreds] + " Hundred";
if (remainder > 0) words += lookup(remainder, true, ord);
else if (ord) words += "th";
} else {
var mag = Math.floor(Math.log10(num) / 3);
if (mag > magnitudes.length) mag = magnitudes.length;
const factor = Math.pow(10, mag * 3);
const mant = Math.floor(num / factor);
const remainder = num - mant * factor;
words = (prev ? ", " : "") + lookup(mant, false, false) + " " + magnitudes[mag - 1];
if (remainder > 0) words += lookup(remainder, true, ord);
else if (ord) words += "th";
}
return words;
};
return lookup(value, false, ordinal);
}
const wordValues = {};
few.forEach(function(word, index) {
wordValues[word.toLowerCase()] = index;
});
ordinals.forEach(function(word, index) {
wordValues[word.toLowerCase()] = index;
});
decades.forEach(function(word, index) {
const lword = word.toLowerCase();
wordValues[lword] = (index + 2) * 10;
wordValues[lword.substring(0, word.length - 1) + "ieth"] = wordValues[lword];
});
wordValues.hundredth = 100;
magnitudes.forEach(function(word, index) {
const lword = word.toLowerCase();
const val = Math.pow(10, (index + 1) * 3);
wordValues[lword] = val;
wordValues[lword + "th"] = val;
});
/**
* Converts a number in english words to numeric value
* @param {string} text - the number in words
* @returns {number} - the numeric value
*/
function wordsToNumber(text) {
const values = text.split(/,\s|\sand\s|[\s\\-]/).map((part) => wordValues[part]);
let segs = [0];
values.forEach((value) => {
if (value < 100) {
let top = segs.pop();
if (top >= 1e3) {
segs.push(top);
top = 0;
}
segs.push(top + value);
} else segs.push(segs.pop() * value);
});
return segs.reduce((a, b) => a + b, 0);
}
const romanNumerals = [
[1e3, "m"],
[900, "cm"],
[500, "d"],
[400, "cd"],
[100, "c"],
[90, "xc"],
[50, "l"],
[40, "xl"],
[10, "x"],
[9, "ix"],
[5, "v"],
[4, "iv"],
[1, "i"]
];
const romanValues = {
"M": 1e3,
"D": 500,
"C": 100,
"L": 50,
"X": 10,
"V": 5,
"I": 1
};
/**
* converts a number to roman numerals
* @param {number} value - the number
* @returns {string} - the number in roman numerals
*/
function decimalToRoman(value) {
for (var index = 0; index < romanNumerals.length; index++) {
const numeral = romanNumerals[index];
if (value >= numeral[0]) return numeral[1] + decimalToRoman(value - numeral[0]);
}
return "";
}
/**
* converts roman numerals to a number
* @param {string} roman - roman number
* @returns {number} - the numeric value
*/
function romanToDecimal(roman) {
var decimal = 0;
var max = 1;
for (var i = roman.length - 1; i >= 0; i--) {
const value = romanValues[roman[i]];
if (value < max) decimal -= value;
else {
max = value;
decimal += value;
}
}
return decimal;
}
/**
* converts a number to spreadsheet style letters
* @param {number} value - the number
* @param {string} aChar - the character representing the start of the sequence, e.g. 'A'
* @returns {string} - the letters
*/
function decimalToLetters(value, aChar) {
var letters = [];
var aCode = aChar.charCodeAt(0);
while (value > 0) {
letters.unshift(String.fromCharCode((value - 1) % 26 + aCode));
value = Math.floor((value - 1) / 26);
}
return letters.join("");
}
/**
* converts spreadsheet style letters to a number
* @param {string} letters - the letters
* @param {string} aChar - the character representing the start of the sequence, e.g. 'A'
* @returns {number} - the numeric value
*/
function lettersToDecimal(letters, aChar) {
var aCode = aChar.charCodeAt(0);
var decimal = 0;
for (var i = 0; i < letters.length; i++) decimal += (letters.charCodeAt(letters.length - i - 1) - aCode + 1) * Math.pow(26, i);
return decimal;
}
/**
* Formats an integer as specified by the XPath fn:format-integer function
* See https://www.w3.org/TR/xpath-functions-31/#func-format-integer
* @param {number} value - the number to be formatted
* @param {string} picture - the picture string that specifies the format
* @returns {string} - the formatted number
*/
function formatInteger(value, picture) {
if (typeof value === "undefined") return;
value = Math.floor(value);
const format = analyseIntegerPicture(picture);
return _formatInteger(value, format);
}
const formats = {
DECIMAL: "decimal",
LETTERS: "letters",
ROMAN: "roman",
WORDS: "words",
SEQUENCE: "sequence"
};
const tcase = {
UPPER: "upper",
LOWER: "lower",
TITLE: "title"
};
/**
* formats an integer using a preprocessed representation of the picture string
* @param {number} value - the number to be formatted
* @param {object} format - the preprocessed representation of the pucture string
* @returns {string} - the formatted number
* @private
*/
function _formatInteger(value, format) {
let formattedInteger;
const negative = value < 0;
value = Math.abs(value);
switch (format.primary) {
case formats.LETTERS:
formattedInteger = decimalToLetters(value, format.case === tcase.UPPER ? "A" : "a");
break;
case formats.ROMAN:
formattedInteger = decimalToRoman(value);
if (format.case === tcase.UPPER) formattedInteger = formattedInteger.toUpperCase();
break;
case formats.WORDS:
formattedInteger = numberToWords(value, format.ordinal);
if (format.case === tcase.UPPER) formattedInteger = formattedInteger.toUpperCase();
else if (format.case === tcase.LOWER) formattedInteger = formattedInteger.toLowerCase();
break;
case formats.DECIMAL:
formattedInteger = "" + value;
var padLength = format.mandatoryDigits - formattedInteger.length;
if (padLength > 0) formattedInteger = new Array(padLength + 1).join("0") + formattedInteger;
if (format.zeroCode !== 48) formattedInteger = stringToArray(formattedInteger).map((code) => {
return String.fromCodePoint(code.codePointAt(0) + format.zeroCode - 48);
}).join("");
if (format.regular) {
const n = Math.floor((formattedInteger.length - 1) / format.groupingSeparators.position);
for (let ii = n; ii > 0; ii--) {
const pos = formattedInteger.length - ii * format.groupingSeparators.position;
formattedInteger = formattedInteger.substr(0, pos) + format.groupingSeparators.character + formattedInteger.substr(pos);
}
} else format.groupingSeparators.reverse().forEach((separator) => {
const pos = formattedInteger.length - separator.position;
formattedInteger = formattedInteger.substr(0, pos) + separator.character + formattedInteger.substr(pos);
});
if (format.ordinal) {
var suffix = {
"1": "st",
"2": "nd",
"3": "rd"
}[formattedInteger[formattedInteger.length - 1]];
if (!suffix || formattedInteger.length > 1 && formattedInteger[formattedInteger.length - 2] === "1") suffix = "th";
formattedInteger = formattedInteger + suffix;
}
break;
case formats.SEQUENCE: throw {
code: "D3130",
value: format.token
};
}
if (negative) formattedInteger = "-" + formattedInteger;
return formattedInteger;
}
const decimalGroups = [
48,
1632,
1776,
1984,
2406,
2534,
2662,
2790,
2918,
3046,
3174,
3302,
3430,
3558,
3664,
3792,
3872,
4160,
4240,
6112,
6160,
6470,
6608,
6784,
6800,
6992,
7088,
7232,
7248,
42528,
43216,
43264,
43472,
43504,
43600,
44016,
65296
];
/**
* preprocesses the picture string
* @param {string} picture - picture string
* @returns {{type: string, primary: string, case: string, ordinal: boolean}} - analysed picture
*/
function analyseIntegerPicture(picture) {
const format = {
type: "integer",
primary: formats.DECIMAL,
case: tcase.LOWER,
ordinal: false
};
let primaryFormat, formatModifier;
const semicolon = picture.lastIndexOf(";");
if (semicolon === -1) primaryFormat = picture;
else {
primaryFormat = picture.substring(0, semicolon);
formatModifier = picture.substring(semicolon + 1);
if (formatModifier[0] === "o") format.ordinal = true;
}
switch (primaryFormat) {
case "A": format.case = tcase.UPPER;
case "a":
format.primary = formats.LETTERS;
break;
case "I": format.case = tcase.UPPER;
case "i":
format.primary = formats.ROMAN;
break;
case "W":
format.case = tcase.UPPER;
format.primary = formats.WORDS;
break;
case "Ww":
format.case = tcase.TITLE;
format.primary = formats.WORDS;
break;
case "w":
format.primary = formats.WORDS;
break;
default: {
let zeroCode = null;
let mandatoryDigits = 0;
let optionalDigits = 0;
let groupingSeparators = [];
let separatorPosition = 0;
stringToArray(primaryFormat).map((c) => c.codePointAt(0)).reverse().forEach((codePoint) => {
let digit = false;
for (let ii = 0; ii < decimalGroups.length; ii++) {
const group = decimalGroups[ii];
if (codePoint >= group && codePoint <= group + 9) {
digit = true;
mandatoryDigits++;
separatorPosition++;
if (zeroCode === null) zeroCode = group;
else if (group !== zeroCode) throw { code: "D3131" };
break;
}
}
if (!digit) if (codePoint === 35) {
separatorPosition++;
optionalDigits++;
} else groupingSeparators.push({
position: separatorPosition,
character: String.fromCodePoint(codePoint)
});
});
if (mandatoryDigits > 0) {
format.primary = formats.DECIMAL;
format.zeroCode = zeroCode;
format.mandatoryDigits = mandatoryDigits;
format.optionalDigits = optionalDigits;
const regularRepeat = function(separators) {
if (separators.length === 0) return 0;
const sepChar = separators[0].character;
for (let ii = 1; ii < separators.length; ii++) if (separators[ii].character !== sepChar) return 0;
const indexes = separators.map((separator) => separator.position);
const gcd = function(a, b) {
return b === 0 ? a : gcd(b, a % b);
};
const factor = indexes.reduce(gcd);
for (let index = 1; index <= indexes.length; index++) if (indexes.indexOf(index * factor) === -1) return 0;
return factor;
};
const regular = regularRepeat(groupingSeparators);
if (regular > 0) {
format.regular = true;
format.groupingSeparators = {
position: regular,
character: groupingSeparators[0].character
};
} else {
format.regular = false;
format.groupingSeparators = groupingSeparators;
}
} else {
format.primary = formats.SEQUENCE;
format.token = primaryFormat;
}
}
}
return format;
}
const defaultPresentationModifiers = {
Y: "1",
M: "1",
D: "1",
d: "1",
F: "n",
W: "1",
w: "1",
X: "1",
x: "1",
H: "1",
h: "1",
P: "n",
m: "01",
s: "01",
f: "1",
Z: "01:01",
z: "01:01",
C: "n",
E: "n"
};
/**
* analyse the date-time picture string
* @param {string} picture - picture string
* @returns {{type: string, parts: Array}} - the analysed string
*/
function analyseDateTimePicture(picture) {
var spec = [];
const format = {
type: "datetime",
parts: spec
};
const addLiteral = function(start$1, end) {
if (end > start$1) {
let literal = picture.substring(start$1, end);
literal = literal.split("]]").join("]");
spec.push({
type: "literal",
value: literal
});
}
};
var start = 0, pos = 0;
while (pos < picture.length) {
if (picture.charAt(pos) === "[") {
if (picture.charAt(pos + 1) === "[") {
addLiteral(start, pos);
spec.push({
type: "literal",
value: "["
});
pos += 2;
start = pos;
continue;
}
addLiteral(start, pos);
start = pos;
pos = picture.indexOf("]", start);
if (pos === -1) throw { code: "D3135" };
let marker = picture.substring(start + 1, pos);
marker = marker.split(/\s+/).join("");
var def = {
type: "marker",
component: marker.charAt(0)
};
var comma = marker.lastIndexOf(",");
var presMod;
if (comma !== -1) {
const widthMod = marker.substring(comma + 1);
const dash = widthMod.indexOf("-");
let min, max;
const parseWidth = function(wm) {
if (typeof wm === "undefined" || wm === "*") return;
else return parseInt(wm);
};
if (dash === -1) min = widthMod;
else {
min = widthMod.substring(0, dash);
max = widthMod.substring(dash + 1);
}
def.width = {
min: parseWidth(min),
max: parseWidth(max)
};
presMod = marker.substring(1, comma);
} else presMod = marker.substring(1);
if (presMod.length === 1) def.presentation1 = presMod;
else if (presMod.length > 1) {
var lastChar = presMod.charAt(presMod.length - 1);
if ("atco".indexOf(lastChar) !== -1) {
def.presentation2 = lastChar;
if (lastChar === "o") def.ordinal = true;
def.presentation1 = presMod.substring(0, presMod.length - 1);
} else def.presentation1 = presMod;
} else def.presentation1 = defaultPresentationModifiers[def.component];
if (typeof def.presentation1 === "undefined") throw {
code: "D3132",
value: def.component
};
if (def.presentation1[0] === "n") def.names = tcase.LOWER;
else if (def.presentation1[0] === "N") if (def.presentation1[1] === "n") def.names = tcase.TITLE;
else def.names = tcase.UPPER;
else if ("YMDdFWwXxHhmsf".indexOf(def.component) !== -1) {
var integerPattern = def.presentation1;
if (def.presentation2) integerPattern += ";" + def.presentation2;
def.integerFormat = analyseIntegerPicture(integerPattern);
if (def.width && def.width.min !== void 0) {
if (def.integerFormat.mandatoryDigits < def.width.min) def.integerFormat.mandatoryDigits = def.width.min;
}
if (def.component === "Y") {
def.n = -1;
if (def.width && def.width.max !== void 0) {
def.n = def.width.max;
def.integerFormat.mandatoryDigits = def.n;
} else {
var w = def.integerFormat.mandatoryDigits + def.integerFormat.optionalDigits;
if (w >= 2) def.n = w;
}
}
const previousPart = spec[spec.length - 1];
if (previousPart && previousPart.integerFormat) previousPart.integerFormat.parseWidth = previousPart.integerFormat.mandatoryDigits;
}
if (def.component === "Z" || def.component === "z") def.integerFormat = analyseIntegerPicture(def.presentation1);
spec.push(def);
start = pos + 1;
}
pos++;
}
addLiteral(start, pos);
return format;
}
const days = [
"",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
];
const months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
];
const millisInADay = 1e3 * 60 * 60 * 24;
const startOfFirstWeek = function(ym) {
const jan1 = Date.UTC(ym.year, ym.month);
var dayOfJan1 = new Date(jan1).getUTCDay();
if (dayOfJan1 === 0) dayOfJan1 = 7;
return dayOfJan1 > 4 ? jan1 + (8 - dayOfJan1) * millisInADay : jan1 - (dayOfJan1 - 1) * millisInADay;
};
const yearMonth = function(year, month) {
return {
year,
month,
nextMonth: function() {
return month === 11 ? yearMonth(year + 1, 0) : yearMonth(year, month + 1);
},
previousMonth: function() {
return month === 0 ? yearMonth(year - 1, 11) : yearMonth(year, month - 1);
},
nextYear: function() {
return yearMonth(year + 1, month);
},
previousYear: function() {
return yearMonth(year - 1, month);
}
};
};
const deltaWeeks = function(start, end) {
return (end - start) / (millisInADay * 7) + 1;
};
const getDateTimeFragment = (date, component) => {
let componentValue;
switch (component) {
case "Y":
componentValue = date.getUTCFullYear();
break;
case "M":
componentValue = date.getUTCMonth() + 1;
break;
case "D":
componentValue = date.getUTCDate();
break;
case "d":
componentValue = (Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) - Date.UTC(date.getUTCFullYear(), 0)) / millisInADay + 1;
break;
case "F":
componentValue = date.getUTCDay();
if (componentValue === 0) componentValue = 7;
break;
case "W": {
const thisYear = yearMonth(date.getUTCFullYear(), 0);
const startOfWeek1 = startOfFirstWeek(thisYear);
const today = Date.UTC(thisYear.year, date.getUTCMonth(), date.getUTCDate());
let week = deltaWeeks(startOfWeek1, today);
if (week > 52) {
if (today >= startOfFirstWeek(thisYear.nextYear())) week = 1;
} else if (week < 1) week = deltaWeeks(startOfFirstWeek(thisYear.previousYear()), today);
componentValue = Math.floor(week);
break;
}
case "w": {
const thisMonth = yearMonth(date.getUTCFullYear(), date.getUTCMonth());
const startOfWeek1 = startOfFirstWeek(thisMonth);
const today = Date.UTC(thisMonth.year, thisMonth.month, date.getUTCDate());
let week = deltaWeeks(startOfWeek1, today);
if (week > 4) {
if (today >= startOfFirstWeek(thisMonth.nextMonth())) week = 1;
} else if (week < 1) week = deltaWeeks(startOfFirstWeek(thisMonth.previousMonth()), today);
componentValue = Math.floor(week);
break;
}
case "X": {
const thisYear = yearMonth(date.getUTCFullYear(), 0);
const startOfISOYear = startOfFirstWeek(thisYear);
const endOfISOYear = startOfFirstWeek(thisYear.nextYear());
const now = date.getTime();
if (now < startOfISOYear) componentValue = thisYear.year - 1;
else if (now >= endOfISOYear) componentValue = thisYear.year + 1;
else componentValue = thisYear.year;
break;
}
case "x": {
const thisMonth = yearMonth(date.getUTCFullYear(), date.getUTCMonth());
const startOfISOMonth = startOfFirstWeek(thisMonth);
const nextMonth = thisMonth.nextMonth();
const endOfISOMonth = startOfFirstWeek(nextMonth);
const now = date.getTime();
if (now < startOfISOMonth) componentValue = thisMonth.previousMonth().month + 1;
else if (now >= endOfISOMonth) componentValue = nextMonth.month + 1;
else componentValue = thisMonth.month + 1;
break;
}
case "H":
componentValue = date.getUTCHours();
break;
case "h":
componentValue = date.getUTCHours();
componentValue = componentValue % 12;
if (componentValue === 0) componentValue = 12;
break;
case "P":
componentValue = date.getUTCHours() >= 12 ? "pm" : "am";
break;
case "m":
componentValue = date.getUTCMinutes();
break;
case "s":
componentValue = date.getUTCSeconds();
break;
case "f":
componentValue = date.getUTCMilliseconds();
break;
case "Z":
case "z": break;
case "C":
componentValue = "ISO";
break;
case "E":
componentValue = "ISO";
break;
}
return componentValue;
};
let iso8601Spec = null;
/**
* formats the date/time as specified by the XPath fn:format-dateTime function
* @param {number} millis - the timestamp to be formatted, in millis since the epoch
* @param {string} picture - the picture string that specifies the format
* @param {string} timezone - the timezone to use
* @returns {string} - the formatted timestamp
*/
function formatDateTime(millis, picture, timezone) {
var offsetHours = 0;
var offsetMinutes = 0;
if (typeof timezone !== "undefined") {
const offset = parseInt(timezone);
offsetHours = Math.floor(offset / 100);
offsetMinutes = offset % 100;
}
var formatComponent = function(date, markerSpec) {
var componentValue = getDateTimeFragment(date, markerSpec.component);
if ("YMDdFWwXxHhms".indexOf(markerSpec.component) !== -1) {
if (markerSpec.component === "Y") {
if (markerSpec.n !== -1) componentValue = componentValue % Math.pow(10, markerSpec.n);
}
if (markerSpec.names) {
if (markerSpec.component === "M" || markerSpec.component === "x") componentValue = months[componentValue - 1];
else if (markerSpec.component === "F") componentValue = days[componentValue];
else throw {
code: "D3133",
value: markerSpec.component
};
if (markerSpec.names === tcase.UPPER) componentValue = componentValue.toUpperCase();
else if (markerSpec.names === tcase.LOWER) componentValue = componentValue.toLowerCase();
if (markerSpec.width && componentValue.length > markerSpec.width.max) componentValue = componentValue.substring(0, markerSpec.width.max);
} else componentValue = _formatInteger(componentValue, markerSpec.integerFormat);
} else if (markerSpec.component === "f") componentValue = _formatInteger(componentValue, markerSpec.integerFormat);
else if (markerSpec.component === "Z" || markerSpec.component === "z") {
const offset = offsetHours * 100 + offsetMinutes;
if (markerSpec.integerFormat.regular) componentValue = _formatInteger(offset, markerSpec.integerFormat);
else {
const numDigits = markerSpec.integerFormat.mandatoryDigits;
if (numDigits === 1 || numDigits === 2) {
componentValue = _formatInteger(offsetHours, markerSpec.integerFormat);
if (offsetMinutes !== 0) componentValue += ":" + formatInteger(offsetMinutes, "00");
} else if (numDigits === 3 || numDigits === 4) componentValue = _formatInteger(offset, markerSpec.integerFormat);
else throw {
code: "D3134",
value: numDigits
};
}
if (offset >= 0) componentValue = "+" + componentValue;
if (markerSpec.component === "z") componentValue = "GMT" + componentValue;
if (offset === 0 && markerSpec.presentation2 === "t") componentValue = "Z";
} else if (markerSpec.component === "P") {
if (markerSpec.names === tcase.UPPER) componentValue = componentValue.toUpperCase();
}
return componentValue;
};
let formatSpec;
if (typeof picture === "undefined") {
if (iso8601Spec === null) iso8601Spec = analyseDateTimePicture("[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f001][Z01:01t]");
formatSpec = iso8601Spec;
} else formatSpec = analyseDateTimePicture(picture);
const offsetMillis = (60 * offsetHours + offsetMinutes) * 60 * 1e3;
const dateTime = new Date(millis + offsetMillis);
let result = "";
formatSpec.parts.forEach(function(part) {
if (part.type === "literal") result += part.value;
else result += formatComponent(dateTime, part);
});
return result;
}
/**
* Generate a regex to parse integers or timestamps
* @param {object} formatSpec - object representing the format
* @returns {object} - regex
*/
function generateRegex(formatSpec) {
var matcher = {};
if (formatSpec.type === "datetime") {
matcher.type = "datetime";
matcher.parts = formatSpec.parts.map(function(part) {
var res = {};
if (part.type === "literal") res.regex = part.value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
else if (part.component === "Z" || part.component === "z") {
let separator;
if (!Array.isArray(part.integerFormat.groupingSeparators)) separator = part.integerFormat.groupingSeparators;
res.regex = "";
if (part.component === "z") res.regex = "GMT";
res.regex += "[-+][0-9]+";
if (separator) res.regex += separator.character + "[0-9]+";
res.parse = function(value) {
if (part.component === "z") value = value.substring(3);
let offsetHours = 0, offsetMinutes = 0;
if (separator) {
offsetHours = Number.parseInt(value.substring(0, value.indexOf(separator.character)));
offsetMinutes = Number.parseInt(value.substring(value.indexOf(separator.character) + 1));
} else if (value.length - 1 <= 2) offsetHours = Number.parseInt(value);
else {
offsetHours = Number.parseInt(value.substring(0, 3));
offsetMinutes = Number.parseInt(value.substring(3));
}
return offsetHours * 60 + offsetMinutes;
};
} else if (part.integerFormat) res = generateRegex(part.integerFormat);
else {
res.regex = "[a-zA-Z]+";
var lookup = {};
if (part.component === "M" || part.component === "x") months.forEach(function(name, index) {
if (part.width && part.width.max) lookup[name.substring(0, part.width.max)] = index + 1;
else lookup[name] = index + 1;
});
else if (part.component === "F") days.forEach(function(name, index) {
if (index > 0) if (part.width && part.width.max) lookup[name.substring(0, part.width.max)] = index;
else lookup[name] = index;
});
else if (part.component === "P") lookup = {
"am": 0,
"AM": 0,
"pm": 1,
"PM": 1
};
else throw {
code: "D3133",
value: part.component
};
res.parse = function(value) {
return lookup[value];
};
}
res.component = part.component;
return res;
});
} else {
matcher.type = "integer";
const isUpper = formatSpec.case === tcase.UPPER;
switch (formatSpec.primary) {
case formats.LETTERS:
matcher.regex = isUpper ? "[A-Z]+" : "[a-z]+";
matcher.parse = function(value) {
return lettersToDecimal(value, isUpper ? "A" : "a");
};
break;
case formats.ROMAN:
matcher.regex = isUpper ? "[MDCLXVI]+" : "[mdclxvi]+";
matcher.parse = function(value) {
return romanToDecimal(isUpper ? value : value.toUpperCase());
};
break;
case formats.WORDS:
matcher.regex = "(?:" + Object.keys(wordValues).concat("and", "[\\-, ]").join("|") + ")+";
matcher.parse = function(value) {
return wordsToNumber(value.toLowerCase());
};
break;
case formats.DECIMAL:
matcher.regex = "[0-9]";
if (formatSpec.parseWidth) matcher.regex += `{${formatSpec.parseWidth}}`;
else matcher.regex += "+";
if (formatSpec.ordinal) matcher.regex += "(?:th|st|nd|rd)";
matcher.parse = function(value) {
let digits = value;
if (formatSpec.ordinal) digits = value.substring(0, value.length - 2);
if (formatSpec.regular) digits = digits.split(",").join("");
else formatSpec.groupingSeparators.forEach((sep) => {
digits = digits.split(sep.character).join("");
});
if (formatSpec.zeroCode !== 48) digits = digits.split("").map((char) => String.fromCodePoint(char.codePointAt(0) - formatSpec.zeroCode + 48)).join("");
return parseInt(digits);
};
break;
case formats.SEQUENCE: throw {
code: "D3130",
value: formatSpec.token
};
}
}
return matcher;
}
/**
* parse a string containing an integer as specified by the picture string
* @param {string} value - the string to parse
* @param {string} picture - the picture string
* @returns {number} - the parsed number
*/
function parseInteger(value, picture) {
if (typeof value === "undefined") return;
return generateRegex(analyseIntegerPicture(picture)).parse(value);
}
/**
* parse a string containing a timestamp as specified by the picture string
* @param {string} timestamp - the string to parse
* @param {string} picture - the picture string
* @returns {number} - the parsed timestamp in millis since the epoch
*/
function parseDateTime(timestamp, picture) {
const matchSpec = generateRegex(analyseDateTimePicture(picture));
const fullRegex = "^" + matchSpec.parts.map((part) => "(" + part.regex + ")").join("") + "$";
var info = new RegExp(fullRegex, "i").exec(timestamp);
if (info !== null) {
const dmA = 161;
const dmB = 130;
const dmC = 84;
const dmD = 72;
const tmA = 23;
const tmB = 47;
const components = {};
for (let i = 1; i < info.length; i++) {
const mpart = matchSpec.parts[i - 1];
if (mpart.parse) components[mpart.component] = mpart.parse(info[i]);
}
if (Object.getOwnPropertyNames(components).length === 0) return;
let mask = 0;
const shift = (bit) => {
mask <<= 1;
mask += bit ? 1 : 0;
};
const isType = (type) => {
return !(~type & mask) && !!(type & mask);
};
"YXMxWwdD".split("").forEach((part) => shift(components[part]));
const dateB = !isType(dmA) && isType(dmB);
const dateC = isType(dmC);
const dateD = !dateC && isType(dmD);
mask = 0;
"PHhmsf".split("").forEach((part) => shift(components[part]));
const timeB = !isType(tmA) && isType(tmB);
const comps = (dateB ? "YD" : dateC ? "XxwF" : dateD ? "XWF" : "YMD") + (timeB ? "Phmsf" : "Hmsf");
const now = this.environment.timestamp;
let startSpecified = false;
let endSpecified = false;
comps.split("").forEach((part) => {
if (typeof components[part] === "undefined") if (startSpecified) {
components[part] = "MDd".indexOf(part) !== -1 ? 1 : 0;
endSpecified = true;
} else components[part] = getDateTimeFragment(now, part);
else {
startSpecified = true;
if (endSpecified) throw { code: "D3136" };
}
});
if (components.M > 0) components.M -= 1;
else components.M = 0;
if (dateB) {
const firstJan = Date.UTC(components.Y, 0);
const offsetMillis = (components.d - 1) * 1e3 * 60 * 60 * 24;
const derivedDate = new Date(firstJan + offsetMillis);
components.M = derivedDate.getUTCMonth();
components.D = derivedDate.getUTCDate();
}
if (dateC) throw { code: "D3136" };
if (dateD) throw { code: "D3136" };
if (timeB) {
components.H = components.h === 12 ? 0 : components.h;
if (components.P === 1) components.H += 12;
}
var millis = Date.UTC(components.Y, components.M, components.D, components.H, components.m, components.s, components.f);
if (components.Z || components.z) millis -= (components.Z || components.z) * 60 * 1e3;
return millis;
}
}
var iso8601regex = /* @__PURE__ */ new RegExp("^\\d{4}(-[01]\\d)*(-[0-3]\\d)*(T[0-2]\\d:[0-5]\\d:[0-5]\\d)*(\\.\\d+)?([+-][0-2]\\d:?[0-5]\\d|Z)?$");
/**
* Converts an ISO 8601 timestamp to milliseconds since the epoch
*
* @param {string} timestamp - the timestamp to be converted
* @param {string} [picture] - the picture string defining the format of the timestamp (defaults to ISO 8601)
* @returns {Number} - milliseconds since the epoch
*/
function toMillis(timestamp, picture) {
if (typeof timestamp === "undefined") return;
if (typeof picture === "undefined") {
if (!iso8601regex.test(timestamp)) throw {
stack: (/* @__PURE__ */ new Error()).stack,
code: "D3110",
value: timestamp
};
return Date.parse(timestamp);
} else return parseDateTime.call(this, timestamp, picture);
}
/**
* Converts milliseconds since the epoch to an ISO 8601 timestamp
* @param {Number} millis - milliseconds since the epoch to be converted
* @param {string} [picture] - the picture string defining the format of the timestamp (defaults to ISO 8601)
* @param {string} [timezone] - the timezone to format the timestamp in (defaults to UTC)
* @returns {String} - the formatted timestamp
*/
function fromMillis(millis, picture, timezone) {
if (typeof millis === "undefined") return;
return formatDateTime.call(this, millis, picture, timezone);
}
return {
formatInteger,
parseInteger,
fromMillis,
toMillis
};
})();
}, { "./utils": 6 }],
2: [function(require$1, module$1, exports$1) {
(function(global$1) {
(function() {
/**
* © Copyright IBM Corp. 2016, 2018 All Rights Reserved
* Project name: JSONata
* This project is licensed under the MIT License, see LICENSE
*/
var utils = require$1("./utils");
module$1.exports = (() => {
var isNumeric = utils.isNumeric;
var isArrayOfStrings = utils.isArrayOfStrings;
var isArrayOfNumbers = utils.isArrayOfNumbers;
var createSequence = utils.createSequence;
var isSequence = utils.isSequence;
var isFunction = utils.isFunction;
var isLambda = utils.isLambda;
var isPromise = utils.isPromise;
var getFunctionArity = utils.getFunctionArity;
var deepEquals = utils.isDeepEqual;
var stringToArray = utils.stringToArray;
/**
* Sum function
* @param {Object} args - Arguments
* @returns {number} Total value of arguments
*/
function sum(args) {
if (typeof args === "undefined") return;
var total = 0;
args.forEach(function(num) {
total += num;
});
return total;
}
/**
* Count function
* @param {Object} args - Arguments
* @returns {number} Number of elements in the array
*/
function count(args) {
if (typeof args === "undefined") return 0;
return args.length;
}
/**
* Max function
* @param {Object} args - Arguments
* @returns {number} Max element in the array
*/
function max(args) {
if (typeof args === "undefined" || args.length === 0) return;
return Math.max.apply(Math, args);
}
/**
* Min function
* @param {Object} args - Arguments
* @returns {number} Min element in the array
*/
function min(args) {
if (typeof args === "undefined" || args.length === 0) return;
return Math.min.apply(Math, args);
}
/**
* Average function
* @param {Object} args - Arguments
* @returns {number} Average element in the array
*/
function average(args) {
if (typeof args === "undefined" || args.length === 0) return;
var total = 0;
args.forEach(function(num) {
total += num;
});
return total / args.length;
}
/**
* Stringify arguments
* @param {Object} arg - Arguments
* @param {boolean} [prettify] - Pretty print the result
* @returns {String} String from arguments
*/
function string(arg, prettify = false) {
if (typeof arg === "undefined") return;
var str;
if (typeof arg === "string") str = arg;
else if (isFunction(arg)) str = "";
else if (typeof arg === "number" && !isFinite(arg)) throw {
code: "D3001",
value: arg,
stack: (/* @__PURE__ */ new Error()).stack
};
else {
var space = prettify ? 2 : 0;
if (Array.isArray(arg) && arg.outerWrapper) arg = arg[0];
str = JSON.stringify(arg, function(key, val) {
return typeof val !== "undefined" && val !== null && val.toPrecision && isNumeric(val) ? Number(val.toPrecision(15)) : val && isFunction(val) ? "" : val;
}, space);
}
return str;
}
/**
* Create substring based on character number and length
* @param {String} str - String to evaluate
* @param {Integer} start - Character number to start substring
* @param {Integer} [length] - Number of characters in substring
* @returns {string|*} Substring
*/
function substring(str, start, length$1) {
if (typeof str === "undefined") return;
var strArray = stringToArray(str);
var strLength = strArray.length;
if (strLength + start < 0) start = 0;
if (typeof length$1 !== "undefined") {
if (length$1 <= 0) return "";
var end = start >= 0 ? start + length$1 : strLength + start + length$1;
return strArray.slice(start, end).join("");
}
return strArray.slice(start).join("");
}
/**
* Create substring up until a character
* @param {String} str - String to evaluate
* @param {String} chars - Character to define substring boundary
* @returns {*} Substring
*/
function substringBefore(str, chars) {
if (typeof str === "undefined") return;
var pos = str.indexOf(chars);
if (pos > -1) return str.substr(0, pos);
else return str;
}
/**
* Create substring after a character
* @param {String} str - String to evaluate
* @param {String} chars - Character to define substring boundary
* @returns {*} Substring
*/
function substringAfter(str, chars) {
if (typeof str === "undefined") return;
var pos = str.indexOf(chars);
if (pos > -1) return str.substr(pos + chars.length);
else return str;
}
/**
* Lowercase a string
* @param {String} str - String to evaluate
* @returns {string} Lowercase string
*/
function lowercase(str) {
if (typeof str === "undefined") return;
return str.toLowerCase();
}
/**
* Uppercase a string
* @param {String} str - String to evaluate
* @returns {string} Uppercase string
*/
function uppercase(str) {
if (typeof str === "undefined") return;
return str.toUpperCase();
}
/**
* length of a string
* @param {String} str - string
* @returns {Number} The number of characters in the string
*/
function length(str) {
if (typeof str === "undefined") return;
return stringToArray(str).length;
}
/**
* Normalize and trim whitespace within a string
* @param {string} str - string to be trimmed
* @returns {string} - trimmed string
*/
function trim(str) {
if (typeof str === "undefined") return;
var result = str.replace(/[ \t\n\r]+/gm, " ");
if (result.charAt(0) === " ") result = result.substring(1);
if (result.charAt(result.length - 1) === " ") result = result.substring(0, result.length - 1);
return result;
}
/**
* Pad a string to a minimum width by adding characters to the start or end
* @param {string} str - string to be padded
* @param {number} width - the minimum width; +ve pads to the right, -ve pads to the left
* @param {string} [char] - the pad character(s); defaults to ' '
* @returns {string} - padded string
*/
function pad(str, width, char) {
if (typeof str === "undefined") return;
if (typeof char === "undefined" || char.length === 0) char = " ";
var result;
width = Math.trunc(width);
var padLength = Math.abs(width) - length(str);
if (padLength > 0) {
var padding = new Array(padLength + 1).join(char);
if (char.length > 1) padding = substring(padding, 0, padLength);
if (width > 0) result = str + padding;
else result = padding + str;
} else result = str;
return result;
}
/**
* Evaluate the matcher function against the str arg
*
* @param {*} matcher - matching function (native or lambda)
* @param {string} str - the string to match against
* @returns {object} - structure that represents the match(es)
*/
async function evaluateMatcher(matcher, str) {
var result = matcher.apply(this, [str]);
if (isPromise(result)) result = await result;
if (result && !(typeof result.start === "number" || result.end === "number" || Array.isArray(result.groups) || isFunction(result.next))) throw {
code: "T1010",
stack: (/* @__PURE__ */ new Error()).stack
};
return result;
}
/**
* Tests if the str contains the token
* @param {String} str - string to test
* @param {String} token - substring or regex to find
* @returns {Boolean} - true if str contains token
*/
async function contains(str, token) {
if (typeof str === "undefined") return;
var result;
if (typeof token === "string") result = str.indexOf(token) !== -1;
else result = typeof await evaluateMatcher(token, str) !== "undefined";
return result;
}
/**
* Match a string with a regex returning an array of object containing details of each match
* @param {String} str - string
* @param {String} regex - the regex applied to the string
* @param {Integer} [limit] - max number of matches to return
* @returns {Array} The array of match objects
*/
async function match(str, regex, limit) {
if (typeof str === "undefined") return;
if (limit < 0) throw {
stack: (/* @__PURE__ */ new Error()).stack,
value: limit,
code: "D3040",
index: 3
};
var result = createSequence();
if (typeof limit === "undefined" || limit > 0) {
var count$1 = 0;
var matches = await evaluateMatcher(regex, str);
if (typeof matches !== "undefined") while (typeof matches !== "undefined" && (typeof limit === "undefined" || count$1 < limit)) {
result.push({
match: matches.match,
index: matches.start,
groups: matches.groups
});
matches = await evaluateMatcher(matches.next);
count$1++;
}
}
return result;
}
/**
* Match a string with a regex returning an array of object containing details of each match
* @param {String} str - string
* @param {String} pattern - the substring/regex applied to the string
* @param {String} replacement - text to replace the matched substrings
* @param {Integer} [limit] - max number of matches to return
* @returns {Array} The array of match objects
*/
async function replace(str, pattern, replacement, limit) {
if (typeof str === "undefined") return;
var self$1 = this;
if (pattern === "") throw {
code: "D3010",
stack: (/* @__PURE__ */ new Error()).stack,
value: pattern,
index: 2
};
if (limit < 0) throw {
code: "D3011",
stack: (/* @__PURE__ */ new Error()).stack,
value: limit,
index: 4
};
var replacer;
if (typeof replacement === "string") replacer = function(regexMatch) {
var substitute = "";
var position$1 = 0;
var index$1 = replacement.indexOf("$", position$1);
while (index$1 !== -1 && position$1 < replacement.length) {
substitute += replacement.substring(position$1, index$1);
position$1 = index$1 + 1;
var dollarVal = replacement.charAt(position$1);
if (dollarVal === "$") {
substitute += "$";
position$1++;
} else if (dollarVal === "0") {
substitute += regexMatch.match;
position$1++;
} els