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.
- package/CHANGELOG.md +59 -0
- package/LICENSE +1 -1
- package/README.md +64 -184
- package/dist/am-ET.js +2 -0
- package/dist/am-ET.umd.js +2 -0
- package/dist/am-Latn-ET.js +2 -0
- package/dist/am-Latn-ET.umd.js +2 -0
- package/dist/ar-SA.js +2 -0
- package/dist/ar-SA.umd.js +2 -0
- package/dist/az-AZ.js +2 -0
- package/dist/az-AZ.umd.js +2 -0
- package/dist/bn-BD.js +2 -0
- package/dist/bn-BD.umd.js +2 -0
- package/dist/cs-CZ.js +2 -0
- package/dist/cs-CZ.umd.js +2 -0
- package/dist/da-DK.js +2 -0
- package/dist/da-DK.umd.js +2 -0
- package/dist/de-DE.js +2 -0
- package/dist/de-DE.umd.js +2 -0
- package/dist/el-GR.js +2 -0
- package/dist/el-GR.umd.js +2 -0
- package/dist/en-AU.js +2 -0
- package/dist/en-AU.umd.js +2 -0
- package/dist/en-BD.js +2 -0
- package/dist/en-BD.umd.js +2 -0
- package/dist/en-CA.js +2 -0
- package/dist/en-CA.umd.js +2 -0
- package/dist/en-GB.js +2 -0
- package/dist/en-GB.umd.js +2 -0
- package/dist/en-GH.js +2 -0
- package/dist/en-GH.umd.js +2 -0
- package/dist/en-IE.js +2 -0
- package/dist/en-IE.umd.js +2 -0
- package/dist/en-IN.js +2 -0
- package/dist/en-IN.umd.js +2 -0
- package/dist/en-KE.js +2 -0
- package/dist/en-KE.umd.js +2 -0
- package/dist/en-MY.js +2 -0
- package/dist/en-MY.umd.js +2 -0
- package/dist/en-NG.js +2 -0
- package/dist/en-NG.umd.js +2 -0
- package/dist/en-NZ.js +2 -0
- package/dist/en-NZ.umd.js +2 -0
- package/dist/en-PH.js +2 -0
- package/dist/en-PH.umd.js +2 -0
- package/dist/en-PK.js +2 -0
- package/dist/en-PK.umd.js +2 -0
- package/dist/en-SG.js +2 -0
- package/dist/en-SG.umd.js +2 -0
- package/dist/en-US.js +2 -0
- package/dist/en-US.umd.js +2 -0
- package/dist/en-ZA.js +2 -0
- package/dist/en-ZA.umd.js +2 -0
- package/dist/es-ES.js +2 -0
- package/dist/es-ES.umd.js +2 -0
- package/dist/es-MX.js +2 -0
- package/dist/es-MX.umd.js +2 -0
- package/dist/es-US.js +2 -0
- package/dist/es-US.umd.js +2 -0
- package/dist/fa-IR.js +2 -0
- package/dist/fa-IR.umd.js +2 -0
- package/dist/fi-FI.js +2 -0
- package/dist/fi-FI.umd.js +2 -0
- package/dist/fil-PH.js +2 -0
- package/dist/fil-PH.umd.js +2 -0
- package/dist/fr-BE.js +2 -0
- package/dist/fr-BE.umd.js +2 -0
- package/dist/fr-FR.js +2 -0
- package/dist/fr-FR.umd.js +2 -0
- package/dist/gu-IN.js +2 -0
- package/dist/gu-IN.umd.js +2 -0
- package/dist/ha-NG.js +2 -0
- package/dist/ha-NG.umd.js +2 -0
- package/dist/hbo-IL.js +2 -0
- package/dist/hbo-IL.umd.js +2 -0
- package/dist/he-IL.js +2 -0
- package/dist/he-IL.umd.js +2 -0
- package/dist/hi-IN.js +2 -0
- package/dist/hi-IN.umd.js +2 -0
- package/dist/hr-HR.js +2 -0
- package/dist/hr-HR.umd.js +2 -0
- package/dist/hu-HU.js +2 -0
- package/dist/hu-HU.umd.js +2 -0
- package/dist/id-ID.js +2 -0
- package/dist/id-ID.umd.js +2 -0
- package/dist/it-IT.js +2 -0
- package/dist/it-IT.umd.js +2 -0
- package/dist/ja-JP.js +2 -0
- package/dist/ja-JP.umd.js +2 -0
- package/dist/ka-GE.js +2 -0
- package/dist/ka-GE.umd.js +2 -0
- package/dist/kn-IN.js +2 -0
- package/dist/kn-IN.umd.js +2 -0
- package/dist/ko-KR.js +2 -0
- package/dist/ko-KR.umd.js +2 -0
- package/dist/lt-LT.js +2 -0
- package/dist/lt-LT.umd.js +2 -0
- package/dist/lv-LV.js +2 -0
- package/dist/lv-LV.umd.js +2 -0
- package/dist/mr-IN.js +2 -0
- package/dist/mr-IN.umd.js +2 -0
- package/dist/ms-MY.js +2 -0
- package/dist/ms-MY.umd.js +2 -0
- package/dist/nb-NO.js +2 -0
- package/dist/nb-NO.umd.js +2 -0
- package/dist/nl-NL.js +2 -0
- package/dist/nl-NL.umd.js +2 -0
- package/dist/pa-IN.js +2 -0
- package/dist/pa-IN.umd.js +2 -0
- package/dist/pl-PL.js +2 -0
- package/dist/pl-PL.umd.js +2 -0
- package/dist/pt-PT.js +2 -0
- package/dist/pt-PT.umd.js +2 -0
- package/dist/ro-RO.js +2 -0
- package/dist/ro-RO.umd.js +2 -0
- package/dist/ru-RU.js +2 -0
- package/dist/ru-RU.umd.js +2 -0
- package/dist/sr-Cyrl-RS.js +2 -0
- package/dist/sr-Cyrl-RS.umd.js +2 -0
- package/dist/sr-Latn-RS.js +2 -0
- package/dist/sr-Latn-RS.umd.js +2 -0
- package/dist/sv-SE.js +2 -0
- package/dist/sv-SE.umd.js +2 -0
- package/dist/sw-KE.js +2 -0
- package/dist/sw-KE.umd.js +2 -0
- package/dist/ta-IN.js +2 -0
- package/dist/ta-IN.umd.js +2 -0
- package/dist/te-IN.js +2 -0
- package/dist/te-IN.umd.js +2 -0
- package/dist/th-TH.js +2 -0
- package/dist/th-TH.umd.js +2 -0
- package/dist/tr-TR.js +2 -0
- package/dist/tr-TR.umd.js +2 -0
- package/dist/uk-UA.js +2 -0
- package/dist/uk-UA.umd.js +2 -0
- package/dist/ur-PK.js +2 -0
- package/dist/ur-PK.umd.js +2 -0
- package/dist/vi-VN.js +2 -0
- package/dist/vi-VN.umd.js +2 -0
- package/dist/yo-NG.js +2 -0
- package/dist/yo-NG.umd.js +2 -0
- package/dist/zh-Hans-CN.js +2 -0
- package/dist/zh-Hans-CN.umd.js +2 -0
- package/dist/zh-Hant-TW.js +2 -0
- package/dist/zh-Hant-TW.umd.js +2 -0
- package/package.json +47 -82
- package/src/am-ET.d.ts +40 -0
- package/src/am-ET.js +269 -0
- package/src/am-Latn-ET.d.ts +35 -0
- package/src/am-Latn-ET.js +264 -0
- package/src/ar-SA.d.ts +49 -0
- package/{lib/languages/ar.js → src/ar-SA.js} +177 -15
- package/src/az-AZ.d.ts +37 -0
- package/src/az-AZ.js +312 -0
- package/src/bn-BD.d.ts +36 -0
- package/src/bn-BD.js +270 -0
- package/src/cs-CZ.d.ts +49 -0
- package/{lib/languages/cs.js → src/cs-CZ.js} +249 -40
- package/src/da-DK.d.ts +44 -0
- package/{lib/languages/da.js → src/da-DK.js} +136 -23
- package/src/de-DE.d.ts +57 -0
- package/src/de-DE.js +603 -0
- package/src/el-GR.d.ts +40 -0
- package/src/el-GR.js +418 -0
- package/src/en-AU.d.ts +47 -0
- package/src/en-AU.js +423 -0
- package/src/en-BD.d.ts +49 -0
- package/src/en-BD.js +415 -0
- package/src/en-CA.d.ts +63 -0
- package/src/en-CA.js +518 -0
- package/src/en-GB.d.ts +56 -0
- package/src/en-GB.js +469 -0
- package/src/en-GH.d.ts +11 -0
- package/src/en-GH.js +345 -0
- package/src/en-IE.d.ts +56 -0
- package/src/en-IE.js +479 -0
- package/src/en-IN.d.ts +49 -0
- package/src/en-IN.js +415 -0
- package/src/en-KE.d.ts +11 -0
- package/src/en-KE.js +345 -0
- package/src/en-MY.d.ts +11 -0
- package/src/en-MY.js +347 -0
- package/src/en-NG.d.ts +56 -0
- package/src/en-NG.js +479 -0
- package/src/en-NZ.d.ts +11 -0
- package/src/en-NZ.js +375 -0
- package/src/en-PH.d.ts +11 -0
- package/src/en-PH.js +345 -0
- package/src/en-PK.d.ts +49 -0
- package/src/en-PK.js +415 -0
- package/src/en-SG.d.ts +11 -0
- package/src/en-SG.js +345 -0
- package/src/en-US.d.ts +63 -0
- package/src/en-US.js +516 -0
- package/src/en-ZA.d.ts +56 -0
- package/src/en-ZA.js +478 -0
- package/src/es-ES.d.ts +65 -0
- package/src/es-ES.js +541 -0
- package/src/es-MX.d.ts +58 -0
- package/{lib/languages/es.js → src/es-MX.js} +237 -47
- package/src/es-US.d.ts +58 -0
- package/src/es-US.js +446 -0
- package/src/fa-IR.d.ts +38 -0
- package/src/fa-IR.js +246 -0
- package/src/fi-FI.d.ts +46 -0
- package/src/fi-FI.js +379 -0
- package/src/fil-PH.d.ts +37 -0
- package/{lib/languages/fil.js → src/fil-PH.js} +149 -24
- package/src/fr-BE.d.ts +49 -0
- package/src/fr-BE.js +453 -0
- package/src/fr-FR.d.ts +63 -0
- package/{lib/languages/fr.js → src/fr-FR.js} +200 -47
- package/src/gu-IN.d.ts +35 -0
- package/src/gu-IN.js +259 -0
- package/src/ha-NG.d.ts +37 -0
- package/{lib/languages/ha.js → src/ha-NG.js} +110 -16
- package/src/hbo-IL.d.ts +39 -0
- package/{lib/languages/hbo.js → src/hbo-IL.js} +217 -43
- package/src/he-IL.d.ts +37 -0
- package/src/he-IL.js +537 -0
- package/src/hi-IN.d.ts +36 -0
- package/src/hi-IN.js +280 -0
- package/src/hr-HR.d.ts +42 -0
- package/src/hr-HR.js +463 -0
- package/src/hu-HU.d.ts +38 -0
- package/{lib/languages/hu.js → src/hu-HU.js} +164 -6
- package/src/id-ID.d.ts +38 -0
- package/{lib/languages/id.js → src/id-ID.js} +106 -20
- package/src/it-IT.d.ts +59 -0
- package/src/it-IT.js +506 -0
- package/src/ja-JP.d.ts +49 -0
- package/{lib/languages/ja.js → src/ja-JP.js} +119 -32
- package/src/ka-GE.d.ts +44 -0
- package/src/ka-GE.js +393 -0
- package/src/kn-IN.d.ts +35 -0
- package/{lib/languages/kn.js → src/kn-IN.js} +156 -34
- package/src/ko-KR.d.ts +45 -0
- package/{lib/languages/ko.js → src/ko-KR.js} +99 -24
- package/src/lt-LT.d.ts +49 -0
- package/src/lt-LT.js +543 -0
- package/src/lv-LV.d.ts +49 -0
- package/src/lv-LV.js +595 -0
- package/src/mr-IN.d.ts +36 -0
- package/src/mr-IN.js +260 -0
- package/src/ms-MY.d.ts +37 -0
- package/{lib/languages/ms.js → src/ms-MY.js} +118 -20
- package/src/nb-NO.d.ts +44 -0
- package/{lib/languages/nb.js → src/nb-NO.js} +165 -33
- package/src/nl-NL.d.ts +54 -0
- package/{lib/languages/nl.js → src/nl-NL.js} +271 -47
- package/src/pa-IN.d.ts +36 -0
- package/src/pa-IN.js +268 -0
- package/src/pl-PL.d.ts +55 -0
- package/src/pl-PL.js +585 -0
- package/src/pt-PT.d.ts +45 -0
- package/src/pt-PT.js +514 -0
- package/src/ro-RO.d.ts +44 -0
- package/{lib/languages/ro.js → src/ro-RO.js} +212 -18
- package/src/ru-RU.d.ts +50 -0
- package/src/ru-RU.js +535 -0
- package/src/sr-Cyrl-RS.d.ts +49 -0
- package/src/sr-Cyrl-RS.js +503 -0
- package/src/sr-Latn-RS.d.ts +49 -0
- package/src/sr-Latn-RS.js +503 -0
- package/src/sv-SE.d.ts +44 -0
- package/{lib/languages/sv.js → src/sv-SE.js} +149 -34
- package/src/sw-KE.d.ts +37 -0
- package/{lib/languages/sw.js → src/sw-KE.js} +117 -6
- package/src/ta-IN.d.ts +35 -0
- package/{lib/languages/ta.js → src/ta-IN.js} +163 -47
- package/src/te-IN.d.ts +35 -0
- package/{lib/languages/te.js → src/te-IN.js} +147 -46
- package/src/th-TH.d.ts +38 -0
- package/{lib/languages/th.js → src/th-TH.js} +99 -6
- package/src/tr-TR.d.ts +48 -0
- package/src/tr-TR.js +397 -0
- package/src/uk-UA.d.ts +42 -0
- package/src/uk-UA.js +463 -0
- package/src/ur-PK.d.ts +36 -0
- package/src/ur-PK.js +268 -0
- package/src/utils/expand-scientific.d.ts +32 -0
- package/src/utils/expand-scientific.js +65 -0
- package/src/utils/parse-cardinal.d.ts +14 -0
- package/{lib/utils/parse-numeric.js → src/utils/parse-cardinal.js} +14 -44
- package/src/utils/parse-currency.d.ts +14 -0
- package/src/utils/parse-currency.js +91 -0
- package/src/utils/parse-ordinal.d.ts +10 -0
- package/src/utils/parse-ordinal.js +103 -0
- package/src/vi-VN.d.ts +48 -0
- package/{lib/languages/vi.js → src/vi-VN.js} +124 -53
- package/src/yo-NG.d.ts +37 -0
- package/src/yo-NG.js +403 -0
- package/src/zh-Hans-CN.d.ts +48 -0
- package/{lib/languages/zh-Hans.js → src/zh-Hans-CN.js} +140 -8
- package/src/zh-Hant-TW.d.ts +50 -0
- package/{lib/languages/zh-Hant.js → src/zh-Hant-TW.js} +139 -8
- package/dist/languages/am-Latn.js +0 -3
- package/dist/languages/am-Latn.js.map +0 -1
- package/dist/languages/am.js +0 -3
- package/dist/languages/am.js.map +0 -1
- package/dist/languages/ar.js +0 -3
- package/dist/languages/ar.js.map +0 -1
- package/dist/languages/az.js +0 -3
- package/dist/languages/az.js.map +0 -1
- package/dist/languages/bn.js +0 -3
- package/dist/languages/bn.js.map +0 -1
- package/dist/languages/cs.js +0 -3
- package/dist/languages/cs.js.map +0 -1
- package/dist/languages/da.js +0 -3
- package/dist/languages/da.js.map +0 -1
- package/dist/languages/de.js +0 -3
- package/dist/languages/de.js.map +0 -1
- package/dist/languages/el.js +0 -3
- package/dist/languages/el.js.map +0 -1
- package/dist/languages/en.js +0 -3
- package/dist/languages/en.js.map +0 -1
- package/dist/languages/es.js +0 -3
- package/dist/languages/es.js.map +0 -1
- package/dist/languages/fa.js +0 -3
- package/dist/languages/fa.js.map +0 -1
- package/dist/languages/fi.js +0 -3
- package/dist/languages/fi.js.map +0 -1
- package/dist/languages/fil.js +0 -3
- package/dist/languages/fil.js.map +0 -1
- package/dist/languages/fr-BE.js +0 -3
- package/dist/languages/fr-BE.js.map +0 -1
- package/dist/languages/fr.js +0 -3
- package/dist/languages/fr.js.map +0 -1
- package/dist/languages/gu.js +0 -3
- package/dist/languages/gu.js.map +0 -1
- package/dist/languages/ha.js +0 -3
- package/dist/languages/ha.js.map +0 -1
- package/dist/languages/hbo.js +0 -3
- package/dist/languages/hbo.js.map +0 -1
- package/dist/languages/he.js +0 -3
- package/dist/languages/he.js.map +0 -1
- package/dist/languages/hi.js +0 -3
- package/dist/languages/hi.js.map +0 -1
- package/dist/languages/hr.js +0 -3
- package/dist/languages/hr.js.map +0 -1
- package/dist/languages/hu.js +0 -3
- package/dist/languages/hu.js.map +0 -1
- package/dist/languages/id.js +0 -3
- package/dist/languages/id.js.map +0 -1
- package/dist/languages/it.js +0 -3
- package/dist/languages/it.js.map +0 -1
- package/dist/languages/ja.js +0 -3
- package/dist/languages/ja.js.map +0 -1
- package/dist/languages/kn.js +0 -3
- package/dist/languages/kn.js.map +0 -1
- package/dist/languages/ko.js +0 -3
- package/dist/languages/ko.js.map +0 -1
- package/dist/languages/lt.js +0 -3
- package/dist/languages/lt.js.map +0 -1
- package/dist/languages/lv.js +0 -3
- package/dist/languages/lv.js.map +0 -1
- package/dist/languages/mr.js +0 -3
- package/dist/languages/mr.js.map +0 -1
- package/dist/languages/ms.js +0 -3
- package/dist/languages/ms.js.map +0 -1
- package/dist/languages/nb.js +0 -3
- package/dist/languages/nb.js.map +0 -1
- package/dist/languages/nl.js +0 -3
- package/dist/languages/nl.js.map +0 -1
- package/dist/languages/pa.js +0 -3
- package/dist/languages/pa.js.map +0 -1
- package/dist/languages/pl.js +0 -3
- package/dist/languages/pl.js.map +0 -1
- package/dist/languages/pt.js +0 -3
- package/dist/languages/pt.js.map +0 -1
- package/dist/languages/ro.js +0 -3
- package/dist/languages/ro.js.map +0 -1
- package/dist/languages/ru.js +0 -3
- package/dist/languages/ru.js.map +0 -1
- package/dist/languages/sr-Cyrl.js +0 -3
- package/dist/languages/sr-Cyrl.js.map +0 -1
- package/dist/languages/sr-Latn.js +0 -3
- package/dist/languages/sr-Latn.js.map +0 -1
- package/dist/languages/sv.js +0 -3
- package/dist/languages/sv.js.map +0 -1
- package/dist/languages/sw.js +0 -3
- package/dist/languages/sw.js.map +0 -1
- package/dist/languages/ta.js +0 -3
- package/dist/languages/ta.js.map +0 -1
- package/dist/languages/te.js +0 -3
- package/dist/languages/te.js.map +0 -1
- package/dist/languages/th.js +0 -3
- package/dist/languages/th.js.map +0 -1
- package/dist/languages/tr.js +0 -3
- package/dist/languages/tr.js.map +0 -1
- package/dist/languages/uk.js +0 -3
- package/dist/languages/uk.js.map +0 -1
- package/dist/languages/ur.js +0 -3
- package/dist/languages/ur.js.map +0 -1
- package/dist/languages/vi.js +0 -3
- package/dist/languages/vi.js.map +0 -1
- package/dist/languages/zh-Hans.js +0 -3
- package/dist/languages/zh-Hans.js.map +0 -1
- package/dist/languages/zh-Hant.js +0 -3
- package/dist/languages/zh-Hant.js.map +0 -1
- package/dist/n2words.js +0 -3
- package/dist/n2words.js.map +0 -1
- package/lib/languages/am-Latn.d.ts +0 -7
- package/lib/languages/am-Latn.js +0 -164
- package/lib/languages/am.d.ts +0 -7
- package/lib/languages/am.js +0 -164
- package/lib/languages/ar.d.ts +0 -17
- package/lib/languages/az.d.ts +0 -7
- package/lib/languages/az.js +0 -176
- package/lib/languages/bn.d.ts +0 -7
- package/lib/languages/bn.js +0 -145
- package/lib/languages/cs.d.ts +0 -18
- package/lib/languages/da.d.ts +0 -14
- package/lib/languages/de.d.ts +0 -17
- package/lib/languages/de.js +0 -332
- package/lib/languages/el.d.ts +0 -14
- package/lib/languages/el.js +0 -243
- package/lib/languages/en.d.ts +0 -17
- package/lib/languages/en.js +0 -256
- package/lib/languages/es.d.ts +0 -21
- package/lib/languages/fa.d.ts +0 -7
- package/lib/languages/fa.js +0 -134
- package/lib/languages/fi.d.ts +0 -14
- package/lib/languages/fi.js +0 -245
- package/lib/languages/fil.d.ts +0 -7
- package/lib/languages/fr-BE.d.ts +0 -11
- package/lib/languages/fr-BE.js +0 -300
- package/lib/languages/fr.d.ts +0 -21
- package/lib/languages/gu.d.ts +0 -7
- package/lib/languages/gu.js +0 -137
- package/lib/languages/ha.d.ts +0 -7
- package/lib/languages/hbo.d.ts +0 -13
- package/lib/languages/he.d.ts +0 -13
- package/lib/languages/he.js +0 -276
- package/lib/languages/hi.d.ts +0 -7
- package/lib/languages/hi.js +0 -145
- package/lib/languages/hr.d.ts +0 -11
- package/lib/languages/hr.js +0 -218
- package/lib/languages/hu.d.ts +0 -7
- package/lib/languages/id.d.ts +0 -7
- package/lib/languages/it.d.ts +0 -19
- package/lib/languages/it.js +0 -377
- package/lib/languages/ja.d.ts +0 -17
- package/lib/languages/kn.d.ts +0 -7
- package/lib/languages/ko.d.ts +0 -14
- package/lib/languages/lt.d.ts +0 -18
- package/lib/languages/lt.js +0 -310
- package/lib/languages/lv.d.ts +0 -18
- package/lib/languages/lv.js +0 -321
- package/lib/languages/mr.d.ts +0 -7
- package/lib/languages/mr.js +0 -137
- package/lib/languages/ms.d.ts +0 -7
- package/lib/languages/nb.d.ts +0 -14
- package/lib/languages/nl.d.ts +0 -26
- package/lib/languages/pa.d.ts +0 -7
- package/lib/languages/pa.js +0 -163
- package/lib/languages/pl.d.ts +0 -22
- package/lib/languages/pl.js +0 -330
- package/lib/languages/pt.d.ts +0 -17
- package/lib/languages/pt.js +0 -306
- package/lib/languages/ro.d.ts +0 -18
- package/lib/languages/ru.d.ts +0 -11
- package/lib/languages/ru.js +0 -240
- package/lib/languages/sr-Cyrl.d.ts +0 -11
- package/lib/languages/sr-Cyrl.js +0 -215
- package/lib/languages/sr-Latn.d.ts +0 -11
- package/lib/languages/sr-Latn.js +0 -215
- package/lib/languages/sv.d.ts +0 -14
- package/lib/languages/sw.d.ts +0 -7
- package/lib/languages/ta.d.ts +0 -7
- package/lib/languages/te.d.ts +0 -7
- package/lib/languages/th.d.ts +0 -7
- package/lib/languages/tr.d.ts +0 -18
- package/lib/languages/tr.js +0 -263
- package/lib/languages/uk.d.ts +0 -11
- package/lib/languages/uk.js +0 -218
- package/lib/languages/ur.d.ts +0 -7
- package/lib/languages/ur.js +0 -163
- package/lib/languages/vi.d.ts +0 -17
- package/lib/languages/zh-Hans.d.ts +0 -11
- package/lib/languages/zh-Hant.d.ts +0 -11
- package/lib/n2words.d.ts +0 -53
- package/lib/n2words.js +0 -122
- package/lib/utils/parse-numeric.d.ts +0 -17
- /package/{lib → src}/utils/is-plain-object.d.ts +0 -0
- /package/{lib → src}/utils/is-plain-object.js +0 -0
- /package/{lib → src}/utils/validate-options.d.ts +0 -0
- /package/{lib → src}/utils/validate-options.js +0 -0
package/src/fa-IR.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persian (Iran) language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: fa-IR | Persian as used in Iran
|
|
5
|
+
*
|
|
6
|
+
* Key features:
|
|
7
|
+
* - "و" (and) conjunction for compound numbers
|
|
8
|
+
* - Omit "یک" (one) before thousand
|
|
9
|
+
* - Pre-composed hundreds (دویست, سيصد, etc.)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
13
|
+
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
14
|
+
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
15
|
+
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Vocabulary
|
|
18
|
+
// ============================================================================
|
|
19
|
+
|
|
20
|
+
const ONES = { 1: 'یک', 2: 'دو', 3: 'سه', 4: 'چهار', 5: 'پنج', 6: 'شش', 7: 'هفت', 8: 'هشت', 9: 'نه' }
|
|
21
|
+
const TEENS = { 10: 'ده', 11: 'یازده', 12: 'دوازده', 13: 'سیزده', 14: 'چهارده', 15: 'پانزده', 16: 'شانزده', 17: 'هفده', 18: 'هجده', 19: 'نوزده' }
|
|
22
|
+
const TENS = { 20: 'بیست', 30: 'سی', 40: 'چهل', 50: 'پنجاه', 60: 'شصت', 70: 'هفتاد', 80: 'هشتاد', 90: 'نود' }
|
|
23
|
+
const HUNDREDS = { 100: 'صد', 200: 'دویست', 300: 'سيصد', 400: 'چهار صد', 500: 'پانصد', 600: 'ششصد', 700: 'هفتصد', 800: 'هشتصد', 900: 'نهصد' }
|
|
24
|
+
|
|
25
|
+
const THOUSAND = 'هزار'
|
|
26
|
+
const MILLION = 'میلیون'
|
|
27
|
+
const MILLIARD = 'میلیارد'
|
|
28
|
+
|
|
29
|
+
const ZERO = 'صفر'
|
|
30
|
+
const NEGATIVE = 'منفى'
|
|
31
|
+
const DECIMAL_SEP = 'ممیّز'
|
|
32
|
+
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Ordinal Vocabulary
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
// Persian ordinals: add -ُم (-om) suffix to cardinal
|
|
38
|
+
// Special forms for 1st, 2nd, 3rd
|
|
39
|
+
const ORDINAL_SUFFIX = 'م' // ـُم (-om)
|
|
40
|
+
const ORDINAL_ONES = {
|
|
41
|
+
1: 'اول', // avval (first)
|
|
42
|
+
2: 'دوم', // dovvom (second)
|
|
43
|
+
3: 'سوم', // sevvom (third)
|
|
44
|
+
4: 'چهارم',
|
|
45
|
+
5: 'پنجم',
|
|
46
|
+
6: 'ششم',
|
|
47
|
+
7: 'هفتم',
|
|
48
|
+
8: 'هشتم',
|
|
49
|
+
9: 'نهم'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// Currency Vocabulary (Iranian Rial)
|
|
54
|
+
// ============================================================================
|
|
55
|
+
|
|
56
|
+
const RIAL = 'ریال'
|
|
57
|
+
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Conversion Functions
|
|
60
|
+
// ============================================================================
|
|
61
|
+
|
|
62
|
+
function integerToWords (n) {
|
|
63
|
+
if (n === 0n) return ZERO
|
|
64
|
+
|
|
65
|
+
// 1-9
|
|
66
|
+
if (n <= 9n) {
|
|
67
|
+
return ONES[Number(n)]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 10-19
|
|
71
|
+
if (n <= 19n) {
|
|
72
|
+
return TEENS[Number(n)]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 20-99
|
|
76
|
+
if (n < 100n) {
|
|
77
|
+
const ones = n % 10n
|
|
78
|
+
const tens = n - ones
|
|
79
|
+
if (ones === 0n) {
|
|
80
|
+
return TENS[Number(tens)]
|
|
81
|
+
}
|
|
82
|
+
return `${TENS[Number(tens)]} و ${ONES[Number(ones)]}`
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 100-999
|
|
86
|
+
if (n < 1000n) {
|
|
87
|
+
const hundreds = 100n * (n / 100n)
|
|
88
|
+
const remainder = n - hundreds
|
|
89
|
+
if (remainder === 0n) {
|
|
90
|
+
return HUNDREDS[Number(hundreds)]
|
|
91
|
+
}
|
|
92
|
+
return `${HUNDREDS[Number(hundreds)]} و ${integerToWords(remainder)}`
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 1000-999999
|
|
96
|
+
if (n < 1_000_000n) {
|
|
97
|
+
const thousandMultiplier = n / 1000n
|
|
98
|
+
// Persian omits "one" before thousand: 1000 is just "هزار", not "یک هزار"
|
|
99
|
+
const thousandPrefix = thousandMultiplier === 1n
|
|
100
|
+
? ''
|
|
101
|
+
: integerToWords(thousandMultiplier) + ' '
|
|
102
|
+
const remainder = n % 1000n
|
|
103
|
+
const suffix = remainder === 0n ? '' : ' ' + integerToWords(remainder)
|
|
104
|
+
return `${thousandPrefix}${THOUSAND}${suffix}`
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 1000000-999999999 (millions)
|
|
108
|
+
if (n < 1_000_000_000n) {
|
|
109
|
+
const millionMultiplier = n / 1_000_000n
|
|
110
|
+
const millionPrefix = integerToWords(millionMultiplier) + ' ' + MILLION
|
|
111
|
+
const remainder = n % 1_000_000n
|
|
112
|
+
const suffix = remainder === 0n ? '' : ' و ' + integerToWords(remainder)
|
|
113
|
+
return `${millionPrefix}${suffix}`
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 1000000000+ (milliards - 10^9)
|
|
117
|
+
const milliardMultiplier = n / 1_000_000_000n
|
|
118
|
+
const milliardPrefix = integerToWords(milliardMultiplier) + ' ' + MILLIARD
|
|
119
|
+
const remainder = n % 1_000_000_000n
|
|
120
|
+
const suffix = remainder === 0n ? '' : ' و ' + integerToWords(remainder)
|
|
121
|
+
return `${milliardPrefix}${suffix}`
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function decimalPartToWords (decimalPart) {
|
|
125
|
+
let result = ''
|
|
126
|
+
let i = 0
|
|
127
|
+
|
|
128
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
129
|
+
if (result) result += ' '
|
|
130
|
+
result += ZERO
|
|
131
|
+
i++
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const remainder = decimalPart.slice(i)
|
|
135
|
+
if (remainder) {
|
|
136
|
+
if (result) result += ' '
|
|
137
|
+
result += integerToWords(BigInt(remainder))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return result
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Converts a numeric value to Persian words.
|
|
145
|
+
*
|
|
146
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
147
|
+
* @returns {string} The number in Persian words
|
|
148
|
+
*/
|
|
149
|
+
function toCardinal (value) {
|
|
150
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
151
|
+
|
|
152
|
+
let result = ''
|
|
153
|
+
|
|
154
|
+
if (isNegative) {
|
|
155
|
+
result = NEGATIVE + ' '
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
result += integerToWords(integerPart)
|
|
159
|
+
|
|
160
|
+
if (decimalPart) {
|
|
161
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return result
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ============================================================================
|
|
168
|
+
// ORDINAL: toOrdinal(value)
|
|
169
|
+
// ============================================================================
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Converts a non-negative integer to Persian ordinal words.
|
|
173
|
+
*
|
|
174
|
+
* Persian ordinals: اول (1st), دوم (2nd), سوم (3rd), then cardinal + م suffix.
|
|
175
|
+
*
|
|
176
|
+
* @param {bigint} n - Positive integer to convert
|
|
177
|
+
* @returns {string} Persian ordinal words
|
|
178
|
+
*/
|
|
179
|
+
function integerToOrdinal (n) {
|
|
180
|
+
// Special forms for 1-9
|
|
181
|
+
if (n >= 1n && n <= 9n) {
|
|
182
|
+
return ORDINAL_ONES[Number(n)]
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// For 10+, add -م suffix to cardinal
|
|
186
|
+
const cardinal = integerToWords(n)
|
|
187
|
+
return cardinal + ORDINAL_SUFFIX
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Converts a numeric value to Persian ordinal words.
|
|
192
|
+
*
|
|
193
|
+
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
194
|
+
* @returns {string} The number as ordinal words
|
|
195
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
196
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* toOrdinal(1) // 'اول'
|
|
200
|
+
* toOrdinal(2) // 'دوم'
|
|
201
|
+
* toOrdinal(10) // 'دهم'
|
|
202
|
+
*/
|
|
203
|
+
function toOrdinal (value) {
|
|
204
|
+
const integerPart = parseOrdinalValue(value)
|
|
205
|
+
return integerToOrdinal(integerPart)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// ============================================================================
|
|
209
|
+
// CURRENCY: toCurrency(value)
|
|
210
|
+
// ============================================================================
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Converts a numeric value to Persian currency words (Rial).
|
|
214
|
+
*
|
|
215
|
+
* Iranian Rial has no subunit in modern usage.
|
|
216
|
+
* (Historically dinar was 1/100 rial, but not used today)
|
|
217
|
+
*
|
|
218
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
219
|
+
* @returns {string} The amount in Persian currency words
|
|
220
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
221
|
+
* @throws {Error} If value is not a valid number format
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* toCurrency(42) // 'چهل و دو ریال'
|
|
225
|
+
* toCurrency(1000) // 'هزار ریال'
|
|
226
|
+
* toCurrency(-5) // 'منفى پنج ریال'
|
|
227
|
+
*/
|
|
228
|
+
function toCurrency (value) {
|
|
229
|
+
const { isNegative, dollars: rial } = parseCurrencyValue(value)
|
|
230
|
+
|
|
231
|
+
let result = ''
|
|
232
|
+
if (isNegative) {
|
|
233
|
+
result = NEGATIVE + ' '
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
result += integerToWords(rial)
|
|
237
|
+
result += ' ' + RIAL
|
|
238
|
+
|
|
239
|
+
return result
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// ============================================================================
|
|
243
|
+
// Exports
|
|
244
|
+
// ============================================================================
|
|
245
|
+
|
|
246
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/fi-FI.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Finnish words.
|
|
3
|
+
*
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @returns {string} The number in Finnish words
|
|
6
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
7
|
+
* @throws {Error} If value is not a valid number format
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* toCardinal(21) // 'kaksikymmentäyksi'
|
|
11
|
+
* toCardinal(1000) // 'tuhat'
|
|
12
|
+
* toCardinal('3.14') // 'kolme pilkku yksi neljä'
|
|
13
|
+
*/
|
|
14
|
+
export function toCardinal(value: number | string | bigint): string;
|
|
15
|
+
/**
|
|
16
|
+
* Converts a numeric value to Finnish ordinal words.
|
|
17
|
+
*
|
|
18
|
+
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
19
|
+
* @returns {string} The number as ordinal words
|
|
20
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
21
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* toOrdinal(1) // 'ensimmäinen'
|
|
25
|
+
* toOrdinal(2) // 'toinen'
|
|
26
|
+
* toOrdinal(3) // 'kolmas'
|
|
27
|
+
* toOrdinal(10) // 'kymmenes'
|
|
28
|
+
*/
|
|
29
|
+
export function toOrdinal(value: number | string | bigint): string;
|
|
30
|
+
/**
|
|
31
|
+
* Converts a numeric value to Finnish currency words (Euro).
|
|
32
|
+
*
|
|
33
|
+
* Euro uses sentti as subunit (100 senttiä = 1 euro).
|
|
34
|
+
* Finnish has singular/plural: 1 euro vs 2 euroa, 1 sentti vs 2 senttiä.
|
|
35
|
+
*
|
|
36
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
37
|
+
* @returns {string} The amount in Finnish currency words
|
|
38
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
39
|
+
* @throws {Error} If value is not a valid number format
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* toCurrency(1) // 'yksi euro'
|
|
43
|
+
* toCurrency(42) // 'neljäkymmentäkaksi euroa'
|
|
44
|
+
* toCurrency(1.50) // 'yksi euro viisikymmentä senttiä'
|
|
45
|
+
*/
|
|
46
|
+
export function toCurrency(value: number | string | bigint): string;
|
package/src/fi-FI.js
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finnish (Finland) language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: fi-FI | Finnish as used in Finland
|
|
5
|
+
*
|
|
6
|
+
* Key features:
|
|
7
|
+
* - Compound tens+ones without spaces: "kaksikymmentäyksi" (21)
|
|
8
|
+
* - Teens with "-toista" suffix
|
|
9
|
+
* - Omit "yksi" before sata/tuhat but keep before miljoona+
|
|
10
|
+
* - Long scale: miljoona, miljardi, biljoona
|
|
11
|
+
* - Per-digit decimal reading
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
15
|
+
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
16
|
+
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Vocabulary (module-level constants)
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
const ONES = ['', 'yksi', 'kaksi', 'kolme', 'neljä', 'viisi', 'kuusi', 'seitsemän', 'kahdeksan', 'yhdeksän']
|
|
23
|
+
|
|
24
|
+
const TEENS = ['kymmenen', 'yksitoista', 'kaksitoista', 'kolmetoista', 'neljätoista', 'viisitoista', 'kuusitoista', 'seitsemäntoista', 'kahdeksantoista', 'yhdeksäntoista']
|
|
25
|
+
|
|
26
|
+
// Tens use "kymmentä" suffix
|
|
27
|
+
const TENS = ['', '', 'kaksikymmentä', 'kolmekymmentä', 'neljäkymmentä', 'viisikymmentä', 'kuusikymmentä', 'seitsemänkymmentä', 'kahdeksankymmentä', 'yhdeksänkymmentä']
|
|
28
|
+
|
|
29
|
+
const HUNDRED = 'sata'
|
|
30
|
+
const THOUSAND = 'tuhat'
|
|
31
|
+
|
|
32
|
+
const ZERO = 'nolla'
|
|
33
|
+
const NEGATIVE = 'miinus'
|
|
34
|
+
const DECIMAL_SEP = 'pilkku'
|
|
35
|
+
|
|
36
|
+
// Long scale
|
|
37
|
+
const SCALES = ['miljoona', 'miljardi', 'biljoona', 'triljoona']
|
|
38
|
+
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// Ordinal Vocabulary
|
|
41
|
+
// ============================================================================
|
|
42
|
+
|
|
43
|
+
// Finnish ordinals: special forms for 1st-2nd, then -s suffix
|
|
44
|
+
const ORDINAL_FIRST = 'ensimmäinen'
|
|
45
|
+
const ORDINAL_SECOND = 'toinen'
|
|
46
|
+
const ORDINAL_SUFFIX = 's' // e.g., kolmas, neljäs
|
|
47
|
+
|
|
48
|
+
// Ordinal forms for basic numbers
|
|
49
|
+
const ORDINAL_ONES = ['', 'ensimmäinen', 'toinen', 'kolmas', 'neljäs', 'viides', 'kuudes', 'seitsemäs', 'kahdeksas', 'yhdeksäs']
|
|
50
|
+
const ORDINAL_TEENS = ['kymmenes', 'yhdestoista', 'kahdestoista', 'kolmastoista', 'neljästoista', 'viidestoista', 'kuudestoista', 'seitsemästoista', 'kahdeksastoista', 'yhdeksästoista']
|
|
51
|
+
const ORDINAL_TENS = ['', '', 'kahdeskymmenes', 'kolmaskymmenes', 'neljäskymmenes', 'viideskymmenes', 'kuudeskymmenes', 'seitsemäskymmenes', 'kahdeksaskymmenes', 'yhdeksäskymmenes']
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Currency Vocabulary (Euro)
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
const EURO = 'euroa'
|
|
58
|
+
const EURO_SINGULAR = 'euro'
|
|
59
|
+
const CENT = 'senttiä'
|
|
60
|
+
const CENT_SINGULAR = 'sentti'
|
|
61
|
+
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// Segment Building
|
|
64
|
+
// ============================================================================
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Builds segment word for 0-999.
|
|
68
|
+
* Omits "yksi" before "sata" (hundred).
|
|
69
|
+
*/
|
|
70
|
+
function buildSegment (n) {
|
|
71
|
+
if (n === 0) return ''
|
|
72
|
+
|
|
73
|
+
const ones = n % 10
|
|
74
|
+
const tens = Math.trunc(n / 10) % 10
|
|
75
|
+
const hundreds = Math.trunc(n / 100)
|
|
76
|
+
|
|
77
|
+
const parts = []
|
|
78
|
+
|
|
79
|
+
// Hundreds - omit "yksi" before sata
|
|
80
|
+
if (hundreds > 0) {
|
|
81
|
+
if (hundreds === 1) {
|
|
82
|
+
parts.push(HUNDRED)
|
|
83
|
+
} else {
|
|
84
|
+
parts.push(ONES[hundreds] + ' ' + HUNDRED)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Tens and ones
|
|
89
|
+
const tensOnes = n % 100
|
|
90
|
+
|
|
91
|
+
if (tensOnes === 0) {
|
|
92
|
+
// Just hundreds
|
|
93
|
+
} else if (tensOnes < 10) {
|
|
94
|
+
parts.push(ONES[ones])
|
|
95
|
+
} else if (tensOnes < 20) {
|
|
96
|
+
parts.push(TEENS[ones])
|
|
97
|
+
} else if (ones === 0) {
|
|
98
|
+
parts.push(TENS[tens])
|
|
99
|
+
} else {
|
|
100
|
+
// Compound: "kaksikymmentäyksi" (no space)
|
|
101
|
+
parts.push(TENS[tens] + ONES[ones])
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return parts.join(' ')
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ============================================================================
|
|
108
|
+
// Conversion Functions
|
|
109
|
+
// ============================================================================
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Converts a non-negative integer to Finnish words.
|
|
113
|
+
*
|
|
114
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
115
|
+
* @returns {string} Finnish words
|
|
116
|
+
*/
|
|
117
|
+
function integerToWords (n) {
|
|
118
|
+
if (n === 0n) return ZERO
|
|
119
|
+
|
|
120
|
+
// Fast path: numbers < 1000 (direct lookup)
|
|
121
|
+
if (n < 1000n) {
|
|
122
|
+
return buildSegment(Number(n))
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Fast path: numbers < 1,000,000 (thousands)
|
|
126
|
+
if (n < 1_000_000n) {
|
|
127
|
+
const thousands = Number(n / 1000n)
|
|
128
|
+
const remainder = Number(n % 1000n)
|
|
129
|
+
|
|
130
|
+
// Omit "yksi" before tuhat
|
|
131
|
+
let result
|
|
132
|
+
if (thousands === 1) {
|
|
133
|
+
result = THOUSAND
|
|
134
|
+
} else {
|
|
135
|
+
result = buildSegment(thousands) + ' ' + THOUSAND
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (remainder > 0) {
|
|
139
|
+
result += ' ' + buildSegment(remainder)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return result
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
146
|
+
return buildLargeNumberWords(n)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Builds words for numbers >= 1,000,000.
|
|
151
|
+
*
|
|
152
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
153
|
+
* @returns {string} Finnish words
|
|
154
|
+
*/
|
|
155
|
+
function buildLargeNumberWords (n) {
|
|
156
|
+
const numStr = n.toString()
|
|
157
|
+
const len = numStr.length
|
|
158
|
+
|
|
159
|
+
// Build segments of 3 digits from right to left
|
|
160
|
+
const segments = []
|
|
161
|
+
const segmentSize = 3
|
|
162
|
+
|
|
163
|
+
const remainderLen = len % segmentSize
|
|
164
|
+
let pos = 0
|
|
165
|
+
if (remainderLen > 0) {
|
|
166
|
+
segments.push(Number(numStr.slice(0, remainderLen)))
|
|
167
|
+
pos = remainderLen
|
|
168
|
+
}
|
|
169
|
+
while (pos < len) {
|
|
170
|
+
segments.push(Number(numStr.slice(pos, pos + segmentSize)))
|
|
171
|
+
pos += segmentSize
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Convert segments to words
|
|
175
|
+
const parts = []
|
|
176
|
+
let scaleIndex = segments.length - 1
|
|
177
|
+
|
|
178
|
+
for (let i = 0; i < segments.length; i++) {
|
|
179
|
+
const segment = segments[i]
|
|
180
|
+
|
|
181
|
+
if (segment !== 0) {
|
|
182
|
+
const segmentWord = buildSegment(segment)
|
|
183
|
+
|
|
184
|
+
if (scaleIndex === 0) {
|
|
185
|
+
// Units segment
|
|
186
|
+
parts.push(segmentWord)
|
|
187
|
+
} else if (scaleIndex === 1) {
|
|
188
|
+
// Thousands - omit "yksi" before tuhat
|
|
189
|
+
if (segment === 1) {
|
|
190
|
+
parts.push(THOUSAND)
|
|
191
|
+
} else {
|
|
192
|
+
parts.push(segmentWord + ' ' + THOUSAND)
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
// Millions+ - keep "yksi" before scale words
|
|
196
|
+
const scaleWord = SCALES[scaleIndex - 2]
|
|
197
|
+
parts.push(segmentWord + ' ' + scaleWord)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
scaleIndex--
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return parts.join(' ')
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Converts decimal digits to Finnish words (per-digit).
|
|
209
|
+
*
|
|
210
|
+
* @param {string} decimalPart - Decimal digits (without the point)
|
|
211
|
+
* @returns {string} Finnish words for decimal part
|
|
212
|
+
*/
|
|
213
|
+
function decimalPartToWords (decimalPart) {
|
|
214
|
+
const parts = []
|
|
215
|
+
|
|
216
|
+
for (const digit of decimalPart) {
|
|
217
|
+
const d = parseInt(digit, 10)
|
|
218
|
+
if (d === 0) {
|
|
219
|
+
parts.push(ZERO)
|
|
220
|
+
} else {
|
|
221
|
+
parts.push(ONES[d])
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return parts.join(' ')
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Converts a numeric value to Finnish words.
|
|
230
|
+
*
|
|
231
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
232
|
+
* @returns {string} The number in Finnish words
|
|
233
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
234
|
+
* @throws {Error} If value is not a valid number format
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* toCardinal(21) // 'kaksikymmentäyksi'
|
|
238
|
+
* toCardinal(1000) // 'tuhat'
|
|
239
|
+
* toCardinal('3.14') // 'kolme pilkku yksi neljä'
|
|
240
|
+
*/
|
|
241
|
+
function toCardinal (value) {
|
|
242
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
243
|
+
|
|
244
|
+
let result = ''
|
|
245
|
+
|
|
246
|
+
if (isNegative) {
|
|
247
|
+
result = NEGATIVE + ' '
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
result += integerToWords(integerPart)
|
|
251
|
+
|
|
252
|
+
if (decimalPart) {
|
|
253
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return result
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// ============================================================================
|
|
260
|
+
// ORDINAL: toOrdinal(value)
|
|
261
|
+
// ============================================================================
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Builds ordinal segment for 0-99.
|
|
265
|
+
* Finnish ordinals have special forms.
|
|
266
|
+
*/
|
|
267
|
+
function buildOrdinalSegment (n) {
|
|
268
|
+
if (n === 0) return ''
|
|
269
|
+
if (n < 10) return ORDINAL_ONES[n]
|
|
270
|
+
if (n < 20) return ORDINAL_TEENS[n - 10]
|
|
271
|
+
|
|
272
|
+
const ones = n % 10
|
|
273
|
+
const tens = Math.trunc(n / 10)
|
|
274
|
+
|
|
275
|
+
if (ones === 0) {
|
|
276
|
+
return ORDINAL_TENS[tens]
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Compound: kahdeskymmenes + first/second/third etc
|
|
280
|
+
// For compound ordinals, only the last part is ordinal form
|
|
281
|
+
return TENS[tens] + ORDINAL_ONES[ones]
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Converts a non-negative integer to Finnish ordinal words.
|
|
286
|
+
*
|
|
287
|
+
* Finnish ordinals: ensimmäinen (1st), toinen (2nd), kolmas (3rd), etc.
|
|
288
|
+
* For larger numbers, use cardinal + ordinal ending.
|
|
289
|
+
*
|
|
290
|
+
* @param {bigint} n - Positive integer to convert
|
|
291
|
+
* @returns {string} Finnish ordinal words
|
|
292
|
+
*/
|
|
293
|
+
function integerToOrdinal (n) {
|
|
294
|
+
// Special cases
|
|
295
|
+
if (n === 1n) return ORDINAL_FIRST
|
|
296
|
+
if (n === 2n) return ORDINAL_SECOND
|
|
297
|
+
|
|
298
|
+
// For numbers < 100, use ordinal forms
|
|
299
|
+
if (n < 100n) {
|
|
300
|
+
return buildOrdinalSegment(Number(n))
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// For larger numbers, use cardinal form with ordinal suffix on last part
|
|
304
|
+
// This is a simplification - full Finnish ordinal grammar is complex
|
|
305
|
+
const cardinal = integerToWords(n)
|
|
306
|
+
// Add ordinal suffix approximation
|
|
307
|
+
return cardinal + ORDINAL_SUFFIX
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Converts a numeric value to Finnish ordinal words.
|
|
312
|
+
*
|
|
313
|
+
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
314
|
+
* @returns {string} The number as ordinal words
|
|
315
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
316
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* toOrdinal(1) // 'ensimmäinen'
|
|
320
|
+
* toOrdinal(2) // 'toinen'
|
|
321
|
+
* toOrdinal(3) // 'kolmas'
|
|
322
|
+
* toOrdinal(10) // 'kymmenes'
|
|
323
|
+
*/
|
|
324
|
+
function toOrdinal (value) {
|
|
325
|
+
const integerPart = parseOrdinalValue(value)
|
|
326
|
+
return integerToOrdinal(integerPart)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// ============================================================================
|
|
330
|
+
// CURRENCY: toCurrency(value)
|
|
331
|
+
// ============================================================================
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Converts a numeric value to Finnish currency words (Euro).
|
|
335
|
+
*
|
|
336
|
+
* Euro uses sentti as subunit (100 senttiä = 1 euro).
|
|
337
|
+
* Finnish has singular/plural: 1 euro vs 2 euroa, 1 sentti vs 2 senttiä.
|
|
338
|
+
*
|
|
339
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
340
|
+
* @returns {string} The amount in Finnish currency words
|
|
341
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
342
|
+
* @throws {Error} If value is not a valid number format
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* toCurrency(1) // 'yksi euro'
|
|
346
|
+
* toCurrency(42) // 'neljäkymmentäkaksi euroa'
|
|
347
|
+
* toCurrency(1.50) // 'yksi euro viisikymmentä senttiä'
|
|
348
|
+
*/
|
|
349
|
+
function toCurrency (value) {
|
|
350
|
+
const { isNegative, dollars: euros, cents } = parseCurrencyValue(value)
|
|
351
|
+
|
|
352
|
+
let result = ''
|
|
353
|
+
if (isNegative) {
|
|
354
|
+
result = NEGATIVE + ' '
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Euro part - always show if non-zero, or if no cents
|
|
358
|
+
if (euros > 0n || cents === 0n) {
|
|
359
|
+
result += integerToWords(euros)
|
|
360
|
+
result += ' ' + (euros === 1n ? EURO_SINGULAR : EURO)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Cent part
|
|
364
|
+
if (cents > 0n) {
|
|
365
|
+
if (euros > 0n) {
|
|
366
|
+
result += ' '
|
|
367
|
+
}
|
|
368
|
+
result += integerToWords(cents)
|
|
369
|
+
result += ' ' + (cents === 1n ? CENT_SINGULAR : CENT)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return result
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// ============================================================================
|
|
376
|
+
// Public API
|
|
377
|
+
// ============================================================================
|
|
378
|
+
|
|
379
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/fil-PH.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Filipino words.
|
|
3
|
+
*
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @returns {string} The number in Filipino words
|
|
6
|
+
*/
|
|
7
|
+
export function toCardinal(value: number | string | bigint): string;
|
|
8
|
+
/**
|
|
9
|
+
* Converts a numeric value to Filipino 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) // 'una'
|
|
18
|
+
* toOrdinal(2) // 'ikalawa'
|
|
19
|
+
* toOrdinal(3) // 'ika-tatlo'
|
|
20
|
+
*/
|
|
21
|
+
export function toOrdinal(value: number | string | bigint): string;
|
|
22
|
+
/**
|
|
23
|
+
* Converts a numeric value to Filipino currency words (Philippine Peso).
|
|
24
|
+
*
|
|
25
|
+
* Uses piso (peso) and sentimo (centavo).
|
|
26
|
+
*
|
|
27
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
28
|
+
* @returns {string} The amount in Filipino currency words
|
|
29
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
30
|
+
* @throws {Error} If value is not a valid number format
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* toCurrency(42) // 'apatnapu dalawang piso'
|
|
34
|
+
* toCurrency(1.50) // 'isang piso at limampung sentimo'
|
|
35
|
+
* toCurrency(-5) // 'negatibo limang piso'
|
|
36
|
+
*/
|
|
37
|
+
export function toCurrency(value: number | string | bigint): string;
|