n2words 1.23.0 → 1.24.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.
Files changed (317) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +182 -53
  3. package/dist/languages/ar.js +2 -0
  4. package/dist/languages/ar.js.map +1 -0
  5. package/dist/languages/az.js +2 -0
  6. package/dist/languages/az.js.map +1 -0
  7. package/dist/languages/bn.js +2 -0
  8. package/dist/languages/bn.js.map +1 -0
  9. package/dist/languages/cs.js +2 -0
  10. package/dist/languages/cs.js.map +1 -0
  11. package/dist/languages/da.js +2 -0
  12. package/dist/languages/da.js.map +1 -0
  13. package/dist/languages/de.js +2 -0
  14. package/dist/languages/de.js.map +1 -0
  15. package/dist/languages/el.js +2 -0
  16. package/dist/languages/el.js.map +1 -0
  17. package/dist/languages/en.js +2 -0
  18. package/dist/languages/en.js.map +1 -0
  19. package/dist/languages/es.js +2 -0
  20. package/dist/languages/es.js.map +1 -0
  21. package/dist/languages/fa.js +2 -0
  22. package/dist/languages/fa.js.map +1 -0
  23. package/dist/languages/fil.js +2 -0
  24. package/dist/languages/fil.js.map +1 -0
  25. package/dist/languages/fr-BE.js +2 -0
  26. package/dist/languages/fr-BE.js.map +1 -0
  27. package/dist/languages/fr.js +2 -0
  28. package/dist/languages/fr.js.map +1 -0
  29. package/dist/languages/gu.js +2 -0
  30. package/dist/languages/gu.js.map +1 -0
  31. package/dist/languages/he.js +2 -0
  32. package/dist/languages/he.js.map +1 -0
  33. package/dist/languages/hi.js +2 -0
  34. package/dist/languages/hi.js.map +1 -0
  35. package/dist/languages/hr.js +2 -0
  36. package/dist/languages/hr.js.map +1 -0
  37. package/dist/languages/hu.js +2 -0
  38. package/dist/languages/hu.js.map +1 -0
  39. package/dist/languages/id.js +2 -0
  40. package/dist/languages/id.js.map +1 -0
  41. package/dist/languages/it.js +2 -0
  42. package/dist/languages/it.js.map +1 -0
  43. package/dist/languages/ja.js +2 -0
  44. package/dist/languages/ja.js.map +1 -0
  45. package/dist/languages/kn.js +2 -0
  46. package/dist/languages/kn.js.map +1 -0
  47. package/dist/languages/ko.js +2 -0
  48. package/dist/languages/ko.js.map +1 -0
  49. package/dist/languages/lt.js +2 -0
  50. package/dist/languages/lt.js.map +1 -0
  51. package/dist/languages/lv.js +2 -0
  52. package/dist/languages/lv.js.map +1 -0
  53. package/dist/languages/mr.js +2 -0
  54. package/dist/languages/mr.js.map +1 -0
  55. package/dist/languages/ms.js +2 -0
  56. package/dist/languages/ms.js.map +1 -0
  57. package/dist/languages/nb.js +2 -0
  58. package/dist/languages/nb.js.map +1 -0
  59. package/dist/languages/nl.js +2 -0
  60. package/dist/languages/nl.js.map +1 -0
  61. package/dist/languages/pa-Guru.js +2 -0
  62. package/dist/languages/pa-Guru.js.map +1 -0
  63. package/dist/languages/pl.js +2 -0
  64. package/dist/languages/pl.js.map +1 -0
  65. package/dist/languages/pt.js +2 -0
  66. package/dist/languages/pt.js.map +1 -0
  67. package/dist/languages/ro.js +2 -0
  68. package/dist/languages/ro.js.map +1 -0
  69. package/dist/languages/ru.js +2 -0
  70. package/dist/languages/ru.js.map +1 -0
  71. package/dist/languages/sr-Latn.js +2 -0
  72. package/dist/languages/sr-Latn.js.map +1 -0
  73. package/dist/languages/sv.js +2 -0
  74. package/dist/languages/sv.js.map +1 -0
  75. package/dist/languages/sw.js +2 -0
  76. package/dist/languages/sw.js.map +1 -0
  77. package/dist/languages/ta.js +2 -0
  78. package/dist/languages/ta.js.map +1 -0
  79. package/dist/languages/te.js +2 -0
  80. package/dist/languages/te.js.map +1 -0
  81. package/dist/languages/th.js +2 -0
  82. package/dist/languages/th.js.map +1 -0
  83. package/dist/languages/tr.js +2 -0
  84. package/dist/languages/tr.js.map +1 -0
  85. package/dist/languages/uk.js +2 -0
  86. package/dist/languages/uk.js.map +1 -0
  87. package/dist/languages/ur.js +2 -0
  88. package/dist/languages/ur.js.map +1 -0
  89. package/dist/languages/vi.js +2 -0
  90. package/dist/languages/vi.js.map +1 -0
  91. package/dist/languages/zh-Hans.js +2 -0
  92. package/dist/languages/zh-Hans.js.map +1 -0
  93. package/dist/n2words.js +1 -1
  94. package/dist/n2words.js.map +1 -1
  95. package/lib/classes/abstract-language.js +211 -110
  96. package/lib/classes/greedy-scale-language.js +195 -0
  97. package/lib/classes/slavic-language.js +251 -0
  98. package/lib/classes/south-asian-language.js +161 -0
  99. package/lib/classes/turkic-language.js +63 -0
  100. package/lib/languages/ar.js +243 -0
  101. package/lib/languages/az.js +58 -0
  102. package/lib/languages/bn.js +126 -0
  103. package/lib/languages/cs.js +212 -0
  104. package/lib/languages/da.js +167 -0
  105. package/lib/languages/de.js +135 -0
  106. package/lib/languages/el.js +116 -0
  107. package/lib/languages/en.js +123 -0
  108. package/lib/languages/es.js +153 -0
  109. package/lib/languages/fa.js +127 -0
  110. package/lib/languages/fil.js +162 -0
  111. package/lib/languages/fr-BE.js +61 -0
  112. package/lib/languages/fr.js +145 -0
  113. package/lib/languages/gu.js +156 -0
  114. package/lib/languages/he.js +329 -0
  115. package/lib/languages/hi.js +126 -0
  116. package/lib/languages/hr.js +157 -0
  117. package/lib/languages/hu.js +155 -0
  118. package/lib/languages/id.js +174 -0
  119. package/lib/languages/it.js +148 -0
  120. package/lib/languages/ja.js +190 -0
  121. package/lib/languages/kn.js +71 -0
  122. package/lib/languages/ko.js +83 -0
  123. package/lib/languages/lt.js +171 -0
  124. package/lib/languages/lv.js +153 -0
  125. package/lib/languages/mr.js +156 -0
  126. package/lib/languages/ms.js +146 -0
  127. package/lib/languages/nb.js +120 -0
  128. package/lib/languages/nl.js +206 -0
  129. package/lib/languages/pa-Guru.js +126 -0
  130. package/lib/languages/pl.js +189 -0
  131. package/lib/languages/pt.js +147 -0
  132. package/lib/languages/ro.js +380 -0
  133. package/lib/languages/ru.js +116 -0
  134. package/lib/languages/sr-Latn.js +157 -0
  135. package/lib/languages/sv.js +127 -0
  136. package/lib/languages/sw.js +121 -0
  137. package/lib/languages/ta.js +226 -0
  138. package/lib/languages/te.js +229 -0
  139. package/lib/languages/th.js +123 -0
  140. package/lib/languages/tr.js +83 -0
  141. package/lib/{i18n → languages}/uk.js +50 -23
  142. package/lib/languages/ur.js +126 -0
  143. package/lib/languages/vi.js +193 -0
  144. package/lib/languages/zh-Hans.js +165 -0
  145. package/lib/n2words.js +246 -75
  146. package/package.json +80 -72
  147. package/typings/classes/abstract-language.d.ts +144 -0
  148. package/typings/classes/greedy-scale-language.d.ts +148 -0
  149. package/typings/classes/slavic-language.d.ts +145 -0
  150. package/typings/classes/south-asian-language.d.ts +101 -0
  151. package/typings/classes/turkic-language.d.ts +42 -0
  152. package/typings/languages/ar.d.ts +93 -0
  153. package/typings/languages/az.d.ts +25 -0
  154. package/typings/languages/bn.d.ts +1 -0
  155. package/typings/languages/cs.d.ts +120 -0
  156. package/typings/languages/da.d.ts +53 -0
  157. package/typings/languages/de.d.ts +26 -0
  158. package/typings/languages/el.d.ts +11 -0
  159. package/typings/languages/en.d.ts +30 -0
  160. package/typings/languages/es.d.ts +43 -0
  161. package/typings/languages/fa.d.ts +81 -0
  162. package/typings/languages/fil.d.ts +12 -0
  163. package/typings/languages/fr-BE.d.ts +41 -0
  164. package/typings/languages/fr.d.ts +43 -0
  165. package/typings/languages/gu.d.ts +12 -0
  166. package/typings/languages/he.d.ts +197 -0
  167. package/typings/languages/hi.d.ts +1 -0
  168. package/typings/languages/hr.d.ts +110 -0
  169. package/typings/languages/hu.d.ts +37 -0
  170. package/typings/languages/id.d.ts +69 -0
  171. package/typings/languages/it.d.ts +51 -0
  172. package/typings/languages/ja.d.ts +58 -0
  173. package/typings/languages/kn.d.ts +11 -0
  174. package/typings/languages/ko.d.ts +25 -0
  175. package/typings/languages/lt.d.ts +110 -0
  176. package/typings/languages/lv.d.ts +99 -0
  177. package/typings/languages/mr.d.ts +12 -0
  178. package/typings/languages/ms.d.ts +37 -0
  179. package/typings/languages/nb.d.ts +27 -0
  180. package/typings/languages/nl.d.ts +65 -0
  181. package/typings/languages/pa-Guru.d.ts +1 -0
  182. package/typings/languages/pl.d.ts +116 -0
  183. package/typings/languages/pt.d.ts +39 -0
  184. package/typings/languages/ro.d.ts +229 -0
  185. package/typings/languages/ru.d.ts +108 -0
  186. package/typings/languages/sr-Latn.d.ts +98 -0
  187. package/typings/languages/sv.d.ts +30 -0
  188. package/typings/languages/sw.d.ts +1 -0
  189. package/typings/languages/ta.d.ts +1 -0
  190. package/typings/languages/te.d.ts +1 -0
  191. package/typings/languages/th.d.ts +1 -0
  192. package/typings/languages/tr.d.ts +46 -0
  193. package/typings/languages/uk.d.ts +117 -0
  194. package/typings/languages/ur.d.ts +1 -0
  195. package/typings/languages/vi.d.ts +116 -0
  196. package/typings/languages/zh-Hans.d.ts +57 -0
  197. package/typings/n2words.d.ts +177 -0
  198. package/dist/ar.js +0 -2
  199. package/dist/ar.js.map +0 -1
  200. package/dist/az.js +0 -2
  201. package/dist/az.js.map +0 -1
  202. package/dist/cz.js +0 -2
  203. package/dist/cz.js.map +0 -1
  204. package/dist/de.js +0 -2
  205. package/dist/de.js.map +0 -1
  206. package/dist/dk.js +0 -2
  207. package/dist/dk.js.map +0 -1
  208. package/dist/en.js +0 -2
  209. package/dist/en.js.map +0 -1
  210. package/dist/es.js +0 -2
  211. package/dist/es.js.map +0 -1
  212. package/dist/fa.js +0 -2
  213. package/dist/fa.js.map +0 -1
  214. package/dist/fr-BE.js +0 -2
  215. package/dist/fr-BE.js.map +0 -1
  216. package/dist/fr.js +0 -2
  217. package/dist/fr.js.map +0 -1
  218. package/dist/he.js +0 -2
  219. package/dist/he.js.map +0 -1
  220. package/dist/hr.js +0 -2
  221. package/dist/hr.js.map +0 -1
  222. package/dist/hu.js +0 -2
  223. package/dist/hu.js.map +0 -1
  224. package/dist/id.js +0 -2
  225. package/dist/id.js.map +0 -1
  226. package/dist/it.js +0 -2
  227. package/dist/it.js.map +0 -1
  228. package/dist/ko.js +0 -2
  229. package/dist/ko.js.map +0 -1
  230. package/dist/lt.js +0 -2
  231. package/dist/lt.js.map +0 -1
  232. package/dist/lv.js +0 -2
  233. package/dist/lv.js.map +0 -1
  234. package/dist/n2words.d.ts +0 -2
  235. package/dist/nl.js +0 -2
  236. package/dist/nl.js.map +0 -1
  237. package/dist/no.js +0 -2
  238. package/dist/no.js.map +0 -1
  239. package/dist/pl.js +0 -2
  240. package/dist/pl.js.map +0 -1
  241. package/dist/pt.js +0 -2
  242. package/dist/pt.js.map +0 -1
  243. package/dist/ro.js +0 -2
  244. package/dist/ro.js.map +0 -1
  245. package/dist/ru.js +0 -2
  246. package/dist/ru.js.map +0 -1
  247. package/dist/sr.js +0 -2
  248. package/dist/sr.js.map +0 -1
  249. package/dist/tr.js +0 -2
  250. package/dist/tr.js.map +0 -1
  251. package/dist/uk.js +0 -2
  252. package/dist/uk.js.map +0 -1
  253. package/dist/vi.js +0 -2
  254. package/dist/vi.js.map +0 -1
  255. package/dist/zh.js +0 -2
  256. package/dist/zh.js.map +0 -1
  257. package/lib/classes/abstract-language.d.ts +0 -54
  258. package/lib/classes/base-language.d.ts +0 -58
  259. package/lib/classes/base-language.js +0 -172
  260. package/lib/i18n/ar.d.ts +0 -41
  261. package/lib/i18n/ar.js +0 -209
  262. package/lib/i18n/az.d.ts +0 -15
  263. package/lib/i18n/az.js +0 -66
  264. package/lib/i18n/cz.d.ts +0 -68
  265. package/lib/i18n/cz.js +0 -135
  266. package/lib/i18n/de.d.ts +0 -17
  267. package/lib/i18n/de.js +0 -103
  268. package/lib/i18n/dk.d.ts +0 -14
  269. package/lib/i18n/dk.js +0 -110
  270. package/lib/i18n/en.d.ts +0 -22
  271. package/lib/i18n/en.js +0 -86
  272. package/lib/i18n/es.d.ts +0 -16
  273. package/lib/i18n/es.js +0 -110
  274. package/lib/i18n/fa.d.ts +0 -54
  275. package/lib/i18n/fa.js +0 -106
  276. package/lib/i18n/fr-BE.d.ts +0 -11
  277. package/lib/i18n/fr-BE.js +0 -20
  278. package/lib/i18n/fr.d.ts +0 -15
  279. package/lib/i18n/fr.js +0 -99
  280. package/lib/i18n/he.d.ts +0 -61
  281. package/lib/i18n/he.js +0 -132
  282. package/lib/i18n/hr.d.ts +0 -68
  283. package/lib/i18n/hr.js +0 -129
  284. package/lib/i18n/hu.d.ts +0 -17
  285. package/lib/i18n/hu.js +0 -135
  286. package/lib/i18n/id.d.ts +0 -43
  287. package/lib/i18n/id.js +0 -156
  288. package/lib/i18n/it.d.ts +0 -29
  289. package/lib/i18n/it.js +0 -137
  290. package/lib/i18n/ko.d.ts +0 -15
  291. package/lib/i18n/ko.js +0 -56
  292. package/lib/i18n/lt.d.ts +0 -68
  293. package/lib/i18n/lt.js +0 -138
  294. package/lib/i18n/lv.d.ts +0 -57
  295. package/lib/i18n/lv.js +0 -120
  296. package/lib/i18n/nl.d.ts +0 -20
  297. package/lib/i18n/nl.js +0 -125
  298. package/lib/i18n/no.d.ts +0 -15
  299. package/lib/i18n/no.js +0 -77
  300. package/lib/i18n/pl.d.ts +0 -67
  301. package/lib/i18n/pl.js +0 -126
  302. package/lib/i18n/pt.d.ts +0 -26
  303. package/lib/i18n/pt.js +0 -118
  304. package/lib/i18n/ro.d.ts +0 -109
  305. package/lib/i18n/ro.js +0 -360
  306. package/lib/i18n/ru.d.ts +0 -30
  307. package/lib/i18n/ru.js +0 -198
  308. package/lib/i18n/sr.d.ts +0 -56
  309. package/lib/i18n/sr.js +0 -127
  310. package/lib/i18n/tr.d.ts +0 -15
  311. package/lib/i18n/tr.js +0 -64
  312. package/lib/i18n/uk.d.ts +0 -78
  313. package/lib/i18n/vi.d.ts +0 -70
  314. package/lib/i18n/vi.js +0 -151
  315. package/lib/i18n/zh.d.ts +0 -18
  316. package/lib/i18n/zh.js +0 -78
  317. package/lib/n2words.d.ts +0 -9
