Initial commit: 11ty website with Fire/Frost branding

This commit is contained in:
The Trinity
2026-04-02 18:39:00 -05:00
commit 40b45dff2e
1646 changed files with 329080 additions and 0 deletions

206
node_modules/luxon/src/impl/conversions.js generated vendored Normal file
View File

@@ -0,0 +1,206 @@
import {
integerBetween,
isLeapYear,
timeObject,
daysInYear,
daysInMonth,
weeksInWeekYear,
isInteger,
isUndefined,
} from "./util.js";
import Invalid from "./invalid.js";
import { ConflictingSpecificationError } from "../errors.js";
const nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
function unitOutOfRange(unit, value) {
return new Invalid(
"unit out of range",
`you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid`
);
}
export function dayOfWeek(year, month, day) {
const d = new Date(Date.UTC(year, month - 1, day));
if (year < 100 && year >= 0) {
d.setUTCFullYear(d.getUTCFullYear() - 1900);
}
const js = d.getUTCDay();
return js === 0 ? 7 : js;
}
function computeOrdinal(year, month, day) {
return day + (isLeapYear(year) ? leapLadder : nonLeapLadder)[month - 1];
}
function uncomputeOrdinal(year, ordinal) {
const table = isLeapYear(year) ? leapLadder : nonLeapLadder,
month0 = table.findIndex((i) => i < ordinal),
day = ordinal - table[month0];
return { month: month0 + 1, day };
}
export function isoWeekdayToLocal(isoWeekday, startOfWeek) {
return ((isoWeekday - startOfWeek + 7) % 7) + 1;
}
/**
* @private
*/
export function gregorianToWeek(gregObj, minDaysInFirstWeek = 4, startOfWeek = 1) {
const { year, month, day } = gregObj,
ordinal = computeOrdinal(year, month, day),
weekday = isoWeekdayToLocal(dayOfWeek(year, month, day), startOfWeek);
let weekNumber = Math.floor((ordinal - weekday + 14 - minDaysInFirstWeek) / 7),
weekYear;
if (weekNumber < 1) {
weekYear = year - 1;
weekNumber = weeksInWeekYear(weekYear, minDaysInFirstWeek, startOfWeek);
} else if (weekNumber > weeksInWeekYear(year, minDaysInFirstWeek, startOfWeek)) {
weekYear = year + 1;
weekNumber = 1;
} else {
weekYear = year;
}
return { weekYear, weekNumber, weekday, ...timeObject(gregObj) };
}
export function weekToGregorian(weekData, minDaysInFirstWeek = 4, startOfWeek = 1) {
const { weekYear, weekNumber, weekday } = weekData,
weekdayOfJan4 = isoWeekdayToLocal(dayOfWeek(weekYear, 1, minDaysInFirstWeek), startOfWeek),
yearInDays = daysInYear(weekYear);
let ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 7 + minDaysInFirstWeek,
year;
if (ordinal < 1) {
year = weekYear - 1;
ordinal += daysInYear(year);
} else if (ordinal > yearInDays) {
year = weekYear + 1;
ordinal -= daysInYear(weekYear);
} else {
year = weekYear;
}
const { month, day } = uncomputeOrdinal(year, ordinal);
return { year, month, day, ...timeObject(weekData) };
}
export function gregorianToOrdinal(gregData) {
const { year, month, day } = gregData;
const ordinal = computeOrdinal(year, month, day);
return { year, ordinal, ...timeObject(gregData) };
}
export function ordinalToGregorian(ordinalData) {
const { year, ordinal } = ordinalData;
const { month, day } = uncomputeOrdinal(year, ordinal);
return { year, month, day, ...timeObject(ordinalData) };
}
/**
* Check if local week units like localWeekday are used in obj.
* If so, validates that they are not mixed with ISO week units and then copies them to the normal week unit properties.
* Modifies obj in-place!
* @param obj the object values
*/
export function usesLocalWeekValues(obj, loc) {
const hasLocaleWeekData =
!isUndefined(obj.localWeekday) ||
!isUndefined(obj.localWeekNumber) ||
!isUndefined(obj.localWeekYear);
if (hasLocaleWeekData) {
const hasIsoWeekData =
!isUndefined(obj.weekday) || !isUndefined(obj.weekNumber) || !isUndefined(obj.weekYear);
if (hasIsoWeekData) {
throw new ConflictingSpecificationError(
"Cannot mix locale-based week fields with ISO-based week fields"
);
}
if (!isUndefined(obj.localWeekday)) obj.weekday = obj.localWeekday;
if (!isUndefined(obj.localWeekNumber)) obj.weekNumber = obj.localWeekNumber;
if (!isUndefined(obj.localWeekYear)) obj.weekYear = obj.localWeekYear;
delete obj.localWeekday;
delete obj.localWeekNumber;
delete obj.localWeekYear;
return {
minDaysInFirstWeek: loc.getMinDaysInFirstWeek(),
startOfWeek: loc.getStartOfWeek(),
};
} else {
return { minDaysInFirstWeek: 4, startOfWeek: 1 };
}
}
export function hasInvalidWeekData(obj, minDaysInFirstWeek = 4, startOfWeek = 1) {
const validYear = isInteger(obj.weekYear),
validWeek = integerBetween(
obj.weekNumber,
1,
weeksInWeekYear(obj.weekYear, minDaysInFirstWeek, startOfWeek)
),
validWeekday = integerBetween(obj.weekday, 1, 7);
if (!validYear) {
return unitOutOfRange("weekYear", obj.weekYear);
} else if (!validWeek) {
return unitOutOfRange("week", obj.weekNumber);
} else if (!validWeekday) {
return unitOutOfRange("weekday", obj.weekday);
} else return false;
}
export function hasInvalidOrdinalData(obj) {
const validYear = isInteger(obj.year),
validOrdinal = integerBetween(obj.ordinal, 1, daysInYear(obj.year));
if (!validYear) {
return unitOutOfRange("year", obj.year);
} else if (!validOrdinal) {
return unitOutOfRange("ordinal", obj.ordinal);
} else return false;
}
export function hasInvalidGregorianData(obj) {
const validYear = isInteger(obj.year),
validMonth = integerBetween(obj.month, 1, 12),
validDay = integerBetween(obj.day, 1, daysInMonth(obj.year, obj.month));
if (!validYear) {
return unitOutOfRange("year", obj.year);
} else if (!validMonth) {
return unitOutOfRange("month", obj.month);
} else if (!validDay) {
return unitOutOfRange("day", obj.day);
} else return false;
}
export function hasInvalidTimeData(obj) {
const { hour, minute, second, millisecond } = obj;
const validHour =
integerBetween(hour, 0, 23) ||
(hour === 24 && minute === 0 && second === 0 && millisecond === 0),
validMinute = integerBetween(minute, 0, 59),
validSecond = integerBetween(second, 0, 59),
validMillisecond = integerBetween(millisecond, 0, 999);
if (!validHour) {
return unitOutOfRange("hour", hour);
} else if (!validMinute) {
return unitOutOfRange("minute", minute);
} else if (!validSecond) {
return unitOutOfRange("second", second);
} else if (!validMillisecond) {
return unitOutOfRange("millisecond", millisecond);
} else return false;
}

95
node_modules/luxon/src/impl/diff.js generated vendored Normal file
View File

@@ -0,0 +1,95 @@
import Duration from "../duration.js";
function dayDiff(earlier, later) {
const utcDayStart = (dt) => dt.toUTC(0, { keepLocalTime: true }).startOf("day").valueOf(),
ms = utcDayStart(later) - utcDayStart(earlier);
return Math.floor(Duration.fromMillis(ms).as("days"));
}
function highOrderDiffs(cursor, later, units) {
const differs = [
["years", (a, b) => b.year - a.year],
["quarters", (a, b) => b.quarter - a.quarter + (b.year - a.year) * 4],
["months", (a, b) => b.month - a.month + (b.year - a.year) * 12],
[
"weeks",
(a, b) => {
const days = dayDiff(a, b);
return (days - (days % 7)) / 7;
},
],
["days", dayDiff],
];
const results = {};
const earlier = cursor;
let lowestOrder, highWater;
/* This loop tries to diff using larger units first.
If we overshoot, we backtrack and try the next smaller unit.
"cursor" starts out at the earlier timestamp and moves closer and closer to "later"
as we use smaller and smaller units.
highWater keeps track of where we would be if we added one more of the smallest unit,
this is used later to potentially convert any difference smaller than the smallest higher order unit
into a fraction of that smallest higher order unit
*/
for (const [unit, differ] of differs) {
if (units.indexOf(unit) >= 0) {
lowestOrder = unit;
results[unit] = differ(cursor, later);
highWater = earlier.plus(results);
if (highWater > later) {
// we overshot the end point, backtrack cursor by 1
results[unit]--;
cursor = earlier.plus(results);
// if we are still overshooting now, we need to backtrack again
// this happens in certain situations when diffing times in different zones,
// because this calculation ignores time zones
if (cursor > later) {
// keep the "overshot by 1" around as highWater
highWater = cursor;
// backtrack cursor by 1
results[unit]--;
cursor = earlier.plus(results);
}
} else {
cursor = highWater;
}
}
}
return [cursor, results, highWater, lowestOrder];
}
export default function (earlier, later, units, opts) {
let [cursor, results, highWater, lowestOrder] = highOrderDiffs(earlier, later, units);
const remainingMillis = later - cursor;
const lowerOrderUnits = units.filter(
(u) => ["hours", "minutes", "seconds", "milliseconds"].indexOf(u) >= 0
);
if (lowerOrderUnits.length === 0) {
if (highWater < later) {
highWater = cursor.plus({ [lowestOrder]: 1 });
}
if (highWater !== cursor) {
results[lowestOrder] = (results[lowestOrder] || 0) + remainingMillis / (highWater - cursor);
}
}
const duration = Duration.fromObject(results, opts);
if (lowerOrderUnits.length > 0) {
return Duration.fromMillis(remainingMillis, opts)
.shiftTo(...lowerOrderUnits)
.plus(duration);
} else {
return duration;
}
}

94
node_modules/luxon/src/impl/digits.js generated vendored Normal file
View File

