n2words 5.0.0 → 5.1.0
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 +128 -42
- 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 +31 -22
- 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 +100 -38
- package/src/sr-Latn-RS.d.ts +35 -15
- package/src/sr-Latn-RS.js +100 -38
- 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/sw-KE.js
CHANGED
|
@@ -12,16 +12,24 @@
|
|
|
12
12
|
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
13
13
|
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
14
14
|
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
15
|
+
import { checkMax } from './utils/check-max.js'
|
|
16
|
+
import { western } from './utils/scale.js'
|
|
15
17
|
|
|
16
18
|
// ============================================================================
|
|
17
19
|
// Vocabulary
|
|
18
20
|
// ============================================================================
|
|
19
21
|
|
|
20
22
|
const ONES = ['sifuri', 'moja', 'mbili', 'tatu', 'nne', 'tano', 'sita', 'saba', 'nane', 'tisa']
|
|
23
|
+
/** @type {Record<number, string>} */
|
|
21
24
|
const TENS = { 10: 'kumi', 20: 'ishirini', 30: 'thelathini', 40: 'arobaini', 50: 'hamsini', 60: 'sitini', 70: 'sabini', 80: 'themanini', 90: 'tisini' }
|
|
22
25
|
|
|
23
26
|
const SCALE_WORDS = ['', 'elfu', 'milioni', 'bilioni', 'trilioni', 'kwadrilioni', 'kwintilioni']
|
|
24
27
|
|
|
28
|
+
// Supported magnitude ceiling (checked at the public entry points), derived from the scale table.
|
|
29
|
+
export const cardinalMax = western(SCALE_WORDS.length - 1)
|
|
30
|
+
export const ordinalMax = western(SCALE_WORDS.length - 1)
|
|
31
|
+
export const currencyMax = western(SCALE_WORDS.length - 1)
|
|
32
|
+
|
|
25
33
|
const ZERO = 'sifuri'
|
|
26
34
|
const NEGATIVE = 'minus'
|
|
27
35
|
const DECIMAL_SEP = 'nukta'
|
|
@@ -32,6 +40,7 @@ const DECIMAL_SEP = 'nukta'
|
|
|
32
40
|
|
|
33
41
|
// Swahili ordinals use "wa" + cardinal: wa kwanza (1st), wa pili (2nd)
|
|
34
42
|
// First few have special forms
|
|
43
|
+
/** @type {Record<number, string>} */
|
|
35
44
|
const ORDINAL_ONES = {
|
|
36
45
|
1: 'wa kwanza',
|
|
37
46
|
2: 'wa pili',
|
|
@@ -41,7 +50,7 @@ const ORDINAL_ONES = {
|
|
|
41
50
|
6: 'wa sita',
|
|
42
51
|
7: 'wa saba',
|
|
43
52
|
8: 'wa nane',
|
|
44
|
-
9: 'wa tisa'
|
|
53
|
+
9: 'wa tisa',
|
|
45
54
|
}
|
|
46
55
|
const ORDINAL_PREFIX = 'wa'
|
|
47
56
|
|
|
@@ -56,7 +65,11 @@ const CENT = 'senti'
|
|
|
56
65
|
// Conversion Functions
|
|
57
66
|
// ============================================================================
|
|
58
67
|
|
|
59
|
-
|
|
68
|
+
/**
|
|
69
|
+
* @param {number} n The integer (0-99) to convert
|
|
70
|
+
* @returns {string} The number in Swahili words
|
|
71
|
+
*/
|
|
72
|
+
function wordsUnder100(n) {
|
|
60
73
|
if (n < 10) return ONES[n]
|
|
61
74
|
if (n === 10) return TENS[10]
|
|
62
75
|
if (n < 20) {
|
|
@@ -69,7 +82,11 @@ function wordsUnder100 (n) {
|
|
|
69
82
|
return TENS[tens] + ' na ' + ONES[ones]
|
|
70
83
|
}
|
|
71
84
|
|
|
72
|
-
|
|
85
|
+
/**
|
|
86
|
+
* @param {number} n The integer (0-999) to convert
|
|
87
|
+
* @returns {string} The number in Swahili words
|
|
88
|
+
*/
|
|
89
|
+
function wordsUnder1000(n) {
|
|
73
90
|
if (n < 100) return wordsUnder100(n)
|
|
74
91
|
if (n === 100) return 'mia moja'
|
|
75
92
|
const hundreds = Math.trunc(n / 100)
|
|
@@ -81,7 +98,8 @@ function wordsUnder1000 (n) {
|
|
|
81
98
|
if (rest > 0) {
|
|
82
99
|
if (rest < 10) {
|
|
83
100
|
parts.push('na ' + ONES[rest])
|
|
84
|
-
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
85
103
|
parts.push(wordsUnder100(rest))
|
|
86
104
|
}
|
|
87
105
|
}
|
|
@@ -89,7 +107,11 @@ function wordsUnder1000 (n) {
|
|
|
89
107
|
return parts.join(' ')
|
|
90
108
|
}
|
|
91
109
|
|
|
92
|
-
|
|
110
|
+
/**
|
|
111
|
+
* @param {bigint} n The integer to split into 3-digit segments
|
|
112
|
+
* @returns {number[]} The segments, least-significant first
|
|
113
|
+
*/
|
|
114
|
+
function extractSegments(n) {
|
|
93
115
|
const segments = []
|
|
94
116
|
let temp = n
|
|
95
117
|
while (temp > 0n) {
|
|
@@ -99,7 +121,11 @@ function extractSegments (n) {
|
|
|
99
121
|
return segments
|
|
100
122
|
}
|
|
101
123
|
|
|
102
|
-
|
|
124
|
+
/**
|
|
125
|
+
* @param {bigint} n The integer to convert
|
|
126
|
+
* @returns {string} The number in Swahili words
|
|
127
|
+
*/
|
|
128
|
+
function integerToWords(n) {
|
|
103
129
|
if (n === 0n) return ZERO
|
|
104
130
|
|
|
105
131
|
// segments stored least-significant first: [ones, thousands, millions, ...]
|
|
@@ -115,13 +141,16 @@ function integerToWords (n) {
|
|
|
115
141
|
// Units segment
|
|
116
142
|
if (val < 10 && parts.length > 0) {
|
|
117
143
|
parts.push('na ' + ONES[val])
|
|
118
|
-
}
|
|
144
|
+
}
|
|
145
|
+
else if (val === 100 && parts.length > 0) {
|
|
119
146
|
// In compound numbers (e.g., 1100 -> 'elfu moja mia'), use 'mia' not 'mia moja'
|
|
120
147
|
parts.push('mia')
|
|
121
|
-
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
122
150
|
parts.push(wordsUnder1000(val))
|
|
123
151
|
}
|
|
124
|
-
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
125
154
|
// Scale segments: 'elfu moja', 'milioni mbili'
|
|
126
155
|
const unit = (val === 1) ? 'moja' : wordsUnder1000(val)
|
|
127
156
|
parts.push(SCALE_WORDS[scaleIndex] + ' ' + unit)
|
|
@@ -131,7 +160,11 @@ function integerToWords (n) {
|
|
|
131
160
|
return parts.join(' ').trim()
|
|
132
161
|
}
|
|
133
162
|
|
|
134
|
-
|
|
163
|
+
/**
|
|
164
|
+
* @param {string} decimalPart The digits after the decimal point
|
|
165
|
+
* @returns {string} The decimal digits in Swahili words
|
|
166
|
+
*/
|
|
167
|
+
function decimalPartToWords(decimalPart) {
|
|
135
168
|
let result = ''
|
|
136
169
|
let i = 0
|
|
137
170
|
|
|
@@ -152,12 +185,12 @@ function decimalPartToWords (decimalPart) {
|
|
|
152
185
|
|
|
153
186
|
/**
|
|
154
187
|
* Converts a numeric value to Swahili words.
|
|
155
|
-
*
|
|
156
188
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
157
189
|
* @returns {string} The number in Swahili words
|
|
158
190
|
*/
|
|
159
|
-
function toCardinal
|
|
191
|
+
function toCardinal(value) {
|
|
160
192
|
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
193
|
+
checkMax(integerPart, cardinalMax, decimalPart)
|
|
161
194
|
|
|
162
195
|
let result = ''
|
|
163
196
|
|
|
@@ -182,11 +215,10 @@ function toCardinal (value) {
|
|
|
182
215
|
* Converts a non-negative integer to Swahili ordinal words.
|
|
183
216
|
*
|
|
184
217
|
* Swahili ordinals: wa kwanza (1st), wa pili (2nd), wa tatu (3rd), etc.
|
|
185
|
-
*
|
|
186
218
|
* @param {bigint} n - Positive integer to convert
|
|
187
219
|
* @returns {string} Swahili ordinal words
|
|
188
220
|
*/
|
|
189
|
-
function integerToOrdinal
|
|
221
|
+
function integerToOrdinal(n) {
|
|
190
222
|
// Special forms for 1-9
|
|
191
223
|
if (n >= 1n && n <= 9n) {
|
|
192
224
|
return ORDINAL_ONES[Number(n)]
|
|
@@ -198,19 +230,18 @@ function integerToOrdinal (n) {
|
|
|
198
230
|
|
|
199
231
|
/**
|
|
200
232
|
* Converts a numeric value to Swahili ordinal words.
|
|
201
|
-
*
|
|
202
233
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
203
234
|
* @returns {string} The number as ordinal words
|
|
204
235
|
* @throws {TypeError} If value is not a valid numeric type
|
|
205
236
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
206
|
-
*
|
|
207
237
|
* @example
|
|
208
238
|
* toOrdinal(1) // 'wa kwanza'
|
|
209
239
|
* toOrdinal(2) // 'wa pili'
|
|
210
240
|
* toOrdinal(10) // 'wa kumi'
|
|
211
241
|
*/
|
|
212
|
-
function toOrdinal
|
|
242
|
+
function toOrdinal(value) {
|
|
213
243
|
const integerPart = parseOrdinalValue(value)
|
|
244
|
+
checkMax(integerPart, ordinalMax)
|
|
214
245
|
return integerToOrdinal(integerPart)
|
|
215
246
|
}
|
|
216
247
|
|
|
@@ -222,19 +253,18 @@ function toOrdinal (value) {
|
|
|
222
253
|
* Converts a numeric value to Swahili currency words (Kenyan Shilling).
|
|
223
254
|
*
|
|
224
255
|
* Uses shilingi and senti (100 senti = 1 shilingi).
|
|
225
|
-
*
|
|
226
256
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
227
257
|
* @returns {string} The amount in Swahili currency words
|
|
228
258
|
* @throws {TypeError} If value is not a valid numeric type
|
|
229
259
|
* @throws {Error} If value is not a valid number format
|
|
230
|
-
*
|
|
231
260
|
* @example
|
|
232
261
|
* toCurrency(42) // 'shilingi arobaini na mbili'
|
|
233
262
|
* toCurrency(1.50) // 'shilingi moja na senti hamsini'
|
|
234
263
|
* toCurrency(-5) // 'minus shilingi tano'
|
|
235
264
|
*/
|
|
236
|
-
function toCurrency
|
|
265
|
+
function toCurrency(value) {
|
|
237
266
|
const { isNegative, dollars: shillings, cents: senti } = parseCurrencyValue(value)
|
|
267
|
+
checkMax(shillings, currencyMax)
|
|
238
268
|
|
|
239
269
|
let result = ''
|
|
240
270
|
if (isNegative) {
|
package/src/ta-IN.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
export const cardinalMax: bigint;
|
|
2
|
+
export const ordinalMax: bigint;
|
|
3
|
+
export const currencyMax: bigint;
|
|
1
4
|
/**
|
|
2
5
|
* Converts a numeric value to Tamil words.
|
|
3
|
-
*
|
|
4
6
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
7
|
* @returns {string} The number in Tamil words
|
|
6
8
|
*/
|
|
7
9
|
export function toCardinal(value: number | string | bigint): string;
|
|
8
10
|
/**
|
|
9
11
|
* Converts a numeric value to Tamil ordinal words.
|
|
10
|
-
*
|
|
11
12
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
12
13
|
* @returns {string} The number as ordinal words
|
|
13
14
|
* @throws {TypeError} If value is not a valid numeric type
|
|
14
15
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
15
|
-
*
|
|
16
16
|
* @example
|
|
17
17
|
* toOrdinal(1) // 'முதல்'
|
|
18
18
|
* toOrdinal(2) // 'இரண்டாவது'
|
|
@@ -21,12 +21,10 @@ export function toCardinal(value: number | string | bigint): string;
|
|
|
21
21
|
export function toOrdinal(value: number | string | bigint): string;
|
|
22
22
|
/**
|
|
23
23
|
* Converts a numeric value to Tamil currency words (Indian Rupee).
|
|
24
|
-
*
|
|
25
24
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
26
25
|
* @returns {string} The amount in Tamil currency words
|
|
27
26
|
* @throws {TypeError} If value is not a valid numeric type
|
|
28
27
|
* @throws {Error} If value is not a valid number format
|
|
29
|
-
*
|
|
30
28
|
* @example
|
|
31
29
|
* toCurrency(42.50) // 'நாற்பத்திரண்டு ரூபாய் ஐம்பது பைசா'
|
|
32
30
|
* toCurrency(1) // 'ஒன்று ரூபாய்'
|
package/src/ta-IN.js
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
17
17
|
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
18
18
|
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
19
|
+
import { checkMax } from './utils/check-max.js'
|
|
20
|
+
import { indian } from './utils/scale.js'
|
|
19
21
|
|
|
20
22
|
// ============================================================================
|
|
21
23
|
// Vocabulary
|
|
@@ -55,7 +57,7 @@ const BELOW_HUNDRED = [
|
|
|
55
57
|
'அறுபது', 'அறுபத்தொன்று', 'அறுபத்திரண்டு', 'அறுபத்திமூன்று', 'அறுபத்திநான்கு', 'அறுபத்தைந்து', 'அறுபத்தாறு', 'அறுபத்தேழு', 'அறுபத்தெட்டு', 'அறுபத்தொன்பது',
|
|
56
58
|
'எழுபது', 'எழுபத்தொன்று', 'எழுபத்திரண்டு', 'எழுபத்திமூன்று', 'எழுபத்திநான்கு', 'எழுபத்தைந்து', 'எழுபத்தாறு', 'எழுபத்தேழு', 'எழுபத்தெட்டு', 'எழுபத்தொன்பது',
|
|
57
59
|
'எண்பது', 'எண்பத்தொன்று', 'எண்பத்திரண்டு', 'எண்பத்திமூன்று', 'எண்பத்திநான்கு', 'எண்பத்தைந்து', 'எண்பத்தாறு', 'எண்பத்தேழு', 'எண்பத்தெட்டு', 'எண்பத்தொன்பது',
|
|
58
|
-
'தொண்ணூறு', 'தொண்ணூற்று ஒன்று', 'தொண்ணூற்று இரண்டு', 'தொண்ணூற்று மூன்று', 'தொண்ணூற்று நான்கு', 'தொண்ணூற்று ஐந்து', 'தொண்ணூற்று ஆறு', 'தொண்ணூற்று ஏழு', 'தொண்ணூற்று எட்டு', 'தொண்ணூற்று ஒன்பது'
|
|
60
|
+
'தொண்ணூறு', 'தொண்ணூற்று ஒன்று', 'தொண்ணூற்று இரண்டு', 'தொண்ணூற்று மூன்று', 'தொண்ணூற்று நான்கு', 'தொண்ணூற்று ஐந்து', 'தொண்ணூற்று ஆறு', 'தொண்ணூற்று ஏழு', 'தொண்ணூற்று எட்டு', 'தொண்ணூற்று ஒன்பது',
|
|
59
61
|
]
|
|
60
62
|
|
|
61
63
|
// Standalone hundreds (when not followed by remainder)
|
|
@@ -70,17 +72,23 @@ const ONES = ['ஒன்று', 'இரண்டு', 'மூன்று', '
|
|
|
70
72
|
// Scale words: index 0 = units, 1 = thousand, 2 = lakh, etc.
|
|
71
73
|
const SCALE_WORDS = ['', 'ஆயிரம்', 'லட்சம்', 'கோடி', 'அரபு', 'கராபு', 'நீல்', 'பத்ம', 'சங்கு']
|
|
72
74
|
|
|
75
|
+
// 3-2-2 Indian grouping: a 3-digit base segment, then 2 digits per scale word
|
|
76
|
+
// (SCALE_WORDS[0] = '' is the units slot). Past the table the scale word is
|
|
77
|
+
// dropped, which collapses the magnitude — so cap there.
|
|
78
|
+
export const cardinalMax = indian(SCALE_WORDS.length)
|
|
79
|
+
export const ordinalMax = indian(SCALE_WORDS.length)
|
|
80
|
+
export const currencyMax = indian(SCALE_WORDS.length)
|
|
81
|
+
|
|
73
82
|
// ============================================================================
|
|
74
83
|
// Segment Building
|
|
75
84
|
// ============================================================================
|
|
76
85
|
|
|
77
86
|
/**
|
|
78
87
|
* Builds words for a 0-999 segment.
|
|
79
|
-
*
|
|
80
88
|
* @param {number} n - Number 0-999
|
|
81
89
|
* @returns {string} Tamil words for the segment
|
|
82
90
|
*/
|
|
83
|
-
function buildSegment
|
|
91
|
+
function buildSegment(n) {
|
|
84
92
|
if (n === 0) return ''
|
|
85
93
|
if (n < 100) return BELOW_HUNDRED[n]
|
|
86
94
|
|
|
@@ -104,11 +112,10 @@ function buildSegment (n) {
|
|
|
104
112
|
*
|
|
105
113
|
* Uses BigInt modulo for segment extraction (faster than string slicing).
|
|
106
114
|
* South Asian 3-2-2 grouping: first 3 digits, then groups of 2.
|
|
107
|
-
*
|
|
108
115
|
* @param {bigint} n - Non-negative integer to convert
|
|
109
116
|
* @returns {string} Tamil words
|
|
110
117
|
*/
|
|
111
|
-
function integerToWords
|
|
118
|
+
function integerToWords(n) {
|
|
112
119
|
if (n === 0n) return ZERO
|
|
113
120
|
|
|
114
121
|
// Fast path: numbers < 1000
|
|
@@ -134,7 +141,8 @@ function integerToWords (n) {
|
|
|
134
141
|
|
|
135
142
|
if (i === 0) {
|
|
136
143
|
words.push(buildSegment(segment))
|
|
137
|
-
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
138
146
|
// Use 'ஒரு' for 1 at scale positions
|
|
139
147
|
const groupWords = (segment === 1) ? 'ஒரு' : BELOW_HUNDRED[segment]
|
|
140
148
|
words.push(groupWords)
|
|
@@ -148,7 +156,12 @@ function integerToWords (n) {
|
|
|
148
156
|
return words.join(' ')
|
|
149
157
|
}
|
|
150
158
|
|
|
151
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Converts the decimal portion of a number to Tamil words (per-digit reading).
|
|
161
|
+
* @param {string} decimalPart - The fractional digits as a string
|
|
162
|
+
* @returns {string} Tamil words for each decimal digit
|
|
163
|
+
*/
|
|
164
|
+
function decimalPartToWords(decimalPart) {
|
|
152
165
|
// Per-digit decimal reading
|
|
153
166
|
const digits = []
|
|
154
167
|
for (const char of decimalPart) {
|
|
@@ -160,12 +173,13 @@ function decimalPartToWords (decimalPart) {
|
|
|
160
173
|
|
|
161
174
|
/**
|
|
162
175
|
* Converts a numeric value to Tamil words.
|
|
163
|
-
*
|
|
164
176
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
165
177
|
* @returns {string} The number in Tamil words
|
|
166
178
|
*/
|
|
167
|
-
function toCardinal
|
|
179
|
+
function toCardinal(value) {
|
|
168
180
|
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
181
|
+
// The fraction is spelled digit by digit, so only the integer part has a ceiling.
|
|
182
|
+
checkMax(integerPart, cardinalMax)
|
|
169
183
|
|
|
170
184
|
let result = ''
|
|
171
185
|
|
|
@@ -190,11 +204,10 @@ function toCardinal (value) {
|
|
|
190
204
|
* Converts a positive integer to Tamil ordinal words.
|
|
191
205
|
*
|
|
192
206
|
* Tamil ordinals: First has special form, 2-6 have special suffixes, then -ஆவது suffix.
|
|
193
|
-
*
|
|
194
207
|
* @param {bigint} n - Positive integer to convert
|
|
195
208
|
* @returns {string} Tamil ordinal words
|
|
196
209
|
*/
|
|
197
|
-
function integerToOrdinal
|
|
210
|
+
function integerToOrdinal(n) {
|
|
198
211
|
// Special ordinals for 1-6
|
|
199
212
|
if (n >= 1n && n <= 6n) {
|
|
200
213
|
return ORDINAL_SPECIAL[Number(n)]
|
|
@@ -207,19 +220,19 @@ function integerToOrdinal (n) {
|
|
|
207
220
|
|
|
208
221
|
/**
|
|
209
222
|
* Converts a numeric value to Tamil ordinal words.
|
|
210
|
-
*
|
|
211
223
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
212
224
|
* @returns {string} The number as ordinal words
|
|
213
225
|
* @throws {TypeError} If value is not a valid numeric type
|
|
214
226
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
215
|
-
*
|
|
216
227
|
* @example
|
|
217
228
|
* toOrdinal(1) // 'முதல்'
|
|
218
229
|
* toOrdinal(2) // 'இரண்டாவது'
|
|
219
230
|
* toOrdinal(10) // 'பத்துஆவது'
|
|
220
231
|
*/
|
|
221
|
-
function toOrdinal
|
|
232
|
+
function toOrdinal(value) {
|
|
222
233
|
const integerPart = parseOrdinalValue(value)
|
|
234
|
+
// Ordinals build on the cardinal speller, so they share its ceiling.
|
|
235
|
+
checkMax(integerPart, ordinalMax)
|
|
223
236
|
return integerToOrdinal(integerPart)
|
|
224
237
|
}
|
|
225
238
|
|
|
@@ -229,19 +242,18 @@ function toOrdinal (value) {
|
|
|
229
242
|
|
|
230
243
|
/**
|
|
231
244
|
* Converts a numeric value to Tamil currency words (Indian Rupee).
|
|
232
|
-
*
|
|
233
245
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
234
246
|
* @returns {string} The amount in Tamil currency words
|
|
235
247
|
* @throws {TypeError} If value is not a valid numeric type
|
|
236
248
|
* @throws {Error} If value is not a valid number format
|
|
237
|
-
*
|
|
238
249
|
* @example
|
|
239
250
|
* toCurrency(42.50) // 'நாற்பத்திரண்டு ரூபாய் ஐம்பது பைசா'
|
|
240
251
|
* toCurrency(1) // 'ஒன்று ரூபாய்'
|
|
241
252
|
* toCurrency(0.01) // 'ஒன்று பைசா'
|
|
242
253
|
*/
|
|
243
|
-
function toCurrency
|
|
254
|
+
function toCurrency(value) {
|
|
244
255
|
const { isNegative, dollars: rupees, cents: paise } = parseCurrencyValue(value)
|
|
256
|
+
checkMax(rupees, currencyMax)
|
|
245
257
|
|
|
246
258
|
// Build result
|
|
247
259
|
let result = ''
|
package/src/te-IN.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
export const cardinalMax: bigint;
|
|
2
|
+
export const ordinalMax: bigint;
|
|
3
|
+
export const currencyMax: bigint;
|
|
1
4
|
/**
|
|
2
5
|
* Converts a numeric value to Telugu words.
|
|
3
|
-
*
|
|
4
6
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
7
|
* @returns {string} The number in Telugu words
|
|
6
8
|
*/
|
|
7
9
|
export function toCardinal(value: number | string | bigint): string;
|
|
8
10
|
/**
|
|
9
11
|
* Converts a numeric value to Telugu ordinal words.
|
|
10
|
-
*
|
|
11
12
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
12
13
|
* @returns {string} The number as ordinal words
|
|
13
14
|
* @throws {TypeError} If value is not a valid numeric type
|
|
14
15
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
15
|
-
*
|
|
16
16
|
* @example
|
|
17
17
|
* toOrdinal(1) // 'మొదటి'
|
|
18
18
|
* toOrdinal(2) // 'రెండవ'
|
|
@@ -21,12 +21,10 @@ export function toCardinal(value: number | string | bigint): string;
|
|
|
21
21
|
export function toOrdinal(value: number | string | bigint): string;
|
|
22
22
|
/**
|
|
23
23
|
* Converts a numeric value to Telugu currency words (Indian Rupee).
|
|
24
|
-
*
|
|
25
24
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
26
25
|
* @returns {string} The amount in Telugu currency words
|
|
27
26
|
* @throws {TypeError} If value is not a valid numeric type
|
|
28
27
|
* @throws {Error} If value is not a valid number format
|
|
29
|
-
*
|
|
30
28
|
* @example
|
|
31
29
|
* toCurrency(42.50) // 'నలభై రెండు రూపాయలు యాభై పైసలు'
|
|
32
30
|
* toCurrency(1) // 'ఒకటి రూపాయి'
|
package/src/te-IN.js
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
15
15
|
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
16
16
|
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
17
|
+
import { checkMax } from './utils/check-max.js'
|
|
18
|
+
import { indian } from './utils/scale.js'
|
|
17
19
|
|
|
18
20
|
// ============================================================================
|
|
19
21
|
// Vocabulary
|
|
@@ -55,7 +57,7 @@ const BELOW_HUNDRED = [
|
|
|
55
57
|
'అరవై', 'అరవై ఒకటి', 'అరవై రెండు', 'అరవై మూడు', 'అరవై నాలుగు', 'అరవై ఐదు', 'అరవై ఆరు', 'అరవై ఏడు', 'అరవై ఎనిమిది', 'అరవై తొమ్మిది',
|
|
56
58
|
'డెబ్బై', 'డెబ్బై ఒకటి', 'డెబ్బై రెండు', 'డెబ్బై మూడు', 'డెబ్బై నాలుగు', 'డెబ్బై ఐదు', 'డెబ్బై ఆరు', 'డెబ్బై ఏడు', 'డెబ్బై ఎనిమిది', 'డెబ్బై తొమ్మిది',
|
|
57
59
|
'ఎనభై', 'ఎనభై ఒకటి', 'ఎనభై రెండు', 'ఎనభై మూడు', 'ఎనభై నాలుగు', 'ఎనభై ఐదు', 'ఎనభై ఆరు', 'ఎనభై ఏడు', 'ఎనభై ఎనిమిది', 'ఎనభై తొమ్మిది',
|
|
58
|
-
'తొంభై', 'తొంభై ఒకటి', 'తొంభై రెండు', 'తొంభై మూడు', 'తొంభై నాలుగు', 'తొంభై ఐదు', 'తొంభై ఆరు', 'తొంభై ఏడు', 'తొంభై ఎనిమిది', 'తొంభై తొమ్మిది'
|
|
60
|
+
'తొంభై', 'తొంభై ఒకటి', 'తొంభై రెండు', 'తొంభై మూడు', 'తొంభై నాలుగు', 'తొంభై ఐదు', 'తొంభై ఆరు', 'తొంభై ఏడు', 'తొంభై ఎనిమిది', 'తొంభై తొమ్మిది',
|
|
59
61
|
]
|
|
60
62
|
|
|
61
63
|
const HUNDREDS = ['', 'వంద', 'రెండు వందలు', 'మూడు వందలు', 'నాలుగు వందలు', 'ఐదు వందలు', 'ఆరు వందలు', 'ఏడు వందలు', 'ఎనిమిది వందలు', 'తొమ్మిది వందలు']
|
|
@@ -66,14 +68,23 @@ const ONES = ['ఒకటి', 'రెండు', 'మూడు', 'నాలు
|
|
|
66
68
|
// Scale words: index 0 = units, 1 = thousand, 2 = lakh, etc.
|
|
67
69
|
const SCALE_WORDS = ['', 'వెయ్యి', 'లక్ష', 'కోటి', 'అరబ్', 'ఖరబ్', 'నిల్', 'పడ్మ', 'శంకు']
|
|
68
70
|
|
|
71
|
+
// 3-2-2 Indian grouping: a 3-digit base segment, then 2 digits per scale word
|
|
72
|
+
// (SCALE_WORDS[0] = '' is the units slot). Past the table the scale word is
|
|
73
|
+
// dropped, which collapses the magnitude — so cap there.
|
|
74
|
+
export const cardinalMax = indian(SCALE_WORDS.length)
|
|
75
|
+
export const ordinalMax = indian(SCALE_WORDS.length)
|
|
76
|
+
export const currencyMax = indian(SCALE_WORDS.length)
|
|
77
|
+
|
|
69
78
|
// ============================================================================
|
|
70
79
|
// Segment Building
|
|
71
80
|
// ============================================================================
|
|
72
81
|
|
|
73
82
|
/**
|
|
74
83
|
* Builds words for a 0-999 segment.
|
|
84
|
+
* @param {number} n - Segment value (0-999)
|
|
85
|
+
* @returns {string} Telugu words for the segment
|
|
75
86
|
*/
|
|
76
|
-
function buildSegment
|
|
87
|
+
function buildSegment(n) {
|
|
77
88
|
if (n === 0) return ''
|
|
78
89
|
if (n < 100) return BELOW_HUNDRED[n]
|
|
79
90
|
|
|
@@ -95,11 +106,10 @@ function buildSegment (n) {
|
|
|
95
106
|
*
|
|
96
107
|
* Uses BigInt modulo for segment extraction (faster than string slicing).
|
|
97
108
|
* South Asian 3-2-2 grouping: first 3 digits, then groups of 2.
|
|
98
|
-
*
|
|
99
109
|
* @param {bigint} n - Non-negative integer to convert
|
|
100
110
|
* @returns {string} Telugu words
|
|
101
111
|
*/
|
|
102
|
-
function integerToWords
|
|
112
|
+
function integerToWords(n) {
|
|
103
113
|
if (n === 0n) return ZERO
|
|
104
114
|
|
|
105
115
|
// Fast path: numbers < 1000 (direct lookup)
|
|
@@ -125,7 +135,8 @@ function integerToWords (n) {
|
|
|
125
135
|
|
|
126
136
|
if (i === 0) {
|
|
127
137
|
words.push(buildSegment(segment))
|
|
128
|
-
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
129
140
|
// Use 'ఒక' for 1 at scale positions
|
|
130
141
|
const groupWords = (segment === 1) ? 'ఒక' : BELOW_HUNDRED[segment]
|
|
131
142
|
words.push(groupWords)
|
|
@@ -139,7 +150,12 @@ function integerToWords (n) {
|
|
|
139
150
|
return words.join(' ')
|
|
140
151
|
}
|
|
141
152
|
|
|
142
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Reads a decimal fraction digit-by-digit in Telugu.
|
|
155
|
+
* @param {string} decimalPart - Fractional digits as a string
|
|
156
|
+
* @returns {string} Telugu words for each digit
|
|
157
|
+
*/
|
|
158
|
+
function decimalPartToWords(decimalPart) {
|
|
143
159
|
// Per-digit decimal reading
|
|
144
160
|
const digits = []
|
|
145
161
|
for (const char of decimalPart) {
|
|
@@ -151,12 +167,13 @@ function decimalPartToWords (decimalPart) {
|
|
|
151
167
|
|
|
152
168
|
/**
|
|
153
169
|
* Converts a numeric value to Telugu words.
|
|
154
|
-
*
|
|
155
170
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
156
171
|
* @returns {string} The number in Telugu words
|
|
157
172
|
*/
|
|
158
|
-
function toCardinal
|
|
173
|
+
function toCardinal(value) {
|
|
159
174
|
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
175
|
+
// The fraction is spelled digit by digit, so only the integer part has a ceiling.
|
|
176
|
+
checkMax(integerPart, cardinalMax)
|
|
160
177
|
|
|
161
178
|
let result = ''
|
|
162
179
|
|
|
@@ -181,11 +198,10 @@ function toCardinal (value) {
|
|
|
181
198
|
* Converts a positive integer to Telugu ordinal words.
|
|
182
199
|
*
|
|
183
200
|
* Telugu ordinals: First 6 are irregular, then add -వ suffix.
|
|
184
|
-
*
|
|
185
201
|
* @param {bigint} n - Positive integer to convert
|
|
186
202
|
* @returns {string} Telugu ordinal words
|
|
187
203
|
*/
|
|
188
|
-
function integerToOrdinal
|
|
204
|
+
function integerToOrdinal(n) {
|
|
189
205
|
// Special ordinals for 1-6
|
|
190
206
|
if (n >= 1n && n <= 6n) {
|
|
191
207
|
return ORDINAL_SPECIAL[Number(n)]
|
|
@@ -198,19 +214,19 @@ function integerToOrdinal (n) {
|
|
|
198
214
|
|
|
199
215
|
/**
|
|
200
216
|
* Converts a numeric value to Telugu ordinal words.
|
|
201
|
-
*
|
|
202
217
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
203
218
|
* @returns {string} The number as ordinal words
|
|
204
219
|
* @throws {TypeError} If value is not a valid numeric type
|
|
205
220
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
206
|
-
*
|
|
207
221
|
* @example
|
|
208
222
|
* toOrdinal(1) // 'మొదటి'
|
|
209
223
|
* toOrdinal(2) // 'రెండవ'
|
|
210
224
|
* toOrdinal(10) // 'పదివ'
|
|
211
225
|
*/
|
|
212
|
-
function toOrdinal
|
|
226
|
+
function toOrdinal(value) {
|
|
213
227
|
const integerPart = parseOrdinalValue(value)
|
|
228
|
+
// Ordinals build on the cardinal speller, so they share its ceiling.
|
|
229
|
+
checkMax(integerPart, ordinalMax)
|
|
214
230
|
return integerToOrdinal(integerPart)
|
|
215
231
|
}
|
|
216
232
|
|
|
@@ -220,19 +236,18 @@ function toOrdinal (value) {
|
|
|
220
236
|
|
|
221
237
|
/**
|
|
222
238
|
* Converts a numeric value to Telugu currency words (Indian Rupee).
|
|
223
|
-
*
|
|
224
239
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
225
240
|
* @returns {string} The amount in Telugu currency words
|
|
226
241
|
* @throws {TypeError} If value is not a valid numeric type
|
|
227
242
|
* @throws {Error} If value is not a valid number format
|
|
228
|
-
*
|
|
229
243
|
* @example
|
|
230
244
|
* toCurrency(42.50) // 'నలభై రెండు రూపాయలు యాభై పైసలు'
|
|
231
245
|
* toCurrency(1) // 'ఒకటి రూపాయి'
|
|
232
246
|
* toCurrency(0.01) // 'ఒకటి పైసా'
|
|
233
247
|
*/
|
|
234
|
-
function toCurrency
|
|
248
|
+
function toCurrency(value) {
|
|
235
249
|
const { isNegative, dollars: rupees, cents: paise } = parseCurrencyValue(value)
|
|
250
|
+
checkMax(rupees, currencyMax)
|
|
236
251
|
|
|
237
252
|
// Build result
|
|
238
253
|
let result = ''
|
package/src/th-TH.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
export const cardinalMax: null;
|
|
2
|
+
export const ordinalMax: null;
|
|
3
|
+
export const currencyMax: null;
|
|
1
4
|
/**
|
|
2
5
|
* Converts a numeric value to Thai words.
|
|
3
|
-
*
|
|
4
6
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
7
|
* @returns {string} The number in Thai words
|
|
6
8
|
*/
|
|
7
9
|
export function toCardinal(value: number | string | bigint): string;
|
|
8
10
|
/**
|
|
9
11
|
* Converts a numeric value to Thai ordinal words.
|
|
10
|
-
*
|
|
11
12
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
12
13
|
* @returns {string} The number as ordinal words
|
|
13
14
|
* @throws {TypeError} If value is not a valid numeric type
|
|
14
15
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
15
|
-
*
|
|
16
16
|
* @example
|
|
17
17
|
* toOrdinal(1) // 'ที่หนึ่ง'
|
|
18
18
|
* toOrdinal(2) // 'ที่สอง'
|
|
@@ -24,12 +24,10 @@ export function toOrdinal(value: number | string | bigint): string;
|
|
|
24
24
|
*
|
|
25
25
|
* Thai Baht uses satang as subunit (100 satang = 1 baht).
|
|
26
26
|
* When whole amounts, adds "ถ้วน" (exactly) suffix.
|
|
27
|
-
*
|
|
28
27
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
29
28
|
* @returns {string} The amount in Thai currency words
|
|
30
29
|
* @throws {TypeError} If value is not a valid numeric type
|
|
31
30
|
* @throws {Error} If value is not a valid number format
|
|
32
|
-
*
|
|
33
31
|
* @example
|
|
34
32
|
* toCurrency(42) // 'สี่สิบสองบาทถ้วน'
|
|
35
33
|
* toCurrency(1.50) // 'หนึ่งบาทห้าสิบสตางค์'
|