1
|
|
|
/*! |
2
|
|
|
* Copyright (c) 2022 Pedro José Batista, licensed under the MIT License. |
3
|
|
|
* See the LICENSE.md file in the project root for more information. |
4
|
|
|
*/ |
5
|
|
|
import Format, { FormatOptions } from "@/format"; |
6
|
|
|
import * as constants from "@/format/constants"; |
7
|
|
|
import Decimal from "decimal.js"; |
8
|
|
|
|
9
|
|
|
export { Decimal }; |
10
|
|
|
export const pow10 = (exponent: Decimal.Value) => Decimal.pow(10, exponent); |
11
|
|
|
export const toString = (target: object) => Object.prototype.toString.call(target); |
12
|
|
|
|
13
|
|
|
export const basicNumbers = [0, -0, 1, -1, 0.5, -0.5, 10, -10, 10.5, -10.5, 100.5, -100.5, 666.6, -666.6, 1000.5, -1000.5, "123456789.1234", "-123456789.1234", Infinity, -Infinity, NaN, -NaN] as const; |
14
|
|
|
export const currencies = ["AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR", "BZD", "CAD", "CDF", "CHF", "CLP", "CNY", "COP", "CRC", "CUP", "CVE", "CZK", "DJF", "DKK", "DOP", "DZD", "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL", "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MYR", "MZN", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "STD", "SVC", "SYP", "SZL", "THB", "TJS", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU", "UZS", "VEF", "VES", "VND", "VUV", "WST", "XAF", "XCD", "XOF", "XPF", "YER", "ZAR", "ZMK", "ZWD"] as const; |
15
|
|
|
export const units = ["acre", "bit", "byte", "celsius", "centimeter", "day", "degree", "fahrenheit", "fluid-ounce", "foot", "gallon", "gigabit", "gigabyte", "gram", "hectare", "hour", "inch", "kilobit", "kilobyte", "kilogram", "kilometer", "liter", "megabit", "megabyte", "meter", "mile", "mile-scandinavian", "milliliter", "millimeter", "millisecond", "minute", "month", "ounce", "percent", "petabyte", "pound", "second", "stone", "terabit", "terabyte", "week", "yard", "year"]; |
16
|
|
|
|
17
|
|
|
export const toStringTag = "[object Decimal.Format]"; |
18
|
|
|
|
19
|
|
|
export const ecmaOptionsDigits = { |
20
|
|
|
maximumFractionDigits: [0, 20], |
21
|
|
|
maximumSignificantDigits: [1, 21], |
22
|
|
|
minimumFractionDigits: [0, 20], |
23
|
|
|
minimumIntegerDigits: [1, 21], |
24
|
|
|
minimumSignificantDigits: [1, 21], |
25
|
|
|
} as const; |
26
|
|
|
|
27
|
|
|
export const optionsDigits = { |
28
|
|
|
maximumFractionDigits: [0, 1000], |
29
|
|
|
maximumSignificantDigits: [1, 1001], |
30
|
|
|
minimumFractionDigits: [0, 1000], |
31
|
|
|
minimumIntegerDigits: [1, 1001], |
32
|
|
|
minimumSignificantDigits: [1, 1001], |
33
|
|
|
} as const; |
34
|
|
|
|
35
|
|
|
export const optionsVariants = { |
36
|
|
|
localeMatcher: [25, "best fit", "lookup"], |
37
|
|
|
notation: [75, "standard", "scientific", "engineering", "compact"], |
38
|
|
|
numberingSystem: [75, "adlm", "ahom", "arab", "arabext", "armn", "armnlow", "bali", "beng", "bhks", "brah", "cakm", "cham", "cyrl", "deva", "ethi", "finance", "fullwide", "geor", "gong", "gonm", "grek", "greklow", "gujr", "guru", "hanidays", "hanidec", "hans", "hansfin", "hant", "hantfin", "hebr", "hmng", "hmnp", "java", "jpan", "jpanfin", "jpanyear", "kali", "khmr", "knda", "lana", "lanatham", "laoo", "latn", "lepc", "limb", "mathbold", "mathdbl", "mathmono", "mathsanb", "mathsans", "mlym", "modi", "mong", "mroo", "mtei", "mymr", "mymrshan", "mymrtlng", "native", "newa", "nkoo", "olck", "orya", "osma", "rohg", "roman", "romanlow", "saur", "shrd", "sind", "sinh", "sora", "sund", "takr", "talu", "taml", "tamldec", "telu", "thai", "tirh", "tibt", "traditio", "vaii", "wara", "wcho"], |
39
|
|
|
signDisplay: [25, "auto", "never", "always", "exceptZero"], |
40
|
|
|
} as const; |
41
|
|
|
|
42
|
|
|
export { constants, Format }; |
43
|
|
|
|
44
|
|
|
// Randomization: |
45
|
|
|
|
46
|
|
|
export const random = (from = 0, to = 100) => |
47
|
|
|
Decimal.random() |
48
|
|
|
.mul(to - from) |
49
|
|
|
.floor() |
50
|
|
|
.add(from) |
51
|
|
|
.toNumber(); |
52
|
|
|
|
53
|
|
|
export const randomVariant = (ecma: boolean) => { |
54
|
|
|
const result: FormatOptions = {}; |
55
|
|
|
|
56
|
|
|
for (const setting in optionsVariants) { |
57
|
|
|
const key = setting as keyof typeof optionsVariants; |
58
|
|
|
const [chance, ...array] = optionsVariants[key]; |
59
|
|
|
|
60
|
|
|
if (random() >= chance) { |
61
|
|
|
continue; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
const index = random(array.length - 1); |
65
|
|
|
result[key] = array[index] as any; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
const { minimumFractionDigits, minimumIntegerDigits, minimumSignificantDigits, maximumSignificantDigits, maximumFractionDigits } = ecma ? ecmaOptionsDigits : optionsDigits; |
69
|
|
|
let fraction = false; |
70
|
|
|
|
71
|
|
|
if (random() >= 50) { |
72
|
|
|
const [min, max] = minimumIntegerDigits; |
73
|
|
|
result.minimumIntegerDigits = random(min, max); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
if (random() >= 75) { |
77
|
|
|
fraction = true; |
78
|
|
|
const [min, max] = minimumFractionDigits; |
79
|
|
|
result.minimumFractionDigits = random(min, max); |
80
|
|
|
result.maximumFractionDigits = Math.max(random(min, max), result.minimumFractionDigits); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
if (!fraction && random() >= 25) { |
84
|
|
|
fraction = true; |
85
|
|
|
const [min, max] = minimumSignificantDigits; |
86
|
|
|
result.minimumSignificantDigits = random(min, max); |
87
|
|
|
result.maximumSignificantDigits = Math.max(random(min, max), result.minimumSignificantDigits); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
return result; |
91
|
|
|
}; |
92
|
|
|
|
93
|
|
|
export const randomOptionsCombinations = (ecma = false) => { |
94
|
|
|
const [decimalStyle, percentStyle, currencyStyle, unitStyle] = [{ style: "decimal" }, { style: "percent" }, { style: "currency", currency: [...currencies], currencyDisplay: ["symbol", "narrowSymbol", "code", "name"] }, { style: "unit", unit: [...units], unitDisplay: ["long", "narrow", "short"] }] as const; |
95
|
|
|
const result: FormatOptions<any, any>[] = [{}]; |
96
|
|
|
|
97
|
|
|
for (let i = 0; i < 30; i++) result.push({ ...decimalStyle, ...randomVariant(ecma) }); |
98
|
|
|
for (let i = 0; i < 30; i++) result.push({ ...percentStyle, ...randomVariant(ecma) }); |
99
|
|
|
|
100
|
|
|
for (const currency of currencyStyle.currency) { |
101
|
|
|
for (const currencyDisplay of currencyStyle.currencyDisplay) { |
102
|
|
|
result.push({ currency, currencyDisplay, style: "currency", ...randomVariant(ecma) }); |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
for (const unit of unitStyle.unit) { |
107
|
|
|
for (const unitDisplay of unitStyle.unitDisplay) { |
108
|
|
|
result.push({ unit, unitDisplay, style: "unit", ...randomVariant(ecma) }); |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
return result; |
113
|
|
|
}; |
114
|
|
|
|