@@ -0,0 +1,94 @@
const numberingSystems = {
arab: "[\u0660-\u0669]",
arabext: "[\u06F0-\u06F9]",
bali: "[\u1B50-\u1B59]",
beng: "[\u09E6-\u09EF]",
deva: "[\u0966-\u096F]",
fullwide: "[\uFF10-\uFF19]",
gujr: "[\u0AE6-\u0AEF]",
hanidec: "[|一|二|三|四|五|六|七|八|九]",
khmr: "[\u17E0-\u17E9]",
knda: "[\u0CE6-\u0CEF]",
laoo: "[\u0ED0-\u0ED9]",
limb: "[\u1946-\u194F]",
mlym: "[\u0D66-\u0D6F]",
mong: "[\u1810-\u1819]",
mymr: "[\u1040-\u1049]",
orya: "[\u0B66-\u0B6F]",
tamldec: "[\u0BE6-\u0BEF]",
telu: "[\u0C66-\u0C6F]",
thai: "[\u0E50-\u0E59]",
tibt: "[\u0F20-\u0F29]",
latn: "\\d",
};
const numberingSystemsUTF16 = {
arab: [1632, 1641],
arabext: [1776, 1785],
bali: [6992, 7001],
beng: [2534, 2543],
deva: [2406, 2415],
fullwide: [65296, 65303],
gujr: [2790, 2799],
khmr: [6112, 6121],
knda: [3302, 3311],
laoo: [3792, 3801],
limb: [6470, 6479],
mlym: [3430, 3439],
mong: [6160, 6169],
mymr: [4160, 4169],
orya: [2918, 2927],
tamldec: [3046, 3055],
telu: [3174, 3183],
thai: [3664, 3673],
tibt: [3872, 3881],
};
const hanidecChars = numberingSystems.hanidec.replace(/[\[|\]]/g, "").split("");
export function parseDigits(str) {
let value = parseInt(str, 10);
if (isNaN(value)) {
value = "";
for (let i = 0; i < str.length; i++) {
const code = str.charCodeAt(i);
if (str[i].search(numberingSystems.hanidec) !== -1) {
value += hanidecChars.indexOf(str[i]);
} else {
for (const key in numberingSystemsUTF16) {
const [min, max] = numberingSystemsUTF16[key];
if (code >= min && code <= max) {
value += code - min;
}
}
}
}
return parseInt(value, 10);
} else {
return value;
}
}
// cache of {numberingSystem: {append: regex}}
const digitRegexCache = new Map();
export function resetDigitRegexCache() {
digitRegexCache.clear();
}
export function digitRegex({ numberingSystem }, append = "") {
const ns = numberingSystem || "latn";
let appendCache = digitRegexCache.get(ns);
if (appendCache === undefined) {
appendCache = new Map();
digitRegexCache.set(ns, appendCache);
}
let regex = appendCache.get(append);
if (regex === undefined) {
regex = new RegExp(`${numberingSystems[ns]}${append}`);
appendCache.set(append, regex);
}
return regex;
}

233
node_modules/luxon/src/impl/english.js generated vendored Normal file
View File

@@ -0,0 +1,233 @@
import * as Formats from "./formats.js";
import { pick } from "./util.js";
function stringify(obj) {
return JSON.stringify(obj, Object.keys(obj).sort());
}
/**
* @private
*/
export const monthsLong = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
export const monthsShort = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
export const monthsNarrow = ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"];
export function months(length) {
switch (length) {
case "narrow":
return [...monthsNarrow];
case "short":
return [...monthsShort];
case "long":
return [...monthsLong];
case "numeric":
return ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
case "2-digit":
return ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
default:
return null;
}
}
export const weekdaysLong = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
];
export const weekdaysShort = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
export const weekdaysNarrow = ["M", "T", "W", "T", "F", "S", "S"];
export function weekdays(length) {
switch (length) {
case "narrow":
return [...weekdaysNarrow];
case "short":
return [...weekdaysShort];
case "long":
return [...weekdaysLong];
case "numeric":
return ["1", "2", "3", "4", "5", "6", "7"];
default:
return null;
}
}
export const meridiems = ["AM", "PM"];
export const erasLong = ["Before Christ", "Anno Domini"];
export const erasShort = ["BC", "AD"];
export const erasNarrow = ["B", "A"];
export function eras(length) {
switch (length) {
case "narrow":
return [...erasNarrow];
case "short":
return [...erasShort];
case "long":
return [...erasLong];
default:
return null;
}
}
export function meridiemForDateTime(dt) {
return meridiems[dt.hour < 12 ? 0 : 1];
}
export function weekdayForDateTime(dt, length) {
return weekdays(length)[dt.weekday - 1];
}
export function monthForDateTime(dt, length) {
return months(length)[dt.month - 1];
}
export function eraForDateTime(dt, length) {
return eras(length)[dt.year < 0 ? 0 : 1];
}
export function formatRelativeTime(unit, count, numeric = "always", narrow = false) {
const units = {
years: ["year", "yr."],
quarters: ["quarter", "qtr."],
months: ["month", "mo."],
weeks: ["week", "wk."],
days: ["day", "day", "days"],
hours: ["hour", "hr."],
minutes: ["minute", "min."],
seconds: ["second", "sec."],
};
const lastable = ["hours", "minutes", "seconds"].indexOf(unit) === -1;
if (numeric === "auto" && lastable) {
const isDay = unit === "days";
switch (count) {
case 1:
return isDay ? "tomorrow" : `next ${units[unit][0]}`;
case -1:
return isDay ? "yesterday" : `last ${units[unit][0]}`;
case 0:
return isDay ? "today" : `this ${units[unit][0]}`;
default: // fall through
}
}
const isInPast = Object.is(count, -0) || count < 0,
fmtValue = Math.abs(count),
singular = fmtValue === 1,
lilUnits = units[unit],
fmtUnit = narrow
? singular
? lilUnits[1]
: lilUnits[2] || lilUnits[1]
: singular
? units[unit][0]
: unit;
return isInPast ? `${fmtValue} ${fmtUnit} ago` : `in ${fmtValue} ${fmtUnit}`;
}
export function formatString(knownFormat) {
// these all have the offsets removed because we don't have access to them
// without all the intl stuff this is backfilling
const filtered = pick(knownFormat, [
"weekday",
"era",
"year",
"month",
"day",
"hour",
"minute",
"second",
"timeZoneName",
"hourCycle",
]),
key = stringify(filtered),
dateTimeHuge = "EEEE, LLLL d, yyyy, h:mm a";
switch (key) {
case stringify(Formats.DATE_SHORT):
return "M/d/yyyy";
case stringify(Formats.DATE_MED):
return "LLL d, yyyy";
case stringify(Formats.DATE_MED_WITH_WEEKDAY):
return "EEE, LLL d, yyyy";
case stringify(Formats.DATE_FULL):
return "LLLL d, yyyy";
case stringify(Formats.DATE_HUGE):
return "EEEE, LLLL d, yyyy";
case stringify(Formats.TIME_SIMPLE):
return "h:mm a";
case stringify(Formats.TIME_WITH_SECONDS):
return "h:mm:ss a";
case stringify(Formats.TIME_WITH_SHORT_OFFSET):
return "h:mm a";
case stringify(Formats.TIME_WITH_LONG_OFFSET):
return "h:mm a";
case stringify(Formats.TIME_24_SIMPLE):
return "HH:mm";
case stringify(Formats.TIME_24_WITH_SECONDS):
return "HH:mm:ss";
case stringify(Formats.TIME_24_WITH_SHORT_OFFSET):
return "HH:mm";
case stringify(Formats.TIME_24_WITH_LONG_OFFSET):
return "HH:mm";
case stringify(Formats.DATETIME_SHORT):
return "M/d/yyyy, h:mm a";
case stringify(Formats.DATETIME_MED):
return "LLL d, yyyy, h:mm a";
case stringify(Formats.DATETIME_FULL):
return "LLLL d, yyyy, h:mm a";
case stringify(Formats.DATETIME_HUGE):
return dateTimeHuge;
case stringify(Formats.DATETIME_SHORT_WITH_SECONDS):
return "M/d/yyyy, h:mm:ss a";
case stringify(Formats.DATETIME_MED_WITH_SECONDS):
return "LLL d, yyyy, h:mm:ss a";
case stringify(Formats.DATETIME_MED_WITH_WEEKDAY):
return "EEE, d LLL yyyy, h:mm a";
case stringify(Formats.DATETIME_FULL_WITH_SECONDS):
return "LLLL d, yyyy, h:mm:ss a";
case stringify(Formats.DATETIME_HUGE_WITH_SECONDS):
return "EEEE, LLLL d, yyyy, h:mm:ss a";
default:
return dateTimeHuge;
}
}

176
node_modules/luxon/src/impl/formats.js generated vendored Normal file
View File

@@ -0,0 +1,176 @@
/**
* @private
*/
const n = "numeric",
s = "short",
l = "long";
export const DATE_SHORT = {
year: n,
month: n,
day: n,
};
export const DATE_MED = {
year: n,
month: s,
day: n,
};
export const DATE_MED_WITH_WEEKDAY = {
year: n,
month: s,
day: n,
weekday: s,
};
export const DATE_FULL = {
year: n,
month: l,
day: n,
};
export const DATE_HUGE = {
year: n,
month: l,
day: n,
weekday: l,
};
export const TIME_SIMPLE = {
hour: n,
minute: n,
};
export const TIME_WITH_SECONDS = {
hour: n,
minute: n,
second: n,
};
export const TIME_WITH_SHORT_OFFSET = {
hour: n,
minute: n,
second: n,
timeZoneName: s,
};
export const TIME_WITH_LONG_OFFSET = {
hour: n,
minute: n,
second: n,
timeZoneName: l,
};
export const TIME_24_SIMPLE = {
hour: n,
minute: n,
hourCycle: "h23",
};
export const TIME_24_WITH_SECONDS = {
hour: n,
minute: n,
second: n,
hourCycle: "h23",
};
export const TIME_24_WITH_SHORT_OFFSET = {
hour: n,
minute: n,
second: n,
hourCycle: "h23",
timeZoneName: s,
};
export const TIME_24_WITH_LONG_OFFSET = {
hour: n,
minute: n,
second: n,
hourCycle: "h23",
timeZoneName: l,
};
export const DATETIME_SHORT = {
year: n,
month: n,
day: n,
hour: n,
minute: n,
};
export const DATETIME_SHORT_WITH_SECONDS = {
year: n,
month: n,
day: n,
hour: n,
minute: n,
second: n,
};
export const DATETIME_MED = {
year: n,
month: s,
day: n,
hour: n,
minute: n,
};
export const DATETIME_MED_WITH_SECONDS = {
year: n,
month: s,
day: n,
hour: n,
minute: n,
second: n,
};
export const DATETIME_MED_WITH_WEEKDAY = {
year: n,
month: s,
day: n,
weekday: s,
hour: n,
minute: n,
};
export const DATETIME_FULL = {
year: n,
month: l,
day: n,
hour: n,
minute: n,
timeZoneName: s,
};
export const DATETIME_FULL_WITH_SECONDS = {
year: n,
month: l,
day: n,
hour: n,
minute: n,
second: n,
timeZoneName: s,
};
export const DATETIME_HUGE = {
year: n,
month: l,
day: n,
weekday: l,
hour: n,
minute: n,
timeZoneName: l,
};
export const DATETIME_HUGE_WITH_SECONDS = {
year: n,
month: l,
day: n,
weekday: l,
hour: n,
minute: n,
second: n,
timeZoneName: l,
};