@@ -0,0 +1,329 @@
1
+ import SlavicLanguage from '../classes/slavic-language.js'
2
+
3
+ /**
4
+ * @typedef {Object} HebrewOptions
5
+ * @property {string} [and='ו'] Conjunction character (typically 'ו' for and).
6
+ * @property {boolean} [biblical=false] Use biblical scale words instead of modern ones.
7
+ * @property {boolean} [feminine=false] Use feminine forms for numbers.
8
+ */
9
+
10
+ /**
11
+ * Hebrew language converter.
12
+ *
13
+ * Implements Hebrew number words using the Slavic language pattern:
14
+ * - Hebrew alphabet and right-to-left text
15
+ * - Hebrew number words (אחת, שתים, שלוש, ארבע...)
16
+ * - Feminine number forms (default in Hebrew)
17
+ * - Optional "ve" (ו, "and") conjunction between number groups
18
+ *
19
+ * Key Features:
20
+ * - Three-form pluralization system shared across Slavic languages
21
+ * * Form 1 (singular): 1 (e.g., "אלף")
22
+ * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., "אלפים")
23
+ * * Form 3 (many): all other numbers (e.g., "אלף")
24
+ * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)
25
+ * - Large number handling via thousands[] array with indexed [singular, few, many] forms
26
+ *
27
+ * Features:
28
+ * - Right-to-left text orientation
29
+ * - Feminine grammatical gender for numbers
30
+ * - Three-form pluralization (similar to Slavic pattern)
31
+ * - Conjunction control via "and" option
32
+ *
33
+ * Inherits from SlavicLanguage for complex pluralization algorithms.
34
+ */
35
+ export class Hebrew extends SlavicLanguage {
36
+ negativeWord = 'מינוס'
37
+ decimalSeparatorWord = 'נקודה'
38
+ zeroWord = 'אפס'
39
+ convertDecimalsPerDigit = true
40
+
41
+ // Modern Hebrew (feminine forms)
42
+ ones = {
43
+ 1: 'אחת',
44
+ 2: 'שתים',
45
+ 3: 'שלש',
46
+ 4: 'ארבע',
47
+ 5: 'חמש',
48
+ 6: 'שש',
49
+ 7: 'שבע',
50
+ 8: 'שמונה',
51
+ 9: 'תשע'
52
+ }
53
+
54
+ tens = {
55
+ 0: 'עשר',
56
+ 1: 'אחת עשרה',
57
+ 2: 'שתים עשרה',
58
+ 3: 'שלש עשרה',
59
+ 4: 'ארבע עשרה',
60
+ 5: 'חמש עשרה',
61
+ 6: 'שש עשרה',
62
+ 7: 'שבע עשרה',
63
+ 8: 'שמונה עשרה',
64
+ 9: 'תשע עשרה'
65
+ }
66
+
67
+ twenties = {
68
+ 2: 'עשרים',
69
+ 3: 'שלשים',
70
+ 4: 'ארבעים',
71
+ 5: 'חמישים',
72
+ 6: 'ששים',
73
+ 7: 'שבעים',
74
+ 8: 'שמונים',
75
+ 9: 'תשעים'
76
+ }
77
+
78
+ hundreds = {
79
+ 1: 'מאה',
80
+ 2: 'מאתיים',
81
+ 3: 'מאות'
82
+ }
83
+
84
+ thousands = {
85
+ 1: 'אלף',
86
+ 2: 'אלפיים',
87
+ 3: 'שלשת אלפים',
88
+ 4: 'ארבעת אלפים',
89
+ 5: 'חמשת אלפים',
90
+ 6: 'ששת אלפים',
91
+ 7: 'שבעת אלפים',
92
+ 8: 'שמונת אלפים',
93
+ 9: 'תשעת אלפים'
94
+ }
95
+
96
+ scale = {
97
+ 1: 'אלף', // thousand (singular)
98
+ 2: 'מיליון', // million
99
+ 3: 'מיליארד', // billion
100
+ 4: 'טריליון', // trillion
101
+ 5: 'קוודרליון', // quadrillion
102
+ 6: 'קווינטיליון' // quintillion
103
+ }
104
+
105
+ scalePlural = {
106
+ 1: 'אלפים', // thousands
107
+ 2: 'מיליונים', // millions
108
+ 3: 'מיליארדים', // billions
109
+ 4: 'טריליונים', // trillions
110
+ 5: 'קוודרליונים', // quadrillions
111
+ 6: 'קווינטיליונים' // quintillions
112
+ }
113
+
114
+ // Biblical Hebrew (masculine forms)
115
+ biblicalOnes = {
116
+ 1: 'אחד',
117
+ 2: 'שניים',
118
+ 3: 'שלשה',
119
+ 4: 'ארבעה',
120
+ 5: 'חמשה',
121
+ 6: 'ששה',
122
+ 7: 'שבעה',
123
+ 8: 'שמונה',
124
+ 9: 'תשעה'
125
+ }
126
+
127
+ biblicalTens = {
128
+ 0: 'עשרה',
129
+ 1: 'אחד עשר',
130
+ 2: 'שנים עשר',
131
+ 3: 'שלשה עשר',
132
+ 4: 'ארבעה עשר',
133
+ 5: 'חמשה עשר',
134
+ 6: 'ששה עשר',
135
+ 7: 'שבעה עשר',
136
+ 8: 'שמונה עשר',
137
+ 9: 'תשעה עשר'
138
+ }
139
+
140
+ biblicalTwenties = {
141
+ 2: 'עשרים',
142
+ 3: 'שלשים',
143
+ 4: 'ארבעים',
144
+ 5: 'חמישים',
145
+ 6: 'ששים',
146
+ 7: 'שבעים',
147
+ 8: 'שמונים',
148
+ 9: 'תשעים'
149
+ }
150
+
151
+ biblicalHundreds = {
152
+ 1: 'מאה',
153
+ 2: 'מאתיים',
154
+ 3: 'מאות'
155
+ }
156
+
157
+ biblicalThousands = {
158
+ 1: 'אלף',
159
+ 2: 'אלפיים',
160
+ 3: 'שלשת אלפים',
161
+ 4: 'ארבעת אלפים',
162
+ 5: 'חמשת אלפים',
163
+ 6: 'ששת אלפים',
164
+ 7: 'שבעת אלפים',
165
+ 8: 'שמונת אלפים',
166
+ 9: 'תשעת אלפים'
167
+ }
168
+
169
+ biblicalScale = {
170
+ 1: 'אלף',
171
+ 2: 'מיליון',
172
+ 3: 'מיליארד',
173
+ 4: 'טריליון',
174
+ 5: 'קוודרליון',
175
+ 6: 'קווינטיליון'
176
+ }
177
+
178
+ biblicalScalePlural = {
179
+ 1: 'אלפים',
180
+ 2: 'מיליונים',
181
+ 3: 'מיליארדים',
182
+ 4: 'טריליונים',
183
+ 5: 'קוודרליונים',
184
+ 6: 'קווינטיליונים'
185
+ }
186
+
187
+ /**
188
+ * Initializes the Hebrew converter with language-specific options.
189
+ *
190
+ * @param {HebrewOptions} [options={}] Configuration options.
191
+ */
192
+ constructor ({ and = 'ו', biblical = false, feminine = false } = {}) {
193
+ super({ feminine })
194
+
195
+ this.and = and
196
+ this.feminine = feminine
197
+
198
+ this.biblical = biblical
199
+ if (this.biblical) {
200
+ this.ones = this.biblicalOnes
201
+ this.tens = this.biblicalTens
202
+ this.twenties = this.biblicalTwenties
203
+ this.hundreds = this.biblicalHundreds
204
+ this.thousands = this.biblicalThousands
205
+ this.scale = this.biblicalScale
206
+ this.scalePlural = this.biblicalScalePlural
207
+ }
208
+ }
209
+
210
+ convertWholePart (number) {
211
+ if (number === 0n) {
212
+ return this.zeroWord
213
+ }
214
+ const words = []
215
+ const chunks = this.splitByX(number.toString(), 3)
216
+ let index = chunks.length
217
+ for (const x of chunks) {
218
+ index = index - 1
219
+ if (x === 0n) {
220
+ continue
221
+ }
222
+
223
+ const [n1, n2, n3] = this.getDigits(x)
224
+
225
+ if (index > 0) {
226
+ // For thousands and above, handle the full chunk value
227
+ const chunkWords = []
228
+ let hasHundreds = false
229
+
230
+ // Process hundreds in this chunk
231
+ if (n3 > 0n) {
232
+ hasHundreds = true
233
+ if (n3 <= 2n) {
234
+ chunkWords.push(this.hundreds[n3])
235
+ } else {
236
+ chunkWords.push(this.ones[n3] + ' ' + this.hundreds[3])
237
+ }
238
+ }
239
+
240
+ // Process tens in this chunk
241
+ if (n2 > 1n) {
242
+ // Add conjunction if there were hundreds before
243
+ const tensWord = this.twenties[n2]
244
+ chunkWords.push(hasHundreds ? this.and + tensWord : tensWord)
245
+ }
246
+
247
+ // Process ones in this chunk
248
+ if (n2 === 1n) {
249
+ // Add conjunction if there were hundreds before
250
+ const onesWord = this.tens[n1]
251
+ chunkWords.push(hasHundreds ? this.and + onesWord : onesWord)
252
+ } else if (n1 > 0n) {
253
+ // For "one million", "one billion", etc., don't add the word "one"
254
+ if (x === 1n && index > 1) {
255
+ // Skip adding "one" for millions/billions/etc.
256
+ } else if (x <= 9n && chunkWords.length === 0 && index === 1) {
257
+ // Use special forms for 1-9 thousand
258
+ chunkWords.push(this.thousands[n1])
259
+ } else {
260
+ const onesWord = this.ones[n1]
261
+ // Add conjunction if there were hundreds or tens before
262
+ chunkWords.push((hasHundreds || n2 > 0n) ? this.and + onesWord : onesWord)
263
+ }
264
+ }
265
+
266
+ // Add scale word (thousand, million, billion, etc.)
267
+ if (x > 9n || index > 1) {
268
+ // For numbers > 9 or higher scales, use appropriate scale word
269
+ if (x === 1n) {
270
+ // Singular form (e.g., "one thousand", "one million")
271
+ chunkWords.push(this.scale[index])
272
+ } else if (x === 2n && index === 1) {
273
+ // Special dual form for "two thousand" (already in thousands[2])
274
+ return [this.thousands[2], ...words].join(' ')
275
+ } else if (x === 2n) {
276
+ // For two million, two billion, etc. - use plural form
277
+ chunkWords.push(this.scalePlural[index])
278
+ } else if (index === 1) {
279
+ // For thousands (10+), always use singular "אלף"
280
+ chunkWords.push(this.scale[index])
281
+ } else {
282
+ // For millions/billions/etc. use plural form
283
+ chunkWords.push(this.scalePlural[index])
284
+ }
285
+ }
286
+
287
+ words.push(chunkWords.join(' '))
288
+ continue
289
+ }
290
+
291
+ if (n3 > 0n) {
292
+ if (n3 <= 2n) {
293
+ words.push(this.hundreds[n3])
294
+ } else {
295
+ words.push(this.ones[n3] + ' ' + this.hundreds[3])
296
+ }
297
+ }
298
+
299
+ if (n2 > 1n) {
300
+ words.push(this.twenties[n2])
301
+ }
302
+
303
+ if (n2 === 1n) {
304
+ words.push(this.tens[n1])
305
+ } else if (n1 > 0n) {
306
+ words.push(this.ones[n1])
307
+ }
308
+ }
309
+
310
+ if (words.length > 1) {
311
+ words[words.length - 1] = this.and + words.at(-1)
312
+ }
313
+
314
+ return words.join(' ')
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Converts a number to Hebrew cardinal (written) form.
320
+ *
321
+ * @param {number|string|bigint} value The number to convert.
322
+ * @param {HebrewOptions} [options={}] Configuration options.
323
+ * @returns {string} The number expressed in Hebrew words.
324
+ * @throws {TypeError} If value is NaN or invalid type.
325
+ * @throws {Error} If value is an invalid number string.
326
+ */
327
+ export default function convertToWords (value, options = {}) {
328
+ return new Hebrew(options).convertToWords(value)
329
+ }
@@ -0,0 +1,126 @@
1
+ import SouthAsianLanguage from '../classes/south-asian-language.js'
2
+
3
+ class Hindi extends SouthAsianLanguage {
4
+ negativeWord = 'माइनस'
5
+ decimalSeparatorWord = 'दशमलव'
6
+ zeroWord = 'शून्य'
7
+ hundredWord = 'सौ'
8
+ belowHundred = [
9
+ 'शून्य',
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
+ 'बत्तीस',
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
+ scaleWords = [
112
+ '',
113
+ 'हज़ार',
114
+ 'लाख',
115
+ 'करोड़',
116
+ 'अरब',
117
+ 'खरब',
118
+ 'नील',
119
+ 'पद्म',
120
+ 'शंख'
121
+ ]
122
+ }
123
+
124
+ export default function convertToWords (value, options = {}) {
125
+ return new Hindi(options).convertToWords(value)
126
+ }
@@ -0,0 +1,157 @@
1
+ import SlavicLanguage from '../classes/slavic-language.js'
2
+
3
+ /**
4
+ * @typedef {Object} SlavicOptions
5
+ * @property {boolean} [feminine=false] Use feminine forms for numbers.
6
+ */
7
+
8
+ /**
9
+ * Croatian language converter.
10
+ *
11
+ * Implements Croatian number words using the Slavic language pattern:
12
+ * - Croatian number words (jedan/jedna, dva/dvije, tri, četiri...)
13
+ * - Gender-aware forms (masculine/feminine)
14
+ * - Slavic three-form pluralization (tisuća/tisuće/tisuća)
15
+ * - Croatian-specific declension endings
16
+ *
17
+ * Key Features:
18
+ * - Three-form pluralization system shared across Slavic languages
19
+ * * Form 1 (singular): 1 (e.g., "tisuća")
20
+ * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., "tisuće")
21
+ * * Form 3 (many): all other numbers (e.g., "tisuća")
22
+ * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)
23
+ * - Large number handling via thousands[] array with indexed [singular, few, many] forms
24
+ * - Gender-specific number forms for 1 and 2 (masculine/feminine dual forms)
25
+ *
26
+ * Features:
27
+ * - Dual gender forms for 1 and 2 (jedan/jedna, dva/dvije)
28
+ * - Latin script orthography
29
+ * - Similar structure to Serbian
30
+ *
31
+ * Inherits from SlavicLanguage for complex pluralization algorithms.
32
+ */
33
+ export class Croatian extends SlavicLanguage {
34
+ negativeWord = 'minus'
35
+ decimalSeparatorWord = 'zarez'
36
+ zeroWord = 'nula'
37
+ ones = {
38
+ 1: ['jedan', 'jedna'],
39
+ 2: ['dva', 'dvije'],
40
+ 3: ['tri', 'tri'],
41
+ 4: ['četiri', 'četiri'],
42
+ 5: ['pet', 'pet'],
43
+ 6: ['šest', 'šest'],
44
+ 7: ['sedam', 'sedam'],
45
+ 8: ['osam', 'osam'],
46
+ 9: ['devet', 'devet']
47
+ }
48
+
49
+ tens = {
50
+ 0: 'deset',
51
+ 1: 'jedanaest',
52
+ 2: 'dvanaest',
53
+ 3: 'trinaest',
54
+ 4: 'četrnaest',
55
+ 5: 'petnaest',
56
+ 6: 'šesnaest',
57
+ 7: 'sedamnaest',
58
+ 8: 'osamnaest',
59
+ 9: 'devetnaest'
60
+ }
61
+
62
+ twenties = {
63
+ 2: 'dvadeset',
64
+ 3: 'trideset',
65
+ 4: 'četrdeset',
66
+ 5: 'pedeset',
67
+ 6: 'šezdeset',
68
+ 7: 'sedamdeset',
69
+ 8: 'osamdeset',
70
+ 9: 'devedeset'
71
+ }
72
+
73
+ hundreds = {
74
+ 1: 'sto',
75
+ 2: 'dvjesto',
76
+ 3: 'tristo',
77
+ 4: 'četiristo',
78
+ 5: 'petsto',
79
+ 6: 'šesto',
80
+ 7: 'sedamsto',
81
+ 8: 'osamsto',
82
+ 9: 'devetsto'
83
+ }
84
+
85
+ SCALE = {
86
+ 0: ['', '', '', false],
87
+ 1: ['tisuća', 'tisuće', 'tisuća', true], // 10 ^ 3
88
+ 2: ['milijun', 'milijuna', 'milijuna', false], // 10 ^ 6
89
+ 3: ['milijarda', 'milijarde', 'milijarda', false], // 10 ^ 9
90
+ 4: ['bilijun', 'bilijuna', 'bilijuna', false], // 10 ^ 12
91
+ 5: ['bilijarda', 'bilijarde', 'bilijarda', false], // 10 ^ 15
92
+ 6: ['trilijun', 'trilijuna', 'trilijuna', false], // 10 ^ 18
93
+ 7: ['trilijarda', 'trilijarde', 'trilijarda', false], // 10 ^ 21
94
+ 8: ['kvadrilijun', 'kvadrilijuna', 'kvadrilijuna', false], // 10 ^ 24
95
+ 9: ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda', false], // 10 ^ 27
96
+ 10: ['kvintilijun', 'kvintilijuna', 'kvintilijuna', false] // 10 ^ 30
97
+ }
98
+
99
+ pluralize (n, forms) {
100
+ const lastDigit = n % 10n
101
+ const lastTwoDigits = n % 100n
102
+
103
+ if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit === 1n) {
104
+ return forms[0]
105
+ }
106
+
107
+ if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit > 1n && lastDigit < 5n) {
108
+ return forms[1]
109
+ }
110
+
111
+ return forms[2]
112
+ }
113
+
114
+ convertWholePart (number) {
115
+ if (number === 0n) {
116
+ return this.zeroWord
117
+ }
118
+ const words = []
119
+ const chunks = this.splitByX(number.toString(), 3)
120
+ let index = chunks.length
121
+ for (const x of chunks) {
122
+ index = index - 1
123
+ const [n1, n2, n3] = this.getDigits(x)
124
+ if (n3 > 0n) {
125
+ words.push(this.hundreds[n3])
126
+ }
127
+ if (n2 > 1n) {
128
+ words.push(this.twenties[n2])
129
+ }
130
+ if (n2 === 1n) {
131
+ words.push(this.tens[n1])
132
+ } else if (n1 > 0n) {
133
+ const isFeminine = (this.feminine || this.SCALE[index][3])
134
+ const genderIndex = isFeminine ? 1 : 0
135
+ words.push(this.ones[n1][genderIndex])
136
+ }
137
+ if ((index > 0) && (x !== 0n)) {
138
+ words.push(this.pluralize(x, this.SCALE[index]))
139
+ }
140
+ }
141
+ return words.join(' ')
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Converts a number to Croatian cardinal (written) form.
147
+ *
148
+ * @param {number|string|bigint} value The number to convert.
149
+ * @param {Object} [options={}] Configuration options.
150
+ * @param {boolean} [options.feminine=false] Use feminine forms for numbers.
151
+ * @returns {string} The number expressed in Croatian words.
152
+ * @throws {TypeError} If value is NaN or invalid type.
153
+ * @throws {Error} If value is an invalid number string.
154
+ */
155
+ export default function convertToWords (value, options = {}) {
156
+ return new Croatian(options).convertToWords(value)
157
+ }