n2words 5.0.0 → 5.1.1
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.
- package/CHANGELOG.md +133 -40
- package/README.md +6 -4
- package/dist/am-ET.js +2 -2
- package/dist/am-ET.umd.js +2 -2
- package/dist/am-Latn-ET.js +2 -2
- package/dist/am-Latn-ET.umd.js +2 -2
- package/dist/ar-SA.js +2 -2
- package/dist/ar-SA.umd.js +2 -2
- package/dist/az-AZ.js +2 -2
- package/dist/az-AZ.umd.js +2 -2
- package/dist/bn-BD.js +2 -2
- package/dist/bn-BD.umd.js +2 -2
- package/dist/cs-CZ.js +2 -2
- package/dist/cs-CZ.umd.js +2 -2
- package/dist/da-DK.js +2 -2
- package/dist/da-DK.umd.js +2 -2
- package/dist/de-DE.js +2 -2
- package/dist/de-DE.umd.js +2 -2
- package/dist/el-GR.js +2 -2
- package/dist/el-GR.umd.js +2 -2
- package/dist/en-AU.js +2 -2
- package/dist/en-AU.umd.js +2 -2
- package/dist/en-BD.js +2 -2
- package/dist/en-BD.umd.js +2 -2
- package/dist/en-CA.js +2 -2
- package/dist/en-CA.umd.js +2 -2
- package/dist/en-GB.js +2 -2
- package/dist/en-GB.umd.js +2 -2
- package/dist/en-GH.js +2 -2
- package/dist/en-GH.umd.js +2 -2
- package/dist/en-IE.js +2 -2
- package/dist/en-IE.umd.js +2 -2
- package/dist/en-IN.js +2 -2
- package/dist/en-IN.umd.js +2 -2
- package/dist/en-KE.js +2 -2
- package/dist/en-KE.umd.js +2 -2
- package/dist/en-MY.js +2 -2
- package/dist/en-MY.umd.js +2 -2
- package/dist/en-NG.js +2 -2
- package/dist/en-NG.umd.js +2 -2
- package/dist/en-NZ.js +2 -2
- package/dist/en-NZ.umd.js +2 -2
- package/dist/en-PH.js +2 -2
- package/dist/en-PH.umd.js +2 -2
- package/dist/en-PK.js +2 -2
- package/dist/en-PK.umd.js +2 -2
- package/dist/en-SG.js +2 -2
- package/dist/en-SG.umd.js +2 -2
- package/dist/en-US.js +2 -2
- package/dist/en-US.umd.js +2 -2
- package/dist/en-ZA.js +2 -2
- package/dist/en-ZA.umd.js +2 -2
- package/dist/es-ES.js +2 -2
- package/dist/es-ES.umd.js +2 -2
- package/dist/es-MX.js +2 -2
- package/dist/es-MX.umd.js +2 -2
- package/dist/es-US.js +2 -2
- package/dist/es-US.umd.js +2 -2
- package/dist/fa-IR.js +2 -2
- package/dist/fa-IR.umd.js +2 -2
- package/dist/fi-FI.js +2 -2
- package/dist/fi-FI.umd.js +2 -2
- package/dist/fil-PH.js +2 -2
- package/dist/fil-PH.umd.js +2 -2
- package/dist/fr-BE.js +2 -2
- package/dist/fr-BE.umd.js +2 -2
- package/dist/fr-FR.js +2 -2
- package/dist/fr-FR.umd.js +2 -2
- package/dist/gu-IN.js +2 -2
- package/dist/gu-IN.umd.js +2 -2
- package/dist/ha-NG.js +2 -2
- package/dist/ha-NG.umd.js +2 -2
- package/dist/hbo-IL.js +2 -2
- package/dist/hbo-IL.umd.js +2 -2
- package/dist/he-IL.js +2 -2
- package/dist/he-IL.umd.js +2 -2
- package/dist/hi-IN.js +2 -2
- package/dist/hi-IN.umd.js +2 -2
- package/dist/hr-HR.js +2 -2
- package/dist/hr-HR.umd.js +2 -2
- package/dist/hu-HU.js +2 -2
- package/dist/hu-HU.umd.js +2 -2
- package/dist/id-ID.js +2 -2
- package/dist/id-ID.umd.js +2 -2
- package/dist/it-IT.js +2 -2
- package/dist/it-IT.umd.js +2 -2
- package/dist/ja-JP.js +2 -2
- package/dist/ja-JP.umd.js +2 -2
- package/dist/ka-GE.js +2 -2
- package/dist/ka-GE.umd.js +2 -2
- package/dist/kn-IN.js +2 -2
- package/dist/kn-IN.umd.js +2 -2
- package/dist/ko-KR.js +2 -2
- package/dist/ko-KR.umd.js +2 -2
- package/dist/lt-LT.js +2 -2
- package/dist/lt-LT.umd.js +2 -2
- package/dist/lv-LV.js +2 -2
- package/dist/lv-LV.umd.js +2 -2
- package/dist/mr-IN.js +2 -2
- package/dist/mr-IN.umd.js +2 -2
- package/dist/ms-MY.js +2 -2
- package/dist/ms-MY.umd.js +2 -2
- package/dist/nb-NO.js +2 -2
- package/dist/nb-NO.umd.js +2 -2
- package/dist/nl-NL.js +2 -2
- package/dist/nl-NL.umd.js +2 -2
- package/dist/pa-IN.js +2 -2
- package/dist/pa-IN.umd.js +2 -2
- package/dist/pl-PL.js +2 -2
- package/dist/pl-PL.umd.js +2 -2
- package/dist/pt-BR.js +2 -2
- package/dist/pt-BR.umd.js +2 -2
- package/dist/pt-PT.js +2 -2
- package/dist/pt-PT.umd.js +2 -2
- package/dist/ro-RO.js +2 -2
- package/dist/ro-RO.umd.js +2 -2
- package/dist/ru-RU.js +2 -2
- package/dist/ru-RU.umd.js +2 -2
- package/dist/sr-Cyrl-RS.js +2 -2
- package/dist/sr-Cyrl-RS.umd.js +2 -2
- package/dist/sr-Latn-RS.js +2 -2
- package/dist/sr-Latn-RS.umd.js +2 -2
- package/dist/sv-SE.js +2 -2
- package/dist/sv-SE.umd.js +2 -2
- package/dist/sw-KE.js +2 -2
- package/dist/sw-KE.umd.js +2 -2
- package/dist/ta-IN.js +2 -2
- package/dist/ta-IN.umd.js +2 -2
- package/dist/te-IN.js +2 -2
- package/dist/te-IN.umd.js +2 -2
- package/dist/th-TH.js +2 -2
- package/dist/th-TH.umd.js +2 -2
- package/dist/tr-TR.js +2 -2
- package/dist/tr-TR.umd.js +2 -2
- package/dist/uk-UA.js +2 -2
- package/dist/uk-UA.umd.js +2 -2
- package/dist/ur-PK.js +2 -2
- package/dist/ur-PK.umd.js +2 -2
- package/dist/vi-VN.js +2 -2
- package/dist/vi-VN.umd.js +2 -2
- package/dist/yo-NG.js +2 -2
- package/dist/yo-NG.umd.js +2 -2
- package/dist/zh-Hans-CN.js +2 -2
- package/dist/zh-Hans-CN.umd.js +2 -2
- package/dist/zh-Hant-TW.js +2 -2
- package/dist/zh-Hant-TW.umd.js +2 -2
- package/package.json +33 -24
- package/src/am-ET.d.ts +3 -5
- package/src/am-ET.js +41 -16
- package/src/am-Latn-ET.d.ts +3 -5
- package/src/am-Latn-ET.js +45 -16
- package/src/ar-SA.d.ts +44 -18
- package/src/ar-SA.js +93 -40
- package/src/az-AZ.d.ts +3 -5
- package/src/az-AZ.js +58 -20
- package/src/bn-BD.d.ts +3 -5
- package/src/bn-BD.js +32 -16
- package/src/cs-CZ.d.ts +3 -6
- package/src/cs-CZ.js +66 -42
- package/src/da-DK.d.ts +3 -6
- package/src/da-DK.js +53 -48
- package/src/de-DE.d.ts +17 -11
- package/src/de-DE.js +88 -57
- package/src/el-GR.d.ts +3 -6
- package/src/el-GR.js +45 -32
- package/src/en-AU.d.ts +17 -11
- package/src/en-AU.js +56 -41
- package/src/en-BD.d.ts +17 -11
- package/src/en-BD.js +60 -41
- package/src/en-CA.d.ts +36 -18
- package/src/en-CA.js +67 -46
- package/src/en-GB.d.ts +17 -11
- package/src/en-GB.js +56 -41
- package/src/en-GH.d.ts +32 -3
- package/src/en-GH.js +104 -26
- package/src/en-IE.d.ts +17 -11
- package/src/en-IE.js +56 -41
- package/src/en-IN.d.ts +17 -11
- package/src/en-IN.js +60 -41
- package/src/en-KE.d.ts +28 -3
- package/src/en-KE.js +93 -26
- package/src/en-MY.d.ts +26 -3
- package/src/en-MY.js +91 -26
- package/src/en-NG.d.ts +17 -11
- package/src/en-NG.js +56 -41
- package/src/en-NZ.d.ts +32 -3
- package/src/en-NZ.js +85 -31
- package/src/en-PH.d.ts +32 -3
- package/src/en-PH.js +97 -26
- package/src/en-PK.d.ts +17 -11
- package/src/en-PK.js +60 -41
- package/src/en-SG.d.ts +28 -3
- package/src/en-SG.js +93 -26
- package/src/en-US.d.ts +36 -18
- package/src/en-US.js +70 -47
- package/src/en-ZA.d.ts +17 -11
- package/src/en-ZA.js +56 -41
- package/src/es-ES.d.ts +53 -21
- package/src/es-ES.js +104 -56
- package/src/es-MX.d.ts +53 -21
- package/src/es-MX.js +104 -56
- package/src/es-US.d.ts +53 -21
- package/src/es-US.js +92 -51
- package/src/fa-IR.d.ts +3 -5
- package/src/fa-IR.js +28 -13
- package/src/fi-FI.d.ts +3 -6
- package/src/fi-FI.js +47 -29
- package/src/fil-PH.d.ts +3 -5
- package/src/fil-PH.js +61 -28
- package/src/fr-BE.d.ts +31 -15
- package/src/fr-BE.js +128 -57
- package/src/fr-FR.d.ts +31 -16
- package/src/fr-FR.js +97 -60
- package/src/gu-IN.d.ts +3 -5
- package/src/gu-IN.js +31 -16
- package/src/ha-NG.d.ts +3 -5
- package/src/ha-NG.js +55 -27
- package/src/hbo-IL.d.ts +26 -12
- package/src/hbo-IL.js +92 -51
- package/src/he-IL.d.ts +17 -10
- package/src/he-IL.js +92 -50
- package/src/hi-IN.d.ts +3 -5
- package/src/hi-IN.js +30 -17
- package/src/hr-HR.d.ts +21 -10
- package/src/hr-HR.js +89 -33
- package/src/hu-HU.d.ts +3 -5
- package/src/hu-HU.js +57 -23
- package/src/id-ID.d.ts +3 -5
- package/src/id-ID.js +56 -23
- package/src/it-IT.d.ts +17 -11
- package/src/it-IT.js +74 -43
- package/src/ja-JP.d.ts +3 -6
- package/src/ja-JP.js +39 -26
- package/src/ka-GE.d.ts +3 -6
- package/src/ka-GE.js +38 -26
- package/src/kn-IN.d.ts +3 -5
- package/src/kn-IN.js +31 -16
- package/src/ko-KR.d.ts +3 -6
- package/src/ko-KR.js +34 -26
- package/src/lt-LT.d.ts +21 -11
- package/src/lt-LT.js +64 -42
- package/src/lv-LV.d.ts +21 -11
- package/src/lv-LV.js +79 -51
- package/src/mr-IN.d.ts +3 -5
- package/src/mr-IN.js +31 -16
- package/src/ms-MY.d.ts +3 -5
- package/src/ms-MY.js +58 -24
- package/src/nb-NO.d.ts +3 -6
- package/src/nb-NO.js +54 -34
- package/src/nl-NL.d.ts +41 -20
- package/src/nl-NL.js +111 -69
- package/src/pa-IN.d.ts +3 -5
- package/src/pa-IN.js +32 -16
- package/src/pl-PL.d.ts +21 -11
- package/src/pl-PL.js +69 -45
- package/src/pt-BR.d.ts +22 -11
- package/src/pt-BR.js +93 -53
- package/src/pt-PT.d.ts +17 -11
- package/src/pt-PT.js +80 -48
- package/src/ro-RO.d.ts +21 -11
- package/src/ro-RO.js +77 -39
- package/src/ru-RU.d.ts +35 -15
- package/src/ru-RU.js +100 -38
- package/src/sr-Cyrl-RS.d.ts +35 -15
- package/src/sr-Cyrl-RS.js +106 -43
- package/src/sr-Latn-RS.d.ts +35 -15
- package/src/sr-Latn-RS.js +106 -43
- package/src/sv-SE.d.ts +3 -6
- package/src/sv-SE.js +53 -34
- package/src/sw-KE.d.ts +3 -5
- package/src/sw-KE.js +50 -20
- package/src/ta-IN.d.ts +3 -5
- package/src/ta-IN.js +29 -17
- package/src/te-IN.d.ts +3 -5
- package/src/te-IN.js +31 -16
- package/src/th-TH.d.ts +3 -5
- package/src/th-TH.js +42 -19
- package/src/tr-TR.d.ts +17 -11
- package/src/tr-TR.js +63 -37
- package/src/uk-UA.d.ts +21 -10
- package/src/uk-UA.js +89 -33
- package/src/ur-PK.d.ts +3 -5
- package/src/ur-PK.js +32 -16
- package/src/utils/check-max.d.ts +26 -0
- package/src/utils/check-max.js +33 -0
- package/src/utils/expand-scientific.d.ts +0 -4
- package/src/utils/expand-scientific.js +7 -9
- package/src/utils/is-plain-object.d.ts +3 -4
- package/src/utils/is-plain-object.js +3 -4
- package/src/utils/parse-cardinal.d.ts +1 -2
- package/src/utils/parse-cardinal.js +12 -9
- package/src/utils/parse-currency.d.ts +1 -2
- package/src/utils/parse-currency.js +9 -11
- package/src/utils/parse-ordinal.d.ts +0 -1
- package/src/utils/parse-ordinal.js +9 -10
- package/src/utils/resolve-options.d.ts +17 -0
- package/src/utils/resolve-options.js +56 -0
- package/src/utils/scale.d.ts +49 -0
- package/src/utils/scale.js +65 -0
- package/src/vi-VN.d.ts +3 -6
- package/src/vi-VN.js +41 -28
- package/src/yo-NG.d.ts +3 -5
- package/src/yo-NG.js +49 -33
- package/src/zh-Hans-CN.d.ts +45 -20
- package/src/zh-Hans-CN.js +84 -31
- package/src/zh-Hant-TW.d.ts +45 -20
- package/src/zh-Hant-TW.js +85 -34
- package/src/utils/validate-options.d.ts +0 -8
- package/src/utils/validate-options.js +0 -16
package/src/ko-KR.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
export const cardinalMax: bigint;
|
|
2
|
+
export const ordinalMax: bigint;
|
|
3
|
+
export const currencyMax: bigint;
|
|
1
4
|
/**
|
|
2
5
|
* Converts a numeric value to Korean words.
|
|
3
|
-
*
|
|
4
6
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
7
|
* @returns {string} The number in Korean words
|
|
6
8
|
* @throws {TypeError} If value is not a valid numeric type
|
|
7
9
|
* @throws {Error} If value is not a valid number format
|
|
8
|
-
*
|
|
9
10
|
* @example
|
|
10
11
|
* toCardinal(21) // '이십일'
|
|
11
12
|
* toCardinal(10000) // '만'
|
|
@@ -14,12 +15,10 @@
|
|
|
14
15
|
export function toCardinal(value: number | string | bigint): string;
|
|
15
16
|
/**
|
|
16
17
|
* Converts a numeric value to Korean ordinal words.
|
|
17
|
-
*
|
|
18
18
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
19
19
|
* @returns {string} The number as ordinal words
|
|
20
20
|
* @throws {TypeError} If value is not a valid numeric type
|
|
21
21
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
22
|
-
*
|
|
23
22
|
* @example
|
|
24
23
|
* toOrdinal(1) // '제일'
|
|
25
24
|
* toOrdinal(2) // '제이'
|
|
@@ -31,12 +30,10 @@ export function toOrdinal(value: number | string | bigint): string;
|
|
|
31
30
|
*
|
|
32
31
|
* Korean Won has no subunit (jeon are historical).
|
|
33
32
|
* Amounts are rounded to whole won.
|
|
34
|
-
*
|
|
35
33
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
36
34
|
* @returns {string} The amount in Korean currency words
|
|
37
35
|
* @throws {TypeError} If value is not a valid numeric type
|
|
38
36
|
* @throws {Error} If value is not a valid number format
|
|
39
|
-
*
|
|
40
37
|
* @example
|
|
41
38
|
* toCurrency(42) // '사십이원'
|
|
42
39
|
* toCurrency(1000) // '천원'
|
package/src/ko-KR.js
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
14
14
|
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
15
15
|
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
16
|
+
import { checkMax } from './utils/check-max.js'
|
|
17
|
+
import { myriad } from './utils/scale.js'
|
|
16
18
|
|
|
17
19
|
// ============================================================================
|
|
18
20
|
// Vocabulary (module-level constants)
|
|
@@ -32,6 +34,13 @@ const DECIMAL_SEP = '점'
|
|
|
32
34
|
// 만 (10^4), 억 (10^8), 조 (10^12), 경 (10^16), etc.
|
|
33
35
|
const SCALES = ['만', '억', '조', '경', '해', '자', '양']
|
|
34
36
|
|
|
37
|
+
// Myriad (4-digit) grouping: each scale word covers a power of 10,000, so the
|
|
38
|
+
// first unsupported value is 10^((SCALES.length + 1) * 4). Ordinals and currency
|
|
39
|
+
// build on the cardinal speller, so they share its ceiling.
|
|
40
|
+
export const cardinalMax = myriad(SCALES.length)
|
|
41
|
+
export const ordinalMax = myriad(SCALES.length)
|
|
42
|
+
export const currencyMax = myriad(SCALES.length)
|
|
43
|
+
|
|
35
44
|
// ============================================================================
|
|
36
45
|
// Ordinal Vocabulary
|
|
37
46
|
// ============================================================================
|
|
@@ -51,8 +60,10 @@ const WON = '원'
|
|
|
51
60
|
/**
|
|
52
61
|
* Builds segment word for 0-9999 (4-digit myriad segment).
|
|
53
62
|
* Korean omits "일" before 십, 백, 천.
|
|
63
|
+
* @param {number} n - Segment value (0-9999)
|
|
64
|
+
* @returns {string} Korean words for the segment
|
|
54
65
|
*/
|
|
55
|
-
function buildSegment
|
|
66
|
+
function buildSegment(n) {
|
|
56
67
|
if (n === 0) return ''
|
|
57
68
|
|
|
58
69
|
const ones = n % 10
|
|
@@ -66,7 +77,8 @@ function buildSegment (n) {
|
|
|
66
77
|
if (thousands > 0) {
|
|
67
78
|
if (thousands === 1) {
|
|
68
79
|
result += THOUSAND
|
|
69
|
-
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
70
82
|
result += ONES[thousands] + THOUSAND
|
|
71
83
|
}
|
|
72
84
|
}
|
|
@@ -75,7 +87,8 @@ function buildSegment (n) {
|
|
|
75
87
|
if (hundreds > 0) {
|
|
76
88
|
if (hundreds === 1) {
|
|
77
89
|
result += HUNDRED
|
|
78
|
-
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
79
92
|
result += ONES[hundreds] + HUNDRED
|
|
80
93
|
}
|
|
81
94
|
}
|
|
@@ -84,7 +97,8 @@ function buildSegment (n) {
|
|
|
84
97
|
if (tens > 0) {
|
|
85
98
|
if (tens === 1) {
|
|
86
99
|
result += TEN
|
|
87
|
-
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
88
102
|
result += ONES[tens] + TEN
|
|
89
103
|
}
|
|
90
104
|
}
|
|
@@ -103,11 +117,10 @@ function buildSegment (n) {
|
|
|
103
117
|
|
|
104
118
|
/**
|
|
105
119
|
* Converts a non-negative integer to Korean words.
|
|
106
|
-
*
|
|
107
120
|
* @param {bigint} n - Non-negative integer to convert
|
|
108
121
|
* @returns {string} Korean words
|
|
109
122
|
*/
|
|
110
|
-
function integerToWords
|
|
123
|
+
function integerToWords(n) {
|
|
111
124
|
if (n === 0n) return ZERO
|
|
112
125
|
|
|
113
126
|
// Fast path: numbers < 10000
|
|
@@ -122,11 +135,10 @@ function integerToWords (n) {
|
|
|
122
135
|
/**
|
|
123
136
|
* Builds words for numbers >= 10000.
|
|
124
137
|
* Uses myriad (만) grouping - 4 digits per segment.
|
|
125
|
-
*
|
|
126
138
|
* @param {bigint} n - Number >= 10000
|
|
127
139
|
* @returns {string} Korean words
|
|
128
140
|
*/
|
|
129
|
-
function buildLargeNumberWords
|
|
141
|
+
function buildLargeNumberWords(n) {
|
|
130
142
|
const numStr = n.toString()
|
|
131
143
|
const len = numStr.length
|
|
132
144
|
|
|
@@ -156,14 +168,16 @@ function buildLargeNumberWords (n) {
|
|
|
156
168
|
if (scaleIndex === 0) {
|
|
157
169
|
// Units segment (no scale word)
|
|
158
170
|
parts.push({ word: buildSegment(segment), isScale: false })
|
|
159
|
-
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
160
173
|
// Segment with scale word
|
|
161
174
|
const scaleWord = SCALES[scaleIndex - 1]
|
|
162
175
|
|
|
163
176
|
// Korean omits segment when it's 1 before scale words
|
|
164
177
|
if (segment === 1) {
|
|
165
178
|
parts.push({ word: scaleWord, isScale: true })
|
|
166
|
-
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
167
181
|
parts.push({ word: buildSegment(segment), isScale: false })
|
|
168
182
|
parts.push({ word: scaleWord, isScale: true })
|
|
169
183
|
}
|
|
@@ -181,11 +195,10 @@ function buildLargeNumberWords (n) {
|
|
|
181
195
|
* Joins parts with Korean spacing rules.
|
|
182
196
|
* - Concatenate without spaces within segments
|
|
183
197
|
* - Space after scale words before next number
|
|
184
|
-
*
|
|
185
|
-
* @param {Array} parts - Parts with isScale metadata
|
|
198
|
+
* @param {Array<{word: string, isScale: boolean}>} parts - Parts with isScale metadata
|
|
186
199
|
* @returns {string} Joined string
|
|
187
200
|
*/
|
|
188
|
-
function joinKoreanParts
|
|
201
|
+
function joinKoreanParts(parts) {
|
|
189
202
|
if (parts.length === 0) return ZERO
|
|
190
203
|
if (parts.length === 1) return parts[0].word
|
|
191
204
|
|
|
@@ -208,11 +221,10 @@ function joinKoreanParts (parts) {
|
|
|
208
221
|
|
|
209
222
|
/**
|
|
210
223
|
* Converts decimal digits to Korean words.
|
|
211
|
-
*
|
|
212
224
|
* @param {string} decimalPart - Decimal digits (without the point)
|
|
213
225
|
* @returns {string} Korean words for decimal part (space-separated)
|
|
214
226
|
*/
|
|
215
|
-
function decimalPartToWords
|
|
227
|
+
function decimalPartToWords(decimalPart) {
|
|
216
228
|
const parts = []
|
|
217
229
|
|
|
218
230
|
// Handle leading zeros
|
|
@@ -233,19 +245,18 @@ function decimalPartToWords (decimalPart) {
|
|
|
233
245
|
|
|
234
246
|
/**
|
|
235
247
|
* Converts a numeric value to Korean words.
|
|
236
|
-
*
|
|
237
248
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
238
249
|
* @returns {string} The number in Korean words
|
|
239
250
|
* @throws {TypeError} If value is not a valid numeric type
|
|
240
251
|
* @throws {Error} If value is not a valid number format
|
|
241
|
-
*
|
|
242
252
|
* @example
|
|
243
253
|
* toCardinal(21) // '이십일'
|
|
244
254
|
* toCardinal(10000) // '만'
|
|
245
255
|
* toCardinal(1000000) // '백만'
|
|
246
256
|
*/
|
|
247
|
-
function toCardinal
|
|
257
|
+
function toCardinal(value) {
|
|
248
258
|
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
259
|
+
checkMax(integerPart, cardinalMax, decimalPart)
|
|
249
260
|
|
|
250
261
|
const parts = []
|
|
251
262
|
|
|
@@ -271,29 +282,27 @@ function toCardinal (value) {
|
|
|
271
282
|
* Converts a non-negative integer to Korean ordinal words.
|
|
272
283
|
*
|
|
273
284
|
* Korean ordinals use "제" prefix + Sino-Korean numeral.
|
|
274
|
-
*
|
|
275
285
|
* @param {bigint} n - Positive integer to convert
|
|
276
286
|
* @returns {string} Korean ordinal words
|
|
277
287
|
*/
|
|
278
|
-
function integerToOrdinal
|
|
288
|
+
function integerToOrdinal(n) {
|
|
279
289
|
return ORDINAL_PREFIX + integerToWords(n)
|
|
280
290
|
}
|
|
281
291
|
|
|
282
292
|
/**
|
|
283
293
|
* Converts a numeric value to Korean ordinal words.
|
|
284
|
-
*
|
|
285
294
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
286
295
|
* @returns {string} The number as ordinal words
|
|
287
296
|
* @throws {TypeError} If value is not a valid numeric type
|
|
288
297
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
289
|
-
*
|
|
290
298
|
* @example
|
|
291
299
|
* toOrdinal(1) // '제일'
|
|
292
300
|
* toOrdinal(2) // '제이'
|
|
293
301
|
* toOrdinal(10) // '제십'
|
|
294
302
|
*/
|
|
295
|
-
function toOrdinal
|
|
303
|
+
function toOrdinal(value) {
|
|
296
304
|
const integerPart = parseOrdinalValue(value)
|
|
305
|
+
checkMax(integerPart, ordinalMax)
|
|
297
306
|
return integerToOrdinal(integerPart)
|
|
298
307
|
}
|
|
299
308
|
|
|
@@ -306,19 +315,18 @@ function toOrdinal (value) {
|
|
|
306
315
|
*
|
|
307
316
|
* Korean Won has no subunit (jeon are historical).
|
|
308
317
|
* Amounts are rounded to whole won.
|
|
309
|
-
*
|
|
310
318
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
311
319
|
* @returns {string} The amount in Korean currency words
|
|
312
320
|
* @throws {TypeError} If value is not a valid numeric type
|
|
313
321
|
* @throws {Error} If value is not a valid number format
|
|
314
|
-
*
|
|
315
322
|
* @example
|
|
316
323
|
* toCurrency(42) // '사십이원'
|
|
317
324
|
* toCurrency(1000) // '천원'
|
|
318
325
|
* toCurrency(-5) // '마이너스 오원'
|
|
319
326
|
*/
|
|
320
|
-
function toCurrency
|
|
327
|
+
function toCurrency(value) {
|
|
321
328
|
const { isNegative, dollars: won } = parseCurrencyValue(value)
|
|
329
|
+
checkMax(won, currencyMax)
|
|
322
330
|
|
|
323
331
|
let result = ''
|
|
324
332
|
if (isNegative) {
|
package/src/lt-LT.d.ts
CHANGED
|
@@ -1,29 +1,41 @@
|
|
|
1
|
+
export const cardinalMax: bigint;
|
|
2
|
+
export const ordinalMax: bigint;
|
|
3
|
+
export const currencyMax: bigint;
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {object} CardinalOptions
|
|
6
|
+
* @property {('masculine'|'feminine')} [gender] - Gender for numbers < 1000
|
|
7
|
+
*/
|
|
8
|
+
/** @type {Required<CardinalOptions>} */
|
|
9
|
+
export const cardinalDefaults: Required<CardinalOptions>;
|
|
10
|
+
/** @type {{ gender: ReadonlyArray<Required<CardinalOptions>['gender']> }} */
|
|
11
|
+
export const cardinalValues: {
|
|
12
|
+
gender: ReadonlyArray<Required<CardinalOptions>["gender"]>;
|
|
13
|
+
};
|
|
14
|
+
export type CardinalOptions = {
|
|
15
|
+
/**
|
|
16
|
+
* - Gender for numbers < 1000
|
|
17
|
+
*/
|
|
18
|
+
gender?: "feminine" | "masculine" | undefined;
|
|
19
|
+
};
|
|
1
20
|
/**
|
|
2
21
|
* Converts a numeric value to Lithuanian words.
|
|
3
|
-
*
|
|
4
22
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
-
* @param {
|
|
6
|
-
* @param {string} [options.gender='masculine'] - Gender for numbers < 1000
|
|
23
|
+
* @param {CardinalOptions} [options] - Conversion options
|
|
7
24
|
* @returns {string} The number in Lithuanian words
|
|
8
25
|
* @throws {TypeError} If value is not a valid numeric type
|
|
9
26
|
* @throws {Error} If value is not a valid number format
|
|
10
|
-
*
|
|
11
27
|
* @example
|
|
12
28
|
* toCardinal(42) // 'keturiasdešimt du'
|
|
13
29
|
* toCardinal(1, { gender: 'feminine' }) // 'viena'
|
|
14
30
|
* toCardinal(1000000) // 'vienas milijonas'
|
|
15
31
|
*/
|
|
16
|
-
export function toCardinal(value: number | string | bigint, options?:
|
|
17
|
-
gender?: string | undefined;
|
|
18
|
-
}): string;
|
|
32
|
+
export function toCardinal(value: number | string | bigint, options?: CardinalOptions): string;
|
|
19
33
|
/**
|
|
20
34
|
* Converts a numeric value to Lithuanian ordinal words (masculine nominative).
|
|
21
|
-
*
|
|
22
35
|
* @param {number | string | bigint} value - The numeric value to convert (must be a positive integer)
|
|
23
36
|
* @returns {string} The number as ordinal words
|
|
24
37
|
* @throws {TypeError} If value is not a valid numeric type
|
|
25
38
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
26
|
-
*
|
|
27
39
|
* @example
|
|
28
40
|
* toOrdinal(1) // 'pirmas'
|
|
29
41
|
* toOrdinal(2) // 'antras'
|
|
@@ -34,12 +46,10 @@ export function toCardinal(value: number | string | bigint, options?: {
|
|
|
34
46
|
export function toOrdinal(value: number | string | bigint): string;
|
|
35
47
|
/**
|
|
36
48
|
* Converts a numeric value to Lithuanian currency words (Euro).
|
|
37
|
-
*
|
|
38
49
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
39
50
|
* @returns {string} The amount in Lithuanian currency words
|
|
40
51
|
* @throws {TypeError} If value is not a valid numeric type
|
|
41
52
|
* @throws {Error} If value is not a valid number format
|
|
42
|
-
*
|
|
43
53
|
* @example
|
|
44
54
|
* toCurrency(42) // 'keturiasdešimt du eurai'
|
|
45
55
|
* toCurrency(1) // 'vienas euras'
|
package/src/lt-LT.js
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
14
14
|
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
15
15
|
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
16
|
-
import {
|
|
16
|
+
import { checkMax } from './utils/check-max.js'
|
|
17
|
+
import { western } from './utils/scale.js'
|
|
18
|
+
import { resolveOptions } from './utils/resolve-options.js'
|
|
17
19
|
|
|
18
20
|
// ============================================================================
|
|
19
21
|
// Vocabulary (module-level constants)
|
|
@@ -71,17 +73,28 @@ const SCALE_FORMS = [
|
|
|
71
73
|
['kvintilijonas', 'kvintilijonai', 'kvintilijonų'],
|
|
72
74
|
['sikstilijonas', 'sikstilijonai', 'sikstilijonų'],
|
|
73
75
|
['septilijonas', 'septilijonai', 'septilijonų'],
|
|
74
|
-
['oktilijonas', 'oktilijonai', 'oktilijonų']
|
|
76
|
+
['oktilijonas', 'oktilijonai', 'oktilijonų'],
|
|
75
77
|
]
|
|
76
78
|
|
|
79
|
+
// Supported magnitude ceilings (checked at the public entry points). Both
|
|
80
|
+
// tables are indexed [scaleIndex - 1] (units separate), so the cardinal/
|
|
81
|
+
// currency ceiling is 10^((SCALE_FORMS.length + 1) * 3) = 10^30, and the
|
|
82
|
+
// shorter ORDINAL_SCALES bounds ordinals at 10^((ORDINAL_SCALES.length + 1) *
|
|
83
|
+
// 3) = 10^15.
|
|
84
|
+
export const cardinalMax = western(SCALE_FORMS.length)
|
|
85
|
+
export const ordinalMax = western(ORDINAL_SCALES.length)
|
|
86
|
+
export const currencyMax = western(SCALE_FORMS.length)
|
|
87
|
+
|
|
77
88
|
// ============================================================================
|
|
78
89
|
// Segment Building
|
|
79
90
|
// ============================================================================
|
|
80
91
|
|
|
81
92
|
/**
|
|
82
93
|
* Builds segment word for 0-999 (masculine form).
|
|
94
|
+
* @param {number} n - Segment value (0-999)
|
|
95
|
+
* @returns {string} Segment words
|
|
83
96
|
*/
|
|
84
|
-
function buildSegment
|
|
97
|
+
function buildSegment(n) {
|
|
85
98
|
if (n === 0) return ''
|
|
86
99
|
|
|
87
100
|
const ones = n % 10
|
|
@@ -104,7 +117,8 @@ function buildSegment (n) {
|
|
|
104
117
|
// Teens or ones
|
|
105
118
|
if (tens === 1) {
|
|
106
119
|
parts.push(TEENS[ones])
|
|
107
|
-
}
|
|
120
|
+
}
|
|
121
|
+
else if (ones > 0) {
|
|
108
122
|
parts.push(ONES_MASC[ones])
|
|
109
123
|
}
|
|
110
124
|
|
|
@@ -113,8 +127,10 @@ function buildSegment (n) {
|
|
|
113
127
|
|
|
114
128
|
/**
|
|
115
129
|
* Builds segment word for 0-999 (feminine form - only differs in ones).
|
|
130
|
+
* @param {number} n - Segment value (0-999)
|
|
131
|
+
* @returns {string} Segment words
|
|
116
132
|
*/
|
|
117
|
-
function buildSegmentFeminine
|
|
133
|
+
function buildSegmentFeminine(n) {
|
|
118
134
|
if (n === 0) return ''
|
|
119
135
|
|
|
120
136
|
const ones = n % 10
|
|
@@ -137,7 +153,8 @@ function buildSegmentFeminine (n) {
|
|
|
137
153
|
// Teens or ones - feminine for ones only
|
|
138
154
|
if (tens === 1) {
|
|
139
155
|
parts.push(TEENS[ones])
|
|
140
|
-
}
|
|
156
|
+
}
|
|
157
|
+
else if (ones > 0) {
|
|
141
158
|
parts.push(ONES_FEM[ones])
|
|
142
159
|
}
|
|
143
160
|
|
|
@@ -153,12 +170,11 @@ function buildSegmentFeminine (n) {
|
|
|
153
170
|
* - Singular: ends in 1 (except 11)
|
|
154
171
|
* - Plural: ends in 2-9 (except 12-19)
|
|
155
172
|
* - Genitive: 0, 10-19, or ends in 0
|
|
156
|
-
*
|
|
157
173
|
* @param {number} n - The segment value
|
|
158
174
|
* @param {string[]} forms - [singular, plural, genitive]
|
|
159
175
|
* @returns {string} The appropriate form
|
|
160
176
|
*/
|
|
161
|
-
function pluralize
|
|
177
|
+
function pluralize(n, forms) {
|
|
162
178
|
if (n === 0) return forms[2]
|
|
163
179
|
|
|
164
180
|
const lastDigit = n % 10
|
|
@@ -189,12 +205,11 @@ function pluralize (n, forms) {
|
|
|
189
205
|
|
|
190
206
|
/**
|
|
191
207
|
* Converts a non-negative integer to Lithuanian words.
|
|
192
|
-
*
|
|
193
208
|
* @param {bigint} n - Non-negative integer to convert
|
|
194
|
-
* @param {
|
|
209
|
+
* @param {string} gender - Gender for numbers < 1000 ('masculine' or 'feminine')
|
|
195
210
|
* @returns {string} Lithuanian words
|
|
196
211
|
*/
|
|
197
|
-
function integerToWords
|
|
212
|
+
function integerToWords(n, gender) {
|
|
198
213
|
if (n === 0n) return ZERO
|
|
199
214
|
|
|
200
215
|
// Fast path: numbers < 1000
|
|
@@ -206,17 +221,15 @@ function integerToWords (n, gender) {
|
|
|
206
221
|
// For numbers >= 1000, feminine only applies to final segment if < 1000
|
|
207
222
|
// But the fixture shows feminine NOT applying for n >= 1000
|
|
208
223
|
// So we use masculine for all segments when n >= 1000
|
|
209
|
-
return buildLargeNumberWords(n
|
|
224
|
+
return buildLargeNumberWords(n)
|
|
210
225
|
}
|
|
211
226
|
|
|
212
227
|
/**
|
|
213
228
|
* Builds words for numbers >= 1000.
|
|
214
|
-
*
|
|
215
229
|
* @param {bigint} n - Number >= 1000
|
|
216
|
-
* @param {Object} options - Conversion options
|
|
217
230
|
* @returns {string} Lithuanian words
|
|
218
231
|
*/
|
|
219
|
-
function buildLargeNumberWords
|
|
232
|
+
function buildLargeNumberWords(n) {
|
|
220
233
|
const numStr = n.toString()
|
|
221
234
|
const len = numStr.length
|
|
222
235
|
|
|
@@ -248,7 +261,8 @@ function buildLargeNumberWords (n, gender) {
|
|
|
248
261
|
if (scaleIndex === 0) {
|
|
249
262
|
// Units segment - use masculine (feminine doesn't apply when n >= 1000)
|
|
250
263
|
parts.push(segmentWord)
|
|
251
|
-
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
252
266
|
// Segment with scale word
|
|
253
267
|
const scaleForms = SCALE_FORMS[scaleIndex - 1]
|
|
254
268
|
const scaleWord = pluralize(segment, scaleForms)
|
|
@@ -264,12 +278,11 @@ function buildLargeNumberWords (n, gender) {
|
|
|
264
278
|
|
|
265
279
|
/**
|
|
266
280
|
* Converts decimal digits to Lithuanian words.
|
|
267
|
-
*
|
|
268
281
|
* @param {string} decimalPart - Decimal digits (without the point)
|
|
269
|
-
* @param {
|
|
282
|
+
* @param {string} gender - Gender for numbers < 1000 ('masculine' or 'feminine')
|
|
270
283
|
* @returns {string} Lithuanian words for decimal part
|
|
271
284
|
*/
|
|
272
|
-
function decimalPartToWords
|
|
285
|
+
function decimalPartToWords(decimalPart, gender) {
|
|
273
286
|
let result = ''
|
|
274
287
|
|
|
275
288
|
// Handle leading zeros
|
|
@@ -290,27 +303,37 @@ function decimalPartToWords (decimalPart, gender) {
|
|
|
290
303
|
return result
|
|
291
304
|
}
|
|
292
305
|
|
|
306
|
+
/**
|
|
307
|
+
* @typedef {object} CardinalOptions
|
|
308
|
+
* @property {('masculine'|'feminine')} [gender] - Gender for numbers < 1000
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
/** @type {Required<CardinalOptions>} */
|
|
312
|
+
export const cardinalDefaults = { gender: 'masculine' }
|
|
313
|
+
|
|
314
|
+
/** @type {{ gender: ReadonlyArray<Required<CardinalOptions>['gender']> }} */
|
|
315
|
+
export const cardinalValues = { gender: ['masculine', 'feminine'] }
|
|
316
|
+
|
|
293
317
|
/**
|
|
294
318
|
* Converts a numeric value to Lithuanian words.
|
|
295
|
-
*
|
|
296
319
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
297
|
-
* @param {
|
|
298
|
-
* @param {string} [options.gender='masculine'] - Gender for numbers < 1000
|
|
320
|
+
* @param {CardinalOptions} [options] - Conversion options
|
|
299
321
|
* @returns {string} The number in Lithuanian words
|
|
300
322
|
* @throws {TypeError} If value is not a valid numeric type
|
|
301
323
|
* @throws {Error} If value is not a valid number format
|
|
302
|
-
*
|
|
303
324
|
* @example
|
|
304
325
|
* toCardinal(42) // 'keturiasdešimt du'
|
|
305
326
|
* toCardinal(1, { gender: 'feminine' }) // 'viena'
|
|
306
327
|
* toCardinal(1000000) // 'vienas milijonas'
|
|
307
328
|
*/
|
|
308
|
-
function toCardinal
|
|
309
|
-
options = validateOptions(options)
|
|
329
|
+
function toCardinal(value, options) {
|
|
310
330
|
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
331
|
+
// Both the integer part and the decimal's significant digits are spelled via
|
|
332
|
+
// the scale builder, so both must clear the ceiling.
|
|
333
|
+
checkMax(integerPart, cardinalMax, decimalPart)
|
|
311
334
|
|
|
312
335
|
// Apply option defaults
|
|
313
|
-
const { gender
|
|
336
|
+
const { gender } = resolveOptions(options, cardinalDefaults, cardinalValues)
|
|
314
337
|
|
|
315
338
|
let result = ''
|
|
316
339
|
|
|
@@ -333,11 +356,10 @@ function toCardinal (value, options) {
|
|
|
333
356
|
|
|
334
357
|
/**
|
|
335
358
|
* Builds ordinal for a 0-99 segment when it's the final (ordinal) part.
|
|
336
|
-
*
|
|
337
359
|
* @param {number} n - Number 0-99
|
|
338
360
|
* @returns {string} Ordinal words
|
|
339
361
|
*/
|
|
340
|
-
function buildOrdinalTensOnes
|
|
362
|
+
function buildOrdinalTensOnes(n) {
|
|
341
363
|
if (n === 0) return ''
|
|
342
364
|
|
|
343
365
|
const onesDigit = n % 10
|
|
@@ -360,11 +382,10 @@ function buildOrdinalTensOnes (n) {
|
|
|
360
382
|
|
|
361
383
|
/**
|
|
362
384
|
* Converts a positive integer to Lithuanian ordinal words (masculine nominative).
|
|
363
|
-
*
|
|
364
385
|
* @param {bigint} n - Positive integer to convert
|
|
365
386
|
* @returns {string} Ordinal Lithuanian words
|
|
366
387
|
*/
|
|
367
|
-
function integerToOrdinal
|
|
388
|
+
function integerToOrdinal(n) {
|
|
368
389
|
if (n < 100n) {
|
|
369
390
|
return buildOrdinalTensOnes(Number(n))
|
|
370
391
|
}
|
|
@@ -406,11 +427,10 @@ function integerToOrdinal (n) {
|
|
|
406
427
|
|
|
407
428
|
/**
|
|
408
429
|
* Builds ordinal words for numbers >= 1,000,000.
|
|
409
|
-
*
|
|
410
430
|
* @param {bigint} n - Number >= 1,000,000
|
|
411
431
|
* @returns {string} Ordinal Lithuanian words
|
|
412
432
|
*/
|
|
413
|
-
function buildLargeOrdinal
|
|
433
|
+
function buildLargeOrdinal(n) {
|
|
414
434
|
const numStr = n.toString()
|
|
415
435
|
const len = numStr.length
|
|
416
436
|
|
|
@@ -445,20 +465,24 @@ function buildLargeOrdinal (n) {
|
|
|
445
465
|
if (scaleIndex === 0) {
|
|
446
466
|
if (isLastNonZero) {
|
|
447
467
|
parts.push(integerToOrdinal(BigInt(segment)))
|
|
448
|
-
}
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
449
470
|
parts.push(buildSegment(segment))
|
|
450
471
|
}
|
|
451
|
-
}
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
452
474
|
if (isLastNonZero) {
|
|
453
475
|
if (segment === 1) {
|
|
454
476
|
parts.push(ORDINAL_SCALES[scaleIndex - 1])
|
|
455
|
-
}
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
456
479
|
// For 2+, include cardinal scale word before ordinal
|
|
457
480
|
const scaleForms = SCALE_FORMS[scaleIndex - 1]
|
|
458
481
|
const cardinalScaleWord = pluralize(segment, scaleForms)
|
|
459
482
|
parts.push(buildSegment(segment) + ' ' + cardinalScaleWord + ' ' + ORDINAL_SCALES[scaleIndex - 1])
|
|
460
483
|
}
|
|
461
|
-
}
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
462
486
|
const scaleForms = SCALE_FORMS[scaleIndex - 1]
|
|
463
487
|
const scaleWord = pluralize(segment, scaleForms)
|
|
464
488
|
parts.push(buildSegment(segment) + ' ' + scaleWord)
|
|
@@ -474,12 +498,10 @@ function buildLargeOrdinal (n) {
|
|
|
474
498
|
|
|
475
499
|
/**
|
|
476
500
|
* Converts a numeric value to Lithuanian ordinal words (masculine nominative).
|
|
477
|
-
*
|
|
478
501
|
* @param {number | string | bigint} value - The numeric value to convert (must be a positive integer)
|
|
479
502
|
* @returns {string} The number as ordinal words
|
|
480
503
|
* @throws {TypeError} If value is not a valid numeric type
|
|
481
504
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
482
|
-
*
|
|
483
505
|
* @example
|
|
484
506
|
* toOrdinal(1) // 'pirmas'
|
|
485
507
|
* toOrdinal(2) // 'antras'
|
|
@@ -487,8 +509,9 @@ function buildLargeOrdinal (n) {
|
|
|
487
509
|
* toOrdinal(100) // 'šimtasis'
|
|
488
510
|
* toOrdinal(1000) // 'tūkstantasis'
|
|
489
511
|
*/
|
|
490
|
-
function toOrdinal
|
|
512
|
+
function toOrdinal(value) {
|
|
491
513
|
const integerPart = parseOrdinalValue(value)
|
|
514
|
+
checkMax(integerPart, ordinalMax)
|
|
492
515
|
return integerToOrdinal(integerPart)
|
|
493
516
|
}
|
|
494
517
|
|
|
@@ -498,20 +521,19 @@ function toOrdinal (value) {
|
|
|
498
521
|
|
|
499
522
|
/**
|
|
500
523
|
* Converts a numeric value to Lithuanian currency words (Euro).
|
|
501
|
-
*
|
|
502
524
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
503
525
|
* @returns {string} The amount in Lithuanian currency words
|
|
504
526
|
* @throws {TypeError} If value is not a valid numeric type
|
|
505
527
|
* @throws {Error} If value is not a valid number format
|
|
506
|
-
*
|
|
507
528
|
* @example
|
|
508
529
|
* toCurrency(42) // 'keturiasdešimt du eurai'
|
|
509
530
|
* toCurrency(1) // 'vienas euras'
|
|
510
531
|
* toCurrency(1.50) // 'vienas euras penkiasdešimt centų'
|
|
511
532
|
* toCurrency(-5) // 'minus penki eurai'
|
|
512
533
|
*/
|
|
513
|
-
function toCurrency
|
|
534
|
+
function toCurrency(value) {
|
|
514
535
|
const { isNegative, dollars: euros, cents } = parseCurrencyValue(value)
|
|
536
|
+
checkMax(euros, currencyMax)
|
|
515
537
|
|
|
516
538
|
let result = ''
|
|
517
539
|
if (isNegative) {
|
package/src/lv-LV.d.ts
CHANGED
|
@@ -1,29 +1,41 @@
|
|
|
1
|
+
export const cardinalMax: bigint;
|
|
2
|
+
export const ordinalMax: bigint;
|
|
3
|
+
export const currencyMax: bigint;
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {object} CardinalOptions
|
|
6
|
+
* @property {('masculine'|'feminine')} [gender] - Gender for numbers < 1000
|
|
7
|
+
*/
|
|
8
|
+
/** @type {Required<CardinalOptions>} */
|
|
9
|
+
export const cardinalDefaults: Required<CardinalOptions>;
|
|
10
|
+
/** @type {{ gender: ReadonlyArray<Required<CardinalOptions>['gender']> }} */
|
|
11
|
+
export const cardinalValues: {
|
|
12
|
+
gender: ReadonlyArray<Required<CardinalOptions>["gender"]>;
|
|
13
|
+
};
|
|
14
|
+
export type CardinalOptions = {
|
|
15
|
+
/**
|
|
16
|
+
* - Gender for numbers < 1000
|
|
17
|
+
*/
|
|
18
|
+
gender?: "feminine" | "masculine" | undefined;
|
|
19
|
+
};
|
|
1
20
|
/**
|
|
2
21
|
* Converts a numeric value to Latvian words.
|
|
3
|
-
*
|
|
4
22
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
-
* @param {
|
|
6
|
-
* @param {string} [options.gender='masculine'] - Gender for numbers < 1000
|
|
23
|
+
* @param {CardinalOptions} [options] - Conversion options
|
|
7
24
|
* @returns {string} The number in Latvian words
|
|
8
25
|
* @throws {TypeError} If value is not a valid numeric type
|
|
9
26
|
* @throws {Error} If value is not a valid number format
|
|
10
|
-
*
|
|
11
27
|
* @example
|
|
12
28
|
* toCardinal(42) // 'četrdesmit divi'
|
|
13
29
|
* toCardinal(1, { gender: 'feminine' }) // 'viena'
|
|
14
30
|
* toCardinal(1000) // 'tūkstotis'
|
|
15
31
|
*/
|
|
16
|
-
export function toCardinal(value: number | string | bigint, options?:
|
|
17
|
-
gender?: string | undefined;
|
|
18
|
-
}): string;
|
|
32
|
+
export function toCardinal(value: number | string | bigint, options?: CardinalOptions): string;
|
|
19
33
|
/**
|
|
20
34
|
* Converts a numeric value to Latvian ordinal words (masculine nominative).
|
|
21
|
-
*
|
|
22
35
|
* @param {number | string | bigint} value - The numeric value to convert (must be a positive integer)
|
|
23
36
|
* @returns {string} The number as ordinal words
|
|
24
37
|
* @throws {TypeError} If value is not a valid numeric type
|
|
25
38
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
26
|
-
*
|
|
27
39
|
* @example
|
|
28
40
|
* toOrdinal(1) // 'pirmais'
|
|
29
41
|
* toOrdinal(2) // 'otrais'
|
|
@@ -34,12 +46,10 @@ export function toCardinal(value: number | string | bigint, options?: {
|
|
|
34
46
|
export function toOrdinal(value: number | string | bigint): string;
|
|
35
47
|
/**
|
|
36
48
|
* Converts a numeric value to Latvian currency words (Euro).
|
|
37
|
-
*
|
|
38
49
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
39
50
|
* @returns {string} The amount in Latvian currency words
|
|
40
51
|
* @throws {TypeError} If value is not a valid numeric type
|
|
41
52
|
* @throws {Error} If value is not a valid number format
|
|
42
|
-
*
|
|
43
53
|
* @example
|
|
44
54
|
* toCurrency(42) // 'četrdesmit divi eiro'
|
|
45
55
|
* toCurrency(1) // 'viens eiro'
|