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
package/src/hr-HR.js ADDED
@@ -0,0 +1,463 @@
1
+ /**
2
+ * Croatian (Croatia) language converter
3
+ *
4
+ * CLDR: hr-HR | Croatian as used in Croatia
5
+ *
6
+ * Key features:
7
+ * - Three-form pluralization (one/few/many)
8
+ * - Gender: thousands are feminine, millions+ are masculine
9
+ * - Irregular hundreds (dvjesto, tristo, etc.)
10
+ * - Long scale naming with -ard forms
11
+ */
12
+
13
+ import { parseCardinalValue } from './utils/parse-cardinal.js'
14
+ import { parseCurrencyValue } from './utils/parse-currency.js'
15
+ import { parseOrdinalValue } from './utils/parse-ordinal.js'
16
+ import { validateOptions } from './utils/validate-options.js'
17
+
18
+ // ============================================================================
19
+ // Vocabulary
20
+ // ============================================================================
21
+
22
+ const ONES_MASC = ['', 'jedan', 'dva', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']
23
+ const ONES_FEM = ['', 'jedna', 'dvije', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']
24
+
25
+ const TEENS = ['deset', 'jedanaest', 'dvanaest', 'trinaest', 'četrnaest', 'petnaest', 'šesnaest', 'sedamnaest', 'osamnaest', 'devetnaest']
26
+ const TENS = ['', '', 'dvadeset', 'trideset', 'četrdeset', 'pedeset', 'šezdeset', 'sedamdeset', 'osamdeset', 'devedeset']
27
+
28
+ // Croatian has irregular hundreds
29
+ const HUNDREDS = ['', 'sto', 'dvjesto', 'tristo', 'četiristo', 'petsto', 'šesto', 'sedamsto', 'osamsto', 'devetsto']
30
+
31
+ const ZERO = 'nula'
32
+ const NEGATIVE = 'minus'
33
+ const DECIMAL_SEP = 'zarez'
34
+
35
+ // ============================================================================
36
+ // Ordinal Vocabulary
37
+ // ============================================================================
38
+
39
+ // Croatian ordinals (masculine nominative singular)
40
+ const ORDINAL_ONES = ['', 'prvi', 'drugi', 'treći', 'četvrti', 'peti', 'šesti', 'sedmi', 'osmi', 'deveti']
41
+
42
+ // Ordinal teens
43
+ const ORDINAL_TEENS = ['deseti', 'jedanaesti', 'dvanaesti', 'trinaesti', 'četrnaesti', 'petnaesti', 'šesnaesti', 'sedamnaesti', 'osamnaesti', 'devetnaesti']
44
+
45
+ // Ordinal tens (for exact tens)
46
+ const ORDINAL_TENS = ['', '', 'dvadeseti', 'trideseti', 'četrdeseti', 'pedeseti', 'šezdeseti', 'sedamdeseti', 'osamdeseti', 'devedeseti']
47
+
48
+ // Ordinal hundreds (for exact hundreds)
49
+ const ORDINAL_HUNDREDS = ['', 'stoti', 'dvjestoti', 'tristoti', 'četiristoti', 'petstoti', 'šeststoti', 'sedamstoti', 'osamstoti', 'devetstoti']
50
+
51
+ // Scale ordinals
52
+ const ORDINAL_SCALES = ['tisućiti', 'milijunti', 'milijarditi', 'bilijunti']
53
+
54
+ // ============================================================================
55
+ // Currency Vocabulary (Croatian Kuna - now Euro)
56
+ // ============================================================================
57
+
58
+ // Euro forms: [singular, few (2-4), many (5+)] - masculine
59
+ const EURO_FORMS = ['euro', 'eura', 'eura']
60
+ // Cent forms: [singular, few (2-4), many (5+)] - masculine
61
+ const CENT_FORMS = ['cent', 'centa', 'centi']
62
+
63
+ // Scale words: [singular, few, many]
64
+ // Thousands (index 0) are feminine, rest are masculine
65
+ const SCALE_FORMS = [
66
+ ['tisuća', 'tisuće', 'tisuća'],
67
+ ['milijun', 'milijuna', 'milijuna'],
68
+ ['milijarda', 'milijarde', 'milijarda'],
69
+ ['bilijun', 'bilijuna', 'bilijuna'],
70
+ ['bilijarda', 'bilijarde', 'bilijarda'],
71
+ ['trilijun', 'trilijuna', 'trilijuna'],
72
+ ['trilijarda', 'trilijarde', 'trilijarda'],
73
+ ['kvadrilijun', 'kvadrilijuna', 'kvadrilijuna'],
74
+ ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda']
75
+ ]
76
+
77
+ // ============================================================================
78
+ // Segment Building
79
+ // ============================================================================
80
+
81
+ function pluralize (n, forms) {
82
+ const num = typeof n === 'bigint' ? Number(n) : n
83
+ const lastDigit = num % 10
84
+ const lastTwoDigits = num % 100
85
+
86
+ if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
87
+ return forms[2]
88
+ }
89
+
90
+ if (lastDigit === 1) return forms[0]
91
+ if (lastDigit >= 2 && lastDigit <= 4) return forms[1]
92
+ return forms[2]
93
+ }
94
+
95
+ function buildSegmentMasc (n) {
96
+ if (n === 0) return ''
97
+
98
+ const onesDigit = n % 10
99
+ const tensDigit = Math.trunc(n / 10) % 10
100
+ const hundredsDigit = Math.trunc(n / 100)
101
+
102
+ const parts = []
103
+
104
+ if (hundredsDigit > 0) {
105
+ parts.push(HUNDREDS[hundredsDigit])
106
+ }
107
+
108
+ if (tensDigit > 1) {
109
+ parts.push(TENS[tensDigit])
110
+ }
111
+
112
+ if (tensDigit === 1) {
113
+ parts.push(TEENS[onesDigit])
114
+ } else if (onesDigit > 0) {
115
+ parts.push(ONES_MASC[onesDigit])
116
+ }
117
+
118
+ return parts.join(' ')
119
+ }
120
+
121
+ function buildSegmentFem (n) {
122
+ if (n === 0) return ''
123
+
124
+ const onesDigit = n % 10
125
+ const tensDigit = Math.trunc(n / 10) % 10
126
+ const hundredsDigit = Math.trunc(n / 100)
127
+
128
+ const parts = []
129
+
130
+ if (hundredsDigit > 0) {
131
+ parts.push(HUNDREDS[hundredsDigit])
132
+ }
133
+
134
+ if (tensDigit > 1) {
135
+ parts.push(TENS[tensDigit])
136
+ }
137
+
138
+ if (tensDigit === 1) {
139
+ parts.push(TEENS[onesDigit])
140
+ } else if (onesDigit > 0) {
141
+ parts.push(ONES_FEM[onesDigit])
142
+ }
143
+
144
+ return parts.join(' ')
145
+ }
146
+
147
+ // ============================================================================
148
+ // Conversion Functions
149
+ // ============================================================================
150
+
151
+ function integerToWords (n, gender) {
152
+ if (n === 0n) return ZERO
153
+
154
+ if (n < 1000n) {
155
+ return gender === 'feminine' ? buildSegmentFem(Number(n)) : buildSegmentMasc(Number(n))
156
+ }
157
+
158
+ return buildLargeNumberWords(n, gender)
159
+ }
160
+
161
+ function buildLargeNumberWords (n, gender) {
162
+ const numStr = n.toString()
163
+ const len = numStr.length
164
+
165
+ const segments = []
166
+ const segmentSize = 3
167
+
168
+ const remainderLen = len % segmentSize
169
+ let pos = 0
170
+ if (remainderLen > 0) {
171
+ segments.push(Number(numStr.slice(0, remainderLen)))
172
+ pos = remainderLen
173
+ }
174
+ while (pos < len) {
175
+ segments.push(Number(numStr.slice(pos, pos + segmentSize)))
176
+ pos += segmentSize
177
+ }
178
+
179
+ const parts = []
180
+ let scaleIndex = segments.length - 1
181
+
182
+ for (let i = 0; i < segments.length; i++) {
183
+ const segment = segments[i]
184
+
185
+ if (segment !== 0) {
186
+ if (scaleIndex === 0) {
187
+ parts.push(gender === 'feminine' ? buildSegmentFem(segment) : buildSegmentMasc(segment))
188
+ } else {
189
+ const scaleForms = SCALE_FORMS[scaleIndex - 1]
190
+ const scaleWord = pluralize(segment, scaleForms)
191
+ // Thousands (scaleIndex=1) are feminine, others masculine
192
+ const isFeminine = scaleIndex === 1
193
+ const segmentWord = isFeminine ? buildSegmentFem(segment) : buildSegmentMasc(segment)
194
+ parts.push(segmentWord + ' ' + scaleWord)
195
+ }
196
+ }
197
+
198
+ scaleIndex--
199
+ }
200
+
201
+ return parts.join(' ')
202
+ }
203
+
204
+ function decimalPartToWords (decimalPart, gender) {
205
+ let result = ''
206
+ let i = 0
207
+
208
+ while (i < decimalPart.length && decimalPart[i] === '0') {
209
+ if (result) result += ' '
210
+ result += ZERO
211
+ i++
212
+ }
213
+
214
+ const remainder = decimalPart.slice(i)
215
+ if (remainder) {
216
+ if (result) result += ' '
217
+ result += integerToWords(BigInt(remainder), gender)
218
+ }
219
+
220
+ return result
221
+ }
222
+
223
+ /**
224
+ * Converts a numeric value to Croatian words.
225
+ *
226
+ * @param {number | string | bigint} value - The numeric value to convert
227
+ * @param {Object} [options] - Optional configuration
228
+ * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
229
+ * @returns {string} The number in Croatian words
230
+ */
231
+ function toCardinal (value, options) {
232
+ options = validateOptions(options)
233
+ const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
234
+
235
+ // Apply option defaults
236
+ const { gender = 'masculine' } = options
237
+
238
+ let result = ''
239
+
240
+ if (isNegative) {
241
+ result = NEGATIVE + ' '
242
+ }
243
+
244
+ result += integerToWords(integerPart, gender)
245
+
246
+ if (decimalPart) {
247
+ result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, gender)
248
+ }
249
+
250
+ return result
251
+ }
252
+
253
+ // ============================================================================
254
+ // ORDINAL: toOrdinal(value)
255
+ // ============================================================================
256
+
257
+ /**
258
+ * Builds ordinal for a 0-99 segment when it's the final (ordinal) part.
259
+ *
260
+ * @param {number} n - Number 0-99
261
+ * @returns {string} Ordinal words
262
+ */
263
+ function buildOrdinalTensOnes (n) {
264
+ if (n === 0) return ''
265
+
266
+ const onesDigit = n % 10
267
+ const tensDigit = Math.trunc(n / 10)
268
+
269
+ if (tensDigit === 0) {
270
+ return ORDINAL_ONES[onesDigit]
271
+ }
272
+
273
+ if (tensDigit === 1) {
274
+ return ORDINAL_TEENS[onesDigit]
275
+ }
276
+
277
+ if (onesDigit === 0) {
278
+ return ORDINAL_TENS[tensDigit]
279
+ }
280
+
281
+ return TENS[tensDigit] + ' ' + ORDINAL_ONES[onesDigit]
282
+ }
283
+
284
+ /**
285
+ * Converts a positive integer to Croatian ordinal words (masculine nominative).
286
+ *
287
+ * @param {bigint} n - Positive integer to convert
288
+ * @returns {string} Ordinal Croatian words
289
+ */
290
+ function integerToOrdinal (n) {
291
+ if (n < 100n) {
292
+ return buildOrdinalTensOnes(Number(n))
293
+ }
294
+
295
+ if (n < 1000n) {
296
+ const num = Number(n)
297
+ const hundredsDigit = Math.trunc(num / 100)
298
+ const remainder = num % 100
299
+
300
+ if (remainder === 0) {
301
+ return ORDINAL_HUNDREDS[hundredsDigit]
302
+ }
303
+
304
+ return HUNDREDS[hundredsDigit] + ' ' + buildOrdinalTensOnes(remainder)
305
+ }
306
+
307
+ if (n < 1_000_000n) {
308
+ const thousands = Number(n / 1000n)
309
+ const remainder = Number(n % 1000n)
310
+
311
+ if (remainder === 0) {
312
+ if (thousands === 1) {
313
+ return ORDINAL_SCALES[0]
314
+ }
315
+ return buildSegmentFem(thousands) + ' ' + ORDINAL_SCALES[0]
316
+ }
317
+
318
+ const scaleWord = pluralize(thousands, SCALE_FORMS[0])
319
+ const thousandsWord = buildSegmentFem(thousands)
320
+ return thousandsWord + ' ' + scaleWord + ' ' + integerToOrdinal(BigInt(remainder))
321
+ }
322
+
323
+ return buildLargeOrdinal(n)
324
+ }
325
+
326
+ /**
327
+ * Builds ordinal words for numbers >= 1,000,000.
328
+ *
329
+ * @param {bigint} n - Number >= 1,000,000
330
+ * @returns {string} Ordinal Croatian words
331
+ */
332
+ function buildLargeOrdinal (n) {
333
+ const numStr = n.toString()
334
+ const len = numStr.length
335
+
336
+ const segments = []
337
+ const segmentSize = 3
338
+
339
+ const remainderLen = len % segmentSize
340
+ let pos = 0
341
+ if (remainderLen > 0) {
342
+ segments.push(Number(numStr.slice(0, remainderLen)))
343
+ pos = remainderLen
344
+ }
345
+ while (pos < len) {
346
+ segments.push(Number(numStr.slice(pos, pos + segmentSize)))
347
+ pos += segmentSize
348
+ }
349
+
350
+ let lastNonZeroIdx = segments.length - 1
351
+ while (lastNonZeroIdx >= 0 && segments[lastNonZeroIdx] === 0) {
352
+ lastNonZeroIdx--
353
+ }
354
+
355
+ const parts = []
356
+ let scaleIndex = segments.length - 1
357
+
358
+ for (let i = 0; i < segments.length; i++) {
359
+ const segment = segments[i]
360
+
361
+ if (segment !== 0) {
362
+ const isLastNonZero = (i === lastNonZeroIdx)
363
+
364
+ if (scaleIndex === 0) {
365
+ if (isLastNonZero) {
366
+ parts.push(integerToOrdinal(BigInt(segment)))
367
+ } else {
368
+ parts.push(buildSegmentMasc(segment))
369
+ }
370
+ } else {
371
+ if (isLastNonZero) {
372
+ if (segment === 1) {
373
+ parts.push(ORDINAL_SCALES[scaleIndex - 1])
374
+ } else {
375
+ const isFeminine = scaleIndex === 1
376
+ const segmentWord = isFeminine ? buildSegmentFem(segment) : buildSegmentMasc(segment)
377
+ parts.push(segmentWord + ' ' + ORDINAL_SCALES[scaleIndex - 1])
378
+ }
379
+ } else {
380
+ const scaleForms = SCALE_FORMS[scaleIndex - 1]
381
+ const scaleWord = pluralize(segment, scaleForms)
382
+ const isFeminine = scaleIndex === 1
383
+ const segmentWord = isFeminine ? buildSegmentFem(segment) : buildSegmentMasc(segment)
384
+ parts.push(segmentWord + ' ' + scaleWord)
385
+ }
386
+ }
387
+ }
388
+
389
+ scaleIndex--
390
+ }
391
+
392
+ return parts.join(' ')
393
+ }
394
+
395
+ /**
396
+ * Converts a numeric value to Croatian ordinal words (masculine nominative).
397
+ *
398
+ * @param {number | string | bigint} value - The numeric value to convert (must be a positive integer)
399
+ * @returns {string} The number as ordinal words
400
+ * @throws {TypeError} If value is not a valid numeric type
401
+ * @throws {RangeError} If value is negative, zero, or has a decimal part
402
+ *
403
+ * @example
404
+ * toOrdinal(1) // 'prvi'
405
+ * toOrdinal(2) // 'drugi'
406
+ * toOrdinal(21) // 'dvadeset prvi'
407
+ * toOrdinal(100) // 'stoti'
408
+ * toOrdinal(1000) // 'tisućiti'
409
+ */
410
+ function toOrdinal (value) {
411
+ const integerPart = parseOrdinalValue(value)
412
+ return integerToOrdinal(integerPart)
413
+ }
414
+
415
+ // ============================================================================
416
+ // CURRENCY: toCurrency(value)
417
+ // ============================================================================
418
+
419
+ /**
420
+ * Converts a numeric value to Croatian currency words (Euro).
421
+ *
422
+ * @param {number | string | bigint} value - The currency amount to convert
423
+ * @returns {string} The amount in Croatian currency words
424
+ * @throws {TypeError} If value is not a valid numeric type
425
+ * @throws {Error} If value is not a valid number format
426
+ *
427
+ * @example
428
+ * toCurrency(42) // 'četrdeset dva eura'
429
+ * toCurrency(1) // 'jedan euro'
430
+ * toCurrency(1.50) // 'jedan euro pedeset centi'
431
+ * toCurrency(-5) // 'minus pet eura'
432
+ */
433
+ function toCurrency (value) {
434
+ const { isNegative, dollars: euros, cents } = parseCurrencyValue(value)
435
+
436
+ let result = ''
437
+ if (isNegative) {
438
+ result = NEGATIVE + ' '
439
+ }
440
+
441
+ // Euro part (masculine)
442
+ if (euros > 0n || cents === 0n) {
443
+ result += integerToWords(euros, 'masculine')
444
+ result += ' ' + pluralize(euros, EURO_FORMS)
445
+ }
446
+
447
+ // Cent part (masculine)
448
+ if (cents > 0n) {
449
+ if (euros > 0n) {
450
+ result += ' '
451
+ }
452
+ result += integerToWords(cents, 'masculine')
453
+ result += ' ' + pluralize(cents, CENT_FORMS)
454
+ }
455
+
456
+ return result
457
+ }
458
+
459
+ // ============================================================================
460
+ // Exports
461
+ // ============================================================================
462
+
463
+ export { toCardinal, toOrdinal, toCurrency }
package/src/hu-HU.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Converts a numeric value to Hungarian words.
3
+ *
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @returns {string} The number in Hungarian words
6
+ */
7
+ export function toCardinal(value: number | string | bigint): string;
8
+ /**
9
+ * Converts a numeric value to Hungarian ordinal words.
10
+ *
11
+ * @param {number | string | bigint} value - The numeric value to convert (positive integer)
12
+ * @returns {string} The number as ordinal words
13
+ * @throws {TypeError} If value is not a valid numeric type
14
+ * @throws {RangeError} If value is negative, zero, or has a decimal part
15
+ *
16
+ * @example
17
+ * toOrdinal(1) // 'első'
18
+ * toOrdinal(2) // 'második'
19
+ * toOrdinal(21) // 'huszonegyedik'
20
+ */
21
+ export function toOrdinal(value: number | string | bigint): string;
22
+ /**
23
+ * Converts a numeric value to Hungarian currency words (Hungarian Forint).
24
+ *
25
+ * Uses forint (no plural form needed in Hungarian).
26
+ * Fillér (1/100) is rarely used but included for completeness.
27
+ *
28
+ * @param {number | string | bigint} value - The currency amount to convert
29
+ * @returns {string} The amount in Hungarian currency words
30
+ * @throws {TypeError} If value is not a valid numeric type
31
+ * @throws {Error} If value is not a valid number format
32
+ *
33
+ * @example
34
+ * toCurrency(42) // 'negyvenkettő forint'
35
+ * toCurrency(1.50) // 'egy forint ötven fillér'
36
+ * toCurrency(-5) // 'mínusz öt forint'
37
+ */
38
+ export function toCurrency(value: number | string | bigint): string;
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Hungarian language converter - Functional Implementation
2
+ * Hungarian (Hungary) language converter
3
3
  *
