@formatjs/ecma402-abstract 3.0.6 → 3.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,13 @@
1
1
  /**
2
+ * CanonicalizeTimeZoneName ( timeZone )
2
3
  * https://tc39.es/ecma402/#sec-canonicalizetimezonename
3
- * @param tz
4
+ *
5
+ * Extended to support UTC offset time zones per ECMA-402 PR #788 (ES2026).
6
+ * Returns the canonical and case-regularized form of a timezone identifier.
7
+ *
8
+ * @param tz - The timezone identifier to canonicalize
9
+ * @param implDetails - Implementation details containing timezone data
10
+ * @returns The canonical timezone identifier
4
11
  */
5
12
  export declare function CanonicalizeTimeZoneName(tz: string, { zoneNames, uppercaseLinks, }: {
6
13
  zoneNames: readonly string[];
@@ -1,17 +1,91 @@
1
+ // Cached regex patterns for performance
2
+ var OFFSET_TIMEZONE_PREFIX_REGEX = /^[+-]/;
3
+ var OFFSET_TIMEZONE_FORMAT_REGEX = /^([+-])(\d{2})(?::?(\d{2}))?(?::?(\d{2}))?(?:\.(\d{1,9}))?$/;
4
+ var TRAILING_ZEROS_REGEX = /0+$/;
1
5
  /**
6
+ * IsTimeZoneOffsetString ( offsetString )
7
+ * https://tc39.es/ecma262/#sec-istimezoneoffsetstring
8
+ *
9
+ * Simplified check to determine if a string is a UTC offset identifier.
10
+ *
11
+ * @param offsetString - The string to check
12
+ * @returns true if offsetString starts with '+' or '-'
13
+ */
14
+ function IsTimeZoneOffsetString(offsetString) {
15
+ // 1. If offsetString does not start with '+' or '-', return false
16
+ return OFFSET_TIMEZONE_PREFIX_REGEX.test(offsetString);
17
+ }
18
+ /**
19
+ * ParseTimeZoneOffsetString ( offsetString )
20
+ * https://tc39.es/ecma262/#sec-parsetimezoneoffsetstring
21
+ *
22
+ * Parses a UTC offset string and returns its canonical representation.
23
+ * Normalizes various formats (±HH, ±HHMM, ±HH:MM, etc.) to ±HH:MM format.
24
+ *
25
+ * @param offsetString - The UTC offset string to parse
26
+ * @returns The canonical offset string in ±HH:MM format (with :SS.sss if non-zero)
27
+ */
28
+ function ParseTimeZoneOffsetString(offsetString) {
29
+ // 1. Let parseResult be ParseText(offsetString, UTCOffset)
30
+ var match = OFFSET_TIMEZONE_FORMAT_REGEX.exec(offsetString);
31
+ // 2. Assert: parseResult is not a List of errors (validated by IsValidTimeZoneName)
32
+ if (!match) {
33
+ return offsetString;
34
+ }
35
+ // 3. Extract components from parseResult
36
+ var sign = match[1];
37
+ var hours = match[2];
38
+ var minutes = match[3] ? match[3] : '00';
39
+ var seconds = match[4];
40
+ var fractional = match[5];
41
+ // 4. Build canonical format: ±HH:MM
42
+ var canonical = "".concat(sign).concat(hours, ":").concat(minutes);
43
+ // 5. If seconds are present and non-zero (or fractional present), include them
44
+ if (seconds && (parseInt(seconds, 10) !== 0 || fractional)) {
45
+ canonical += ":".concat(seconds);
46
+ // 6. If fractional seconds present, include them (trim trailing zeros)
47
+ if (fractional) {
48
+ var trimmedFractional = fractional.replace(TRAILING_ZEROS_REGEX, '');
49
+ if (trimmedFractional) {
50
+ canonical += ".".concat(trimmedFractional);
51
+ }
52
+ }
53
+ }
54
+ // 7. Return canonical representation
55
+ return canonical;
56
+ }
57
+ /**
58
+ * CanonicalizeTimeZoneName ( timeZone )
2
59
  * https://tc39.es/ecma402/#sec-canonicalizetimezonename
3
- * @param tz
60
+ *
61
+ * Extended to support UTC offset time zones per ECMA-402 PR #788 (ES2026).
62
+ * Returns the canonical and case-regularized form of a timezone identifier.
63
+ *
64
+ * @param tz - The timezone identifier to canonicalize
65
+ * @param implDetails - Implementation details containing timezone data
66
+ * @returns The canonical timezone identifier
4
67
  */
5
68
  export function CanonicalizeTimeZoneName(tz, _a) {
6
69
  var zoneNames = _a.zoneNames, uppercaseLinks = _a.uppercaseLinks;
70
+ // 1. If IsTimeZoneOffsetString(timeZone) is true, then
71
+ // a. Return ParseTimeZoneOffsetString(timeZone)
72
+ // Per ECMA-402 PR #788, UTC offset identifiers are canonicalized
73
+ if (IsTimeZoneOffsetString(tz)) {
74
+ return ParseTimeZoneOffsetString(tz);
75
+ }
76
+ // 2. Let ianaTimeZone be the String value of the Zone or Link name
77
+ // in the IANA Time Zone Database that is an ASCII-case-insensitive
78
+ // match of timeZone
7
79
  var uppercasedTz = tz.toUpperCase();
8
80
  var uppercasedZones = zoneNames.reduce(function (all, z) {
9
81
  all[z.toUpperCase()] = z;
10
82
  return all;
11
83
  }, {});
12
84
  var ianaTimeZone = uppercaseLinks[uppercasedTz] || uppercasedZones[uppercasedTz];
85
+ // 3. If ianaTimeZone is "Etc/UTC" or "Etc/GMT", return "UTC"
13
86
  if (ianaTimeZone === 'Etc/UTC' || ianaTimeZone === 'Etc/GMT') {
14
87
  return 'UTC';
15
88
  }
89
+ // 4. Return ianaTimeZone
16
90
  return ianaTimeZone;
17
91
  }
@@ -1,7 +1,15 @@
1
1
  /**
2
+ * IsValidTimeZoneName ( timeZone )
2
3
  * https://tc39.es/ecma402/#sec-isvalidtimezonename
3
- * @param tz
4
- * @param implDetails implementation details
4
+ *
5
+ * Extended to support UTC offset time zones per ECMA-402 PR #788 (ES2026).
6
+ * The abstract operation validates both:
7
+ * 1. UTC offset identifiers (e.g., "+01:00", "-05:30")
8
+ * 2. Available named time zone identifiers from IANA Time Zone Database
9
+ *
10
+ * @param tz - The timezone identifier to validate
11
+ * @param implDetails - Implementation details containing timezone data
12
+ * @returns true if timeZone is a valid identifier
5
13
  */
6
14
  export declare function IsValidTimeZoneName(tz: string, { zoneNamesFromData, uppercaseLinks, }: {
7
15
  zoneNamesFromData: readonly string[];
@@ -1,10 +1,61 @@
1
+ // Cached regex patterns for performance
2
+ var OFFSET_TIMEZONE_PREFIX_REGEX = /^[+-]/;
3
+ var OFFSET_TIMEZONE_FORMAT_REGEX = /^([+-])(\d{2})(?::?(\d{2}))?(?::?(\d{2}))?(?:\.(\d{1,9}))?$/;
1
4
  /**
5
+ * IsTimeZoneOffsetString ( offsetString )
6
+ * https://tc39.es/ecma262/#sec-istimezoneoffsetstring
7
+ *
8
+ * Validates whether a string represents a valid UTC offset timezone.
9
+ * Supports formats: ±HH, ±HHMM, ±HH:MM, ±HH:MM:SS, ±HH:MM:SS.sss
10
+ *
11
+ * @param offsetString - The string to validate as a timezone offset
12
+ * @returns true if offsetString is a valid UTC offset format
13
+ */
14
+ function IsTimeZoneOffsetString(offsetString) {
15
+ // 1. If offsetString does not start with '+' or '-', return false
16
+ if (!OFFSET_TIMEZONE_PREFIX_REGEX.test(offsetString)) {
17
+ return false;
18
+ }
19
+ // 2. Let parseResult be ParseText(offsetString, UTCOffset)
20
+ var match = OFFSET_TIMEZONE_FORMAT_REGEX.exec(offsetString);
21
+ // 3. If parseResult is a List of errors, return false
22
+ if (!match) {
23
+ return false;
24
+ }
25
+ // 4. Validate component ranges per ECMA-262 grammar
26
+ // Hour must be 0-23, Minute must be 0-59, Second must be 0-59
27
+ var hours = parseInt(match[2], 10);
28
+ var minutes = match[3] ? parseInt(match[3], 10) : 0;
29
+ var seconds = match[4] ? parseInt(match[4], 10) : 0;
30
+ if (hours > 23 || minutes > 59 || seconds > 59) {
31
+ return false;
32
+ }
33
+ // 5. Return true
34
+ return true;
35
+ }
36
+ /**
37
+ * IsValidTimeZoneName ( timeZone )
2
38
  * https://tc39.es/ecma402/#sec-isvalidtimezonename
3
- * @param tz
4
- * @param implDetails implementation details
39
+ *
40
+ * Extended to support UTC offset time zones per ECMA-402 PR #788 (ES2026).
41
+ * The abstract operation validates both:
42
+ * 1. UTC offset identifiers (e.g., "+01:00", "-05:30")
43
+ * 2. Available named time zone identifiers from IANA Time Zone Database
44
+ *
45
+ * @param tz - The timezone identifier to validate
46
+ * @param implDetails - Implementation details containing timezone data
47
+ * @returns true if timeZone is a valid identifier
5
48
  */
6
49
  export function IsValidTimeZoneName(tz, _a) {
7
50
  var zoneNamesFromData = _a.zoneNamesFromData, uppercaseLinks = _a.uppercaseLinks;
51
+ // 1. If IsTimeZoneOffsetString(timeZone) is true, return true
52
+ // Per ECMA-402 PR #788, UTC offset identifiers are valid
53
+ if (IsTimeZoneOffsetString(tz)) {
54
+ return true;
55
+ }
56
+ // 2. Let timeZones be AvailableNamedTimeZoneIdentifiers()
57
+ // 3. If timeZones contains an element equal to timeZone, return true
58
+ // NOTE: Implementation uses case-insensitive comparison per spec note
8
59
  var uppercasedTz = tz.toUpperCase();
9
60
  var zoneNames = new Set();
10
61
  var linkNames = new Set();
@@ -13,5 +64,9 @@ export function IsValidTimeZoneName(tz, _a) {
13
64
  linkNames.add(linkName.toUpperCase());
14
65
  zoneNames.add(uppercaseLinks[linkName].toUpperCase());
15
66
  });
16
- return zoneNames.has(uppercasedTz) || linkNames.has(uppercasedTz);
67
+ if (zoneNames.has(uppercasedTz) || linkNames.has(uppercasedTz)) {
68
+ return true;
69
+ }
70
+ // 4. Return false
71
+ return false;
17
72
  }
@@ -44,7 +44,16 @@ export function ComputeExponentForMagnitude(internalSlots, magnitude) {
44
44
  return 0;
45
45
  }
46
46
  if (num > thresholds[thresholds.length - 1]) {
47
- return thresholds[thresholds.length - 1].length - 1;
47
+ // GH #4236: When number exceeds max threshold, use the exponent
48
+ // corresponding to the largest available threshold in locale data.
49
+ // Calculate exponent the same way as for normal thresholds (lines 70-73).
50
+ var magnitudeKey_1 = thresholds[thresholds.length - 1];
51
+ var compactPattern_1 = thresholdMap[magnitudeKey_1].other;
52
+ if (compactPattern_1 === '0') {
53
+ return 0;
54
+ }
55
+ return (magnitudeKey_1.length -
56
+ thresholdMap[magnitudeKey_1].other.match(/0+/)[0].length);
48
57
  }
49
58
  var i = thresholds.indexOf(num);
50
59
  if (i === -1) {
@@ -1,782 +1,67 @@
1
1
  export var digitMapping = {
2
- "adlm": [
3
- "𞥐",
4
- "𞥑",
5
- "𞥒",
6
- "𞥓",
7
- "𞥔",
8
- "𞥕",
9
- "𞥖",
10
- "𞥗",
11
- "𞥘",
12
- "𞥙"
13
- ],
14
- "ahom": [
15
- "𑜰",
16
- "𑜱",
17
- "𑜲",
18
- "𑜳",
19
- "𑜴",
20
- "𑜵",
21
- "𑜶",
22
- "𑜷",
23
- "𑜸",
24
- "𑜹"
25
- ],
26
- "arab": [
27
- "٠",
28
- "١",
29
- "٢",
30
- "٣",
31
- "٤",
32
- "٥",
33
- "٦",
34
- "٧",
35
- "٨",
36
- "٩"
37
- ],
38
- "arabext": [
39
- "۰",
40
- "۱",
41
- "۲",
42
- "۳",
43
- "۴",
44
- "۵",
45
- "۶",
46
- "۷",
47
- "۸",
48
- "۹"
49
- ],
50
- "bali": [
51
- "᭐",
52
- "᭑",
53
- "᭒",
54
- "᭓",
55
- "᭔",
56
- "᭕",
57
- "᭖",
58
- "᭗",
59
- "᭘",
60
- "᭙"
61
- ],
62
- "beng": [
63
- "০",
64
- "১",
65
- "২",
66
- "৩",
67
- "৪",
68
- "৫",
69
- "৬",
70
- "৭",
71
- "৮",
72
- "৯"
73
- ],
74
- "bhks": [
75
- "𑱐",
76
- "𑱑",
77
- "𑱒",
78
- "𑱓",
79
- "𑱔",
80
- "𑱕",
81
- "𑱖",
82
- "𑱗",
83
- "𑱘",
84
- "𑱙"
85
- ],
86
- "brah": [
87
- "𑁦",
88
- "𑁧",
89
- "𑁨",
90
- "𑁩",
91
- "𑁪",
92
- "𑁫",
93
- "𑁬",
94
- "𑁭",
95
- "𑁮",
96
- "𑁯"
97
- ],
98
- "cakm": [
99
- "𑄶",
100
- "𑄷",
101
- "𑄸",
102
- "𑄹",
103
- "𑄺",
104
- "𑄻",
105
- "𑄼",
106
- "𑄽",
107
- "𑄾",
108
- "𑄿"
109
- ],
110
- "cham": [
111
- "꩐",
112
- "꩑",
113
- "꩒",
114
- "꩓",
115
- "꩔",
116
- "꩕",
117
- "꩖",
118
- "꩗",
119
- "꩘",
120
- "꩙"
121
- ],
122
- "deva": [
123
- "०",
124
- "१",
125
- "२",
126
- "३",
127
- "४",
128
- "५",
129
- "६",
130
- "७",
131
- "८",
132
- "९"
133
- ],
134
- "diak": [
135
- "𑥐",
136
- "𑥑",
137
- "𑥒",
138
- "𑥓",
139
- "𑥔",
140
- "𑥕",
141
- "𑥖",
142
- "𑥗",
143
- "𑥘",
144
- "𑥙"
145
- ],
146
- "fullwide": [
147
- "0",
148
- "1",
149
- "2",
150
- "3",
151
- "4",
152
- "5",
153
- "6",
154
- "7",
155
- "8",
156
- "9"
157
- ],
158
- "gong": [
159
- "𑶠",
160
- "𑶡",
161
- "𑶢",
162
- "𑶣",
163
- "𑶤",
164
- "𑶥",
165
- "𑶦",
166
- "𑶧",
167
- "𑶨",
168
- "𑶩"
169
- ],
170
- "gonm": [
171
- "𑵐",
172
- "𑵑",
173
- "𑵒",
174
- "𑵓",
175
- "𑵔",
176
- "𑵕",
177
- "𑵖",
178
- "𑵗",
179
- "𑵘",
180
- "𑵙"
181
- ],
182
- "gujr": [
183
- "૦",
184
- "૧",
185
- "૨",
186
- "૩",
187
- "૪",
188
- "૫",
189
- "૬",
190
- "૭",
191
- "૮",
192
- "૯"
193
- ],
194
- "guru": [
195
- "੦",
196
- "੧",
197
- "੨",
198
- "੩",
199
- "੪",
200
- "੫",
201
- "੬",
202
- "੭",
203
- "੮",
204
- "੯"
205
- ],
206
- "hanidec": [
207
- "〇",
208
- "一",
209
- "二",
210
- "三",
211
- "四",
212
- "五",
213
- "六",
214
- "七",
215
- "八",
216
- "九"
217
- ],
218
- "hmng": [
219
- "𖭐",
220
- "𖭑",
221
- "𖭒",
222
- "𖭓",
223
- "𖭔",
224
- "𖭕",
225
- "𖭖",
226
- "𖭗",
227
- "𖭘",
228
- "𖭙"
229
- ],
230
- "hmnp": [
231
- "𞅀",
232
- "𞅁",
233
- "𞅂",
234
- "𞅃",
235
- "𞅄",
236
- "𞅅",
237
- "𞅆",
238
- "𞅇",
239
- "𞅈",
240
- "𞅉"
241
- ],
242
- "java": [
243
- "꧐",
244
- "꧑",
245
- "꧒",
246
- "꧓",
247
- "꧔",
248
- "꧕",
249
- "꧖",
250
- "꧗",
251
- "꧘",
252
- "꧙"
253
- ],
254
- "kali": [
255
- "꤀",
256
- "꤁",
257
- "꤂",
258
- "꤃",
259
- "꤄",
260
- "꤅",
261
- "꤆",
262
- "꤇",
263
- "꤈",
264
- "꤉"
265
- ],
266
- "khmr": [
267
- "០",
268
- "១",
269
- "២",
270
- "៣",
271
- "៤",
272
- "៥",
273
- "៦",
274
- "៧",
275
- "៨",
276
- "៩"
277
- ],
278
- "knda": [
279
- "೦",
280
- "೧",
281
- "೨",
282
- "೩",
283
- "೪",
284
- "೫",
285
- "೬",
286
- "೭",
287
- "೮",
288
- "೯"
289
- ],
290
- "lana": [
291
- "᪀",
292
- "᪁",
293
- "᪂",
294
- "᪃",
295
- "᪄",
296
- "᪅",
297
- "᪆",
298
- "᪇",
299
- "᪈",
300
- "᪉"
301
- ],
302
- "lanatham": [
303
- "᪐",
304
- "᪑",
305
- "᪒",
306
- "᪓",
307
- "᪔",
308
- "᪕",
309
- "᪖",
310
- "᪗",
311
- "᪘",
312
- "᪙"
313
- ],
314
- "laoo": [
315
- "໐",
316
- "໑",
317
- "໒",
318
- "໓",
319
- "໔",
320
- "໕",
321
- "໖",
322
- "໗",
323
- "໘",
324
- "໙"
325
- ],
326
- "lepc": [
327
- "᪐",
328
- "᪑",
329
- "᪒",
330
- "᪓",
331
- "᪔",
332
- "᪕",
333
- "᪖",
334
- "᪗",
335
- "᪘",
336
- "᪙"
337
- ],
338
- "limb": [
339
- "᥆",
340
- "᥇",
341
- "᥈",
342
- "᥉",
343
- "᥊",
344
- "᥋",
345
- "᥌",
346
- "᥍",
347
- "᥎",
348
- "᥏"
349
- ],
350
- "mathbold": [
351
- "𝟎",
352
- "𝟏",
353
- "𝟐",
354
- "𝟑",
355
- "𝟒",
356
- "𝟓",
357
- "𝟔",
358
- "𝟕",
359
- "𝟖",
360
- "𝟗"
361
- ],
362
- "mathdbl": [
363
- "𝟘",
364
- "𝟙",
365
- "𝟚",
366
- "𝟛",
367
- "𝟜",
368
- "𝟝",
369
- "𝟞",
370
- "𝟟",
371
- "𝟠",
372
- "𝟡"
373
- ],
374
- "mathmono": [
375
- "𝟶",
376
- "𝟷",
377
- "𝟸",
378
- "𝟹",
379
- "𝟺",
380
- "𝟻",
381
- "𝟼",
382
- "𝟽",
383
- "𝟾",
384
- "𝟿"
385
- ],
386
- "mathsanb": [
387
- "𝟬",
388
- "𝟭",
389
- "𝟮",
390
- "𝟯",
391
- "𝟰",
392
- "𝟱",
393
- "𝟲",
394
- "𝟳",
395
- "𝟴",
396
- "𝟵"
397
- ],
398
- "mathsans": [
399
- "𝟢",
400
- "𝟣",
401
- "𝟤",
402
- "𝟥",
403
- "𝟦",
404
- "𝟧",
405
- "𝟨",
406
- "𝟩",
407
- "𝟪",
408
- "𝟫"
409
- ],
410
- "mlym": [
411
- "൦",
412
- "൧",
413
- "൨",
414
- "൩",
415
- "൪",
416
- "൫",
417
- "൬",
418
- "൭",
419
- "൮",
420
- "൯"
421
- ],
422
- "modi": [
423
- "𑙐",
424
- "𑙑",
425
- "𑙒",
426
- "𑙓",
427
- "𑙔",
428
- "𑙕",
429
- "𑙖",
430
- "𑙗",
431
- "𑙘",
432
- "𑙙"
433
- ],
434
- "mong": [
435
- "᠐",
436
- "᠑",
437
- "᠒",
438
- "᠓",
439
- "᠔",
440
- "᠕",
441
- "᠖",
442
- "᠗",
443
- "᠘",
444
- "᠙"
445
- ],
446
- "mroo": [
447
- "𖩠",
448
- "𖩡",
449
- "𖩢",
450
- "𖩣",
451
- "𖩤",
452
- "𖩥",
453
- "𖩦",
454
- "𖩧",
455
- "𖩨",
456
- "𖩩"
457
- ],
458
- "mtei": [
459
- "꯰",
460
- "꯱",
461
- "꯲",
462
- "꯳",
463
- "꯴",
464
- "꯵",
465
- "꯶",
466
- "꯷",
467
- "꯸",
468
- "꯹"
469
- ],
470
- "mymr": [
471
- "၀",
472
- "၁",
473
- "၂",
474
- "၃",
475
- "၄",
476
- "၅",
477
- "၆",
478
- "၇",
479
- "၈",
480
- "၉"
481
- ],
482
- "mymrshan": [
483
- "႐",
484
- "႑",
485
- "႒",
486
- "႓",
487
- "႔",
488
- "႕",
489
- "႖",
490
- "႗",
491
- "႘",
492
- "႙"
493
- ],
494
- "mymrtlng": [
495
- "꧰",
496
- "꧱",
497
- "꧲",
498
- "꧳",
499
- "꧴",
500
- "꧵",
501
- "꧶",
502
- "꧷",
503
- "꧸",
504
- "꧹"
505
- ],
506
- "newa": [
507
- "𑑐",
508
- "𑑑",
509
- "𑑒",
510
- "𑑓",
511
- "𑑔",
512
- "𑑕",
513
- "𑑖",
514
- "𑑗",
515
- "𑑘",
516
- "𑑙"
517
- ],
518
- "nkoo": [
519
- "߀",
520
- "߁",
521
- "߂",
522
- "߃",
523
- "߄",
524
- "߅",
525
- "߆",
526
- "߇",
527
- "߈",
528
- "߉"
529
- ],
530
- "olck": [
531
- "᱐",
532
- "᱑",
533
- "᱒",
534
- "᱓",
535
- "᱔",
536
- "᱕",
537
- "᱖",
538
- "᱗",
539
- "᱘",
540
- "᱙"
541
- ],
542
- "orya": [
543
- "୦",
544
- "୧",
545
- "୨",
546
- "୩",
547
- "୪",
548
- "୫",
549
- "୬",
550
- "୭",
551
- "୮",
552
- "୯"
553
- ],
554
- "osma": [
555
- "𐒠",
556
- "𐒡",
557
- "𐒢",
558
- "𐒣",
559
- "𐒤",
560
- "𐒥",
561
- "𐒦",
562
- "𐒧",
563
- "𐒨",
564
- "𐒩"
565
- ],
566
- "rohg": [
567
- "𐴰",
568
- "𐴱",
569
- "𐴲",
570
- "𐴳",
571
- "𐴴",
572
- "𐴵",
573
- "𐴶",
574
- "𐴷",
575
- "𐴸",
576
- "𐴹"
577
- ],
578
- "saur": [
579
- "꣐",
580
- "꣑",
581
- "꣒",
582
- "꣓",
583
- "꣔",
584
- "꣕",
585
- "꣖",
586
- "꣗",
587
- "꣘",
588
- "꣙"
589
- ],
590
- "segment": [
591
- "🯰",
592
- "🯱",
593
- "🯲",
594
- "🯳",
595
- "🯴",
596
- "🯵",
597
- "🯶",
598
- "🯷",
599
- "🯸",
600
- "🯹"
601
- ],
602
- "shrd": [
603
- "𑇐",
604
- "𑇑",
605
- "𑇒",
606
- "𑇓",
607
- "𑇔",
608
- "𑇕",
609
- "𑇖",
610
- "𑇗",
611
- "𑇘",
612
- "𑇙"
613
- ],
614
- "sind": [
615
- "𑋰",
616
- "𑋱",
617
- "𑋲",
618
- "𑋳",
619
- "𑋴",
620
- "𑋵",
621
- "𑋶",
622
- "𑋷",
623
- "𑋸",
624
- "𑋹"
625
- ],
626
- "sinh": [
627
- "෦",
628
- "෧",
629
- "෨",
630
- "෩",
631
- "෪",
632
- "෫",
633
- "෬",
634
- "෭",
635
- "෮",
636
- "෯"
637
- ],
638
- "sora": [
639
- "𑃰",
640
- "𑃱",
641
- "𑃲",
642
- "𑃳",
643
- "𑃴",
644
- "𑃵",
645
- "𑃶",
646
- "𑃷",
647
- "𑃸",
648
- "𑃹"
649
- ],
650
- "sund": [
651
- "᮰",
652
- "᮱",
653
- "᮲",
654
- "᮳",
655
- "᮴",
656
- "᮵",
657
- "᮶",
658
- "᮷",
659
- "᮸",
660
- "᮹"
661
- ],
662
- "takr": [
663
- "𑛀",
664
- "𑛁",
665
- "𑛂",
666
- "𑛃",
667
- "𑛄",
668
- "𑛅",
669
- "𑛆",
670
- "𑛇",
671
- "𑛈",
672
- "𑛉"
673
- ],
674
- "talu": [
675
- "᧐",
676
- "᧑",
677
- "᧒",
678
- "᧓",
679
- "᧔",
680
- "᧕",
681
- "᧖",
682
- "᧗",
683
- "᧘",
684
- "᧙"
685
- ],
686
- "tamldec": [
687
- "௦",
688
- "௧",
689
- "௨",
690
- "௩",
691
- "௪",
692
- "௫",
693
- "௬",
694
- "௭",
695
- "௮",
696
- "௯"
697
- ],
698
- "telu": [
699
- "౦",
700
- "౧",
701
- "౨",
702
- "౩",
703
- "౪",
704
- "౫",
705
- "౬",
706
- "౭",
707
- "౮",
708
- "౯"
709
- ],
710
- "thai": [
711
- "๐",
712
- "๑",
713
- "๒",
714
- "๓",
715
- "๔",
716
- "๕",
717
- "๖",
718
- "๗",
719
- "๘",
720
- "๙"
721
- ],
722
- "tibt": [
723
- "༠",
724
- "༡",
725
- "༢",
726
- "༣",
727
- "༤",
728
- "༥",
729
- "༦",
730
- "༧",
731
- "༨",
732
- "༩"
733
- ],
734
- "tirh": [
735
- "𑓐",
736
- "𑓑",
737
- "𑓒",
738
- "𑓓",
739
- "𑓔",
740
- "𑓕",
741
- "𑓖",
742
- "𑓗",
743
- "𑓘",
744
- "𑓙"
745
- ],
746
- "vaii": [
747
- "ᘠ",
748
- "ᘡ",
749
- "ᘢ",
750
- "ᘣ",
751
- "ᘤ",
752
- "ᘥ",
753
- "ᘦ",
754
- "ᘧ",
755
- "ᘨ",
756
- "ᘩ"
757
- ],
758
- "wara": [
759
- "𑣠",
760
- "𑣡",
761
- "𑣢",
762
- "𑣣",
763
- "𑣤",
764
- "𑣥",
765
- "𑣦",
766
- "𑣧",
767
- "𑣨",
768
- "𑣩"
769
- ],
770
- "wcho": [
771
- "𞋰",
772
- "𞋱",
773
- "𞋲",
774
- "𞋳",
775
- "𞋴",
776
- "𞋵",
777
- "𞋶",
778
- "𞋷",
779
- "𞋸",
780
- "𞋹"
781
- ]
2
+ adlm: ['𞥐', '𞥑', '𞥒', '𞥓', '𞥔', '𞥕', '𞥖', '𞥗', '𞥘', '𞥙'],
3
+ ahom: ['𑜰', '𑜱', '𑜲', '𑜳', '𑜴', '𑜵', '𑜶', '𑜷', '𑜸', '𑜹'],
4
+ arab: ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'],
5
+ arabext: ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'],
6
+ bali: ['᭐', '᭑', '᭒', '᭓', '᭔', '᭕', '᭖', '᭗', '᭘', '᭙'],
7
+ beng: ['০', '১', '২', '৩', '৪', '৫', '৬', '৭', '৮', '৯'],
8
+ bhks: ['𑱐', '𑱑', '𑱒', '𑱓', '𑱔', '𑱕', '𑱖', '𑱗', '𑱘', '𑱙'],
9
+ brah: ['𑁦', '𑁧', '𑁨', '𑁩', '𑁪', '𑁫', '𑁬', '𑁭', '𑁮', '𑁯'],
10
+ cakm: ['𑄶', '𑄷', '𑄸', '𑄹', '𑄺', '𑄻', '𑄼', '𑄽', '𑄾', '𑄿'],
11
+ cham: ['꩐', '꩑', '꩒', '꩓', '꩔', '꩕', '꩖', '꩗', '꩘', '꩙'],
12
+ deva: ['०', '१', '२', '३', '४', '५', '६', '७', '८', '९'],
13
+ diak: ['𑥐', '𑥑', '𑥒', '𑥓', '𑥔', '𑥕', '𑥖', '𑥗', '𑥘', '𑥙'],
14
+ fullwide: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
15
+ gong: ['𑶠', '𑶡', '𑶢', '𑶣', '𑶤', '𑶥', '𑶦', '𑶧', '𑶨', '𑶩'],
16
+ gonm: ['𑵐', '𑵑', '𑵒', '𑵓', '𑵔', '𑵕', '𑵖', '𑵗', '𑵘', '𑵙'],
17
+ gujr: ['૦', '૧', '૨', '૩', '૪', '૫', '૬', '૭', '૮', '૯'],
18
+ guru: ['੦', '੧', '੨', '੩', '੪', '੫', '੬', '੭', '੮', '੯'],
19
+ hanidec: ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九'],
20
+ hmng: ['𖭐', '𖭑', '𖭒', '𖭓', '𖭔', '𖭕', '𖭖', '𖭗', '𖭘', '𖭙'],
21
+ hmnp: ['𞅀', '𞅁', '𞅂', '𞅃', '𞅄', '𞅅', '𞅆', '𞅇', '𞅈', '𞅉'],
22
+ java: ['꧐', '꧑', '꧒', '꧓', '꧔', '꧕', '꧖', '꧗', '꧘', '꧙'],
23
+ kali: ['꤀', '꤁', '꤂', '꤃', '꤄', '꤅', '꤆', '꤇', '꤈', '꤉'],
24
+ khmr: ['០', '១', '២', '៣', '៤', '៥', '៦', '៧', '៨', '៩'],
25
+ knda: ['೦', '೧', '೨', '೩', '೪', '೫', '೬', '೭', '೮', '೯'],
26
+ lana: ['᪀', '᪁', '᪂', '᪃', '᪄', '᪅', '᪆', '᪇', '᪈', '᪉'],
27
+ lanatham: ['᪐', '᪑', '᪒', '᪓', '᪔', '᪕', '᪖', '᪗', '᪘', '᪙'],
28
+ laoo: ['໐', '໑', '໒', '໓', '໔', '໕', '໖', '໗', '໘', '໙'],
29
+ lepc: ['᪐', '᪑', '᪒', '᪓', '᪔', '᪕', '᪖', '᪗', '᪘', '᪙'],
30
+ limb: ['᥆', '᥇', '᥈', '᥉', '᥊', '᥋', '᥌', '᥍', '᥎', '᥏'],
31
+ mathbold: ['𝟎', '𝟏', '𝟐', '𝟑', '𝟒', '𝟓', '𝟔', '𝟕', '𝟖', '𝟗'],
32
+ mathdbl: ['𝟘', '𝟙', '𝟚', '𝟛', '𝟜', '𝟝', '𝟞', '𝟟', '𝟠', '𝟡'],
33
+ mathmono: ['𝟶', '𝟷', '𝟸', '𝟹', '𝟺', '𝟻', '𝟼', '𝟽', '𝟾', '𝟿'],
34
+ mathsanb: ['𝟬', '𝟭', '𝟮', '𝟯', '𝟰', '𝟱', '𝟲', '𝟳', '𝟴', '𝟵'],
35
+ mathsans: ['𝟢', '𝟣', '𝟤', '𝟥', '𝟦', '𝟧', '𝟨', '𝟩', '𝟪', '𝟫'],
36
+ mlym: ['൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯'],
37
+ modi: ['𑙐', '𑙑', '𑙒', '𑙓', '𑙔', '𑙕', '𑙖', '𑙗', '𑙘', '𑙙'],
38
+ mong: ['᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙'],
39
+ mroo: ['𖩠', '𖩡', '𖩢', '𖩣', '𖩤', '𖩥', '𖩦', '𖩧', '𖩨', '𖩩'],
40
+ mtei: ['꯰', '꯱', '꯲', '꯳', '꯴', '꯵', '꯶', '꯷', '꯸', '꯹'],
41
+ mymr: ['၀', '၁', '၂', '၃', '၄', '၅', '၆', '၇', '၈', '၉'],
42
+ mymrshan: ['႐', '႑', '႒', '႓', '႔', '႕', '႖', '႗', '႘', '႙'],
43
+ mymrtlng: ['꧰', '꧱', '꧲', '꧳', '꧴', '꧵', '꧶', '꧷', '꧸', '꧹'],
44
+ newa: ['𑑐', '𑑑', '𑑒', '𑑓', '𑑔', '𑑕', '𑑖', '𑑗', '𑑘', '𑑙'],
45
+ nkoo: ['߀', '߁', '߂', '߃', '߄', '߅', '߆', '߇', '߈', '߉'],
46
+ olck: ['᱐', '᱑', '᱒', '᱓', '᱔', '᱕', '᱖', '᱗', '᱘', '᱙'],
47
+ orya: ['୦', '୧', '୨', '୩', '୪', '୫', '୬', '୭', '୮', '୯'],
48
+ osma: ['𐒠', '𐒡', '𐒢', '𐒣', '𐒤', '𐒥', '𐒦', '𐒧', '𐒨', '𐒩'],
49
+ rohg: ['𐴰', '𐴱', '𐴲', '𐴳', '𐴴', '𐴵', '𐴶', '𐴷', '𐴸', '𐴹'],
50
+ saur: ['꣐', '꣑', '꣒', '꣓', '꣔', '꣕', '꣖', '꣗', '꣘', '꣙'],
51
+ segment: ['🯰', '🯱', '🯲', '🯳', '🯴', '🯵', '🯶', '🯷', '🯸', '🯹'],
52
+ shrd: ['𑇐', '𑇑', '𑇒', '𑇓', '𑇔', '𑇕', '𑇖', '𑇗', '𑇘', '𑇙'],
53
+ sind: ['𑋰', '𑋱', '𑋲', '𑋳', '𑋴', '𑋵', '𑋶', '𑋷', '𑋸', '𑋹'],
54
+ sinh: ['෦', '෧', '෨', '෩', '෪', '෫', '෬', '෭', '෮', '෯'],
55
+ sora: ['𑃰', '𑃱', '𑃲', '𑃳', '𑃴', '𑃵', '𑃶', '𑃷', '𑃸', '𑃹'],
56
+ sund: ['᮰', '᮱', '᮲', '᮳', '᮴', '᮵', '᮶', '᮷', '᮸', '᮹'],
57
+ takr: ['𑛀', '𑛁', '𑛂', '𑛃', '𑛄', '𑛅', '𑛆', '𑛇', '𑛈', '𑛉'],
58
+ talu: ['᧐', '᧑', '᧒', '᧓', '᧔', '᧕', '᧖', '᧗', '᧘', '᧙'],
59
+ tamldec: ['௦', '௧', '௨', '௩', '௪', '௫', '௬', '௭', '௮', '௯'],
60
+ telu: ['౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯'],
61
+ thai: ['๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙'],
62
+ tibt: ['༠', '༡', '༢', '༣', '༤', '༥', '༦', '༧', '༨', '༩'],
63
+ tirh: ['𑓐', '𑓑', '𑓒', '𑓓', '𑓔', '𑓕', '𑓖', '𑓗', '𑓘', '𑓙'],
64
+ vaii: ['ᘠ', 'ᘡ', 'ᘢ', 'ᘣ', 'ᘤ', 'ᘥ', 'ᘦ', 'ᘧ', 'ᘨ', 'ᘩ'],
65
+ wara: ['𑣠', '𑣡', '𑣢', '𑣣', '𑣤', '𑣥', '𑣦', '𑣧', '𑣨', '𑣩'],
66
+ wcho: ['𞋰', '𞋱', '𞋲', '𞋳', '𞋴', '𞋵', '𞋶', '𞋷', '𞋸', '𞋹'],
782
67
  };
@@ -398,7 +398,7 @@ function getPatternForSign(pattern, sign) {
398
398
  //
399
399
  // Returning null means the compact display pattern cannot be found.
400
400
  function getCompactDisplayPattern(numberResult, pl, data, style, compactDisplay, currencyDisplay, numberingSystem) {
401
- var _a;
401
+ var _a, _b;
402
402
  var roundedNumber = numberResult.roundedNumber, sign = numberResult.sign, magnitude = numberResult.magnitude;
403
403
  var magnitudeKey = String(Math.pow(10, magnitude));
404
404
  var defaultNumberingSystem = data.numbers.nu[0];
@@ -409,6 +409,15 @@ function getCompactDisplayPattern(numberResult, pl, data, style, compactDisplay,
409
409
  byNumberingSystem[defaultNumberingSystem];
410
410
  // NOTE: compact notation ignores currencySign!
411
411
  var compactPluralRules = (_a = currencyData.short) === null || _a === void 0 ? void 0 : _a[magnitudeKey];
412
+ // GH #4236: If magnitude exceeds available patterns, use the largest available
413
+ if (!compactPluralRules) {
414
+ var thresholds = Object.keys(currencyData.short || {});
415
+ if (thresholds.length > 0 &&
416
+ magnitudeKey > thresholds[thresholds.length - 1]) {
417
+ magnitudeKey = thresholds[thresholds.length - 1];
418
+ compactPluralRules = (_b = currencyData.short) === null || _b === void 0 ? void 0 : _b[magnitudeKey];
419
+ }
420
+ }
412
421
  if (!compactPluralRules) {
413
422
  return null;
414
423
  }
@@ -419,6 +428,15 @@ function getCompactDisplayPattern(numberResult, pl, data, style, compactDisplay,
419
428
  var byCompactDisplay = byNumberingSystem[numberingSystem] ||
420
429
  byNumberingSystem[defaultNumberingSystem];
421
430
  var compactPlaralRule = byCompactDisplay[compactDisplay][magnitudeKey];
431
+ // GH #4236: If magnitude exceeds available patterns, use the largest available
432
+ if (!compactPlaralRule) {
433
+ var thresholds = Object.keys(byCompactDisplay[compactDisplay]);
434
+ if (thresholds.length > 0 &&
435
+ magnitudeKey > thresholds[thresholds.length - 1]) {
436
+ magnitudeKey = thresholds[thresholds.length - 1];
437
+ compactPlaralRule = byCompactDisplay[compactDisplay][magnitudeKey];
438
+ }
439
+ }
422
440
  if (!compactPlaralRule) {
423
441
  return null;
424
442
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@formatjs/ecma402-abstract",
3
3
  "description": "A collection of implementation for ECMAScript abstract operations",
4
- "version": "3.0.6",
4
+ "version": "3.0.7",
5
5
  "license": "MIT",
6
6
  "author": "Long Ho <holevietlong@gmail.com",
7
7
  "type": "module",
@@ -13,8 +13,8 @@
13
13
  "dependencies": {
14
14
  "decimal.js": "^10.4.3",
15
15
  "tslib": "^2.8.0",
16
- "@formatjs/fast-memoize": "3.0.1",
17
- "@formatjs/intl-localematcher": "0.7.3"
16
+ "@formatjs/intl-localematcher": "0.7.4",
17
+ "@formatjs/fast-memoize": "3.0.2"
18
18
  },
19
19
  "bugs": "https://github.com/formatjs/formatjs/issues",
20
20
  "gitHead": "a7842673d8ad205171ad7c8cb8bb2f318b427c0c",