n2words 3.0.0 → 4.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 (488) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/LICENSE +1 -1
  3. package/README.md +64 -184
  4. package/dist/am-ET.js +2 -0
  5. package/dist/am-ET.umd.js +2 -0
  6. package/dist/am-Latn-ET.js +2 -0
  7. package/dist/am-Latn-ET.umd.js +2 -0
  8. package/dist/ar-SA.js +2 -0
  9. package/dist/ar-SA.umd.js +2 -0
  10. package/dist/az-AZ.js +2 -0
  11. package/dist/az-AZ.umd.js +2 -0
  12. package/dist/bn-BD.js +2 -0
  13. package/dist/bn-BD.umd.js +2 -0
  14. package/dist/cs-CZ.js +2 -0
  15. package/dist/cs-CZ.umd.js +2 -0
  16. package/dist/da-DK.js +2 -0
  17. package/dist/da-DK.umd.js +2 -0
  18. package/dist/de-DE.js +2 -0
  19. package/dist/de-DE.umd.js +2 -0
  20. package/dist/el-GR.js +2 -0
  21. package/dist/el-GR.umd.js +2 -0
  22. package/dist/en-AU.js +2 -0
  23. package/dist/en-AU.umd.js +2 -0
  24. package/dist/en-BD.js +2 -0
  25. package/dist/en-BD.umd.js +2 -0
  26. package/dist/en-CA.js +2 -0
  27. package/dist/en-CA.umd.js +2 -0
  28. package/dist/en-GB.js +2 -0
  29. package/dist/en-GB.umd.js +2 -0
  30. package/dist/en-GH.js +2 -0
  31. package/dist/en-GH.umd.js +2 -0
  32. package/dist/en-IE.js +2 -0
  33. package/dist/en-IE.umd.js +2 -0
  34. package/dist/en-IN.js +2 -0
  35. package/dist/en-IN.umd.js +2 -0
  36. package/dist/en-KE.js +2 -0
  37. package/dist/en-KE.umd.js +2 -0
  38. package/dist/en-MY.js +2 -0
  39. package/dist/en-MY.umd.js +2 -0
  40. package/dist/en-NG.js +2 -0
  41. package/dist/en-NG.umd.js +2 -0
  42. package/dist/en-NZ.js +2 -0
  43. package/dist/en-NZ.umd.js +2 -0
  44. package/dist/en-PH.js +2 -0
  45. package/dist/en-PH.umd.js +2 -0
  46. package/dist/en-PK.js +2 -0
  47. package/dist/en-PK.umd.js +2 -0
  48. package/dist/en-SG.js +2 -0
  49. package/dist/en-SG.umd.js +2 -0
  50. package/dist/en-US.js +2 -0
  51. package/dist/en-US.umd.js +2 -0
  52. package/dist/en-ZA.js +2 -0
  53. package/dist/en-ZA.umd.js +2 -0
  54. package/dist/es-ES.js +2 -0
  55. package/dist/es-ES.umd.js +2 -0
  56. package/dist/es-MX.js +2 -0
  57. package/dist/es-MX.umd.js +2 -0
  58. package/dist/es-US.js +2 -0
  59. package/dist/es-US.umd.js +2 -0
  60. package/dist/fa-IR.js +2 -0
  61. package/dist/fa-IR.umd.js +2 -0
  62. package/dist/fi-FI.js +2 -0
  63. package/dist/fi-FI.umd.js +2 -0
  64. package/dist/fil-PH.js +2 -0
  65. package/dist/fil-PH.umd.js +2 -0
  66. package/dist/fr-BE.js +2 -0
  67. package/dist/fr-BE.umd.js +2 -0
  68. package/dist/fr-FR.js +2 -0
  69. package/dist/fr-FR.umd.js +2 -0
  70. package/dist/gu-IN.js +2 -0
  71. package/dist/gu-IN.umd.js +2 -0
  72. package/dist/ha-NG.js +2 -0
  73. package/dist/ha-NG.umd.js +2 -0
  74. package/dist/hbo-IL.js +2 -0
  75. package/dist/hbo-IL.umd.js +2 -0
  76. package/dist/he-IL.js +2 -0
  77. package/dist/he-IL.umd.js +2 -0
  78. package/dist/hi-IN.js +2 -0
  79. package/dist/hi-IN.umd.js +2 -0
  80. package/dist/hr-HR.js +2 -0
  81. package/dist/hr-HR.umd.js +2 -0
  82. package/dist/hu-HU.js +2 -0
  83. package/dist/hu-HU.umd.js +2 -0
  84. package/dist/id-ID.js +2 -0
  85. package/dist/id-ID.umd.js +2 -0
  86. package/dist/it-IT.js +2 -0
  87. package/dist/it-IT.umd.js +2 -0
  88. package/dist/ja-JP.js +2 -0
  89. package/dist/ja-JP.umd.js +2 -0
  90. package/dist/ka-GE.js +2 -0
  91. package/dist/ka-GE.umd.js +2 -0
  92. package/dist/kn-IN.js +2 -0
  93. package/dist/kn-IN.umd.js +2 -0
  94. package/dist/ko-KR.js +2 -0
  95. package/dist/ko-KR.umd.js +2 -0
  96. package/dist/lt-LT.js +2 -0
  97. package/dist/lt-LT.umd.js +2 -0
  98. package/dist/lv-LV.js +2 -0
  99. package/dist/lv-LV.umd.js +2 -0
  100. package/dist/mr-IN.js +2 -0
  101. package/dist/mr-IN.umd.js +2 -0
  102. package/dist/ms-MY.js +2 -0
  103. package/dist/ms-MY.umd.js +2 -0
  104. package/dist/nb-NO.js +2 -0
  105. package/dist/nb-NO.umd.js +2 -0
  106. package/dist/nl-NL.js +2 -0
  107. package/dist/nl-NL.umd.js +2 -0
  108. package/dist/pa-IN.js +2 -0
  109. package/dist/pa-IN.umd.js +2 -0
  110. package/dist/pl-PL.js +2 -0
  111. package/dist/pl-PL.umd.js +2 -0
  112. package/dist/pt-PT.js +2 -0
  113. package/dist/pt-PT.umd.js +2 -0
  114. package/dist/ro-RO.js +2 -0
  115. package/dist/ro-RO.umd.js +2 -0
  116. package/dist/ru-RU.js +2 -0
  117. package/dist/ru-RU.umd.js +2 -0
  118. package/dist/sr-Cyrl-RS.js +2 -0
  119. package/dist/sr-Cyrl-RS.umd.js +2 -0
  120. package/dist/sr-Latn-RS.js +2 -0
  121. package/dist/sr-Latn-RS.umd.js +2 -0
  122. package/dist/sv-SE.js +2 -0
  123. package/dist/sv-SE.umd.js +2 -0
  124. package/dist/sw-KE.js +2 -0
  125. package/dist/sw-KE.umd.js +2 -0
  126. package/dist/ta-IN.js +2 -0
  127. package/dist/ta-IN.umd.js +2 -0
  128. package/dist/te-IN.js +2 -0
  129. package/dist/te-IN.umd.js +2 -0
  130. package/dist/th-TH.js +2 -0
  131. package/dist/th-TH.umd.js +2 -0
  132. package/dist/tr-TR.js +2 -0
  133. package/dist/tr-TR.umd.js +2 -0
  134. package/dist/uk-UA.js +2 -0
  135. package/dist/uk-UA.umd.js +2 -0
  136. package/dist/ur-PK.js +2 -0
  137. package/dist/ur-PK.umd.js +2 -0
  138. package/dist/vi-VN.js +2 -0
  139. package/dist/vi-VN.umd.js +2 -0
  140. package/dist/yo-NG.js +2 -0
  141. package/dist/yo-NG.umd.js +2 -0
  142. package/dist/zh-Hans-CN.js +2 -0
  143. package/dist/zh-Hans-CN.umd.js +2 -0
  144. package/dist/zh-Hant-TW.js +2 -0
  145. package/dist/zh-Hant-TW.umd.js +2 -0
  146. package/package.json +47 -82
  147. package/src/am-ET.d.ts +40 -0
  148. package/src/am-ET.js +269 -0
  149. package/src/am-Latn-ET.d.ts +35 -0
  150. package/src/am-Latn-ET.js +264 -0
  151. package/src/ar-SA.d.ts +49 -0
  152. package/{lib/languages/ar.js → src/ar-SA.js} +177 -15
  153. package/src/az-AZ.d.ts +37 -0
  154. package/src/az-AZ.js +312 -0
  155. package/src/bn-BD.d.ts +36 -0
  156. package/src/bn-BD.js +270 -0
  157. package/src/cs-CZ.d.ts +49 -0
  158. package/{lib/languages/cs.js → src/cs-CZ.js} +249 -40
  159. package/src/da-DK.d.ts +44 -0
  160. package/{lib/languages/da.js → src/da-DK.js} +136 -23
  161. package/src/de-DE.d.ts +57 -0
  162. package/src/de-DE.js +603 -0
  163. package/src/el-GR.d.ts +40 -0
  164. package/src/el-GR.js +418 -0
  165. package/src/en-AU.d.ts +47 -0
  166. package/src/en-AU.js +423 -0
  167. package/src/en-BD.d.ts +49 -0
  168. package/src/en-BD.js +415 -0
  169. package/src/en-CA.d.ts +63 -0
  170. package/src/en-CA.js +518 -0
  171. package/src/en-GB.d.ts +56 -0
  172. package/src/en-GB.js +469 -0
  173. package/src/en-GH.d.ts +11 -0
  174. package/src/en-GH.js +345 -0
  175. package/src/en-IE.d.ts +56 -0
  176. package/src/en-IE.js +479 -0
  177. package/src/en-IN.d.ts +49 -0
  178. package/src/en-IN.js +415 -0
  179. package/src/en-KE.d.ts +11 -0
  180. package/src/en-KE.js +345 -0
  181. package/src/en-MY.d.ts +11 -0
  182. package/src/en-MY.js +347 -0
  183. package/src/en-NG.d.ts +56 -0
  184. package/src/en-NG.js +479 -0
  185. package/src/en-NZ.d.ts +11 -0
  186. package/src/en-NZ.js +375 -0
  187. package/src/en-PH.d.ts +11 -0
  188. package/src/en-PH.js +345 -0
  189. package/src/en-PK.d.ts +49 -0
  190. package/src/en-PK.js +415 -0
  191. package/src/en-SG.d.ts +11 -0
  192. package/src/en-SG.js +345 -0
  193. package/src/en-US.d.ts +63 -0
  194. package/src/en-US.js +516 -0
  195. package/src/en-ZA.d.ts +56 -0
  196. package/src/en-ZA.js +478 -0
  197. package/src/es-ES.d.ts +65 -0
  198. package/src/es-ES.js +541 -0
  199. package/src/es-MX.d.ts +58 -0
  200. package/{lib/languages/es.js → src/es-MX.js} +237 -47
  201. package/src/es-US.d.ts +58 -0
  202. package/src/es-US.js +446 -0
  203. package/src/fa-IR.d.ts +38 -0
  204. package/src/fa-IR.js +246 -0
  205. package/src/fi-FI.d.ts +46 -0
  206. package/src/fi-FI.js +379 -0
  207. package/src/fil-PH.d.ts +37 -0
  208. package/{lib/languages/fil.js → src/fil-PH.js} +149 -24
  209. package/src/fr-BE.d.ts +49 -0
  210. package/src/fr-BE.js +453 -0
  211. package/src/fr-FR.d.ts +63 -0
  212. package/{lib/languages/fr.js → src/fr-FR.js} +200 -47
  213. package/src/gu-IN.d.ts +35 -0
  214. package/src/gu-IN.js +259 -0
  215. package/src/ha-NG.d.ts +37 -0
  216. package/{lib/languages/ha.js → src/ha-NG.js} +110 -16
  217. package/src/hbo-IL.d.ts +39 -0
  218. package/{lib/languages/hbo.js → src/hbo-IL.js} +217 -43
  219. package/src/he-IL.d.ts +37 -0
  220. package/src/he-IL.js +537 -0
  221. package/src/hi-IN.d.ts +36 -0
  222. package/src/hi-IN.js +280 -0
  223. package/src/hr-HR.d.ts +42 -0
  224. package/src/hr-HR.js +463 -0
  225. package/src/hu-HU.d.ts +38 -0
  226. package/{lib/languages/hu.js → src/hu-HU.js} +164 -6
  227. package/src/id-ID.d.ts +38 -0
  228. package/{lib/languages/id.js → src/id-ID.js} +106 -20
  229. package/src/it-IT.d.ts +59 -0
  230. package/src/it-IT.js +506 -0
  231. package/src/ja-JP.d.ts +49 -0
  232. package/{lib/languages/ja.js → src/ja-JP.js} +119 -32
  233. package/src/ka-GE.d.ts +44 -0
  234. package/src/ka-GE.js +393 -0
  235. package/src/kn-IN.d.ts +35 -0
  236. package/{lib/languages/kn.js → src/kn-IN.js} +156 -34
  237. package/src/ko-KR.d.ts +45 -0
  238. package/{lib/languages/ko.js → src/ko-KR.js} +99 -24
  239. package/src/lt-LT.d.ts +49 -0
  240. package/src/lt-LT.js +543 -0
  241. package/src/lv-LV.d.ts +49 -0
  242. package/src/lv-LV.js +595 -0
  243. package/src/mr-IN.d.ts +36 -0
  244. package/src/mr-IN.js +260 -0
  245. package/src/ms-MY.d.ts +37 -0
  246. package/{lib/languages/ms.js → src/ms-MY.js} +118 -20
  247. package/src/nb-NO.d.ts +44 -0
  248. package/{lib/languages/nb.js → src/nb-NO.js} +165 -33
  249. package/src/nl-NL.d.ts +54 -0
  250. package/{lib/languages/nl.js → src/nl-NL.js} +271 -47
  251. package/src/pa-IN.d.ts +36 -0
  252. package/src/pa-IN.js +268 -0
  253. package/src/pl-PL.d.ts +55 -0
  254. package/src/pl-PL.js +585 -0
  255. package/src/pt-PT.d.ts +45 -0
  256. package/src/pt-PT.js +514 -0
  257. package/src/ro-RO.d.ts +44 -0
  258. package/{lib/languages/ro.js → src/ro-RO.js} +212 -18
  259. package/src/ru-RU.d.ts +50 -0
  260. package/src/ru-RU.js +535 -0
  261. package/src/sr-Cyrl-RS.d.ts +49 -0
  262. package/src/sr-Cyrl-RS.js +503 -0
  263. package/src/sr-Latn-RS.d.ts +49 -0
  264. package/src/sr-Latn-RS.js +503 -0
  265. package/src/sv-SE.d.ts +44 -0
  266. package/{lib/languages/sv.js → src/sv-SE.js} +149 -34
  267. package/src/sw-KE.d.ts +37 -0
  268. package/{lib/languages/sw.js → src/sw-KE.js} +117 -6
  269. package/src/ta-IN.d.ts +35 -0
  270. package/{lib/languages/ta.js → src/ta-IN.js} +163 -47
  271. package/src/te-IN.d.ts +35 -0
  272. package/{lib/languages/te.js → src/te-IN.js} +147 -46
  273. package/src/th-TH.d.ts +38 -0
  274. package/{lib/languages/th.js → src/th-TH.js} +99 -6
  275. package/src/tr-TR.d.ts +48 -0
  276. package/src/tr-TR.js +397 -0
  277. package/src/uk-UA.d.ts +42 -0
  278. package/src/uk-UA.js +463 -0
  279. package/src/ur-PK.d.ts +36 -0
  280. package/src/ur-PK.js +268 -0
  281. package/src/utils/expand-scientific.d.ts +32 -0
  282. package/src/utils/expand-scientific.js +65 -0
  283. package/src/utils/parse-cardinal.d.ts +14 -0
  284. package/{lib/utils/parse-numeric.js → src/utils/parse-cardinal.js} +14 -44
  285. package/src/utils/parse-currency.d.ts +14 -0
  286. package/src/utils/parse-currency.js +91 -0
  287. package/src/utils/parse-ordinal.d.ts +10 -0
  288. package/src/utils/parse-ordinal.js +103 -0
  289. package/src/vi-VN.d.ts +48 -0
  290. package/{lib/languages/vi.js → src/vi-VN.js} +124 -53
  291. package/src/yo-NG.d.ts +37 -0
  292. package/src/yo-NG.js +403 -0
  293. package/src/zh-Hans-CN.d.ts +48 -0
  294. package/{lib/languages/zh-Hans.js → src/zh-Hans-CN.js} +140 -8
  295. package/src/zh-Hant-TW.d.ts +50 -0
  296. package/{lib/languages/zh-Hant.js → src/zh-Hant-TW.js} +139 -8
  297. package/dist/languages/am-Latn.js +0 -3
  298. package/dist/languages/am-Latn.js.map +0 -1
  299. package/dist/languages/am.js +0 -3
  300. package/dist/languages/am.js.map +0 -1
  301. package/dist/languages/ar.js +0 -3
  302. package/dist/languages/ar.js.map +0 -1
  303. package/dist/languages/az.js +0 -3
  304. package/dist/languages/az.js.map +0 -1
  305. package/dist/languages/bn.js +0 -3
  306. package/dist/languages/bn.js.map +0 -1
  307. package/dist/languages/cs.js +0 -3
  308. package/dist/languages/cs.js.map +0 -1
  309. package/dist/languages/da.js +0 -3
  310. package/dist/languages/da.js.map +0 -1
  311. package/dist/languages/de.js +0 -3
  312. package/dist/languages/de.js.map +0 -1
  313. package/dist/languages/el.js +0 -3
  314. package/dist/languages/el.js.map +0 -1
  315. package/dist/languages/en.js +0 -3
  316. package/dist/languages/en.js.map +0 -1
  317. package/dist/languages/es.js +0 -3
  318. package/dist/languages/es.js.map +0 -1
  319. package/dist/languages/fa.js +0 -3
  320. package/dist/languages/fa.js.map +0 -1
  321. package/dist/languages/fi.js +0 -3
  322. package/dist/languages/fi.js.map +0 -1
  323. package/dist/languages/fil.js +0 -3
  324. package/dist/languages/fil.js.map +0 -1
  325. package/dist/languages/fr-BE.js +0 -3
  326. package/dist/languages/fr-BE.js.map +0 -1
  327. package/dist/languages/fr.js +0 -3
  328. package/dist/languages/fr.js.map +0 -1
  329. package/dist/languages/gu.js +0 -3
  330. package/dist/languages/gu.js.map +0 -1
  331. package/dist/languages/ha.js +0 -3
  332. package/dist/languages/ha.js.map +0 -1
  333. package/dist/languages/hbo.js +0 -3
  334. package/dist/languages/hbo.js.map +0 -1
  335. package/dist/languages/he.js +0 -3
  336. package/dist/languages/he.js.map +0 -1
  337. package/dist/languages/hi.js +0 -3
  338. package/dist/languages/hi.js.map +0 -1
  339. package/dist/languages/hr.js +0 -3
  340. package/dist/languages/hr.js.map +0 -1
  341. package/dist/languages/hu.js +0 -3
  342. package/dist/languages/hu.js.map +0 -1
  343. package/dist/languages/id.js +0 -3
  344. package/dist/languages/id.js.map +0 -1
  345. package/dist/languages/it.js +0 -3
  346. package/dist/languages/it.js.map +0 -1
  347. package/dist/languages/ja.js +0 -3
  348. package/dist/languages/ja.js.map +0 -1
  349. package/dist/languages/kn.js +0 -3
  350. package/dist/languages/kn.js.map +0 -1
  351. package/dist/languages/ko.js +0 -3
  352. package/dist/languages/ko.js.map +0 -1
  353. package/dist/languages/lt.js +0 -3
  354. package/dist/languages/lt.js.map +0 -1
  355. package/dist/languages/lv.js +0 -3
  356. package/dist/languages/lv.js.map +0 -1
  357. package/dist/languages/mr.js +0 -3
  358. package/dist/languages/mr.js.map +0 -1
  359. package/dist/languages/ms.js +0 -3
  360. package/dist/languages/ms.js.map +0 -1
  361. package/dist/languages/nb.js +0 -3
  362. package/dist/languages/nb.js.map +0 -1
  363. package/dist/languages/nl.js +0 -3
  364. package/dist/languages/nl.js.map +0 -1
  365. package/dist/languages/pa.js +0 -3
  366. package/dist/languages/pa.js.map +0 -1
  367. package/dist/languages/pl.js +0 -3
  368. package/dist/languages/pl.js.map +0 -1
  369. package/dist/languages/pt.js +0 -3
  370. package/dist/languages/pt.js.map +0 -1
  371. package/dist/languages/ro.js +0 -3
  372. package/dist/languages/ro.js.map +0 -1
  373. package/dist/languages/ru.js +0 -3
  374. package/dist/languages/ru.js.map +0 -1
  375. package/dist/languages/sr-Cyrl.js +0 -3
  376. package/dist/languages/sr-Cyrl.js.map +0 -1
  377. package/dist/languages/sr-Latn.js +0 -3
  378. package/dist/languages/sr-Latn.js.map +0 -1
  379. package/dist/languages/sv.js +0 -3
  380. package/dist/languages/sv.js.map +0 -1
  381. package/dist/languages/sw.js +0 -3
  382. package/dist/languages/sw.js.map +0 -1
  383. package/dist/languages/ta.js +0 -3
  384. package/dist/languages/ta.js.map +0 -1
  385. package/dist/languages/te.js +0 -3
  386. package/dist/languages/te.js.map +0 -1
  387. package/dist/languages/th.js +0 -3
  388. package/dist/languages/th.js.map +0 -1
  389. package/dist/languages/tr.js +0 -3
  390. package/dist/languages/tr.js.map +0 -1
  391. package/dist/languages/uk.js +0 -3
  392. package/dist/languages/uk.js.map +0 -1
  393. package/dist/languages/ur.js +0 -3
  394. package/dist/languages/ur.js.map +0 -1
  395. package/dist/languages/vi.js +0 -3
  396. package/dist/languages/vi.js.map +0 -1
  397. package/dist/languages/zh-Hans.js +0 -3
  398. package/dist/languages/zh-Hans.js.map +0 -1
  399. package/dist/languages/zh-Hant.js +0 -3
  400. package/dist/languages/zh-Hant.js.map +0 -1
  401. package/dist/n2words.js +0 -3
  402. package/dist/n2words.js.map +0 -1
  403. package/lib/languages/am-Latn.d.ts +0 -7
  404. package/lib/languages/am-Latn.js +0 -164
  405. package/lib/languages/am.d.ts +0 -7
  406. package/lib/languages/am.js +0 -164
  407. package/lib/languages/ar.d.ts +0 -17
  408. package/lib/languages/az.d.ts +0 -7
  409. package/lib/languages/az.js +0 -176
  410. package/lib/languages/bn.d.ts +0 -7
  411. package/lib/languages/bn.js +0 -145
  412. package/lib/languages/cs.d.ts +0 -18
  413. package/lib/languages/da.d.ts +0 -14
  414. package/lib/languages/de.d.ts +0 -17
  415. package/lib/languages/de.js +0 -332
  416. package/lib/languages/el.d.ts +0 -14
  417. package/lib/languages/el.js +0 -243
  418. package/lib/languages/en.d.ts +0 -17
  419. package/lib/languages/en.js +0 -256
  420. package/lib/languages/es.d.ts +0 -21
  421. package/lib/languages/fa.d.ts +0 -7
  422. package/lib/languages/fa.js +0 -134
  423. package/lib/languages/fi.d.ts +0 -14
  424. package/lib/languages/fi.js +0 -245
  425. package/lib/languages/fil.d.ts +0 -7
  426. package/lib/languages/fr-BE.d.ts +0 -11
  427. package/lib/languages/fr-BE.js +0 -300
  428. package/lib/languages/fr.d.ts +0 -21
  429. package/lib/languages/gu.d.ts +0 -7
  430. package/lib/languages/gu.js +0 -137
  431. package/lib/languages/ha.d.ts +0 -7
  432. package/lib/languages/hbo.d.ts +0 -13
  433. package/lib/languages/he.d.ts +0 -13
  434. package/lib/languages/he.js +0 -276
  435. package/lib/languages/hi.d.ts +0 -7
  436. package/lib/languages/hi.js +0 -145
  437. package/lib/languages/hr.d.ts +0 -11
  438. package/lib/languages/hr.js +0 -218
  439. package/lib/languages/hu.d.ts +0 -7
  440. package/lib/languages/id.d.ts +0 -7
  441. package/lib/languages/it.d.ts +0 -19
  442. package/lib/languages/it.js +0 -377
  443. package/lib/languages/ja.d.ts +0 -17
  444. package/lib/languages/kn.d.ts +0 -7
  445. package/lib/languages/ko.d.ts +0 -14
  446. package/lib/languages/lt.d.ts +0 -18
  447. package/lib/languages/lt.js +0 -310
  448. package/lib/languages/lv.d.ts +0 -18
  449. package/lib/languages/lv.js +0 -321
  450. package/lib/languages/mr.d.ts +0 -7
  451. package/lib/languages/mr.js +0 -137
  452. package/lib/languages/ms.d.ts +0 -7
  453. package/lib/languages/nb.d.ts +0 -14
  454. package/lib/languages/nl.d.ts +0 -26
  455. package/lib/languages/pa.d.ts +0 -7
  456. package/lib/languages/pa.js +0 -163
  457. package/lib/languages/pl.d.ts +0 -22
  458. package/lib/languages/pl.js +0 -330
  459. package/lib/languages/pt.d.ts +0 -17
  460. package/lib/languages/pt.js +0 -306
  461. package/lib/languages/ro.d.ts +0 -18
  462. package/lib/languages/ru.d.ts +0 -11
  463. package/lib/languages/ru.js +0 -240
  464. package/lib/languages/sr-Cyrl.d.ts +0 -11
  465. package/lib/languages/sr-Cyrl.js +0 -215
  466. package/lib/languages/sr-Latn.d.ts +0 -11
  467. package/lib/languages/sr-Latn.js +0 -215
  468. package/lib/languages/sv.d.ts +0 -14
  469. package/lib/languages/sw.d.ts +0 -7
  470. package/lib/languages/ta.d.ts +0 -7
  471. package/lib/languages/te.d.ts +0 -7
  472. package/lib/languages/th.d.ts +0 -7
  473. package/lib/languages/tr.d.ts +0 -18
  474. package/lib/languages/tr.js +0 -263
  475. package/lib/languages/uk.d.ts +0 -11
  476. package/lib/languages/uk.js +0 -218
  477. package/lib/languages/ur.d.ts +0 -7
  478. package/lib/languages/ur.js +0 -163
  479. package/lib/languages/vi.d.ts +0 -17
  480. package/lib/languages/zh-Hans.d.ts +0 -11
  481. package/lib/languages/zh-Hant.d.ts +0 -11
  482. package/lib/n2words.d.ts +0 -53
  483. package/lib/n2words.js +0 -122
  484. package/lib/utils/parse-numeric.d.ts +0 -17
  485. /package/{lib → src}/utils/is-plain-object.d.ts +0 -0
  486. /package/{lib → src}/utils/is-plain-object.js +0 -0
  487. /package/{lib → src}/utils/validate-options.d.ts +0 -0
  488. /package/{lib → src}/utils/validate-options.js +0 -0
