n2words 2.0.0 → 3.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 +64 -0
- package/README.md +86 -188
- package/dist/languages/am-Latn.js +3 -0
- package/dist/languages/am-Latn.js.map +1 -0
- package/dist/languages/am.js +3 -0
- package/dist/languages/am.js.map +1 -0
- package/dist/languages/ar.js +3 -0
- package/dist/languages/ar.js.map +1 -0
- package/dist/languages/az.js +3 -0
- package/dist/languages/az.js.map +1 -0
- package/dist/languages/bn.js +3 -0
- package/dist/languages/bn.js.map +1 -0
- package/dist/languages/cs.js +3 -0
- package/dist/languages/cs.js.map +1 -0
- package/dist/languages/da.js +3 -0
- package/dist/languages/da.js.map +1 -0
- package/dist/languages/de.js +3 -0
- package/dist/languages/de.js.map +1 -0
- package/dist/languages/el.js +3 -0
- package/dist/languages/el.js.map +1 -0
- package/dist/languages/en.js +3 -0
- package/dist/languages/en.js.map +1 -0
- package/dist/languages/es.js +3 -0
- package/dist/languages/es.js.map +1 -0
- package/dist/languages/fa.js +3 -0
- package/dist/languages/fa.js.map +1 -0
- package/dist/languages/fi.js +3 -0
- package/dist/languages/fi.js.map +1 -0
- package/dist/languages/fil.js +3 -0
- package/dist/languages/fil.js.map +1 -0
- package/dist/languages/fr-BE.js +3 -0
- package/dist/languages/fr-BE.js.map +1 -0
- package/dist/languages/fr.js +3 -0
- package/dist/languages/fr.js.map +1 -0
- package/dist/languages/gu.js +3 -0
- package/dist/languages/gu.js.map +1 -0
- package/dist/languages/ha.js +3 -0
- package/dist/languages/ha.js.map +1 -0
- package/dist/languages/hbo.js +3 -0
- package/dist/languages/hbo.js.map +1 -0
- package/dist/languages/he.js +3 -0
- package/dist/languages/he.js.map +1 -0
- package/dist/languages/hi.js +3 -0
- package/dist/languages/hi.js.map +1 -0
- package/dist/languages/hr.js +3 -0
- package/dist/languages/hr.js.map +1 -0
- package/dist/languages/hu.js +3 -0
- package/dist/languages/hu.js.map +1 -0
- package/dist/languages/id.js +3 -0
- package/dist/languages/id.js.map +1 -0
- package/dist/languages/it.js +3 -0
- package/dist/languages/it.js.map +1 -0
- package/dist/languages/ja.js +3 -0
- package/dist/languages/ja.js.map +1 -0
- package/dist/languages/ka.js +3 -0
- package/dist/languages/ka.js.map +1 -0
- package/dist/languages/kn.js +3 -0
- package/dist/languages/kn.js.map +1 -0
- package/dist/languages/ko.js +3 -0
- package/dist/languages/ko.js.map +1 -0
- package/dist/languages/lt.js +3 -0
- package/dist/languages/lt.js.map +1 -0
- package/dist/languages/lv.js +3 -0
- package/dist/languages/lv.js.map +1 -0
- package/dist/languages/mr.js +3 -0
- package/dist/languages/mr.js.map +1 -0
- package/dist/languages/ms.js +3 -0
- package/dist/languages/ms.js.map +1 -0
- package/dist/languages/nb.js +3 -0
- package/dist/languages/nb.js.map +1 -0
- package/dist/languages/nl.js +3 -0
- package/dist/languages/nl.js.map +1 -0
- package/dist/languages/pa.js +3 -0
- package/dist/languages/pa.js.map +1 -0
- package/dist/languages/pl.js +3 -0
- package/dist/languages/pl.js.map +1 -0
- package/dist/languages/pt.js +3 -0
- package/dist/languages/pt.js.map +1 -0
- package/dist/languages/ro.js +3 -0
- package/dist/languages/ro.js.map +1 -0
- package/dist/languages/ru.js +3 -0
- package/dist/languages/ru.js.map +1 -0
- package/dist/languages/sr-Cyrl.js +3 -0
- package/dist/languages/sr-Cyrl.js.map +1 -0
- package/dist/languages/sr-Latn.js +3 -0
- package/dist/languages/sr-Latn.js.map +1 -0
- package/dist/languages/sv.js +3 -0
- package/dist/languages/sv.js.map +1 -0
- package/dist/languages/sw.js +3 -0
- package/dist/languages/sw.js.map +1 -0
- package/dist/languages/ta.js +3 -0
- package/dist/languages/ta.js.map +1 -0
- package/dist/languages/te.js +3 -0
- package/dist/languages/te.js.map +1 -0
- package/dist/languages/th.js +3 -0
- package/dist/languages/th.js.map +1 -0
- package/dist/languages/tr.js +3 -0
- package/dist/languages/tr.js.map +1 -0
- package/dist/languages/uk.js +3 -0
- package/dist/languages/uk.js.map +1 -0
- package/dist/languages/ur.js +3 -0
- package/dist/languages/ur.js.map +1 -0
- package/dist/languages/vi.js +3 -0
- package/dist/languages/vi.js.map +1 -0
- package/dist/languages/yo.js +3 -0
- package/dist/languages/yo.js.map +1 -0
- package/dist/languages/zh-Hans.js +3 -0
- package/dist/languages/zh-Hans.js.map +1 -0
- package/dist/languages/zh-Hant.js +3 -0
- package/dist/languages/zh-Hant.js.map +1 -0
- package/dist/n2words.js +2 -2
- package/dist/n2words.js.map +1 -1
- package/lib/languages/am-Latn.d.ts +7 -0
- package/lib/languages/am-Latn.js +159 -0
- package/lib/languages/am.d.ts +7 -0
- package/lib/languages/am.js +159 -0
- package/lib/languages/ar.d.ts +14 -27
- package/lib/languages/ar.js +175 -129
- package/lib/languages/az.d.ts +4 -9
- package/lib/languages/az.js +166 -37
- package/lib/languages/bn.d.ts +4 -8
- package/lib/languages/bn.js +159 -124
- package/lib/languages/cs.d.ts +15 -85
- package/lib/languages/cs.js +293 -114
- package/lib/languages/da.d.ts +11 -12
- package/lib/languages/da.js +269 -101
- package/lib/languages/de.d.ts +14 -11
- package/lib/languages/de.js +305 -86
- package/lib/languages/el.d.ts +11 -11
- package/lib/languages/el.js +224 -78
- package/lib/languages/en.d.ts +14 -13
- package/lib/languages/en.js +228 -72
- package/lib/languages/es.d.ts +18 -12
- package/lib/languages/es.js +297 -103
- package/lib/languages/fa.d.ts +4 -44
- package/lib/languages/fa.js +112 -122
- package/lib/languages/fi.d.ts +14 -0
- package/lib/languages/fi.js +238 -0
- package/lib/languages/fil.d.ts +4 -13
- package/lib/languages/fil.js +196 -106
- package/lib/languages/fr-BE.d.ts +8 -8
- package/lib/languages/fr-BE.js +285 -19
- package/lib/languages/fr.d.ts +18 -12
- package/lib/languages/fr.js +339 -89
- package/lib/languages/gu.d.ts +4 -8
- package/lib/languages/gu.js +143 -125
- package/lib/languages/ha.d.ts +7 -0
- package/lib/languages/ha.js +225 -0
- package/lib/languages/hbo.d.ts +10 -110
- package/lib/languages/hbo.js +245 -214
- package/lib/languages/he.d.ts +10 -77
- package/lib/languages/he.js +231 -172
- package/lib/languages/hi.d.ts +4 -8
- package/lib/languages/hi.js +163 -124
- package/lib/languages/hr.d.ts +8 -77
- package/lib/languages/hr.js +200 -89
- package/lib/languages/hu.d.ts +4 -19
- package/lib/languages/hu.js +198 -119
- package/lib/languages/id.d.ts +4 -34
- package/lib/languages/id.js +166 -129
- package/lib/languages/it.d.ts +16 -34
- package/lib/languages/it.js +307 -97
- package/lib/languages/ja.d.ts +14 -14
- package/lib/languages/ja.js +221 -111
- package/lib/languages/ka.d.ts +17 -0
- package/lib/languages/ka.js +291 -0
- package/lib/languages/kn.d.ts +4 -8
- package/lib/languages/kn.js +143 -35
- package/lib/languages/ko.d.ts +11 -11
- package/lib/languages/ko.js +250 -49
- package/lib/languages/lt.d.ts +15 -67
- package/lib/languages/lt.js +287 -122
- package/lib/languages/lv.d.ts +15 -67
- package/lib/languages/lv.js +288 -106
- package/lib/languages/mr.d.ts +4 -8
- package/lib/languages/mr.js +143 -125
- package/lib/languages/ms.d.ts +4 -28
- package/lib/languages/ms.js +166 -116
- package/lib/languages/nb.d.ts +11 -9
- package/lib/languages/nb.js +272 -87
- package/lib/languages/nl.d.ts +23 -13
- package/lib/languages/nl.js +299 -133
- package/lib/languages/pa.d.ts +4 -8
- package/lib/languages/pa.js +151 -124
- package/lib/languages/pl.d.ts +19 -77
- package/lib/languages/pl.js +294 -87
- package/lib/languages/pt.d.ts +14 -26
- package/lib/languages/pt.js +272 -92
- package/lib/languages/ro.d.ts +15 -155
- package/lib/languages/ro.js +219 -235
- package/lib/languages/ru.d.ts +8 -82
- package/lib/languages/ru.js +239 -90
- package/lib/languages/sr-Cyrl.d.ts +8 -77
- package/lib/languages/sr-Cyrl.js +197 -89
- package/lib/languages/sr-Latn.d.ts +8 -77
- package/lib/languages/sr-Latn.js +197 -89
- package/lib/languages/sv.d.ts +11 -11
- package/lib/languages/sv.js +278 -74
- package/lib/languages/sw.d.ts +4 -36
- package/lib/languages/sw.js +133 -106
- package/lib/languages/ta.d.ts +4 -17
- package/lib/languages/ta.js +143 -202
- package/lib/languages/te.d.ts +4 -19
- package/lib/languages/te.js +133 -196
- package/lib/languages/th.d.ts +4 -14
- package/lib/languages/th.js +135 -91
- package/lib/languages/tr.d.ts +15 -9
- package/lib/languages/tr.js +245 -49
- package/lib/languages/uk.d.ts +8 -82
- package/lib/languages/uk.js +206 -78
- package/lib/languages/ur.d.ts +4 -8
- package/lib/languages/ur.js +151 -124
- package/lib/languages/vi.d.ts +14 -69
- package/lib/languages/vi.js +278 -129
- package/lib/languages/yo.d.ts +7 -0
- package/lib/languages/yo.js +303 -0
- package/lib/languages/zh-Hans.d.ts +8 -18
- package/lib/languages/zh-Hans.js +163 -92
- package/lib/languages/zh-Hant.d.ts +8 -18
- package/lib/languages/zh-Hant.js +181 -90
- package/lib/n2words.d.ts +55 -209
- package/lib/n2words.js +115 -530
- package/lib/utils/is-plain-object.d.ts +13 -0
- package/lib/utils/is-plain-object.js +17 -0
- package/lib/utils/parse-numeric.d.ts +17 -0
- package/lib/utils/parse-numeric.js +108 -0
- package/lib/utils/validate-options.d.ts +8 -0
- package/lib/utils/validate-options.js +16 -0
- package/package.json +26 -14
- package/dist/ArabicConverter.js +0 -3
- package/dist/ArabicConverter.js.map +0 -1
- package/dist/AzerbaijaniConverter.js +0 -3
- package/dist/AzerbaijaniConverter.js.map +0 -1
- package/dist/BanglaConverter.js +0 -3
- package/dist/BanglaConverter.js.map +0 -1
- package/dist/BiblicalHebrewConverter.js +0 -3
- package/dist/BiblicalHebrewConverter.js.map +0 -1
- package/dist/CroatianConverter.js +0 -3
- package/dist/CroatianConverter.js.map +0 -1
- package/dist/CzechConverter.js +0 -3
- package/dist/CzechConverter.js.map +0 -1
- package/dist/DanishConverter.js +0 -3
- package/dist/DanishConverter.js.map +0 -1
- package/dist/DutchConverter.js +0 -3
- package/dist/DutchConverter.js.map +0 -1
- package/dist/EnglishConverter.js +0 -3
- package/dist/EnglishConverter.js.map +0 -1
- package/dist/FilipinoConverter.js +0 -3
- package/dist/FilipinoConverter.js.map +0 -1
- package/dist/FrenchBelgiumConverter.js +0 -3
- package/dist/FrenchBelgiumConverter.js.map +0 -1
- package/dist/FrenchConverter.js +0 -3
- package/dist/FrenchConverter.js.map +0 -1
- package/dist/GermanConverter.js +0 -3
- package/dist/GermanConverter.js.map +0 -1
- package/dist/GreekConverter.js +0 -3
- package/dist/GreekConverter.js.map +0 -1
- package/dist/GujaratiConverter.js +0 -3
- package/dist/GujaratiConverter.js.map +0 -1
- package/dist/HebrewConverter.js +0 -3
- package/dist/HebrewConverter.js.map +0 -1
- package/dist/HindiConverter.js +0 -3
- package/dist/HindiConverter.js.map +0 -1
- package/dist/HungarianConverter.js +0 -3
- package/dist/HungarianConverter.js.map +0 -1
- package/dist/IndonesianConverter.js +0 -3
- package/dist/IndonesianConverter.js.map +0 -1
- package/dist/ItalianConverter.js +0 -3
- package/dist/ItalianConverter.js.map +0 -1
- package/dist/JapaneseConverter.js +0 -3
- package/dist/JapaneseConverter.js.map +0 -1
- package/dist/KannadaConverter.js +0 -3
- package/dist/KannadaConverter.js.map +0 -1
- package/dist/KoreanConverter.js +0 -3
- package/dist/KoreanConverter.js.map +0 -1
- package/dist/LatvianConverter.js +0 -3
- package/dist/LatvianConverter.js.map +0 -1
- package/dist/LithuanianConverter.js +0 -3
- package/dist/LithuanianConverter.js.map +0 -1
- package/dist/MalayConverter.js +0 -3
- package/dist/MalayConverter.js.map +0 -1
- package/dist/MarathiConverter.js +0 -3
- package/dist/MarathiConverter.js.map +0 -1
- package/dist/NorwegianBokmalConverter.js +0 -3
- package/dist/NorwegianBokmalConverter.js.map +0 -1
- package/dist/PersianConverter.js +0 -3
- package/dist/PersianConverter.js.map +0 -1
- package/dist/PolishConverter.js +0 -3
- package/dist/PolishConverter.js.map +0 -1
- package/dist/PortugueseConverter.js +0 -3
- package/dist/PortugueseConverter.js.map +0 -1
- package/dist/PunjabiConverter.js +0 -3
- package/dist/PunjabiConverter.js.map +0 -1
- package/dist/RomanianConverter.js +0 -3
- package/dist/RomanianConverter.js.map +0 -1
- package/dist/RussianConverter.js +0 -3
- package/dist/RussianConverter.js.map +0 -1
- package/dist/SerbianCyrillicConverter.js +0 -3
- package/dist/SerbianCyrillicConverter.js.map +0 -1
- package/dist/SerbianLatinConverter.js +0 -3
- package/dist/SerbianLatinConverter.js.map +0 -1
- package/dist/SimplifiedChineseConverter.js +0 -3
- package/dist/SimplifiedChineseConverter.js.map +0 -1
- package/dist/SpanishConverter.js +0 -3
- package/dist/SpanishConverter.js.map +0 -1
- package/dist/SwahiliConverter.js +0 -3
- package/dist/SwahiliConverter.js.map +0 -1
- package/dist/SwedishConverter.js +0 -3
- package/dist/SwedishConverter.js.map +0 -1
- package/dist/TamilConverter.js +0 -3
- package/dist/TamilConverter.js.map +0 -1
- package/dist/TeluguConverter.js +0 -3
- package/dist/TeluguConverter.js.map +0 -1
- package/dist/ThaiConverter.js +0 -3
- package/dist/ThaiConverter.js.map +0 -1
- package/dist/TraditionalChineseConverter.js +0 -3
- package/dist/TraditionalChineseConverter.js.map +0 -1
- package/dist/TurkishConverter.js +0 -3
- package/dist/TurkishConverter.js.map +0 -1
- package/dist/UkrainianConverter.js +0 -3
- package/dist/UkrainianConverter.js.map +0 -1
- package/dist/UrduConverter.js +0 -3
- package/dist/UrduConverter.js.map +0 -1
- package/dist/VietnameseConverter.js +0 -3
- package/dist/VietnameseConverter.js.map +0 -1
- package/lib/classes/abstract-language.d.ts +0 -178
- package/lib/classes/abstract-language.js +0 -268
- package/lib/classes/greedy-scale-language.d.ts +0 -109
- package/lib/classes/greedy-scale-language.js +0 -201
- package/lib/classes/slavic-language.d.ts +0 -148
- package/lib/classes/slavic-language.js +0 -281
- package/lib/classes/south-asian-language.d.ts +0 -70
- package/lib/classes/south-asian-language.js +0 -154
- package/lib/classes/turkic-language.d.ts +0 -26
- package/lib/classes/turkic-language.js +0 -59
package/lib/languages/ar.js
CHANGED
|
@@ -1,159 +1,205 @@
|
|
|
1
|
-
import { AbstractLanguage } from '../classes/abstract-language.js'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* Arabic language converter
|
|
2
|
+
* Arabic language converter - Functional Implementation
|
|
3
|
+
*
|
|
4
|
+
* Self-contained converter with gender agreement and complex pluralization.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Key features:
|
|
7
7
|
* - Gender agreement (masculine/feminine forms)
|
|
8
8
|
* - Complex pluralization (singular/dual/plural)
|
|
9
9
|
* - Traditional Arabic number naming conventions
|
|
10
|
-
* -
|
|
10
|
+
* - "و" (and) conjunction between segments
|
|
11
11
|
*/
|
|
12
|
-
export class Arabic extends AbstractLanguage {
|
|
13
|
-
negativeWord = 'ناقص'
|
|
14
|
-
decimalSeparatorWord = 'فاصلة'
|
|
15
|
-
zeroWord = 'صفر'
|
|
16
|
-
|
|
17
|
-
tensWords = ['عشرون', 'ثلاثون', 'أربعون', 'خمسون', 'ستون', 'سبعون', 'ثمانون', 'تسعون']
|
|
18
|
-
hundredsWords = ['', 'مائة', 'مئتان', 'ثلاثمائة', 'أربعمائة', 'خمسمائة', 'ستمائة', 'سبعمائة', 'ثمانمائة', 'تسعمائة']
|
|
19
|
-
|
|
20
|
-
// Magnitude words with three forms: singular, appended (tanween), plural
|
|
21
|
-
scaleWords = ['مائة', 'ألف', 'مليون', 'مليار', 'تريليون', 'كوادريليون', 'كوينتليون', 'سكستيليون']
|
|
22
|
-
scaleAppendedWords = ['', 'ألفاً', 'مليوناً', 'ملياراً', 'تريليوناً', 'كوادريليوناً', 'كوينتليوناً', 'سكستيليوناً']
|
|
23
|
-
scalePluralWords = ['', 'آلاف', 'ملايين', 'مليارات', 'تريليونات', 'كوادريليونات', 'كوينتليونات', 'سكستيليونات']
|
|
24
|
-
|
|
25
|
-
// Dual forms (Arabic has singular, dual, plural)
|
|
26
|
-
dualWords = ['مئتان', 'ألفان', 'مليونان', 'ملياران', 'تريليونان', 'كوادريليونان', 'كوينتليونان', 'سكستيليونان']
|
|
27
|
-
dualAppendedWords = ['مئتا', 'ألفا', 'مليونا', 'مليارا', 'تريليونا', 'كوادريليونا', 'كوينتليونا', 'سكستيليونا']
|
|
28
|
-
|
|
29
|
-
// Gender-specific number words (1-19)
|
|
30
|
-
ones = {
|
|
31
|
-
masculine: [
|
|
32
|
-
'واحد', 'اثنان', 'ثلاثة', 'أربعة', 'خمسة', 'ستة', 'سبعة', 'ثمانية', 'تسعة', 'عشرة',
|
|
33
|
-
'أحد عشر', 'اثنا عشر', 'ثلاثة عشر', 'أربعة عشر', 'خمسة عشر', 'ستة عشر', 'سبعة عشر', 'ثمانية عشر', 'تسعة عشر'
|
|
34
|
-
],
|
|
35
|
-
feminine: [
|
|
36
|
-
'واحدة', 'اثنتان', 'ثلاث', 'أربع', 'خمس', 'ست', 'سبع', 'ثمان', 'تسع', 'عشر',
|
|
37
|
-
'إحدى عشرة', 'اثنتا عشرة', 'ثلاث عشرة', 'أربع عشرة', 'خمس عشرة', 'ست عشرة', 'سبع عشرة', 'ثماني عشرة', 'تسع عشرة'
|
|
38
|
-
]
|
|
39
|
-
}
|
|
40
12
|
|
|
41
|
-
|
|
42
|
-
|
|
13
|
+
import { parseNumericValue } from '../utils/parse-numeric.js'
|
|
14
|
+
import { validateOptions } from '../utils/validate-options.js'
|
|
43
15
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Vocabulary
|
|
18
|
+
// ============================================================================
|
|
47
19
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
20
|
+
const TENS = ['عشرون', 'ثلاثون', 'أربعون', 'خمسون', 'ستون', 'سبعون', 'ثمانون', 'تسعون']
|
|
21
|
+
const HUNDREDS = ['', 'مائة', 'مئتان', 'ثلاثمائة', 'أربعمائة', 'خمسمائة', 'ستمائة', 'سبعمائة', 'ثمانمائة', 'تسعمائة']
|
|
22
|
+
|
|
23
|
+
// Magnitude words with three forms: singular, appended (tanween), plural
|
|
24
|
+
const SCALE_WORDS = ['مائة', 'ألف', 'مليون', 'مليار', 'تريليون', 'كوادريليون', 'كوينتليون', 'سكستيليون']
|
|
25
|
+
const SCALE_APPENDED = ['', 'ألفاً', 'مليوناً', 'ملياراً', 'تريليوناً', 'كوادريليوناً', 'كوينتليوناً', 'سكستيليوناً']
|
|
26
|
+
const SCALE_PLURAL = ['', 'آلاف', 'ملايين', 'مليارات', 'تريليونات', 'كوادريليونات', 'كوينتليونات', 'سكستيليونات']
|
|
27
|
+
|
|
28
|
+
// Dual forms
|
|
29
|
+
const DUAL = ['مئتان', 'ألفان', 'مليونان', 'ملياران', 'تريليونان', 'كوادريليونان', 'كوينتليونان', 'سكستيليونان']
|
|
30
|
+
const DUAL_APPENDED = ['مئتا', 'ألفا', 'مليونا', 'مليارا', 'تريليونا', 'كوادريليونا', 'كوينتليونا', 'سكستيليونا']
|
|
31
|
+
|
|
32
|
+
// Gender-specific forms (1-19)
|
|
33
|
+
const ONES_MASC = ['واحد', 'اثنان', 'ثلاثة', 'أربعة', 'خمسة', 'ستة', 'سبعة', 'ثمانية', 'تسعة', 'عشرة', 'أحد عشر', 'اثنا عشر', 'ثلاثة عشر', 'أربعة عشر', 'خمسة عشر', 'ستة عشر', 'سبعة عشر', 'ثمانية عشر', 'تسعة عشر']
|
|
34
|
+
const ONES_FEM = ['واحدة', 'اثنتان', 'ثلاث', 'أربع', 'خمس', 'ست', 'سبع', 'ثمان', 'تسع', 'عشر', 'إحدى عشرة', 'اثنتا عشرة', 'ثلاث عشرة', 'أربع عشرة', 'خمس عشرة', 'ست عشرة', 'سبع عشرة', 'ثماني عشرة', 'تسع عشرة']
|
|
53
35
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
36
|
+
const ZERO = 'صفر'
|
|
37
|
+
const NEGATIVE = 'ناقص'
|
|
38
|
+
const DECIMAL_SEP = 'فاصلة'
|
|
39
|
+
const AND = 'و'
|
|
40
|
+
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// Conversion Functions
|
|
43
|
+
// ============================================================================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Convert a 3-digit group to words.
|
|
47
|
+
* Returns a clean string with no leading/trailing spaces.
|
|
48
|
+
* Arabic "و" (and) is attached to following word: "مائة وخمسة" not "مائة و خمسة"
|
|
49
|
+
*/
|
|
50
|
+
function segmentToWords (groupNumber, groupLevel, fullNumber, ones) {
|
|
51
|
+
const tensValue = groupNumber % 100
|
|
52
|
+
const hundredsDigit = Math.trunc(groupNumber / 100)
|
|
53
|
+
let result = ''
|
|
54
|
+
|
|
55
|
+
// Process hundreds
|
|
56
|
+
if (hundredsDigit > 0) {
|
|
57
|
+
if (tensValue === 0 && hundredsDigit === 2) {
|
|
58
|
+
result = DUAL[0]
|
|
59
|
+
} else {
|
|
60
|
+
const hundredsWord = HUNDREDS[hundredsDigit]
|
|
61
|
+
if (hundredsWord) {
|
|
62
|
+
result = hundredsWord
|
|
63
|
+
if (tensValue !== 0) {
|
|
64
|
+
result += ' ' + AND // "مائة و" - و attaches to next word
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
57
68
|
}
|
|
58
69
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
returnValue = this.dualWords[0]
|
|
70
|
-
} else {
|
|
71
|
-
const hundredsWord = this.hundredsWords[hundreds]
|
|
72
|
-
if (hundredsWord) {
|
|
73
|
-
returnValue = hundredsWord
|
|
74
|
-
if (tens !== 0) {
|
|
75
|
-
returnValue += ' و'
|
|
76
|
-
}
|
|
70
|
+
// Process tens and ones
|
|
71
|
+
if (tensValue > 0) {
|
|
72
|
+
if (tensValue < 20) {
|
|
73
|
+
if (tensValue === 2 && hundredsDigit === 0 && groupLevel > 0) {
|
|
74
|
+
const numValue = Number(fullNumber)
|
|
75
|
+
const pow = Math.trunc(Math.log10(numValue))
|
|
76
|
+
if (pow % 3 === 0 && fullNumber === BigInt(2 * Math.pow(10, pow))) {
|
|
77
|
+
result += (groupNumber === 2 ? DUAL[groupLevel] : DUAL_APPENDED[groupLevel])
|
|
78
|
+
} else {
|
|
79
|
+
result += DUAL[groupLevel]
|
|
77
80
|
}
|
|
81
|
+
} else if (tensValue === 1 && groupLevel > 0) {
|
|
82
|
+
result += SCALE_WORDS[groupLevel]
|
|
83
|
+
} else {
|
|
84
|
+
result += ones[tensValue - 1]
|
|
78
85
|
}
|
|
86
|
+
} else {
|
|
87
|
+
const onesDigit = tensValue % 10
|
|
88
|
+
const tensIndex = Math.trunc(tensValue / 10) - 2
|
|
89
|
+
|
|
90
|
+
if (onesDigit > 0) {
|
|
91
|
+
result += ones[onesDigit - 1] + ' ' + AND // "ستة و" attaches to tens
|
|
92
|
+
}
|
|
93
|
+
result += TENS[tensIndex]
|
|
79
94
|
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return result
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function integerToWords (n, options) {
|
|
101
|
+
if (n === 0n) return ZERO
|
|
102
|
+
|
|
103
|
+
const gender = options.gender || 'masculine'
|
|
104
|
+
const ones = gender === 'feminine' ? ONES_FEM : ONES_MASC
|
|
105
|
+
|
|
106
|
+
let temp = n
|
|
107
|
+
let group = 0
|
|
108
|
+
const groups = []
|
|
109
|
+
|
|
110
|
+
while (temp > 0n) {
|
|
111
|
+
const numberToProcess = Number(temp % 1000n)
|
|
112
|
+
temp = temp / 1000n
|
|
113
|
+
|
|
114
|
+
if (numberToProcess > 0) {
|
|
115
|
+
const groupDescription = segmentToWords(numberToProcess, group, n, ones)
|
|
80
116
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
117
|
+
if (groupDescription) {
|
|
118
|
+
let groupText = groupDescription
|
|
119
|
+
|
|
120
|
+
// Add scale word for groups > 0
|
|
121
|
+
if (group > 0 && numberToProcess > 2) {
|
|
122
|
+
const remainder = numberToProcess % 100
|
|
123
|
+
if (remainder === 1) {
|
|
124
|
+
groupText += ' ' + SCALE_WORDS[group]
|
|
125
|
+
} else if (numberToProcess >= 3 && numberToProcess <= 10) {
|
|
126
|
+
groupText += ' ' + SCALE_PLURAL[group]
|
|
90
127
|
} else {
|
|
91
|
-
|
|
128
|
+
groupText += ' ' + (groups.length > 0 ? SCALE_APPENDED[group] : SCALE_WORDS[group])
|
|
92
129
|
}
|
|
93
|
-
} else if (tens === 1 && groupLevel > 0) {
|
|
94
|
-
returnValue += this.scaleWords[groupLevel]
|
|
95
|
-
} else {
|
|
96
|
-
returnValue += this.selectedOnes[tens - 1]
|
|
97
130
|
}
|
|
98
|
-
} else { // 20 -> 99
|
|
99
|
-
const ones = tens % 10
|
|
100
|
-
const tensIndex = Math.trunc(tens / 10) - 2
|
|
101
131
|
|
|
102
|
-
|
|
103
|
-
returnValue += this.selectedOnes[ones - 1]
|
|
104
|
-
returnValue += ' و'
|
|
105
|
-
}
|
|
106
|
-
returnValue += this.tensWords[tensIndex]
|
|
132
|
+
groups.unshift(groupText)
|
|
107
133
|
}
|
|
108
134
|
}
|
|
109
135
|
|
|
110
|
-
|
|
136
|
+
group++
|
|
111
137
|
}
|
|
112
138
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return this.zeroWord
|
|
117
|
-
}
|
|
118
|
-
let temp = integerPart
|
|
119
|
-
let group = 0
|
|
120
|
-
let result = ''
|
|
121
|
-
|
|
122
|
-
// Process each group of 3 digits (right to left)
|
|
123
|
-
while (temp > 0n) {
|
|
124
|
-
const numberToProcess = Number(temp % 1000n)
|
|
125
|
-
temp = temp / 1000n
|
|
126
|
-
|
|
127
|
-
if (numberToProcess > 0) {
|
|
128
|
-
const groupDescription = this.segmentToWords(numberToProcess, group, integerPart)
|
|
129
|
-
|
|
130
|
-
if (groupDescription) {
|
|
131
|
-
// Add group name for thousands, millions, etc.
|
|
132
|
-
if (group > 0) {
|
|
133
|
-
if (result) {
|
|
134
|
-
result = ' و' + result
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (numberToProcess > 2) {
|
|
138
|
-
const remainder = numberToProcess % 100
|
|
139
|
-
if (remainder === 1) {
|
|
140
|
-
result = this.scaleWords[group] + ' ' + result
|
|
141
|
-
} else if (numberToProcess >= 3 && numberToProcess <= 10) {
|
|
142
|
-
result = this.scalePluralWords[group] + ' ' + result
|
|
143
|
-
} else {
|
|
144
|
-
result = (result ? this.scaleAppendedWords[group] : this.scaleWords[group]) + ' ' + result
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
139
|
+
// Join groups with و (and) - space before و, attaches to next word
|
|
140
|
+
// Use simple join since segmentToWords returns clean strings
|
|
141
|
+
if (groups.length === 1) return groups[0]
|
|
148
142
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
143
|
+
// Build result: "group1 وgroup2 وgroup3"
|
|
144
|
+
let result = groups[0]
|
|
145
|
+
for (let i = 1; i < groups.length; i++) {
|
|
146
|
+
result += ' ' + AND + groups[i]
|
|
147
|
+
}
|
|
148
|
+
return result
|
|
149
|
+
}
|
|
153
150
|
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
function decimalPartToWords (decimalPart, options) {
|
|
152
|
+
const parts = []
|
|
153
|
+
let i = 0
|
|
154
|
+
|
|
155
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
156
|
+
parts.push(ZERO)
|
|
157
|
+
i++
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const remainder = decimalPart.slice(i)
|
|
161
|
+
if (remainder) {
|
|
162
|
+
parts.push(integerToWords(BigInt(remainder), options))
|
|
163
|
+
}
|
|
156
164
|
|
|
157
|
-
|
|
165
|
+
return parts.join(' ')
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Converts a numeric value to Arabic words.
|
|
170
|
+
*
|
|
171
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
172
|
+
* @param {Object} [options] - Optional configuration
|
|
173
|
+
* @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
|
|
174
|
+
* @param {string} [options.negativeWord] - Custom word for negative numbers
|
|
175
|
+
* @returns {string} The number in Arabic words
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* toWords(1) // 'واحد'
|
|
179
|
+
* toWords(1, {gender: 'feminine'}) // 'واحدة'
|
|
180
|
+
*/
|
|
181
|
+
function toWords (value, options) {
|
|
182
|
+
options = validateOptions(options)
|
|
183
|
+
const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
|
|
184
|
+
|
|
185
|
+
const parts = []
|
|
186
|
+
|
|
187
|
+
if (isNegative) {
|
|
188
|
+
parts.push(options.negativeWord || NEGATIVE)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
parts.push(integerToWords(integerPart, options))
|
|
192
|
+
|
|
193
|
+
if (decimalPart) {
|
|
194
|
+
parts.push(DECIMAL_SEP)
|
|
195
|
+
parts.push(decimalPartToWords(decimalPart, options))
|
|
158
196
|
}
|
|
197
|
+
|
|
198
|
+
return parts.join(' ')
|
|
159
199
|
}
|
|
200
|
+
|
|
201
|
+
// ============================================================================
|
|
202
|
+
// Exports
|
|
203
|
+
// ============================================================================
|
|
204
|
+
|
|
205
|
+
export { toWords }
|
package/lib/languages/az.d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Azerbaijani
|
|
2
|
+
* Converts a numeric value to Azerbaijani words.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - Turkic language number patterns
|
|
7
|
-
* - Large numbers up to quintillion
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @returns {string} The number in Azerbaijani words
|
|
8
6
|
*/
|
|
9
|
-
export
|
|
10
|
-
scaleWords: (string | bigint)[][];
|
|
11
|
-
}
|
|
12
|
-
import { TurkicLanguage } from '../classes/turkic-language.js';
|
|
7
|
+
export function toWords(value: number | string | bigint): string;
|
package/lib/languages/az.js
CHANGED
|
@@ -1,42 +1,171 @@
|
|
|
1
|
-
import { TurkicLanguage } from '../classes/turkic-language.js'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* Azerbaijani language converter
|
|
2
|
+
* Azerbaijani language converter - Functional Implementation
|
|
3
|
+
*
|
|
4
|
+
* Self-contained module with its own input validation, ready for subpath exports.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Key features:
|
|
7
|
+
* - Turkic language patterns
|
|
7
8
|
* - Implicit "bir" (one) omission before hundreds and thousands
|
|
8
|
-
* -
|
|
9
|
-
* - Large numbers up to quintillion
|
|
9
|
+
* - Short scale naming
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
11
|
+
|
|
12
|
+
import { parseNumericValue } from '../utils/parse-numeric.js'
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Vocabulary
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
const ONES = ['', 'bir', 'iki', 'üç', 'dörd', 'beş', 'altı', 'yeddi', 'səkkiz', 'doqquz']
|
|
19
|
+
const TEENS = ['on', 'on bir', 'on iki', 'on üç', 'on dörd', 'on beş', 'on altı', 'on yeddi', 'on səkkiz', 'on doqquz']
|
|
20
|
+
const TENS = ['', '', 'iyirmi', 'otuz', 'qırx', 'əlli', 'altmış', 'yetmiş', 'səksən', 'doxsan']
|
|
21
|
+
|
|
22
|
+
const HUNDRED = 'yüz'
|
|
23
|
+
const THOUSAND = 'min'
|
|
24
|
+
|
|
25
|
+
const ZERO = 'sıfır'
|
|
26
|
+
const NEGATIVE = 'mənfi'
|
|
27
|
+
const DECIMAL_SEP = 'nöqtə'
|
|
28
|
+
|
|
29
|
+
// Short scale
|
|
30
|
+
const SCALE_WORDS = ['', THOUSAND, 'milyon', 'milyar', 'trilyon', 'katrilyon', 'kentilyon']
|
|
31
|
+
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Precomputed Lookup Table
|
|
34
|
+
// ============================================================================
|
|
35
|
+
|
|
36
|
+
function buildSegment (n) {
|
|
37
|
+
if (n === 0) return ''
|
|
38
|
+
|
|
39
|
+
const ones = n % 10
|
|
40
|
+
const tensDigit = Math.floor(n / 10) % 10
|
|
41
|
+
const hundredsDigit = Math.floor(n / 100)
|
|
42
|
+
|
|
43
|
+
const parts = []
|
|
44
|
+
|
|
45
|
+
if (hundredsDigit > 0) {
|
|
46
|
+
if (hundredsDigit === 1) {
|
|
47
|
+
parts.push(HUNDRED)
|
|
48
|
+
} else {
|
|
49
|
+
parts.push(ONES[hundredsDigit] + ' ' + HUNDRED)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (tensDigit === 1) {
|
|
54
|
+
parts.push(TEENS[ones])
|
|
55
|
+
} else {
|
|
56
|
+
if (tensDigit > 1) {
|
|
57
|
+
parts.push(TENS[tensDigit])
|
|
58
|
+
}
|
|
59
|
+
if (ones > 0) {
|
|
60
|
+
parts.push(ONES[ones])
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return parts.join(' ')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Conversion Functions
|
|
69
|
+
// ============================================================================
|
|
70
|
+
|
|
71
|
+
function integerToWords (n) {
|
|
72
|
+
if (n === 0n) return ZERO
|
|
73
|
+
|
|
74
|
+
if (n < 1000n) {
|
|
75
|
+
return buildSegment(Number(n))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return buildLargeNumberWords(n)
|
|
42
79
|
}
|
|
80
|
+
|
|
81
|
+
function buildLargeNumberWords (n) {
|
|
82
|
+
const numStr = n.toString()
|
|
83
|
+
const len = numStr.length
|
|
84
|
+
|
|
85
|
+
const segments = []
|
|
86
|
+
const segmentSize = 3
|
|
87
|
+
|
|
88
|
+
const remainderLen = len % segmentSize
|
|
89
|
+
let pos = 0
|
|
90
|
+
if (remainderLen > 0) {
|
|
91
|
+
segments.push(Number(numStr.slice(0, remainderLen)))
|
|
92
|
+
pos = remainderLen
|
|
93
|
+
}
|
|
94
|
+
while (pos < len) {
|
|
95
|
+
segments.push(Number(numStr.slice(pos, pos + segmentSize)))
|
|
96
|
+
pos += segmentSize
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const parts = []
|
|
100
|
+
let scaleIndex = segments.length - 1
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < segments.length; i++) {
|
|
103
|
+
const segment = segments[i]
|
|
104
|
+
|
|
105
|
+
if (segment !== 0) {
|
|
106
|
+
const scaleWord = SCALE_WORDS[scaleIndex] || ''
|
|
107
|
+
|
|
108
|
+
if (scaleIndex === 0) {
|
|
109
|
+
parts.push(buildSegment(segment))
|
|
110
|
+
} else if (scaleIndex === 1 && segment === 1) {
|
|
111
|
+
// Omit "bir" before thousand
|
|
112
|
+
parts.push(scaleWord)
|
|
113
|
+
} else {
|
|
114
|
+
parts.push(buildSegment(segment) + ' ' + scaleWord)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
scaleIndex--
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return parts.join(' ')
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function decimalPartToWords (decimalPart) {
|
|
125
|
+
let result = ''
|
|
126
|
+
let i = 0
|
|
127
|
+
|
|
128
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
129
|
+
if (result) result += ' '
|
|
130
|
+
result += ZERO
|
|
131
|
+
i++
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const remainder = decimalPart.slice(i)
|
|
135
|
+
if (remainder) {
|
|
136
|
+
if (result) result += ' '
|
|
137
|
+
result += integerToWords(BigInt(remainder))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return result
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Converts a numeric value to Azerbaijani words.
|
|
145
|
+
*
|
|
146
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
147
|
+
* @returns {string} The number in Azerbaijani words
|
|
148
|
+
*/
|
|
149
|
+
function toWords (value) {
|
|
150
|
+
const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
|
|
151
|
+
|
|
152
|
+
let result = ''
|
|
153
|
+
|
|
154
|
+
if (isNegative) {
|
|
155
|
+
result = NEGATIVE + ' '
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
result += integerToWords(integerPart)
|
|
159
|
+
|
|
160
|
+
if (decimalPart) {
|
|
161
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return result
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ============================================================================
|
|
168
|
+
// Exports
|
|
169
|
+
// ============================================================================
|
|
170
|
+
|
|
171
|
+
export { toWords }
|
package/lib/languages/bn.d.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Converts a numeric value to Bengali words.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - Bangla script (Bengali)
|
|
7
|
-
* - Complete word forms for 0-99
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @returns {string} The number in Bengali words
|
|
8
6
|
*/
|
|
9
|
-
export
|
|
10
|
-
}
|
|
11
|
-
import { SouthAsianLanguage } from '../classes/south-asian-language.js';
|
|
7
|
+
export function toWords(value: number | string | bigint): string;
|