UNPKG

@formatjs/intl-numberformat

Version:

Ponyfill for ES2020 Intl.NumberFormat

1,953 lines (1,952 loc) 144 kB
import { currencyDigitsData } from "@formatjs_generated/cldr.number/currency-digits.js"; import { numberingSystemNames } from "@formatjs_generated/cldr.number/numbering-systems.js"; import { supportedLocales } from "@formatjs_generated/cldr.supported-locales/intl-numberformat.js"; //#region packages/ecma262-abstract/OrdinaryHasInstance.js function IsCallable$1(fn) { return typeof fn === "function"; } /** * https://tc39.es/ecma262/#sec-ordinaryhasinstance */ function OrdinaryHasInstance(C, O, internalSlots) { if (!IsCallable$1(C)) return false; if (internalSlots?.boundTargetFunction) return O instanceof internalSlots?.boundTargetFunction; if (typeof O !== "object") return false; let P = C.prototype; if (typeof P !== "object") throw new TypeError("OrdinaryHasInstance called on an object with an invalid prototype property."); return Object.prototype.isPrototypeOf.call(P, O); } //#endregion //#region packages/ecma402-abstract/CanonicalizeLocaleList.js /** * http://ecma-international.org/ecma-402/7.0/index.html#sec-canonicalizelocalelist * @param locales */ function CanonicalizeLocaleList$1(locales) { return Intl.getCanonicalLocales(locales); } //#endregion //#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 packages/ecma402-abstract/utils.js function repeat(s, times) { if (typeof s.repeat === "function") return s.repeat(times); const arr = Array.from({ length: times }); for (let i = 0; i < arr.length; i++) arr[i] = s; return arr.join(""); } function defineProperty(target, name, { value }) { Object.defineProperty(target, name, { configurable: true, enumerable: false, writable: true, value }); } function ensureIntl() { if (typeof Intl === "undefined") Object.defineProperty(globalThis, "Intl", { configurable: true, enumerable: false, writable: true, value: {} }); return Intl; } function invariant$2(condition, message, Err = Error) { if (!condition) throw new Err(message); } memoize((...args) => new Intl.NumberFormat(...args), { strategy: strategies.variadic }); const createMemoizedPluralRules = memoize((...args) => new Intl.PluralRules(...args), { strategy: strategies.variadic }); memoize((...args) => new Intl.ListFormat(...args), { strategy: strategies.variadic }); //#endregion //#region node_modules/.aspect_rules_js/@formatjs+bigdecimal@0.0.0/node_modules/@formatjs/bigdecimal/index.js const DIV_PRECISION = 40; function removeTrailingZeros(mantissa, exponent) { if (mantissa === 0n) return [0n, 0]; while (mantissa % 10n === 0n) { mantissa /= 10n; exponent++; } return [mantissa, exponent]; } function bigintAbs(n) { return n < 0n ? -n : n; } function digitCount(n) { if (n === 0n) return 1; if (n < 0n) n = -n; let count = 0; const big15 = 1000000000000000n; while (n >= big15) { n /= big15; count += 15; } let r = Number(n); while (r >= 1) { r /= 10; count++; } return count; } const TEN_BIGINT = 10n; function bigintPow10(n) { if (n <= 0) return 1n; let result = 1n; let base = TEN_BIGINT; let exp = n; while (exp > 0) { if (exp & 1) result *= base; base *= base; exp >>= 1; } return result; } function parseDecimalString(s) { s = s.trim(); if (s === "NaN") return { mantissa: 0n, exponent: 0, special: 1, negativeZero: false }; if (s === "Infinity" || s === "+Infinity") return { mantissa: 0n, exponent: 0, special: 2, negativeZero: false }; if (s === "-Infinity") return { mantissa: 0n, exponent: 0, special: 3, negativeZero: false }; let negative = false; let idx = 0; if (s[idx] === "-") { negative = true; idx++; } else if (s[idx] === "+") idx++; let eIdx = s.indexOf("e", idx); if (eIdx === -1) eIdx = s.indexOf("E", idx); let sciExp = 0; let numPart; if (eIdx !== -1) { sciExp = parseInt(s.substring(eIdx + 1), 10); numPart = s.substring(idx, eIdx); } else numPart = s.substring(idx); const dotIdx = numPart.indexOf("."); let intPart; let fracPart; if (dotIdx !== -1) { intPart = numPart.substring(0, dotIdx); fracPart = numPart.substring(dotIdx + 1); } else { intPart = numPart; fracPart = ""; } const combined = intPart + fracPart; const exponent = sciExp - fracPart.length; if (combined === "" || combined === "0" || /^0+$/.test(combined)) return { mantissa: 0n, exponent: 0, special: 0, negativeZero: negative }; let mantissa = BigInt(combined); if (negative) mantissa = -mantissa; const [normMantissa, normExponent] = removeTrailingZeros(mantissa, exponent); return { mantissa: normMantissa, exponent: normExponent, special: 0, negativeZero: false }; } var BigDecimal = class BigDecimal { constructor(value) { if (typeof value === "bigint") { const [m, e] = removeTrailingZeros(value, 0); this._mantissa = m; this._exponent = e; this._special = 0; this._negativeZero = false; return; } if (typeof value === "number") { if (Number.isNaN(value)) { this._mantissa = 0n; this._exponent = 0; this._special = 1; this._negativeZero = false; return; } if (value === Infinity) { this._mantissa = 0n; this._exponent = 0; this._special = 2; this._negativeZero = false; return; } if (value === -Infinity) { this._mantissa = 0n; this._exponent = 0; this._special = 3; this._negativeZero = false; return; } if (value === 0) { this._mantissa = 0n; this._exponent = 0; this._special = 0; this._negativeZero = Object.is(value, -0); return; } value = String(value); } const parsed = parseDecimalString(value); this._mantissa = parsed.mantissa; this._exponent = parsed.exponent; this._special = parsed.special; this._negativeZero = parsed.negativeZero; } static _create(mantissa, exponent, special, negativeZero) { const bd = Object.create(BigDecimal.prototype); bd._mantissa = mantissa; bd._exponent = exponent; bd._special = special; bd._negativeZero = negativeZero; return bd; } static _coerce(v) { return v instanceof BigDecimal ? v : new BigDecimal(v); } times(y) { const other = BigDecimal._coerce(y); if (this._special || other._special) return this._specialArith(other, "times"); if (this._mantissa === 0n || other._mantissa === 0n) { const negZero = this._isSignNegative() ? !other._isSignNegative() : other._isSignNegative(); return BigDecimal._create(0n, 0, 0, negZero); } const [nm, ne] = removeTrailingZeros(this._mantissa * other._mantissa, this._exponent + other._exponent); return BigDecimal._create(nm, ne, 0, false); } div(y) { const other = BigDecimal._coerce(y); if (this._special || other._special) return this._specialArith(other, "div"); if (other._mantissa === 0n) { if (this._mantissa === 0n) return BigDecimal._create(0n, 0, 1, false); const neg = this._isSignNegative() !== other._isSignNegative(); return BigDecimal._create(0n, 0, neg ? 3 : 2, false); } if (this._mantissa === 0n) { const negZero = this._isSignNegative() !== other._isSignNegative(); return BigDecimal._create(0n, 0, 0, negZero); } const [nm, ne] = removeTrailingZeros(this._mantissa * bigintPow10(DIV_PRECISION) / other._mantissa, this._exponent - other._exponent - DIV_PRECISION); return BigDecimal._create(nm, ne, 0, false); } plus(y) { const other = BigDecimal._coerce(y); if (this._special || other._special) return this._specialArith(other, "plus"); if (this._mantissa === 0n && other._mantissa === 0n) { const negZero = this._negativeZero && other._negativeZero; return BigDecimal._create(0n, 0, 0, negZero); } if (this._mantissa === 0n) return other; if (other._mantissa === 0n) return this; let m1 = this._mantissa; let m2 = other._mantissa; const e1 = this._exponent; const e2 = other._exponent; const minE = Math.min(e1, e2); if (e1 > minE) m1 *= bigintPow10(e1 - minE); if (e2 > minE) m2 *= bigintPow10(e2 - minE); const sum = m1 + m2; if (sum === 0n) return BigDecimal._create(0n, 0, 0, false); const [nm, ne] = removeTrailingZeros(sum, minE); return BigDecimal._create(nm, ne, 0, false); } minus(y) { return this.plus(BigDecimal._coerce(y).negated()); } mod(y) { const other = BigDecimal._coerce(y); if (this._special || other._special) { if (this._special === 1 || other._special === 1) return BigDecimal._create(0n, 0, 1, false); if (this._special === 2 || this._special === 3) return BigDecimal._create(0n, 0, 1, false); if (other._special === 2 || other._special === 3) return this; } if (other._mantissa === 0n) return BigDecimal._create(0n, 0, 1, false); if (this._mantissa === 0n) return this; let m1 = this._mantissa; let m2 = other._mantissa; const e1 = this._exponent; const e2 = other._exponent; const minE = Math.min(e1, e2); if (e1 > minE) m1 *= bigintPow10(e1 - minE); if (e2 > minE) m2 *= bigintPow10(e2 - minE); const remainder = m1 % m2; if (remainder === 0n) return BigDecimal._create(0n, 0, 0, false); const [nm, ne] = removeTrailingZeros(remainder, minE); return BigDecimal._create(nm, ne, 0, false); } abs() { if (this._special === 1) return this; if (this._special === 3) return BigDecimal._create(0n, 0, 2, false); return BigDecimal._create(bigintAbs(this._mantissa), this._exponent, this._special, false); } negated() { if (this._special === 1) return this; if (this._special === 2) return BigDecimal._create(0n, 0, 3, false); if (this._special === 3) return BigDecimal._create(0n, 0, 2, false); if (this._mantissa === 0n) return BigDecimal._create(0n, 0, 0, !this._negativeZero); return BigDecimal._create(-this._mantissa, this._exponent, 0, false); } pow(n) { if (this._special === 1) return this; if (n === 0) return new BigDecimal(1); if (n < 0) return new BigDecimal(1).div(this.pow(-n)); if (this._special === 2) return this; if (this._special === 3) return n % 2 === 0 ? BigDecimal._create(0n, 0, 2, false) : this; if (this._mantissa === 0n) return new BigDecimal(0); const [nm, ne] = removeTrailingZeros(this._mantissa ** BigInt(n), this._exponent * n); return BigDecimal._create(nm, ne, 0, false); } floor() { if (this._special !== 0) return this; if (this._mantissa === 0n) return this; if (this._exponent >= 0) return this; const divisor = bigintPow10(-this._exponent); const m = this._mantissa; let q = m / divisor; if (m < 0n && m % divisor !== 0n) q -= 1n; if (q === 0n) { const negZero = this._mantissa < 0n; return BigDecimal._create(0n, 0, 0, negZero); } const [nm, ne] = removeTrailingZeros(q, 0); return BigDecimal._create(nm, ne, 0, false); } ceil() { if (this._special !== 0) return this; if (this._mantissa === 0n) return this; if (this._exponent >= 0) return this; const divisor = bigintPow10(-this._exponent); const m = this._mantissa; let q = m / divisor; if (m > 0n && m % divisor !== 0n) q += 1n; if (q === 0n) return BigDecimal._create(0n, 0, 0, false); const [nm, ne] = removeTrailingZeros(q, 0); return BigDecimal._create(nm, ne, 0, false); } log(base) { if (this._special === 1) return this; if (this._special === 3) return BigDecimal._create(0n, 0, 1, false); if (this._special === 2) return BigDecimal._create(0n, 0, 2, false); if (this._mantissa < 0n) return BigDecimal._create(0n, 0, 1, false); if (this._mantissa === 0n) return BigDecimal._create(0n, 0, 3, false); if (base === 10) return this._log10(); const log10x = this._log10(); const log10b = new BigDecimal(Math.log10(base)); return log10x.div(log10b); } _log10() { const absMantissa = bigintAbs(this._mantissa); const digits = digitCount(absMantissa); let log10Mantissa; if (digits <= 15) log10Mantissa = Math.log10(Number(absMantissa)); else { const shift = digits - 17; const leading = absMantissa / bigintPow10(shift); log10Mantissa = Math.log10(Number(leading)) + shift; } return new BigDecimal(log10Mantissa + this._exponent); } eq(y) { const other = BigDecimal._coerce(y); if (this._special === 1 || other._special === 1) return false; if (this._special !== other._special) return false; if (this._special !== 0) return true; if (this._mantissa === 0n && other._mantissa === 0n) return true; return this._mantissa === other._mantissa && this._exponent === other._exponent; } _compareTo(other) { if (this._special === 1 || other._special === 1) return NaN; if (this._special === 2) return other._special === 2 ? 0 : 1; if (this._special === 3) return other._special === 3 ? 0 : -1; if (other._special === 2) return -1; if (other._special === 3) return 1; const thisZero = this._mantissa === 0n; const otherZero = other._mantissa === 0n; if (thisZero && otherZero) return 0; if (thisZero) return other._mantissa > 0n ? -1 : 1; if (otherZero) return this._mantissa > 0n ? 1 : -1; const thisNeg = this._mantissa < 0n; if (thisNeg !== other._mantissa < 0n) return thisNeg ? -1 : 1; let m1 = this._mantissa; let m2 = other._mantissa; const e1 = this._exponent; const e2 = other._exponent; const minE = Math.min(e1, e2); if (e1 > minE) m1 *= bigintPow10(e1 - minE); if (e2 > minE) m2 *= bigintPow10(e2 - minE); if (m1 < m2) return -1; if (m1 > m2) return 1; return 0; } lessThan(y) { return this._compareTo(BigDecimal._coerce(y)) === -1; } greaterThan(y) { return this._compareTo(BigDecimal._coerce(y)) === 1; } lessThanOrEqualTo(y) { const c = this._compareTo(BigDecimal._coerce(y)); return c === 0 || c === -1; } greaterThanOrEqualTo(y) { const c = this._compareTo(BigDecimal._coerce(y)); return c === 0 || c === 1; } isZero() { return this._special === 0 && this._mantissa === 0n; } isNaN() { return this._special === 1; } isFinite() { return this._special === 0; } isNegative() { if (this._special === 1) return false; if (this._special === 3) return true; if (this._special === 2) return false; if (this._mantissa === 0n) return this._negativeZero; return this._mantissa < 0n; } isPositive() { if (this._special === 1) return false; if (this._special === 2) return true; if (this._special === 3) return false; if (this._mantissa === 0n) return !this._negativeZero; return this._mantissa > 0n; } isInteger() { if (this._special !== 0) return false; if (this._mantissa === 0n) return true; return this._exponent >= 0; } toJSON() { return this.toString(); } toNumber() { if (this._special === 1) return NaN; if (this._special === 2) return Infinity; if (this._special === 3) return -Infinity; if (this._mantissa === 0n) return this._negativeZero ? -0 : 0; return Number(this.toString()); } toString() { if (this._special === 1) return "NaN"; if (this._special === 2) return "Infinity"; if (this._special === 3) return "-Infinity"; if (this._mantissa === 0n) return "0"; const negative = this._mantissa < 0n; const absStr = bigintAbs(this._mantissa).toString(); const prefix = negative ? "-" : ""; if (this._exponent === 0) return prefix + absStr; if (this._exponent > 0) return prefix + absStr + "0".repeat(this._exponent); const decimalPlaces = -this._exponent; if (decimalPlaces < absStr.length) { const intPart = absStr.slice(0, absStr.length - decimalPlaces); const fracPart = absStr.slice(absStr.length - decimalPlaces); return prefix + intPart + "." + fracPart; } else { const leadingZeros = decimalPlaces - absStr.length; return prefix + "0." + "0".repeat(leadingZeros) + absStr; } } static pow(base, exp) { const n = typeof exp === "number" ? exp : exp.toNumber(); if (typeof base === "number" && base === 10) return BigDecimal._create(1n, n, 0, false); return (base instanceof BigDecimal ? base : new BigDecimal(base)).pow(n); } static set(_config) {} _isSignNegative() { if (this._special === 3) return true; if (this._mantissa < 0n) return true; if (this._mantissa === 0n) return this._negativeZero; return false; } _specialArith(other, op) { const a = this._special; const b = other._special; if (a === 1 || b === 1) return BigDecimal._create(0n, 0, 1, false); const aNeg = this._isSignNegative(); const bNeg = other._isSignNegative(); const aInf = a === 2 || a === 3; const bInf = b === 2 || b === 3; if (op === "times") { if (aInf || bInf) { if (aInf && other._mantissa === 0n && !bInf || bInf && this._mantissa === 0n && !aInf) return BigDecimal._create(0n, 0, 1, false); const neg = aNeg !== bNeg; return BigDecimal._create(0n, 0, neg ? 3 : 2, false); } } if (op === "div") { if (aInf && bInf) return BigDecimal._create(0n, 0, 1, false); if (aInf) { const neg = aNeg !== bNeg; return BigDecimal._create(0n, 0, neg ? 3 : 2, false); } if (bInf) { const negZero = aNeg !== bNeg; return BigDecimal._create(0n, 0, 0, negZero); } } if (op === "plus") { if (aInf && bInf) { if (aNeg !== bNeg) return BigDecimal._create(0n, 0, 1, false); return this; } if (aInf) return this; if (bInf) return other; } return BigDecimal._create(0n, 0, 1, false); } }; //#endregion //#region packages/ecma402-abstract/NumberFormat/decimal-cache.js /** * Cached function to compute powers of 10 for Decimal.js operations. * This cache significantly reduces overhead in ComputeExponent and ToRawFixed * by memoizing expensive Decimal.pow(10, n) calculations. * * Common exponents (e.g., -20 to 20) are used repeatedly in number formatting, * so caching provides substantial performance benefits. * * @param exponent - Can be a number or Decimal. If Decimal, it will be converted to string for cache key. */ const getPowerOf10 = memoize((exponent) => { return BigDecimal.pow(10, exponent); }); //#endregion //#region packages/ecma402-abstract/NumberFormat/ComputeExponentForMagnitude.js /** * The abstract operation ComputeExponentForMagnitude computes an exponent by which to scale a * number of the given magnitude (power of ten of the most significant digit) according to the * locale and the desired notation (scientific, engineering, or compact). */ function ComputeExponentForMagnitude(internalSlots, magnitude) { const { notation, dataLocaleData, numberingSystem } = internalSlots; switch (notation) { case "standard": return 0; case "scientific": return magnitude.toNumber(); case "engineering": return magnitude.div(3).floor().times(3).toNumber(); default: { invariant$2(notation === "compact", "Invalid notation"); const { compactDisplay, style, currencyDisplay } = internalSlots; let thresholdMap; if (style === "currency" && currencyDisplay !== "name") thresholdMap = (dataLocaleData.numbers.currency[numberingSystem] || dataLocaleData.numbers.currency[dataLocaleData.numbers.nu[0]]).short; else { const decimal = dataLocaleData.numbers.decimal[numberingSystem] || dataLocaleData.numbers.decimal[dataLocaleData.numbers.nu[0]]; thresholdMap = compactDisplay === "long" ? decimal.long : decimal.short; } if (!thresholdMap) return 0; const num = getPowerOf10(magnitude).toString(); const thresholds = Object.keys(thresholdMap); if (num < thresholds[0]) return 0; if (num > thresholds[thresholds.length - 1]) { const magnitudeKey = thresholds[thresholds.length - 1]; if (thresholdMap[magnitudeKey].other === "0") return 0; return magnitudeKey.length - thresholdMap[magnitudeKey].other.match(/0+/)[0].length; } const i = thresholds.indexOf(num); if (i === -1) return 0; const magnitudeKey = thresholds[i]; if (thresholdMap[magnitudeKey].other === "0") return 0; return magnitudeKey.length - thresholdMap[magnitudeKey].other.match(/0+/)[0].length; } } } //#endregion //#region packages/ecma402-abstract/constants.js const ZERO = new BigDecimal(0); const NEGATIVE_ZERO = new BigDecimal(-0); //#endregion //#region packages/ecma402-abstract/NumberFormat/GetUnsignedRoundingMode.js const negativeMapping = { ceil: "zero", floor: "infinity", expand: "infinity", trunc: "zero", halfCeil: "half-zero", halfFloor: "half-infinity", halfExpand: "half-infinity", halfTrunc: "half-zero", halfEven: "half-even" }; const positiveMapping = { ceil: "infinity", floor: "zero", expand: "infinity", trunc: "zero", halfCeil: "half-infinity", halfFloor: "half-zero", halfExpand: "half-infinity", halfTrunc: "half-zero", halfEven: "half-even" }; function GetUnsignedRoundingMode(roundingMode, isNegative) { if (isNegative) return negativeMapping[roundingMode]; return positiveMapping[roundingMode]; } //#endregion //#region packages/ecma402-abstract/NumberFormat/ApplyUnsignedRoundingMode.js function ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode) { if (x.eq(r1) || r1.eq(r2)) return r1; if (x.eq(r2)) return r2; invariant$2(r1.lessThan(x) && x.lessThan(r2), `x should be between r1 and r2 but x=${x}, r1=${r1}, r2=${r2}`); if (unsignedRoundingMode === "zero") return r1; if (unsignedRoundingMode === "infinity") return r2; const d1 = x.minus(r1); const d2 = r2.minus(x); if (d1.lessThan(d2)) return r1; if (d2.lessThan(d1)) return r2; invariant$2(d1.eq(d2), "d1 should be equal to d2"); if (unsignedRoundingMode === "half-zero") return r1; if (unsignedRoundingMode === "half-infinity") return r2; invariant$2(unsignedRoundingMode === "half-even", "unsignedRoundingMode should be half-even"); if (r1.div(r2.minus(r1)).mod(2).isZero()) return r1; return r2; } //#endregion //#region packages/ecma402-abstract/NumberFormat/ToRawFixed.js function ToRawFixedFn(n, f) { return n.times(getPowerOf10(-f)); } function findN1R1(x, f, roundingIncrement) { const n1 = x.times(getPowerOf10(f)).floor().div(roundingIncrement).floor().times(roundingIncrement); return { n1, r1: ToRawFixedFn(n1, f) }; } function findN2R2(x, f, roundingIncrement) { const n2 = x.times(getPowerOf10(f)).ceil().div(roundingIncrement).ceil().times(roundingIncrement); return { n2, r2: ToRawFixedFn(n2, f) }; } /** * https://tc39.es/ecma402/#sec-torawfixed * @param x a finite non-negative Number or BigInt * @param minFraction an integer between 0 and 20 * @param maxFraction an integer between 0 and 20 */ function ToRawFixed(x, minFraction, maxFraction, roundingIncrement, unsignedRoundingMode) { const f = maxFraction; const { n1, r1 } = findN1R1(x, f, roundingIncrement); const { n2, r2 } = findN2R2(x, f, roundingIncrement); const r = ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode); let n, xFinal; let m; if (r.eq(r1)) { n = n1; xFinal = r1; } else { n = n2; xFinal = r2; } if (n.isZero()) m = "0"; else m = n.toString(); let int; if (f !== 0) { let k = m.length; if (k <= f) { m = repeat("0", f - k + 1) + m; k = f + 1; } const a = m.slice(0, k - f); const b = m.slice(m.length - f); m = a + "." + b; int = a.length; } else int = m.length; let cut = maxFraction - minFraction; while (cut > 0 && m[m.length - 1] === "0") { m = m.slice(0, m.length - 1); cut--; } if (m[m.length - 1] === ".") m = m.slice(0, m.length - 1); return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int, roundingMagnitude: -f }; } //#endregion //#region packages/ecma402-abstract/NumberFormat/ToRawPrecision.js function findN1E1R1(x, p) { const maxN1 = getPowerOf10(p); const minN1 = getPowerOf10(p - 1); let e1 = x.log(10).floor(); const divisor = getPowerOf10(e1.minus(p).plus(1)); let n1 = x.div(divisor).floor(); let r1 = n1.times(divisor); if (n1.greaterThanOrEqualTo(maxN1)) { e1 = e1.plus(1); const newDivisor = getPowerOf10(e1.minus(p).plus(1)); n1 = x.div(newDivisor).floor(); r1 = n1.times(newDivisor); } else if (n1.lessThan(minN1)) { e1 = e1.minus(1); const newDivisor = getPowerOf10(e1.minus(p).plus(1)); n1 = x.div(newDivisor).floor(); r1 = n1.times(newDivisor); } if (r1.lessThanOrEqualTo(x) && n1.lessThan(maxN1) && n1.greaterThanOrEqualTo(minN1)) return { n1, e1, r1 }; let currentE1 = x.div(minN1).log(10).plus(p).minus(1).ceil(); while (true) { const currentDivisor = getPowerOf10(currentE1.minus(p).plus(1)); let currentN1 = x.div(currentDivisor).floor(); if (currentN1.lessThan(maxN1) && currentN1.greaterThanOrEqualTo(minN1)) { const currentR1 = currentN1.times(currentDivisor); if (currentR1.lessThanOrEqualTo(x)) return { n1: currentN1, e1: currentE1, r1: currentR1 }; } currentE1 = currentE1.minus(1); } } function findN2E2R2(x, p) { const maxN2 = getPowerOf10(p); const minN2 = getPowerOf10(p - 1); let e2 = x.log(10).floor(); const divisor = getPowerOf10(e2.minus(p).plus(1)); let n2 = x.div(divisor).ceil(); let r2 = n2.times(divisor); if (n2.greaterThanOrEqualTo(maxN2)) { e2 = e2.plus(1); const newDivisor = getPowerOf10(e2.minus(p).plus(1)); n2 = x.div(newDivisor).ceil(); r2 = n2.times(newDivisor); } else if (n2.lessThan(minN2)) { e2 = e2.minus(1); const newDivisor = getPowerOf10(e2.minus(p).plus(1)); n2 = x.div(newDivisor).ceil(); r2 = n2.times(newDivisor); } if (r2.greaterThanOrEqualTo(x) && n2.lessThan(maxN2) && n2.greaterThanOrEqualTo(minN2)) return { n2, e2, r2 }; let currentE2 = x.div(maxN2).log(10).plus(p).minus(1).floor(); while (true) { const currentDivisor = getPowerOf10(currentE2.minus(p).plus(1)); let currentN2 = x.div(currentDivisor).ceil(); if (currentN2.lessThan(maxN2) && currentN2.greaterThanOrEqualTo(minN2)) { const currentR2 = currentN2.times(currentDivisor); if (currentR2.greaterThanOrEqualTo(x)) return { n2: currentN2, e2: currentE2, r2: currentR2 }; } currentE2 = currentE2.plus(1); } } /** * https://tc39.es/ecma402/#sec-torawprecision * @param x a finite non-negative Number or BigInt * @param minPrecision an integer between 1 and 21 * @param maxPrecision an integer between 1 and 21 */ function ToRawPrecision(x, minPrecision, maxPrecision, unsignedRoundingMode) { const p = maxPrecision; let m; let e; let xFinal; if (x.isZero()) { m = repeat("0", p); e = 0; xFinal = ZERO; } else { const { n1, e1, r1 } = findN1E1R1(x, p); const { n2, e2, r2 } = findN2E2R2(x, p); let r = ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode); let n; if (r.eq(r1)) { n = n1; e = e1.toNumber(); xFinal = r1; } else { n = n2; e = e2.toNumber(); xFinal = r2; } m = n.toString(); } let int; if (e >= p - 1) { m = m + repeat("0", e - p + 1); int = e + 1; } else if (e >= 0) { m = m.slice(0, e + 1) + "." + m.slice(m.length - (p - (e + 1))); int = e + 1; } else { invariant$2(e < 0, "e should be less than 0"); m = "0." + repeat("0", -e - 1) + m; int = 1; } if (m.includes(".") && maxPrecision > minPrecision) { let cut = maxPrecision - minPrecision; while (cut > 0 && m[m.length - 1] === "0") { m = m.slice(0, m.length - 1); cut--; } if (m[m.length - 1] === ".") m = m.slice(0, m.length - 1); } return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int, roundingMagnitude: e }; } //#endregion //#region packages/ecma402-abstract/NumberFormat/FormatNumericToString.js /** * https://tc39.es/ecma402/#sec-formatnumberstring */ function FormatNumericToString(intlObject, _x) { let x = _x; let sign; if (x.isZero() && x.isNegative()) { sign = "negative"; x = ZERO; } else { invariant$2(x.isFinite(), "NumberFormatDigitInternalSlots value is not finite"); if (x.lessThan(0)) sign = "negative"; else sign = "positive"; if (sign === "negative") x = x.negated(); } let result; const roundingType = intlObject.roundingType; const unsignedRoundingMode = GetUnsignedRoundingMode(intlObject.roundingMode, sign === "negative"); switch (roundingType) { case "significantDigits": result = ToRawPrecision(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits, unsignedRoundingMode); break; case "fractionDigits": result = ToRawFixed(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits, intlObject.roundingIncrement, unsignedRoundingMode); break; default: let sResult = ToRawPrecision(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits, unsignedRoundingMode); let fResult = ToRawFixed(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits, intlObject.roundingIncrement, unsignedRoundingMode); if (intlObject.roundingType === "morePrecision") if (sResult.roundingMagnitude <= fResult.roundingMagnitude) result = sResult; else result = fResult; else { invariant$2(intlObject.roundingType === "lessPrecision", "Invalid roundingType"); if (sResult.roundingMagnitude <= fResult.roundingMagnitude) result = fResult; else result = sResult; } break; } x = result.roundedNumber; let string = result.formattedString; if (intlObject.trailingZeroDisplay === "stripIfInteger" && x.isInteger()) { let i = string.indexOf("."); if (i > -1) string = string.slice(0, i); } const int = result.integerDigitsCount; const minInteger = intlObject.minimumIntegerDigits; if (int < minInteger) string = repeat("0", minInteger - int) + string; if (sign === "negative") if (x.isZero()) x = NEGATIVE_ZERO; else x = x.negated(); return { roundedNumber: x, formattedString: string }; } //#endregion //#region packages/ecma402-abstract/NumberFormat/ComputeExponent.js /** * The abstract operation ComputeExponent computes an exponent (power of ten) by which to scale x * according to the number formatting settings. It handles cases such as 999 rounding up to 1000, * requiring a different exponent. * * NOT IN SPEC: it returns [exponent, magnitude]. */ function ComputeExponent(internalSlots, x) { if (x.isZero()) return [0, 0]; if (x.isNegative()) x = x.negated(); const xNum = x.toNumber(); let magnitude; if (Number.isFinite(xNum) && Number.isSafeInteger(xNum) && xNum > 0 && xNum <= 999999) magnitude = new BigDecimal(Math.floor(Math.log10(xNum))); else magnitude = x.log(10).floor(); const exponent = ComputeExponentForMagnitude(internalSlots, magnitude); x = x.times(getPowerOf10(-exponent)); const formatNumberResult = FormatNumericToString(internalSlots, x); if (formatNumberResult.roundedNumber.isZero()) return [exponent, magnitude.toNumber()]; const roundedNum = formatNumberResult.roundedNumber.toNumber(); let newMagnitude; if (Number.isFinite(roundedNum) && Number.isSafeInteger(roundedNum) && roundedNum > 0 && roundedNum <= 999999) newMagnitude = new BigDecimal(Math.floor(Math.log10(roundedNum))); else newMagnitude = formatNumberResult.roundedNumber.log(10).floor(); if (newMagnitude.eq(magnitude.minus(exponent))) return [exponent, magnitude.toNumber()]; return [ComputeExponentForMagnitude(internalSlots, magnitude.plus(1)), magnitude.plus(1).toNumber()]; } //#endregion //#region node_modules/.aspect_rules_js/@formatjs_generated+unicode@0.0.0/node_modules/@formatjs_generated/unicode/regex.js const S_UNICODE_REGEX = /[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C1\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2429\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E5\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD803[\uDD8E\uDD8F\uDED1-\uDED8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDC00-\uDCEF\uDCFA-\uDCFC\uDD00-\uDEB3\uDEBA-\uDED0\uDEE0-\uDEF0\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED8\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0-\uDCBB\uDCC0\uDCC1\uDCD0-\uDCD8\uDD00-\uDE57\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF-\uDEF8\uDF00-\uDF92\uDF94-\uDFEF\uDFFA]/; //#endregion //#region node_modules/.aspect_rules_js/@formatjs_generated+unicode@0.0.0/node_modules/@formatjs_generated/unicode/digit-mapping.js const digitMapping = { "adlm": [ "𞥐", "𞥑", "𞥒", "𞥓", "𞥔", "𞥕", "𞥖", "𞥗", "𞥘", "𞥙" ], "ahom": [ "𑜰", "𑜱", "𑜲", "𑜳", "𑜴", "𑜵", "𑜶", "𑜷", "𑜸", "𑜹" ], "arab": [ "٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩" ], "arabext": [ "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" ], "bali": [ "᭐", "᭑", "᭒", "᭓", "᭔", "᭕", "᭖", "᭗", "᭘", "᭙" ], "beng": [ "০", "১", "২", "৩", "৪", "৫", "৬", "৭", "৮", "৯" ], "bhks": [ "𑱐", "𑱑", "𑱒", "𑱓", "𑱔", "𑱕", "𑱖", "𑱗", "𑱘", "𑱙" ], "brah": [ "𑁦", "𑁧", "𑁨", "𑁩", "𑁪", "𑁫", "𑁬", "𑁭", "𑁮", "𑁯" ], "cakm": [ "𑄶", "𑄷", "𑄸", "𑄹", "𑄺", "𑄻", "𑄼", "𑄽", "𑄾", "𑄿" ], "cham": [ "꩐", "꩑", "꩒", "꩓", "꩔", "꩕", "꩖", "꩗", "꩘", "꩙" ], "deva": [ "०", "१", "२", "३", "४", "५", "६", "७", "८", "९" ], "diak": [ "𑥐", "𑥑", "𑥒", "𑥓", "𑥔", "𑥕", "𑥖", "𑥗", "𑥘", "𑥙" ], "fullwide": [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ], "gong": [ "𑶠", "𑶡", "𑶢", "𑶣", "𑶤", "𑶥", "𑶦", "𑶧", "𑶨", "𑶩" ], "gonm": [ "𑵐", "𑵑", "𑵒", "𑵓", "𑵔", "𑵕", "𑵖", "𑵗", "𑵘", "𑵙" ], "gujr": [ "૦", "૧", "૨", "૩", "૪", "૫", "૬", "૭", "૮", "૯" ], "guru": [ "੦", "੧", "੨", "੩", "੪", "੫", "੬", "੭", "੮", "੯" ], "hanidec": [ "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" ], "hmng": [ "𖭐", "𖭑", "𖭒", "𖭓", "𖭔", "𖭕", "𖭖", "𖭗", "𖭘", "𖭙" ], "hmnp": [ "𞅀", "𞅁", "𞅂", "𞅃", "𞅄", "𞅅", "𞅆", "𞅇", "𞅈", "𞅉" ], "java": [ "꧐", "꧑", "꧒", "꧓", "꧔", "꧕", "꧖", "꧗", "꧘", "꧙" ], "kali": [ "꤀", "꤁", "꤂", "꤃", "꤄", "꤅", "꤆", "꤇", "꤈", "꤉" ], "khmr": [ "០", "១", "២", "៣", "៤", "៥", "៦", "៧", "៨", "៩" ], "knda": [ "೦", "೧", "೨", "೩", "೪", "೫", "೬", "೭", "೮", "೯" ], "lana": [ "᪀", "᪁", "᪂", "᪃", "᪄", "᪅", "᪆", "᪇", "᪈", "᪉" ], "lanatham": [ "᪐", "᪑", "᪒", "᪓", "᪔", "᪕", "᪖", "᪗", "᪘", "᪙" ], "laoo": [ "໐", "໑", "໒", "໓", "໔", "໕", "໖", "໗", "໘", "໙" ], "lepc": [ "᪐", "᪑", "᪒", "᪓", "᪔", "᪕", "᪖", "᪗", "᪘", "᪙" ], "limb": [ "᥆", "᥇", "᥈", "᥉", "᥊", "᥋", "᥌", "᥍", "᥎", "᥏" ], "mathbold": [ "𝟎", "𝟏", "𝟐", "𝟑", "𝟒", "𝟓", "𝟔", "𝟕", "𝟖", "𝟗" ], "mathdbl": [ "𝟘", "𝟙", "𝟚", "𝟛", "𝟜", "𝟝", "𝟞", "𝟟", "𝟠", "𝟡" ], "mathmono": [ "𝟶", "𝟷", "𝟸", "𝟹", "𝟺", "𝟻", "𝟼", "𝟽", "𝟾", "𝟿" ], "mathsanb": [ "𝟬", "𝟭", "𝟮", "𝟯", "𝟰", "𝟱", "𝟲", "𝟳", "𝟴", "𝟵" ], "mathsans": [ "𝟢", "𝟣", "𝟤", "𝟥", "𝟦", "𝟧", "𝟨", "𝟩", "𝟪", "𝟫" ], "mlym": [ "൦", "൧", "൨", "൩", "൪", "൫", "൬", "൭", "൮", "൯" ], "modi": [ "𑙐", "𑙑", "𑙒", "𑙓", "𑙔", "𑙕", "𑙖", "𑙗", "𑙘", "𑙙" ], "mong": [ "᠐", "᠑", "᠒", "᠓", "᠔", "᠕", "᠖", "᠗", "᠘", "᠙" ], "mroo": [ "𖩠", "𖩡", "𖩢", "𖩣", "𖩤", "𖩥", "𖩦", "𖩧", "𖩨", "𖩩" ], "mtei": [ "꯰", "꯱", "꯲", "꯳", "꯴", "꯵", "꯶", "꯷", "꯸", "꯹" ], "mymr": [ "၀", "၁", "၂", "၃", "၄", "၅", "၆", "၇", "၈", "၉" ], "mymrshan": [ "႐", "႑", "႒", "႓", "႔", "႕", "႖", "႗", "႘", "႙" ], "mymrtlng": [ "꧰", "꧱", "꧲", "꧳", "꧴", "꧵", "꧶", "꧷", "꧸", "꧹" ], "newa": [ "𑑐", "𑑑", "𑑒", "𑑓", "𑑔", "𑑕", "𑑖", "𑑗", "𑑘", "𑑙" ], "nkoo": [ "߀", "߁", "߂", "߃", "߄", "߅", "߆", "߇", "߈", "߉" ], "olck": [ "᱐", "᱑", "᱒", "᱓", "᱔", "᱕", "᱖", "᱗", "᱘", "᱙" ], "orya": [ "୦", "୧", "୨", "୩", "୪", "୫", "୬", "୭", "୮", "୯" ], "osma": [ "𐒠", "𐒡", "𐒢", "𐒣", "𐒤", "𐒥", "𐒦", "𐒧", "𐒨", "𐒩" ], "rohg": [ "𐴰", "𐴱", "𐴲", "𐴳", "𐴴", "𐴵", "𐴶", "𐴷", "𐴸", "𐴹" ], "saur": [ "꣐", "꣑", "꣒", "꣓", "꣔", "꣕", "꣖", "꣗", "꣘", "꣙" ], "segment": [ "🯰", "🯱", "🯲", "🯳", "🯴", "🯵", "🯶", "🯷", "🯸", "🯹" ], "shrd": [ "𑇐", "𑇑", "𑇒", "𑇓", "𑇔", "𑇕", "𑇖", "𑇗", "𑇘", "𑇙" ], "sind": [ "𑋰", "𑋱", "𑋲", "𑋳", "𑋴", "𑋵", "𑋶", "𑋷", "𑋸", "𑋹" ], "sinh": [ "෦", "෧", "෨", "෩", "෪", "෫", "෬", "෭", "෮", "෯" ], "sora": [ "𑃰", "𑃱", "𑃲", "𑃳", "𑃴", "𑃵", "𑃶", "𑃷", "𑃸", "𑃹" ], "sund": [ "᮰", "᮱", "᮲", "᮳", "᮴", "᮵", "᮶", "᮷", "᮸", "᮹" ], "takr": [ "𑛀", "𑛁", "𑛂", "𑛃", "𑛄", "𑛅", "𑛆", "𑛇", "𑛈", "𑛉" ], "talu": [ "᧐", "᧑", "᧒", "᧓", "᧔", "᧕", "᧖", "᧗", "᧘", "᧙" ], "tamldec": [ "௦", "௧", "௨", "௩", "௪", "௫", "௬", "௭", "௮", "௯" ], "telu": [ "౦", "౧", "౨", "౩", "౪", "౫", "౬", "౭", "౮", "౯" ], "thai": [ "๐", "๑", "๒", "๓", "๔", "๕", "๖", "๗", "๘", "๙" ], "tibt": [ "༠", "༡", "༢", "༣", "༤", "༥", "༦", "༧", "༨", "༩" ], "tirh": [ "𑓐", "𑓑", "𑓒", "𑓓", "𑓔", "𑓕", "𑓖", "𑓗", "𑓘", "𑓙" ], "vaii": [ "ᘠ", "ᘡ", "ᘢ", "ᘣ", "ᘤ", "ᘥ", "ᘦ", "ᘧ", "ᘨ", "ᘩ" ], "wara": [ "𑣠", "𑣡", "𑣢", "𑣣", "𑣤", "𑣥", "𑣦", "𑣧", "𑣨", "𑣩" ], "wcho": [ "𞋰", "𞋱", "𞋲", "𞋳", "𞋴", "𞋵", "𞋶", "𞋷", "𞋸", "𞋹" ] }; //#endregion //#region packages/ecma402-abstract/NumberFormat/format_to_parts.js const CARET_S_UNICODE_REGEX = new RegExp(`^${S_UNICODE_REGEX.source}`); const S_DOLLAR_UNICODE_REGEX = new RegExp(`${S_UNICODE_REGEX.source}$`); const CLDR_NUMBER_PATTERN = /[#0](?:[.,][#0]+)*/g; function formatToParts$1(numberResult, data, pl, options) { const { sign, exponent, magnitude } = numberResult; const { notation, style, numberingSystem } = options; const defaultNumberingSystem = data.numbers.nu[0]; let compactNumberPattern = null; if (notation === "compact" && magnitude) compactNumberPattern = getCompactDisplayPattern(numberResult, pl, data, style, options.compactDisplay, options.currencyDisplay, numberingSystem); let nonNameCurrencyPart; if (style === "currency" && options.currencyDisplay !== "name") { const byCurrencyDisplay = data.currencies[options.currency]; if (byCurrencyDisplay) switch (options.currencyDisplay) { case "code": nonNameCurrencyPart = options.currency; break; case "symbol": nonNameCurrencyPart = byCurrencyDisplay.symbol; break; default: nonNameCurrencyPart = byCurrencyDisplay.narrow; break; } else nonNameCurrencyPart = options.currency; } let numberPattern; if (!compactNumberPattern) if (style === "decimal" || style === "unit" || style === "currency" && options.currencyDisplay === "name") numberPattern = getPatternForSign((data.numbers.decimal[numberingSystem] || data.numbers.decimal[defaultNumberingSystem]).standard, sign); else if (style === "currency") numberPattern = getPatternForSign((data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem])[options.currencySign], sign); else numberPattern = getPatternForSign(data.numbers.percent[numberingSystem] || data.numbers.percent[defaultNumberingSystem], sign); else numberPattern = compactNumberPattern; const decimalNumberPattern = CLDR_NUMBER_PATTERN.exec(numberPattern)[0]; numberPattern = numberPattern.replace(CLDR_NUMBER_PATTERN, "{0}").replace(/'(.)'/g, "$1"); if (style === "currency" && options.currencyDisplay !== "name") { const currencyData = data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]; const afterCurrency = currencyData.currencySpacing.afterInsertBetween; if (afterCurrency && !S_DOLLAR_UNICODE_REGEX.test(nonNameCurrencyPart)) numberPattern = numberPattern.replace("¤{0}", `¤${afterCurrency}{0}`); const beforeCurrency = currencyData.currencySpacing.beforeInsertBetween; if (beforeCurrency && !CARET_S_UNICODE_REGEX.test(nonNameCurrencyPart)) numberPattern = numberPattern.replace("{0}¤", `{0}${beforeCurrency}¤`); } const numberPatternParts = numberPattern.split(/({c:[^}]+}|\{0\}|[¤%\-+])/g); const numberParts = []; const symbols = data.numbers.symbols[numberingSystem] || data.numbers.symbols[defaultNumberingSystem]; for (const part of numberPatternParts) { if (!part) continue; switch (part) { case "{0}": numberParts.push(...partitionNumberIntoParts(symbols, numberResult, notation, exponent, numberingSystem, !compactNumberPattern && (options.useGrouping ?? true), decimalNumberPattern, style, options.roundingIncrement, GetUnsignedRoundingMode(options.roundingMode, sign === -1))); break; case "-": numberParts.push({ type: "minusSign", value: symbols.minusSign }); break; case "+": numberParts.push({ type: "plusSign", value: symbols.plusSign }); break; case "%": numberParts.push({ type: "percentSign", value: symbols.percentSign }); break; case "¤": numberParts.push({ type: "currency", value: nonNameCurrencyPart }); break; default: if (part.startsWith("{c:")) numberParts.push({ type: "compact", value: part.substring(3, part.length - 1) }); else numberParts.push({ type: "literal", value: part }); break; } } switch (style) { case "currency": if (options.currencyDisplay === "name") { const unitPattern = (data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]).unitPattern; let unitName; const currencyNameData = data.currencies[options.currency]; if (currencyNameData) unitName = selectPlural(pl, numberResult.roundedNumber.times(getPowerOf10(exponent)).toNumber(), currencyNameData.displayName); else unitName = options.currency; const unitPatternParts = unitPattern.split(/(\{[01]\})/g); const result = []; for (const part of unitPatternParts) switch (part) { case "{0}": result.push(...numberParts); break; case "{1}": result.push({ type: "currency", value: unitName }); break; default: if (part) result.push({ type: "literal", value: part }); break; } return result; } else return numberParts; case "unit": { const { unit, unitDisplay } = options; let unitData = data.units.simple[unit]; let unitPattern; if (unitData) unitPattern = selectPlural(pl, numberResult.roundedNumber.times(getPowerOf10(exponent)).toNumber(), data.units.simple[unit][unitDisplay]); else { const [numeratorUnit, denominatorUnit] = unit.split("-per-"); unitData = data.units.simple[numeratorUnit]; const numeratorUnitPattern = selectPlural(pl, numberResult.roundedNumber.times(getPowerOf10(exponent)).toNumber(), data.units.simple[numeratorUnit][unitDisplay]); const perUnitPattern = data.units.simple[denominatorUnit].perUnit[unitDisplay]; if (perUnitPattern) unitPattern = perUnitPattern.replace("{0}", numeratorUnitPattern); else { const perPattern = data.units.compound.per[unitDisplay]; const denominatorPattern = selectPlural(pl, 1, data.units.simple[denominatorUnit][unitDisplay]); unitPattern = unitPattern = perPattern.replace("{0}", numeratorUnitPattern).replace("{1}", denominatorPattern.replace("{0}", "")); } } const result = []; for (const part of unitPattern.split(/(\s*\{0\}\s*)/)) { const interpolateMatch = /^(\s*)\{0\}(\s*)$/.exec(part); if (interpolateMatch) { if (interpolateMatch[1]) result.push({ type: "literal", value: interpolateMatch[1] }); result.push(...numberParts); if (interpolateMatch[2]) result.push({ type: "literal", value: interpolateMatch[2] }); } else if (part) result.push({ type: "unit", value: part }); } return result; } default: return numberParts; } } function partitionNumberIntoParts(symbols, numberResult, notation, exponent, numberingSystem, useGrouping, decimalNumberPattern, style, roundingIncrement, unsignedRoundingMode) { const result = []; let { formattedString: n, roundedNumber: x } = numberResult; if (x.isNaN()) return [{ type: "nan", value: n }]; else if (!x.isFinite()) return [{ type: "infinity", value: n }]; const digitReplacementTable = digitMapping[numberingSystem]; if (digitReplacementTable) n = n.replace(/\d/g, (digit) => digitReplacementTable[+digit] || digit); const decimalSepIndex = n.indexOf("."); let integer; let fraction; if (decimalSepIndex > 0) { integer = n.slice(0, decimalSepIndex); fraction = n.slice(decimalSepIndex + 1); } else integer = n; let shouldUseGrouping = false; if (useGrouping === "always") shouldUseGrouping = true; else if (useGrouping === "min2") shouldUseGrouping = x.greaterThanOrEqualTo(1e4); else if (useGrouping === "auto" || useGrouping) shouldUseGrouping = notation !== "compact" || x.greaterThanOrEqualTo(1e4); if (shouldUseGrouping) { const groupSepSymbol = style === "currency" && symbols.currencyGroup != null ? symbols.currencyGroup : symbols.group; const groups = []; const patternGroups = decimalNumberPattern.split(".")[0].split(","); let primaryGroupingSize = 3; let secondaryGroupingSize = 3; if (patternGroups.length > 1) primaryGroupingSize = patternGroups[patternGroups.length - 1].length; if (patternGroups.length > 2) secondaryGroupingSize = patternGroups[patternGroups.length - 2].length; let i = integer.length - primaryGroupingSize; if (i > 0) { groups.push(integer.slice(i, i + primaryGroupingSize)); for (i -= secondaryGroupingSize; i > 0; i -= secondaryGroupingSize) groups.push(integer.slice(i, i + secondaryGroupingSize)); groups.push(integer.slice(0, i + secondaryGroupingSize)); } else groups.push(integer); while (groups.length > 0) { const integerGroup = groups.pop();