434
node_modules/luxon/src/impl/formatter.js generated vendored Normal file
View File

@@ -0,0 +1,434 @@
import * as English from "./english.js";
import * as Formats from "./formats.js";
import { padStart } from "./util.js";
function stringifyTokens(splits, tokenToString) {
let s = "";
for (const token of splits) {
if (token.literal) {
s += token.val;
} else {
s += tokenToString(token.val);
}
}
return s;
}
const macroTokenToFormatOpts = {
D: Formats.DATE_SHORT,
DD: Formats.DATE_MED,
DDD: Formats.DATE_FULL,
DDDD: Formats.DATE_HUGE,
t: Formats.TIME_SIMPLE,
tt: Formats.TIME_WITH_SECONDS,
ttt: Formats.TIME_WITH_SHORT_OFFSET,
tttt: Formats.TIME_WITH_LONG_OFFSET,
T: Formats.TIME_24_SIMPLE,
TT: Formats.TIME_24_WITH_SECONDS,
TTT: Formats.TIME_24_WITH_SHORT_OFFSET,
TTTT: Formats.TIME_24_WITH_LONG_OFFSET,
f: Formats.DATETIME_SHORT,
ff: Formats.DATETIME_MED,
fff: Formats.DATETIME_FULL,
ffff: Formats.DATETIME_HUGE,
F: Formats.DATETIME_SHORT_WITH_SECONDS,
FF: Formats.DATETIME_MED_WITH_SECONDS,
FFF: Formats.DATETIME_FULL_WITH_SECONDS,
FFFF: Formats.DATETIME_HUGE_WITH_SECONDS,
};
/**
* @private
*/
export default class Formatter {
static create(locale, opts = {}) {
return new Formatter(locale, opts);
}
static parseFormat(fmt) {
// white-space is always considered a literal in user-provided formats
// the " " token has a special meaning (see unitForToken)
let current = null,
currentFull = "",
bracketed = false;
const splits = [];
for (let i = 0; i < fmt.length; i++) {
const c = fmt.charAt(i);
if (c === "'") {
// turn '' into a literal signal quote instead of just skipping the empty literal
if (currentFull.length > 0 || bracketed) {
splits.push({
literal: bracketed || /^\s+$/.test(currentFull),
val: currentFull === "" ? "'" : currentFull,
});
}
current = null;
currentFull = "";
bracketed = !bracketed;
} else if (bracketed) {
currentFull += c;
} else if (c === current) {
currentFull += c;
} else {
if (currentFull.length > 0) {
splits.push({ literal: /^\s+$/.test(currentFull), val: currentFull });
}
currentFull = c;
current = c;
}
}
if (currentFull.length > 0) {
splits.push({ literal: bracketed || /^\s+$/.test(currentFull), val: currentFull });
}
return splits;
}
static macroTokenToFormatOpts(token) {
return macroTokenToFormatOpts[token];
}
constructor(locale, formatOpts) {
this.opts = formatOpts;
this.loc = locale;
this.systemLoc = null;
}
formatWithSystemDefault(dt, opts) {
if (this.systemLoc === null) {
this.systemLoc = this.loc.redefaultToSystem();
}
const df = this.systemLoc.dtFormatter(dt, { ...this.opts, ...opts });
return df.format();
}
dtFormatter(dt, opts = {}) {
return this.loc.dtFormatter(dt, { ...this.opts, ...opts });
}
formatDateTime(dt, opts) {
return this.dtFormatter(dt, opts).format();
}
formatDateTimeParts(dt, opts) {
return this.dtFormatter(dt, opts).formatToParts();
}
formatInterval(interval, opts) {
const df = this.dtFormatter(interval.start, opts);
return df.dtf.formatRange(interval.start.toJSDate(), interval.end.toJSDate());
}
resolvedOptions(dt, opts) {
return this.dtFormatter(dt, opts).resolvedOptions();
}
num(n, p = 0, signDisplay = undefined) {
// we get some perf out of doing this here, annoyingly
if (this.opts.forceSimple) {
return padStart(n, p);
}
const opts = { ...this.opts };
if (p > 0) {
opts.padTo = p;
}
if (signDisplay) {
opts.signDisplay = signDisplay;
}
return this.loc.numberFormatter(opts).format(n);
}
formatDateTimeFromString(dt, fmt) {
const knownEnglish = this.loc.listingMode() === "en",
useDateTimeFormatter = this.loc.outputCalendar && this.loc.outputCalendar !== "gregory",
string = (opts, extract) => this.loc.extract(dt, opts, extract),
formatOffset = (opts) => {
if (dt.isOffsetFixed && dt.offset === 0 && opts.allowZ) {
return "Z";
}
return dt.isValid ? dt.zone.formatOffset(dt.ts, opts.format) : "";
},
meridiem = () =>
knownEnglish
? English.meridiemForDateTime(dt)
: string({ hour: "numeric", hourCycle: "h12" }, "dayperiod"),
month = (length, standalone) =>
knownEnglish
? English.monthForDateTime(dt, length)
: string(standalone ? { month: length } : { month: length, day: "numeric" }, "month"),
weekday = (length, standalone) =>
knownEnglish
? English.weekdayForDateTime(dt, length)
: string(
standalone ? { weekday: length } : { weekday: length, month: "long", day: "numeric" },
"weekday"
),
maybeMacro = (token) => {
const formatOpts = Formatter.macroTokenToFormatOpts(token);
if (formatOpts) {
return this.formatWithSystemDefault(dt, formatOpts);
} else {
return token;
}
},
era = (length) =>
knownEnglish ? English.eraForDateTime(dt, length) : string({ era: length }, "era"),
tokenToString = (token) => {
// Where possible: https://cldr.unicode.org/translation/date-time/date-time-symbols
switch (token) {
// ms
case "S":
return this.num(dt.millisecond);
case "u":
// falls through
case "SSS":
return this.num(dt.millisecond, 3);
// seconds
case "s":
return this.num(dt.second);
case "ss":
return this.num(dt.second, 2);
// fractional seconds
case "uu":
return this.num(Math.floor(dt.millisecond / 10), 2);
case "uuu":
return this.num(Math.floor(dt.millisecond / 100));
// minutes
case "m":
return this.num(dt.minute);
case "mm":
return this.num(dt.minute, 2);
// hours
case "h":
return this.num(dt.hour % 12 === 0 ? 12 : dt.hour % 12);
case "hh":
return this.num(dt.hour % 12 === 0 ? 12 : dt.hour % 12, 2);
case "H":
return this.num(dt.hour);
case "HH":
return this.num(dt.hour, 2);
// offset
case "Z":
// like +6
return formatOffset({ format: "narrow", allowZ: this.opts.allowZ });
case "ZZ":
// like +06:00
return formatOffset({ format: "short", allowZ: this.opts.allowZ });
case "ZZZ":
// like +0600
return formatOffset({ format: "techie", allowZ: this.opts.allowZ });
case "ZZZZ":
// like EST
return dt.zone.offsetName(dt.ts, { format: "short", locale: this.loc.locale });
case "ZZZZZ":
// like Eastern Standard Time
return dt.zone.offsetName(dt.ts, { format: "long", locale: this.loc.locale });
// zone
case "z":
// like America/New_York
return dt.zoneName;
// meridiems
case "a":
return meridiem();
// dates
case "d":
return useDateTimeFormatter ? string({ day: "numeric" }, "day") : this.num(dt.day);
case "dd":
return useDateTimeFormatter ? string({ day: "2-digit" }, "day") : this.num(dt.day, 2);
// weekdays - standalone
case "c":
// like 1
return this.num(dt.weekday);
case "ccc":
// like 'Tues'
return weekday("short", true);
case "cccc":
// like 'Tuesday'
return weekday("long", true);
case "ccccc":
// like 'T'
return weekday("narrow", true);
// weekdays - format
case "E":
// like 1
return this.num(dt.weekday);
case "EEE":
// like 'Tues'
return weekday("short", false);
case "EEEE":
// like 'Tuesday'
return weekday("long", false);
case "EEEEE":
// like 'T'
return weekday("narrow", false);
// months - standalone
case "L":
// like 1
return useDateTimeFormatter
? string({ month: "numeric", day: "numeric" }, "month")
: this.num(dt.month);
case "LL":
// like 01, doesn't seem to work
return useDateTimeFormatter
? string({ month: "2-digit", day: "numeric" }, "month")
: this.num(dt.month, 2);
case "LLL":
// like Jan
return month("short", true);
case "LLLL":
// like January
return month("long", true);
case "LLLLL":
// like J
return month("narrow", true);
// months - format
case "M":
// like 1
return useDateTimeFormatter
? string({ month: "numeric" }, "month")
: this.num(dt.month);
case "MM":
// like 01
return useDateTimeFormatter
? string({ month: "2-digit" }, "month")
: this.num(dt.month, 2);
case "MMM":
// like Jan
return month("short", false);
case "MMMM":
// like January
return month("long", false);
case "MMMMM":
// like J
return month("narrow", false);
// years
case "y":
// like 2014
return useDateTimeFormatter ? string({ year: "numeric" }, "year") : this.num(dt.year);
case "yy":
// like 14
return useDateTimeFormatter
? string({ year: "2-digit" }, "year")
: this.num(dt.year.toString().slice(-2), 2);
case "yyyy":
// like 0012
return useDateTimeFormatter
? string({ year: "numeric" }, "year")
: this.num(dt.year, 4);
case "yyyyyy":
// like 000012
return useDateTimeFormatter
? string({ year: "numeric" }, "year")
: this.num(dt.year, 6);
// eras
case "G":
// like AD
return era("short");
case "GG":
// like Anno Domini
return era("long");
case "GGGGG":
return era("narrow");
case "kk":
return this.num(dt.weekYear.toString().slice(-2), 2);
case "kkkk":
return this.num(dt.weekYear, 4);
case "W":
return this.num(dt.weekNumber);
case "WW":
return this.num(dt.weekNumber, 2);
case "n":
return this.num(dt.localWeekNumber);
case "nn":
return this.num(dt.localWeekNumber, 2);
case "ii":
return this.num(dt.localWeekYear.toString().slice(-2), 2);
case "iiii":
return this.num(dt.localWeekYear, 4);
case "o":
return this.num(dt.ordinal);
case "ooo":
return this.num(dt.ordinal, 3);
case "q":
// like 1
return this.num(dt.quarter);
case "qq":
// like 01
return this.num(dt.quarter, 2);
case "X":
return this.num(Math.floor(dt.ts / 1000));
case "x":
return this.num(dt.ts);
default:
return maybeMacro(token);
}
};
return stringifyTokens(Formatter.parseFormat(fmt), tokenToString);
}
formatDurationFromString(dur, fmt) {
const invertLargest = this.opts.signMode === "negativeLargestOnly" ? -1 : 1;
const tokenToField = (token) => {
switch (token[0]) {
case "S":
return "milliseconds";
case "s":
return "seconds";
case "m":
return "minutes";
case "h":
return "hours";
case "d":
return "days";
case "w":
return "weeks";
case "M":
return "months";
case "y":
return "years";
default:
return null;
}
},
tokenToString = (lildur, info) => (token) => {
const mapped = tokenToField(token);
if (mapped) {
const inversionFactor =
info.isNegativeDuration && mapped !== info.largestUnit ? invertLargest : 1;
let signDisplay;
if (this.opts.signMode === "negativeLargestOnly" && mapped !== info.largestUnit) {
signDisplay = "never";
} else if (this.opts.signMode === "all") {
signDisplay = "always";
} else {
// "auto" and "negative" are the same, but "auto" has better support
signDisplay = "auto";
}
return this.num(lildur.get(mapped) * inversionFactor, token.length, signDisplay);
} else {
return token;
}
},
tokens = Formatter.parseFormat(fmt),
realTokens = tokens.reduce(
(found, { literal, val }) => (literal ? found : found.concat(val)),
[]
),
collapsed = dur.shiftTo(...realTokens.map(tokenToField).filter((t) => t)),
durationInfo = {
isNegativeDuration: collapsed < 0,
// this relies on "collapsed" being based on "shiftTo", which builds up the object
// in order
largestUnit: Object.keys(collapsed.values)[0],
};
return stringifyTokens(tokens, tokenToString(collapsed, durationInfo));
}
}

