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.
Files changed (322) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +317 -59
  3. package/dist/ArabicConverter.js +3 -0
  4. package/dist/ArabicConverter.js.map +1 -0
  5. package/dist/AzerbaijaniConverter.js +3 -0
  6. package/dist/AzerbaijaniConverter.js.map +1 -0
  7. package/dist/BanglaConverter.js +3 -0
  8. package/dist/BanglaConverter.js.map +1 -0
  9. package/dist/BiblicalHebrewConverter.js +3 -0
  10. package/dist/BiblicalHebrewConverter.js.map +1 -0
  11. package/dist/CroatianConverter.js +3 -0
  12. package/dist/CroatianConverter.js.map +1 -0
  13. package/dist/CzechConverter.js +3 -0
  14. package/dist/CzechConverter.js.map +1 -0
  15. package/dist/DanishConverter.js +3 -0
  16. package/dist/DanishConverter.js.map +1 -0
  17. package/dist/DutchConverter.js +3 -0
  18. package/dist/DutchConverter.js.map +1 -0
  19. package/dist/EnglishConverter.js +3 -0
  20. package/dist/EnglishConverter.js.map +1 -0
  21. package/dist/FilipinoConverter.js +3 -0
  22. package/dist/FilipinoConverter.js.map +1 -0
  23. package/dist/FrenchBelgiumConverter.js +3 -0
  24. package/dist/FrenchBelgiumConverter.js.map +1 -0
  25. package/dist/FrenchConverter.js +3 -0
  26. package/dist/FrenchConverter.js.map +1 -0
  27. package/dist/GermanConverter.js +3 -0
  28. package/dist/GermanConverter.js.map +1 -0
  29. package/dist/GreekConverter.js +3 -0
  30. package/dist/GreekConverter.js.map +1 -0
  31. package/dist/GujaratiConverter.js +3 -0
  32. package/dist/GujaratiConverter.js.map +1 -0
  33. package/dist/HebrewConverter.js +3 -0
  34. package/dist/HebrewConverter.js.map +1 -0
  35. package/dist/HindiConverter.js +3 -0
  36. package/dist/HindiConverter.js.map +1 -0
  37. package/dist/HungarianConverter.js +3 -0
  38. package/dist/HungarianConverter.js.map +1 -0
  39. package/dist/IndonesianConverter.js +3 -0
  40. package/dist/IndonesianConverter.js.map +1 -0
  41. package/dist/ItalianConverter.js +3 -0
  42. package/dist/ItalianConverter.js.map +1 -0
  43. package/dist/JapaneseConverter.js +3 -0
  44. package/dist/JapaneseConverter.js.map +1 -0
  45. package/dist/KannadaConverter.js +3 -0
  46. package/dist/KannadaConverter.js.map +1 -0
  47. package/dist/KoreanConverter.js +3 -0
  48. package/dist/KoreanConverter.js.map +1 -0
  49. package/dist/LatvianConverter.js +3 -0
  50. package/dist/LatvianConverter.js.map +1 -0
  51. package/dist/LithuanianConverter.js +3 -0
  52. package/dist/LithuanianConverter.js.map +1 -0
  53. package/dist/MalayConverter.js +3 -0
  54. package/dist/MalayConverter.js.map +1 -0
  55. package/dist/MarathiConverter.js +3 -0
  56. package/dist/MarathiConverter.js.map +1 -0
  57. package/dist/NorwegianBokmalConverter.js +3 -0
  58. package/dist/NorwegianBokmalConverter.js.map +1 -0
  59. package/dist/PersianConverter.js +3 -0
  60. package/dist/PersianConverter.js.map +1 -0
  61. package/dist/PolishConverter.js +3 -0
  62. package/dist/PolishConverter.js.map +1 -0
  63. package/dist/PortugueseConverter.js +3 -0
  64. package/dist/PortugueseConverter.js.map +1 -0
  65. package/dist/PunjabiConverter.js +3 -0
  66. package/dist/PunjabiConverter.js.map +1 -0
  67. package/dist/RomanianConverter.js +3 -0
  68. package/dist/RomanianConverter.js.map +1 -0
  69. package/dist/RussianConverter.js +3 -0
  70. package/dist/RussianConverter.js.map +1 -0
  71. package/dist/SerbianCyrillicConverter.js +3 -0
  72. package/dist/SerbianCyrillicConverter.js.map +1 -0
  73. package/dist/SerbianLatinConverter.js +3 -0
  74. package/dist/SerbianLatinConverter.js.map +1 -0
  75. package/dist/SimplifiedChineseConverter.js +3 -0
  76. package/dist/SimplifiedChineseConverter.js.map +1 -0
  77. package/dist/SpanishConverter.js +3 -0
  78. package/dist/SpanishConverter.js.map +1 -0
  79. package/dist/SwahiliConverter.js +3 -0
  80. package/dist/SwahiliConverter.js.map +1 -0
  81. package/dist/SwedishConverter.js +3 -0
  82. package/dist/SwedishConverter.js.map +1 -0
  83. package/dist/TamilConverter.js +3 -0
  84. package/dist/TamilConverter.js.map +1 -0
  85. package/dist/TeluguConverter.js +3 -0
  86. package/dist/TeluguConverter.js.map +1 -0
  87. package/dist/ThaiConverter.js +3 -0
  88. package/dist/ThaiConverter.js.map +1 -0
  89. package/dist/TraditionalChineseConverter.js +3 -0
  90. package/dist/TraditionalChineseConverter.js.map +1 -0
  91. package/dist/TurkishConverter.js +3 -0
  92. package/dist/TurkishConverter.js.map +1 -0
  93. package/dist/UkrainianConverter.js +3 -0
  94. package/dist/UkrainianConverter.js.map +1 -0
  95. package/dist/UrduConverter.js +3 -0
  96. package/dist/UrduConverter.js.map +1 -0
  97. package/dist/VietnameseConverter.js +3 -0
  98. package/dist/VietnameseConverter.js.map +1 -0
  99. package/dist/n2words.js +3 -2
  100. package/dist/n2words.js.map +1 -1
  101. package/lib/classes/abstract-language.d.ts +158 -34
  102. package/lib/classes/abstract-language.js +223 -115
  103. package/lib/classes/greedy-scale-language.d.ts +109 -0
  104. package/lib/classes/greedy-scale-language.js +201 -0
  105. package/lib/classes/slavic-language.d.ts +148 -0
  106. package/lib/classes/slavic-language.js +281 -0
  107. package/lib/classes/south-asian-language.d.ts +70 -0
  108. package/lib/classes/south-asian-language.js +154 -0
  109. package/lib/classes/turkic-language.d.ts +26 -0
  110. package/lib/classes/turkic-language.js +59 -0
  111. package/lib/languages/ar.d.ts +30 -0
  112. package/lib/languages/ar.js +159 -0
  113. package/lib/languages/az.d.ts +12 -0
  114. package/lib/languages/az.js +42 -0
  115. package/lib/languages/bn.d.ts +11 -0
  116. package/lib/languages/bn.js +131 -0
  117. package/lib/languages/cs.d.ts +88 -0
  118. package/lib/languages/cs.js +143 -0
  119. package/lib/languages/da.d.ts +15 -0
  120. package/lib/languages/da.js +120 -0
  121. package/lib/languages/de.d.ts +14 -0
  122. package/lib/languages/de.js +101 -0
  123. package/lib/languages/el.d.ts +14 -0
  124. package/lib/languages/el.js +90 -0
  125. package/lib/languages/en.d.ts +16 -0
  126. package/lib/languages/en.js +86 -0
  127. package/lib/languages/es.d.ts +15 -0
  128. package/lib/languages/es.js +121 -0
  129. package/lib/languages/fa.d.ts +47 -0
  130. package/lib/languages/fa.js +144 -0
  131. package/lib/languages/fil.d.ts +16 -0
  132. package/lib/languages/fil.js +121 -0
  133. package/lib/languages/fr-BE.d.ts +11 -0
  134. package/lib/languages/fr-BE.js +25 -0
  135. package/lib/languages/fr.d.ts +15 -0
  136. package/lib/languages/fr.js +106 -0
  137. package/lib/languages/gu.d.ts +11 -0
  138. package/lib/languages/gu.js +132 -0
  139. package/lib/languages/hbo.d.ts +113 -0
  140. package/lib/languages/hbo.js +251 -0
  141. package/lib/languages/he.d.ts +80 -0
  142. package/lib/languages/he.js +206 -0
  143. package/lib/languages/hi.d.ts +11 -0
  144. package/lib/languages/hi.js +131 -0
  145. package/lib/languages/hr.d.ts +80 -0
  146. package/lib/languages/hr.js +113 -0
  147. package/lib/languages/hu.d.ts +22 -0
  148. package/lib/languages/hu.js +137 -0
  149. package/lib/languages/id.d.ts +37 -0
  150. package/lib/languages/id.js +159 -0
  151. package/lib/languages/it.d.ts +37 -0
  152. package/lib/languages/it.js +132 -0
  153. package/lib/languages/ja.d.ts +17 -0
  154. package/lib/languages/ja.js +137 -0
  155. package/lib/languages/kn.d.ts +11 -0
  156. package/lib/languages/kn.js +42 -0
  157. package/lib/languages/ko.d.ts +14 -0
  158. package/lib/languages/ko.js +55 -0
  159. package/lib/{i18n/pl.d.ts → languages/lt.d.ts} +18 -15
  160. package/lib/languages/lt.js +136 -0
  161. package/lib/{i18n/lt.d.ts → languages/lv.d.ts} +16 -14
  162. package/lib/languages/lv.js +130 -0
  163. package/lib/languages/mr.d.ts +11 -0
  164. package/lib/languages/mr.js +132 -0
  165. package/lib/languages/ms.d.ts +31 -0
  166. package/lib/languages/ms.js +150 -0
  167. package/lib/languages/nb.d.ts +12 -0
  168. package/lib/languages/nb.js +100 -0
  169. package/lib/languages/nl.d.ts +16 -0
  170. package/lib/languages/nl.js +155 -0
  171. package/lib/languages/pa.d.ts +11 -0
  172. package/lib/languages/pa.js +131 -0
  173. package/lib/{i18n/uk.d.ts → languages/pl.d.ts} +16 -14
  174. package/lib/languages/pl.js +110 -0
  175. package/lib/languages/pt.d.ts +29 -0
  176. package/lib/languages/pt.js +112 -0
  177. package/lib/languages/ro.d.ts +158 -0
  178. package/lib/languages/ro.js +273 -0
  179. package/lib/languages/ru.d.ts +85 -0
  180. package/lib/languages/ru.js +96 -0
  181. package/lib/languages/sr-Cyrl.d.ts +80 -0
  182. package/lib/languages/sr-Cyrl.js +113 -0
  183. package/lib/{i18n/cz.d.ts → languages/sr-Latn.d.ts} +26 -14
  184. package/lib/languages/sr-Latn.js +113 -0
  185. package/lib/languages/sv.d.ts +14 -0
  186. package/lib/languages/sv.js +90 -0
  187. package/lib/languages/sw.d.ts +39 -0
  188. package/lib/languages/sw.js +126 -0
  189. package/lib/languages/ta.d.ts +20 -0
  190. package/lib/languages/ta.js +226 -0
  191. package/lib/languages/te.d.ts +22 -0
  192. package/lib/languages/te.js +219 -0
  193. package/lib/languages/th.d.ts +17 -0
  194. package/lib/languages/th.js +117 -0
  195. package/lib/languages/tr.d.ts +12 -0
  196. package/lib/languages/tr.js +56 -0
  197. package/lib/languages/uk.d.ts +85 -0
  198. package/lib/{i18n → languages}/uk.js +33 -32
  199. package/lib/languages/ur.d.ts +11 -0
  200. package/lib/languages/ur.js +131 -0
  201. package/lib/{i18n → languages}/vi.d.ts +15 -13
  202. package/lib/languages/vi.js +147 -0
  203. package/lib/languages/zh-Hans.d.ts +21 -0
  204. package/lib/languages/zh-Hans.js +111 -0
  205. package/lib/languages/zh-Hant.d.ts +21 -0
  206. package/lib/languages/zh-Hant.js +111 -0
  207. package/lib/n2words.d.ts +207 -7
  208. package/lib/n2words.js +535 -81
  209. package/package.json +126 -79
  210. package/dist/ar.js +0 -2
  211. package/dist/ar.js.map +0 -1
  212. package/dist/az.js +0 -2
  213. package/dist/az.js.map +0 -1
  214. package/dist/cz.js +0 -2
  215. package/dist/cz.js.map +0 -1
  216. package/dist/de.js +0 -2
  217. package/dist/de.js.map +0 -1
  218. package/dist/dk.js +0 -2
  219. package/dist/dk.js.map +0 -1
  220. package/dist/en.js +0 -2
  221. package/dist/en.js.map +0 -1
  222. package/dist/es.js +0 -2
  223. package/dist/es.js.map +0 -1
  224. package/dist/fa.js +0 -2
  225. package/dist/fa.js.map +0 -1
  226. package/dist/fr-BE.js +0 -2
  227. package/dist/fr-BE.js.map +0 -1
  228. package/dist/fr.js +0 -2
  229. package/dist/fr.js.map +0 -1
  230. package/dist/he.js +0 -2
  231. package/dist/he.js.map +0 -1
  232. package/dist/hr.js +0 -2
  233. package/dist/hr.js.map +0 -1
  234. package/dist/hu.js +0 -2
  235. package/dist/hu.js.map +0 -1
  236. package/dist/id.js +0 -2
  237. package/dist/id.js.map +0 -1
  238. package/dist/it.js +0 -2
  239. package/dist/it.js.map +0 -1
  240. package/dist/ko.js +0 -2
  241. package/dist/ko.js.map +0 -1
  242. package/dist/lt.js +0 -2
  243. package/dist/lt.js.map +0 -1
  244. package/dist/lv.js +0 -2
  245. package/dist/lv.js.map +0 -1
  246. package/dist/n2words.d.ts +0 -2
  247. package/dist/nl.js +0 -2
  248. package/dist/nl.js.map +0 -1
  249. package/dist/no.js +0 -2
  250. package/dist/no.js.map +0 -1
  251. package/dist/pl.js +0 -2
  252. package/dist/pl.js.map +0 -1
  253. package/dist/pt.js +0 -2
  254. package/dist/pt.js.map +0 -1
  255. package/dist/ro.js +0 -2
  256. package/dist/ro.js.map +0 -1
  257. package/dist/ru.js +0 -2
  258. package/dist/ru.js.map +0 -1
  259. package/dist/sr.js +0 -2
  260. package/dist/sr.js.map +0 -1
  261. package/dist/tr.js +0 -2
  262. package/dist/tr.js.map +0 -1
  263. package/dist/uk.js +0 -2
  264. package/dist/uk.js.map +0 -1
  265. package/dist/vi.js +0 -2
  266. package/dist/vi.js.map +0 -1
  267. package/dist/zh.js +0 -2
  268. package/dist/zh.js.map +0 -1
  269. package/lib/classes/base-language.d.ts +0 -58
  270. package/lib/classes/base-language.js +0 -172
  271. package/lib/i18n/ar.d.ts +0 -41
  272. package/lib/i18n/ar.js +0 -209
  273. package/lib/i18n/az.d.ts +0 -15
  274. package/lib/i18n/az.js +0 -66
  275. package/lib/i18n/cz.js +0 -135
  276. package/lib/i18n/de.d.ts +0 -17
  277. package/lib/i18n/de.js +0 -103
  278. package/lib/i18n/dk.d.ts +0 -14
  279. package/lib/i18n/dk.js +0 -110
  280. package/lib/i18n/en.d.ts +0 -22
  281. package/lib/i18n/en.js +0 -86
  282. package/lib/i18n/es.d.ts +0 -16
  283. package/lib/i18n/es.js +0 -110
  284. package/lib/i18n/fa.d.ts +0 -54
  285. package/lib/i18n/fa.js +0 -106
  286. package/lib/i18n/fr-BE.d.ts +0 -11
  287. package/lib/i18n/fr-BE.js +0 -20
  288. package/lib/i18n/fr.d.ts +0 -15
  289. package/lib/i18n/fr.js +0 -99
  290. package/lib/i18n/he.d.ts +0 -61
  291. package/lib/i18n/he.js +0 -132
  292. package/lib/i18n/hr.d.ts +0 -68
  293. package/lib/i18n/hr.js +0 -129
  294. package/lib/i18n/hu.d.ts +0 -17
  295. package/lib/i18n/hu.js +0 -135
  296. package/lib/i18n/id.d.ts +0 -43
  297. package/lib/i18n/id.js +0 -156
  298. package/lib/i18n/it.d.ts +0 -29
  299. package/lib/i18n/it.js +0 -137
  300. package/lib/i18n/ko.d.ts +0 -15
  301. package/lib/i18n/ko.js +0 -56
  302. package/lib/i18n/lt.js +0 -138
  303. package/lib/i18n/lv.d.ts +0 -57
  304. package/lib/i18n/lv.js +0 -120
  305. package/lib/i18n/nl.d.ts +0 -20
  306. package/lib/i18n/nl.js +0 -125
  307. package/lib/i18n/no.d.ts +0 -15
  308. package/lib/i18n/no.js +0 -77
  309. package/lib/i18n/pl.js +0 -126
  310. package/lib/i18n/pt.d.ts +0 -26
  311. package/lib/i18n/pt.js +0 -118
  312. package/lib/i18n/ro.d.ts +0 -109
  313. package/lib/i18n/ro.js +0 -360
  314. package/lib/i18n/ru.d.ts +0 -30
  315. package/lib/i18n/ru.js +0 -198
  316. package/lib/i18n/sr.d.ts +0 -56
  317. package/lib/i18n/sr.js +0 -127
  318. package/lib/i18n/tr.d.ts +0 -15
  319. package/lib/i18n/tr.js +0 -64
  320. package/lib/i18n/vi.js +0 -151
  321. package/lib/i18n/zh.d.ts +0 -18
  322. package/lib/i18n/zh.js +0 -78
