n2words 1.23.1 → 2.0.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/LICENSE +1 -1
- package/README.md +317 -59
- package/dist/ArabicConverter.js +3 -0
- package/dist/ArabicConverter.js.map +1 -0
- package/dist/AzerbaijaniConverter.js +3 -0
- package/dist/AzerbaijaniConverter.js.map +1 -0
- package/dist/BanglaConverter.js +3 -0
- package/dist/BanglaConverter.js.map +1 -0
- package/dist/BiblicalHebrewConverter.js +3 -0
- package/dist/BiblicalHebrewConverter.js.map +1 -0
- package/dist/CroatianConverter.js +3 -0
- package/dist/CroatianConverter.js.map +1 -0
- package/dist/CzechConverter.js +3 -0
- package/dist/CzechConverter.js.map +1 -0
- package/dist/DanishConverter.js +3 -0
- package/dist/DanishConverter.js.map +1 -0
- package/dist/DutchConverter.js +3 -0
- package/dist/DutchConverter.js.map +1 -0
- package/dist/EnglishConverter.js +3 -0
- package/dist/EnglishConverter.js.map +1 -0
- package/dist/FilipinoConverter.js +3 -0
- package/dist/FilipinoConverter.js.map +1 -0
- package/dist/FrenchBelgiumConverter.js +3 -0
- package/dist/FrenchBelgiumConverter.js.map +1 -0
- package/dist/FrenchConverter.js +3 -0
- package/dist/FrenchConverter.js.map +1 -0
- package/dist/GermanConverter.js +3 -0
- package/dist/GermanConverter.js.map +1 -0
- package/dist/GreekConverter.js +3 -0
- package/dist/GreekConverter.js.map +1 -0
- package/dist/GujaratiConverter.js +3 -0
- package/dist/GujaratiConverter.js.map +1 -0
- package/dist/HebrewConverter.js +3 -0
- package/dist/HebrewConverter.js.map +1 -0
- package/dist/HindiConverter.js +3 -0
- package/dist/HindiConverter.js.map +1 -0
- package/dist/HungarianConverter.js +3 -0
- package/dist/HungarianConverter.js.map +1 -0
- package/dist/IndonesianConverter.js +3 -0
- package/dist/IndonesianConverter.js.map +1 -0
- package/dist/ItalianConverter.js +3 -0
- package/dist/ItalianConverter.js.map +1 -0
- package/dist/JapaneseConverter.js +3 -0
- package/dist/JapaneseConverter.js.map +1 -0
- package/dist/KannadaConverter.js +3 -0
- package/dist/KannadaConverter.js.map +1 -0
- package/dist/KoreanConverter.js +3 -0
- package/dist/KoreanConverter.js.map +1 -0
- package/dist/LatvianConverter.js +3 -0
- package/dist/LatvianConverter.js.map +1 -0
- package/dist/LithuanianConverter.js +3 -0
- package/dist/LithuanianConverter.js.map +1 -0
- package/dist/MalayConverter.js +3 -0
- package/dist/MalayConverter.js.map +1 -0
- package/dist/MarathiConverter.js +3 -0
- package/dist/MarathiConverter.js.map +1 -0
- package/dist/NorwegianBokmalConverter.js +3 -0
- package/dist/NorwegianBokmalConverter.js.map +1 -0
- package/dist/PersianConverter.js +3 -0
- package/dist/PersianConverter.js.map +1 -0
- package/dist/PolishConverter.js +3 -0
- package/dist/PolishConverter.js.map +1 -0
- package/dist/PortugueseConverter.js +3 -0
- package/dist/PortugueseConverter.js.map +1 -0
- package/dist/PunjabiConverter.js +3 -0
- package/dist/PunjabiConverter.js.map +1 -0
- package/dist/RomanianConverter.js +3 -0
- package/dist/RomanianConverter.js.map +1 -0
- package/dist/RussianConverter.js +3 -0
- package/dist/RussianConverter.js.map +1 -0
- package/dist/SerbianCyrillicConverter.js +3 -0
- package/dist/SerbianCyrillicConverter.js.map +1 -0
- package/dist/SerbianLatinConverter.js +3 -0
- package/dist/SerbianLatinConverter.js.map +1 -0
- package/dist/SimplifiedChineseConverter.js +3 -0
- package/dist/SimplifiedChineseConverter.js.map +1 -0
- package/dist/SpanishConverter.js +3 -0
- package/dist/SpanishConverter.js.map +1 -0
- package/dist/SwahiliConverter.js +3 -0
- package/dist/SwahiliConverter.js.map +1 -0
- package/dist/SwedishConverter.js +3 -0
- package/dist/SwedishConverter.js.map +1 -0
- package/dist/TamilConverter.js +3 -0
- package/dist/TamilConverter.js.map +1 -0
- package/dist/TeluguConverter.js +3 -0
- package/dist/TeluguConverter.js.map +1 -0
- package/dist/ThaiConverter.js +3 -0
- package/dist/ThaiConverter.js.map +1 -0
- package/dist/TraditionalChineseConverter.js +3 -0
- package/dist/TraditionalChineseConverter.js.map +1 -0
- package/dist/TurkishConverter.js +3 -0
- package/dist/TurkishConverter.js.map +1 -0
- package/dist/UkrainianConverter.js +3 -0
- package/dist/UkrainianConverter.js.map +1 -0
- package/dist/UrduConverter.js +3 -0
- package/dist/UrduConverter.js.map +1 -0
- package/dist/VietnameseConverter.js +3 -0
- package/dist/VietnameseConverter.js.map +1 -0
- package/dist/n2words.js +3 -2
- package/dist/n2words.js.map +1 -1
- package/lib/classes/abstract-language.d.ts +158 -34
- package/lib/classes/abstract-language.js +223 -115
- package/lib/classes/greedy-scale-language.d.ts +109 -0
- package/lib/classes/greedy-scale-language.js +201 -0
- package/lib/classes/slavic-language.d.ts +148 -0
- package/lib/classes/slavic-language.js +281 -0
- package/lib/classes/south-asian-language.d.ts +70 -0
- package/lib/classes/south-asian-language.js +154 -0
- package/lib/classes/turkic-language.d.ts +26 -0
- package/lib/classes/turkic-language.js +59 -0
- package/lib/languages/ar.d.ts +30 -0
- package/lib/languages/ar.js +159 -0
- package/lib/languages/az.d.ts +12 -0
- package/lib/languages/az.js +42 -0
- package/lib/languages/bn.d.ts +11 -0
- package/lib/languages/bn.js +131 -0
- package/lib/languages/cs.d.ts +88 -0
- package/lib/languages/cs.js +143 -0
- package/lib/languages/da.d.ts +15 -0
- package/lib/languages/da.js +120 -0
- package/lib/languages/de.d.ts +14 -0
- package/lib/languages/de.js +101 -0
- package/lib/languages/el.d.ts +14 -0
- package/lib/languages/el.js +90 -0
- package/lib/languages/en.d.ts +16 -0
- package/lib/languages/en.js +86 -0
- package/lib/languages/es.d.ts +15 -0
- package/lib/languages/es.js +121 -0
- package/lib/languages/fa.d.ts +47 -0
- package/lib/languages/fa.js +144 -0
- package/lib/languages/fil.d.ts +16 -0
- package/lib/languages/fil.js +121 -0
- package/lib/languages/fr-BE.d.ts +11 -0
- package/lib/languages/fr-BE.js +25 -0
- package/lib/languages/fr.d.ts +15 -0
- package/lib/languages/fr.js +106 -0
- package/lib/languages/gu.d.ts +11 -0
- package/lib/languages/gu.js +132 -0
- package/lib/languages/hbo.d.ts +113 -0
- package/lib/languages/hbo.js +251 -0
- package/lib/languages/he.d.ts +80 -0
- package/lib/languages/he.js +206 -0
- package/lib/languages/hi.d.ts +11 -0
- package/lib/languages/hi.js +131 -0
- package/lib/languages/hr.d.ts +80 -0
- package/lib/languages/hr.js +113 -0
- package/lib/languages/hu.d.ts +22 -0
- package/lib/languages/hu.js +137 -0
- package/lib/languages/id.d.ts +37 -0
- package/lib/languages/id.js +159 -0
- package/lib/languages/it.d.ts +37 -0
- package/lib/languages/it.js +132 -0
- package/lib/languages/ja.d.ts +17 -0
- package/lib/languages/ja.js +137 -0
- package/lib/languages/kn.d.ts +11 -0
- package/lib/languages/kn.js +42 -0
- package/lib/languages/ko.d.ts +14 -0
- package/lib/languages/ko.js +55 -0
- package/lib/{i18n/pl.d.ts → languages/lt.d.ts} +18 -15
- package/lib/languages/lt.js +136 -0
- package/lib/{i18n/lt.d.ts → languages/lv.d.ts} +16 -14
- package/lib/languages/lv.js +130 -0
- package/lib/languages/mr.d.ts +11 -0
- package/lib/languages/mr.js +132 -0
- package/lib/languages/ms.d.ts +31 -0
- package/lib/languages/ms.js +150 -0
- package/lib/languages/nb.d.ts +12 -0
- package/lib/languages/nb.js +100 -0
- package/lib/languages/nl.d.ts +16 -0
- package/lib/languages/nl.js +155 -0
- package/lib/languages/pa.d.ts +11 -0
- package/lib/languages/pa.js +131 -0
- package/lib/{i18n/uk.d.ts → languages/pl.d.ts} +16 -14
- package/lib/languages/pl.js +110 -0
- package/lib/languages/pt.d.ts +29 -0
- package/lib/languages/pt.js +112 -0
- package/lib/languages/ro.d.ts +158 -0
- package/lib/languages/ro.js +273 -0
- package/lib/languages/ru.d.ts +85 -0
- package/lib/languages/ru.js +96 -0
- package/lib/languages/sr-Cyrl.d.ts +80 -0
- package/lib/languages/sr-Cyrl.js +113 -0
- package/lib/{i18n/cz.d.ts → languages/sr-Latn.d.ts} +26 -14
- package/lib/languages/sr-Latn.js +113 -0
- package/lib/languages/sv.d.ts +14 -0
- package/lib/languages/sv.js +90 -0
- package/lib/languages/sw.d.ts +39 -0
- package/lib/languages/sw.js +126 -0
- package/lib/languages/ta.d.ts +20 -0
- package/lib/languages/ta.js +226 -0
- package/lib/languages/te.d.ts +22 -0
- package/lib/languages/te.js +219 -0
- package/lib/languages/th.d.ts +17 -0
- package/lib/languages/th.js +117 -0
- package/lib/languages/tr.d.ts +12 -0
- package/lib/languages/tr.js +56 -0
- package/lib/languages/uk.d.ts +85 -0
- package/lib/{i18n → languages}/uk.js +33 -32
- package/lib/languages/ur.d.ts +11 -0
- package/lib/languages/ur.js +131 -0
- package/lib/{i18n → languages}/vi.d.ts +15 -13
- package/lib/languages/vi.js +147 -0
- package/lib/languages/zh-Hans.d.ts +21 -0
- package/lib/languages/zh-Hans.js +111 -0
- package/lib/languages/zh-Hant.d.ts +21 -0
- package/lib/languages/zh-Hant.js +111 -0
- package/lib/n2words.d.ts +207 -7
- package/lib/n2words.js +535 -81
- package/package.json +126 -79
- package/dist/ar.js +0 -2
- package/dist/ar.js.map +0 -1
- package/dist/az.js +0 -2
- package/dist/az.js.map +0 -1
- package/dist/cz.js +0 -2
- package/dist/cz.js.map +0 -1
- package/dist/de.js +0 -2
- package/dist/de.js.map +0 -1
- package/dist/dk.js +0 -2
- package/dist/dk.js.map +0 -1
- package/dist/en.js +0 -2
- package/dist/en.js.map +0 -1
- package/dist/es.js +0 -2
- package/dist/es.js.map +0 -1
- package/dist/fa.js +0 -2
- package/dist/fa.js.map +0 -1
- package/dist/fr-BE.js +0 -2
- package/dist/fr-BE.js.map +0 -1
- package/dist/fr.js +0 -2
- package/dist/fr.js.map +0 -1
- package/dist/he.js +0 -2
- package/dist/he.js.map +0 -1
- package/dist/hr.js +0 -2
- package/dist/hr.js.map +0 -1
- package/dist/hu.js +0 -2
- package/dist/hu.js.map +0 -1
- package/dist/id.js +0 -2
- package/dist/id.js.map +0 -1
- package/dist/it.js +0 -2
- package/dist/it.js.map +0 -1
- package/dist/ko.js +0 -2
- package/dist/ko.js.map +0 -1
- package/dist/lt.js +0 -2
- package/dist/lt.js.map +0 -1
- package/dist/lv.js +0 -2
- package/dist/lv.js.map +0 -1
- package/dist/n2words.d.ts +0 -2
- package/dist/nl.js +0 -2
- package/dist/nl.js.map +0 -1
- package/dist/no.js +0 -2
- package/dist/no.js.map +0 -1
- package/dist/pl.js +0 -2
- package/dist/pl.js.map +0 -1
- package/dist/pt.js +0 -2
- package/dist/pt.js.map +0 -1
- package/dist/ro.js +0 -2
- package/dist/ro.js.map +0 -1
- package/dist/ru.js +0 -2
- package/dist/ru.js.map +0 -1
- package/dist/sr.js +0 -2
- package/dist/sr.js.map +0 -1
- package/dist/tr.js +0 -2
- package/dist/tr.js.map +0 -1
- package/dist/uk.js +0 -2
- package/dist/uk.js.map +0 -1
- package/dist/vi.js +0 -2
- package/dist/vi.js.map +0 -1
- package/dist/zh.js +0 -2
- package/dist/zh.js.map +0 -1
- package/lib/classes/base-language.d.ts +0 -58
- package/lib/classes/base-language.js +0 -172
- package/lib/i18n/ar.d.ts +0 -41
- package/lib/i18n/ar.js +0 -209
- package/lib/i18n/az.d.ts +0 -15
- package/lib/i18n/az.js +0 -66
- package/lib/i18n/cz.js +0 -135
- package/lib/i18n/de.d.ts +0 -17
- package/lib/i18n/de.js +0 -103
- package/lib/i18n/dk.d.ts +0 -14
- package/lib/i18n/dk.js +0 -110
- package/lib/i18n/en.d.ts +0 -22
- package/lib/i18n/en.js +0 -86
- package/lib/i18n/es.d.ts +0 -16
- package/lib/i18n/es.js +0 -110
- package/lib/i18n/fa.d.ts +0 -54
- package/lib/i18n/fa.js +0 -106
- package/lib/i18n/fr-BE.d.ts +0 -11
- package/lib/i18n/fr-BE.js +0 -20
- package/lib/i18n/fr.d.ts +0 -15
- package/lib/i18n/fr.js +0 -99
- package/lib/i18n/he.d.ts +0 -61
- package/lib/i18n/he.js +0 -132
- package/lib/i18n/hr.d.ts +0 -68
- package/lib/i18n/hr.js +0 -129
- package/lib/i18n/hu.d.ts +0 -17
- package/lib/i18n/hu.js +0 -135
- package/lib/i18n/id.d.ts +0 -43
- package/lib/i18n/id.js +0 -156
- package/lib/i18n/it.d.ts +0 -29
- package/lib/i18n/it.js +0 -137
- package/lib/i18n/ko.d.ts +0 -15
- package/lib/i18n/ko.js +0 -56
- package/lib/i18n/lt.js +0 -138
- package/lib/i18n/lv.d.ts +0 -57
- package/lib/i18n/lv.js +0 -120
- package/lib/i18n/nl.d.ts +0 -20
- package/lib/i18n/nl.js +0 -125
- package/lib/i18n/no.d.ts +0 -15
- package/lib/i18n/no.js +0 -77
- package/lib/i18n/pl.js +0 -126
- package/lib/i18n/pt.d.ts +0 -26
- package/lib/i18n/pt.js +0 -118
- package/lib/i18n/ro.d.ts +0 -109
- package/lib/i18n/ro.js +0 -360
- package/lib/i18n/ru.d.ts +0 -30
- package/lib/i18n/ru.js +0 -198
- package/lib/i18n/sr.d.ts +0 -56
- package/lib/i18n/sr.js +0 -127
- package/lib/i18n/tr.d.ts +0 -15
- package/lib/i18n/tr.js +0 -64
- package/lib/i18n/vi.js +0 -151
- package/lib/i18n/zh.d.ts +0 -18
- package/lib/i18n/zh.js +0 -78
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { AbstractLanguage } from '../classes/abstract-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Arabic language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Gender agreement (masculine/feminine forms)
|
|
8
|
+
* - Complex pluralization (singular/dual/plural)
|
|
9
|
+
* - Traditional Arabic number naming conventions
|
|
10
|
+
* - Right-to-left text orientation
|
|
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
|
+
|
|
41
|
+
constructor (options = {}) {
|
|
42
|
+
super()
|
|
43
|
+
|
|
44
|
+
this.setOptions({
|
|
45
|
+
gender: 'masculine'
|
|
46
|
+
}, options)
|
|
47
|
+
|
|
48
|
+
// Allow custom negativeWord via options
|
|
49
|
+
if (options.negativeWord !== undefined) {
|
|
50
|
+
this.negativeWord = options.negativeWord
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Selects masculine or feminine number forms based on options. */
|
|
55
|
+
get selectedOnes () {
|
|
56
|
+
return this.ones[this.options.gender === 'feminine' ? 'feminine' : 'masculine']
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Converts a 3-digit segment (0-999) to Arabic words with gender/plural rules. */
|
|
60
|
+
segmentToWords (groupNumber, groupLevel, fullNumber) {
|
|
61
|
+
const tens = groupNumber % 100
|
|
62
|
+
const hundredsRaw = groupNumber / 100
|
|
63
|
+
const hundreds = Math.trunc(hundredsRaw)
|
|
64
|
+
let returnValue = ''
|
|
65
|
+
|
|
66
|
+
// Process hundreds
|
|
67
|
+
if (hundreds > 0) {
|
|
68
|
+
if (tens === 0 && hundreds === 2) {
|
|
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
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Process tens and ones
|
|
82
|
+
if (tens > 0) {
|
|
83
|
+
if (tens < 20) { // 1 -> 19
|
|
84
|
+
if (tens === 2 && hundreds === 0 && groupLevel > 0) {
|
|
85
|
+
// Cache expensive log10 calculation
|
|
86
|
+
const numValue = Number(fullNumber)
|
|
87
|
+
const pow = Math.trunc(Math.log10(numValue))
|
|
88
|
+
if (pow % 3 === 0 && fullNumber === BigInt(2 * Math.pow(10, pow))) {
|
|
89
|
+
returnValue = groupNumber === 2 ? this.dualWords[groupLevel] : this.dualAppendedWords[groupLevel]
|
|
90
|
+
} else {
|
|
91
|
+
returnValue = this.dualWords[groupLevel]
|
|
92
|
+
}
|
|
93
|
+
} else if (tens === 1 && groupLevel > 0) {
|
|
94
|
+
returnValue += this.scaleWords[groupLevel]
|
|
95
|
+
} else {
|
|
96
|
+
returnValue += this.selectedOnes[tens - 1]
|
|
97
|
+
}
|
|
98
|
+
} else { // 20 -> 99
|
|
99
|
+
const ones = tens % 10
|
|
100
|
+
const tensIndex = Math.trunc(tens / 10) - 2
|
|
101
|
+
|
|
102
|
+
if (ones > 0) {
|
|
103
|
+
returnValue += this.selectedOnes[ones - 1]
|
|
104
|
+
returnValue += ' و'
|
|
105
|
+
}
|
|
106
|
+
returnValue += this.tensWords[tensIndex]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return returnValue
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Converts integer part to Arabic words by processing 3-digit groups. */
|
|
114
|
+
integerToWords (integerPart) {
|
|
115
|
+
if (integerPart === 0n) {
|
|
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
|
+
}
|
|
148
|
+
|
|
149
|
+
// Add group description (prepend for RTL)
|
|
150
|
+
result = groupDescription + ' ' + result
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
group++
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return result.replace(/\s+/g, ' ').trim()
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azerbaijani language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Implicit "bir" (one) omission before hundreds and thousands
|
|
6
|
+
* - Turkic language number patterns
|
|
7
|
+
* - Large numbers up to quintillion
|
|
8
|
+
*/
|
|
9
|
+
export class Azerbaijani extends TurkicLanguage {
|
|
10
|
+
scaleWords: (string | bigint)[][];
|
|
11
|
+
}
|
|
12
|
+
import { TurkicLanguage } from '../classes/turkic-language.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { TurkicLanguage } from '../classes/turkic-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Azerbaijani language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Implicit "bir" (one) omission before hundreds and thousands
|
|
8
|
+
* - Turkic language number patterns
|
|
9
|
+
* - Large numbers up to quintillion
|
|
10
|
+
*/
|
|
11
|
+
export class Azerbaijani extends TurkicLanguage {
|
|
12
|
+
negativeWord = 'mənfi'
|
|
13
|
+
decimalSeparatorWord = 'nöqtə'
|
|
14
|
+
zeroWord = 'sıfır'
|
|
15
|
+
|
|
16
|
+
scaleWords = [[1_000_000_000_000_000_000n, 'kentilyon'],
|
|
17
|
+
[1_000_000_000_000_000n, 'katrilyon'],
|
|
18
|
+
[1_000_000_000_000n, 'trilyon'],
|
|
19
|
+
[1_000_000_000n, 'milyar'],
|
|
20
|
+
[1_000_000n, 'milyon'],
|
|
21
|
+
[1000n, 'min'],
|
|
22
|
+
[100n, 'yüz'],
|
|
23
|
+
[90n, 'doxsan'],
|
|
24
|
+
[80n, 'səksən'],
|
|
25
|
+
[70n, 'yetmiş'],
|
|
26
|
+
[60n, 'altmış'],
|
|
27
|
+
[50n, 'əlli'],
|
|
28
|
+
[40n, 'qırx'],
|
|
29
|
+
[30n, 'otuz'],
|
|
30
|
+
[20n, 'iyirmi'],
|
|
31
|
+
[10n, 'on'],
|
|
32
|
+
[9n, 'doqquz'],
|
|
33
|
+
[8n, 'səkkiz'],
|
|
34
|
+
[7n, 'yeddi'],
|
|
35
|
+
[6n, 'altı'],
|
|
36
|
+
[5n, 'beş'],
|
|
37
|
+
[4n, 'dörd'],
|
|
38
|
+
[3n, 'üç'],
|
|
39
|
+
[2n, 'iki'],
|
|
40
|
+
[1n, 'bir'],
|
|
41
|
+
[0n, 'sıfır']]
|
|
42
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bangla language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Indian numbering system (হাজার, লাখ, কোটি)
|
|
6
|
+
* - Bangla script (Bengali)
|
|
7
|
+
* - Complete word forms for 0-99
|
|
8
|
+
*/
|
|
9
|
+
export class Bangla extends SouthAsianLanguage {
|
|
10
|
+
}
|
|
11
|
+
import { SouthAsianLanguage } from '../classes/south-asian-language.js';
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { SouthAsianLanguage } from '../classes/south-asian-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Bangla language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Indian numbering system (হাজার, লাখ, কোটি)
|
|
8
|
+
* - Bangla script (Bengali)
|
|
9
|
+
* - Complete word forms for 0-99
|
|
10
|
+
*/
|
|
11
|
+
export class Bangla extends SouthAsianLanguage {
|
|
12
|
+
negativeWord = 'মাইনাস'
|
|
13
|
+
decimalSeparatorWord = 'দশমিক'
|
|
14
|
+
zeroWord = 'শূন্য'
|
|
15
|
+
hundredWord = 'শত'
|
|
16
|
+
|
|
17
|
+
belowHundredWords = [
|
|
18
|
+
'শূন্য',
|
|
19
|
+
'এক',
|
|
20
|
+
'দুই',
|
|
21
|
+
'তিন',
|
|
22
|
+
'চার',
|
|
23
|
+
'পাঁচ',
|
|
24
|
+
'ছয়',
|
|
25
|
+
'সাত',
|
|
26
|
+
'আট',
|
|
27
|
+
'নয়',
|
|
28
|
+
'দশ',
|
|
29
|
+
'এগারো',
|
|
30
|
+
'বারো',
|
|
31
|
+
'তেরো',
|
|
32
|
+
'চৌদ্দ',
|
|
33
|
+
'পনেরো',
|
|
34
|
+
'ষোল',
|
|
35
|
+
'সতেরো',
|
|
36
|
+
'আঠারো',
|
|
37
|
+
'উনিশ',
|
|
38
|
+
'বিশ',
|
|
39
|
+
'একুশ',
|
|
40
|
+
'বাইশ',
|
|
41
|
+
'তেইশ',
|
|
42
|
+
'চব্বিশ',
|
|
43
|
+
'পঁচিশ',
|
|
44
|
+
'ছাব্বিশ',
|
|
45
|
+
'সাতাশ',
|
|
46
|
+
'আঠাশ',
|
|
47
|
+
'উনত্রিশ',
|
|
48
|
+
'ত্রিশ',
|
|
49
|
+
'একত্রিশ',
|
|
50
|
+
'বত্রিশ',
|
|
51
|
+
'তেত্রিশ',
|
|
52
|
+
'চৌত্রিশ',
|
|
53
|
+
'পঁয়ত্রিশ',
|
|
54
|
+
'ছত্রিশ',
|
|
55
|
+
'সাঁইত্রিশ',
|
|
56
|
+
'আটত্রিশ',
|
|
57
|
+
'উনচল্লিশ',
|
|
58
|
+
'চল্লিশ',
|
|
59
|
+
'একচল্লিশ',
|
|
60
|
+
'বেয়াল্লিশ',
|
|
61
|
+
'তেতাল্লিশ',
|
|
62
|
+
'চুয়াল্লিশ',
|
|
63
|
+
'পঁয়তাল্লিশ',
|
|
64
|
+
'ছেচল্লিশ',
|
|
65
|
+
'সাতচল্লিশ',
|
|
66
|
+
'আটচল্লিশ',
|
|
67
|
+
'উনপঞ্চাশ',
|
|
68
|
+
'পঞ্চাশ',
|
|
69
|
+
'একান্ন',
|
|
70
|
+
'বাহান্ন',
|
|
71
|
+
'তিপ্পান্ন',
|
|
72
|
+
'চুয়ান্ন',
|
|
73
|
+
'পঞ্চান্ন',
|
|
74
|
+
'ছাপ্পান্ন',
|
|
75
|
+
'সাতান্ন',
|
|
76
|
+
'আটান্ন',
|
|
77
|
+
'উনষাট',
|
|
78
|
+
'ষাট',
|
|
79
|
+
'একষট্টি',
|
|
80
|
+
'বাষট্টি',
|
|
81
|
+
'তেষট্টি',
|
|
82
|
+
'চৌষট্টি',
|
|
83
|
+
'পঁয়ষট্টি',
|
|
84
|
+
'ছেষট্টি',
|
|
85
|
+
'সাতষট্টি',
|
|
86
|
+
'আটষট্টি',
|
|
87
|
+
'ঊনসত্তর',
|
|
88
|
+
'সত্তর',
|
|
89
|
+
'একাত্তর',
|
|
90
|
+
'বাহাত্তর',
|
|
91
|
+
'তেহাত্তর',
|
|
92
|
+
'চুয়াত্তর',
|
|
93
|
+
'পঁচাত্তর',
|
|
94
|
+
'ছিয়াত্তর',
|
|
95
|
+
'সাতাত্তর',
|
|
96
|
+
'আটাত্তর',
|
|
97
|
+
'উনআশি',
|
|
98
|
+
'আশি',
|
|
99
|
+
'একাশি',
|
|
100
|
+
'বিরাশি',
|
|
101
|
+
'তিরাশি',
|
|
102
|
+
'চুরাশি',
|
|
103
|
+
'পঁচাশি',
|
|
104
|
+
'ছিয়াশি',
|
|
105
|
+
'সাতাশি',
|
|
106
|
+
'আটাশি',
|
|
107
|
+
'উননব্বই',
|
|
108
|
+
'নব্বই',
|
|
109
|
+
'একানব্বই',
|
|
110
|
+
'বিরানব্বই',
|
|
111
|
+
'তিরানব্বই',
|
|
112
|
+
'চুরানব্বই',
|
|
113
|
+
'পঁচানব্বই',
|
|
114
|
+
'ছিয়ানব্বই',
|
|
115
|
+
'সাতানব্বই',
|
|
116
|
+
'আটানব্বই',
|
|
117
|
+
'নিরানব্বই'
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
scaleWords = [
|
|
121
|
+
'',
|
|
122
|
+
'হাজার',
|
|
123
|
+
'লাখ',
|
|
124
|
+
'কোটি',
|
|
125
|
+
'আরব',
|
|
126
|
+
'খরব',
|
|
127
|
+
'নীল',
|
|
128
|
+
'পদ্ম',
|
|
129
|
+
'শঙ্খ'
|
|
130
|
+
]
|
|
131
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Czech language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Three-form pluralization (one/few/many)
|
|
6
|
+
* - Dynamic decimal separator (celá/celé/celých)
|
|
7
|
+
* - Gender agreement in number words
|
|
8
|
+
*/
|
|
9
|
+
export class Czech extends SlavicLanguage {
|
|
10
|
+
constructor(options?: {});
|
|
11
|
+
onesWords: {
|
|
12
|
+
1: string;
|
|
13
|
+
2: string;
|
|
14
|
+
3: string;
|
|
15
|
+
4: string;
|
|
16
|
+
5: string;
|
|
17
|
+
6: string;
|
|
18
|
+
7: string;
|
|
19
|
+
8: string;
|
|
20
|
+
9: string;
|
|
21
|
+
};
|
|
22
|
+
onesFeminineWords: {
|
|
23
|
+
1: string;
|
|
24
|
+
2: string;
|
|
25
|
+
3: string;
|
|
26
|
+
4: string;
|
|
27
|
+
5: string;
|
|
28
|
+
6: string;
|
|
29
|
+
7: string;
|
|
30
|
+
8: string;
|
|
31
|
+
9: string;
|
|
32
|
+
};
|
|
33
|
+
teensWords: {
|
|
34
|
+
0: string;
|
|
35
|
+
1: string;
|
|
36
|
+
2: string;
|
|
37
|
+
3: string;
|
|
38
|
+
4: string;
|
|
39
|
+
5: string;
|
|
40
|
+
6: string;
|
|
41
|
+
7: string;
|
|
42
|
+
8: string;
|
|
43
|
+
9: string;
|
|
44
|
+
};
|
|
45
|
+
twentiesWords: {
|
|
46
|
+
2: string;
|
|
47
|
+
3: string;
|
|
48
|
+
4: string;
|
|
49
|
+
5: string;
|
|
50
|
+
6: string;
|
|
51
|
+
7: string;
|
|
52
|
+
8: string;
|
|
53
|
+
9: string;
|
|
54
|
+
};
|
|
55
|
+
hundredsWords: {
|
|
56
|
+
1: string;
|
|
57
|
+
2: string;
|
|
58
|
+
3: string;
|
|
59
|
+
4: string;
|
|
60
|
+
5: string;
|
|
61
|
+
6: string;
|
|
62
|
+
7: string;
|
|
63
|
+
8: string;
|
|
64
|
+
9: string;
|
|
65
|
+
};
|
|
66
|
+
pluralForms: {
|
|
67
|
+
1: string[];
|
|
68
|
+
2: string[];
|
|
69
|
+
3: string[];
|
|
70
|
+
4: string[];
|
|
71
|
+
5: string[];
|
|
72
|
+
6: string[];
|
|
73
|
+
7: string[];
|
|
74
|
+
8: string[];
|
|
75
|
+
9: string[];
|
|
76
|
+
10: string[];
|
|
77
|
+
};
|
|
78
|
+
/** Returns decimal separator word based on integer part (celá/celé/celých). */
|
|
79
|
+
get decimalSeparatorWord(): "celá" | "celé" | "celých";
|
|
80
|
+
/**
|
|
81
|
+
* Override toWords to cache integer part before decimal separator is accessed.
|
|
82
|
+
*/
|
|
83
|
+
toWords(isNegative: any, integerPart: any, decimalPart: any): string;
|
|
84
|
+
/** Selects Czech plural form: 1 = singular, 2-4 = few, else = many. */
|
|
85
|
+
pluralize(n: any, forms: any): any;
|
|
86
|
+
#private;
|
|
87
|
+
}
|
|
88
|
+
import { SlavicLanguage } from '../classes/slavic-language.js';
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { SlavicLanguage } from '../classes/slavic-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Czech language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Three-form pluralization (one/few/many)
|
|
8
|
+
* - Dynamic decimal separator (celá/celé/celých)
|
|
9
|
+
* - Gender agreement in number words
|
|
10
|
+
*/
|
|
11
|
+
export class Czech extends SlavicLanguage {
|
|
12
|
+
negativeWord = 'mínus'
|
|
13
|
+
zeroWord = 'nula'
|
|
14
|
+
|
|
15
|
+
onesWords = {
|
|
16
|
+
1: 'jedna',
|
|
17
|
+
2: 'dva',
|
|
18
|
+
3: 'tři',
|
|
19
|
+
4: 'čtyři',
|
|
20
|
+
5: 'pět',
|
|
21
|
+
6: 'šest',
|
|
22
|
+
7: 'sedm',
|
|
23
|
+
8: 'osm',
|
|
24
|
+
9: 'devět'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
onesFeminineWords = {
|
|
28
|
+
1: 'jedna',
|
|
29
|
+
2: 'dvě',
|
|
30
|
+
3: 'tři',
|
|
31
|
+
4: 'čtyři',
|
|
32
|
+
5: 'pět',
|
|
33
|
+
6: 'šest',
|
|
34
|
+
7: 'sedm',
|
|
35
|
+
8: 'osm',
|
|
36
|
+
9: 'devět'
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
teensWords = {
|
|
40
|
+
0: 'deset',
|
|
41
|
+
1: 'jedenáct',
|
|
42
|
+
2: 'dvanáct',
|
|
43
|
+
3: 'třináct',
|
|
44
|
+
4: 'čtrnáct',
|
|
45
|
+
5: 'patnáct',
|
|
46
|
+
6: 'šestnáct',
|
|
47
|
+
7: 'sedmnáct',
|
|
48
|
+
8: 'osmnáct',
|
|
49
|
+
9: 'devatenáct'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
twentiesWords = {
|
|
53
|
+
2: 'dvacet',
|
|
54
|
+
3: 'třicet',
|
|
55
|
+
4: 'čtyřicet',
|
|
56
|
+
5: 'padesát',
|
|
57
|
+
6: 'šedesát',
|
|
58
|
+
7: 'sedmdesát',
|
|
59
|
+
8: 'osmdesát',
|
|
60
|
+
9: 'devadesát'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
hundredsWords = {
|
|
64
|
+
1: 'sto',
|
|
65
|
+
2: 'dvě stě',
|
|
66
|
+
3: 'tři sta',
|
|
67
|
+
4: 'čtyři sta',
|
|
68
|
+
5: 'pět set',
|
|
69
|
+
6: 'šest set',
|
|
70
|
+
7: 'sedm set',
|
|
71
|
+
8: 'osm set',
|
|
72
|
+
9: 'devět set'
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
pluralForms = {
|
|
76
|
+
1: ['tisíc', 'tisíce', 'tisíc'], // 10^ 3
|
|
77
|
+
2: ['milion', 'miliony', 'milionů'], // 10^ 6
|
|
78
|
+
3: ['miliarda', 'miliardy', 'miliard'], // 10^ 9
|
|
79
|
+
4: ['bilion', 'biliony', 'bilionů'], // 10^ 12
|
|
80
|
+
5: ['biliarda', 'biliardy', 'biliard'], // 10^ 15
|
|
81
|
+
6: ['trilion', 'triliony', 'trilionů'], // 10^ 18
|
|
82
|
+
7: ['triliarda', 'triliardy', 'triliard'], // 10^ 21
|
|
83
|
+
8: ['kvadrilion', 'kvadriliony', 'kvadrilionů'], // 10^ 24
|
|
84
|
+
9: ['kvadriliarda', 'kvadriliardy', 'kvadriliard'], // 10^ 27
|
|
85
|
+
10: ['quintillion', 'quintilliony', 'quintillionů'] // 10^ 30
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Czech omits "one" before scale words.
|
|
90
|
+
* e.g., 1000 is "tisíc" not "jedna tisíc"
|
|
91
|
+
*/
|
|
92
|
+
omitOneBeforeScale = true
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Cached integer part for decimal separator word selection.
|
|
96
|
+
* Set by toWords() before calling super.toWords().
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
#integerPart = 0n
|
|
100
|
+
|
|
101
|
+
/** Returns decimal separator word based on integer part (celá/celé/celých). */
|
|
102
|
+
get decimalSeparatorWord () {
|
|
103
|
+
if (this.#integerPart === 0n || this.#integerPart === 1n) {
|
|
104
|
+
return 'celá'
|
|
105
|
+
} else if (this.#integerPart >= 2n && this.#integerPart <= 4n) {
|
|
106
|
+
return 'celé'
|
|
107
|
+
} else {
|
|
108
|
+
return 'celých'
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
constructor (options = {}) {
|
|
113
|
+
super(options)
|
|
114
|
+
|
|
115
|
+
// Remove the inherited decimalSeparatorWord property so our getter works
|
|
116
|
+
delete this.decimalSeparatorWord
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Override toWords to cache integer part before decimal separator is accessed.
|
|
121
|
+
*/
|
|
122
|
+
toWords (isNegative, integerPart, decimalPart) {
|
|
123
|
+
this.#integerPart = integerPart
|
|
124
|
+
return super.toWords(isNegative, integerPart, decimalPart)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Selects Czech plural form: 1 = singular, 2-4 = few, else = many. */
|
|
128
|
+
pluralize (n, forms) {
|
|
129
|
+
if (n === 1n) {
|
|
130
|
+
return forms[0]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Check if n is in the "few" form range (2-4, 22-24, 32-34, etc., excluding teens)
|
|
134
|
+
const lastDigit = n % 10n
|
|
135
|
+
const lastTwoDigits = n % 100n
|
|
136
|
+
|
|
137
|
+
if (lastDigit > 1n && lastDigit < 5n && (lastTwoDigits < 10n || lastTwoDigits > 20n)) {
|
|
138
|
+
return forms[1]
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return forms[2]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Danish language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Vigesimal (base-20) number system
|
|
6
|
+
* - Units-before-tens ordering (e.g., "tre-og-tyve" = 23)
|
|
7
|
+
* - Optional ordinal numbers via ordFlag option
|
|
8
|
+
*/
|
|
9
|
+
export class Danish extends GreedyScaleLanguage {
|
|
10
|
+
constructor(options?: {});
|
|
11
|
+
scaleWords: (string | bigint)[][];
|
|
12
|
+
/** Combines two word-sets with Danish vigesimal and reversal rules. */
|
|
13
|
+
combineWordSets(preceding: any, following: any): any;
|
|
14
|
+
}
|
|
15
|
+
import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
|