deploy: v0.12 fix 存档key名

This commit is contained in:
2026-06-24 03:09:02 +00:00
parent 7a08d49fe3
commit e0a5281119
58743 changed files with 7297269 additions and 39505 deletions
@@ -0,0 +1,3 @@
import Decimal from 'decimal.js';
import { UnsignedRoundingModeType } from '../types/number';
export declare function ApplyUnsignedRoundingMode(x: Decimal, r1: Decimal, r2: Decimal, unsignedRoundingMode: UnsignedRoundingModeType): Decimal;
@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApplyUnsignedRoundingMode = ApplyUnsignedRoundingMode;
var utils_1 = require("../utils");
function ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode) {
if (x.eq(r1))
return r1;
(0, utils_1.invariant)(r1.lessThan(x) && x.lessThan(r2), "x should be between r1 and r2 but x=".concat(x, ", r1=").concat(r1, ", r2=").concat(r2));
if (unsignedRoundingMode === 'zero') {
return r1;
}
if (unsignedRoundingMode === 'infinity') {
return r2;
}
var d1 = x.minus(r1);
var d2 = r2.minus(x);
if (d1.lessThan(d2)) {
return r1;
}
if (d2.lessThan(d1)) {
return r2;
}
(0, utils_1.invariant)(d1.eq(d2), 'd1 should be equal to d2');
if (unsignedRoundingMode === 'half-zero') {
return r1;
}
if (unsignedRoundingMode === 'half-infinity') {
return r2;
}
(0, utils_1.invariant)(unsignedRoundingMode === 'half-even', 'unsignedRoundingMode should be half-even');
var cardinality = r1.div(r2.minus(r1)).mod(2);
if (cardinality.isZero()) {
return r1;
}
return r2;
}
@@ -0,0 +1,8 @@
import { NumberFormatInternal, NumberFormatPart } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-collapsenumberrange
* LDML: https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#collapsing-number-ranges
*/
export declare function CollapseNumberRange(numberFormat: Intl.NumberFormat, result: NumberFormatPart[], { getInternalSlots, }: {
getInternalSlots(nf: Intl.NumberFormat): NumberFormatInternal;
}): NumberFormatPart[];
@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CollapseNumberRange = CollapseNumberRange;
var PART_TYPES_TO_COLLAPSE = new Set([
'unit',
'exponentMinusSign',
'minusSign',
'plusSign',
'percentSign',
'exponentSeparator',
'percent',
'percentSign',
'currency',
'literal',
]);
/**
* https://tc39.es/ecma402/#sec-collapsenumberrange
* LDML: https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#collapsing-number-ranges
*/
function CollapseNumberRange(numberFormat, result, _a) {
var getInternalSlots = _a.getInternalSlots;
var internalSlots = getInternalSlots(numberFormat);
var symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem];
var rangeSignRegex = new RegExp("s?[".concat(symbols.rangeSign, "]s?"));
var rangeSignIndex = result.findIndex(function (r) { return r.type === 'literal' && rangeSignRegex.test(r.value); });
var prefixSignParts = [];
for (var i = rangeSignIndex - 1; i >= 0; i--) {
if (!PART_TYPES_TO_COLLAPSE.has(result[i].type)) {
break;
}
prefixSignParts.unshift(result[i]);
}
// Don't collapse if it's a single code point
if (Array.from(prefixSignParts.map(function (p) { return p.value; }).join('')).length > 1) {
var newResult = Array.from(result);
newResult.splice(rangeSignIndex - prefixSignParts.length, prefixSignParts.length);
return newResult;
}
var suffixSignParts = [];
for (var i = rangeSignIndex + 1; i < result.length; i++) {
if (!PART_TYPES_TO_COLLAPSE.has(result[i].type)) {
break;
}
suffixSignParts.push(result[i]);
}
// Don't collapse if it's a single code point
if (Array.from(suffixSignParts.map(function (p) { return p.value; }).join('')).length > 1) {
var newResult = Array.from(result);
newResult.splice(rangeSignIndex + 1, suffixSignParts.length);
return newResult;
}
return result;
}
@@ -0,0 +1,10 @@
import Decimal from 'decimal.js';
import { NumberFormatInternal } from '../types/number';
/**
* 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].
*/
export declare function ComputeExponent(internalSlots: NumberFormatInternal, x: Decimal): [number, number];
@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComputeExponent = ComputeExponent;
var tslib_1 = require("tslib");
var decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
var ComputeExponentForMagnitude_1 = require("./ComputeExponentForMagnitude");
var FormatNumericToString_1 = require("./FormatNumericToString");
/**
* 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();
}
var magnitude = x.log(10).floor();
var exponent = (0, ComputeExponentForMagnitude_1.ComputeExponentForMagnitude)(internalSlots, magnitude);
// Preserve more precision by doing multiplication when exponent is negative.
x = x.times(decimal_js_1.default.pow(10, -exponent));
var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(internalSlots, x);
if (formatNumberResult.roundedNumber.isZero()) {
return [exponent, magnitude.toNumber()];
}
var newMagnitude = formatNumberResult.roundedNumber.log(10).floor();
if (newMagnitude.eq(magnitude.minus(exponent))) {
return [exponent, magnitude.toNumber()];
}
return [
(0, ComputeExponentForMagnitude_1.ComputeExponentForMagnitude)(internalSlots, magnitude.plus(1)),
magnitude.plus(1).toNumber(),
];
}
@@ -0,0 +1,8 @@
import Decimal from 'decimal.js';
import { NumberFormatInternal } from '../types/number';
/**
* 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).
*/
export declare function ComputeExponentForMagnitude(internalSlots: NumberFormatInternal, magnitude: Decimal): number;
@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComputeExponentForMagnitude = ComputeExponentForMagnitude;
var tslib_1 = require("tslib");
var decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
var utils_1 = require("../utils");
decimal_js_1.default.set({
toExpPos: 100,
});
/**
* 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) {
var notation = internalSlots.notation, dataLocaleData = internalSlots.dataLocaleData, numberingSystem = internalSlots.numberingSystem;
switch (notation) {
case 'standard':
return 0;
case 'scientific':
return magnitude.toNumber();
case 'engineering':
var thousands = magnitude.div(3).floor();
return thousands.times(3).toNumber();
default: {
(0, utils_1.invariant)(notation === 'compact', 'Invalid notation');
// Let exponent be an implementation- and locale-dependent (ILD) integer by which to scale a
// number of the given magnitude in compact notation for the current locale.
var compactDisplay = internalSlots.compactDisplay, style = internalSlots.style, currencyDisplay = internalSlots.currencyDisplay;
var thresholdMap = void 0;
if (style === 'currency' && currencyDisplay !== 'name') {
var currency = dataLocaleData.numbers.currency[numberingSystem] ||
dataLocaleData.numbers.currency[dataLocaleData.numbers.nu[0]];
thresholdMap = currency.short;
}
else {
var decimal = dataLocaleData.numbers.decimal[numberingSystem] ||
dataLocaleData.numbers.decimal[dataLocaleData.numbers.nu[0]];
thresholdMap = compactDisplay === 'long' ? decimal.long : decimal.short;
}
if (!thresholdMap) {
return 0;
}
var num = decimal_js_1.default.pow(10, magnitude).toString();
var thresholds = Object.keys(thresholdMap); // TODO: this can be pre-processed
if (num < thresholds[0]) {
return 0;
}
if (num > thresholds[thresholds.length - 1]) {
return thresholds[thresholds.length - 1].length - 1;
}
var i = thresholds.indexOf(num);
if (i === -1) {
return 0;
}
// See https://unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formats
// Special handling if the pattern is precisely `0`.
var magnitudeKey = thresholds[i];
// TODO: do we need to handle plural here?
var compactPattern = thresholdMap[magnitudeKey].other;
if (compactPattern === '0') {
return 0;
}
// Example: in zh-TW, `10000000` maps to `0000萬`. So we need to return 8 - 4 = 4 here.
return (magnitudeKey.length -
thresholdMap[magnitudeKey].other.match(/0+/)[0].length);
}
}
}
@@ -0,0 +1,6 @@
/**
* https://tc39.es/ecma402/#sec-currencydigits
*/
export declare function CurrencyDigits(c: string, { currencyDigitsData }: {
currencyDigitsData: Record<string, number>;
}): number;
+13
View File
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CurrencyDigits = CurrencyDigits;
var _262_1 = require("../262");
/**
* https://tc39.es/ecma402/#sec-currencydigits
*/
function CurrencyDigits(c, _a) {
var currencyDigitsData = _a.currencyDigitsData;
return (0, _262_1.HasOwnProperty)(currencyDigitsData, c)
? currencyDigitsData[c]
: 2;
}
@@ -0,0 +1,5 @@
import { NumberFormatInternal, NumberFormatPart } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-formatapproximately
*/
export declare function FormatApproximately(internalSlots: NumberFormatInternal, result: NumberFormatPart[]): NumberFormatPart[];
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormatApproximately = FormatApproximately;
/**
* https://tc39.es/ecma402/#sec-formatapproximately
*/
function FormatApproximately(internalSlots, result) {
var symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem];
var approximatelySign = symbols.approximatelySign;
result.push({ type: 'approximatelySign', value: approximatelySign });
return result;
}
@@ -0,0 +1,3 @@
import Decimal from 'decimal.js';
import { NumberFormatInternal } from '../types/number';
export declare function FormatNumeric(internalSlots: NumberFormatInternal, x: Decimal): string;
@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormatNumeric = FormatNumeric;
var PartitionNumberPattern_1 = require("./PartitionNumberPattern");
function FormatNumeric(internalSlots, x) {
var parts = (0, PartitionNumberPattern_1.PartitionNumberPattern)(internalSlots, x);
return parts.map(function (p) { return p.value; }).join('');
}
@@ -0,0 +1,8 @@
import Decimal from 'decimal.js';
import { NumberFormatInternal } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-formatnumericrange
*/
export declare function FormatNumericRange(numberFormat: Intl.NumberFormat, x: Decimal, y: Decimal, { getInternalSlots, }: {
getInternalSlots(nf: Intl.NumberFormat): NumberFormatInternal;
}): string;
@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormatNumericRange = FormatNumericRange;
var PartitionNumberRangePattern_1 = require("./PartitionNumberRangePattern");
/**
* https://tc39.es/ecma402/#sec-formatnumericrange
*/
function FormatNumericRange(numberFormat, x, y, _a) {
var getInternalSlots = _a.getInternalSlots;
var parts = (0, PartitionNumberRangePattern_1.PartitionNumberRangePattern)(numberFormat, x, y, {
getInternalSlots: getInternalSlots,
});
return parts.map(function (part) { return part.value; }).join('');
}
@@ -0,0 +1,8 @@
import Decimal from 'decimal.js';
import { NumberFormatInternal, NumberRangeToParts } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-formatnumericrangetoparts
*/
export declare function FormatNumericRangeToParts(numberFormat: Intl.NumberFormat, x: Decimal, y: Decimal, { getInternalSlots, }: {
getInternalSlots(nf: Intl.NumberFormat): NumberFormatInternal;
}): NumberRangeToParts[];
@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormatNumericRangeToParts = FormatNumericRangeToParts;
var PartitionNumberRangePattern_1 = require("./PartitionNumberRangePattern");
/**
* https://tc39.es/ecma402/#sec-formatnumericrangetoparts
*/
function FormatNumericRangeToParts(numberFormat, x, y, _a) {
var getInternalSlots = _a.getInternalSlots;
var parts = (0, PartitionNumberRangePattern_1.PartitionNumberRangePattern)(numberFormat, x, y, {
getInternalSlots: getInternalSlots,
});
return parts.map(function (part, index) { return ({
type: part.type,
value: part.value,
source: part.source,
result: index.toString(),
}); });
}
@@ -0,0 +1,5 @@
import Decimal from 'decimal.js';
import { NumberFormatInternal, NumberFormatPart } from '../types/number';
export declare function FormatNumericToParts(nf: Intl.NumberFormat, x: Decimal, implDetails: {
getInternalSlots(nf: Intl.NumberFormat): NumberFormatInternal;
}): NumberFormatPart[];
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormatNumericToParts = FormatNumericToParts;
var _262_1 = require("../262");
var PartitionNumberPattern_1 = require("./PartitionNumberPattern");
function FormatNumericToParts(nf, x, implDetails) {
var parts = (0, PartitionNumberPattern_1.PartitionNumberPattern)(implDetails.getInternalSlots(nf), x);
var result = (0, _262_1.ArrayCreate)(0);
for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
var part = parts_1[_i];
result.push({
type: part.type,
value: part.value,
});
}
return result;
}
@@ -0,0 +1,9 @@
import Decimal from 'decimal.js';
import { NumberFormatDigitInternalSlots } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-formatnumberstring
*/
export declare function FormatNumericToString(intlObject: Pick<NumberFormatDigitInternalSlots, 'roundingType' | 'minimumSignificantDigits' | 'maximumSignificantDigits' | 'minimumIntegerDigits' | 'minimumFractionDigits' | 'maximumFractionDigits' | 'roundingIncrement' | 'roundingMode' | 'trailingZeroDisplay'>, _x: Decimal): {
roundedNumber: Decimal;
formattedString: string;
};
@@ -0,0 +1,87 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormatNumericToString = FormatNumericToString;
var constants_1 = require("../constants");
var utils_1 = require("../utils");
var GetUnsignedRoundingMode_1 = require("./GetUnsignedRoundingMode");
var ToRawFixed_1 = require("./ToRawFixed");
var ToRawPrecision_1 = require("./ToRawPrecision");
/**
* https://tc39.es/ecma402/#sec-formatnumberstring
*/
function FormatNumericToString(intlObject, _x) {
var x = _x;
var sign;
// -0
if (x.isZero() && x.isNegative()) {
sign = 'negative';
x = constants_1.ZERO;
}
else {
(0, utils_1.invariant)(x.isFinite(), 'NumberFormatDigitInternalSlots value is not finite');
if (x.lessThan(0)) {
sign = 'negative';
}
else {
sign = 'positive';
}
if (sign === 'negative') {
x = x.negated();
}
}
var result;
var roundingType = intlObject.roundingType;
var unsignedRoundingMode = (0, GetUnsignedRoundingMode_1.GetUnsignedRoundingMode)(intlObject.roundingMode, sign === 'negative');
switch (roundingType) {
case 'significantDigits':
result = (0, ToRawPrecision_1.ToRawPrecision)(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits, unsignedRoundingMode);
break;
case 'fractionDigits':
result = (0, ToRawFixed_1.ToRawFixed)(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits, intlObject.roundingIncrement, unsignedRoundingMode);
break;
default:
var sResult = (0, ToRawPrecision_1.ToRawPrecision)(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits, unsignedRoundingMode);
var fResult = (0, ToRawFixed_1.ToRawFixed)(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits, intlObject.roundingIncrement, unsignedRoundingMode);
if (intlObject.roundingType === 'morePrecision') {
if (sResult.roundingMagnitude <= fResult.roundingMagnitude) {
result = sResult;
}
else {
result = fResult;
}
}
else {
(0, utils_1.invariant)(intlObject.roundingType === 'lessPrecision', 'Invalid roundingType');
if (sResult.roundingMagnitude <= fResult.roundingMagnitude) {
result = fResult;
}
else {
result = sResult;
}
}
break;
}
x = result.roundedNumber;
var string = result.formattedString;
if (intlObject.trailingZeroDisplay === 'stripIfInteger' && x.isInteger()) {
var i = string.indexOf('.');
if (i > -1) {
string = string.slice(0, i);
}
}
var int = result.integerDigitsCount;
var minInteger = intlObject.minimumIntegerDigits;
if (int < minInteger) {
var forwardZeros = (0, utils_1.repeat)('0', minInteger - int);
string = forwardZeros + string;
}
if (sign === 'negative') {
if (x.isZero()) {
x = constants_1.NEGATIVE_ZERO;
}
else {
x = x.negated();
}
}
return { roundedNumber: x, formattedString: string };
}
@@ -0,0 +1,2 @@
import { RoundingModeType, UnsignedRoundingModeType } from '../types/number';
export declare function GetUnsignedRoundingMode(roundingMode: RoundingModeType, isNegative: boolean): UnsignedRoundingModeType;
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GetUnsignedRoundingMode = GetUnsignedRoundingMode;
var negativeMapping = {
ceil: 'zero',
floor: 'infinity',
expand: 'infinity',
trunc: 'zero',
halfCeil: 'half-zero',
halfFloor: 'half-infinity',
halfExpand: 'half-infinity',
halfTrunc: 'half-zero',
halfEven: 'half-even',
};
var 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];
}
@@ -0,0 +1,12 @@
import { NumberFormatInternal, NumberFormatLocaleInternalData, NumberFormatOptions } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-initializenumberformat
*/
export declare function InitializeNumberFormat(nf: Intl.NumberFormat, locales: string | ReadonlyArray<string> | undefined, opts: NumberFormatOptions | undefined, { getInternalSlots, localeData, availableLocales, numberingSystemNames, getDefaultLocale, currencyDigitsData, }: {
getInternalSlots(nf: Intl.NumberFormat): NumberFormatInternal;
localeData: Record<string, NumberFormatLocaleInternalData | undefined>;
availableLocales: Set<string>;
numberingSystemNames: ReadonlyArray<string>;
getDefaultLocale(): string;
currencyDigitsData: Record<string, number>;
}): Intl.NumberFormat;
@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InitializeNumberFormat = InitializeNumberFormat;
var intl_localematcher_1 = require("@formatjs/intl-localematcher");
var CanonicalizeLocaleList_1 = require("../CanonicalizeLocaleList");
var CoerceOptionsToObject_1 = require("../CoerceOptionsToObject");
var GetOption_1 = require("../GetOption");
var GetStringOrBooleanOption_1 = require("../GetStringOrBooleanOption");
var utils_1 = require("../utils");
var CurrencyDigits_1 = require("./CurrencyDigits");
var SetNumberFormatDigitOptions_1 = require("./SetNumberFormatDigitOptions");
var SetNumberFormatUnitOptions_1 = require("./SetNumberFormatUnitOptions");
/**
* https://tc39.es/ecma402/#sec-initializenumberformat
*/
function InitializeNumberFormat(nf, locales, opts, _a) {
var getInternalSlots = _a.getInternalSlots, localeData = _a.localeData, availableLocales = _a.availableLocales, numberingSystemNames = _a.numberingSystemNames, getDefaultLocale = _a.getDefaultLocale, currencyDigitsData = _a.currencyDigitsData;
var requestedLocales = (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(locales);
var options = (0, CoerceOptionsToObject_1.CoerceOptionsToObject)(opts);
var opt = Object.create(null);
var matcher = (0, GetOption_1.GetOption)(options, 'localeMatcher', 'string', ['lookup', 'best fit'], 'best fit');
opt.localeMatcher = matcher;
var numberingSystem = (0, GetOption_1.GetOption)(options, 'numberingSystem', 'string', undefined, undefined);
if (numberingSystem !== undefined &&
numberingSystemNames.indexOf(numberingSystem) < 0) {
// 8.a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal,
// throw a RangeError exception.
throw RangeError("Invalid numberingSystems: ".concat(numberingSystem));
}
opt.nu = numberingSystem;
var r = (0, intl_localematcher_1.ResolveLocale)(Array.from(availableLocales), requestedLocales, opt,
// [[RelevantExtensionKeys]] slot, which is a constant
['nu'], localeData, getDefaultLocale);
var dataLocaleData = localeData[r.dataLocale];
(0, utils_1.invariant)(!!dataLocaleData, "Missing locale data for ".concat(r.dataLocale));
var internalSlots = getInternalSlots(nf);
internalSlots.locale = r.locale;
internalSlots.dataLocale = r.dataLocale;
internalSlots.numberingSystem = r.nu;
internalSlots.dataLocaleData = dataLocaleData;
(0, SetNumberFormatUnitOptions_1.SetNumberFormatUnitOptions)(internalSlots, options);
var style = internalSlots.style;
var notation = (0, GetOption_1.GetOption)(options, 'notation', 'string', ['standard', 'scientific', 'engineering', 'compact'], 'standard');
internalSlots.notation = notation;
var mnfdDefault;
var mxfdDefault;
if (style === 'currency' && notation === 'standard') {
var currency = internalSlots.currency;
var cDigits = (0, CurrencyDigits_1.CurrencyDigits)(currency, { currencyDigitsData: currencyDigitsData });
mnfdDefault = cDigits;
mxfdDefault = cDigits;
}
else {
mnfdDefault = 0;
mxfdDefault = style === 'percent' ? 0 : 3;
}
(0, SetNumberFormatDigitOptions_1.SetNumberFormatDigitOptions)(internalSlots, options, mnfdDefault, mxfdDefault, notation);
var compactDisplay = (0, GetOption_1.GetOption)(options, 'compactDisplay', 'string', ['short', 'long'], 'short');
var defaultUseGrouping = 'auto';
if (notation === 'compact') {
internalSlots.compactDisplay = compactDisplay;
defaultUseGrouping = 'min2';
}
var useGrouping = (0, GetStringOrBooleanOption_1.GetStringOrBooleanOption)(options, 'useGrouping', ['min2', 'auto', 'always'], 'always', false, defaultUseGrouping);
internalSlots.useGrouping = useGrouping;
var signDisplay = (0, GetOption_1.GetOption)(options, 'signDisplay', 'string', ['auto', 'never', 'always', 'exceptZero', 'negative'], 'auto');
internalSlots.signDisplay = signDisplay;
return nf;
}
@@ -0,0 +1,6 @@
import Decimal from 'decimal.js';
import { NumberFormatInternal, NumberFormatPart } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-partitionnumberpattern
*/
export declare function PartitionNumberPattern(internalSlots: NumberFormatInternal, _x: Decimal): NumberFormatPart[];
@@ -0,0 +1,130 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PartitionNumberPattern = PartitionNumberPattern;
var tslib_1 = require("tslib");
var decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
var utils_1 = require("../utils");
var ComputeExponent_1 = require("./ComputeExponent");
var format_to_parts_1 = tslib_1.__importDefault(require("./format_to_parts"));
var FormatNumericToString_1 = require("./FormatNumericToString");
/**
* https://tc39.es/ecma402/#sec-partitionnumberpattern
*/
function PartitionNumberPattern(internalSlots, _x) {
var _a;
var x = _x;
// IMPL: We need to record the magnitude of the number
var magnitude = 0;
// 2. Let dataLocaleData be internalSlots.[[dataLocaleData]].
var pl = internalSlots.pl, dataLocaleData = internalSlots.dataLocaleData, numberingSystem = internalSlots.numberingSystem;
// 3. Let symbols be dataLocaleData.[[numbers]].[[symbols]][internalSlots.[[numberingSystem]]].
var symbols = dataLocaleData.numbers.symbols[numberingSystem] ||
dataLocaleData.numbers.symbols[dataLocaleData.numbers.nu[0]];
// 4. Let exponent be 0.
var exponent = 0;
// 5. Let n be ! ToString(x).
var n;
// 6. If x is NaN, then
if (x.isNaN()) {
// 6.a. Let n be symbols.[[nan]].
n = symbols.nan;
}
else if (!x.isFinite()) {
// 7. Else if x is a non-finite Number, then
// 7.a. Let n be symbols.[[infinity]].
n = symbols.infinity;
}
else {
// 8. Else,
if (!x.isZero()) {
// 8.a. If x < 0, let x be -x.
(0, utils_1.invariant)(x.isFinite(), 'Input must be a mathematical value');
// 8.b. If internalSlots.[[style]] is "percent", let x be 100 × x.
if (internalSlots.style == 'percent') {
x = x.times(100);
}
// 8.c. Let exponent be ComputeExponent(numberFormat, x).
;
_a = (0, ComputeExponent_1.ComputeExponent)(internalSlots, x), exponent = _a[0],
// IMPL: We need to record the magnitude of the number
magnitude = _a[1];
// 8.d. Let x be x × 10^(-exponent).
x = x.times(decimal_js_1.default.pow(10, -exponent));
}
// 8.e. Let formatNumberResult be FormatNumericToString(internalSlots, x).
var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(internalSlots, x);
// 8.f. Let n be formatNumberResult.[[formattedString]].
n = formatNumberResult.formattedString;
// 8.g. Let x be formatNumberResult.[[roundedNumber]].
x = formatNumberResult.roundedNumber;
}
// 9. Let sign be 0.
var sign;
// 10. If x is negative, then
var signDisplay = internalSlots.signDisplay;
switch (signDisplay) {
case 'never':
// 10.a. If internalSlots.[[signDisplay]] is "never", then
// 10.a.i. Let sign be 0.
sign = 0;
break;
case 'auto':
// 10.b. Else if internalSlots.[[signDisplay]] is "auto", then
if (x.isPositive() || x.isNaN()) {
// 10.b.i. If x is positive or x is NaN, let sign be 0.
sign = 0;
}
else {
// 10.b.ii. Else, let sign be -1.
sign = -1;
}
break;
case 'always':
// 10.c. Else if internalSlots.[[signDisplay]] is "always", then
if (x.isPositive() || x.isNaN()) {
// 10.c.i. If x is positive or x is NaN, let sign be 1.
sign = 1;
}
else {
// 10.c.ii. Else, let sign be -1.
sign = -1;
}
break;
case 'exceptZero':
// 10.d. Else if internalSlots.[[signDisplay]] is "exceptZero", then
if (x.isZero()) {
// 10.d.i. If x is 0, let sign be 0.
sign = 0;
}
else if (x.isNegative()) {
// 10.d.ii. Else if x is negative, let sign be -1.
sign = -1;
}
else {
// 10.d.iii. Else, let sign be 1.
sign = 1;
}
break;
default:
// 10.e. Else,
(0, utils_1.invariant)(signDisplay === 'negative', 'signDisplay must be "negative"');
if (x.isNegative() && !x.isZero()) {
// 10.e.i. If x is negative and x is not 0, let sign be -1.
sign = -1;
}
else {
// 10.e.ii. Else, let sign be 0.
sign = 0;
}
break;
}
// 11. Return ? FormatNumberToParts(numberFormat, x, n, exponent, sign).
return (0, format_to_parts_1.default)({
roundedNumber: x,
formattedString: n,
exponent: exponent,
// IMPL: We're returning this for our implementation of formatToParts
magnitude: magnitude,
sign: sign,
}, internalSlots.dataLocaleData, pl, internalSlots);
}
@@ -0,0 +1,8 @@
import Decimal from 'decimal.js';
import { NumberFormatInternal, NumberFormatPart } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-partitionnumberrangepattern
*/
export declare function PartitionNumberRangePattern(numberFormat: Intl.NumberFormat, x: Decimal, y: Decimal, { getInternalSlots, }: {
getInternalSlots(nf: Intl.NumberFormat): NumberFormatInternal;
}): NumberFormatPart[];
@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PartitionNumberRangePattern = PartitionNumberRangePattern;
var utils_1 = require("../utils");
var CollapseNumberRange_1 = require("./CollapseNumberRange");
var FormatApproximately_1 = require("./FormatApproximately");
var FormatNumeric_1 = require("./FormatNumeric");
var PartitionNumberPattern_1 = require("./PartitionNumberPattern");
/**
* https://tc39.es/ecma402/#sec-partitionnumberrangepattern
*/
function PartitionNumberRangePattern(numberFormat, x, y, _a) {
var getInternalSlots = _a.getInternalSlots;
// 1. Assert: x and y are both mathematical values.
(0, utils_1.invariant)(!x.isNaN() && !y.isNaN(), 'Input must be a number', RangeError);
var internalSlots = getInternalSlots(numberFormat);
// 3. Let xResult be ? PartitionNumberPattern(numberFormat, x).
var xResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(internalSlots, x);
// 4. Let yResult be ? PartitionNumberPattern(numberFormat, y).
var yResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(internalSlots, y);
if ((0, FormatNumeric_1.FormatNumeric)(internalSlots, x) === (0, FormatNumeric_1.FormatNumeric)(internalSlots, y)) {
var appxResult = (0, FormatApproximately_1.FormatApproximately)(internalSlots, xResult);
appxResult.forEach(function (el) {
el.source = 'shared';
});
return appxResult;
}
var result = [];
xResult.forEach(function (el) {
el.source = 'startRange';
result.push(el);
});
// 9. Let symbols be internalSlots.[[dataLocaleData]].[[numbers]].[[symbols]][internalSlots.[[numberingSystem]]].
var rangeSeparator = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem]
.rangeSign;
result.push({ type: 'literal', value: rangeSeparator, source: 'shared' });
yResult.forEach(function (el) {
el.source = 'endRange';
result.push(el);
});
// 13. Return ? CollapseNumberRange(numberFormat, result).
return (0, CollapseNumberRange_1.CollapseNumberRange)(numberFormat, result, { getInternalSlots: getInternalSlots });
}
@@ -0,0 +1,5 @@
import { NumberFormatDigitInternalSlots, NumberFormatDigitOptions, NumberFormatNotation } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-setnfdigitoptions
*/
export declare function SetNumberFormatDigitOptions(internalSlots: NumberFormatDigitInternalSlots, opts: NumberFormatDigitOptions, mnfdDefault: number, mxfdDefault: number, notation: NumberFormatNotation): void;
@@ -0,0 +1,182 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SetNumberFormatDigitOptions = SetNumberFormatDigitOptions;
var DefaultNumberOption_1 = require("../DefaultNumberOption");
var GetNumberOption_1 = require("../GetNumberOption");
var GetOption_1 = require("../GetOption");
var utils_1 = require("../utils");
//IMPL: Valid rounding increments as per implementation
var VALID_ROUNDING_INCREMENTS = new Set([
1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000,
]);
/**
* https://tc39.es/ecma402/#sec-setnfdigitoptions
*/
function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mxfdDefault, notation) {
// 1. Let mnid be ? GetNumberOption(opts, "minimumIntegerDigits", 1, 21, 1).
var mnid = (0, GetNumberOption_1.GetNumberOption)(opts, 'minimumIntegerDigits', 1, 21, 1);
// 2. Let mnfd be opts.[[MinimumFractionDigits]].
var mnfd = opts.minimumFractionDigits;
// 3. Let mxfd be opts.[[MaximumFractionDigits]].
var mxfd = opts.maximumFractionDigits;
// 4. Let mnsd be opts.[[MinimumSignificantDigits]].
var mnsd = opts.minimumSignificantDigits;
// 5. Let mxsd be opts.[[MaximumSignificantDigits]].
var mxsd = opts.maximumSignificantDigits;
// 6. Set internalSlots.[[MinimumIntegerDigits]] to mnid.
internalSlots.minimumIntegerDigits = mnid;
// 7. Let roundingIncrement be ? GetNumberOption(opts, "roundingIncrement", 1, 5000, 1).
var roundingIncrement = (0, GetNumberOption_1.GetNumberOption)(opts, 'roundingIncrement', 1, 5000, 1);
// 8. If roundingIncrement is not an element of the list {1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000}, throw a RangeError exception.
(0, utils_1.invariant)(VALID_ROUNDING_INCREMENTS.has(roundingIncrement), "Invalid rounding increment value: ".concat(roundingIncrement, ".\nValid values are ").concat(Array.from(VALID_ROUNDING_INCREMENTS).join(', '), "."));
// 9. Let roundingMode be ? GetOption(opts, "roundingMode", "string", « "ceil", "floor", "expand", "trunc", "halfCeil", "halfFloor", "halfExpand", "halfTrunc", "halfEven" », "halfExpand").
var roundingMode = (0, GetOption_1.GetOption)(opts, 'roundingMode', 'string', [
'ceil',
'floor',
'expand',
'trunc',
'halfCeil',
'halfFloor',
'halfExpand',
'halfTrunc',
'halfEven',
], 'halfExpand');
// 10. Let roundingPriority be ? GetOption(opts, "roundingPriority", "string", « "auto", "morePrecision", "lessPrecision" », "auto").
var roundingPriority = (0, GetOption_1.GetOption)(opts, 'roundingPriority', 'string', ['auto', 'morePrecision', 'lessPrecision'], 'auto');
// 11. Let trailingZeroDisplay be ? GetOption(opts, "trailingZeroDisplay", "string", « "auto", "stripIfInteger" », "auto").
var trailingZeroDisplay = (0, GetOption_1.GetOption)(opts, 'trailingZeroDisplay', 'string', ['auto', 'stripIfInteger'], 'auto');
// 12. If roundingIncrement is not 1, then
if (roundingIncrement !== 1) {
// 12.a. Set mxfdDefault to mnfdDefault.
mxfdDefault = mnfdDefault;
}
// 13. Set internalSlots.[[RoundingIncrement]] to roundingIncrement.
internalSlots.roundingIncrement = roundingIncrement;
// 14. Set internalSlots.[[RoundingMode]] to roundingMode.
internalSlots.roundingMode = roundingMode;
// 15. Set internalSlots.[[TrailingZeroDisplay]] to trailingZeroDisplay.
internalSlots.trailingZeroDisplay = trailingZeroDisplay;
// 16. Let hasSd be true if mnsd is not undefined or mxsd is not undefined; otherwise, let hasSd be false.
var hasSd = mnsd !== undefined || mxsd !== undefined;
// 17. Let hasFd be true if mnfd is not undefined or mxfd is not undefined; otherwise, let hasFd be false.
var hasFd = mnfd !== undefined || mxfd !== undefined;
// 18. Let needSd be true.
var needSd = true;
// 19. Let needFd be true.
var needFd = true;
// 20. If roundingPriority is "auto", then
if (roundingPriority === 'auto') {
// 20.a. Set needSd to hasSd.
needSd = hasSd;
// 20.b. If hasSd is true or hasFd is false and notation is "compact", then
if (hasSd || (!hasFd && notation === 'compact')) {
// 20.b.i. Set needFd to false.
needFd = false;
}
}
// 21. If needSd is true, then
if (needSd) {
// 21.a. If hasSd is true, then
if (hasSd) {
// 21.a.i. Set internalSlots.[[MinimumSignificantDigits]] to ? DefaultNumberOption(mnsd, 1, 21, 1).
internalSlots.minimumSignificantDigits = (0, DefaultNumberOption_1.DefaultNumberOption)(mnsd, 1, 21, 1);
// 21.a.ii. Set internalSlots.[[MaximumSignificantDigits]] to ? DefaultNumberOption(mxsd, internalSlots.[[MinimumSignificantDigits]], 21, 21).
internalSlots.maximumSignificantDigits = (0, DefaultNumberOption_1.DefaultNumberOption)(mxsd, internalSlots.minimumSignificantDigits, 21, 21);
}
else {
// 21.b. Else,
// 21.b.i. Set internalSlots.[[MinimumSignificantDigits]] to 1.
internalSlots.minimumSignificantDigits = 1;
// 21.b.ii. Set internalSlots.[[MaximumSignificantDigits]] to 21.
internalSlots.maximumSignificantDigits = 21;
}
}
// 22. If needFd is true, then
if (needFd) {
// 22.a. If hasFd is true, then
if (hasFd) {
// 22.a.i. Set mnfd to ? DefaultNumberOption(mnfd, 0, 100, undefined).
mnfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnfd, 0, 100, undefined);
// 22.a.ii. Set mxfd to ? DefaultNumberOption(mxfd, 0, 100, undefined).
mxfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxfd, 0, 100, undefined);
// 22.a.iii. If mnfd is undefined, then
if (mnfd === undefined) {
// 22.a.iii.1. Assert: mxfd is not undefined.
(0, utils_1.invariant)(mxfd !== undefined, 'maximumFractionDigits must be defined');
// 22.a.iii.2. Set mnfd to min(mnfdDefault, mxfd).
mnfd = Math.min(mnfdDefault, mxfd);
}
else if (mxfd === undefined) {
// 22.a.iv. Else if mxfd is undefined, then
// 22.a.iv.1. Set mxfd to max(mxfdDefault, mnfd).
mxfd = Math.max(mxfdDefault, mnfd);
}
else if (mnfd > mxfd) {
// 22.a.v. Else if mnfd > mxfd, throw a RangeError exception.
throw new RangeError("Invalid range, ".concat(mnfd, " > ").concat(mxfd));
}
// 22.a.vi. Set internalSlots.[[MinimumFractionDigits]] to mnfd.
internalSlots.minimumFractionDigits = mnfd;
// 22.a.vii. Set internalSlots.[[MaximumFractionDigits]] to mxfd.
internalSlots.maximumFractionDigits = mxfd;
}
else {
// 22.b. Else,
// 22.b.i. Set internalSlots.[[MinimumFractionDigits]] to mnfdDefault.
internalSlots.minimumFractionDigits = mnfdDefault;
// 22.b.ii. Set internalSlots.[[MaximumFractionDigits]] to mxfdDefault.
internalSlots.maximumFractionDigits = mxfdDefault;
}
}
// 23. If needSd is false and needFd is false, then
if (!needSd && !needFd) {
// 23.a. Set internalSlots.[[MinimumFractionDigits]] to 0.
internalSlots.minimumFractionDigits = 0;
// 23.b. Set internalSlots.[[MaximumFractionDigits]] to 0.
internalSlots.maximumFractionDigits = 0;
// 23.c. Set internalSlots.[[MinimumSignificantDigits]] to 1.
internalSlots.minimumSignificantDigits = 1;
// 23.d. Set internalSlots.[[MaximumSignificantDigits]] to 2.
internalSlots.maximumSignificantDigits = 2;
// 23.e. Set internalSlots.[[RoundingType]] to "morePrecision".
internalSlots.roundingType = 'morePrecision';
// 23.f. Set internalSlots.[[RoundingPriority]] to "morePrecision".
internalSlots.roundingPriority = 'morePrecision';
}
else if (roundingPriority === 'morePrecision') {
// 24. Else if roundingPriority is "morePrecision", then
// 24.a. Set internalSlots.[[RoundingType]] to "morePrecision".
internalSlots.roundingType = 'morePrecision';
// 24.b. Set internalSlots.[[RoundingPriority]] to "morePrecision".
internalSlots.roundingPriority = 'morePrecision';
}
else if (roundingPriority === 'lessPrecision') {
// 25. Else if roundingPriority is "lessPrecision", then
// 25.a. Set internalSlots.[[RoundingType]] to "lessPrecision".
internalSlots.roundingType = 'lessPrecision';
// 25.b. Set internalSlots.[[RoundingPriority]] to "lessPrecision".
internalSlots.roundingPriority = 'lessPrecision';
}
else if (hasSd) {
// 26. Else if hasSd is true, then
// 26.a. Set internalSlots.[[RoundingType]] to "significantDigits".
internalSlots.roundingType = 'significantDigits';
// 26.b. Set internalSlots.[[RoundingPriority]] to "auto".
internalSlots.roundingPriority = 'auto';
}
else {
// 27. Else,
// 27.a. Set internalSlots.[[RoundingType]] to "fractionDigits".
internalSlots.roundingType = 'fractionDigits';
// 27.b. Set internalSlots.[[RoundingPriority]] to "auto".
internalSlots.roundingPriority = 'auto';
}
// 28. If roundingIncrement is not 1, then
if (roundingIncrement !== 1) {
// 28.a. Assert: internalSlots.[[RoundingType]] is "fractionDigits".
(0, utils_1.invariant)(internalSlots.roundingType === 'fractionDigits', 'Invalid roundingType', TypeError);
// 28.b. Assert: internalSlots.[[MaximumFractionDigits]] is equal to internalSlots.[[MinimumFractionDigits]].
(0, utils_1.invariant)(internalSlots.maximumFractionDigits ===
internalSlots.minimumFractionDigits, 'With roundingIncrement > 1, maximumFractionDigits and minimumFractionDigits must be equal.', RangeError);
}
}
@@ -0,0 +1,5 @@
import { NumberFormatInternal, NumberFormatOptions } from '../types/number';
/**
* https://tc39.es/ecma402/#sec-setnumberformatunitoptions
*/
export declare function SetNumberFormatUnitOptions(internalSlots: NumberFormatInternal, options?: NumberFormatOptions | undefined): void;
@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SetNumberFormatUnitOptions = SetNumberFormatUnitOptions;
var GetOption_1 = require("../GetOption");
var IsWellFormedCurrencyCode_1 = require("../IsWellFormedCurrencyCode");
var IsWellFormedUnitIdentifier_1 = require("../IsWellFormedUnitIdentifier");
var utils_1 = require("../utils");
/**
* https://tc39.es/ecma402/#sec-setnumberformatunitoptions
*/
function SetNumberFormatUnitOptions(internalSlots, options) {
if (options === void 0) { options = Object.create(null); }
// 1. Let style be ? GetOption(options, "style", "string", « "decimal", "percent", "currency", "unit" », "decimal").
var style = (0, GetOption_1.GetOption)(options, 'style', 'string', ['decimal', 'percent', 'currency', 'unit'], 'decimal');
// 2. Set internalSlots.[[Style]] to style.
internalSlots.style = style;
// 3. Let currency be ? GetOption(options, "currency", "string", undefined, undefined).
var currency = (0, GetOption_1.GetOption)(options, 'currency', 'string', undefined, undefined);
// 4. If currency is not undefined, then
// a. If the result of IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception.
(0, utils_1.invariant)(currency === undefined || (0, IsWellFormedCurrencyCode_1.IsWellFormedCurrencyCode)(currency), 'Malformed currency code', RangeError);
// 5. If style is "currency" and currency is undefined, throw a TypeError exception.
(0, utils_1.invariant)(style !== 'currency' || currency !== undefined, 'currency cannot be undefined', TypeError);
// 6. Let currencyDisplay be ? GetOption(options, "currencyDisplay", "string", « "code", "symbol", "narrowSymbol", "name" », "symbol").
var currencyDisplay = (0, GetOption_1.GetOption)(options, 'currencyDisplay', 'string', ['code', 'symbol', 'narrowSymbol', 'name'], 'symbol');
// 7. Let currencySign be ? GetOption(options, "currencySign", "string", « "standard", "accounting" », "standard").
var currencySign = (0, GetOption_1.GetOption)(options, 'currencySign', 'string', ['standard', 'accounting'], 'standard');
// 8. Let unit be ? GetOption(options, "unit", "string", undefined, undefined).
var unit = (0, GetOption_1.GetOption)(options, 'unit', 'string', undefined, undefined);
// 9. If unit is not undefined, then
// a. If the result of IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception.
(0, utils_1.invariant)(unit === undefined || (0, IsWellFormedUnitIdentifier_1.IsWellFormedUnitIdentifier)(unit), 'Invalid unit argument for Intl.NumberFormat()', RangeError);
// 10. If style is "unit" and unit is undefined, throw a TypeError exception.
(0, utils_1.invariant)(style !== 'unit' || unit !== undefined, 'unit cannot be undefined', TypeError);
// 11. Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « "short", "narrow", "long" », "short").
var unitDisplay = (0, GetOption_1.GetOption)(options, 'unitDisplay', 'string', ['short', 'narrow', 'long'], 'short');
// 12. If style is "currency", then
if (style === 'currency') {
// a. Set internalSlots.[[Currency]] to the result of converting currency to upper case as specified in 6.1.
internalSlots.currency = currency.toUpperCase();
// b. Set internalSlots.[[CurrencyDisplay]] to currencyDisplay.
internalSlots.currencyDisplay = currencyDisplay;
// c. Set internalSlots.[[CurrencySign]] to currencySign.
internalSlots.currencySign = currencySign;
}
// 13. If style is "unit", then
if (style === 'unit') {
// a. Set internalSlots.[[Unit]] to unit.
internalSlots.unit = unit;
// b. Set internalSlots.[[UnitDisplay]] to unitDisplay.
internalSlots.unitDisplay = unitDisplay;
}
}
+9
View File
@@ -0,0 +1,9 @@
import Decimal from 'decimal.js';
import { RawNumberFormatResult, UnsignedRoundingModeType } from '../types/number';
/**
* 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
*/
export declare function ToRawFixed(x: Decimal, minFraction: number, maxFraction: number, roundingIncrement: number, unsignedRoundingMode: UnsignedRoundingModeType): RawNumberFormatResult;
+123
View File
@@ -0,0 +1,123 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ToRawFixed = ToRawFixed;
var tslib_1 = require("tslib");
var decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
var utils_1 = require("../utils");
var ApplyUnsignedRoundingMode_1 = require("./ApplyUnsignedRoundingMode");
//IMPL: Setting Decimal configuration
decimal_js_1.default.set({
toExpPos: 100,
});
//IMPL: Helper function to calculate raw fixed value
function ToRawFixedFn(n, f) {
return n.times(decimal_js_1.default.pow(10, -f));
}
//IMPL: Helper function to find n1 and r1
function findN1R1(x, f, roundingIncrement) {
var nx = x.times(decimal_js_1.default.pow(10, f)).floor();
var n1 = nx.div(roundingIncrement).floor().times(roundingIncrement);
var r1 = ToRawFixedFn(n1, f);
return {
n1: n1,
r1: r1,
};
}
//IMPL: Helper function to find n2 and r2
function findN2R2(x, f, roundingIncrement) {
var nx = x.times(decimal_js_1.default.pow(10, f)).ceil();
var n2 = nx.div(roundingIncrement).ceil().times(roundingIncrement);
var r2 = ToRawFixedFn(n2, f);
return {
n2: n2,
r2: r2,
};
}
/**
* 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) {
// 1. Let f be maxFraction.
var f = maxFraction;
// 2. Let n1 and r1 be the results of performing the maximized rounding of x to f fraction digits.
var _a = findN1R1(x, f, roundingIncrement), n1 = _a.n1, r1 = _a.r1;
// 3. Let n2 and r2 be the results of performing the minimized rounding of x to f fraction digits.
var _b = findN2R2(x, f, roundingIncrement), n2 = _b.n2, r2 = _b.r2;
// 4. Let r be ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode).
var r = (0, ApplyUnsignedRoundingMode_1.ApplyUnsignedRoundingMode)(x, r1, r2, unsignedRoundingMode);
var n, xFinal;
var m;
// 5. If r is equal to r1, then
if (r.eq(r1)) {
// a. Let n be n1.
n = n1;
// b. Let xFinal be r1.
xFinal = r1;
}
else {
// 6. Else,
// a. Let n be n2.
n = n2;
// b. Let xFinal be r2.
xFinal = r2;
}
// 7. If n is 0, let m be "0".
if (n.isZero()) {
m = '0';
}
else {
// 8. Else, let m be the String representation of n.
m = n.toString();
}
var int;
// 9. If f is not 0, then
if (f !== 0) {
// a. Let k be the length of m.
var k = m.length;
// b. If k < f, then
if (k <= f) {
// i. Let z be the String value consisting of f + 1 - k occurrences of the character "0".
var z = (0, utils_1.repeat)('0', f - k + 1);
// ii. Set m to the string-concatenation of z and m.
m = z + m;
// iii. Set k to f + 1.
k = f + 1;
}
// c. Let a be the substring of m from 0 to k - f.
var a = m.slice(0, k - f);
// d. Let b be the substring of m from k - f to k.
var b = m.slice(m.length - f);
// e. Set m to the string-concatenation of a, ".", and b.
m = a + '.' + b;
// f. Let int be the length of a.
int = a.length;
}
else {
// 10. Else, let int be the length of m.
int = m.length;
}
// 11. Let cut be maxFraction - minFraction.
var cut = maxFraction - minFraction;
// 12. Repeat, while cut > 0 and the last character of m is "0",
while (cut > 0 && m[m.length - 1] === '0') {
// a. Remove the last character from m.
m = m.slice(0, m.length - 1);
// b. Decrease cut by 1.
cut--;
}
// 13. If the last character of m is ".", then
if (m[m.length - 1] === '\u002e') {
// a. Remove the last character from m.
m = m.slice(0, m.length - 1);
}
// 14. Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: -f }.
return {
formattedString: m,
roundedNumber: xFinal,
integerDigitsCount: int,
roundingMagnitude: -f,
};
}
@@ -0,0 +1,9 @@
import Decimal from 'decimal.js';
import { RawNumberFormatResult, UnsignedRoundingModeType } from '../types/number';
/**
* 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
*/
export declare function ToRawPrecision(x: Decimal, minPrecision: number, maxPrecision: number, unsignedRoundingMode: UnsignedRoundingModeType): RawNumberFormatResult;
+152
View File
@@ -0,0 +1,152 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ToRawPrecision = ToRawPrecision;
var tslib_1 = require("tslib");
var decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
var constants_1 = require("../constants");
var utils_1 = require("../utils");
var ApplyUnsignedRoundingMode_1 = require("./ApplyUnsignedRoundingMode");
//IMPL: Helper function to find n1, e1, and r1
function findN1E1R1(x, p) {
var maxN1 = decimal_js_1.default.pow(10, p);
var minN1 = decimal_js_1.default.pow(10, p - 1);
var maxE1 = x.div(minN1).log(10).plus(p).minus(1).ceil();
var currentE1 = maxE1;
while (true) {
var currentN1 = x.div(decimal_js_1.default.pow(10, currentE1.minus(p).plus(1))).floor();
if (currentN1.lessThan(maxN1) && currentN1.greaterThanOrEqualTo(minN1)) {
var currentR1 = currentN1.times(decimal_js_1.default.pow(10, currentE1.minus(p).plus(1)));
if (currentR1.lessThanOrEqualTo(x)) {
return {
n1: currentN1,
e1: currentE1,
r1: currentR1,
};
}
}
currentE1 = currentE1.minus(1);
}
}
//IMPL: Helper function to find n2, e2, and r2
function findN2E2R2(x, p) {
var maxN2 = decimal_js_1.default.pow(10, p);
var minN2 = decimal_js_1.default.pow(10, p - 1);
var minE2 = x.div(maxN2).log(10).plus(p).minus(1).floor();
var currentE2 = minE2;
while (true) {
var currentN2 = x.div(decimal_js_1.default.pow(10, currentE2.minus(p).plus(1))).ceil();
if (currentN2.lessThan(maxN2) && currentN2.greaterThanOrEqualTo(minN2)) {
var currentR2 = currentN2.times(decimal_js_1.default.pow(10, currentE2.minus(p).plus(1)));
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) {
// 1. Let p be maxPrecision.
var p = maxPrecision;
var m;
var e;
var xFinal;
// 2. If x = 0, then
if (x.isZero()) {
// a. Let m be the String value consisting of p occurrences of the character "0".
m = (0, utils_1.repeat)('0', p);
// b. Let e be 0.
e = 0;
// c. Let xFinal be 0.
xFinal = constants_1.ZERO;
}
else {
// 3. Else,
// a. Let {n1, e1, r1} be the result of findN1E1R1(x, p).
var _a = findN1E1R1(x, p), n1 = _a.n1, e1 = _a.e1, r1 = _a.r1;
// b. Let {n2, e2, r2} be the result of findN2E2R2(x, p).
var _b = findN2E2R2(x, p), n2 = _b.n2, e2 = _b.e2, r2 = _b.r2;
// c. Let r be ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode).
var r = (0, ApplyUnsignedRoundingMode_1.ApplyUnsignedRoundingMode)(x, r1, r2, unsignedRoundingMode);
var n
// d. If r = r1, then
= void 0;
// d. If r = r1, then
if (r.eq(r1)) {
// i. Let n be n1.
n = n1;
// ii. Let e be e1.
e = e1.toNumber();
// iii. Let xFinal be r1.
xFinal = r1;
}
else {
// e. Else,
// i. Let n be n2.
n = n2;
// ii. Let e be e2.
e = e2.toNumber();
// iii. Let xFinal be r2.
xFinal = r2;
}
// f. Let m be the String representation of n.
m = n.toString();
}
var int;
// 4. If e ≥ p - 1, then
if (e >= p - 1) {
// a. Let m be the string-concatenation of m and p - 1 - e occurrences of the character "0".
m = m + (0, utils_1.repeat)('0', e - p + 1);
// b. Let int be e + 1.
int = e + 1;
}
else if (e >= 0) {
// 5. Else if e ≥ 0, then
// a. Let m be the string-concatenation of the first e + 1 characters of m, ".", and the remaining p - (e + 1) characters of m.
m = m.slice(0, e + 1) + '.' + m.slice(m.length - (p - (e + 1)));
// b. Let int be e + 1.
int = e + 1;
}
else {
// 6. Else,
// a. Assert: e < 0.
(0, utils_1.invariant)(e < 0, 'e should be less than 0');
// b. Let m be the string-concatenation of "0.", -e - 1 occurrences of the character "0", and m.
m = '0.' + (0, utils_1.repeat)('0', -e - 1) + m;
// c. Let int be 1.
int = 1;
}
// 7. If m contains ".", and maxPrecision > minPrecision, then
if (m.includes('.') && maxPrecision > minPrecision) {
// a. Let cut be maxPrecision - minPrecision.
var cut = maxPrecision - minPrecision;
// b. Repeat, while cut > 0 and the last character of m is "0",
while (cut > 0 && m[m.length - 1] === '0') {
// i. Remove the last character from m.
m = m.slice(0, m.length - 1);
// ii. Decrease cut by 1.
cut--;
}
// c. If the last character of m is ".", then
if (m[m.length - 1] === '.') {
// i. Remove the last character from m.
m = m.slice(0, m.length - 1);
}
}
// 8. Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: e }.
return {
formattedString: m,
roundedNumber: xFinal,
integerDigitsCount: int,
roundingMagnitude: e,
};
}
@@ -0,0 +1 @@
export declare const digitMapping: Record<string, ReadonlyArray<string>>;
@@ -0,0 +1,785 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.digitMapping = void 0;
exports.digitMapping = {
"adlm": [
"𞥐",
"𞥑",
"𞥒",
"𞥓",
"𞥔",
"𞥕",
"𞥖",
"𞥗",
"𞥘",
"𞥙"
],
"ahom": [
"𑜰",
"𑜱",
"𑜲",
"𑜳",
"𑜴",
"𑜵",
"𑜶",
"𑜷",
"𑜸",
"𑜹"
],
"arab": [
"٠",
"١",
"٢",
"٣",
"٤",
"٥",
"٦",
"٧",
"٨",
"٩"
],
"arabext": [
"۰",
"۱",
"۲",
"۳",
"۴",
"۵",
"۶",
"۷",
"۸",
"۹"
],
"bali": [
"᭐",
"᭑",
"᭒",
"᭓",
"᭔",
"᭕",
"᭖",
"᭗",
"᭘",
"᭙"
],
"beng": [
"",
"১",
"২",
"৩",
"",
"৫",
"৬",
"",
"৮",
"৯"
],
"bhks": [
"𑱐",
"𑱑",
"𑱒",
"𑱓",
"𑱔",
"𑱕",
"𑱖",
"𑱗",
"𑱘",
"𑱙"
],
"brah": [
"𑁦",
"𑁧",
"𑁨",
"𑁩",
"𑁪",
"𑁫",
"𑁬",
"𑁭",
"𑁮",
"𑁯"
],
"cakm": [
"𑄶",
"𑄷",
"𑄸",
"𑄹",
"𑄺",
"𑄻",
"𑄼",
"𑄽",
"𑄾",
"𑄿"
],
"cham": [
"꩐",
"꩑",
"꩒",
"꩓",
"꩔",
"꩕",
"꩖",
"꩗",
"꩘",
"꩙"
],
"deva": [
"",
"१",
"२",
"३",
"४",
"५",
"६",
"७",
"८",
"९"
],
"diak": [
"𑥐",
"𑥑",
"𑥒",
"𑥓",
"𑥔",
"𑥕",
"𑥖",
"𑥗",
"𑥘",
"𑥙"
],
"fullwide": [
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
],
"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": [
"𞋰",
"𞋱",
"𞋲",
"𞋳",
"𞋴",
"𞋵",
"𞋶",
"𞋷",
"𞋸",
"𞋹"
]
};
@@ -0,0 +1,24 @@
import Decimal from 'decimal.js';
import { NumberFormatLocaleInternalData, NumberFormatOptionsCompactDisplay, NumberFormatOptionsCurrencyDisplay, NumberFormatOptionsCurrencySign, NumberFormatOptionsNotation, NumberFormatOptionsStyle, NumberFormatOptionsUnitDisplay, NumberFormatPart, RoundingModeType, UseGroupingType } from '../types/number';
interface NumberResult {
formattedString: string;
roundedNumber: Decimal;
sign: -1 | 0 | 1;
exponent: number;
magnitude: number;
}
export default function formatToParts(numberResult: NumberResult, data: NumberFormatLocaleInternalData, pl: Intl.PluralRules, options: {
numberingSystem: string;
useGrouping?: UseGroupingType;
style: NumberFormatOptionsStyle;
notation: NumberFormatOptionsNotation;
compactDisplay?: NumberFormatOptionsCompactDisplay;
currency?: string;
currencyDisplay?: NumberFormatOptionsCurrencyDisplay;
currencySign?: NumberFormatOptionsCurrencySign;
unit?: string;
unitDisplay?: NumberFormatOptionsUnitDisplay;
roundingIncrement: number;
roundingMode: RoundingModeType;
}): NumberFormatPart[];
export {};
+451
View File
@@ -0,0 +1,451 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = formatToParts;
var tslib_1 = require("tslib");
var decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
var regex_generated_1 = require("../regex.generated");
var digit_mapping_generated_1 = require("./digit-mapping.generated");
var GetUnsignedRoundingMode_1 = require("./GetUnsignedRoundingMode");
var ToRawFixed_1 = require("./ToRawFixed");
// This is from: unicode-12.1.0/General_Category/Symbol/regex.js
// IE11 does not support unicode flag, otherwise this is just /\p{S}/u.
// /^\p{S}/u
var CARET_S_UNICODE_REGEX = new RegExp("^".concat(regex_generated_1.S_UNICODE_REGEX.source));
// /\p{S}$/u
var S_DOLLAR_UNICODE_REGEX = new RegExp("".concat(regex_generated_1.S_UNICODE_REGEX.source, "$"));
var CLDR_NUMBER_PATTERN = /[#0](?:[\.,][#0]+)*/g;
function formatToParts(numberResult, data, pl, options) {
var _a;
var sign = numberResult.sign, exponent = numberResult.exponent, magnitude = numberResult.magnitude;
var notation = options.notation, style = options.style, numberingSystem = options.numberingSystem;
var defaultNumberingSystem = data.numbers.nu[0];
// #region Part 1: partition and interpolate the CLDR number pattern.
// ----------------------------------------------------------
var compactNumberPattern = null;
if (notation === 'compact' && magnitude) {
compactNumberPattern = getCompactDisplayPattern(numberResult, pl, data, style, options.compactDisplay, options.currencyDisplay, numberingSystem);
}
// This is used multiple times
var nonNameCurrencyPart;
if (style === 'currency' && options.currencyDisplay !== 'name') {
var 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 {
// Fallback for unknown currency
nonNameCurrencyPart = options.currency;
}
}
var numberPattern;
if (!compactNumberPattern) {
// Note: if the style is unit, or is currency and the currency display is name,
// its unit parts will be interpolated in part 2. So here we can fallback to decimal.
if (style === 'decimal' ||
style === 'unit' ||
(style === 'currency' && options.currencyDisplay === 'name')) {
// Shortcut for decimal
var decimalData = data.numbers.decimal[numberingSystem] ||
data.numbers.decimal[defaultNumberingSystem];
numberPattern = getPatternForSign(decimalData.standard, sign);
}
else if (style === 'currency') {
var currencyData = data.numbers.currency[numberingSystem] ||
data.numbers.currency[defaultNumberingSystem];
// We replace number pattern part with `0` for easier postprocessing.
numberPattern = getPatternForSign(currencyData[options.currencySign], sign);
}
else {
// percent
var percentPattern = data.numbers.percent[numberingSystem] ||
data.numbers.percent[defaultNumberingSystem];
numberPattern = getPatternForSign(percentPattern, sign);
}
}
else {
numberPattern = compactNumberPattern;
}
// Extract the decimal number pattern string. It looks like "#,##0,00", which will later be
// used to infer decimal group sizes.
var decimalNumberPattern = CLDR_NUMBER_PATTERN.exec(numberPattern)[0];
// Now we start to substitute patterns
// 1. replace strings like `0` and `#,##0.00` with `{0}`
// 2. unquote characters (invariant: the quoted characters does not contain the special tokens)
numberPattern = numberPattern
.replace(CLDR_NUMBER_PATTERN, '{0}')
.replace(/'(.)'/g, '$1');
// Handle currency spacing (both compact and non-compact).
if (style === 'currency' && options.currencyDisplay !== 'name') {
var currencyData = data.numbers.currency[numberingSystem] ||
data.numbers.currency[defaultNumberingSystem];
// See `currencySpacing` substitution rule in TR-35.
// Here we always assume the currencyMatch is "[:^S:]" and surroundingMatch is "[:digit:]".
//
// Example 1: for pattern "#,##0.00¤" with symbol "US$", we replace "¤" with the symbol,
// but insert an extra non-break space before the symbol, because "[:^S:]" matches "U" in
// "US$" and "[:digit:]" matches the latn numbering system digits.
//
// Example 2: for pattern "¤#,##0.00" with symbol "US$", there is no spacing between symbol
// and number, because `$` does not match "[:^S:]".
//
// Implementation note: here we do the best effort to infer the insertion.
// We also assume that `beforeInsertBetween` and `afterInsertBetween` will never be `;`.
var afterCurrency = currencyData.currencySpacing.afterInsertBetween;
if (afterCurrency && !S_DOLLAR_UNICODE_REGEX.test(nonNameCurrencyPart)) {
numberPattern = numberPattern.replace('¤{0}', "\u00A4".concat(afterCurrency, "{0}"));
}
var beforeCurrency = currencyData.currencySpacing.beforeInsertBetween;
if (beforeCurrency && !CARET_S_UNICODE_REGEX.test(nonNameCurrencyPart)) {
numberPattern = numberPattern.replace('{0}¤', "{0}".concat(beforeCurrency, "\u00A4"));
}
}
// The following tokens are special: `{0}`, `¤`, `%`, `-`, `+`, `{c:...}.
var numberPatternParts = numberPattern.split(/({c:[^}]+}|\{0\}|[¤%\-\+])/g);
var numberParts = [];
var symbols = data.numbers.symbols[numberingSystem] ||
data.numbers.symbols[defaultNumberingSystem];
for (var _i = 0, numberPatternParts_1 = numberPatternParts; _i < numberPatternParts_1.length; _i++) {
var part = numberPatternParts_1[_i];
if (!part) {
continue;
}
switch (part) {
case '{0}': {
// We only need to handle scientific and engineering notation here.
numberParts.push.apply(numberParts, partitionNumberIntoParts(symbols, numberResult, notation, exponent, numberingSystem,
// If compact number pattern exists, do not insert group separators.
!compactNumberPattern && ((_a = options.useGrouping) !== null && _a !== void 0 ? _a : true), decimalNumberPattern, style, options.roundingIncrement, (0, GetUnsignedRoundingMode_1.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 '¤':
// Computed above when handling currency spacing.
numberParts.push({ type: 'currency', value: nonNameCurrencyPart });
break;
default:
if (/^\{c:/.test(part)) {
numberParts.push({
type: 'compact',
value: part.substring(3, part.length - 1),
});
}
else {
// literal
numberParts.push({ type: 'literal', value: part });
}
break;
}
}
// #endregion
// #region Part 2: interpolate unit pattern if necessary.
// ----------------------------------------------
switch (style) {
case 'currency': {
// `currencyDisplay: 'name'` has similar pattern handling as units.
if (options.currencyDisplay === 'name') {
var unitPattern = (data.numbers.currency[numberingSystem] ||
data.numbers.currency[defaultNumberingSystem]).unitPattern;
// Select plural
var unitName = void 0;
var currencyNameData = data.currencies[options.currency];
if (currencyNameData) {
unitName = selectPlural(pl, numberResult.roundedNumber
.times(decimal_js_1.default.pow(10, exponent))
.toNumber(), currencyNameData.displayName);
}
else {
// Fallback for unknown currency
unitName = options.currency;
}
// Do {0} and {1} substitution
var unitPatternParts = unitPattern.split(/(\{[01]\})/g);
var result = [];
for (var _b = 0, unitPatternParts_1 = unitPatternParts; _b < unitPatternParts_1.length; _b++) {
var part = unitPatternParts_1[_b];
switch (part) {
case '{0}':
result.push.apply(result, 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': {
var unit = options.unit, unitDisplay = options.unitDisplay;
var unitData = data.units.simple[unit];
var unitPattern = void 0;
if (unitData) {
// Simple unit pattern
unitPattern = selectPlural(pl, numberResult.roundedNumber
.times(decimal_js_1.default.pow(10, exponent))
.toNumber(), data.units.simple[unit][unitDisplay]);
}
else {
// See: http://unicode.org/reports/tr35/tr35-general.html#perUnitPatterns
// If cannot find unit in the simple pattern, it must be "per" compound pattern.
// Implementation note: we are not following TR-35 here because we need to format to parts!
var _c = unit.split('-per-'), numeratorUnit = _c[0], denominatorUnit = _c[1];
unitData = data.units.simple[numeratorUnit];
var numeratorUnitPattern = selectPlural(pl, numberResult.roundedNumber
.times(decimal_js_1.default.pow(10, exponent))
.toNumber(), data.units.simple[numeratorUnit][unitDisplay]);
var perUnitPattern = data.units.simple[denominatorUnit].perUnit[unitDisplay];
if (perUnitPattern) {
// perUnitPattern exists, combine it with numeratorUnitPattern
unitPattern = perUnitPattern.replace('{0}', numeratorUnitPattern);
}
else {
// get compoundUnit pattern (e.g. "{0} per {1}"), repalce {0} with numerator pattern and {1} with
// the denominator pattern in singular form.
var perPattern = data.units.compound.per[unitDisplay];
var denominatorPattern = selectPlural(pl, 1, data.units.simple[denominatorUnit][unitDisplay]);
unitPattern = unitPattern = perPattern
.replace('{0}', numeratorUnitPattern)
.replace('{1}', denominatorPattern.replace('{0}', ''));
}
}
var result = [];
// We need spacing around "{0}" because they are not treated as "unit" parts, but "literal".
for (var _d = 0, _e = unitPattern.split(/(\s*\{0\}\s*)/); _d < _e.length; _d++) {
var part = _e[_d];
var interpolateMatch = /^(\s*)\{0\}(\s*)$/.exec(part);
if (interpolateMatch) {
// Space before "{0}"
if (interpolateMatch[1]) {
result.push({ type: 'literal', value: interpolateMatch[1] });
}
// "{0}" itself
result.push.apply(result, numberParts);
// Space after "{0}"
if (interpolateMatch[2]) {
result.push({ type: 'literal', value: interpolateMatch[2] });
}
}
else if (part) {
result.push({ type: 'unit', value: part });
}
}
return result;
}
default:
return numberParts;
}
// #endregion
}
// A subset of https://tc39.es/ecma402/#sec-partitionnotationsubpattern
// Plus the exponent parts handling.
function partitionNumberIntoParts(symbols, numberResult, notation, exponent, numberingSystem, useGrouping,
/**
* This is the decimal number pattern without signs or symbols.
* It is used to infer the group size when `useGrouping` is true.
*
* A typical value looks like "#,##0.00" (primary group size is 3).
* Some locales like Hindi has secondary group size of 2 (e.g. "#,##,##0.00").
*/
decimalNumberPattern, style, roundingIncrement, unsignedRoundingMode) {
var result = [];
// eslint-disable-next-line prefer-const
var n = numberResult.formattedString, x = numberResult.roundedNumber;
if (x.isNaN()) {
return [{ type: 'nan', value: n }];
}
else if (!x.isFinite()) {
return [{ type: 'infinity', value: n }];
}
var digitReplacementTable = digit_mapping_generated_1.digitMapping[numberingSystem];
if (digitReplacementTable) {
n = n.replace(/\d/g, function (digit) { return digitReplacementTable[+digit] || digit; });
}
// TODO: Else use an implementation dependent algorithm to map n to the appropriate
// representation of n in the given numbering system.
var decimalSepIndex = n.indexOf('.');
var integer;
var fraction;
if (decimalSepIndex > 0) {
integer = n.slice(0, decimalSepIndex);
fraction = n.slice(decimalSepIndex + 1);
}
else {
integer = n;
}
// #region Grouping integer digits
// The weird compact and x >= 10000 check is to ensure consistency with Node.js and Chrome.
// Note that `de` does not have compact form for thousands, but Node.js does not insert grouping separator
// unless the rounded number is greater than 10000:
// NumberFormat('de', {notation: 'compact', compactDisplay: 'short'}).format(1234) //=> "1234"
// NumberFormat('de').format(1234) //=> "1.234"
var shouldUseGrouping = false;
if (useGrouping === 'always') {
shouldUseGrouping = true;
}
else if (useGrouping === 'min2') {
shouldUseGrouping = x.greaterThanOrEqualTo(10000);
}
else if (useGrouping === 'auto' || useGrouping) {
shouldUseGrouping = notation !== 'compact' || x.greaterThanOrEqualTo(10000);
}
if (shouldUseGrouping) {
// a. Let groupSepSymbol be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
// For currency we should use `currencyGroup` instead of generic `group`
var groupSepSymbol = style === 'currency' && symbols.currencyGroup != null
? symbols.currencyGroup
: symbols.group;
var groups = [];
// > There may be two different grouping sizes: The primary grouping size used for the least
// > significant integer group, and the secondary grouping size used for more significant groups.
// > If a pattern contains multiple grouping separators, the interval between the last one and the
// > end of the integer defines the primary grouping size, and the interval between the last two
// > defines the secondary grouping size. All others are ignored.
var integerNumberPattern = decimalNumberPattern.split('.')[0];
var patternGroups = integerNumberPattern.split(',');
var primaryGroupingSize = 3;
var secondaryGroupingSize = 3;
if (patternGroups.length > 1) {
primaryGroupingSize = patternGroups[patternGroups.length - 1].length;
}
if (patternGroups.length > 2) {
secondaryGroupingSize = patternGroups[patternGroups.length - 2].length;
}
var i = integer.length - primaryGroupingSize;
if (i > 0) {
// Slice the least significant integer group
groups.push(integer.slice(i, i + primaryGroupingSize));
// Then iteratively push the more signicant groups
// TODO: handle surrogate pairs in some numbering system digits
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) {
var integerGroup = groups.pop();
result.push({ type: 'integer', value: integerGroup });
if (groups.length > 0) {
result.push({ type: 'group', value: groupSepSymbol });
}
}
}
else {
result.push({ type: 'integer', value: integer });
}
// #endregion
if (fraction !== undefined) {
var decimalSepSymbol = style === 'currency' && symbols.currencyDecimal != null
? symbols.currencyDecimal
: symbols.decimal;
result.push({ type: 'decimal', value: decimalSepSymbol }, { type: 'fraction', value: fraction });
}
if ((notation === 'scientific' || notation === 'engineering') &&
x.isFinite()) {
result.push({ type: 'exponentSeparator', value: symbols.exponential });
if (exponent < 0) {
result.push({ type: 'exponentMinusSign', value: symbols.minusSign });
exponent = -exponent;
}
var exponentResult = (0, ToRawFixed_1.ToRawFixed)(new decimal_js_1.default(exponent), 0, 0, roundingIncrement, unsignedRoundingMode);
result.push({
type: 'exponentInteger',
value: exponentResult.formattedString,
});
}
return result;
}
function getPatternForSign(pattern, sign) {
if (pattern.indexOf(';') < 0) {
pattern = "".concat(pattern, ";-").concat(pattern);
}
var _a = pattern.split(';'), zeroPattern = _a[0], negativePattern = _a[1];
switch (sign) {
case 0:
return zeroPattern;
case -1:
return negativePattern;
default:
return negativePattern.indexOf('-') >= 0
? negativePattern.replace(/-/g, '+')
: "+".concat(zeroPattern);
}
}
// Find the CLDR pattern for compact notation based on the magnitude of data and style.
//
// Example return value: "¤ {c:laki}000;¤{c:laki} -0" (`sw` locale):
// - Notice the `{c:...}` token that wraps the compact literal.
// - The consecutive zeros are normalized to single zero to match CLDR_NUMBER_PATTERN.
//
// Returning null means the compact display pattern cannot be found.
function getCompactDisplayPattern(numberResult, pl, data, style, compactDisplay, currencyDisplay, numberingSystem) {
var _a;
var roundedNumber = numberResult.roundedNumber, sign = numberResult.sign, magnitude = numberResult.magnitude;
var magnitudeKey = String(Math.pow(10, magnitude));
var defaultNumberingSystem = data.numbers.nu[0];
var pattern;
if (style === 'currency' && currencyDisplay !== 'name') {
var byNumberingSystem = data.numbers.currency;
var currencyData = byNumberingSystem[numberingSystem] ||
byNumberingSystem[defaultNumberingSystem];
// NOTE: compact notation ignores currencySign!
var compactPluralRules = (_a = currencyData.short) === null || _a === void 0 ? void 0 : _a[magnitudeKey];
if (!compactPluralRules) {
return null;
}
pattern = selectPlural(pl, roundedNumber.toNumber(), compactPluralRules);
}
else {
var byNumberingSystem = data.numbers.decimal;
var byCompactDisplay = byNumberingSystem[numberingSystem] ||
byNumberingSystem[defaultNumberingSystem];
var compactPlaralRule = byCompactDisplay[compactDisplay][magnitudeKey];
if (!compactPlaralRule) {
return null;
}
pattern = selectPlural(pl, roundedNumber.toNumber(), compactPlaralRule);
}
// See https://unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formats
// > If the value is precisely “0”, either explicit or defaulted, then the normal number format
// > pattern for that sort of object is supplied.
if (pattern === '0') {
return null;
}
pattern = getPatternForSign(pattern, sign)
// Extract compact literal from the pattern
.replace(/([^\s;\-\+\d¤]+)/g, '{c:$1}')
// We replace one or more zeros with a single zero so it matches `CLDR_NUMBER_PATTERN`.
.replace(/0+/, '0');
return pattern;
}
function selectPlural(pl, x, rules) {
return rules[pl.select(x)] || rules.other;
}