package/lib/i18n/ro.js DELETED
@@ -1,360 +0,0 @@
1
- import AbstractLanguage from '../classes/abstract-language.js';
2
-
3
- export class N2WordsRO extends AbstractLanguage {
4
- /** @type {boolean} */
5
- feminine;
6
-
7
- /** @type {object} */
8
- ones = {
9
- 1: 'unu',
10
- 2: 'doi',
11
- 3: 'trei',
12
- 4: 'patru',
13
- 5: 'cinci',
14
- 6: 'șase',
15
- 7: 'șapte',
16
- 8: 'opt',
17
- 9: 'nouă'
18
- };
19
-
20
- /** @type {object} */
21
- onesFeminine = {
22
- 1: 'una',
23
- 2: 'două',
24
- 3: 'trei',
25
- 4: 'patru',
26
- 5: 'cinci',
27
- 6: 'șase',
28
- 7: 'șapte',
29
- 8: 'opt',
30
- 9: 'nouă'
31
- };
32
-
33
- /** @type {object} */
34
- tens = {
35
- 0: 'zece',
36
- 1: 'unsprezece',
37
- 2: 'douăsprezece',
38
- 3: 'treisprezece',
39
- 4: 'paisprezece',
40
- 5: 'cincisprezece',
41
- 6: 'șaisprezece',
42
- 7: 'șaptesprezece',
43
- 8: 'optsprezece',
44
- 9: 'nouăsprezece'
45
- };
46
-
47
- /** @type {object} */
48
- tensMasculine = {
49
- 0: 'zece',
50
- 1: 'unsprezece',
51
- 2: 'doisprezece',
52
- 3: 'treisprezece',
53
- 4: 'paisprezece',
54
- 5: 'cincisprezece',
55
- 6: 'șaisprezece',
56
- 7: 'șaptesprezece',
57
- 8: 'optsprezece',
58
- 9: 'nouăsprezece'
59
- };
60
-
61
- /** @type {object} */
62
- twenties = {
63
- 2: 'douăzeci',
64
- 3: 'treizeci',
65
- 4: 'patruzeci',
66
- 5: 'cincizeci',
67
- 6: 'șaizeci',
68
- 7: 'șaptezeci',
69
- 8: 'optzeci',
70
- 9: 'nouăzeci'
71
- };
72
-
73
- /** @type {object} */
74
- hundreds = {
75
- 1: 'o sută',
76
- 2: 'două sute',
77
- 3: 'trei sute',
78
- 4: 'patru sute',
79
- 5: 'cinci sute',
80
- 6: 'șase sute',
81
- 7: 'șapte sute',
82
- 8: 'opt sute',
83
- 9: 'nouă sute'
84
- };
85
-
86
- /**
87
- * Romanian big units.
88
- * For each power group we keep: singular, plural, feminineUnits?, needsDe?
89
- * - 10^3: mie/mii (feminine units in chunk; "de" for chunk >= 20)
90
- * - 10^6: milion/milioane ("de" for chunk >= 20)
91
- * - 10^9: miliard/miliarde ("de" for chunk >= 20)
92
- */
93
- thousands = {
94
- 1: { singular: 'mie', plural: 'mii', feminine: true, needsDe: true }, // 10^3
95
- 2: { singular: 'milion', plural: 'milioane', feminine: false, needsDe: true }, // 10^6
96
- 3: { singular: 'miliard', plural: 'miliarde', feminine: false, needsDe: true },// 10^9
97
- 4: { singular: 'trilion', plural: 'trilioane', feminine: false, needsDe: true }, // 10^12
98
- 5: { singular: 'cvadrilion', plural: 'cvadrilioane', feminine: false, needsDe: true }, // 10^15
99
- 6: { singular: 'cvintilion', plural: 'cvintilioane', feminine: false, needsDe: true }, // 10^18
100
- 7: { singular: 'sextilion', plural: 'sextilioane', feminine: false, needsDe: true }, // 10^21
101
- 8: { singular: 'septilion', plural: 'septilioane', feminine: false, needsDe: true }, // 10^24
102
- };
103
-
104
- constructor(options) {
105
- options = Object.assign({
106
- negativeWord: 'minus',
107
- separatorWord: 'virgulă',
108
- zero: 'zero',
109
- feminine: false
110
- }, options);
111
-
112
- super(options);
113
- this.feminine = options.feminine;
114
- }
115
-
116
- toCardinal(number) {
117
- if (number == 0) {
118
- return this.zero;
119
- }
120
-
121
- const words = [];
122
- const chunks = this.splitByX(number.toString(), 3);
123
- let index = chunks.length;
124
-
125
- for (const x of chunks) {
126
- let onesMap = [];
127
- index = index - 1;
128
-
129
- if (x == 0n) continue;
130
-
131
- const [n1, n2, n3] = this.getDigits(x); // units, tens, hundreds (as BigInt)
132
-
133
- // hundreds (only for the last group, not for thousands)
134
- if (n3 > 0n && index === 0) {
135
- words.push(this.hundreds[Number(n3)]);
136
- }
137
-
138
- // tens & teens (only for the last group, not for thousands)
139
- if (index === 0) {
140
- if (n2 > 1n) {
141
- words.push(this.twenties[Number(n2)]);
142
- }
143
-
144
- if (n2 == 1n) {
145
- words.push(this.tens[Number(n1)]);
146
- } else if (n1 > 0n) {
147
- // pick masculine/feminine units (only for the last group, not for thousands)
148
- const feminineUnits = this.feminine && index === 0;
149
- onesMap = feminineUnits ? this.onesFeminine : this.ones;
150
-
151
- // if there is a twenty/treizeci/etc AND ones > 0 → add "și"
152
- if (n2 > 1n) words.push('și');
153
- words.push(onesMap[Number(n1)]);
154
- }
155
- }
156
-
157
- // big unit name (mie/mii, milion/milioane, …)
158
- if (index > 0) {
159
- const form = this.thousands[index];
160
- if (form) {
161
- words.push(this.romanianPluralize(x, form));
162
- } else {
163
- // For very large numbers beyond our defined units, just spell out the number
164
- words.push(this.spellUnder1000(Number(x), true));
165
- }
166
- }
167
- }
168
-
169
- return words.join(' ').replaceAll(/\s+/g, ' ').trim();
170
- }
171
-
172
- /**
173
- * Split numeric string into BigInt groups of size x from left to right.
174
- * @param {string} n - The numeric string to split
175
- * @param {number} x - The size of each group
176
- * @returns {bigint[]} Array of BigInt groups
177
- */
178
- splitByX(n, x) {
179
- const results = [];
180
- const l = n.length;
181
- let result;
182
-
183
- if (l > x) {
184
- const start = l % x;
185
- if (start > 0) {
186
- result = n.slice(0, start);
187
- results.push(BigInt(result));
188
- }
189
- for (let index = start; index < l; index += x) {
190
- result = n.slice(index, index + x);
191
- results.push(BigInt(result));
192
- }
193
- } else {
194
- results.push(BigInt(n));
195
- }
196
- return results;
197
- }
198
-
199
- getDigits(value) {
200
- // returns [units, tens, hundreds] as BigInt
201
- const stringValue = value.toString().padStart(3, '0').slice(-3);
202
- const a = [...stringValue].toReversed();
203
- return a.map(BigInt);
204
- }
205
-
206
- /**
207
- * Romanian pluralization & "de" rule for big units.
208
- * - 1 → singular with article ("o mie", "un milion", "un miliard", …)
209
- * - otherwise → spell chunk + (optional "de") + plural
210
- * "de" is inserted when chunk >= 20 (e.g., "douăzeci de mii/milioane/miliarde").
211
- * @param {bigint} chunk - The chunk value
212
- * @param {object} form - The form object with singular, plural, feminine, needsDe properties
213
- * @returns {string} The pluralized form
214
- */
215
- romanianPluralize(chunk, form) {
216
- const n = Number(chunk);
217
-
218
- if (n === 1) {
219
- // article differs for feminine "mie" (o mie) vs the rest (un milion/miliard…)
220
- const article = form.feminine ? 'o' : 'un';
221
- return `${article} ${form.singular}`;
222
- }
223
-
224
- // For 21 with big units, use feminine "una" with plural nouns
225
- if (n === 21 && form.needsDe) {
226
- return `douăzeci și una de ${form.plural}`;
227
- }
228
-
229
- // spell the chunk itself (use feminine units for big numbers)
230
- const words = this.spellUnder1000(n, true);
231
-
232
- // "de" after >= 20 (covers 20, 21, 100, 101, 999, etc.)
233
- const needsDe = form.needsDe && n >= 20;
234
- const de = needsDe ? ' de ' : ' ';
235
-
236
- return `${words}${de}${form.plural}`;
237
- }
238
-
239
- spellUnder100(n, feminineUnits = false) {
240
- if (n < 10) {
241
- return (feminineUnits ? this.onesFeminine : this.ones)[n];
242
- }
243
- if (n < 20) {
244
- return this.tens[n - 10];
245
- }
246
- const t = Math.floor(n / 10);
247
- const u = n % 10;
248
- return u
249
- ? `${this.twenties[t]} și ${(feminineUnits ? this.onesFeminine : this.ones)[u]}`
250
- : this.twenties[t];
251
- }
252
-
253
- spellUnder1000(n, feminineUnits = false) {
254
- if (n < 100) return this.spellUnder100(n, feminineUnits);
255
- const h = Math.floor(n / 100);
256
- const r = n % 100;
257
- const hundredWords = this.hundreds[h];
258
- if (!r) return hundredWords;
259
- // Standard readable form: "o sută unu" (for units) or "o sută cincizeci" (for tens)
260
- const separator = r < 20 ? ' ' : ' ';
261
- return `${hundredWords}${separator}${this.spellUnder100(r, feminineUnits)}`;
262
- }
263
-
264
- /**
265
- * Override decimalToCardinal to use masculine forms for decimal places
266
- * @param {string} decimal Decimal string to convert
267
- * @returns {string} Value in written format
268
- */
269
- decimalToCardinal(decimal) {
270
- const words = [];
271
-
272
- // Split decimal string into an array of characters
273
- const chars = [...decimal];
274
-
275
- // Loop through characters adding leading zeros to words array
276
- let index = 0;
277
- while (index < chars.length && chars[index] === '0') {
278
- words.push(this.zero);
279
- index++;
280
- }
281
-
282
- // Prevent further processing if entire string was zeros
283
- if (index === chars.length) {
284
- return words;
285
- }
286
-
287
- // Convert and add remaining using masculine forms for decimal places
288
- const decimalNumber = BigInt(decimal);
289
- const masculineWords = this.toCardinalWithMasculine(decimalNumber);
290
- return [...words, masculineWords];
291
- }
292
-
293
- /**
294
- * Convert number to cardinal form using masculine units
295
- * @param {bigint} number Number to convert
296
- * @returns {string} Value in written format
297
- */
298
- toCardinalWithMasculine(number) {
299
- if (number == 0) {
300
- return this.zero;
301
- }
302
-
303
- const words = [];
304
- const chunks = this.splitByX(number.toString(), 3);
305
- let index = chunks.length;
306
-
307
- for (const x of chunks) {
308
- let onesMap = [];
309
- index = index - 1;
310
-
311
- if (x == 0n) continue;
312
-
313
- const [n1, n2, n3] = this.getDigits(x); // units, tens, hundreds (as BigInt)
314
-
315
- // hundreds
316
- if (n3 > 0n) {
317
- words.push(this.hundreds[Number(n3)]);
318
- }
319
-
320
- // tens & teens
321
- if (n2 > 1n) {
322
- words.push(this.twenties[Number(n2)]);
323
- }
324
-
325
- if (n2 == 1n) {
326
- words.push(this.tensMasculine[Number(n1)]);
327
- } else if (n1 > 0n) {
328
- // Always use masculine units for decimal places
329
- onesMap = this.ones;
330
-
331
- // if there is a twenty/treizeci/etc AND ones > 0 → add "și"
332
- if (n2 > 1n) words.push('și');
333
- words.push(onesMap[Number(n1)]);
334
- }
335
-
336
- // big unit name (mie/mii, milion/milioane, …)
337
- if (index > 0) {
338
- const form = this.thousands[index];
339
- if (form) {
340
- words.push(this.romanianPluralize(x, form));
341
- } else {
342
- // For very large numbers beyond our defined units, just spell out the number
343
- words.push(this.spellUnder1000(Number(x), false));
344
- }
345
- }
346
- }
347
-
348
- return words.join(' ').replaceAll(/\s+/g, ' ').trim();
349
- }
350
- }
351
-
352
- /**
353
- * Converts a value to cardinal (written) form.
354
- * @param {number|string|bigint} value Number to be convert.
355
- * @param {object} [options] Options for class.
356
- * @returns {string} Value in cardinal (written) format.
357
- */
358
- export default function floatToCardinal(value, options = {}) {
359
- return new N2WordsRO(options).floatToCardinal(value);
360
- }
package/lib/i18n/ru.d.ts DELETED
@@ -1,30 +0,0 @@
1
- /**
2
- * Converts a value to cardinal (written) form.
3
- * @param {number|string|bigint} value Number to be convert.
4
- * @param {object} [options] Options for class.
5
- * @returns {string} Value in cardinal (written) format.
6
- * @throws {Error} Value cannot be invalid.
7
- */
8
- export default function floatToCardinal(value: number | string | bigint, options?: object): string;
9
- export class N2WordsRU extends AbstractLanguage {
10
- constructor(options: any);
11
- /** @type {boolean} */
12
- feminine: boolean;
13
- /** @type {object} */
14
- ones: object;
15
- /** @type {object} */
16
- onesFeminine: object;
17
- /** @type {object} */
18
- tens: object;
19
- /** @type {object} */
20
- twenties: object;
21
- /** @type {object} */
22
- hundreds: object;
23
- /** @type {object} */
24
- thousands: object;
25
- toCardinal(number: any): string;
26
- splitByX(n: any, x: any): bigint[];
27
- getDigits(value: any): any;
28
- pluralize(n: any, forms: any): any;
29
- }
30
- import AbstractLanguage from '../classes/abstract-language.js';
package/lib/i18n/ru.js DELETED
@@ -1,198 +0,0 @@
1
- import AbstractLanguage from '../classes/abstract-language.js';
2
-
3
- export class N2WordsRU extends AbstractLanguage {
4
- /** @type {boolean} */
5
- feminine;
6
-
7
- /** @type {object} */
8
- ones = {
9
- 1: 'один',
10
- 2: 'два',
11
- 3: 'три',
12
- 4: 'четыре',
13
- 5: 'пять',
14
- 6: 'шесть',
15
- 7: 'семь',
16
- 8: 'восемь',
17
- 9: 'девять'
18
- };
19
-
20
- /** @type {object} */
21
- onesFeminine = {
22
- 1: 'одна',
23
- 2: 'две',
24
- 3: 'три',
25
- 4: 'четыре',
26
- 5: 'пять',
27
- 6: 'шесть',
28
- 7: 'семь',
29
- 8: 'восемь',
30
- 9: 'девять'
31
- };
32
-
33
- /** @type {object} */
34
- tens = {
35
- 0: 'десять',
36
- 1: 'одиннадцать',
37
- 2: 'двенадцать',
38
- 3: 'тринадцать',
39
- 4: 'четырнадцать',
40
- 5: 'пятнадцать',
41
- 6: 'шестнадцать',
42
- 7: 'семнадцать',
43
- 8: 'восемнадцать',
44
- 9: 'девятнадцать'
45
- };
46
-
47
- /** @type {object} */
48
- twenties = {
49
- 2: 'двадцать',
50
- 3: 'тридцать',
51
- 4: 'сорок',
52
- 5: 'пятьдесят',
53
- 6: 'шестьдесят',
54
- 7: 'семьдесят',
55
- 8: 'восемьдесят',
56
- 9: 'девяносто'
57
- };
58
-
59
- /** @type {object} */
60
- hundreds = {
61
- 1: 'сто',
62
- 2: 'двести',
63
- 3: 'триста',
64
- 4: 'четыреста',
65
- 5: 'пятьсот',
66
- 6: 'шестьсот',
67
- 7: 'семьсот',
68
- 8: 'восемьсот',
69
- 9: 'девятьсот'
70
- };
71
-
72
- /** @type {object} */
73
- thousands = {
74
- 1: ['тысяча', 'тысячи', 'тысяч'], // 10^ 3
75
- 2: ['миллион', 'миллиона', 'миллионов'], // 10^ 6
76
- 3: ['миллиард', 'миллиарда', 'миллиардов'], // 10^ 9
77
- 4: ['триллион', 'триллиона', 'триллионов'], // 10^ 12
78
- 5: ['квадриллион', 'квадриллиона', 'квадриллионов'], // 10^ 15
79
- 6: ['квинтиллион', 'квинтиллиона', 'квинтиллионов'], // 10^ 18
80
- 7: ['секстиллион', 'секстиллиона', 'секстиллионов'], // 10^ 21
81
- 8: ['септиллион', 'септиллиона', 'септиллионов'], // 10^ 24
82
- 9: ['октиллион', 'октиллиона', 'октиллионов'], // 10^ 27
83
- 10: ['нониллион', 'нониллиона', 'нониллионов'], // 10^ 30
84
- };
85
-
86
- constructor(options) {
87
- options = Object.assign({
88
- negativeWord: 'минус',
89
- separatorWord: 'запятая',
90
- zero: 'ноль',
91
- feminine: false
92
- }, options);
93
-
94
- super(options);
95
-
96
- this.feminine = options.feminine;
97
- }
98
-
99
- toCardinal(number) {
100
- if (number == 0) {
101
- return this.zero;
102
- }
103
-
104
- const words = [];
105
-
106
- const chunks = this.splitByX(number.toString(), 3);
107
-
108
- let index = chunks.length;
109
-
110
- for (const x of chunks) {
111
- let ones = [];
112
- index = index - 1;
113
-
114
- if (x == 0) {
115
- continue;
116
- }
117
-
118
- const [n1, n2, n3] = this.getDigits(x);
119
-
120
- if (n3 > 0) {
121
- words.push(this.hundreds[n3]);
122
- }
123
-
124
- if (n2 > 1) {
125
- words.push(this.twenties[n2]);
126
- }
127
-
128
- if (n2 == 1) {
129
- words.push(this.tens[n1]);
130
- } else if (n1 > 0) {
131
- ones = (index == 1 || this.feminine && index == 0) ? this.onesFeminine : this.ones;
132
- words.push(ones[n1]);
133
- }
134
-
135
- if (index > 0) {
136
- words.push(this.pluralize(x, this.thousands[index]));
137
- }
138
- }
139
-
140
- return words.join(' ');
141
- }
142
-
143
- splitByX(n, x) {
144
- const results = [];
145
- const l = n.length;
146
- let result;
147
-
148
- if (l > x) {
149
- const start = l % x;
150
-
151
- if (start > 0) {
152
- result = n.slice(0, start);
153
-
154
- results.push(BigInt(result));
155
- }
156
-
157
- for (let index = start; index < l; index += x) {
158
- result = n.slice(index, index + x);
159
-
160
- results.push(BigInt(result));
161
- }
162
- } else {
163
- results.push(BigInt(n));
164
- }
165
-
166
- return results;
167
- }
168
-
169
- getDigits(value) {
170
- // TODO ESLint suggestion
171
- // eslint-disable-next-line unicorn/no-useless-spread
172
- const a = [...value.toString().padStart(3, '0').slice(-3)].toReversed();
173
- return a.map(BigInt);
174
- }
175
-
176
- pluralize(n, forms) {
177
- let form = 2;
178
- if ((n % 100n < 10n) || (n % 100n > 20n)) {
179
- if (n % 10n == 1n) {
180
- form = 0;
181
- } else if ((n % 10n < 5n) && (n % 10n > 1n)) {
182
- form = 1;
183
- }
184
- }
185
- return forms[form];
186
- }
187
- }
188
-
189
- /**
190
- * Converts a value to cardinal (written) form.
191
- * @param {number|string|bigint} value Number to be convert.
192
- * @param {object} [options] Options for class.
193
- * @returns {string} Value in cardinal (written) format.
194
- * @throws {Error} Value cannot be invalid.
195
- */
196
- export default function floatToCardinal (value, options = {}) {
197
- return new N2WordsRU(options).floatToCardinal(value);
198
- }
package/lib/i18n/sr.d.ts DELETED
@@ -1,56 +0,0 @@
1
- /**
2
- * Converts a value to cardinal (written) form.
3
- * @param {number|string|bigint} value Number to be convert.
4
- * @param {object} [options] Options for class.
5
- * @returns {string} Value in cardinal (written) format.
6
- * @throws {Error} Value cannot be invalid.
7
- */
8
- export default function floatToCardinal(value: number | string | bigint, options?: object): string;
9
- export class N2WordsSR extends N2WordsRU {
10
- ones: {
11
- 1: string[];
12
- 2: string[];
13
- 3: string[];
14
- 4: string[];
15
- 5: string[];
16
- 6: string[];
17
- 7: string[];
18
- 8: string[];
19
- 9: string[];
20
- };
21
- tens: {
22
- 0: string;
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
- twenties: {
34
- 2: string;
35
- 3: string;
36
- 4: string;
37
- 5: string;
38
- 6: string;
39
- 7: string;
40
- 8: string;
41
- 9: string;
42
- };
43
- hundreds: {
44
- 1: string;
45
- 2: string;
46
- 3: string;
47
- 4: string;
48
- 5: string;
49
- 6: string;
50
- 7: string;
51
- 8: string;
52
- 9: string;
53
- };
54
- SCALE: (string | boolean)[][];
55
- }
56
- import { N2WordsRU } from './ru.js';