14
node_modules/luxon/src/impl/invalid.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
export default class Invalid {
constructor(reason, explanation) {
this.reason = reason;
this.explanation = explanation;
}
toMessage() {
if (this.explanation) {
return `${this.reason}: ${this.explanation}`;
} else {
return this.reason;
}
}
}

569
node_modules/luxon/src/impl/locale.js generated vendored Normal file
View File

@@ -0,0 +1,569 @@
import { hasLocaleWeekInfo, hasRelative, padStart, roundTo, validateWeekSettings } from "./util.js";
import * as English from "./english.js";
import Settings from "../settings.js";
import DateTime from "../datetime.js";
import IANAZone from "../zones/IANAZone.js";
// todo - remap caching
let intlLFCache = {};
function getCachedLF(locString, opts = {}) {
const key = JSON.stringify([locString, opts]);
let dtf = intlLFCache[key];
if (!dtf) {
dtf = new Intl.ListFormat(locString, opts);
intlLFCache[key] = dtf;
}
return dtf;
}
const intlDTCache = new Map();
function getCachedDTF(locString, opts = {}) {
const key = JSON.stringify([locString, opts]);
let dtf = intlDTCache.get(key);
if (dtf === undefined) {
dtf = new Intl.DateTimeFormat(locString, opts);
intlDTCache.set(key, dtf);
}
return dtf;
}
const intlNumCache = new Map();
function getCachedINF(locString, opts = {}) {
const key = JSON.stringify([locString, opts]);
let inf = intlNumCache.get(key);
if (inf === undefined) {
inf = new Intl.NumberFormat(locString, opts);
intlNumCache.set(key, inf);
}
return inf;
}
const intlRelCache = new Map();
function getCachedRTF(locString, opts = {}) {
const { base, ...cacheKeyOpts } = opts; // exclude `base` from the options
const key = JSON.stringify([locString, cacheKeyOpts]);
let inf = intlRelCache.get(key);
if (inf === undefined) {
inf = new Intl.RelativeTimeFormat(locString, opts);
intlRelCache.set(key, inf);
}
return inf;
}
let sysLocaleCache = null;
function systemLocale() {
if (sysLocaleCache) {
return sysLocaleCache;
} else {
sysLocaleCache = new Intl.DateTimeFormat().resolvedOptions().locale;
return sysLocaleCache;
}
}
const intlResolvedOptionsCache = new Map();
function getCachedIntResolvedOptions(locString) {
let opts = intlResolvedOptionsCache.get(locString);
if (opts === undefined) {
opts = new Intl.DateTimeFormat(locString).resolvedOptions();
intlResolvedOptionsCache.set(locString, opts);
}
return opts;
}
const weekInfoCache = new Map();
function getCachedWeekInfo(locString) {
let data = weekInfoCache.get(locString);
if (!data) {
const locale = new Intl.Locale(locString);
// browsers currently implement this as a property, but spec says it should be a getter function
data = "getWeekInfo" in locale ? locale.getWeekInfo() : locale.weekInfo;
// minimalDays was removed from WeekInfo: https://github.com/tc39/proposal-intl-locale-info/issues/86
if (!("minimalDays" in data)) {
data = { ...fallbackWeekSettings, ...data };
}
weekInfoCache.set(locString, data);
}
return data;
}
function parseLocaleString(localeStr) {
// I really want to avoid writing a BCP 47 parser
// see, e.g. https://github.com/wooorm/bcp-47
// Instead, we'll do this:
// a) if the string has no -u extensions, just leave it alone
// b) if it does, use Intl to resolve everything
// c) if Intl fails, try again without the -u
// private subtags and unicode subtags have ordering requirements,
// and we're not properly parsing this, so just strip out the
// private ones if they exist.
const xIndex = localeStr.indexOf("-x-");
if (xIndex !== -1) {
localeStr = localeStr.substring(0, xIndex);
}
const uIndex = localeStr.indexOf("-u-");
if (uIndex === -1) {
return [localeStr];
} else {
let options;
let selectedStr;
try {
options = getCachedDTF(localeStr).resolvedOptions();
selectedStr = localeStr;
} catch (e) {
const smaller = localeStr.substring(0, uIndex);
options = getCachedDTF(smaller).resolvedOptions();
selectedStr = smaller;
}
const { numberingSystem, calendar } = options;
return [selectedStr, numberingSystem, calendar];
}
}
function intlConfigString(localeStr, numberingSystem, outputCalendar) {
if (outputCalendar || numberingSystem) {
if (!localeStr.includes("-u-")) {
localeStr += "-u";
}
if (outputCalendar) {
localeStr += `-ca-${outputCalendar}`;
}
if (numberingSystem) {
localeStr += `-nu-${numberingSystem}`;
}
return localeStr;
} else {
return localeStr;
}
}
function mapMonths(f) {
const ms = [];
for (let i = 1; i <= 12; i++) {
const dt = DateTime.utc(2009, i, 1);
ms.push(f(dt));
}
return ms;
}
function mapWeekdays(f) {
const ms = [];
for (let i = 1; i <= 7; i++) {
const dt = DateTime.utc(2016, 11, 13 + i);
ms.push(f(dt));
}
return ms;
}
function listStuff(loc, length, englishFn, intlFn) {
const mode = loc.listingMode();
if (mode === "error") {
return null;
} else if (mode === "en") {
return englishFn(length);
} else {
return intlFn(length);
}
}
function supportsFastNumbers(loc) {
if (loc.numberingSystem && loc.numberingSystem !== "latn") {
return false;
} else {
return (
loc.numberingSystem === "latn" ||
!loc.locale ||
loc.locale.startsWith("en") ||
getCachedIntResolvedOptions(loc.locale).numberingSystem === "latn"
);
}
}
/**
* @private
*/
class PolyNumberFormatter {
constructor(intl, forceSimple, opts) {
this.padTo = opts.padTo || 0;
this.floor = opts.floor || false;
const { padTo, floor, ...otherOpts } = opts;
if (!forceSimple || Object.keys(otherOpts).length > 0) {
const intlOpts = { useGrouping: false, ...opts };
if (opts.padTo > 0) intlOpts.minimumIntegerDigits = opts.padTo;
this.inf = getCachedINF(intl, intlOpts);
}
}
format(i) {
if (this.inf) {
const fixed = this.floor ? Math.floor(i) : i;
return this.inf.format(fixed);
} else {
// to match the browser's numberformatter defaults
const fixed = this.floor ? Math.floor(i) : roundTo(i, 3);
return padStart(fixed, this.padTo);
}
}
}
/**
* @private
*/
class PolyDateFormatter {
constructor(dt, intl, opts) {
this.opts = opts;
this.originalZone = undefined;
let z = undefined;
if (this.opts.timeZone) {
// Don't apply any workarounds if a timeZone is explicitly provided in opts
this.dt = dt;
} else if (dt.zone.type === "fixed") {
// UTC-8 or Etc/UTC-8 are not part of tzdata, only Etc/GMT+8 and the like.
// That is why fixed-offset TZ is set to that unless it is:
// 1. Representing offset 0 when UTC is used to maintain previous behavior and does not become GMT.
// 2. Unsupported by the browser:
// - some do not support Etc/
// - < Etc/GMT-14, > Etc/GMT+12, and 30-minute or 45-minute offsets are not part of tzdata
const gmtOffset = -1 * (dt.offset / 60);
const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`;
if (dt.offset !== 0 && IANAZone.create(offsetZ).valid) {
z = offsetZ;
this.dt = dt;
} else {
// Not all fixed-offset zones like Etc/+4:30 are present in tzdata so
// we manually apply the offset and substitute the zone as needed.
z = "UTC";
this.dt = dt.offset === 0 ? dt : dt.setZone("UTC").plus({ minutes: dt.offset });
this.originalZone = dt.zone;
}
} else if (dt.zone.type === "system") {
this.dt = dt;
} else if (dt.zone.type === "iana") {
this.dt = dt;
z = dt.zone.name;
} else {
// Custom zones can have any offset / offsetName so we just manually
// apply the offset and substitute the zone as needed.
z = "UTC";
this.dt = dt.setZone("UTC").plus({ minutes: dt.offset });
this.originalZone = dt.zone;
}
const intlOpts = { ...this.opts };
intlOpts.timeZone = intlOpts.timeZone || z;
this.dtf = getCachedDTF(intl, intlOpts);
}
format() {
if (this.originalZone) {
// If we have to substitute in the actual zone name, we have to use
// formatToParts so that the timezone can be replaced.
return this.formatToParts()
.map(({ value }) => value)
.join("");
}
return this.dtf.format(this.dt.toJSDate());
}
formatToParts() {
const parts = this.dtf.formatToParts(this.dt.toJSDate());
if (this.originalZone) {
return parts.map((part) => {
if (part.type === "timeZoneName") {
const offsetName = this.originalZone.offsetName(this.dt.ts, {
locale: this.dt.locale,
format: this.opts.timeZoneName,
});
return {
...part,
value: offsetName,
};
} else {
return part;
}
});
}
return parts;
}
resolvedOptions() {
return this.dtf.resolvedOptions();
}
}
/**
* @private
*/
class PolyRelFormatter {
constructor(intl, isEnglish, opts) {
this.opts = { style: "long", ...opts };
if (!isEnglish && hasRelative()) {
this.rtf = getCachedRTF(intl, opts);
}
}
format(count, unit) {
if (this.rtf) {
return this.rtf.format(count, unit);
} else {
return English.formatRelativeTime(unit, count, this.opts.numeric, this.opts.style !== "long");
}
}
formatToParts(count, unit) {
if (this.rtf) {
return this.rtf.formatToParts(count, unit);
} else {
return [];
}
}
}
const fallbackWeekSettings = {
firstDay: 1,
minimalDays: 4,
weekend: [6, 7],
};
/**
* @private
*/
export default class Locale {
static fromOpts(opts) {
return Locale.create(
opts.locale,
opts.numberingSystem,
opts.outputCalendar,
opts.weekSettings,
opts.defaultToEN
);
}
static create(locale, numberingSystem, outputCalendar, weekSettings, defaultToEN = false) {
const specifiedLocale = locale || Settings.defaultLocale;
// the system locale is useful for human-readable strings but annoying for parsing/formatting known formats
const localeR = specifiedLocale || (defaultToEN ? "en-US" : systemLocale());
const numberingSystemR = numberingSystem || Settings.defaultNumberingSystem;
const outputCalendarR = outputCalendar || Settings.defaultOutputCalendar;
const weekSettingsR = validateWeekSettings(weekSettings) || Settings.defaultWeekSettings;
return new Locale(localeR, numberingSystemR, outputCalendarR, weekSettingsR, specifiedLocale);
}
static resetCache() {
sysLocaleCache = null;
intlDTCache.clear();
intlNumCache.clear();
intlRelCache.clear();
intlResolvedOptionsCache.clear();
weekInfoCache.clear();
}
static fromObject({ locale, numberingSystem, outputCalendar, weekSettings } = {}) {
return Locale.create(locale, numberingSystem, outputCalendar, weekSettings);
}
constructor(locale, numbering, outputCalendar, weekSettings, specifiedLocale) {
const [parsedLocale, parsedNumberingSystem, parsedOutputCalendar] = parseLocaleString(locale);
this.locale = parsedLocale;
this.numberingSystem = numbering || parsedNumberingSystem || null;
this.outputCalendar = outputCalendar || parsedOutputCalendar || null;
this.weekSettings = weekSettings;
this.intl = intlConfigString(this.locale, this.numberingSystem, this.outputCalendar);
this.weekdaysCache = { format: {}, standalone: {} };
this.monthsCache = { format: {}, standalone: {} };
this.meridiemCache = null;
this.eraCache = {};
this.specifiedLocale = specifiedLocale;
this.fastNumbersCached = null;
}
get fastNumbers() {
if (this.fastNumbersCached == null) {
this.fastNumbersCached = supportsFastNumbers(this);
}
return this.fastNumbersCached;
}
listingMode() {
const isActuallyEn = this.isEnglish();
const hasNoWeirdness =
(this.numberingSystem === null || this.numberingSystem === "latn") &&
(this.outputCalendar === null || this.outputCalendar === "gregory");
return isActuallyEn && hasNoWeirdness ? "en" : "intl";
}
clone(alts) {
if (!alts || Object.getOwnPropertyNames(alts).length === 0) {
return this;
} else {
return Locale.create(
alts.locale || this.specifiedLocale,
alts.numberingSystem || this.numberingSystem,
alts.outputCalendar || this.outputCalendar,
validateWeekSettings(alts.weekSettings) || this.weekSettings,
alts.defaultToEN || false
);
}
}
redefaultToEN(alts = {}) {
return this.clone({ ...alts, defaultToEN: true });
}
redefaultToSystem(alts = {}) {
return this.clone({ ...alts, defaultToEN: false });
}
months(length, format = false) {
return listStuff(this, length, English.months, () => {
// Workaround for "ja" locale: formatToParts does not label all parts of the month
// as "month" and for this locale there is no difference between "format" and "non-format".
// As such, just use format() instead of formatToParts() and take the whole string
const monthSpecialCase = this.intl === "ja" || this.intl.startsWith("ja-");
format &= !monthSpecialCase;
const intl = format ? { month: length, day: "numeric" } : { month: length },
formatStr = format ? "format" : "standalone";
if (!this.monthsCache[formatStr][length]) {
const mapper = !monthSpecialCase
? (dt) => this.extract(dt, intl, "month")
: (dt) => this.dtFormatter(dt, intl).format();
this.monthsCache[formatStr][length] = mapMonths(mapper);
}
return this.monthsCache[formatStr][length];
});
}
weekdays(length, format = false) {
return listStuff(this, length, English.weekdays, () => {
const intl = format
? { weekday: length, year: "numeric", month: "long", day: "numeric" }
: { weekday: length },
formatStr = format ? "format" : "standalone";
if (!this.weekdaysCache[formatStr][length]) {
this.weekdaysCache[formatStr][length] = mapWeekdays((dt) =>
this.extract(dt, intl, "weekday")
);
}
return this.weekdaysCache[formatStr][length];
});
}
meridiems() {
return listStuff(
this,
undefined,
() => English.meridiems,
() => {
// In theory there could be aribitrary day periods. We're gonna assume there are exactly two
// for AM and PM. This is probably wrong, but it's makes parsing way easier.
if (!this.meridiemCache) {
const intl = { hour: "numeric", hourCycle: "h12" };
this.meridiemCache = [DateTime.utc(2016, 11, 13, 9), DateTime.utc(2016, 11, 13, 19)].map(
(dt) => this.extract(dt, intl, "dayperiod")
);
}
return this.meridiemCache;
}
);
}
eras(length) {
return listStuff(this, length, English.eras, () => {
const intl = { era: length };
// This is problematic. Different calendars are going to define eras totally differently. What I need is the minimum set of dates
// to definitely enumerate them.
if (!this.eraCache[length]) {
this.eraCache[length] = [DateTime.utc(-40, 1, 1), DateTime.utc(2017, 1, 1)].map((dt) =>
this.extract(dt, intl, "era")
);
}
return this.eraCache[length];
});
}
extract(dt, intlOpts, field) {
const df = this.dtFormatter(dt, intlOpts),
results = df.formatToParts(),
matching = results.find((m) => m.type.toLowerCase() === field);
return matching ? matching.value : null;
}
numberFormatter(opts = {}) {
// this forcesimple option is never used (the only caller short-circuits on it, but it seems safer to leave)
// (in contrast, the rest of the condition is used heavily)
return new PolyNumberFormatter(this.intl, opts.forceSimple || this.fastNumbers, opts);
}
dtFormatter(dt, intlOpts = {}) {
return new PolyDateFormatter(dt, this.intl, intlOpts);
}
relFormatter(opts = {}) {
return new PolyRelFormatter(this.intl, this.isEnglish(), opts);
}
listFormatter(opts = {}) {
return getCachedLF(this.intl, opts);
}
isEnglish() {
return (
this.locale === "en" ||
this.locale.toLowerCase() === "en-us" ||
getCachedIntResolvedOptions(this.intl).locale.startsWith("en-us")
);
}
getWeekSettings() {
if (this.weekSettings) {
return this.weekSettings;
} else if (!hasLocaleWeekInfo()) {
return fallbackWeekSettings;
} else {
return getCachedWeekInfo(this.locale);
}
}
getStartOfWeek() {
return this.getWeekSettings().firstDay;
}
getMinDaysInFirstWeek() {
return this.getWeekSettings().minimalDays;
}
getWeekendDays() {
return this.getWeekSettings().weekend;
}
equals(other) {
return (
this.locale === other.locale &&
this.numberingSystem === other.numberingSystem &&
this.outputCalendar === other.outputCalendar
);
}
toString() {
return `Locale(${this.locale}, ${this.numberingSystem}, ${this.outputCalendar})`;
}
}

335
node_modules/luxon/src/impl/regexParser.js generated vendored Normal file
View File

@@ -0,0 +1,335 @@
import {
untruncateYear,
signedOffset,
parseInteger,
parseMillis,
isUndefined,
parseFloating,
} from "./util.js";
import * as English from "./english.js";
import FixedOffsetZone from "../zones/fixedOffsetZone.js";
import IANAZone from "../zones/IANAZone.js";
/*
* This file handles parsing for well-specified formats. Here's how it works:
* Two things go into parsing: a regex to match with and an extractor to take apart the groups in the match.
* An extractor is just a function that takes a regex match array and returns a { year: ..., month: ... } object
* parse() does the work of executing the regex and applying the extractor. It takes multiple regex/extractor pairs to try in sequence.
* Extractors can take a "cursor" representing the offset in the match to look at. This makes it easy to combine extractors.
* combineExtractors() does the work of combining them, keeping track of the cursor through multiple extractions.
* Some extractions are super dumb and simpleParse and fromStrings help DRY them.
*/
const ianaRegex = /[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/;
function combineRegexes(...regexes) {
const full = regexes.reduce((f, r) => f + r.source, "");
return RegExp(`^${full}$`);
}
function combineExtractors(...extractors) {
return (m) =>
extractors
.reduce(
([mergedVals, mergedZone, cursor], ex) => {
const [val, zone, next] = ex(m, cursor);
return [{ ...mergedVals, ...val }, zone || mergedZone, next];
},
[{}, null, 1]
)
.slice(0, 2);
}
function parse(s, ...patterns) {
if (s == null) {
return [null, null];
}
for (const [regex, extractor] of patterns) {
const m = regex.exec(s);
if (m) {
return extractor(m);
}
}
return [null, null];
}
function simpleParse(...keys) {
return (match, cursor) => {
const ret = {};
let i;
for (i = 0; i < keys.length; i++) {
ret[keys[i]] = parseInteger(match[cursor + i]);
}
return [ret, null, cursor + i];
};
}
// ISO and SQL parsing
const offsetRegex = /(?:([Zz])|([+-]\d\d)(?::?(\d\d))?)/;
const isoExtendedZone = `(?:${offsetRegex.source}?(?:\\[(${ianaRegex.source})\\])?)?`;
const isoTimeBaseRegex = /(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/;
const isoTimeRegex = RegExp(`${isoTimeBaseRegex.source}${isoExtendedZone}`);
const isoTimeExtensionRegex = RegExp(`(?:[Tt]${isoTimeRegex.source})?`);
const isoYmdRegex = /([+-]\d{6}|\d{4})(?:-?(\d\d)(?:-?(\d\d))?)?/;
const isoWeekRegex = /(\d{4})-?W(\d\d)(?:-?(\d))?/;
const isoOrdinalRegex = /(\d{4})-?(\d{3})/;
const extractISOWeekData = simpleParse("weekYear", "weekNumber", "weekDay");
const extractISOOrdinalData = simpleParse("year", "ordinal");
const sqlYmdRegex = /(\d{4})-(\d\d)-(\d\d)/; // dumbed-down version of the ISO one
const sqlTimeRegex = RegExp(
`${isoTimeBaseRegex.source} ?(?:${offsetRegex.source}|(${ianaRegex.source}))?`
);
const sqlTimeExtensionRegex = RegExp(`(?: ${sqlTimeRegex.source})?`);
function int(match, pos, fallback) {
const m = match[pos];
return isUndefined(m) ? fallback : parseInteger(m);
}
function extractISOYmd(match, cursor) {
const item = {
year: int(match, cursor),
month: int(match, cursor + 1, 1),
day: int(match, cursor + 2, 1),
};
return [item, null, cursor + 3];
}
function extractISOTime(match, cursor) {
const item = {
hours: int(match, cursor, 0),
minutes: int(match, cursor + 1, 0),
seconds: int(match, cursor + 2, 0),
milliseconds: parseMillis(match[cursor + 3]),
};
return [item, null, cursor + 4];
}
function extractISOOffset(match, cursor) {
const local = !match[cursor] && !match[cursor + 1],
fullOffset = signedOffset(match[cursor + 1], match[cursor + 2]),
zone = local ? null : FixedOffsetZone.instance(fullOffset);
return [{}, zone, cursor + 3];
}
function extractIANAZone(match, cursor) {
const zone = match[cursor] ? IANAZone.create(match[cursor]) : null;
return [{}, zone, cursor + 1];
}
// ISO time parsing
const isoTimeOnly = RegExp(`^T?${isoTimeBaseRegex.source}$`);
// ISO duration parsing
const isoDuration =
/^-?P(?:(?:(-?\d{1,20}(?:\.\d{1,20})?)Y)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20}(?:\.\d{1,20})?)W)?(?:(-?\d{1,20}(?:\.\d{1,20})?)D)?(?:T(?:(-?\d{1,20}(?:\.\d{1,20})?)H)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20})(?:[.,](-?\d{1,20}))?S)?)?)$/;
function extractISODuration(match) {
const [s, yearStr, monthStr, weekStr, dayStr, hourStr, minuteStr, secondStr, millisecondsStr] =
match;
const hasNegativePrefix = s[0] === "-";
const negativeSeconds = secondStr && secondStr[0] === "-";
const maybeNegate = (num, force = false) =>
num !== undefined && (force || (num && hasNegativePrefix)) ? -num : num;
return [
{
years: maybeNegate(parseFloating(yearStr)),
months: maybeNegate(parseFloating(monthStr)),
weeks: maybeNegate(parseFloating(weekStr)),
days: maybeNegate(parseFloating(dayStr)),
hours: maybeNegate(parseFloating(hourStr)),
minutes: maybeNegate(parseFloating(minuteStr)),
seconds: maybeNegate(parseFloating(secondStr), secondStr === "-0"),
milliseconds: maybeNegate(parseMillis(millisecondsStr), negativeSeconds),
},
];
}
// These are a little braindead. EDT *should* tell us that we're in, say, America/New_York
// and not just that we're in -240 *right now*. But since I don't think these are used that often
// I'm just going to ignore that
const obsOffsets = {
GMT: 0,
EDT: -4 * 60,
EST: -5 * 60,
CDT: -5 * 60,
CST: -6 * 60,
MDT: -6 * 60,
MST: -7 * 60,
PDT: -7 * 60,
PST: -8 * 60,
};
function fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
const result = {
year: yearStr.length === 2 ? untruncateYear(parseInteger(yearStr)) : parseInteger(yearStr),
month: English.monthsShort.indexOf(monthStr) + 1,
day: parseInteger(dayStr),
hour: parseInteger(hourStr),
minute: parseInteger(minuteStr),
};
if (secondStr) result.second = parseInteger(secondStr);
if (weekdayStr) {
result.weekday =
weekdayStr.length > 3
? English.weekdaysLong.indexOf(weekdayStr) + 1
: English.weekdaysShort.indexOf(weekdayStr) + 1;
}
return result;
}
// RFC 2822/5322
const rfc2822 =
/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;
function extractRFC2822(match) {
const [
,
weekdayStr,
dayStr,
monthStr,
yearStr,
hourStr,
minuteStr,
secondStr,
obsOffset,
milOffset,
offHourStr,
offMinuteStr,
] = match,
result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
let offset;
if (obsOffset) {
offset = obsOffsets[obsOffset];
} else if (milOffset) {
offset = 0;
} else {
offset = signedOffset(offHourStr, offMinuteStr);
}
return [result, new FixedOffsetZone(offset)];
}
function preprocessRFC2822(s) {
// Remove comments and folding whitespace and replace multiple-spaces with a single space
return s
.replace(/\([^()]*\)|[\n\t]/g, " ")
.replace(/(\s\s+)/g, " ")
.trim();
}
// http date
const rfc1123 =
/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/,
rfc850 =
/^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/,
ascii =
/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/;
function extractRFC1123Or850(match) {
const [, weekdayStr, dayStr, monthStr, yearStr, hourStr, minuteStr, secondStr] = match,
result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
return [result, FixedOffsetZone.utcInstance];
}
function extractASCII(match) {
const [, weekdayStr, monthStr, dayStr, hourStr, minuteStr, secondStr, yearStr] = match,
result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
return [result, FixedOffsetZone.utcInstance];
}
const isoYmdWithTimeExtensionRegex = combineRegexes(isoYmdRegex, isoTimeExtensionRegex);
const isoWeekWithTimeExtensionRegex = combineRegexes(isoWeekRegex, isoTimeExtensionRegex);
const isoOrdinalWithTimeExtensionRegex = combineRegexes(isoOrdinalRegex, isoTimeExtensionRegex);
const isoTimeCombinedRegex = combineRegexes(isoTimeRegex);
const extractISOYmdTimeAndOffset = combineExtractors(
extractISOYmd,
extractISOTime,
extractISOOffset,
extractIANAZone
);
const extractISOWeekTimeAndOffset = combineExtractors(
extractISOWeekData,
extractISOTime,
extractISOOffset,
extractIANAZone
);
const extractISOOrdinalDateAndTime = combineExtractors(
extractISOOrdinalData,
extractISOTime,
extractISOOffset,
extractIANAZone
);
const extractISOTimeAndOffset = combineExtractors(
extractISOTime,
extractISOOffset,
extractIANAZone
);
/*
* @private
*/
export function parseISODate(s) {
return parse(
s,
[isoYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset],
[isoWeekWithTimeExtensionRegex, extractISOWeekTimeAndOffset],
[isoOrdinalWithTimeExtensionRegex, extractISOOrdinalDateAndTime],
[isoTimeCombinedRegex, extractISOTimeAndOffset]
);
}
export function parseRFC2822Date(s) {
return parse(preprocessRFC2822(s), [rfc2822, extractRFC2822]);
}
export function parseHTTPDate(s) {
return parse(
s,
[rfc1123, extractRFC1123Or850],
[rfc850, extractRFC1123Or850],
[ascii, extractASCII]
);
}
export function parseISODuration(s) {
return parse(s, [isoDuration, extractISODuration]);
}
const extractISOTimeOnly = combineExtractors(extractISOTime);
export function parseISOTimeOnly(s) {
return parse(s, [isoTimeOnly, extractISOTimeOnly]);
}
const sqlYmdWithTimeExtensionRegex = combineRegexes(sqlYmdRegex, sqlTimeExtensionRegex);
const sqlTimeCombinedRegex = combineRegexes(sqlTimeRegex);
const extractISOTimeOffsetAndIANAZone = combineExtractors(
extractISOTime,
extractISOOffset,
extractIANAZone
);
export function parseSQL(s) {
return parse(
s,
[sqlYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset],
[sqlTimeCombinedRegex, extractISOTimeOffsetAndIANAZone]
);
}

505
node_modules/luxon/src/impl/tokenParser.js generated vendored Normal file
View File

@@ -0,0 +1,505 @@
import { parseMillis, isUndefined, untruncateYear, signedOffset, hasOwnProperty } from "./util.js";
import Formatter from "./formatter.js";
import FixedOffsetZone from "../zones/fixedOffsetZone.js";
import IANAZone from "../zones/IANAZone.js";
import DateTime from "../datetime.js";
import { digitRegex, parseDigits } from "./digits.js";
import { ConflictingSpecificationError } from "../errors.js";
const MISSING_FTP = "missing Intl.DateTimeFormat.formatToParts support";
function intUnit(regex, post = (i) => i) {
return { regex, deser: ([s]) => post(parseDigits(s)) };
}
const NBSP = String.fromCharCode(160);
const spaceOrNBSP = `[ ${NBSP}]`;
const spaceOrNBSPRegExp = new RegExp(spaceOrNBSP, "g");
function fixListRegex(s) {
// make dots optional and also make them literal
// make space and non breakable space characters interchangeable
return s.replace(/\./g, "\\.?").replace(spaceOrNBSPRegExp, spaceOrNBSP);
}
function stripInsensitivities(s) {
return s
.replace(/\./g, "") // ignore dots that were made optional
.replace(spaceOrNBSPRegExp, " ") // interchange space and nbsp
.toLowerCase();
}
function oneOf(strings, startIndex) {
if (strings === null) {
return null;
} else {
return {
regex: RegExp(strings.map(fixListRegex).join("|")),
deser: ([s]) =>
strings.findIndex((i) => stripInsensitivities(s) === stripInsensitivities(i)) + startIndex,
};
}
}
function offset(regex, groups) {
return { regex, deser: ([, h, m]) => signedOffset(h, m), groups };
}
function simple(regex) {
return { regex, deser: ([s]) => s };
}
function escapeToken(value) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
/**
* @param token
* @param {Locale} loc
*/
function unitForToken(token, loc) {
const one = digitRegex(loc),
two = digitRegex(loc, "{2}"),
three = digitRegex(loc, "{3}"),
four = digitRegex(loc, "{4}"),
six = digitRegex(loc, "{6}"),
oneOrTwo = digitRegex(loc, "{1,2}"),
oneToThree = digitRegex(loc, "{1,3}"),
oneToSix = digitRegex(loc, "{1,6}"),
oneToNine = digitRegex(loc, "{1,9}"),
twoToFour = digitRegex(loc, "{2,4}"),
fourToSix = digitRegex(loc, "{4,6}"),
literal = (t) => ({ regex: RegExp(escapeToken(t.val)), deser: ([s]) => s, literal: true }),
unitate = (t) => {
if (token.literal) {
return literal(t);
}
switch (t.val) {
// era
case "G":
return oneOf(loc.eras("short"), 0);
case "GG":
return oneOf(loc.eras("long"), 0);
// years
case "y":
return intUnit(oneToSix);
case "yy":
return intUnit(twoToFour, untruncateYear);
case "yyyy":
return intUnit(four);
case "yyyyy":
return intUnit(fourToSix);
case "yyyyyy":
return intUnit(six);
// months
case "M":
return intUnit(oneOrTwo);
case "MM":
return intUnit(two);
case "MMM":
return oneOf(loc.months("short", true), 1);
case "MMMM":
return oneOf(loc.months("long", true), 1);
case "L":
return intUnit(oneOrTwo);
case "LL":
return intUnit(two);
case "LLL":
return oneOf(loc.months("short", false), 1);
case "LLLL":
return oneOf(loc.months("long", false), 1);
// dates
case "d":
return intUnit(oneOrTwo);
case "dd":
return intUnit(two);
// ordinals
case "o":
return intUnit(oneToThree);
case "ooo":
return intUnit(three);
// time
case "HH":
return intUnit(two);
case "H":
return intUnit(oneOrTwo);
case "hh":
return intUnit(two);
case "h":
return intUnit(oneOrTwo);
case "mm":
return intUnit(two);
case "m":
return intUnit(oneOrTwo);
case "q":
return intUnit(oneOrTwo);
case "qq":
return intUnit(two);
case "s":
return intUnit(oneOrTwo);
case "ss":
return intUnit(two);
case "S":
return intUnit(oneToThree);
case "SSS":
return intUnit(three);
case "u":
return simple(oneToNine);
case "uu":
return simple(oneOrTwo);
case "uuu":
return intUnit(one);
// meridiem
case "a":
return oneOf(loc.meridiems(), 0);
// weekYear (k)
case "kkkk":
return intUnit(four);
case "kk":
return intUnit(twoToFour, untruncateYear);
// weekNumber (W)
case "W":
return intUnit(oneOrTwo);
case "WW":
return intUnit(two);
// weekdays
case "E":
case "c":
return intUnit(one);
case "EEE":
return oneOf(loc.weekdays("short", false), 1);
case "EEEE":
return oneOf(loc.weekdays("long", false), 1);
case "ccc":
return oneOf(loc.weekdays("short", true), 1);
case "cccc":
return oneOf(loc.weekdays("long", true), 1);
// offset/zone
case "Z":
case "ZZ":
return offset(new RegExp(`([+-]${oneOrTwo.source})(?::(${two.source}))?`), 2);
case "ZZZ":
return offset(new RegExp(`([+-]${oneOrTwo.source})(${two.source})?`), 2);
// we don't support ZZZZ (PST) or ZZZZZ (Pacific Standard Time) in parsing
// because we don't have any way to figure out what they are
case "z":
return simple(/[a-z_+-/]{1,256}?/i);
// this special-case "token" represents a place where a macro-token expanded into a white-space literal
// in this case we accept any non-newline white-space
case " ":
return simple(/[^\S\n\r]/);
default:
return literal(t);
}
};
const unit = unitate(token) || {
invalidReason: MISSING_FTP,
};
unit.token = token;
return unit;
}
const partTypeStyleToTokenVal = {
year: {
"2-digit": "yy",
numeric: "yyyyy",
},
month: {
numeric: "M",
"2-digit": "MM",
short: "MMM",
long: "MMMM",
},
day: {
numeric: "d",
"2-digit": "dd",
},
weekday: {
short: "EEE",
long: "EEEE",
},
dayperiod: "a",
dayPeriod: "a",
hour12: {
numeric: "h",
"2-digit": "hh",
},
hour24: {
numeric: "H",
"2-digit": "HH",
},
minute: {
numeric: "m",
"2-digit": "mm",
},
second: {
numeric: "s",
"2-digit": "ss",
},
timeZoneName: {
long: "ZZZZZ",
short: "ZZZ",
},
};
function tokenForPart(part, formatOpts, resolvedOpts) {
const { type, value } = part;
if (type === "literal") {
const isSpace = /^\s+$/.test(value);
return {
literal: !isSpace,
val: isSpace ? " " : value,
};
}
const style = formatOpts[type];
// The user might have explicitly specified hour12 or hourCycle
// if so, respect their decision
// if not, refer back to the resolvedOpts, which are based on the locale
let actualType = type;
if (type === "hour") {
if (formatOpts.hour12 != null) {
actualType = formatOpts.hour12 ? "hour12" : "hour24";
} else if (formatOpts.hourCycle != null) {
if (formatOpts.hourCycle === "h11" || formatOpts.hourCycle === "h12") {
actualType = "hour12";
} else {
actualType = "hour24";
}
} else {
// tokens only differentiate between 24 hours or not,
// so we do not need to check hourCycle here, which is less supported anyways
actualType = resolvedOpts.hour12 ? "hour12" : "hour24";
}
}
let val = partTypeStyleToTokenVal[actualType];
if (typeof val === "object") {
val = val[style];
}
if (val) {
return {
literal: false,
val,
};
}
return undefined;
}
function buildRegex(units) {
const re = units.map((u) => u.regex).reduce((f, r) => `${f}(${r.source})`, "");
return [`^${re}$`, units];
}
function match(input, regex, handlers) {
const matches = input.match(regex);
if (matches) {
const all = {};
let matchIndex = 1;
for (const i in handlers) {
if (hasOwnProperty(handlers, i)) {
const h = handlers[i],
groups = h.groups ? h.groups + 1 : 1;
if (!h.literal && h.token) {
all[h.token.val[0]] = h.deser(matches.slice(matchIndex, matchIndex + groups));
}
matchIndex += groups;
}
}
return [matches, all];
} else {
return [matches, {}];
}
}
function dateTimeFromMatches(matches) {
const toField = (token) => {
switch (token) {
case "S":
return "millisecond";
case "s":
return "second";
case "m":
return "minute";
case "h":
case "H":
return "hour";
case "d":
return "day";
case "o":
return "ordinal";
case "L":
case "M":
return "month";
case "y":
return "year";
case "E":
case "c":
return "weekday";
case "W":
return "weekNumber";
case "k":
return "weekYear";
case "q":
return "quarter";
default:
return null;
}
};
let zone = null;
let specificOffset;
if (!isUndefined(matches.z)) {
zone = IANAZone.create(matches.z);
}
if (!isUndefined(matches.Z)) {
if (!zone) {
zone = new FixedOffsetZone(matches.Z);
}
specificOffset = matches.Z;
}
if (!isUndefined(matches.q)) {
matches.M = (matches.q - 1) * 3 + 1;
}
if (!isUndefined(matches.h)) {
if (matches.h < 12 && matches.a === 1) {
matches.h += 12;
} else if (matches.h === 12 && matches.a === 0) {
matches.h = 0;
}
}
if (matches.G === 0 && matches.y) {
matches.y = -matches.y;
}
if (!isUndefined(matches.u)) {
matches.S = parseMillis(matches.u);
}
const vals = Object.keys(matches).reduce((r, k) => {
const f = toField(k);
if (f) {
r[f] = matches[k];
}
return r;
}, {});
return [vals, zone, specificOffset];
}
let dummyDateTimeCache = null;
function getDummyDateTime() {
if (!dummyDateTimeCache) {
dummyDateTimeCache = DateTime.fromMillis(1555555555555);
}
return dummyDateTimeCache;
}
function maybeExpandMacroToken(token, locale) {
if (token.literal) {
return token;
}
const formatOpts = Formatter.macroTokenToFormatOpts(token.val);
const tokens = formatOptsToTokens(formatOpts, locale);
if (tokens == null || tokens.includes(undefined)) {
return token;
}
return tokens;
}
export function expandMacroTokens(tokens, locale) {
return Array.prototype.concat(...tokens.map((t) => maybeExpandMacroToken(t, locale)));
}
/**
* @private
*/
export class TokenParser {
constructor(locale, format) {
this.locale = locale;
this.format = format;
this.tokens = expandMacroTokens(Formatter.parseFormat(format), locale);
this.units = this.tokens.map((t) => unitForToken(t, locale));
this.disqualifyingUnit = this.units.find((t) => t.invalidReason);
if (!this.disqualifyingUnit) {
const [regexString, handlers] = buildRegex(this.units);
this.regex = RegExp(regexString, "i");
this.handlers = handlers;
}
}
explainFromTokens(input) {
if (!this.isValid) {
return { input, tokens: this.tokens, invalidReason: this.invalidReason };
} else {
const [rawMatches, matches] = match(input, this.regex, this.handlers),
[result, zone, specificOffset] = matches
? dateTimeFromMatches(matches)
: [null, null, undefined];
if (hasOwnProperty(matches, "a") && hasOwnProperty(matches, "H")) {
throw new ConflictingSpecificationError(
"Can't include meridiem when specifying 24-hour format"
);
}
return {
input,
tokens: this.tokens,
regex: this.regex,
rawMatches,
matches,
result,
zone,
specificOffset,
};
}
}
get isValid() {
return !this.disqualifyingUnit;
}
get invalidReason() {
return this.disqualifyingUnit ? this.disqualifyingUnit.invalidReason : null;
}
}
export function explainFromTokens(locale, input, format) {
const parser = new TokenParser(locale, format);
return parser.explainFromTokens(input);
}
export function parseFromTokens(locale, input, format) {
const { result, zone, specificOffset, invalidReason } = explainFromTokens(locale, input, format);
return [result, zone, specificOffset, invalidReason];
}
export function formatOptsToTokens(formatOpts, locale) {
if (!formatOpts) {
return null;
}
const formatter = Formatter.create(locale, formatOpts);
const df = formatter.dtFormatter(getDummyDateTime());
const parts = df.formatToParts();
const resolvedOpts = df.resolvedOptions();
return parts.map((p) => tokenForPart(p, formatOpts, resolvedOpts));
}

330
node_modules/luxon/src/impl/util.js generated vendored Normal file
View File

@@ -0,0 +1,330 @@
/*
This is just a junk drawer, containing anything used across multiple classes.
Because Luxon is small(ish), this should stay small and we won't worry about splitting
it up into, say, parsingUtil.js and basicUtil.js and so on. But they are divided up by feature area.
*/
import { InvalidArgumentError } from "../errors.js";
import Settings from "../settings.js";
import { dayOfWeek, isoWeekdayToLocal } from "./conversions.js";
/**
* @private
*/
// TYPES
export function isUndefined(o) {
return typeof o === "undefined";
}
export function isNumber(o) {
return typeof o === "number";
}
export function isInteger(o) {
return typeof o === "number" && o % 1 === 0;
}
export function isString(o) {
return typeof o === "string";
}
export function isDate(o) {
return Object.prototype.toString.call(o) === "[object Date]";
}
// CAPABILITIES
export function hasRelative() {
try {
return typeof Intl !== "undefined" && !!Intl.RelativeTimeFormat;
} catch (e) {
return false;
}
}
export function hasLocaleWeekInfo() {
try {
return (
typeof Intl !== "undefined" &&
!!Intl.Locale &&
("weekInfo" in Intl.Locale.prototype || "getWeekInfo" in Intl.Locale.prototype)
);
} catch (e) {
return false;
}
}
// OBJECTS AND ARRAYS
export function maybeArray(thing) {
return Array.isArray(thing) ? thing : [thing];
}
export function bestBy(arr, by, compare) {
if (arr.length === 0) {
return undefined;
}
return arr.reduce((best, next) => {
const pair = [by(next), next];
if (!best) {
return pair;
} else if (compare(best[0], pair[0]) === best[0]) {
return best;
} else {
return pair;
}
}, null)[1];
}
export function pick(obj, keys) {
return keys.reduce((a, k) => {
a[k] = obj[k];
return a;
}, {});
}
export function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
export function validateWeekSettings(settings) {
if (settings == null) {
return null;
} else if (typeof settings !== "object") {
throw new InvalidArgumentError("Week settings must be an object");
} else {
if (
!integerBetween(settings.firstDay, 1, 7) ||
!integerBetween(settings.minimalDays, 1, 7) ||
!Array.isArray(settings.weekend) ||
settings.weekend.some((v) => !integerBetween(v, 1, 7))
) {
throw new InvalidArgumentError("Invalid week settings");
}
return {
firstDay: settings.firstDay,
minimalDays: settings.minimalDays,
weekend: Array.from(settings.weekend),
};
}
}
// NUMBERS AND STRINGS
export function integerBetween(thing, bottom, top) {
return isInteger(thing) && thing >= bottom && thing <= top;
}
// x % n but takes the sign of n instead of x
export function floorMod(x, n) {
return x - n * Math.floor(x / n);
}
export function padStart(input, n = 2) {
const isNeg = input < 0;
let padded;
if (isNeg) {
padded = "-" + ("" + -input).padStart(n, "0");
} else {
padded = ("" + input).padStart(n, "0");
}
return padded;
}
export function parseInteger(string) {
if (isUndefined(string) || string === null || string === "") {
return undefined;
} else {
return parseInt(string, 10);
}
}
export function parseFloating(string) {
if (isUndefined(string) || string === null || string === "") {
return undefined;
} else {
return parseFloat(string);
}
}
export function parseMillis(fraction) {
// Return undefined (instead of 0) in these cases, where fraction is not set
if (isUndefined(fraction) || fraction === null || fraction === "") {
return undefined;
} else {
const f = parseFloat("0." + fraction) * 1000;
return Math.floor(f);
}
}
export function roundTo(number, digits, rounding = "round") {
const factor = 10 ** digits;
switch (rounding) {
case "expand":
return number > 0
? Math.ceil(number * factor) / factor
: Math.floor(number * factor) / factor;
case "trunc":
return Math.trunc(number * factor) / factor;
case "round":
return Math.round(number * factor) / factor;
case "floor":
return Math.floor(number * factor) / factor;
case "ceil":
return Math.ceil(number * factor) / factor;
default:
throw new RangeError(`Value rounding ${rounding} is out of range`);
}
}
// DATE BASICS
export function isLeapYear(year) {
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
}
export function daysInYear(year) {
return isLeapYear(year) ? 366 : 365;
}
export function daysInMonth(year, month) {
const modMonth = floorMod(month - 1, 12) + 1,
modYear = year + (month - modMonth) / 12;
if (modMonth === 2) {
return isLeapYear(modYear) ? 29 : 28;
} else {
return [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][modMonth - 1];
}
}
// convert a calendar object to a local timestamp (epoch, but with the offset baked in)
export function objToLocalTS(obj) {
let d = Date.UTC(
obj.year,
obj.month - 1,
obj.day,
obj.hour,
obj.minute,
obj.second,
obj.millisecond
);
// for legacy reasons, years between 0 and 99 are interpreted as 19XX; revert that
if (obj.year < 100 && obj.year >= 0) {
d = new Date(d);
// set the month and day again, this is necessary because year 2000 is a leap year, but year 100 is not
// so if obj.year is in 99, but obj.day makes it roll over into year 100,
// the calculations done by Date.UTC are using year 2000 - which is incorrect
d.setUTCFullYear(obj.year, obj.month - 1, obj.day);
}
return +d;
}
// adapted from moment.js: https://github.com/moment/moment/blob/000ac1800e620f770f4eb31b5ae908f6167b0ab2/src/lib/units/week-calendar-utils.js
function firstWeekOffset(year, minDaysInFirstWeek, startOfWeek) {
const fwdlw = isoWeekdayToLocal(dayOfWeek(year, 1, minDaysInFirstWeek), startOfWeek);
return -fwdlw + minDaysInFirstWeek - 1;
}
export function weeksInWeekYear(weekYear, minDaysInFirstWeek = 4, startOfWeek = 1) {
const weekOffset = firstWeekOffset(weekYear, minDaysInFirstWeek, startOfWeek);
const weekOffsetNext = firstWeekOffset(weekYear + 1, minDaysInFirstWeek, startOfWeek);
return (daysInYear(weekYear) - weekOffset + weekOffsetNext) / 7;
}
export function untruncateYear(year) {
if (year > 99) {
return year;
} else return year > Settings.twoDigitCutoffYear ? 1900 + year : 2000 + year;
}
// PARSING
export function parseZoneInfo(ts, offsetFormat, locale, timeZone = null) {
const date = new Date(ts),
intlOpts = {
hourCycle: "h23",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
};
if (timeZone) {
intlOpts.timeZone = timeZone;
}
const modified = { timeZoneName: offsetFormat, ...intlOpts };
const parsed = new Intl.DateTimeFormat(locale, modified)
.formatToParts(date)
.find((m) => m.type.toLowerCase() === "timezonename");
return parsed ? parsed.value : null;
}
// signedOffset('-5', '30') -> -330
export function signedOffset(offHourStr, offMinuteStr) {
let offHour = parseInt(offHourStr, 10);
// don't || this because we want to preserve -0
if (Number.isNaN(offHour)) {
offHour = 0;
}
const offMin = parseInt(offMinuteStr, 10) || 0,
offMinSigned = offHour < 0 || Object.is(offHour, -0) ? -offMin : offMin;
return offHour * 60 + offMinSigned;
}
// COERCION
export function asNumber(value) {
const numericValue = Number(value);
if (typeof value === "boolean" || value === "" || !Number.isFinite(numericValue))
throw new InvalidArgumentError(`Invalid unit value ${value}`);
return numericValue;
}
export function normalizeObject(obj, normalizer) {
const normalized = {};
for (const u in obj) {
if (hasOwnProperty(obj, u)) {
const v = obj[u];
if (v === undefined || v === null) continue;
normalized[normalizer(u)] = asNumber(v);
}
}
return normalized;
}
/**
* Returns the offset's value as a string
* @param {number} ts - Epoch milliseconds for which to get the offset
* @param {string} format - What style of offset to return.
* Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively
* @return {string}
*/
export function formatOffset(offset, format) {
const hours = Math.trunc(Math.abs(offset / 60)),
minutes = Math.trunc(Math.abs(offset % 60)),
sign = offset >= 0 ? "+" : "-";
switch (format) {
case "short":
return `${sign}${padStart(hours, 2)}:${padStart(minutes, 2)}`;
case "narrow":
return `${sign}${hours}${minutes > 0 ? `:${minutes}` : ""}`;
case "techie":
return `${sign}${padStart(hours, 2)}${padStart(minutes, 2)}`;
default:
throw new RangeError(`Value format ${format} is out of range for property format`);
}
}
export function timeObject(obj) {
return pick(obj, ["hour", "minute", "second", "millisecond"]);
}

34
node_modules/luxon/src/impl/zoneUtil.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
/**
* @private
*/
import Zone from "../zone.js";
import IANAZone from "../zones/IANAZone.js";
import FixedOffsetZone from "../zones/fixedOffsetZone.js";
import InvalidZone from "../zones/invalidZone.js";
import { isUndefined, isString, isNumber } from "./util.js";
import SystemZone from "../zones/systemZone.js";
export function normalizeZone(input, defaultZone) {
let offset;
if (isUndefined(input) || input === null) {
return defaultZone;
} else if (input instanceof Zone) {
return input;
} else if (isString(input)) {
const lowered = input.toLowerCase();
if (lowered === "default") return defaultZone;
else if (lowered === "local" || lowered === "system") return SystemZone.instance;
else if (lowered === "utc" || lowered === "gmt") return FixedOffsetZone.utcInstance;
else return FixedOffsetZone.parseSpecifier(lowered) || IANAZone.create(input);
} else if (isNumber(input)) {
return FixedOffsetZone.instance(input);
} else if (typeof input === "object" && "offset" in input && typeof input.offset === "function") {
// This is dumb, but the instanceof check above doesn't seem to really work
// so we're duck checking it
return input;
} else {
return new InvalidZone(input);
}
}