4
- * Self-contained converter with agglutinative word formation.
4
+ * CLDR: hu-HU | Hungarian as used in Hungary
5
5
  *
6
6
  * Key features:
7
7
  * - Agglutinative structure (no spaces between compound parts)
@@ -10,7 +10,9 @@
10
10
  * - "két" instead of "kettő" in compound forms
11
11
  */
12
12
 
13
- import { parseNumericValue } from '../utils/parse-numeric.js'
13
+ import { parseCardinalValue } from './utils/parse-cardinal.js'
14
+ import { parseCurrencyValue } from './utils/parse-currency.js'
15
+ import { parseOrdinalValue } from './utils/parse-ordinal.js'
14
16
 
15
17
  // ============================================================================
16
18
  // Vocabulary
@@ -71,6 +73,42 @@ const ZERO = 'nulla'
71
73
  const NEGATIVE = 'mínusz'
72
74
  const DECIMAL_SEP = 'egész'
73
75
 
76
+ // ============================================================================
77
+ // Ordinal Vocabulary
78
+ // ============================================================================
79
+
80
+ // Hungarian ordinals: special forms 1-10, then cardinal + -dik/-ik suffix
81
+ // Vowel harmony determines -dik vs -ik
82
+ const ORDINAL_SPECIAL = {
83
+ 1: 'első',
84
+ 2: 'második',
85
+ 3: 'harmadik',
86
+ 4: 'negyedik',
87
+ 5: 'ötödik',
88
+ 6: 'hatodik',
89
+ 7: 'hetedik',
90
+ 8: 'nyolcadik',
91
+ 9: 'kilencedik',
92
+ 10: 'tizedik',
93
+ 20: 'huszadik',
94
+ 30: 'harmincadik',
95
+ 40: 'negyvenedik',
96
+ 50: 'ötvenedik',
97
+ 60: 'hatvanadik',
98
+ 70: 'hetvenedik',
99
+ 80: 'nyolcvanadik',
100
+ 90: 'kilencvenedik',
101
+ 100: 'századik',
102
+ 1000: 'ezredik'
103
+ }
104
+
105
+ // ============================================================================
106
+ // Currency Vocabulary (Hungarian Forint)
107
+ // ============================================================================
108
+
109
+ const FORINT = 'forint' // same singular and plural
110
+ const FILLER = 'fillér' // subunit (rarely used, same singular and plural)
111
+
74
112
  // ============================================================================