@@ -1,240 +0,0 @@
1
- /**
2
- * Russian language converter - Functional Implementation
3
- *
4
- * Self-contained converter using shared Slavic utilities.
5
- *
6
- * Key features:
7
- * - Three-form pluralization (one/few/many)
8
- * - Gender: thousands are feminine, millions+ are masculine
9
- * - Irregular hundreds (двести, триста, etc.)
10
- * - Long scale naming
11
- */
12
-
13
- import { parseNumericValue } from '../utils/parse-numeric.js'
14
- import { validateOptions } from '../utils/validate-options.js'
15
-
16
- // ============================================================================
17
- // Slavic Utilities (inlined for performance)
18
- // ============================================================================
19
-
20
- function pluralize (n, forms) {
21
- const num = typeof n === 'bigint' ? Number(n) : n
22
- const lastDigit = num % 10
23
- const lastTwoDigits = num % 100
24
-
25
- if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
26
- return forms[2]
27
- }
28
-
29
- if (lastDigit === 1) return forms[0]
30
- if (lastDigit >= 2 && lastDigit <= 4) return forms[1]
31
- return forms[2]
32
- }
33
-
34
- function buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {
35
- const masc = new Array(1000)
36
- const fem = new Array(1000)
37
-
38
- for (let i = 0; i < 1000; i++) {
39
- masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)
40
- fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)
41
- }
42
-
43
- return { masc, fem }
44
- }
45
-
46
- function buildSegment (n, ones, teens, tens, hundreds) {
47
- if (n === 0) return ''
48
-
49
- const onesDigit = n % 10
50
- const tensDigit = Math.floor(n / 10) % 10
51
- const hundredsDigit = Math.floor(n / 100)
52
-
53
- const parts = []
54
-
55
- if (hundredsDigit > 0) {
56
- parts.push(hundreds[hundredsDigit])
57
- }
58
-
59
- if (tensDigit > 1) {
60
- parts.push(tens[tensDigit])
61
- }
62
-
63
- if (tensDigit === 1) {
64
- parts.push(teens[onesDigit])
65
- } else if (onesDigit > 0) {
66
- parts.push(ones[onesDigit])
67
- }
68
-
69
- return parts.join(' ')
70
- }
71
-
72
- // ============================================================================
73
- // Vocabulary
74
- // ============================================================================
75
-
76
- const ONES_MASC = ['', 'один', 'два', 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять']
77
- const ONES_FEM = ['', 'одна', 'две', 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять']
78
-
79
- const TEENS = ['десять', 'одиннадцать', 'двенадцать', 'тринадцать', 'четырнадцать', 'пятнадцать', 'шестнадцать', 'семнадцать', 'восемнадцать', 'девятнадцать']
80
- const TENS = ['', '', 'двадцать', 'тридцать', 'сорок', 'пятьдесят', 'шестьдесят', 'семьдесят', 'восемьдесят', 'девяносто']
81
-
82
- // Irregular hundreds
83
- const HUNDREDS = ['', 'сто', 'двести', 'триста', 'четыреста', 'пятьсот', 'шестьсот', 'семьсот', 'восемьсот', 'девятьсот']
84
-
85
- const ZERO = 'ноль'
86
- const NEGATIVE = 'минус'
87
- const DECIMAL_SEP = 'запятая'
88
-
89
- // Scale words: [singular, few, many]
90
- // Thousands (index 0) are feminine, rest are masculine
91
- const SCALE_FORMS = [
92
- ['тысяча', 'тысячи', 'тысяч'],
93
- ['миллион', 'миллиона', 'миллионов'],
94
- ['миллиард', 'миллиарда', 'миллиардов'],
95
- ['триллион', 'триллиона', 'триллионов'],
96
- ['квадриллион', 'квадриллиона', 'квадриллионов'],
97
- ['квинтиллион', 'квинтиллиона', 'квинтиллионов'],
98
- ['секстиллион', 'секстиллиона', 'секстиллионов'],
99
- ['септиллион', 'септиллиона', 'септиллионов'],
100
- ['октиллион', 'октиллиона', 'октиллионов'],
101
- ['нониллион', 'нониллиона', 'нониллионов']
102
- ]
103
-
104
- // ============================================================================
105
- // Precomputed Lookup Tables
106
- // ============================================================================
107
-
108
- const { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)
109
-
110
- // ============================================================================
111
- // Conversion Functions
112
- // ============================================================================
113
-
114
- function integerToWords (n, options = {}) {
115
- if (n === 0n) return ZERO
116
-
117
- const feminine = options.gender === 'feminine'
118
-
119
- if (n < 1000n) {
120
- const segments = feminine ? SEGMENTS_FEM : SEGMENTS_MASC
121
- return segments[Number(n)]
122
- }
123
-
124
- if (n < 1_000_000n) {
125
- const thousands = Number(n / 1000n)
126
- const remainder = Number(n % 1000n)
127
-
128
- // Thousands are always feminine in Russian
129
- const thousandsWord = SEGMENTS_FEM[thousands]
130
- const scaleWord = pluralize(thousands, SCALE_FORMS[0])
131
-
132
- let result = thousandsWord + ' ' + scaleWord
133
-
134
- if (remainder > 0) {
135
- const segments = feminine ? SEGMENTS_FEM : SEGMENTS_MASC
136
- result += ' ' + segments[remainder]
137
- }
138
-
139
- return result
140
- }
141
-
142
- return buildLargeNumberWords(n, options)
143
- }
144
-
145
- function buildLargeNumberWords (n, options) {
146
- const feminine = options.gender === 'feminine'
147
- const numStr = n.toString()
148
- const len = numStr.length
149
-
150
- const segments = []
151
- const segmentSize = 3
152
-
153
- const remainderLen = len % segmentSize
154
- let pos = 0
155
- if (remainderLen > 0) {
156
- segments.push(Number(numStr.slice(0, remainderLen)))
157
- pos = remainderLen
158
- }
159
- while (pos < len) {
160
- segments.push(Number(numStr.slice(pos, pos + segmentSize)))
161
- pos += segmentSize
162
- }
163
-
164
- const parts = []
165
- let scaleIndex = segments.length - 1
166
-
167
- for (let i = 0; i < segments.length; i++) {
168
- const segment = segments[i]
169
-
170
- if (segment !== 0) {
171
- if (scaleIndex === 0) {
172
- const segmentWords = feminine ? SEGMENTS_FEM : SEGMENTS_MASC
173
- parts.push(segmentWords[segment])
174
- } else {
175
- const scaleForms = SCALE_FORMS[scaleIndex - 1]
176
- const scaleWord = pluralize(segment, scaleForms)
177
- // Thousands (scaleIndex=1) are feminine, others masculine
178
- const isFeminine = scaleIndex === 1
179
- const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC
180
- parts.push(segmentWords[segment] + ' ' + scaleWord)
181
- }
182
- }
183
-
184
- scaleIndex--
185
- }
186
-
187
- return parts.join(' ')
188
- }
189
-
190
- function decimalPartToWords (decimalPart, options) {
191
- let result = ''
192
- let i = 0
193
-
194
- while (i < decimalPart.length && decimalPart[i] === '0') {
195
- if (result) result += ' '
196
- result += ZERO
197
- i++
198
- }
199
-
200
- const remainder = decimalPart.slice(i)
201
- if (remainder) {
202
- if (result) result += ' '
203
- result += integerToWords(BigInt(remainder), options)
204
- }
205
-
206
- return result
207
- }
208
-
209
- /**
210
- * Converts a numeric value to Russian words.
211
- *
212
- * @param {number | string | bigint} value - The numeric value to convert
213
- * @param {Object} [options] - Optional configuration
214
- * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
215
- * @returns {string} The number in Russian words
216
- */
217
- function toWords (value, options) {
218
- options = validateOptions(options)
219
- const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
220
-
221
- let result = ''
222
-
223
- if (isNegative) {
224
- result = NEGATIVE + ' '
225
- }
226
-
227
- result += integerToWords(integerPart, options)
228
-
229
- if (decimalPart) {
230
- result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)
231
- }
232
-
233
- return result
234
- }
235
-
236
- // ============================================================================
237
- // Exports
238
- // ============================================================================
239
-
240
- export { toWords }
@@ -1,11 +0,0 @@
1
- /**
2
- * Converts a numeric value to Serbian (Cyrillic) words.
3
- *
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
- * @returns {string} The number in Serbian Cyrillic words
8
- */
9
- export function toWords(value: number | string | bigint, options?: {
10
- gender?: "masculine" | "feminine" | undefined;
11
- }): string;
@@ -1,215 +0,0 @@
1
- /**
2
- * Serbian Cyrillic language converter - Functional Implementation
3
- *
4
- * Self-contained converter using shared Slavic utilities.
5
- *
6
- * Key features:
7
- * - Three-form pluralization (one/few/many)
8
- * - Gender: thousands are feminine, millions+ are masculine
9
- * - Irregular hundreds
10
- * - Long scale naming with -ard forms
11
- * - Cyrillic script
12
- */
13
-
14
- import { parseNumericValue } from '../utils/parse-numeric.js'
15
- import { validateOptions } from '../utils/validate-options.js'
16
-
17
- // ============================================================================
18
- // Slavic Utilities (inlined for performance)
19
- // ============================================================================
20
-
21
- function pluralize (n, forms) {
22
- const num = typeof n === 'bigint' ? Number(n) : n
23
- const lastDigit = num % 10
24
- const lastTwoDigits = num % 100
25
-
26
- if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
27
- return forms[2]
28
- }
29
-
30
- if (lastDigit === 1) return forms[0]
31
- if (lastDigit >= 2 && lastDigit <= 4) return forms[1]
32
- return forms[2]
33
- }
34
-
35
- function buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {
36
- const masc = new Array(1000)
37
- const fem = new Array(1000)
38
-
39
- for (let i = 0; i < 1000; i++) {
40
- masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)
41
- fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)
42
- }
43
-
44
- return { masc, fem }
45
- }
46
-
47
- function buildSegment (n, ones, teens, tens, hundreds) {
48
- if (n === 0) return ''
49
-
50
- const onesDigit = n % 10
51
- const tensDigit = Math.floor(n / 10) % 10
52
- const hundredsDigit = Math.floor(n / 100)
53
-
54
- const parts = []
55
-
56
- if (hundredsDigit > 0) {
57
- parts.push(hundreds[hundredsDigit])
58
- }
59
-
60
- if (tensDigit > 1) {
61
- parts.push(tens[tensDigit])
62
- }
63
-
64
- if (tensDigit === 1) {
65
- parts.push(teens[onesDigit])
66
- } else if (onesDigit > 0) {
67
- parts.push(ones[onesDigit])
68
- }
69
-
70
- return parts.join(' ')
71
- }
72
-
73
- // ============================================================================
74
- // Vocabulary
75
- // ============================================================================
76
-
77
- const ONES_MASC = ['', 'један', 'два', 'три', 'четири', 'пет', 'шест', 'седам', 'осам', 'девет']
78
- const ONES_FEM = ['', 'једна', 'две', 'три', 'четири', 'пет', 'шест', 'седам', 'осам', 'девет']
79
- const TEENS = ['десет', 'једанаест', 'дванаест', 'тринаест', 'четрнаест', 'петнаест', 'шеснаест', 'седамнаест', 'осамнаест', 'деветнаест']
80
- const TENS = ['', '', 'двадесет', 'тридесет', 'четрдесет', 'педесет', 'шездесет', 'седамдесет', 'осамдесет', 'деведесет']
81
- const HUNDREDS = ['', 'сто', 'двеста', 'триста', 'четиристо', 'петсто', 'шесто', 'седамсто', 'осамсто', 'девестo']
82
-
83
- const ZERO = 'нула'
84
- const NEGATIVE = 'минус'
85
- const DECIMAL_SEP = 'запета'
86
-
87
- // Scale words: [singular, few, many]
88
- const SCALE_FORMS = [
89
- ['хиљада', 'хиљаде', 'хиљада'],
90
- ['милион', 'милиона', 'милиона'],
91
- ['милијарда', 'милијарде', 'милијарда'],
92
- ['билион', 'билиона', 'билиона'],
93
- ['билијарда', 'билијарде', 'билијарда'],
94
- ['трилион', 'трилиона', 'трилиона'],
95
- ['трилијарда', 'трилијарде', 'трилијарда'],
96
- ['квадрилион', 'квадрилиона', 'квадрилиона'],
97
- ['квадрилијарда', 'квадрилијарде', 'квадрилијарда']
98
- ]
99
-
100
- // ============================================================================
101
- // Precomputed Lookup Tables
102
- // ============================================================================
103
-
104
- const { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)
105
-
106
- // ============================================================================
107
- // Conversion Functions
108
- // ============================================================================
109
-
110
- function integerToWords (n, options = {}) {
111
- if (n === 0n) return ZERO
112
-
113
- if (n < 1000n) {
114
- const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC
115
- return segments[Number(n)]
116
- }
117
-
118
- return buildLargeNumberWords(n, options)
119
- }
120
-
121
- function buildLargeNumberWords (n, options) {
122
- const numStr = n.toString()
123
- const len = numStr.length
124
-
125
- const segments = []
126
- const segmentSize = 3
127
-
128
- const remainderLen = len % segmentSize
129
- let pos = 0
130
- if (remainderLen > 0) {
131
- segments.push(Number(numStr.slice(0, remainderLen)))
132
- pos = remainderLen
133
- }
134
- while (pos < len) {
135
- segments.push(Number(numStr.slice(pos, pos + segmentSize)))
136
- pos += segmentSize
137
- }
138
-
139
- const parts = []
140
- let scaleIndex = segments.length - 1
141
-
142
- for (let i = 0; i < segments.length; i++) {
143
- const segment = segments[i]
144
-
145
- if (segment !== 0) {
146
- if (scaleIndex === 0) {
147
- const segmentWords = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC
148
- parts.push(segmentWords[segment])
149
- } else {
150
- const scaleForms = SCALE_FORMS[scaleIndex - 1]
151
- const scaleWord = pluralize(segment, scaleForms)
152
- // Thousands (scaleIndex=1) are feminine, others masculine
153
- const isFeminine = scaleIndex === 1
154
- const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC
155
- parts.push(segmentWords[segment] + ' ' + scaleWord)
156
- }
157
- }
158
-
159
- scaleIndex--
160
- }
161
-
162
- return parts.join(' ')
163
- }
164
-
165
- function decimalPartToWords (decimalPart, options) {
166
- let result = ''
167
- let i = 0
168
-
169
- while (i < decimalPart.length && decimalPart[i] === '0') {
170
- if (result) result += ' '
171
- result += ZERO
172
- i++
173
- }
174
-
175
- const remainder = decimalPart.slice(i)
176
- if (remainder) {
177
- if (result) result += ' '
178
- result += integerToWords(BigInt(remainder), options)
179
- }
180
-
181
- return result
182
- }
183
-
184
- /**
185
- * Converts a numeric value to Serbian (Cyrillic) words.
186
- *
187
- * @param {number | string | bigint} value - The numeric value to convert
188
- * @param {Object} [options] - Optional configuration
189
- * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
190
- * @returns {string} The number in Serbian Cyrillic words
191
- */
192
- function toWords (value, options) {
193
- options = validateOptions(options)
194
- const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
195
-
196
- let result = ''
197
-
198
- if (isNegative) {
199
- result = NEGATIVE + ' '
200
- }
201
-
202
- result += integerToWords(integerPart, options)
203
-
204
- if (decimalPart) {
205
- result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)
206
- }
207
-
208
- return result
209
- }
210
-
211
- // ============================================================================
212
- // Exports
213
- // ============================================================================
214
-
215
- export { toWords }
@@ -1,11 +0,0 @@
1
- /**
2
- * Converts a numeric value to Serbian (Latin) words.
3
- *
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
- * @returns {string} The number in Serbian Latin words
8
- */
9
- export function toWords(value: number | string | bigint, options?: {
10
- gender?: "masculine" | "feminine" | undefined;
11
- }): string;
@@ -1,215 +0,0 @@
1
- /**
2
- * Serbian Latin language converter - Functional Implementation
3
- *
4
- * Self-contained converter using shared Slavic utilities.
5
- *
6
- * Key features:
7
- * - Three-form pluralization (one/few/many)
8
- * - Gender: thousands are feminine, millions+ are masculine
9
- * - Irregular hundreds (dvesta, trista, etc.)
10
- * - Long scale naming with -ard forms
11
- * - Latin script
12
- */
13
-
14
- import { parseNumericValue } from '../utils/parse-numeric.js'
15
- import { validateOptions } from '../utils/validate-options.js'
16
-
17
- // ============================================================================
18
- // Slavic Utilities (inlined for performance)
19
- // ============================================================================
20
-
21
- function pluralize (n, forms) {
22
- const num = typeof n === 'bigint' ? Number(n) : n
23
- const lastDigit = num % 10
24
- const lastTwoDigits = num % 100
25
-
26
- if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
27
- return forms[2]
28
- }
29
-
30
- if (lastDigit === 1) return forms[0]
31
- if (lastDigit >= 2 && lastDigit <= 4) return forms[1]
32
- return forms[2]
33
- }
34
-
35
- function buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {
36
- const masc = new Array(1000)
37
- const fem = new Array(1000)
38
-
39
- for (let i = 0; i < 1000; i++) {
40
- masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)
41
- fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)
42
- }
43
-
44
- return { masc, fem }
45
- }
46
-
47
- function buildSegment (n, ones, teens, tens, hundreds) {
48
- if (n === 0) return ''
49
-
50
- const onesDigit = n % 10
51
- const tensDigit = Math.floor(n / 10) % 10
52
- const hundredsDigit = Math.floor(n / 100)
53
-
54
- const parts = []
55
-
56
- if (hundredsDigit > 0) {
57
- parts.push(hundreds[hundredsDigit])
58
- }
59
-
60
- if (tensDigit > 1) {
61
- parts.push(tens[tensDigit])
62
- }
63
-
64
- if (tensDigit === 1) {
65
- parts.push(teens[onesDigit])
66
- } else if (onesDigit > 0) {
67
- parts.push(ones[onesDigit])
68
- }
69
-
70
- return parts.join(' ')
71
- }
72
-
73
- // ============================================================================
74
- // Vocabulary
75
- // ============================================================================
76
-
77
- const ONES_MASC = ['', 'jedan', 'dva', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']
78
- const ONES_FEM = ['', 'jedna', 'dve', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']
79
- const TEENS = ['deset', 'jedanaest', 'dvanaest', 'trinaest', 'četrnaest', 'petnaest', 'šesnaest', 'sedamnaest', 'osamnaest', 'devetnaest']
80
- const TENS = ['', '', 'dvadeset', 'trideset', 'četrdeset', 'pedeset', 'šezdeset', 'sedamdeset', 'osamdeset', 'devedeset']
81
- const HUNDREDS = ['', 'sto', 'dvesta', 'trista', 'četiristo', 'petsto', 'šesto', 'sedamsto', 'osamsto', 'devetsto']
82
-
83
- const ZERO = 'nula'
84
- const NEGATIVE = 'minus'
85
- const DECIMAL_SEP = 'zapeta'
86
-
87
- // Scale words: [singular, few, many]
88
- const SCALE_FORMS = [
89
- ['hiljada', 'hiljade', 'hiljada'],
90
- ['milion', 'miliona', 'miliona'],
91
- ['milijarda', 'milijarde', 'milijarda'],
92
- ['bilion', 'biliona', 'biliona'],
93
- ['bilijarda', 'bilijarde', 'bilijarda'],
94
- ['trilion', 'triliona', 'triliona'],
95
- ['trilijarda', 'trilijarde', 'trilijarda'],
96
- ['kvadrilion', 'kvadriliona', 'kvadriliona'],
97
- ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda']
98
- ]
99
-
100
- // ============================================================================
101
- // Precomputed Lookup Tables
102
- // ============================================================================
103
-
104
- const { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)
105
-
106
- // ============================================================================
107
- // Conversion Functions
108
- // ============================================================================
109
-
110
- function integerToWords (n, options = {}) {
111
- if (n === 0n) return ZERO
112
-
113
- if (n < 1000n) {
114
- const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC
115
- return segments[Number(n)]
116
- }
117
-
118
- return buildLargeNumberWords(n, options)
119
- }
120
-
121
- function buildLargeNumberWords (n, options) {
122
- const numStr = n.toString()
123
- const len = numStr.length
124
-
125
- const segments = []
126
- const segmentSize = 3
127
-
128
- const remainderLen = len % segmentSize
129
- let pos = 0
130
- if (remainderLen > 0) {
131
- segments.push(Number(numStr.slice(0, remainderLen)))
132
- pos = remainderLen
133
- }
134
- while (pos < len) {
135
- segments.push(Number(numStr.slice(pos, pos + segmentSize)))
136
- pos += segmentSize
137
- }
138
-
139
- const parts = []
140
- let scaleIndex = segments.length - 1
141
-
142
- for (let i = 0; i < segments.length; i++) {
143
- const segment = segments[i]
144
-
145
- if (segment !== 0) {
146
- if (scaleIndex === 0) {
147
- const segmentWords = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC
148
- parts.push(segmentWords[segment])
149
- } else {
150
- const scaleForms = SCALE_FORMS[scaleIndex - 1]
151
- const scaleWord = pluralize(segment, scaleForms)
152
- // Thousands (scaleIndex=1) are feminine, others masculine
153
- const isFeminine = scaleIndex === 1
154
- const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC
155
- parts.push(segmentWords[segment] + ' ' + scaleWord)
156
- }
157
- }
158
-
159
- scaleIndex--
160
- }
161
-
162
- return parts.join(' ')
163
- }
164
-
165
- function decimalPartToWords (decimalPart, options) {
166
- let result = ''
167
- let i = 0
168
-
169
- while (i < decimalPart.length && decimalPart[i] === '0') {
170
- if (result) result += ' '
171
- result += ZERO
172
- i++
173
- }
174
-
175
- const remainder = decimalPart.slice(i)
176
- if (remainder) {
177
- if (result) result += ' '
178
- result += integerToWords(BigInt(remainder), options)
179
- }
180
-
181
- return result
182
- }
183
-
184
- /**
185
- * Converts a numeric value to Serbian (Latin) words.
186
- *
187
- * @param {number | string | bigint} value - The numeric value to convert
188
- * @param {Object} [options] - Optional configuration
189
- * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
190
- * @returns {string} The number in Serbian Latin words
191
- */
192
- function toWords (value, options) {
193
- options = validateOptions(options)
194
- const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
195
-
196
- let result = ''
197
-
198
- if (isNegative) {
199
- result = NEGATIVE + ' '
200
- }
201
-
202
- result += integerToWords(integerPart, options)
203
-
204
- if (decimalPart) {
205
- result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)
206
- }
207
-
208
- return result
209
- }
210
-
211
- // ============================================================================
212
- // Exports
213
- // ============================================================================
214
-
215
- export { toWords }