react-intl
Version:
Internationalize React apps. This library provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.
3,689 lines • 100 kB
JavaScript
"use client";
import * as React from "react";
import { Fragment, jsx } from "react/jsx-runtime";
//#region node_modules/.aspect_rules_js/@formatjs+fast-memoize@0.0.0/node_modules/@formatjs/fast-memoize/index.js
function memoize(fn, options) {
const cache = options && options.cache ? options.cache : cacheDefault;
const serializer = options && options.serializer ? options.serializer : serializerDefault;
return (options && options.strategy ? options.strategy : strategyDefault)(fn, {
cache,
serializer
});
}
function isPrimitive(value) {
return value == null || typeof value === "number" || typeof value === "boolean";
}
function monadic(fn, cache, serializer, arg) {
const cacheKey = isPrimitive(arg) ? arg : serializer(arg);
let computedValue = cache.get(cacheKey);
if (typeof computedValue === "undefined") {
computedValue = fn.call(this, arg);
cache.set(cacheKey, computedValue);
}
return computedValue;
}
function variadic(fn, cache, serializer) {
const args = Array.prototype.slice.call(arguments, 3);
const cacheKey = serializer(args);
let computedValue = cache.get(cacheKey);
if (typeof computedValue === "undefined") {
computedValue = fn.apply(this, args);
cache.set(cacheKey, computedValue);
}
return computedValue;
}
function assemble(fn, context, strategy, cache, serialize) {
return strategy.bind(context, fn, cache, serialize);
}
function strategyDefault(fn, options) {
const strategy = fn.length === 1 ? monadic : variadic;
return assemble(fn, this, strategy, options.cache.create(), options.serializer);
}
function strategyVariadic(fn, options) {
return assemble(fn, this, variadic, options.cache.create(), options.serializer);
}
function strategyMonadic(fn, options) {
return assemble(fn, this, monadic, options.cache.create(), options.serializer);
}
const serializerDefault = function() {
return JSON.stringify(arguments);
};
var ObjectWithoutPrototypeCache = class {
constructor() {
this.cache = Object.create(null);
}
get(key) {
return this.cache[key];
}
set(key, value) {
this.cache[key] = value;
}
};
const cacheDefault = { create: function create() {
return new ObjectWithoutPrototypeCache();
} };
const strategies = {
variadic: strategyVariadic,
monadic: strategyMonadic
};
//#endregion
//#region node_modules/.aspect_rules_js/@formatjs+icu-skeleton-parser@0.0.0/node_modules/@formatjs/icu-skeleton-parser/index.js
/**
* https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
* Credit: https://github.com/caridy/intl-datetimeformat-pattern/blob/master/index.js
* with some tweaks
*/
const DATE_TIME_REGEX = /(?:[Eec]{1,6}|G{1,5}|[Qq]{1,5}|(?:[yYur]+|U{1,5})|[ML]{1,5}|d{1,2}|D{1,3}|F{1}|[abB]{1,5}|[hkHK]{1,2}|w{1,2}|W{1}|m{1,2}|s{1,2}|[zZOvVxX]{1,4})(?=([^']*'[^']*')*[^']*$)/g;
/**
* Parse Date time skeleton into Intl.DateTimeFormatOptions
* Ref: https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
* @public
* @param skeleton skeleton string
*/
function parseDateTimeSkeleton(skeleton) {
const result = {};
skeleton.replace(DATE_TIME_REGEX, (match) => {
const len = match.length;
switch (match[0]) {
case "G":
result.era = len === 4 ? "long" : len === 5 ? "narrow" : "short";
break;
case "y":
result.year = len === 2 ? "2-digit" : "numeric";
break;
case "Y":
case "u":
case "U":
case "r": throw new RangeError("`Y/u/U/r` (year) patterns are not supported, use `y` instead");
case "q":
case "Q": throw new RangeError("`q/Q` (quarter) patterns are not supported");
case "M":
case "L":
result.month = [
"numeric",
"2-digit",
"short",
"long",
"narrow"
][len - 1];
break;
case "w":
case "W": throw new RangeError("`w/W` (week) patterns are not supported");
case "d":
result.day = ["numeric", "2-digit"][len - 1];
break;
case "D":
case "F":
case "g": throw new RangeError("`D/F/g` (day) patterns are not supported, use `d` instead");
case "E":
result.weekday = len === 4 ? "long" : len === 5 ? "narrow" : "short";
break;
case "e":
if (len < 4) throw new RangeError("`e..eee` (weekday) patterns are not supported");
result.weekday = [
"short",
"long",
"narrow",
"short"
][len - 3];
break;
case "c":
if (len < 4) throw new RangeError("`c..ccc` (weekday) patterns are not supported");
result.weekday = [
"short",
"long",
"narrow",
"short"
][len - 3];
break;
case "a":
result.hour12 = true;
break;
case "b":
case "B": throw new RangeError("`b/B` (period) patterns are not supported, use `a` instead");
case "h":
result.hourCycle = "h12";
result.hour = ["numeric", "2-digit"][len - 1];
break;
case "H":
result.hourCycle = "h23";
result.hour = ["numeric", "2-digit"][len - 1];
break;
case "K":
result.hourCycle = "h11";
result.hour = ["numeric", "2-digit"][len - 1];
break;
case "k":
result.hourCycle = "h24";
result.hour = ["numeric", "2-digit"][len - 1];
break;
case "j":
case "J":
case "C": throw new RangeError("`j/J/C` (hour) patterns are not supported, use `h/H/K/k` instead");
case "m":
result.minute = ["numeric", "2-digit"][len - 1];
break;
case "s":
result.second = ["numeric", "2-digit"][len - 1];
break;
case "S":
case "A": throw new RangeError("`S/A` (second) patterns are not supported, use `s` instead");
case "z":
result.timeZoneName = len < 4 ? "short" : "long";
break;
case "Z":
case "O":
case "v":
case "V":
case "X":
case "x": throw new RangeError("`Z/O/v/V/X/x` (timeZone) patterns are not supported, use `z` instead");
}
return "";
});
return result;
}
const WHITE_SPACE_REGEX = /[\t-\r \x85\u200E\u200F\u2028\u2029]/i;
function parseNumberSkeletonFromString(skeleton) {
if (skeleton.length === 0) throw new Error("Number skeleton cannot be empty");
const stringTokens = skeleton.split(WHITE_SPACE_REGEX).filter((x) => x.length > 0);
const tokens = [];
for (const stringToken of stringTokens) {
let stemAndOptions = stringToken.split("/");
if (stemAndOptions.length === 0) throw new Error("Invalid number skeleton");
const [stem, ...options] = stemAndOptions;
for (const option of options) if (option.length === 0) throw new Error("Invalid number skeleton");
tokens.push({
stem,
options
});
}
return tokens;
}
function icuUnitToEcma(unit) {
return unit.replace(/^(.*?)-/, "");
}
const FRACTION_PRECISION_REGEX = /^\.(?:(0+)(\*)?|(#+)|(0+)(#+))$/g;
const SIGNIFICANT_PRECISION_REGEX = /^(@+)?(\+|#+)?[rs]?$/g;
const INTEGER_WIDTH_REGEX = /(\*)(0+)|(#+)(0+)|(0+)/g;
const CONCISE_INTEGER_WIDTH_REGEX = /^(0+)$/;
function parseSignificantPrecision(str) {
const result = {};
if (str[str.length - 1] === "r") result.roundingPriority = "morePrecision";
else if (str[str.length - 1] === "s") result.roundingPriority = "lessPrecision";
str.replace(SIGNIFICANT_PRECISION_REGEX, function(_, g1, g2) {
if (typeof g2 !== "string") {
result.minimumSignificantDigits = g1.length;
result.maximumSignificantDigits = g1.length;
} else if (g2 === "+") result.minimumSignificantDigits = g1.length;
else if (g1[0] === "#") result.maximumSignificantDigits = g1.length;
else {
result.minimumSignificantDigits = g1.length;
result.maximumSignificantDigits = g1.length + (typeof g2 === "string" ? g2.length : 0);
}
return "";
});
return result;
}
function parseSign(str) {
switch (str) {
case "sign-auto": return { signDisplay: "auto" };
case "sign-accounting":
case "()": return { currencySign: "accounting" };
case "sign-always":
case "+!": return { signDisplay: "always" };
case "sign-accounting-always":
case "()!": return {
signDisplay: "always",
currencySign: "accounting"
};
case "sign-except-zero":
case "+?": return { signDisplay: "exceptZero" };
case "sign-accounting-except-zero":
case "()?": return {
signDisplay: "exceptZero",
currencySign: "accounting"
};
case "sign-never":
case "+_": return { signDisplay: "never" };
}
}
function parseConciseScientificAndEngineeringStem(stem) {
let result;
if (stem[0] === "E" && stem[1] === "E") {
result = { notation: "engineering" };
stem = stem.slice(2);
} else if (stem[0] === "E") {
result = { notation: "scientific" };
stem = stem.slice(1);
}
if (result) {
const signDisplay = stem.slice(0, 2);
if (signDisplay === "+!") {
result.signDisplay = "always";
stem = stem.slice(2);
} else if (signDisplay === "+?") {
result.signDisplay = "exceptZero";
stem = stem.slice(2);
}
if (!CONCISE_INTEGER_WIDTH_REGEX.test(stem)) throw new Error("Malformed concise eng/scientific notation");
result.minimumIntegerDigits = stem.length;
}
return result;
}
function parseNotationOptions(opt) {
const result = {};
const signOpts = parseSign(opt);
if (signOpts) return signOpts;
return result;
}
/**
* https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#skeleton-stems-and-options
*/
function parseNumberSkeleton(tokens) {
let result = {};
for (const token of tokens) {
switch (token.stem) {
case "percent":
case "%":
result.style = "percent";
continue;
case "%x100":
result.style = "percent";
result.scale = 100;
continue;
case "currency":
result.style = "currency";
result.currency = token.options[0];
continue;
case "group-off":
case ",_":
result.useGrouping = false;
continue;
case "precision-integer":
case ".":
result.maximumFractionDigits = 0;
continue;
case "measure-unit":
case "unit":
result.style = "unit";
result.unit = icuUnitToEcma(token.options[0]);
continue;
case "compact-short":
case "K":
result.notation = "compact";
result.compactDisplay = "short";
continue;
case "compact-long":
case "KK":
result.notation = "compact";
result.compactDisplay = "long";
continue;
case "scientific":
result = {
...result,
notation: "scientific",
...token.options.reduce((all, opt) => ({
...all,
...parseNotationOptions(opt)
}), {})
};
continue;
case "engineering":
result = {
...result,
notation: "engineering",
...token.options.reduce((all, opt) => ({
...all,
...parseNotationOptions(opt)
}), {})
};
continue;
case "notation-simple":
result.notation = "standard";
continue;
case "unit-width-narrow":
result.currencyDisplay = "narrowSymbol";
result.unitDisplay = "narrow";
continue;
case "unit-width-short":
result.currencyDisplay = "code";
result.unitDisplay = "short";
continue;
case "unit-width-full-name":
result.currencyDisplay = "name";
result.unitDisplay = "long";
continue;
case "unit-width-iso-code":
result.currencyDisplay = "symbol";
continue;
case "scale":
result.scale = parseFloat(token.options[0]);
continue;
case "rounding-mode-floor":
result.roundingMode = "floor";
continue;
case "rounding-mode-ceiling":
result.roundingMode = "ceil";
continue;
case "rounding-mode-down":
result.roundingMode = "trunc";
continue;
case "rounding-mode-up":
result.roundingMode = "expand";
continue;
case "rounding-mode-half-even":
result.roundingMode = "halfEven";
continue;
case "rounding-mode-half-down":
result.roundingMode = "halfTrunc";
continue;
case "rounding-mode-half-up":
result.roundingMode = "halfExpand";
continue;
case "integer-width":
if (token.options.length > 1) throw new RangeError("integer-width stems only accept a single optional option");
token.options[0].replace(INTEGER_WIDTH_REGEX, function(_, g1, g2, g3, g4, g5) {
if (g1) result.minimumIntegerDigits = g2.length;
else if (g3 && g4) throw new Error("We currently do not support maximum integer digits");
else if (g5) throw new Error("We currently do not support exact integer digits");
return "";
});
continue;
}
if (CONCISE_INTEGER_WIDTH_REGEX.test(token.stem)) {
result.minimumIntegerDigits = token.stem.length;
continue;
}
if (FRACTION_PRECISION_REGEX.test(token.stem)) {
if (token.options.length > 1) throw new RangeError("Fraction-precision stems only accept a single optional option");
token.stem.replace(FRACTION_PRECISION_REGEX, function(_, g1, g2, g3, g4, g5) {
if (g2 === "*") result.minimumFractionDigits = g1.length;
else if (g3 && g3[0] === "#") result.maximumFractionDigits = g3.length;
else if (g4 && g5) {
result.minimumFractionDigits = g4.length;
result.maximumFractionDigits = g4.length + g5.length;
} else {
result.minimumFractionDigits = g1.length;
result.maximumFractionDigits = g1.length;
}
return "";
});
const opt = token.options[0];
if (opt === "w") result = {
...result,
trailingZeroDisplay: "stripIfInteger"
};
else if (opt) result = {
...result,
...parseSignificantPrecision(opt)
};
continue;
}
if (SIGNIFICANT_PRECISION_REGEX.test(token.stem)) {
result = {
...result,
...parseSignificantPrecision(token.stem)
};
continue;
}
const signOpts = parseSign(token.stem);
if (signOpts) result = {
...result,
...signOpts
};
const conciseScientificAndEngineeringOpts = parseConciseScientificAndEngineeringStem(token.stem);
if (conciseScientificAndEngineeringOpts) result = {
...result,
...conciseScientificAndEngineeringOpts
};
}
return result;
}
//#endregion
//#region node_modules/.aspect_rules_js/@formatjs+icu-messageformat-parser@0.0.0/node_modules/@formatjs/icu-messageformat-parser/index.js
let ErrorKind = /* @__PURE__ */ function(ErrorKind) {
/** Argument is unclosed (e.g. `{0`) */
ErrorKind[ErrorKind["EXPECT_ARGUMENT_CLOSING_BRACE"] = 1] = "EXPECT_ARGUMENT_CLOSING_BRACE";
/** Argument is empty (e.g. `{}`). */
ErrorKind[ErrorKind["EMPTY_ARGUMENT"] = 2] = "EMPTY_ARGUMENT";
/** Argument is malformed (e.g. `{foo!}``) */
ErrorKind[ErrorKind["MALFORMED_ARGUMENT"] = 3] = "MALFORMED_ARGUMENT";
/** Expect an argument type (e.g. `{foo,}`) */
ErrorKind[ErrorKind["EXPECT_ARGUMENT_TYPE"] = 4] = "EXPECT_ARGUMENT_TYPE";
/** Unsupported argument type (e.g. `{foo,foo}`) */
ErrorKind[ErrorKind["INVALID_ARGUMENT_TYPE"] = 5] = "INVALID_ARGUMENT_TYPE";
/** Expect an argument style (e.g. `{foo, number, }`) */
ErrorKind[ErrorKind["EXPECT_ARGUMENT_STYLE"] = 6] = "EXPECT_ARGUMENT_STYLE";
/** The number skeleton is invalid. */
ErrorKind[ErrorKind["INVALID_NUMBER_SKELETON"] = 7] = "INVALID_NUMBER_SKELETON";
/** The date time skeleton is invalid. */
ErrorKind[ErrorKind["INVALID_DATE_TIME_SKELETON"] = 8] = "INVALID_DATE_TIME_SKELETON";
/** Exepct a number skeleton following the `::` (e.g. `{foo, number, ::}`) */
ErrorKind[ErrorKind["EXPECT_NUMBER_SKELETON"] = 9] = "EXPECT_NUMBER_SKELETON";
/** Exepct a date time skeleton following the `::` (e.g. `{foo, date, ::}`) */
ErrorKind[ErrorKind["EXPECT_DATE_TIME_SKELETON"] = 10] = "EXPECT_DATE_TIME_SKELETON";
/** Unmatched apostrophes in the argument style (e.g. `{foo, number, 'test`) */
ErrorKind[ErrorKind["UNCLOSED_QUOTE_IN_ARGUMENT_STYLE"] = 11] = "UNCLOSED_QUOTE_IN_ARGUMENT_STYLE";
/** Missing select argument options (e.g. `{foo, select}`) */
ErrorKind[ErrorKind["EXPECT_SELECT_ARGUMENT_OPTIONS"] = 12] = "EXPECT_SELECT_ARGUMENT_OPTIONS";
/** Expecting an offset value in `plural` or `selectordinal` argument (e.g `{foo, plural, offset}`) */
ErrorKind[ErrorKind["EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE"] = 13] = "EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE";
/** Offset value in `plural` or `selectordinal` is invalid (e.g. `{foo, plural, offset: x}`) */
ErrorKind[ErrorKind["INVALID_PLURAL_ARGUMENT_OFFSET_VALUE"] = 14] = "INVALID_PLURAL_ARGUMENT_OFFSET_VALUE";
/** Expecting a selector in `select` argument (e.g `{foo, select}`) */
ErrorKind[ErrorKind["EXPECT_SELECT_ARGUMENT_SELECTOR"] = 15] = "EXPECT_SELECT_ARGUMENT_SELECTOR";
/** Expecting a selector in `plural` or `selectordinal` argument (e.g `{foo, plural}`) */
ErrorKind[ErrorKind["EXPECT_PLURAL_ARGUMENT_SELECTOR"] = 16] = "EXPECT_PLURAL_ARGUMENT_SELECTOR";
/** Expecting a message fragment after the `select` selector (e.g. `{foo, select, apple}`) */
ErrorKind[ErrorKind["EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT"] = 17] = "EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT";
/**
* Expecting a message fragment after the `plural` or `selectordinal` selector
* (e.g. `{foo, plural, one}`)
*/
ErrorKind[ErrorKind["EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT"] = 18] = "EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT";
/** Selector in `plural` or `selectordinal` is malformed (e.g. `{foo, plural, =x {#}}`) */
ErrorKind[ErrorKind["INVALID_PLURAL_ARGUMENT_SELECTOR"] = 19] = "INVALID_PLURAL_ARGUMENT_SELECTOR";
/**
* Duplicate selectors in `plural` or `selectordinal` argument.
* (e.g. {foo, plural, one {#} one {#}})
*/
ErrorKind[ErrorKind["DUPLICATE_PLURAL_ARGUMENT_SELECTOR"] = 20] = "DUPLICATE_PLURAL_ARGUMENT_SELECTOR";
/** Duplicate selectors in `select` argument.
* (e.g. {foo, select, apple {apple} apple {apple}})
*/
ErrorKind[ErrorKind["DUPLICATE_SELECT_ARGUMENT_SELECTOR"] = 21] = "DUPLICATE_SELECT_ARGUMENT_SELECTOR";
/** Plural or select argument option must have `other` clause. */
ErrorKind[ErrorKind["MISSING_OTHER_CLAUSE"] = 22] = "MISSING_OTHER_CLAUSE";
/** The tag is malformed. (e.g. `<bold!>foo</bold!>) */
ErrorKind[ErrorKind["INVALID_TAG"] = 23] = "INVALID_TAG";
/** The tag name is invalid. (e.g. `<123>foo</123>`) */
ErrorKind[ErrorKind["INVALID_TAG_NAME"] = 25] = "INVALID_TAG_NAME";
/** The closing tag does not match the opening tag. (e.g. `<bold>foo</italic>`) */
ErrorKind[ErrorKind["UNMATCHED_CLOSING_TAG"] = 26] = "UNMATCHED_CLOSING_TAG";
/** The opening tag has unmatched closing tag. (e.g. `<bold>foo`) */
ErrorKind[ErrorKind["UNCLOSED_TAG"] = 27] = "UNCLOSED_TAG";
return ErrorKind;
}({});
let TYPE = /* @__PURE__ */ function(TYPE) {
/**
* Raw text
*/
TYPE[TYPE["literal"] = 0] = "literal";
/**
* Variable w/o any format, e.g `var` in `this is a {var}`
*/
TYPE[TYPE["argument"] = 1] = "argument";
/**
* Variable w/ number format
*/
TYPE[TYPE["number"] = 2] = "number";
/**
* Variable w/ date format
*/
TYPE[TYPE["date"] = 3] = "date";
/**
* Variable w/ time format
*/
TYPE[TYPE["time"] = 4] = "time";
/**
* Variable w/ select format
*/
TYPE[TYPE["select"] = 5] = "select";
/**
* Variable w/ plural format
*/
TYPE[TYPE["plural"] = 6] = "plural";
/**
* Only possible within plural argument.
* This is the `#` symbol that will be substituted with the count.
*/
TYPE[TYPE["pound"] = 7] = "pound";
/**
* XML-like tag
*/
TYPE[TYPE["tag"] = 8] = "tag";
return TYPE;
}({});
/**
* Type Guards
*/
function isLiteralElement(el) {
return el.type === 0;
}
function isArgumentElement(el) {
return el.type === 1;
}
function isNumberElement(el) {
return el.type === 2;
}
function isDateElement(el) {
return el.type === 3;
}
function isTimeElement(el) {
return el.type === 4;
}
function isSelectElement(el) {
return el.type === 5;
}
function isPluralElement(el) {
return el.type === 6;
}
function isPoundElement(el) {
return el.type === 7;
}
function isTagElement(el) {
return el.type === 8;
}
function isNumberSkeleton(el) {
return !!(el && typeof el === "object" && el.type === 0);
}
function isDateTimeSkeleton(el) {
return !!(el && typeof el === "object" && el.type === 1);
}
const SPACE_SEPARATOR_REGEX = /[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/;
const timeData = {
"001": ["H", "h"],
"419": [
"h",
"H",
"hB",
"hb"
],
"AC": [
"H",
"h",
"hb",
"hB"
],
"AD": ["H", "hB"],
"AE": [
"h",
"hB",
"hb",
"H"
],
"AF": [
"H",
"hb",
"hB",
"h"
],
"AG": [
"h",
"hb",
"H",
"hB"
],
"AI": [
"H",
"h",
"hb",
"hB"
],
"AL": [
"h",
"H",
"hB"
],
"AM": ["H", "hB"],
"AO": ["H", "hB"],
"AR": [
"h",
"H",
"hB",
"hb"
],
"AS": ["h", "H"],
"AT": ["H", "hB"],
"AU": [
"h",
"hb",
"H",
"hB"
],
"AW": ["H", "hB"],
"AX": ["H"],
"AZ": [
"H",
"hB",
"h"
],
"BA": [
"H",
"hB",
"h"
],
"BB": [
"h",
"hb",
"H",
"hB"
],
"BD": [
"h",
"hB",
"H"
],
"BE": ["H", "hB"],
"BF": ["H", "hB"],
"BG": [
"H",
"hB",
"h"
],
"BH": [
"h",
"hB",
"hb",
"H"
],
"BI": ["H", "h"],
"BJ": ["H", "hB"],
"BL": ["H", "hB"],
"BM": [
"h",
"hb",
"H",
"hB"
],
"BN": [
"hb",
"hB",
"h",
"H"
],
"BO": [
"h",
"H",
"hB",
"hb"
],
"BQ": ["H"],
"BR": ["H", "hB"],
"BS": [
"h",
"hb",
"H",
"hB"
],
"BT": ["h", "H"],
"BW": [
"H",
"h",
"hb",
"hB"
],
"BY": ["H", "h"],
"BZ": [
"H",
"h",
"hb",
"hB"
],
"CA": [
"h",
"hb",
"H",
"hB"
],
"CC": [
"H",
"h",
"hb",
"hB"
],
"CD": ["hB", "H"],
"CF": [
"H",
"h",
"hB"
],
"CG": ["H", "hB"],
"CH": [
"H",
"hB",
"h"
],
"CI": ["H", "hB"],
"CK": [
"H",
"h",
"hb",
"hB"
],
"CL": [
"h",
"H",
"hB",
"hb"
],
"CM": [
"H",
"h",
"hB"
],
"CN": [
"H",
"hB",
"hb",
"h"
],
"CO": [
"h",
"H",
"hB",
"hb"
],
"CP": ["H"],
"CR": [
"h",
"H",
"hB",
"hb"
],
"CU": [
"h",
"H",
"hB",
"hb"
],
"CV": ["H", "hB"],
"CW": ["H", "hB"],
"CX": [
"H",
"h",
"hb",
"hB"
],
"CY": [
"h",
"H",
"hb",
"hB"
],
"CZ": ["H"],
"DE": ["H", "hB"],
"DG": [
"H",
"h",
"hb",
"hB"
],
"DJ": ["h", "H"],
"DK": ["H"],
"DM": [
"h",
"hb",
"H",
"hB"
],
"DO": [
"h",
"H",
"hB",
"hb"
],
"DZ": [
"h",
"hB",
"hb",
"H"
],
"EA": [
"H",
"h",
"hB",
"hb"
],
"EC": [
"h",
"H",
"hB",
"hb"
],
"EE": ["H", "hB"],
"EG": [
"h",
"hB",
"hb",
"H"
],
"EH": [
"h",
"hB",
"hb",
"H"
],
"ER": ["h", "H"],
"ES": [
"H",
"hB",
"h",
"hb"
],
"ET": [
"hB",
"hb",
"h",
"H"
],
"FI": ["H"],
"FJ": [
"h",
"hb",
"H",
"hB"
],
"FK": [
"H",
"h",
"hb",
"hB"
],
"FM": [
"h",
"hb",
"H",
"hB"
],
"FO": ["H", "h"],
"FR": ["H", "hB"],
"GA": ["H", "hB"],
"GB": [
"H",
"h",
"hb",
"hB"
],
"GD": [
"h",
"hb",
"H",
"hB"
],
"GE": [
"H",
"hB",
"h"
],
"GF": ["H", "hB"],
"GG": [
"H",
"h",
"hb",
"hB"
],
"GH": ["h", "H"],
"GI": [
"H",
"h",
"hb",
"hB"
],
"GL": ["H", "h"],
"GM": [
"h",
"hb",
"H",
"hB"
],
"GN": ["H", "hB"],
"GP": ["H", "hB"],
"GQ": [
"H",
"hB",
"h",
"hb"
],
"GR": [
"h",
"H",
"hb",
"hB"
],
"GS": [
"H",
"h",
"hb",
"hB"
],
"GT": [
"h",
"H",
"hB",
"hb"
],
"GU": [
"h",
"hb",
"H",
"hB"
],
"GW": ["H", "hB"],
"GY": [
"h",
"hb",
"H",
"hB"
],
"HK": [
"h",
"hB",
"hb",
"H"
],
"HN": [
"h",
"H",
"hB",
"hb"
],
"HR": ["H", "hB"],
"HU": ["H", "h"],
"IC": [
"H",
"h",
"hB",
"hb"
],
"ID": ["H"],
"IE": [
"H",
"h",
"hb",
"hB"
],
"IL": ["H", "hB"],
"IM": [
"H",
"h",
"hb",
"hB"
],
"IN": ["h", "H"],
"IO": [
"H",
"h",
"hb",
"hB"
],
"IQ": [
"h",
"hB",
"hb",
"H"
],
"IR": ["hB", "H"],
"IS": ["H"],
"IT": ["H", "hB"],
"JE": [
"H",
"h",
"hb",
"hB"
],
"JM": [
"h",
"hb",
"H",
"hB"
],
"JO": [
"h",
"hB",
"hb",
"H"
],
"JP": [
"H",
"K",
"h"
],
"KE": [
"hB",
"hb",
"H",
"h"
],
"KG": [
"H",
"h",
"hB",
"hb"
],
"KH": [
"hB",
"h",
"H",
"hb"
],
"KI": [
"h",
"hb",
"H",
"hB"
],
"KM": [
"H",
"h",
"hB",
"hb"
],
"KN": [
"h",
"hb",
"H",
"hB"
],
"KP": [
"h",
"H",
"hB",
"hb"
],
"KR": [
"h",
"H",
"hB",
"hb"
],
"KW": [
"h",
"hB",
"hb",
"H"
],
"KY": [
"h",
"hb",
"H",
"hB"
],
"KZ": ["H", "hB"],
"LA": [
"H",
"hb",
"hB",
"h"
],
"LB": [
"h",
"hB",
"hb",
"H"
],
"LC": [
"h",
"hb",
"H",
"hB"
],
"LI": [
"H",
"hB",
"h"
],
"LK": [
"H",
"h",
"hB",
"hb"
],
"LR": [
"h",
"hb",
"H",
"hB"
],
"LS": ["h", "H"],
"LT": [
"H",
"h",
"hb",
"hB"
],
"LU": [
"H",
"h",
"hB"
],
"LV": [
"H",
"hB",
"hb",
"h"
],
"LY": [
"h",
"hB",
"hb",
"H"
],
"MA": [
"H",
"h",
"hB",
"hb"
],
"MC": ["H", "hB"],
"MD": ["H", "hB"],
"ME": [
"H",
"hB",
"h"
],
"MF": ["H", "hB"],
"MG": ["H", "h"],
"MH": [
"h",
"hb",
"H",
"hB"
],
"MK": [
"H",
"h",
"hb",
"hB"
],
"ML": ["H"],
"MM": [
"hB",
"hb",
"H",
"h"
],
"MN": [
"H",
"h",
"hb",
"hB"
],
"MO": [
"h",
"hB",
"hb",
"H"
],
"MP": [
"h",
"hb",
"H",
"hB"
],
"MQ": ["H", "hB"],
"MR": [
"h",
"hB",
"hb",
"H"
],
"MS": [
"H",
"h",
"hb",
"hB"
],
"MT": ["H", "h"],
"MU": ["H", "h"],
"MV": ["H", "h"],
"MW": [
"h",
"hb",
"H",
"hB"
],
"MX": [
"h",
"H",
"hB",
"hb"
],
"MY": [
"hb",
"hB",
"h",
"H"
],
"MZ": ["H", "hB"],
"NA": [
"h",
"H",
"hB",
"hb"
],
"NC": ["H", "hB"],
"NE": ["H"],
"NF": [
"H",
"h",
"hb",
"hB"
],
"NG": [
"H",
"h",
"hb",
"hB"
],
"NI": [
"h",
"H",
"hB",
"hb"
],
"NL": ["H", "hB"],
"NO": ["H", "h"],
"NP": [
"H",
"h",
"hB"
],
"NR": [
"H",
"h",
"hb",
"hB"
],
"NU": [
"H",
"h",
"hb",
"hB"
],
"NZ": [
"h",
"hb",
"H",
"hB"
],
"OM": [
"h",
"hB",
"hb",
"H"
],
"PA": [
"h",
"H",
"hB",
"hb"
],
"PE": [
"h",
"H",
"hB",
"hb"
],
"PF": [
"H",
"h",
"hB"
],
"PG": ["h", "H"],
"PH": [
"h",
"hB",
"hb",
"H"
],
"PK": [
"h",
"hB",
"H"
],
"PL": ["H", "h"],
"PM": ["H", "hB"],
"PN": [
"H",
"h",
"hb",
"hB"
],
"PR": [
"h",
"H",
"hB",
"hb"
],
"PS": [
"h",
"hB",
"hb",
"H"
],
"PT": ["H", "hB"],
"PW": ["h", "H"],
"PY": [
"h",
"H",
"hB",
"hb"
],
"QA": [
"h",
"hB",
"hb",
"H"
],
"RE": ["H", "hB"],
"RO": ["H", "hB"],
"RS": [
"H",
"hB",
"h"
],
"RU": ["H"],
"RW": ["H", "h"],
"SA": [
"h",
"hB",
"hb",
"H"
],
"SB": [
"h",
"hb",
"H",
"hB"
],
"SC": [
"H",
"h",
"hB"
],
"SD": [
"h",
"hB",
"hb",
"H"
],
"SE": ["H"],
"SG": [
"h",
"hb",
"H",
"hB"
],
"SH": [
"H",
"h",
"hb",
"hB"
],
"SI": ["H", "hB"],
"SJ": ["H"],
"SK": ["H"],
"SL": [
"h",
"hb",
"H",
"hB"
],
"SM": [
"H",
"h",
"hB"
],
"SN": [
"H",
"h",
"hB"
],
"SO": ["h", "H"],
"SR": ["H", "hB"],
"SS": [
"h",
"hb",
"H",
"hB"
],
"ST": ["H", "hB"],
"SV": [
"h",
"H",
"hB",
"hb"
],
"SX": [
"H",
"h",
"hb",
"hB"
],
"SY": [
"h",
"hB",
"hb",
"H"
],
"SZ": [
"h",
"hb",
"H",
"hB"
],
"TA": [
"H",
"h",
"hb",
"hB"
],
"TC": [
"h",
"hb",
"H",
"hB"
],
"TD": [
"h",
"H",
"hB"
],
"TF": [
"H",
"h",
"hB"
],
"TG": ["H", "hB"],
"TH": ["H", "h"],
"TJ": ["H", "h"],
"TL": [
"H",
"hB",
"hb",
"h"
],
"TM": ["H", "h"],
"TN": [
"h",
"hB",
"hb",
"H"
],
"TO": ["h", "H"],
"TR": ["H", "hB"],
"TT": [
"h",
"hb",
"H",
"hB"
],
"TW": [
"hB",
"hb",
"h",
"H"
],
"TZ": [
"hB",
"hb",
"H",
"h"
],
"UA": [
"H",
"hB",
"h"
],
"UG": [
"hB",
"hb",
"H",
"h"
],
"UM": [
"h",
"hb",
"H",
"hB"
],
"US": [
"h",
"hb",
"H",
"hB"
],
"UY": [
"h",
"H",
"hB",
"hb"
],
"UZ": [
"H",
"hB",
"h"
],
"VA": [
"H",
"h",
"hB"
],
"VC": [
"h",
"hb",
"H",
"hB"
],
"VE": [
"h",
"H",
"hB",
"hb"
],
"VG": [
"h",
"hb",
"H",
"hB"
],
"VI": [
"h",
"hb",
"H",
"hB"
],
"VN": ["H", "h"],
"VU": ["h", "H"],
"WF": ["H", "hB"],
"WS": ["h", "H"],
"XK": [
"H",
"hB",
"h"
],
"YE": [
"h",
"hB",
"hb",
"H"
],
"YT": ["H", "hB"],
"ZA": [
"H",
"h",
"hb",
"hB"
],
"ZM": [
"h",
"hb",
"H",
"hB"
],
"ZW": ["H", "h"],
"af-ZA": [
"H",
"h",
"hB",
"hb"
],
"ar-001": [
"h",
"hB",
"hb",
"H"
],
"ca-ES": [
"H",
"h",
"hB"
],
"en-001": [
"h",
"hb",
"H",
"hB"
],
"en-HK": [
"h",
"hb",
"H",
"hB"
],
"en-IL": [
"H",
"h",
"hb",
"hB"
],
"en-MY": [
"h",
"hb",
"H",
"hB"
],
"es-BR": [
"H",
"h",
"hB",
"hb"
],
"es-ES": [
"H",
"h",
"hB",
"hb"
],
"es-GQ": [
"H",
"h",
"hB",
"hb"
],
"fr-CA": [
"H",
"h",
"hB"
],
"gl-ES": [
"H",
"h",
"hB"
],
"gu-IN": [
"hB",
"hb",
"h",
"H"
],
"hi-IN": [
"hB",
"h",
"H"
],
"it-CH": [
"H",
"h",
"hB"
],
"it-IT": [
"H",
"h",
"hB"
],
"kn-IN": [
"hB",
"h",
"H"
],
"ku-SY": ["H", "hB"],
"ml-IN": [
"hB",
"h",
"H"
],
"mr-IN": [
"hB",
"hb",
"h",
"H"
],
"pa-IN": [
"hB",
"hb",
"h",
"H"
],
"ta-IN": [
"hB",
"h",
"hb",
"H"
],
"te-IN": [
"hB",
"h",
"H"
],
"zu-ZA": [
"H",
"hB",
"hb",
"h"
]
};
/**
* Returns the best matching date time pattern if a date time skeleton
* pattern is provided with a locale. Follows the Unicode specification:
* https://www.unicode.org/reports/tr35/tr35-dates.html#table-mapping-requested-time-skeletons-to-patterns
* @param skeleton date time skeleton pattern that possibly includes j, J or C
* @param locale
*/
function getBestPattern(skeleton, locale) {
let skeletonCopy = "";
for (let patternPos = 0; patternPos < skeleton.length; patternPos++) {
const patternChar = skeleton.charAt(patternPos);
if (patternChar === "j") {
let extraLength = 0;
while (patternPos + 1 < skeleton.length && skeleton.charAt(patternPos + 1) === patternChar) {
extraLength++;
patternPos++;
}
let hourLen = 1 + (extraLength & 1);
let dayPeriodLen = extraLength < 2 ? 1 : 3 + (extraLength >> 1);
let dayPeriodChar = "a";
let hourChar = getDefaultHourSymbolFromLocale(locale);
if (hourChar == "H" || hourChar == "k") dayPeriodLen = 0;
while (dayPeriodLen-- > 0) skeletonCopy += dayPeriodChar;
while (hourLen-- > 0) skeletonCopy = hourChar + skeletonCopy;
} else if (patternChar === "J") skeletonCopy += "H";
else skeletonCopy += patternChar;
}
return skeletonCopy;
}
/**
* Maps the [hour cycle type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/hourCycle)
* of the given `locale` to the corresponding time pattern.
* @param locale
*/
function getDefaultHourSymbolFromLocale(locale) {
let hourCycle = locale.hourCycle;
if (hourCycle === void 0 && locale.hourCycles && locale.hourCycles.length) hourCycle = locale.hourCycles[0];
if (hourCycle) switch (hourCycle) {
case "h24": return "k";
case "h23": return "H";
case "h12": return "h";
case "h11": return "K";
default: throw new Error("Invalid hourCycle");
}
const languageTag = locale.language;
let regionTag;
if (languageTag !== "root") regionTag = locale.maximize().region;
return (timeData[regionTag || ""] || timeData[languageTag || ""] || timeData[`${languageTag}-001`] || timeData["001"])[0];
}
const SPACE_SEPARATOR_START_REGEX = new RegExp(`^${SPACE_SEPARATOR_REGEX.source}*`);
const SPACE_SEPARATOR_END_REGEX = new RegExp(`${SPACE_SEPARATOR_REGEX.source}*$`);
function createLocation(start, end) {
return {
start,
end
};
}
const hasNativeFromEntries = !!Object.fromEntries;
const hasTrimStart = !!String.prototype.trimStart;
const hasTrimEnd = !!String.prototype.trimEnd;
const fromEntries = hasNativeFromEntries ? Object.fromEntries : function fromEntries(entries) {
const obj = {};
for (const [k, v] of entries) obj[k] = v;
return obj;
};
const trimStart = hasTrimStart ? function trimStart(s) {
return s.trimStart();
} : function trimStart(s) {
return s.replace(SPACE_SEPARATOR_START_REGEX, "");
};
const trimEnd = hasTrimEnd ? function trimEnd(s) {
return s.trimEnd();
} : function trimEnd(s) {
return s.replace(SPACE_SEPARATOR_END_REGEX, "");
};
const IDENTIFIER_PREFIX_RE = new RegExp("([^\\p{White_Space}\\p{Pattern_Syntax}]*)", "yu");
function matchIdentifierAtIndex(s, index) {
IDENTIFIER_PREFIX_RE.lastIndex = index;
return IDENTIFIER_PREFIX_RE.exec(s)[1] ?? "";
}
function plainTopLevelEndPosition(message) {
if (message.length === 0) return null;
let line = 1;
let column = 1;
for (let offset = 0; offset < message.length;) {
const code = message.charCodeAt(offset);
switch (code) {
case 35:
case 39:
case 60:
case 123:
case 125: return null;
}
if (code === 10) {
line++;
column = 1;
offset++;
} else {
column++;
if (code >= 55296 && code <= 56319 && offset + 1 < message.length) {
const next = message.charCodeAt(offset + 1);
offset += next >= 56320 && next <= 57343 ? 2 : 1;
} else offset++;
}
}
return {
offset: message.length,
line,
column
};
}
var Parser = class {
constructor(message, options = {}) {
this.message = message;
this.position = {
offset: 0,
line: 1,
column: 1
};
this.ignoreTag = !!options.ignoreTag;
this.locale = options.locale;
this.requiresOtherClause = !!options.requiresOtherClause;
this.shouldParseSkeletons = !!options.shouldParseSkeletons;
}
parse() {
if (this.offset() !== 0) throw Error("parser can only be used once");
if (this.message.length > 0) {
const firstCode = this.message.charCodeAt(0);
if (firstCode !== 35 && firstCode !== 39 && firstCode !== 60 && firstCode !== 123 && firstCode !== 125) {
const plainEndPosition = plainTopLevelEndPosition(this.message);
if (plainEndPosition) {
const start = this.clonePosition();
this.position = plainEndPosition;
return {
val: [{
type: 0,
value: this.message,
location: createLocation(start, this.clonePosition())
}],
err: null
};
}
}
}
return this.parseMessage(0, "", false);
}
parseMessage(nestingLevel, parentArgType, expectingCloseTag) {
let elements = [];
while (!this.isEOF()) {
const char = this.char();
if (char === 123) {
const result = this.parseArgument(nestingLevel, expectingCloseTag);
if (result.err) return result;
elements.push(result.val);
} else if (char === 125 && nestingLevel > 0) break;
else if (char === 35 && (parentArgType === "plural" || parentArgType === "selectordinal")) {
const position = this.clonePosition();
this.bump();
elements.push({
type: 7,
location: createLocation(position, this.clonePosition())
});
} else if (char === 60 && !this.ignoreTag && this.peek() === 47) {
if (expectingCloseTag) break;
else return this.error(26, createLocation(this.clonePosition(), this.clonePosition()));
} else if (char === 60 && !this.ignoreTag && _isAlpha(this.peek() || 0)) {
const result = this.parseTag(nestingLevel, parentArgType);
if (result.err) return result;
elements.push(result.val);
} else {
const result = this.parseLiteral(nestingLevel, parentArgType);
if (result.err) return result;
elements.push(result.val);
}
}
return {
val: elements,
err: null
};
}
/**
* A tag name must start with an ASCII lower/upper case letter. The grammar is based on the
* [custom element name][] except that a dash is NOT always mandatory and uppercase letters
* are accepted:
*
* ```
* tag ::= "<" tagName (whitespace)* "/>" | "<" tagName (whitespace)* ">" message "</" tagName (whitespace)* ">"
* tagName ::= [a-z] (PENChar)*
* PENChar ::=
* "-" | "." | [0-9] | "_" | [a-z] | [A-Z] | #xB7 | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x37D] |
* [#x37F-#x1FFF] | [#x200C-#x200D] | [#x203F-#x2040] | [#x2070-#x218F] | [#x2C00-#x2FEF] |
* [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
* ```
*
* [custom element name]: https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
* NOTE: We're a bit more lax here since HTML technically does not allow uppercase HTML element but we do
* since other tag-based engines like React allow it
*/
parseTag(nestingLevel, parentArgType) {
const startPosition = this.clonePosition();
this.bump();
const tagName = this.parseTagName();
this.bumpSpace();
if (this.bumpIf("/>")) return {
val: {
type: 0,
value: `<${tagName}/>`,
location: createLocation(startPosition, this.clonePosition())
},
err: null
};
else if (this.bumpIf(">")) {
const childrenResult = this.parseMessage(nestingLevel + 1, parentArgType, true);
if (childrenResult.err) return childrenResult;
const children = childrenResult.val;
const endTagStartPosition = this.clonePosition();
if (this.bumpIf("</")) {
if (this.isEOF() || !_isAlpha(this.char())) return this.error(23, createLocation(endTagStartPosition, this.clonePosition()));
const closingTagNameStartPosition = this.clonePosition();
if (tagName !== this.parseTagName()) return this.error(26, createLocation(closingTagNameStartPosition, this.clonePosition()));
this.bumpSpace();
if (!this.bumpIf(">")) return this.error(23, createLocation(endTagStartPosition, this.clonePosition()));
return {
val: {
type: 8,
value: tagName,
children,
location: createLocation(startPosition, this.clonePosition())
},
err: null
};
} else return this.error(27, createLocation(startPosition, this.clonePosition()));
} else return this.error(23, createLocation(startPosition, this.clonePosition()));
}
/**
* This method assumes that the caller has peeked ahead for the first tag character.
*/
parseTagName() {
const startOffset = this.offset();
this.bump();
while (!this.isEOF() && _isPotentialElementNameChar(this.char())) this.bump();
return this.message.slice(startOffset, this.offset());
}
parseLiteral(nestingLevel, parentArgType) {
const start = this.clonePosition();
let value = "";
while (true) {
const parseQuoteResult = this.tryParseQuote(parentArgType);
if (parseQuoteResult) {
value += parseQuoteResult;
continue;
}
const parseUnquotedResult = this.tryParseUnquoted(nestingLevel, parentArgType);
if (parseUnquotedResult) {
value += parseUnquotedResult;
continue;
}
const parseLeftAngleResult = this.tryParseLeftAngleBracket();
if (parseLeftAngleResult) {
value += parseLeftAngleResult;
continue;
}
break;
}
const location = createLocation(start, this.clonePosition());
return {
val: {
type: 0,
value,
location
},
err: null
};
}
tryParseLeftAngleBracket() {
if (!this.isEOF() && this.char() === 60 && (this.ignoreTag || !_isAlphaOrSlash(this.peek() || 0))) {
this.bump();
return "<";
}
return null;
}
/**
* Starting with ICU 4.8, an ASCII apostrophe only starts quoted text if it immediately precedes
* a character that requires quoting (that is, "only where needed"), and works the same in
* nested messages as on the top level of the pattern. The new behavior is otherwise compatible.
*/
tryParseQuote(parentArgType) {
if (this.isEOF() || this.char() !== 39) return null;
switch (this.peek()) {
case 39:
this.bump();
this.bump();
return "'";
case 123:
case 60:
case 62:
case 125: break;
case 35:
if (parentArgType === "plural" || parentArgType === "selectordinal") break;
return null;
default: return null;
}
this.bump();
const codePoints = [this.char()];
this.bump();
while (!this.isEOF()) {
const ch = this.char();
if (ch === 39) {
if (this.peek() === 39) {
codePoints.push(39);
this.bump();
} else {
this.bump();
break;
}
} else codePoints.push(ch);
this.bump();
}
return String.fromCodePoint(...codePoints);
}
tryParseUnquoted(nestingLevel, parentArgType) {
if (this.isEOF()) return null;
const ch = this.char();
if (ch === 60 || ch === 123 || ch === 35 && (parentArgType === "plural" || parentArgType === "selectordinal") || ch === 125 && nestingLevel > 0) return null;
else {
this.bump();
return String.fromCodePoint(ch);
}
}
parseArgument(nestingLevel, expectingCloseTag) {
const openingBracePosition = this.clonePosition();
this.bump();
this.bumpSpace();
if (this.isEOF()) return this.error(1, createLocation(openingBracePosition, this.clonePosition()));
if (this.char() === 125) {
this.bump();
return this.error(2, createLocation(openingBracePosition, this.clonePosition()));
}
let value = this.parseIdentifierIfPossible().value;
if (!value) return this.error(3, createLocation(openingBracePosition, this.clonePosition()));
this.bumpSpace();
if (this.isEOF()) return this.error(1, createLocation(openingBracePosition, this.clonePosition()));
switch (this.char()) {
case 125:
this.bump();
return {
val: {
type: 1,
value,
location: createLocation(openingBracePosition, this.clonePosition())
},
err: null
};
case 44:
this.bump();
this.bumpSpace();
if (this.isEOF()) return this.error(1, createLocation(openingBracePosition, this.clonePosition()));
return this.parseArgumentOptions(nestingLevel, expectingCloseTag, value, openingBracePosition);
default: return this.error(3, createLocation(openingBracePosition, this.clonePosition()));
}
}
/**
* Advance the parser until the end of the identifier, if it is currently on
* an identifier character. Return an empty string otherwise.
*/
parseIdentifierIfPossible() {
const startingPosition = this.clonePosition();
const startOffset = this.offset();
const value = matchIdentifierAtIndex(this.message, startOffset);
const endOffset = startOffset + value.length;
this.bumpTo(endOffset);
return {
value,
location: createLocation(startingPosition, this.clonePosition())
};
}
parseArgumentOptions(nestingLevel, expectingCloseTag, value, openingBracePosition) {
let typeStartPosition = this.clonePosition();
let argType = this.parseIdentifierIfPossible().value;
let typeEndPosition = this.clonePosition();
switch (argType) {
case "": return this.error(4, createLocation(typeStartPosition, typeEndPosition));
case "number":
case "date":
case "time": {
this.bumpSpace();
let styleAndLocation = null;
if (this.bumpIf(",")) {
this.bumpSpace();
const styleStartPosition = this.clonePosition();
const result = this.parseSimpleArgStyleIfPossible();
if (result.err) return result;
const style = trimEnd(result.val);
if (style.length === 0) return this.error(6, createLocation(this.clonePosition(), this.clonePosition()));
styleAndLocation = {
style,
styleLocation: createLocation(styleStartPosition, this.clonePosition())
};
}
const argCloseResult = this.tryParseArgumentClose(openingBracePosition);
if (argCloseResult.err) return argCloseResult;
const location = createLocation(openingBracePosition, this.clonePosition());
if (styleAndLocation && styleAndLocation.style.startsWith("::")) {
let skeleton = trimStart(styleAndLocation.style.slice(2));
if (argType === "number") {
const result = this.parseNumberSkeletonFromString(skeleton, styleAndLocation.styleLocation);
if (result.err) return result;
return {
val: {
type: 2,
value,
location,
style: result.val
},
err: null
};
} else {
if (skeleton.length === 0) return this.error(10, location);
let dateTimePattern = skeleton;
if (this.locale) dateTimePattern = getBestPattern(skeleton, this.locale);
const style = {
type: 1,
pattern: dateTimePattern,
location: styleAndLocation.styleLocation,
parsedOptions: this.shouldParseSkeletons ? parseDateTimeSkeleton(dateTimePattern) : {}
};
return {
val: {
type: argType === "date" ? 3 : 4,
value,
location,
style
},
err: null
};
}
}
return {
val: {
type: argType === "number" ? 2 : argType === "date" ? 3 : 4,
value,
location,
style: styleAndLocation?.style ?? null
},
err: null
};
}
case "plural":
case "selectordinal":
case "select": {
const typeEndPosition = this.clonePosition();
this.bumpSpace();
if (!this.bumpIf(",")) return this.error(12, createLocation(typeEndPosition, { ...typeEndPosition }));
this.bumpSpace();
let identifierAndLocation = this.parseIdentifierIfPossible();
let pluralOffset = 0;
if (argType !== "select" && identifierAndLocation.value === "offset") {
if (!this.bumpIf(":")) return this.error(13, createLocation(this.clonePosition(), this.clonePosition()));
this.bumpSpace();
const result = this.tryParseDecimalInteger(13, 14);
if (result.err) return result;
this.bumpSpace();
identifierAndLocation = this.parseIdentifierIfPossible();
pluralOffset = result.val;
}
const optionsResult = this.tryParsePluralOrSelectOptions(nestingLevel, argType, expectingCloseTag, identifierAndLocation);
if (optionsResult.err) return optionsResult;
const argCloseResult = this.tryParseArgumentClose(openingBracePosition);
if (argCloseResult.err) return argCloseResult;
const location = createLocation(openingBracePosition, this.clonePosition());
if (argType === "select") return {
val: {
type: 5,
value,
options: fromEntries(optionsResult.val),
location
},
err: null
};
else return {
val: {
type: 6,
value,
options: fromEntries(optionsResult.val),
offset: pluralOffset,
pluralType: argType === "plural" ? "cardinal" : "ordinal",
location
},
err: null
};
}
default: return this.error(5, createLocation(typeStartPosition, typeEndPosition));
}
}
tryParseArgumentClose(openingBracePosition) {
if (this.isEOF() || this.char() !== 125) return this.error(1, createLocation(openingBracePosition, this.clonePosition()));
this.bump();
return {
val: true,
err: null
};
}
/**
* See: https://github.com/unicode-org/icu/blob/af7ed1f6d2298013dc303628438ec4abe1f16479/icu4c/source/common/messagepattern.cpp#L659
*/
parseSimpleArgStyleIfPossible() {
let nestedBraces = 0;
const startPosition = this.clonePosition();
while (!this.isEOF()) switch (this.char()) {
case 39: {
this.bump();
let apostrophePosition = this.clonePosition();
if (!this.bumpUntil("'")) return this.error(11, createLocation(apostrophePosition, this.clonePosition()));
this.bump();
break;
}
case 123:
nestedBraces += 1;
this.bump();
break;
case 125:
if (nestedBraces > 0) nestedBraces -= 1;
else return {
val: this.message.slice(startPosition.offset, this.offset()),
err: null
};
break;
default: this.bump();
}
return {
val: this.message.slice(startPosition.offset, this.offset()),
err: null
};
}
parseNumberSkeletonFromString(skeleton, location) {
let tokens = [];
try {
tokens = parseNumberSkeletonFromString(skeleton);
} catch {
return this.error(7, location);
}
return {
val: {
type: 0,
tokens,
location,
parsedOptions: this.shouldParseSkeletons ? parseNumberSkeleton(tokens) : {}
},
err: null
};
}
/**
* @param nesting_level The current nesting level of messages.
* This can be positive when parsing message fragment in select or plural argument options.
* @param parent_arg_type The parent argument's type.
* @param parsed_first_identifier If provided, this is the first identifier-like selector of
* the argument. It is a by-product of a previous parsing attempt.
* @param expecting_close_tag If true, this message is directly or indirectly nested inside
* between a pair of opening and closing tags. The nested message will not parse beyond
* the closing tag boundary.
*/
tryParsePluralOrSelectOptions(nestingLevel, parentArgType, expectCloseTag, parsedFirstIdentifier) {
let hasOtherClause = false;
const options = [];
const parsedSelectors = /* @__PURE__ */ new Set();
let { value: selector, location: selectorLocation } = parsedFirstIdentifier;
while (true) {
if (selector.length === 0) {
const startPosition = this.clonePosition();
if (parentArgType !== "select" && this.bumpIf("=")) {
const result = this.tryParseDecimalInteger(16, 19);
if (result.err) return result;
selectorLocation = createLocation(startPosition, this.clonePosition());
selector = this.message.slice(startPosition.offset, this.offset());
} else break;
}
if (parsedSelectors.has(selector)) return this.error(parentArgType === "select" ? 21 : 20, selectorLocation);
if (selector === "other") hasOtherClause = true;
this.bumpSpace();
const openingBracePosition = this.clonePosition();
if (!this.bumpIf("{")) return this.error(parentArgType === "select" ? 17 : 18, createLocation(this.clonePosition(), this.clonePosition()));
const fragmentResult = this.parseMessage(nestingLevel + 1, parentArgType, expectCloseTag);
if (fragmentResult.err) return fragmentResult;
const argCloseResult = this.tryParseArgumentClose(openingBracePosition);
if (argCloseResult.err) return argCloseResult;
options.push([selector, {
value: fragmentResult.val,
location: createLocation(openingBracePosition, this.clonePosition())
}]);
parsedSelectors.add(selector);
this.bumpSpace();
({value: selector, location: selectorLocation} = this.parseIdentifierIfPossible());
}
if (options.length === 0) return this.error(parentArgType === "select" ? 15 : 16, createLocation(this.clonePosition(), this.clonePosition()));
if (this.requiresOtherClause && !hasOtherClause) return this.error(22, createLocation(this.clonePosition(), this.clonePosition()));
return {
val: options,
err: null
};
}
tryParseDecimalInteger(expectNumberError, invalidNumberError) {
let sign = 1;
const startingPosition = this.clonePosition();
if (this.bumpIf("+")) {} else if (this.bumpIf("-")) sign = -1;
let hasDigits = false;
let decimal = 0;
while (!this.isEOF()) {
const ch = this.char();
if (ch >= 48 && ch <= 57) {
hasDigits = true;
decimal = decimal * 10 + (ch - 48);
this.bump();
} else break;
}
const location = createLocation(startingPosition, this.clonePosition());
if (!hasDigits) return this.error(expectNumberError, location);
decimal *= sign;
if (!Number.isSafeInteger(decimal)) return this.error(invalidNumberError, location);
return {
val: decimal,
err: null
};
}
offset() {
return this.position.offset;
}
isEOF() {
return this.offset() === this.message.length;
}
clonePosition() {
return {
offset: this.position.offset,
line: this.position.line,
column: this.position.column
};
}
/**
* Return the code point at the current position of the parser.
* Throws if the index is out of bound.
*/
char() {
const offset = this.position.offset;
if (offset >= this.message.length) throw Error("out of bound");
const code = this.message.codePointAt(offset);
if (code === void 0) throw Error(`Offset ${offset} is at invalid UTF-16 code unit boundary`);
return code;
}
error(kind, location) {
return {
val: null,
err: {
kind,
message: this.message,
location
}
};
}
/** Bump the parser to the next UTF-16 code unit. */
bump() {
if (this.isEOF()) return;
const code = this.char();
if (code === 10) {
this.position.line += 1;
this.position.column = 1;
this.position.offset += 1;
} else {
this.position.column += 1;
this.position.offset += code < 65536 ? 1 : 2;
}
}
/**
* If the substring starting at the current position of the parser has
* the given prefix, then bump the parser to the character immediately
* following the prefix and return true. Otherwise, don't bump the parser
* and return false.
*/
bumpIf(prefix) {
if (this.message.startsWith(prefix, this.offset())) {
for (let i = 0; i < prefix.length; i++) this.bump();
return true;
}
return false;
}
/**
* Bump the parser until the pattern character is found and return `true`.
* Otherwise bump to the end of the file and return `false`.
*/
bumpUntil(pattern) {
const currentOffset = this.offset();
const index = this.message.indexOf(pattern, currentOffset);
if (index >= 0) {
this.bumpTo(index);
return true;
} else {
this.bumpTo(this.message.length);
return false;
}
}
/**
* Bump the parser to the target offset.
* If target offset is beyond the end of the input, bump the parser to the end of the input.
*/
bumpTo(targetOffset) {
if (this.offset() > targetOffset) throw Error(`targetOffset ${targetOffset} must be greater than or equal to the current offset ${this.offset()}`);
targetOffset = Math.min(targetOffset, this.message.length);
while (true) {
const offset = this.offset();
if (offset === targetOffset) break;
if (offset > targetOffset) throw Error(`targetOffset ${targetOffset} is at invalid UTF-16 code unit boundary`);
this.bump();
if (this.isEOF()) break;
}
}
/** advance the parser through all whitespace to the next non-whitespace code unit. */
bumpSpace() {
while (!this.isEOF() && _isWhiteSpace(this.char())) this.bump();
}
/**
* Peek at the *next* Unicode codepoint in the input without advancing the parser.
* If the input has been exhausted, then this returns null.
*/
peek() {
if (this.isEOF()) return null;
const code = this.char();
const offset = this.offset();
return this.message.charCodeAt(offset + (code >= 65536 ? 2 : 1)) ?? null;
}
};
/**
* This check if codepoint is alphabet (lower & uppercase)
* @param codepoint
* @returns
*/
function _isAlpha(codepoint) {
return codepoint >= 97 && codepoint <= 122 || codepoint >= 65 && codepoint <= 90;
}
function _isAlphaOrSlash(codepoint) {
return _isAlpha(codepoint) || codepoint === 47;
}
/** See `parseTag` function docs. */
function _isPotentialElementNameChar(c) {
return c === 45 || c === 46 || c >= 48 && c <= 57 || c === 95 || c >= 97 && c <= 122 || c >= 65 && c <= 90 || c == 183 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 893 || c >= 895 && c <= 8191 || c >= 8204 && c <= 8205 || c >= 8255 && c <= 8256 || c >= 8304 && c <= 8591 || c >= 11264 && c <= 12271 || c >= 12289 && c <= 55295 || c >= 63744 && c <= 64975 || c >= 65008 && c <= 65533 || c >= 65536 && c <= 983039;
}
/**
* Code point equivalent of regex `\p{White_Space}`.
* From: https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt
*/
function _isWhiteSpace(c) {
return c >= 9 && c <= 13 || c === 32 || c === 133 || c >= 8206 && c <= 8207 || c === 8232 || c === 8233;
}
function pruneLocation(els) {
els.forEach((el) => {
delete el.location;
if (isSelectElement(el) || isPluralElement(el)) for (const k in el.options) {
delete el.options[k].location;
pruneLocation(el.options[k].value);
}
else if (isNumberElement(el) && isNumberSkeleton(el.style)) delete el.style.location;
else if ((isDateElement(el) || isTimeElement(el)) && isDateTimeSkeleton(el.style)) delete el.style.location;
else if (isTagElement(el)) pruneLocation(el.children);
});
}
function parse(message, opts = {}) {
opts = {
shouldParseSkeletons: true,
requiresOtherClause: true,
...opts
};
const result = new Parser(message, opts).parse();
if (result.err) {
const error = SyntaxError(ErrorKind[result.err.kind]);
error.location = result.err.location;
error.originalMessage = result.err.message;
throw error;
}
if (!opts?.captureLocation) pruneLocation(result.val);
return result.val;
}
//#endregion
//#region node_modules/.aspect_rules_js/intl-messageformat@0.0.0/node_modules/intl-messageformat/index.js
let ErrorCode = /* @__PURE__ */ function(ErrorCode) {
ErrorCode["MISSING_VALUE"] = "MISSING_VALUE";
ErrorCode["INVALID_VALUE"] = "INVALID_VALUE";
ErrorCode["MISSING_INTL_API"] = "MISSING_INTL_API";
return ErrorCode;
}({});
var FormatError = class extends Error {
constructor(msg, code, originalMessage) {
super(msg);
this.code = code;
this.originalMessage = originalMessage;
}
toString() {
return `[formatjs Error: ${this.code}] ${this.message}`;
}
};
var InvalidValueError = class extends FormatError {
constructor(variableId, value, options, originalMessage) {
super(`Invalid values for "${variableId}": "${value}". Options are "${Object.keys(options).join("\", \"")}"`, "INVALID_VALUE", originalMessage);
}
};
var InvalidValueTypeError = class extends FormatError {
constructor(value, type, originalMessage) {
super(`Value for "${value}" must be of type ${type}`, "INVALID_VALUE", originalMessage);
}
};
var MissingValueError = class extends FormatError {
constructor(variableId, originalMessage) {
super(`The intl string context variable "${variableId}" was not provided to the string "${originalMessage}"`, "MISSING_VALUE", originalMessage);
}
};
function mergeLiteral(parts) {
if (parts.length < 2) return parts;
return parts.reduce((all, part) => {
const lastPart = all[all.length - 1];
if (!lastPart || lastPart.type !== 0 || part.type !== 0) all.push(part);
else lastPart.value += part.value;
return all;
}, []);
}
function isFormatXMLElementFn(el) {
return typeof el === "function";
}
function formatToParts(els, locales, formatters, formats, values, currentPluralValue, originalMessage) {
if (els.length === 1 && isLiteralElement(els[0])) return [{
type: 0,
value: els[0].value
}];
const result = [];
for (const el of els) {
if (isLiteralElement(el)) {
result.push({
type: 0,
value: el.value
});
continue;
}
if (isPoundElement(el)) {
if (typeof currentPluralValue === "number") result.push({
type: 0,
value: formatters.getNumberFormat(locales).format(currentPluralValue)
});
continue;
}
const { value: varName } = el;
if (!(values && varName in values)) throw new MissingValueError(varName, originalMessage);
let value = values[varName];
if (isArgumentElement(el)) {
if (!value || typeof value === "string" || typeof value === "number" || typeof value === "bigint") value = typeof value === "string" || typeof value === "number" || typeof value === "bigint" ? String(value) : "";
result.push({
type: typeof value === "string" ? 0 : 1,
value
});
continue;
}
if (isDateElement(el)) {
const style = typeof el.style === "string" ? formats.date[el.style] : isDateTimeSkeleton(el.style) ? el.style.parsedOptions : void 0;
result.push({
type: 0,
value: formatters.getDateTimeFormat(locales, style).format(value)
});
continue;
}
if (isTimeElement(el)) {
const style = typeof el.style === "string" ? formats.time[el.style] : isDateTimeSkeleton(el.style) ? el.style.parsedOptions : formats.time.medium;
result.push({
type: 0,
value: formatters.getDateTimeFormat(locales, style).format(value)
});
continue;
}
if (isNumberElement(el)) {
const style = typeof el.style === "string" ? formats.number[el.style] : isNumberSkeleton(el.style) ? el.style.parsedOptions : void 0;
if (style && style.scale) {
const scale = style.scale || 1;
if (typeof value === "bigint") {
if (!Number.isInteger(scale)) throw new TypeError(`Cannot apply fractional scale ${scale} to bigint value. Scale must be an integer when formatting bigint.`);
value = value * BigInt(scale);
} else value = value * scale;
}
result.push({
type: 0,
value: formatters.getNumberFormat(locales, style).format(value)
});
continue;
}
if (isTagElement(el)) {
const { children, value } = el;
const formatFn = values[value];
if (!isFormatXMLElementFn(formatFn)) throw new InvalidValueTypeError(value, "function", originalMessage);
let chunks = formatFn(formatToParts(children, locales, formatters, formats, values, currentPluralValue).map((p) => p.value));
if (!Array.isArray(chunks)) chunks = [chunks];
result.push(...chunks.map((c) => {
return {
type: typeof c === "string" ? 0 : 1,
value: c
};
}));
}
if (isSelectElement(el)) {
const key = value;
const opt = (Object.prototype.hasOwnProperty.call(el.options, key) ? el.options[key] : void 0) || el.options.other;
if (!opt) throw new InvalidValueError(el.value, value, Object.keys(el.options), originalMessage);
result.push(...formatToParts(opt.value, locales, formatters, formats, values));
continue;
}
if (isPluralElement(el)) {
const exactKey = `=${value}`;
let opt = Object.prototype.hasOwnProperty.call(el.options, exactKey) ? el.options[exactKey] : void 0;
if (!opt) {
if (!Intl.PluralRules) throw new FormatError(`Intl.PluralRules is not available in this environment.
Try polyfilling it using "@formatjs/intl-pluralrules"
`, "MISSING_INTL_API", originalMessage);
const numericValue = typeof value === "bigint" ? Number(value) : value;
const rule = formatters.getPluralRules(locales, { type: el.pluralType }).select(numericValue - (el.offset || 0));
opt = (Object.prototype.hasOwnProperty.call(el.options, rule) ? el.options[rule] : void 0) || el.options.other;
}
if (!opt) throw new InvalidValueError(el.value, value, Object.keys(el.options), originalMessage);
const numericValue = typeof value === "bigint" ? Number(value) : value;
result.push(...formatToParts(opt.value, locales, formatters, formats, values, numericValue - (el.offset || 0)));
continue;
}
}
return mergeLiteral(result);
}
function mergeConfig(c1, c2) {
if (!c2) return c1;
return {
...c1,
...c2,
...Object.keys(c1).reduce((all, k) => {
all[k] = {
...c1[k],
...c2[k]
};
return all;
}, {})
};
}
function mergeConfigs(defaultConfig, configs) {
if (!configs) return defaultConfig;
return Object.keys(defaultConfig).reduce((all, k) => {
all[k] = mergeConfig(defaultConfig[k], configs[k]);
return all;
}, { ...defaultConfig });
}
function createFastMemoizeCache$1(store) {
return { create() {
return {
get(key) {
return store[key];
},
set(key, value) {
store[key] = value;
}
};
} };
}
function createDefaultFormatters(cache = {
number: {},
dateTime: {},
pluralRules: {}
}) {
return {
getNumberFormat: memoize((...args) => new Intl.NumberFormat(...args), {
cache: createFastMemoizeCache$1(cache.number),
strategy: strategies.variadic
}),
getDateTimeFormat: memoize((...args) => new Intl.DateTimeFormat(...args), {
cache: createFastMemoizeCache$1(cache.dateTime),
strategy: strategies.variadic
}),
getPluralRules: memoize((...args) => new Intl.PluralRules(...args), {
cache: createFastMemoizeCache$1(cache.pluralRules),
strategy: strategies.variadic
})
};
}
var IntlMessageFormat = class IntlMessageFormat {
constructor(message, locales = IntlMessageFormat.defaultLocale, overrideFormats, opts) {
this.formatterCache = {
number: {},
dateTime: {},
pluralRules: {}
};
this.format = (values) => {
const parts = this.formatToParts(values);
if (parts.length === 1) return parts[0].value;
const result = parts.reduce((all, part) => {
if (!all.length || part.type !== 0 || typeof all[all.length - 1] !== "string") all.push(part.value);
else all[all.length - 1] += part.value;
return all;
}, []);
if (result.length <= 1) return result[0] || "";
return result;
};
this.formatToParts = (values) => formatToParts(this.ast, this.locales, this.formatters, this.formats, values, void 0, this.message);
this.resolvedOptions = () => ({ locale: this.resolvedLocale?.toString() || Intl.NumberFormat.supportedLocalesOf(this.locales)[0] });
this.getAst = () => this.ast;
this.locales = locales;
this.resolvedLocale = IntlMessageFormat.resolveLocale(locales);
if (typeof message === "string") {
this.message = message;
if (!IntlMessageFormat.__parse) throw new TypeError("IntlMessageFormat.__parse must be set to process `message` of type `string`");
const { ...parseOpts } = opts || {};
this.ast = IntlMessageFormat.__parse(message, {
...parseOpts,
locale: this.resolvedLocale
});
} else this.ast = message;
if (!Array.isArray(this.ast)) throw new TypeError("A message must be provided as a String or AST.");
this.formats = mergeConfigs(IntlMessageFormat.formats, overrideFormats);
this.formatters = opts && opts.formatters || createDefaultFormatters(this.formatterCache);
}
static {
this.memoizedDefaultLocale = null;
}
static get defaultLocale() {
if (!IntlMessageFormat.memoizedDefaultLocale) IntlMessageFormat.memoizedDefaultLocale = new Intl.NumberFormat().resolvedOptions().locale;
return IntlMessageFormat.memoizedDefaultLocale;
}
static {
this.resolveLocale = (locales) => {
if (typeof Intl.Locale === "undefined") return;
const supportedLocales = Intl.NumberFormat.supportedLocalesOf(locales);
if (supportedLocales.length > 0) return new Intl.Locale(supportedLocales[0]);
return new Intl.Locale(typeof locales === "string" ? locales : locales[0]);
};
}
static {
this.__parse = parse;
}
static {
this.formats = {
number: {
integer: { maximumFractionDigits: 0 },
currency: { style: "currency" },
percent: { style: "percent" }
},
date: {
short: {
month: "numeric",
day: "numeric",
year: "2-digit"
},
medium: {
month: "short",
day: "numeric",
year: "numeric"
},
long: {
month: "long",
day: "numeric",
year: "numeric"
},
full: {
weekday: "long",
month: "long",
day: "numeric",
year: "numeric"
}
},
time: {
short: {
hour: "numeric",
minute: "numeric"
},
medium: {
hour: "numeric",
minute: "numeric",
second: "numeric"
},
long: {
hour: "numeric",
minute: "numeric",
second: "numeric",
timeZoneName: "short"
},
full: {
hour: "numeric",
minute: "numeric",
second: "numeric",
timeZoneName: "short"
}
}
};
}
};
//#endregion
//#region node_modules/.aspect_rules_js/@formatjs+intl@0.0.0/node_modules/@formatjs/intl/index.js
let IntlErrorCode = /* @__PURE__ */ function(IntlErrorCode) {
IntlErrorCode["FORMAT_ERROR"] = "FORMAT_ERROR";
IntlErrorCode["UNSUPPORTED_FORMATTER"] = "UNSUPPORTED_FORMATTER";
IntlErrorCode["INVALID_CONFIG"] = "INVALID_CONFIG";
IntlErrorCode["MISSING_DATA"] = "MISSING_DATA";
IntlErrorCode["MISSING_TRANSLATION"] = "MISSING_TRANSLATION";
return IntlErrorCode;
}({});
var IntlError = class IntlError extends Error {
constructor(code, message, exception) {
const err = exception ? exception instanceof Error ? exception : new Error(String(exception)) : void 0;
super(`[@formatjs/intl Error ${code}] ${message}
${err ? `\n${err.message}\n${err.stack}` : ""}`);
this.code = code;
if (typeof Error.captureStackTrace === "function") Error.captureStackTrace(this, IntlError);
}
};
var UnsupportedFormatterError = class extends IntlError {
constructor(message, exception) {
super("UNSUPPORTED_FORMATTER", message, exception);
}
};
var InvalidConfigError = class extends IntlError {
constructor(message, exception) {
super("INVALID_CONFIG", message, exception);
}
};
var MissingDataError = class extends IntlError {
constructor(message, exception) {
super("MISSING_DATA", message, exception);
}
};
var IntlFormatError = class extends IntlError {
constructor(message, locale, exception) {
super("FORMAT_ERROR", `${message}
Locale: ${locale}
`, exception);
this.locale = locale;
}
};
var MessageFormatError = class extends IntlFormatError {
constructor(message, locale, descriptor, exception) {
super(`${message}
MessageID: ${descriptor?.id}
Default Message: ${descriptor?.defaultMessage}
Description: ${descriptor?.description}
`, locale, exception);
this.descriptor = descriptor;
this.locale = locale;
}
};
var MissingTranslationError = class extends IntlError {
constructor(descriptor, locale) {
super("MISSING_TRANSLATION", `Missing message: "${descriptor.id}" for locale "${locale}", using ${descriptor.defaultMessage ? `default message (${typeof descriptor.defaultMessage === "string" ? descriptor.defaultMessage : descriptor.defaultMessage.map((e) => e.value ?? JSON.stringify(e)).join()})` : "id"} as fallback.`);
this.descriptor = descriptor;
}
};
function invariant$1(condition, message, Err = Error) {
if (!condition) throw new Err(message);
}
function filterProps(props, allowlist, defaults = {}) {
return allowlist.reduce((filtered, name) => {
if (name in props) filtered[name] = props[name];
else if (name in defaults) filtered[name] = defaults[name];
return filtered;
}, {});
}
const defaultErrorHandler = (error) => {
if (process.env.NODE_ENV !== "production") console.error(error);
};
const defaultWarnHandler = (warning) => {
if (process.env.NODE_ENV !== "production") console.warn(warning);
};
const DEFAULT_INTL_CONFIG$1 = {
formats: {},
messages: {},
timeZone: void 0,
defaultLocale: "en",
defaultFormats: {},
fallbackOnEmptyString: true,
onError: defaultErrorHandler,
onWarn: defaultWarnHandler
};
function createIntlCache() {
return {
dateTime: {},
number: {},
message: {},
relativeTime: {},
pluralRules: {},
list: {},
displayNames: {}
};
}
function createFastMemoizeCache(store) {
return { create() {
return {
get(key) {
return store[key];
},
set(key, value) {
store[key] = value;
}
};
} };
}
/**
* Create intl formatters and populate cache
* @param cache explicit cache to prevent leaking memory
*/
function createFormatters(cache = createIntlCache()) {
const RelativeTimeFormat = Intl.RelativeTimeFormat;
const ListFormat = Intl.ListFormat;
const DisplayNames = Intl.DisplayNames;
const getDateTimeFormat = memoize((...args) => new Intl.DateTimeFormat(...args), {
cache: createFastMemoizeCache(cache.dateTime),
strategy: strategies.variadic
});
const getNumberFormat = memoize((...args) => new Intl.NumberFormat(...args), {
cache: createFastMemoizeCache(cache.number),
strategy: strategies.variadic
});
const getPluralRules = memoize((...args) => new Intl.PluralRules(...args), {
cache: createFastMemoizeCache(cache.pluralRules),
strategy: strategies.variadic
});
return {
getDateTimeFormat,
getNumberFormat,
getMessageFormat: memoize((message, locales, overrideFormats, opts) => new IntlMessageFormat(message, locales, overrideFormats, {
formatters: {
getNumberFormat,
getDateTimeFormat,
getPluralRules
},
...opts
}), {
cache: createFastMemoizeCache(cache.message),
strategy: strategies.variadic
}),
getRelativeTimeFormat: memoize((...args) => new RelativeTimeFormat(...args), {
cache: createFastMemoizeCache(cache.relativeTime),
strategy: strategies.variadic
}),
getPluralRules,
getListFormat: memoize((...args) => new ListFormat(...args), {
cache: createFastMemoizeCache(cache.list),
strategy: strategies.variadic
}),
getDisplayNames: memoize((...args) => new DisplayNames(...args), {
cache: createFastMemoizeCache(cache.displayNames),
strategy: strategies.variadic
})
};
}
function getNamedFormat(formats, type, name, onError) {
const formatType = formats && formats[type];
let format;
if (formatType) format = formatType[name];
if (format) return format;
onError(new UnsupportedFormatterError(`No ${type} format named: ${name}`));
}
function setTimeZoneInOptions(opts, timeZone) {
return Object.keys(opts).reduce((all, k) => {
all[k] = {
timeZone,
...opts[k]
};
return all;
}, {});
}
function deepMergeOptions(opts1, opts2) {
return Object.keys({
...opts1,
...opts2
}).reduce((all, k) => {
all[k] = {
...opts1[k],
...opts2[k]
};
return all;
}, {});
}
function deepMergeFormatsAndSetTimeZone(f1, timeZone) {
if (!timeZone) return f1;
const mfFormats = IntlMessageFormat.formats;
return {
...mfFormats,
...f1,
date: deepMergeOptions(setTimeZoneInOptions(mfFormats.date, timeZone), setTimeZoneInOptions(f1.date || {}, timeZone)),
time: deepMergeOptions(setTimeZoneInOptions(mfFormats.time, timeZone), setTimeZoneInOptions(f1.time || {}, timeZone))
};
}
function getMessageDescriptorContext(messageDescriptor) {
const { defaultMessage } = messageDescriptor;
try {
return defaultMessage !== void 0 ? `\nDefault Message: ${typeof defaultMessage === "string" ? defaultMessage : JSON.stringify(defaultMessage)}` : `\nMessage Descriptor: ${JSON.stringify(messageDescriptor)}`;
} catch {
return "";
}
}
const formatMessage$1 = ({ locale, formats, messages, defaultLocale, defaultFormats, fallbackOnEmptyString, onError, timeZone, defaultRichTextElements }, state, messageDescriptor = { id: "" }, values, opts) => {
const { id: msgId, defaultMessage } = messageDescriptor;
if (!msgId) invariant$1(false, `[@formatjs/intl] An \`id\` must be provided to format a message. You can either:
1. Configure your build toolchain with [babel-plugin-formatjs](https://formatjs.github.io/docs/tooling/babel-plugin)
or [@formatjs/ts-transformer](https://formatjs.github.io/docs/tooling/ts-transformer) OR
2. Configure your \`eslint\` config to include [eslint-plugin-formatjs](https://formatjs.github.io/docs/tooling/linter#enforce-id)
to autofix this issue${getMessageDescriptorContext(messageDescriptor)}`);
const id = String(msgId);
const message = messages && Object.prototype.hasOwnProperty.call(messages, id) && messages[id];
if (Array.isArray(message) && message.length === 1 && message[0].type === TYPE.literal) return message[0].value;
values = {
...defaultRichTextElements,
...values
};
formats = deepMergeFormatsAndSetTimeZone(formats, timeZone);
defaultFormats = deepMergeFormatsAndSetTimeZone(defaultFormats, timeZone);
if (!message) {
if (fallbackOnEmptyString === false && message === "") return message;
if (!defaultMessage || locale && locale.toLowerCase() !== defaultLocale.toLowerCase()) onError(new MissingTranslationError(messageDescriptor, locale));
if (defaultMessage) try {
return state.getMessageFormat(defaultMessage, defaultLocale, defaultFormats, opts).format(values);
} catch (e) {
onError(new MessageFormatError(`Error formatting default message for: "${id}", rendering default message verbatim`, locale, messageDescriptor, e));
return typeof defaultMessage === "string" ? defaultMessage : id;
}
return id;
}
try {
return state.getMessageFormat(message, locale, formats, {
formatters: state,
...opts
}).format(values);
} catch (e) {
onError(new MessageFormatError(`Error formatting message: "${id}", using ${defaultMessage ? "default message" : "id"} as fallback.`, locale, messageDescriptor, e));
}
if (defaultMessage) try {
return state.getMessageFormat(defaultMessage, defaultLocale, defaultFormats, opts).format(values);
} catch (e) {
onError(new MessageFormatError(`Error formatting the default message for: "${id}", rendering message verbatim`, locale, messageDescriptor, e));
}
if (typeof message === "string") return message;
if (typeof defaultMessage === "string") return defaultMessage;
return id;
};
const DATE_TIME_FORMAT_OPTIONS = [
"formatMatcher",
"timeZone",
"hour12",
"weekday",
"era",
"year",
"month",
"day",
"hour",
"minute",
"second",
"timeZoneName",
"hourCycle",
"dateStyle",
"timeStyle",
"calendar",
"numberingSystem",
"fractionalSecondDigits"
];
function getFormatter$2({ locale, formats, onError, timeZone }, type, getDateTimeFormat, options = {}) {
const { format } = options;
const defaults = {
...timeZone && { timeZone },
...format && getNamedFormat(formats, type, format, onError)
};
let filteredOptions = filterProps(options, DATE_TIME_FORMAT_OPTIONS, defaults);
if (type === "time" && !filteredOptions.hour && !filteredOptions.minute && !filteredOptions.second && !filteredOptions.timeStyle && !filteredOptions.dateStyle) filteredOptions = {
...filteredOptions,
hour: "numeric",
minute: "numeric"
};
return getDateTimeFormat(locale, filteredOptions);
}
function formatDate(config, getDateTimeFormat, value, options = {}) {
const date = typeof value === "string" ? new Date(value || 0) : value;
try {
return getFormatter$2(config, "date", getDateTimeFormat, options).format(date);
} catch (e) {
config.onError(new IntlFormatError("Error formatting date.", config.locale, e));
}
return String(date);
}
function formatTime(config, getDateTimeFormat, value, options = {}) {
const date = typeof value === "string" ? new Date(value || 0) : value;
try {
return getFormatter$2(config, "time", getDateTimeFormat, options).format(date);
} catch (e) {
config.onError(new IntlFormatError("Error formatting time.", config.locale, e));
}
return String(date);
}
function formatDateTimeRange(config, getDateTimeFormat, from, to, options = {}) {
const fromDate = typeof from === "string" ? new Date(from || 0) : from;
const toDate = typeof to === "string" ? new Date(to || 0) : to;
try {
return getFormatter$2(config, "dateTimeRange", getDateTimeFormat, options).formatRange(fromDate, toDate);
} catch (e) {
config.onError(new IntlFormatError("Error formatting date time range.", config.locale, e));
}
return String(fromDate);
}
function formatDateToParts(config, getDateTimeFormat, value, options = {}) {
const date = typeof value === "string" ? new Date(value || 0) : value;
try {
return getFormatter$2(config, "date", getDateTimeFormat, options).formatToParts(date);
} catch (e) {
config.onError(new IntlFormatError("Error formatting date.", config.locale, e));
}
return [];
}
function formatTimeToParts(config, getDateTimeFormat, value, options = {}) {
const date = typeof value === "string" ? new Date(value || 0) : value;
try {
return getFormatter$2(config, "time", getDateTimeFormat, options).formatToParts(date);
} catch (e) {
config.onError(new IntlFormatError("Error formatting time.", config.locale, e));
}
return [];
}
const DISPLAY_NAMES_OPTONS = [
"style",
"type",
"fallback",
"languageDisplay"
];
function formatDisplayName({ locale, onError }, getDisplayNames, value, options) {
if (!Intl.DisplayNames) onError(new FormatError(`Intl.DisplayNames is not available in this environment.
Try polyfilling it using "@formatjs/intl-displaynames"
`, ErrorCode.MISSING_INTL_API));
const filteredOptions = filterProps(options, DISPLAY_NAMES_OPTONS);
try {
return getDisplayNames(locale, filteredOptions).of(value);
} catch (e) {
onError(new IntlFormatError("Error formatting display name.", locale, e));
}
}
const LIST_FORMAT_OPTIONS = ["type", "style"];
const now = Date.now();
function generateToken(i) {
return `${now}_${i}_${now}`;
}
function formatList(opts, getListFormat, values, options = {}) {
const results = formatListToParts(opts, getListFormat, values, options).reduce((all, el) => {
const val = el.value;
if (typeof val !== "string") all.push(val);
else if (typeof all[all.length - 1] === "string") all[all.length - 1] += val;
else all.push(val);
return all;
}, []);
return results.length === 1 ? results[0] : results.length === 0 ? "" : results;
}
function formatListToParts({ locale, onError }, getListFormat, values, options = {}) {
if (!Intl.ListFormat) onError(new FormatError(`Intl.ListFormat is not available in this environment.
Try polyfilling it using "@formatjs/intl-listformat"
`, ErrorCode.MISSING_INTL_API));
const filteredOptions = filterProps(options, LIST_FORMAT_OPTIONS);
try {
const richValues = {};
const serializedValues = Array.from(values).map((v, i) => {
if (typeof v === "object" && v !== null) {
const id = generateToken(i);
richValues[id] = v;
return id;
}
return String(v);
});
return getListFormat(locale, filteredOptions).formatToParts(serializedValues).map((part) => part.type === "literal" ? part : {
...part,
value: richValues[part.value] || part.value
});
} catch (e) {
onError(new IntlFormatError("Error formatting list.", locale, e));
}
return values;
}
const PLURAL_FORMAT_OPTIONS = ["type"];
function formatPlural({ locale, onError }, getPluralRules, value, options = {}) {
if (!Intl.PluralRules) onError(new FormatError(`Intl.PluralRules is not available in this environment.
Try polyfilling it using "@formatjs/intl-pluralrules"
`, ErrorCode.MISSING_INTL_API));
const filteredOptions = filterProps(options, PLURAL_FORMAT_OPTIONS);
try {
return getPluralRules(locale, filteredOptions).select(value);
} catch (e) {
onError(new IntlFormatError("Error formatting plural.", locale, e));
}
return "other";
}
const RELATIVE_TIME_FORMAT_OPTIONS = ["numeric", "style"];
function getFormatter$1({ locale, formats, onError }, getRelativeTimeFormat, options = {}) {
const { format } = options;
const defaults = !!format && getNamedFormat(formats, "relative", format, onError) || {};
return getRelativeTimeFormat(locale, filterProps(options, RELATIVE_TIME_FORMAT_OPTIONS, defaults));
}
function formatRelativeTime(config, getRelativeTimeFormat, value, unit, options = {}) {
if (!unit) unit = "second";
if (!Intl.RelativeTimeFormat) config.onError(new FormatError(`Intl.RelativeTimeFormat is not available in this environment.
Try polyfilling it using "@formatjs/intl-relativetimeformat"
`, ErrorCode.MISSING_INTL_API));
try {
return getFormatter$1(config, getRelativeTimeFormat, options).format(value, unit);
} catch (e) {
config.onError(new IntlFormatError("Error formatting relative time.", config.locale, e));
}
return String(value);
}
const NUMBER_FORMAT_OPTIONS = [
"style",
"currency",
"unit",
"unitDisplay",
"useGrouping",
"minimumIntegerDigits",
"minimumFractionDigits",
"maximumFractionDigits",
"minimumSignificantDigits",
"maximumSignificantDigits",
"compactDisplay",
"currencyDisplay",
"currencySign",
"notation",
"signDisplay",
"unit",
"unitDisplay",
"numberingSystem",
"trailingZeroDisplay",
"roundingPriority",
"roundingIncrement",
"roundingMode"
];
function getFormatter({ locale, formats, onError }, getNumberFormat, options = {}) {
const { format } = options;
const defaults = format && getNamedFormat(formats, "number", format, onError) || {};
return getNumberFormat(locale, filterProps(options, NUMBER_FORMAT_OPTIONS, defaults));
}
function formatNumber(config, getNumberFormat, value, options = {}) {
try {
return getFormatter(config, getNumberFormat, options).format(value);
} catch (e) {
config.onError(new IntlFormatError("Error formatting number.", config.locale, e));
}
return String(value);
}
function formatNumberToParts(config, getNumberFormat, value, options = {}) {
try {
return getFormatter(config, getNumberFormat, options).formatToParts(value);
} catch (e) {
config.onError(new IntlFormatError("Error formatting number.", config.locale, e));
}
return [];
}
function messagesContainString(messages) {
return typeof (messages ? messages[Object.keys(messages)[0]] : void 0) === "string";
}
function verifyConfigMessages(config) {
if (config.onWarn && config.defaultRichTextElements && messagesContainString(config.messages || {})) config.onWarn(`[@formatjs/intl] "defaultRichTextElements" was specified but "message" was not pre-compiled.
Please consider using "@formatjs/cli" to pre-compile your messages for performance.
For more details see https://formatjs.github.io/docs/getting-started/message-distribution`);
}
/**
* Create intl object
* @param config intl config
* @param cache cache for formatter instances to prevent memory leak
*/
function createIntl$1(config, cache) {
const formatters = createFormatters(cache);
const resolvedConfig = {
...DEFAULT_INTL_CONFIG$1,
...config
};
const { locale, defaultLocale, onError } = resolvedConfig;
if (!locale) {
if (onError) onError(new InvalidConfigError(`"locale" was not configured, using "${defaultLocale}" as fallback. See https://formatjs.github.io/docs/react-intl/api#intlshape for more details`));
resolvedConfig.locale = resolvedConfig.defaultLocale || "en";
} else if (!Intl.NumberFormat.supportedLocalesOf(locale).length && onError) onError(new MissingDataError(`Missing locale data for locale: "${locale}" in Intl.NumberFormat. Using default locale: "${defaultLocale}" as fallback. See https://formatjs.github.io/docs/react-intl#runtime-requirements for more details`));
else if (!Intl.DateTimeFormat.supportedLocalesOf(locale).length && onError) onError(new MissingDataError(`Missing locale data for locale: "${locale}" in Intl.DateTimeFormat. Using default locale: "${defaultLocale}" as fallback. See https://formatjs.github.io/docs/react-intl#runtime-requirements for more details`));
verifyConfigMessages(resolvedConfig);
return {
...resolvedConfig,
formatters,
formatNumber: formatNumber.bind(null, resolvedConfig, formatters.getNumberFormat),
formatNumberToParts: formatNumberToParts.bind(null, resolvedConfig, formatters.getNumberFormat),
formatRelativeTime: formatRelativeTime.bind(null, resolvedConfig, formatters.getRelativeTimeFormat),
formatDate: formatDate.bind(null, resolvedConfig, formatters.getDateTimeFormat),
formatDateToParts: formatDateToParts.bind(null, resolvedConfig, formatters.getDateTimeFormat),
formatTime: formatTime.bind(null, resolvedConfig, formatters.getDateTimeFormat),
formatDateTimeRange: formatDateTimeRange.bind(null, resolvedConfig, formatters.getDateTimeFormat),
formatTimeToParts: formatTimeToParts.bind(null, resolvedConfig, formatters.getDateTimeFormat),
formatPlural: formatPlural.bind(null, resolvedConfig, formatters.getPluralRules),
formatMessage: formatMessage$1.bind(null, resolvedConfig, formatters),
$t: formatMessage$1.bind(null, resolvedConfig, formatters),
formatList: formatList.bind(null, resolvedConfig, formatters.getListFormat),
formatListToParts: formatListToParts.bind(null, resolvedConfig, formatters.getListFormat),
formatDisplayName: formatDisplayName.bind(null, resolvedConfig, formatters.getDisplayNames)
};
}
//#endregion
//#region packages/react-intl/utils.tsx
function invariant(condition, message, Err = Error) {
if (!condition) throw new Err(message);
}
function invariantIntlContext(intl) {
invariant(intl, "[React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.");
}
const DEFAULT_INTL_CONFIG = {
...DEFAULT_INTL_CONFIG$1,
textComponent: React.Fragment
};
/**
* Builds an array of {@link React.ReactNode}s with index-based keys, similar to
* {@link React.Children.toArray}. However, this function tells React that it
* was intentional, so they won't produce a bunch of warnings about it.
*
* React doesn't recommend doing this because it makes reordering inefficient,
* but we mostly need this for message chunks, which don't tend to reorder to
* begin with.
*
*/
const toKeyedReactNodeArray = (children) => {
return React.Children.toArray(children).map((child, index) => {
if (React.isValidElement(child)) return /* @__PURE__ */ jsx(React.Fragment, { children: child }, index);
return child;
});
};
/**
* Takes a `formatXMLElementFn`, and composes it in function, which passes
* argument `parts` through, assigning unique key to each part, to prevent
* "Each child in a list should have a unique "key"" React error.
* @param formatXMLElementFn
*/
function assignUniqueKeysToParts(formatXMLElementFn) {
return function(parts) {
return formatXMLElementFn(toKeyedReactNodeArray(parts));
};
}
function shallowEqual(objA, objB) {
if (objA === objB) return true;
if (!objA || !objB) return false;
var aKeys = Object.keys(objA);
var bKeys = Object.keys(objB);
var len = aKeys.length;
if (bKeys.length !== len) return false;
for (var i = 0; i < len; i++) {
var key = aKeys[i];
if (objA[key] !== objB[key] || !Object.prototype.hasOwnProperty.call(objB, key)) return false;
}
return true;
}
//#endregion
//#region packages/react-intl/components/context.ts
const IntlContext = React.createContext(null);
const Provider = IntlContext.Provider;
//#endregion
//#region packages/react-intl/components/useIntl.ts
function useIntl() {
const intl = React.useContext(IntlContext);
invariantIntlContext(intl);
return intl;
}
//#endregion
//#region packages/react-intl/components/createFormattedComponent.tsx
var DisplayName = /* @__PURE__ */ function(DisplayName) {
DisplayName["formatDate"] = "FormattedDate";
DisplayName["formatTime"] = "FormattedTime";
DisplayName["formatNumber"] = "FormattedNumber";
DisplayName["formatList"] = "FormattedList";
DisplayName["formatDisplayName"] = "FormattedDisplayName";
return DisplayName;
}(DisplayName || {});
var DisplayNameParts = /* @__PURE__ */ function(DisplayNameParts) {
DisplayNameParts["formatDate"] = "FormattedDateParts";
DisplayNameParts["formatTime"] = "FormattedTimeParts";
DisplayNameParts["formatNumber"] = "FormattedNumberParts";
DisplayNameParts["formatList"] = "FormattedListParts";
return DisplayNameParts;
}(DisplayNameParts || {});
const FormattedNumberParts = (props) => {
const intl = useIntl();
const { value, children, ...formatProps } = props;
return children(intl.formatNumberToParts(value, formatProps));
};
FormattedNumberParts.displayName = "FormattedNumberParts";
const FormattedListParts = (props) => {
const intl = useIntl();
const { value, children, ...formatProps } = props;
return children(intl.formatListToParts(value, formatProps));
};
FormattedListParts.displayName = "FormattedListParts";
function createFormattedDateTimePartsComponent(name) {
const ComponentParts = (props) => {
const intl = useIntl();
const { value, children, ...formatProps } = props;
const date = typeof value === "string" ? new Date(value || 0) : value;
return children(name === "formatDate" ? intl.formatDateToParts(date, formatProps) : intl.formatTimeToParts(date, formatProps));
};
ComponentParts.displayName = DisplayNameParts[name];
return ComponentParts;
}
function createFormattedComponent(name) {
const Component = (props) => {
const intl = useIntl();
const { value, children, ...formatProps } = props;
const formattedValue = intl[name](value, formatProps);
if (typeof children === "function") return children(formattedValue);
const Text = intl.textComponent || React.Fragment;
return /* @__PURE__ */ jsx(Text, { children: formattedValue });
};
Component.displayName = DisplayName[name];
return Component;
}
//#endregion
//#region packages/react-intl/components/createIntl.ts
function assignUniqueKeysToFormatXMLElementFnArgument(values) {
if (!values) return values;
return Object.keys(values).reduce((acc, k) => {
const v = values[k];
acc[k] = isFormatXMLElementFn(v) ? assignUniqueKeysToParts(v) : v;
return acc;
}, {});
}
const formatMessage = (config, formatters, descriptor, rawValues, ...rest) => {
const values = assignUniqueKeysToFormatXMLElementFnArgument(rawValues);
const chunks = formatMessage$1(config, formatters, descriptor, values, ...rest);
if (Array.isArray(chunks)) return toKeyedReactNodeArray(chunks);
return chunks;
};
/**
* Create intl object
* @param config intl config
* @param cache cache for formatter instances to prevent memory leak
*/
const createIntl = ({ defaultRichTextElements: rawDefaultRichTextElements, ...config }, cache) => {
const defaultRichTextElements = assignUniqueKeysToFormatXMLElementFnArgument(rawDefaultRichTextElements);
const coreIntl = createIntl$1({
...DEFAULT_INTL_CONFIG,
...config,
defaultRichTextElements
}, cache);
const resolvedConfig = {
locale: coreIntl.locale,
timeZone: coreIntl.timeZone,
fallbackOnEmptyString: coreIntl.fallbackOnEmptyString,
formats: coreIntl.formats,
defaultLocale: coreIntl.defaultLocale,
defaultFormats: coreIntl.defaultFormats,
messages: coreIntl.messages,
onError: coreIntl.onError,
defaultRichTextElements
};
return {
...coreIntl,
formatMessage: formatMessage.bind(null, resolvedConfig, coreIntl.formatters),
$t: formatMessage.bind(null, resolvedConfig, coreIntl.formatters)
};
};
//#endregion
//#region packages/react-intl/components/dateTimeRange.tsx
const FormattedDateTimeRange = (props) => {
const intl = useIntl();
const { from, to, children, ...formatProps } = props;
const formattedValue = intl.formatDateTimeRange(from, to, formatProps);
if (typeof children === "function") return children(formattedValue);
const Text = intl.textComponent || React.Fragment;
return /* @__PURE__ */ jsx(Text, { children: formattedValue });
};
FormattedDateTimeRange.displayName = "FormattedDateTimeRange";
//#endregion
//#region packages/react-intl/components/message.tsx
function areEqual(prevProps, nextProps) {
const { values, ...otherProps } = prevProps;
const { values: nextValues, ...nextOtherProps } = nextProps;
return shallowEqual(nextValues, values) && shallowEqual(otherProps, nextOtherProps);
}
function FormattedMessage(props) {
const { formatMessage, textComponent: Text = React.Fragment } = useIntl();
const { id, description, defaultMessage, values, children, tagName: Component = Text, ignoreTag } = props;
const nodes = formatMessage({
id,
description,
defaultMessage
}, values, { ignoreTag });
if (typeof children === "function") return children(Array.isArray(nodes) ? nodes : [nodes]);
if (Component) return /* @__PURE__ */ jsx(Component, { children: nodes });
return /* @__PURE__ */ jsx(Fragment, { children: nodes });
}
FormattedMessage.displayName = "FormattedMessage";
const MemoizedFormattedMessage = React.memo(FormattedMessage, areEqual);
MemoizedFormattedMessage.displayName = "MemoizedFormattedMessage";
//#endregion
//#region packages/react-intl/components/plural.tsx
const FormattedPlural = (props) => {
const { formatPlural, textComponent: Text } = useIntl();
const { value, other, children } = props;
const formattedPlural = props[formatPlural(value, props)] || other;
if (typeof children === "function") return children(formattedPlural);
if (Text) return /* @__PURE__ */ jsx(Text, { children: formattedPlural });
return formattedPlural;
};
FormattedPlural.displayName = "FormattedPlural";
//#endregion
//#region packages/react-intl/components/provider.tsx
function processIntlConfig(config) {
return {
locale: config.locale,
timeZone: config.timeZone,
fallbackOnEmptyString: config.fallbackOnEmptyString,
formats: config.formats,
textComponent: config.textComponent,
messages: config.messages,
defaultLocale: config.defaultLocale,
defaultFormats: config.defaultFormats,
onError: config.onError,
onWarn: config.onWarn,
wrapRichTextChunksInFragment: config.wrapRichTextChunksInFragment,
defaultRichTextElements: config.defaultRichTextElements
};
}
function IntlProviderImpl(props) {
const cacheRef = React.useRef(createIntlCache());
const prevConfigRef = React.useRef(void 0);
const intlRef = React.useRef(void 0);
const filteredProps = {};
for (const key in props) if (props[key] !== void 0) filteredProps[key] = props[key];
const config = processIntlConfig({
...DEFAULT_INTL_CONFIG,
...filteredProps
});
if (!prevConfigRef.current || !shallowEqual(prevConfigRef.current, config)) {
prevConfigRef.current = config;
intlRef.current = createIntl(config, cacheRef.current);
}
invariantIntlContext(intlRef.current);
return /* @__PURE__ */ jsx(Provider, {
value: intlRef.current,
children: props.children
});
}
IntlProviderImpl.displayName = "IntlProvider";
const IntlProvider = IntlProviderImpl;
//#endregion
//#region packages/react-intl/components/relative.tsx
const MINUTE = 60;
const HOUR = 3600;
const DAY = 86400;
function selectUnit(seconds) {
const absValue = Math.abs(seconds);
if (absValue < MINUTE) return "second";
if (absValue < HOUR) return "minute";
if (absValue < DAY) return "hour";
return "day";
}
function getDurationInSeconds(unit) {
switch (unit) {
case "second": return 1;
case "minute": return MINUTE;
case "hour": return HOUR;
default: return DAY;
}
}
function valueToSeconds(value, unit) {
if (!value) return 0;
switch (unit) {
case "second": return value;
case "minute": return value * MINUTE;
default: return value * HOUR;
}
}
const INCREMENTABLE_UNITS = [
"second",
"minute",
"hour"
];
function canIncrement(unit = "second") {
return INCREMENTABLE_UNITS.indexOf(unit) > -1;
}
const SimpleFormattedRelativeTime = (props) => {
const { formatRelativeTime, textComponent: Text } = useIntl();
const { children, value, unit, ...otherProps } = props;
const formattedRelativeTime = formatRelativeTime(value || 0, unit, otherProps);
if (typeof children === "function") return children(formattedRelativeTime);
if (Text) return /* @__PURE__ */ jsx(Text, { children: formattedRelativeTime });
return /* @__PURE__ */ jsx(Fragment, { children: formattedRelativeTime });
};
const FormattedRelativeTime = ({ value = 0, unit = "second", updateIntervalInSeconds, ...otherProps }) => {
invariant(!updateIntervalInSeconds || !!(updateIntervalInSeconds && canIncrement(unit)), "Cannot schedule update with unit longer than hour");
const [prevUnit, setPrevUnit] = React.useState();
const [prevValue, setPrevValue] = React.useState(0);
const [currentValueInSeconds, setCurrentValueInSeconds] = React.useState(0);
const updateTimer = React.useRef(void 0);
if (unit !== prevUnit || value !== prevValue) {
setPrevValue(value || 0);
setPrevUnit(unit);
setCurrentValueInSeconds(canIncrement(unit) ? valueToSeconds(value, unit) : 0);
}
React.useEffect(() => {
function clearUpdateTimer() {
clearTimeout(updateTimer.current);
}
clearUpdateTimer();
if (!updateIntervalInSeconds || !canIncrement(unit)) return clearUpdateTimer;
const nextValueInSeconds = currentValueInSeconds - updateIntervalInSeconds;
const nextUnit = selectUnit(nextValueInSeconds);
if (nextUnit === "day") return clearUpdateTimer;
const unitDuration = getDurationInSeconds(nextUnit);
const prevInterestingValueInSeconds = nextValueInSeconds - nextValueInSeconds % unitDuration;
const nextInterestingValueInSeconds = prevInterestingValueInSeconds >= currentValueInSeconds ? prevInterestingValueInSeconds - unitDuration : prevInterestingValueInSeconds;
const delayInSeconds = Math.abs(nextInterestingValueInSeconds - currentValueInSeconds);
if (currentValueInSeconds !== nextInterestingValueInSeconds) updateTimer.current = setTimeout(() => setCurrentValueInSeconds(nextInterestingValueInSeconds), delayInSeconds * 1e3);
return clearUpdateTimer;
}, [
currentValueInSeconds,
updateIntervalInSeconds,
unit
]);
let currentValue = value || 0;
let currentUnit = unit;
if (canIncrement(unit) && typeof currentValueInSeconds === "number" && updateIntervalInSeconds) {
currentUnit = selectUnit(currentValueInSeconds);
const unitDuration = getDurationInSeconds(currentUnit);
currentValue = Math.round(currentValueInSeconds / unitDuration);
}
return /* @__PURE__ */ jsx(SimpleFormattedRelativeTime, {
value: currentValue,
unit: currentUnit,
...otherProps
});
};
FormattedRelativeTime.displayName = "FormattedRelativeTime";
//#endregion
//#region packages/react-intl/index.ts
function defineMessages(msgs) {
return msgs;
}
function defineMessage(msg) {
return msg;
}
const FormattedDate = createFormattedComponent("formatDate");
const FormattedTime = createFormattedComponent("formatTime");
const FormattedNumber = createFormattedComponent("formatNumber");
const FormattedList = createFormattedComponent("formatList");
const FormattedDisplayName = createFormattedComponent("formatDisplayName");
const FormattedDateParts = createFormattedDateTimePartsComponent("formatDate");
const FormattedTimeParts = createFormattedDateTimePartsComponent("formatTime");
//#endregion
export { FormattedDate, FormattedDateParts, FormattedDateTimeRange, FormattedDisplayName, FormattedList, FormattedListParts, MemoizedFormattedMessage as FormattedMessage, FormattedNumber, FormattedNumberParts, FormattedPlural, FormattedRelativeTime, FormattedTime, FormattedTimeParts, IntlContext, IntlProvider, InvalidConfigError, MessageFormatError, MissingDataError, MissingTranslationError, Provider as RawIntlProvider, IntlError as ReactIntlError, IntlErrorCode as ReactIntlErrorCode, UnsupportedFormatterError, createIntl, createIntlCache, defineMessage, defineMessages, useIntl };
//# sourceMappingURL=react-intl.esbuild.iife.js.map