n2words 2.0.0 → 3.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/CHANGELOG.md +49 -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/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/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 +164 -0
- package/lib/languages/am.d.ts +7 -0
- package/lib/languages/am.js +164 -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 +171 -37
- package/lib/languages/bn.d.ts +4 -8
- package/lib/languages/bn.js +138 -124
- package/lib/languages/cs.d.ts +15 -85
- package/lib/languages/cs.js +310 -114
- package/lib/languages/da.d.ts +11 -12
- package/lib/languages/da.js +276 -101
- package/lib/languages/de.d.ts +14 -11
- package/lib/languages/de.js +317 -86
- package/lib/languages/el.d.ts +11 -11
- package/lib/languages/el.js +231 -78
- package/lib/languages/en.d.ts +14 -13
- package/lib/languages/en.js +242 -72
- package/lib/languages/es.d.ts +18 -12
- package/lib/languages/es.js +317 -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 +245 -0
- package/lib/languages/fil.d.ts +4 -13
- package/lib/languages/fil.js +207 -106
- package/lib/languages/fr-BE.d.ts +8 -8
- package/lib/languages/fr-BE.js +294 -19
- package/lib/languages/fr.d.ts +18 -12
- package/lib/languages/fr.js +352 -89
- package/lib/languages/gu.d.ts +4 -8
- package/lib/languages/gu.js +130 -125
- package/lib/languages/ha.d.ts +7 -0
- package/lib/languages/ha.js +230 -0
- package/lib/languages/hbo.d.ts +10 -110
- package/lib/languages/hbo.js +263 -214
- package/lib/languages/he.d.ts +10 -77
- package/lib/languages/he.js +242 -172
- package/lib/languages/hi.d.ts +4 -8
- package/lib/languages/hi.js +138 -124
- package/lib/languages/hr.d.ts +8 -77
- package/lib/languages/hr.js +194 -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 +171 -129
- package/lib/languages/it.d.ts +16 -34
- package/lib/languages/it.js +339 -94
- package/lib/languages/ja.d.ts +14 -14
- package/lib/languages/ja.js +233 -111
- package/lib/languages/kn.d.ts +4 -8
- package/lib/languages/kn.js +130 -35
- package/lib/languages/ko.d.ts +11 -11
- package/lib/languages/ko.js +257 -49
- package/lib/languages/lt.d.ts +15 -67
- package/lib/languages/lt.js +296 -122
- package/lib/languages/lv.d.ts +15 -67
- package/lib/languages/lv.js +297 -106
- package/lib/languages/mr.d.ts +4 -8
- package/lib/languages/mr.js +130 -125
- package/lib/languages/ms.d.ts +4 -28
- package/lib/languages/ms.js +171 -116
- package/lib/languages/nb.d.ts +11 -9
- package/lib/languages/nb.js +282 -87
- package/lib/languages/nl.d.ts +23 -13
- package/lib/languages/nl.js +317 -133
- package/lib/languages/pa.d.ts +4 -8
- package/lib/languages/pa.js +156 -124
- package/lib/languages/pl.d.ts +19 -77
- package/lib/languages/pl.js +307 -87
- package/lib/languages/pt.d.ts +14 -26
- package/lib/languages/pt.js +286 -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 +222 -78
- package/lib/languages/sr-Cyrl.d.ts +8 -77
- package/lib/languages/sr-Cyrl.js +191 -89
- package/lib/languages/sr-Latn.d.ts +8 -77
- package/lib/languages/sr-Latn.js +191 -89
- package/lib/languages/sv.d.ts +11 -11
- package/lib/languages/sv.js +288 -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 +129 -201
- package/lib/languages/te.d.ts +4 -19
- package/lib/languages/te.js +141 -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 +256 -49
- package/lib/languages/uk.d.ts +8 -82
- package/lib/languages/uk.js +200 -78
- package/lib/languages/ur.d.ts +4 -8
- package/lib/languages/ur.js +156 -124
- package/lib/languages/vi.d.ts +14 -69
- package/lib/languages/vi.js +294 -125
- 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 +53 -209
- package/lib/n2words.js +111 -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/hbo.js
CHANGED
|
@@ -1,251 +1,300 @@
|
|
|
1
|
-
import { SlavicLanguage } from '../classes/slavic-language.js'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* Biblical Hebrew language converter
|
|
2
|
+
* Biblical Hebrew language converter - Functional Implementation
|
|
3
|
+
*
|
|
4
|
+
* Self-contained converter with segment-based decomposition.
|
|
5
|
+
*
|
|
6
|
+
* Key features:
|
|
7
|
+
* - Gender agreement (masculine default, feminine via option)
|
|
8
|
+
* - Dual forms for 2, 200, 2000
|
|
9
|
+
* - Special 1-9 thousands construct state
|
|
10
|
+
* - "ו" (ve) conjunction rules vary by position
|
|
11
|
+
* - Per-digit decimal reading
|
|
5
12
|
*
|
|
6
|
-
*
|
|
7
|
-
* - Three-form pluralization (one/few/many)
|
|
8
|
-
* - Gender agreement (masculine/feminine)
|
|
9
|
-
* - Optional "ו" (and) conjunction control
|
|
13
|
+
* Optimization: Precomputed segment lookup tables for both genders.
|
|
10
14
|
*/
|
|
11
|
-
export class BiblicalHebrew extends SlavicLanguage {
|
|
12
|
-
negativeWord = 'מינוס'
|
|
13
|
-
decimalSeparatorWord = 'נקודה'
|
|
14
|
-
zeroWord = 'אפס'
|
|
15
|
-
usePerDigitDecimals = true
|
|
16
|
-
|
|
17
|
-
// Biblical Hebrew (masculine forms as default - historically accurate)
|
|
18
|
-
onesWords = {
|
|
19
|
-
1: 'אחד',
|
|
20
|
-
2: 'שניים',
|
|
21
|
-
3: 'שלשה',
|
|
22
|
-
4: 'ארבעה',
|
|
23
|
-
5: 'חמשה',
|
|
24
|
-
6: 'ששה',
|
|
25
|
-
7: 'שבעה',
|
|
26
|
-
8: 'שמונה',
|
|
27
|
-
9: 'תשעה'
|
|
28
|
-
}
|
|
29
15
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
1: 'אחד עשר',
|
|
33
|
-
2: 'שנים עשר',
|
|
34
|
-
3: 'שלשה עשר',
|
|
35
|
-
4: 'ארבעה עשר',
|
|
36
|
-
5: 'חמשה עשר',
|
|
37
|
-
6: 'ששה עשר',
|
|
38
|
-
7: 'שבעה עשר',
|
|
39
|
-
8: 'שמונה עשר',
|
|
40
|
-
9: 'תשעה עשר'
|
|
41
|
-
}
|
|
16
|
+
import { parseNumericValue } from '../utils/parse-numeric.js'
|
|
17
|
+
import { validateOptions } from '../utils/validate-options.js'
|
|
42
18
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
4: 'ארבעים',
|
|
47
|
-
5: 'חמישים',
|
|
48
|
-
6: 'ששים',
|
|
49
|
-
7: 'שבעים',
|
|
50
|
-
8: 'שמונים',
|
|
51
|
-
9: 'תשעים'
|
|
52
|
-
}
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Vocabulary (arrays for indexed access - faster than object property lookup)
|
|
21
|
+
// ============================================================================
|
|
53
22
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
23
|
+
// Masculine forms (default in Biblical Hebrew) - index 0 unused
|
|
24
|
+
const ONES_MASC = ['', 'אחד', 'שניים', 'שלשה', 'ארבעה', 'חמשה', 'ששה', 'שבעה', 'שמונה', 'תשעה']
|
|
25
|
+
const TEENS_MASC = ['עשרה', 'אחד עשר', 'שנים עשר', 'שלשה עשר', 'ארבעה עשר', 'חמשה עשר', 'ששה עשר', 'שבעה עשר', 'שמונה עשר', 'תשעה עשר']
|
|
26
|
+
const THOUSANDS_MASC = ['', 'אלף', 'אלפיים', 'שלשה אלפים', 'ארבעה אלפים', 'חמשה אלפים', 'ששה אלפים', 'שבעה אלפים', 'שמונה אלפים', 'תשעה אלפים']
|
|
59
27
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
4: 'ארבעה אלפים',
|
|
65
|
-
5: 'חמשה אלפים',
|
|
66
|
-
6: 'ששה אלפים',
|
|
67
|
-
7: 'שבעה אלפים',
|
|
68
|
-
8: 'שמונה אלפים',
|
|
69
|
-
9: 'תשעה אלפים'
|
|
70
|
-
}
|
|
28
|
+
// Feminine forms - index 0 unused
|
|
29
|
+
const ONES_FEM = ['', 'אחת', 'שתים', 'שלש', 'ארבע', 'חמש', 'שש', 'שבע', 'שמונה', 'תשע']
|
|
30
|
+
const TEENS_FEM = ['עשר', 'אחת עשרה', 'שתים עשרה', 'שלש עשרה', 'ארבע עשרה', 'חמש עשרה', 'שש עשרה', 'שבע עשרה', 'שמונה עשרה', 'תשע עשרה']
|
|
31
|
+
const THOUSANDS_FEM = ['', 'אלף', 'אלפיים', 'שלשת אלפים', 'ארבעת אלפים', 'חמשת אלפים', 'ששת אלפים', 'שבעת אלפים', 'שמונת אלפים', 'תשעת אלפים']
|
|
71
32
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
3: 'שלשת אלפים',
|
|
77
|
-
4: 'ארבעת אלפים',
|
|
78
|
-
5: 'חמשת אלפים',
|
|
79
|
-
6: 'ששת אלפים',
|
|
80
|
-
7: 'שבעת אלפים',
|
|
81
|
-
8: 'שמונת אלפים',
|
|
82
|
-
9: 'תשעת אלפים'
|
|
83
|
-
}
|
|
33
|
+
// Shared vocabulary
|
|
34
|
+
const TENS = ['', '', 'עשרים', 'שלשים', 'ארבעים', 'חמישים', 'ששים', 'שבעים', 'שמונים', 'תשעים']
|
|
35
|
+
const HUNDREDS = ['', 'מאה', 'מאתיים', 'שלשה מאות', 'ארבעה מאות', 'חמשה מאות', 'ששה מאות', 'שבעה מאות', 'שמונה מאות', 'תשעה מאות']
|
|
36
|
+
const HUNDREDS_FEM = ['', 'מאה', 'מאתיים', 'שלש מאות', 'ארבע מאות', 'חמש מאות', 'שש מאות', 'שבע מאות', 'שמונה מאות', 'תשע מאות']
|
|
84
37
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
3: 'מיליארד', // billion
|
|
89
|
-
4: 'טריליון', // trillion
|
|
90
|
-
5: 'קוודרליון', // quadrillion
|
|
91
|
-
6: 'קווינטיליון' // quintillion
|
|
92
|
-
}
|
|
38
|
+
// Scale words (index 1 = thousands, 2 = millions, etc.)
|
|
39
|
+
const SCALE = ['', 'אלף', 'מיליון', 'מיליארד', 'טריליון', 'קוודרליון', 'קווינטיליון']
|
|
40
|
+
const SCALE_PLURAL = ['', 'אלפים', 'מיליונים', 'מיליארדים', 'טריליונים', 'קוודרליונים', 'קווינטיליונים']
|
|
93
41
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
42
|
+
const ZERO = 'אפס'
|
|
43
|
+
const NEGATIVE = 'מינוס'
|
|
44
|
+
const DECIMAL_SEP = 'נקודה'
|
|
45
|
+
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Precomputed Lookup Tables (built once at module load)
|
|
48
|
+
// ============================================================================
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Builds segment word for scale segments (thousands, millions, etc.).
|
|
52
|
+
* "ו" is added before tens and ones when following hundreds.
|
|
53
|
+
*/
|
|
54
|
+
function buildScaleSegment (n, andWord, ONES, TEENS, HUNDREDS_ARR) {
|
|
55
|
+
if (n === 0) return ''
|
|
102
56
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
8: 'שמונה',
|
|
113
|
-
9: 'תשע'
|
|
57
|
+
const ones = n % 10
|
|
58
|
+
const tens = Math.floor(n / 10) % 10
|
|
59
|
+
const hundreds = Math.floor(n / 100)
|
|
60
|
+
|
|
61
|
+
let result = ''
|
|
62
|
+
|
|
63
|
+
// Hundreds
|
|
64
|
+
if (hundreds > 0) {
|
|
65
|
+
result = HUNDREDS_ARR[hundreds]
|
|
114
66
|
}
|
|
115
67
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
68
|
+
// Tens and ones
|
|
69
|
+
if (tens === 1) {
|
|
70
|
+
// Teens (10-19)
|
|
71
|
+
const teenWord = TEENS[ones]
|
|
72
|
+
if (result) {
|
|
73
|
+
result += ' ' + andWord + teenWord
|
|
74
|
+
} else {
|
|
75
|
+
result = teenWord
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
// Tens (20-90)
|
|
79
|
+
if (tens >= 2) {
|
|
80
|
+
if (result) {
|
|
81
|
+
result += ' ' + andWord + TENS[tens]
|
|
82
|
+
} else {
|
|
83
|
+
result = TENS[tens]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Ones
|
|
88
|
+
if (ones > 0) {
|
|
89
|
+
if (result) {
|
|
90
|
+
result += ' ' + andWord + ONES[ones]
|
|
91
|
+
} else {
|
|
92
|
+
result = ONES[ones]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
127
95
|
}
|
|
128
96
|
|
|
129
|
-
|
|
130
|
-
|
|
97
|
+
return result
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Builds segment word for units segment (no scale word).
|
|
102
|
+
* "ו" is only added before the final ones digit.
|
|
103
|
+
*/
|
|
104
|
+
function buildUnitsSegment (n, andWord, ONES, TEENS, HUNDREDS_ARR) {
|
|
105
|
+
if (n === 0) return ''
|
|
131
106
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}, options)
|
|
107
|
+
const ones = n % 10
|
|
108
|
+
const tens = Math.floor(n / 10) % 10
|
|
109
|
+
const hundreds = Math.floor(n / 100)
|
|
136
110
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
111
|
+
let result = ''
|
|
112
|
+
|
|
113
|
+
// Hundreds
|
|
114
|
+
if (hundreds > 0) {
|
|
115
|
+
result = HUNDREDS_ARR[hundreds]
|
|
142
116
|
}
|
|
143
117
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
118
|
+
// Tens (no conjunction)
|
|
119
|
+
if (tens === 1) {
|
|
120
|
+
// Teens (10-19)
|
|
121
|
+
if (result) {
|
|
122
|
+
result += ' ' + TEENS[ones]
|
|
123
|
+
} else {
|
|
124
|
+
result = TEENS[ones]
|
|
148
125
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
continue
|
|
126
|
+
} else {
|
|
127
|
+
if (tens >= 2) {
|
|
128
|
+
if (result) {
|
|
129
|
+
result += ' ' + TENS[tens]
|
|
130
|
+
} else {
|
|
131
|
+
result = TENS[tens]
|
|
156
132
|
}
|
|
133
|
+
}
|
|
157
134
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
hasHundreds = true
|
|
168
|
-
if (n3 <= 2n) {
|
|
169
|
-
chunkWords.push(this.hundredsWords[n3])
|
|
170
|
-
} else {
|
|
171
|
-
chunkWords.push(this.onesWords[n3] + ' ' + this.hundredsWords[3])
|
|
172
|
-
}
|
|
173
|
-
}
|
|
135
|
+
// Ones - conjunction only here
|
|
136
|
+
if (ones > 0) {
|
|
137
|
+
if (result) {
|
|
138
|
+
result += ' ' + andWord + ONES[ones]
|
|
139
|
+
} else {
|
|
140
|
+
result = ONES[ones]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
174
144
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
// Add conjunction if there were hundreds before
|
|
178
|
-
const tensWord = this.twentiesWords[n2]
|
|
179
|
-
chunkWords.push(hasHundreds ? this.options.andWord + tensWord : tensWord)
|
|
180
|
-
}
|
|
145
|
+
return result
|
|
146
|
+
}
|
|
181
147
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
} else if (n1 > 0n) {
|
|
188
|
-
// For "one million", "one billion", etc., don't add the word "one"
|
|
189
|
-
if (x === 1n && index > 1) {
|
|
190
|
-
// Skip adding "one" for millions/billions/etc.
|
|
191
|
-
} else if (x <= 9n && chunkWords.length === 0 && index === 1) {
|
|
192
|
-
// Use special forms for 1-9 thousand
|
|
193
|
-
chunkWords.push(this.pluralForms[n1])
|
|
194
|
-
} else {
|
|
195
|
-
const onesWord = this.onesWords[n1]
|
|
196
|
-
// Add conjunction if there were hundreds or tens before
|
|
197
|
-
chunkWords.push((hasHundreds || n2 > 0n) ? this.options.andWord + onesWord : onesWord)
|
|
198
|
-
}
|
|
199
|
-
}
|
|
148
|
+
// Precompute all 1000 segment words for masculine (default) with default conjunction
|
|
149
|
+
const SCALE_SEGMENTS_MASC = new Array(1000)
|
|
150
|
+
const UNITS_SEGMENTS_MASC = new Array(1000)
|
|
151
|
+
const SCALE_SEGMENTS_FEM = new Array(1000)
|
|
152
|
+
const UNITS_SEGMENTS_FEM = new Array(1000)
|
|
200
153
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
} else if (x === 2n && index === 1) {
|
|
208
|
-
// Special dual form for "two thousand" (already in thousands[2])
|
|
209
|
-
return [this.pluralForms[2], ...words].join(' ')
|
|
210
|
-
} else if (x === 2n) {
|
|
211
|
-
// For two million, two billion, etc. - use plural form
|
|
212
|
-
chunkWords.push(this.scalePlural[index])
|
|
213
|
-
} else if (index === 1) {
|
|
214
|
-
// For thousands (10+), always use singular "אלף"
|
|
215
|
-
chunkWords.push(this.scale[index])
|
|
216
|
-
} else {
|
|
217
|
-
// For millions/billions/etc. use plural form
|
|
218
|
-
chunkWords.push(this.scalePlural[index])
|
|
219
|
-
}
|
|
220
|
-
}
|
|
154
|
+
for (let i = 0; i < 1000; i++) {
|
|
155
|
+
SCALE_SEGMENTS_MASC[i] = buildScaleSegment(i, 'ו', ONES_MASC, TEENS_MASC, HUNDREDS)
|
|
156
|
+
UNITS_SEGMENTS_MASC[i] = buildUnitsSegment(i, 'ו', ONES_MASC, TEENS_MASC, HUNDREDS)
|
|
157
|
+
SCALE_SEGMENTS_FEM[i] = buildScaleSegment(i, 'ו', ONES_FEM, TEENS_FEM, HUNDREDS_FEM)
|
|
158
|
+
UNITS_SEGMENTS_FEM[i] = buildUnitsSegment(i, 'ו', ONES_FEM, TEENS_FEM, HUNDREDS_FEM)
|
|
159
|
+
}
|
|
221
160
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
161
|
+
// ============================================================================
|
|
162
|
+
// Conversion Functions
|
|
163
|
+
// ============================================================================
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Converts a non-negative integer to Biblical Hebrew words.
|
|
167
|
+
*
|
|
168
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
169
|
+
* @param {Object} options - Conversion options
|
|
170
|
+
* @returns {string} Biblical Hebrew words
|
|
171
|
+
*/
|
|
172
|
+
function integerToWords (n, options) {
|
|
173
|
+
if (n === 0n) return ZERO
|
|
174
|
+
|
|
175
|
+
const andWord = options.andWord ?? 'ו'
|
|
176
|
+
const gender = options.gender || 'masculine'
|
|
177
|
+
const isFeminine = gender === 'feminine'
|
|
178
|
+
const usePrecomputed = andWord === 'ו'
|
|
179
|
+
|
|
180
|
+
// Select vocabulary based on gender
|
|
181
|
+
const ONES = isFeminine ? ONES_FEM : ONES_MASC
|
|
182
|
+
const TEENS = isFeminine ? TEENS_FEM : TEENS_MASC
|
|
183
|
+
const THOUSANDS_SPECIAL = isFeminine ? THOUSANDS_FEM : THOUSANDS_MASC
|
|
184
|
+
const HUNDREDS_ARR = isFeminine ? HUNDREDS_FEM : HUNDREDS
|
|
185
|
+
const SCALE_SEGS = isFeminine ? SCALE_SEGMENTS_FEM : SCALE_SEGMENTS_MASC
|
|
186
|
+
const UNITS_SEGS = isFeminine ? UNITS_SEGMENTS_FEM : UNITS_SEGMENTS_MASC
|
|
187
|
+
|
|
188
|
+
// Fast path: numbers < 1000 (direct lookup)
|
|
189
|
+
if (n < 1000n) {
|
|
190
|
+
return usePrecomputed ? UNITS_SEGS[Number(n)] : buildUnitsSegment(Number(n), andWord, ONES, TEENS, HUNDREDS_ARR)
|
|
191
|
+
}
|
|
225
192
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
193
|
+
// Extract segments using BigInt modulo
|
|
194
|
+
const segments = []
|
|
195
|
+
let temp = n
|
|
196
|
+
while (temp > 0n) {
|
|
197
|
+
segments.push(Number(temp % 1000n))
|
|
198
|
+
temp = temp / 1000n
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Build result string directly
|
|
202
|
+
let result = ''
|
|
203
|
+
|
|
204
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
205
|
+
const segment = segments[i]
|
|
206
|
+
if (segment === 0) continue
|
|
207
|
+
|
|
208
|
+
if (i === 0) {
|
|
209
|
+
// Units segment (no scale word)
|
|
210
|
+
const segmentWord = usePrecomputed ? UNITS_SEGS[segment] : buildUnitsSegment(segment, andWord, ONES, TEENS, HUNDREDS_ARR)
|
|
211
|
+
if (result) {
|
|
212
|
+
// Add "ו" before single-digit units when following scale words
|
|
213
|
+
if (segment <= 9) {
|
|
214
|
+
result += ' ' + andWord + segmentWord
|
|
229
215
|
} else {
|
|
230
|
-
|
|
216
|
+
result += ' ' + segmentWord
|
|
231
217
|
}
|
|
218
|
+
} else {
|
|
219
|
+
result = segmentWord
|
|
232
220
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
221
|
+
} else if (i === 1) {
|
|
222
|
+
// Thousands - special handling for 1-9
|
|
223
|
+
if (segment <= 9) {
|
|
224
|
+
if (result) result += ' '
|
|
225
|
+
result += THOUSANDS_SPECIAL[segment]
|
|
226
|
+
} else {
|
|
227
|
+
const segmentWord = usePrecomputed ? SCALE_SEGS[segment] : buildScaleSegment(segment, andWord, ONES, TEENS, HUNDREDS_ARR)
|
|
228
|
+
if (result) result += ' '
|
|
229
|
+
result += segmentWord + ' ' + SCALE[1]
|
|
236
230
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
231
|
+
} else {
|
|
232
|
+
// Millions and above
|
|
233
|
+
if (segment === 1) {
|
|
234
|
+
if (result) result += ' '
|
|
235
|
+
result += SCALE[i]
|
|
236
|
+
} else {
|
|
237
|
+
const segmentWord = usePrecomputed ? SCALE_SEGS[segment] : buildScaleSegment(segment, andWord, ONES, TEENS, HUNDREDS_ARR)
|
|
238
|
+
if (result) result += ' '
|
|
239
|
+
result += segmentWord + ' ' + SCALE_PLURAL[i]
|
|
242
240
|
}
|
|
243
241
|
}
|
|
242
|
+
}
|
|
244
243
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
244
|
+
return result
|
|
245
|
+
}
|
|
248
246
|
|
|
249
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Converts decimal digits to Biblical Hebrew words (digit by digit).
|
|
249
|
+
*
|
|
250
|
+
* @param {string} decimalPart - Decimal digits (without the point)
|
|
251
|
+
* @param {Object} options - Conversion options
|
|
252
|
+
* @returns {string} Biblical Hebrew words for decimal part
|
|
253
|
+
*/
|
|
254
|
+
function decimalPartToWords (decimalPart, options) {
|
|
255
|
+
const gender = options.gender || 'masculine'
|
|
256
|
+
const ONES = gender === 'feminine' ? ONES_FEM : ONES_MASC
|
|
257
|
+
|
|
258
|
+
let result = ''
|
|
259
|
+
for (let i = 0; i < decimalPart.length; i++) {
|
|
260
|
+
const d = parseInt(decimalPart[i], 10)
|
|
261
|
+
if (result) result += ' '
|
|
262
|
+
result += d === 0 ? ZERO : ONES[d]
|
|
250
263
|
}
|
|
264
|
+
|
|
265
|
+
return result
|
|
251
266
|
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Converts a numeric value to Biblical Hebrew words.
|
|
270
|
+
*
|
|
271
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
272
|
+
* @param {Object} [options] - Optional configuration
|
|
273
|
+
* @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
|
|
274
|
+
* @param {string} [options.andWord] - Custom conjunction word
|
|
275
|
+
* @returns {string} The number in Biblical Hebrew words
|
|
276
|
+
*/
|
|
277
|
+
function toWords (value, options) {
|
|
278
|
+
options = validateOptions(options)
|
|
279
|
+
const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
|
|
280
|
+
|
|
281
|
+
let result = ''
|
|
282
|
+
|
|
283
|
+
if (isNegative) {
|
|
284
|
+
result = NEGATIVE + ' '
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
result += integerToWords(integerPart, options)
|
|
288
|
+
|
|
289
|
+
if (decimalPart) {
|
|
290
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return result
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ============================================================================
|
|
297
|
+
// Exports
|
|
298
|
+
// ============================================================================
|
|
299
|
+
|
|
300
|
+
export { toWords }
|
package/lib/languages/he.d.ts
CHANGED
|
@@ -1,80 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Modern Hebrew
|
|
2
|
+
* Converts a numeric value to Modern Hebrew words.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @param {Object} [options] - Optional configuration
|
|
6
|
+
* @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
|
|
7
|
+
* @param {string} [options.andWord] - Custom conjunction word
|
|
8
|
+
* @returns {string} The number in Modern Hebrew words
|
|
9
9
|
*/
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
2: string;
|
|
15
|
-
3: string;
|
|
16
|
-
4: string;
|
|
17
|
-
5: string;
|
|
18
|
-
6: string;
|
|
19
|
-
7: string;
|
|
20
|
-
8: string;
|
|
21
|
-
9: string;
|
|
22
|
-
};
|
|
23
|
-
teensWords: {
|
|
24
|
-
0: string;
|
|
25
|
-
1: string;
|
|
26
|
-
2: string;
|
|
27
|
-
3: string;
|
|
28
|
-
4: string;
|
|
29
|
-
5: string;
|
|
30
|
-
6: string;
|
|
31
|
-
7: string;
|
|
32
|
-
8: string;
|
|
33
|
-
9: string;
|
|
34
|
-
};
|
|
35
|
-
twentiesWords: {
|
|
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
|
-
hundredsWords: {
|
|
46
|
-
1: string;
|
|
47
|
-
2: string;
|
|
48
|
-
3: string;
|
|
49
|
-
};
|
|
50
|
-
pluralForms: {
|
|
51
|
-
1: string;
|
|
52
|
-
2: string;
|
|
53
|
-
3: string;
|
|
54
|
-
4: string;
|
|
55
|
-
5: string;
|
|
56
|
-
6: string;
|
|
57
|
-
7: string;
|
|
58
|
-
8: string;
|
|
59
|
-
9: string;
|
|
60
|
-
};
|
|
61
|
-
scale: {
|
|
62
|
-
1: string;
|
|
63
|
-
2: string;
|
|
64
|
-
3: string;
|
|
65
|
-
4: string;
|
|
66
|
-
5: string;
|
|
67
|
-
6: string;
|
|
68
|
-
};
|
|
69
|
-
scalePlural: {
|
|
70
|
-
1: string;
|
|
71
|
-
2: string;
|
|
72
|
-
3: string;
|
|
73
|
-
4: string;
|
|
74
|
-
5: string;
|
|
75
|
-
6: string;
|
|
76
|
-
};
|
|
77
|
-
/** Converts integer part to Hebrew words with special handling for thousands. */
|
|
78
|
-
integerToWords(integerPart: any): string;
|
|
79
|
-
}
|
|
80
|
-
import { SlavicLanguage } from '../classes/slavic-language.js';
|
|
10
|
+
export function toWords(value: number | string | bigint, options?: {
|
|
11
|
+
gender?: "masculine" | "feminine" | undefined;
|
|
12
|
+
andWord?: string | undefined;
|
|
13
|
+
}): string;
|