75
113
  // Conversion Functions
76
114
  // ============================================================================
@@ -191,8 +229,8 @@ function decimalPartToWords (decimalPart) {
191
229
  * @param {number | string | bigint} value - The numeric value to convert
192
230
  * @returns {string} The number in Hungarian words
193
231
  */
194
- function toWords (value) {
195
- const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
232
+ function toCardinal (value) {
233
+ const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
196
234
 
197
235
  let result = ''
198
236
 
@@ -209,8 +247,128 @@ function toWords (value) {
209
247
  return result
210
248
  }
211
249
 
250
+ // ============================================================================
251
+ // ORDINAL: toOrdinal(value)
252
+ // ============================================================================
253
+
254
+ /**
255
+ * Converts a non-negative integer to Hungarian ordinal words.
256
+ *
257
+ * Hungarian ordinals: első (1st), második (2nd), harmadik (3rd), etc.
258
+ * 1-10 have special forms, others use cardinal + -dik/-edik/-adik/-ödik suffix.
259
+ *
260
+ * @param {bigint} n - Positive integer to convert
261
+ * @returns {string} Hungarian ordinal words
262
+ */
263
+ function integerToOrdinal (n) {
264
+ const num = Number(n)
265
+
266
+ // Exact special forms
267
+ if (ORDINAL_SPECIAL[num]) {
268
+ return ORDINAL_SPECIAL[num]
269
+ }
270
+
271
+ // For compound numbers, get cardinal and add suffix
272
+ const cardinal = integerToWords(n)
273
+
274
+ // Determine suffix based on last vowel (vowel harmony)
275
+ // Back vowels (a,á,o,ó,u,ú) -> -adik
276
+ // Front unrounded (e,é,i,í) -> -edik
277
+ // Front rounded (ö,ő,ü,ű) -> -ödik
278
+ // If ends in consonant, add linking vowel + dik
279
+
280
+ const lastChar = cardinal[cardinal.length - 1]
281
+
282
+ // If ends in vowel, just add -dik
283
+ if ('aáoóuúeéiíöőüű'.includes(lastChar)) {
284
+ return cardinal + 'dik'
285
+ }
286
+
287
+ // If ends in consonant, find last vowel for harmony
288
+ const backVowels = 'aáoóuú'
289
+ const frontRoundedVowels = 'öőüű'
290
+
291
+ for (let i = cardinal.length - 1; i >= 0; i--) {
292
+ const char = cardinal[i]
293
+ if (backVowels.includes(char)) {
294
+ return cardinal + 'adik'
295
+ }
296
+ if (frontRoundedVowels.includes(char)) {
297
+ return cardinal + 'ödik'
298
+ }
299
+ if ('eéií'.includes(char)) {
300
+ return cardinal + 'edik'
301
+ }
302
+ }
303
+
304
+ // Default to -edik
305
+ return cardinal + 'edik'
306
+ }
307
+
308
+ /**
309
+ * Converts a numeric value to Hungarian ordinal words.
310
+ *
311
+ * @param {number | string | bigint} value - The numeric value to convert (positive integer)
312
+ * @returns {string} The number as ordinal words
313
+ * @throws {TypeError} If value is not a valid numeric type
314
+ * @throws {RangeError} If value is negative, zero, or has a decimal part
315
+ *
316
+ * @example
317
+ * toOrdinal(1) // 'első'
318
+ * toOrdinal(2) // 'második'
319
+ * toOrdinal(21) // 'huszonegyedik'
320
+ */
321
+ function toOrdinal (value) {
322
+ const integerPart = parseOrdinalValue(value)
323
+ return integerToOrdinal(integerPart)
324
+ }
325
+
326
+ // ============================================================================
327
+ // CURRENCY: toCurrency(value)
328
+ // ============================================================================
329
+
330
+ /**
331
+ * Converts a numeric value to Hungarian currency words (Hungarian Forint).
332
+ *
333
+ * Uses forint (no plural form needed in Hungarian).
334
+ * Fillér (1/100) is rarely used but included for completeness.
335
+ *
336
+ * @param {number | string | bigint} value - The currency amount to convert
337
+ * @returns {string} The amount in Hungarian currency words
338
+ * @throws {TypeError} If value is not a valid numeric type
339
+ * @throws {Error} If value is not a valid number format
340
+ *
341
+ * @example
342
+ * toCurrency(42) // 'negyvenkettő forint'
343
+ * toCurrency(1.50) // 'egy forint ötven fillér'
344
+ * toCurrency(-5) // 'mínusz öt forint'
345
+ */
346
+ function toCurrency (value) {
347
+ const { isNegative, dollars: forint, cents: filler } = parseCurrencyValue(value)
348
+
349
+ let result = ''
350
+ if (isNegative) {
351
+ result = NEGATIVE + ' '
352
+ }
353
+
354
+ // Forint part
355
+ if (forint > 0n || filler === 0n) {
356
+ result += integerToWords(forint) + ' ' + FORINT
357
+ }
358
+
359
+ // Fillér part
360
+ if (filler > 0n) {
361
+ if (forint > 0n) {
362
+ result += ' '
363
+ }
364
+ result += integerToWords(filler) + ' ' + FILLER
365
+ }
366
+
367
+ return result
368
+ }
369
+
212
370
  // ============================================================================
213
371
  // Exports
214
372
  // ============================================================================
215
373
 
216
- export { toWords }
374
+ export { toCardinal, toOrdinal, toCurrency }