n2words 3.1.0 → 5.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 +51 -40
- 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-BR.js +2 -0
- package/dist/pt-BR.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 +61 -88
- 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/{lib/languages/bn.js → src/bn-BD.js} +110 -6
- package/src/cs-CZ.d.ts +49 -0
- package/{lib/languages/cs.js → src/cs-CZ.js} +240 -14
- package/src/da-DK.d.ts +44 -0
- package/{lib/languages/da.js → src/da-DK.js} +131 -11
- 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/{lib/languages/en.js → src/en-NZ.js} +164 -31
- 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} +228 -18
- 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/{lib/languages/fi.js → src/fi-FI.js} +152 -11
- package/src/fil-PH.d.ts +37 -0
- package/{lib/languages/fil.js → src/fil-PH.js} +144 -8
- package/src/fr-BE.d.ts +49 -0
- package/{lib/languages → src}/fr-BE.js +175 -13
- package/src/fr-FR.d.ts +63 -0
- package/{lib/languages/fr.js → src/fr-FR.js} +182 -16
- package/src/gu-IN.d.ts +35 -0
- package/{lib/languages/gu.js → src/gu-IN.js} +115 -6
- package/src/ha-NG.d.ts +37 -0
- package/{lib/languages/ha.js → src/ha-NG.js} +107 -8
- package/src/hbo-IL.d.ts +39 -0
- package/{lib/languages/hbo.js → src/hbo-IL.js} +211 -19
- package/src/he-IL.d.ts +37 -0
- package/src/he-IL.js +537 -0
- package/src/hi-IN.d.ts +36 -0
- package/{lib/languages/hi.js → src/hi-IN.js} +116 -6
- 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} +99 -8
- package/src/it-IT.d.ts +59 -0
- package/{lib/languages/it.js → src/it-IT.js} +179 -15
- package/src/ja-JP.d.ts +49 -0
- package/{lib/languages/ja.js → src/ja-JP.js} +111 -12
- package/src/ka-GE.d.ts +44 -0
- package/{lib/languages/ka.js → src/ka-GE.js} +113 -11
- package/src/kn-IN.d.ts +35 -0
- package/{lib/languages/kn.js → src/kn-IN.js} +115 -6
- package/src/ko-KR.d.ts +45 -0
- package/{lib/languages/ko.js → src/ko-KR.js} +94 -12
- 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/{lib/languages/mr.js → src/mr-IN.js} +116 -6
- package/src/ms-MY.d.ts +37 -0
- package/{lib/languages/ms.js → src/ms-MY.js} +111 -8
- package/src/nb-NO.d.ts +44 -0
- package/{lib/languages/nb.js → src/nb-NO.js} +153 -11
- package/src/nl-NL.d.ts +54 -0
- package/{lib/languages/nl.js → src/nl-NL.js} +260 -18
- package/src/pa-IN.d.ts +36 -0
- package/{lib/languages/pa.js → src/pa-IN.js} +116 -6
- package/src/pl-PL.d.ts +55 -0
- package/src/pl-PL.js +585 -0
- package/src/pt-BR.d.ts +31 -0
- package/src/pt-BR.js +534 -0
- package/src/pt-PT.d.ts +45 -0
- package/{lib/languages/pt.js → src/pt-PT.js} +234 -12
- 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} +136 -11
- 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} +109 -6
- package/src/te-IN.d.ts +35 -0
- package/{lib/languages/te.js → src/te-IN.js} +115 -6
- 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/{lib/languages/tr.js → src/tr-TR.js} +168 -23
- package/src/uk-UA.d.ts +42 -0
- package/src/uk-UA.js +463 -0
- package/src/ur-PK.d.ts +36 -0
- package/{lib/languages/ur.js → src/ur-PK.js} +116 -6
- 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} +102 -11
- package/src/yo-NG.d.ts +37 -0
- package/{lib/languages/yo.js → src/yo-NG.js} +109 -9
- 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/ka.js +0 -3
- package/dist/languages/ka.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/yo.js +0 -3
- package/dist/languages/yo.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 -159
- package/lib/languages/am.d.ts +0 -7
- package/lib/languages/am.js +0 -159
- package/lib/languages/ar.d.ts +0 -17
- package/lib/languages/az.d.ts +0 -7
- package/lib/languages/az.js +0 -171
- package/lib/languages/bn.d.ts +0 -7
- 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 -320
- package/lib/languages/el.d.ts +0 -14
- package/lib/languages/el.js +0 -236
- package/lib/languages/en.d.ts +0 -17
- 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/fil.d.ts +0 -7
- package/lib/languages/fr-BE.d.ts +0 -11
- package/lib/languages/fr.d.ts +0 -21
- package/lib/languages/gu.d.ts +0 -7
- 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 -265
- package/lib/languages/hi.d.ts +0 -7
- package/lib/languages/hr.d.ts +0 -11
- package/lib/languages/hr.js +0 -224
- 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/ja.d.ts +0 -17
- package/lib/languages/ka.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 -301
- package/lib/languages/lv.d.ts +0 -18
- package/lib/languages/lv.js +0 -312
- package/lib/languages/mr.d.ts +0 -7
- 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/pl.d.ts +0 -22
- package/lib/languages/pl.js +0 -317
- package/lib/languages/pt.d.ts +0 -17
- package/lib/languages/ro.d.ts +0 -18
- package/lib/languages/ru.d.ts +0 -11
- package/lib/languages/ru.js +0 -245
- package/lib/languages/sr-Cyrl.d.ts +0 -11
- package/lib/languages/sr-Cyrl.js +0 -221
- package/lib/languages/sr-Latn.d.ts +0 -11
- package/lib/languages/sr-Latn.js +0 -221
- 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/uk.d.ts +0 -11
- package/lib/languages/uk.js +0 -224
- package/lib/languages/ur.d.ts +0 -7
- package/lib/languages/vi.d.ts +0 -17
- package/lib/languages/yo.d.ts +0 -7
- package/lib/languages/zh-Hans.d.ts +0 -11
- package/lib/languages/zh-Hant.d.ts +0 -11
- package/lib/n2words.d.ts +0 -55
- package/lib/n2words.js +0 -126
- 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
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Arabic language converter
|
|
2
|
+
* Arabic (Saudi Arabia) language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: ar-SA | Modern Standard Arabic as used in Saudi Arabia
|
|
3
5
|
*
|
|
4
6
|
* Self-contained converter with gender agreement and complex pluralization.
|
|
5
7
|
*
|
|
@@ -10,8 +12,10 @@
|
|
|
10
12
|
* - "و" (and) conjunction between segments
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
+
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
16
|
+
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
17
|
+
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
18
|
+
import { validateOptions } from './utils/validate-options.js'
|
|
15
19
|
|
|
16
20
|
// ============================================================================
|
|
17
21
|
// Vocabulary
|
|
@@ -38,6 +42,32 @@ const NEGATIVE = 'ناقص'
|
|
|
38
42
|
const DECIMAL_SEP = 'فاصلة'
|
|
39
43
|
const AND = 'و'
|
|
40
44
|
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Ordinal Vocabulary
|
|
47
|
+
// ============================================================================
|
|
48
|
+
|
|
49
|
+
// Masculine ordinal forms (1-10)
|
|
50
|
+
const ORDINAL_MASC = ['الأول', 'الثاني', 'الثالث', 'الرابع', 'الخامس', 'السادس', 'السابع', 'الثامن', 'التاسع', 'العاشر']
|
|
51
|
+
|
|
52
|
+
// Feminine ordinal forms (1-10)
|
|
53
|
+
const ORDINAL_FEM = ['الأولى', 'الثانية', 'الثالثة', 'الرابعة', 'الخامسة', 'السادسة', 'السابعة', 'الثامنة', 'التاسعة', 'العاشرة']
|
|
54
|
+
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// Currency Vocabulary (Saudi Riyal)
|
|
57
|
+
// ============================================================================
|
|
58
|
+
|
|
59
|
+
// Riyal: singular, dual, plural (3-10), plural (11+)
|
|
60
|
+
const RIYAL_SINGULAR = 'ريال'
|
|
61
|
+
const RIYAL_DUAL = 'ريالان'
|
|
62
|
+
const RIYAL_PLURAL_3_10 = 'ريالات'
|
|
63
|
+
const RIYAL_PLURAL_11 = 'ريالاً'
|
|
64
|
+
|
|
65
|
+
// Halala: singular, dual, plural (3-10), plural (11+)
|
|
66
|
+
const HALALA_SINGULAR = 'هللة'
|
|
67
|
+
const HALALA_DUAL = 'هللتان'
|
|
68
|
+
const HALALA_PLURAL_3_10 = 'هللات'
|
|
69
|
+
const HALALA_PLURAL_11 = 'هللة'
|
|
70
|
+
|
|
41
71
|
// ============================================================================
|
|
42
72
|
// Conversion Functions
|
|
43
73
|
// ============================================================================
|
|
@@ -97,10 +127,9 @@ function segmentToWords (groupNumber, groupLevel, fullNumber, ones) {
|
|
|
97
127
|
return result
|
|
98
128
|
}
|
|
99
129
|
|
|
100
|
-
function integerToWords (n,
|
|
130
|
+
function integerToWords (n, gender) {
|
|
101
131
|
if (n === 0n) return ZERO
|
|
102
132
|
|
|
103
|
-
const gender = options.gender || 'masculine'
|
|
104
133
|
const ones = gender === 'feminine' ? ONES_FEM : ONES_MASC
|
|
105
134
|
|
|
106
135
|
let temp = n
|
|
@@ -148,7 +177,7 @@ function integerToWords (n, options) {
|
|
|
148
177
|
return result
|
|
149
178
|
}
|
|
150
179
|
|
|
151
|
-
function decimalPartToWords (decimalPart,
|
|
180
|
+
function decimalPartToWords (decimalPart, gender) {
|
|
152
181
|
const parts = []
|
|
153
182
|
let i = 0
|
|
154
183
|
|
|
@@ -159,7 +188,7 @@ function decimalPartToWords (decimalPart, options) {
|
|
|
159
188
|
|
|
160
189
|
const remainder = decimalPart.slice(i)
|
|
161
190
|
if (remainder) {
|
|
162
|
-
parts.push(integerToWords(BigInt(remainder),
|
|
191
|
+
parts.push(integerToWords(BigInt(remainder), gender))
|
|
163
192
|
}
|
|
164
193
|
|
|
165
194
|
return parts.join(' ')
|
|
@@ -175,31 +204,164 @@ function decimalPartToWords (decimalPart, options) {
|
|
|
175
204
|
* @returns {string} The number in Arabic words
|
|
176
205
|
*
|
|
177
206
|
* @example
|
|
178
|
-
*
|
|
179
|
-
*
|
|
207
|
+
* toCardinal(1) // 'واحد'
|
|
208
|
+
* toCardinal(1, {gender: 'feminine'}) // 'واحدة'
|
|
180
209
|
*/
|
|
181
|
-
function
|
|
210
|
+
function toCardinal (value, options) {
|
|
182
211
|
options = validateOptions(options)
|
|
183
|
-
const { isNegative, integerPart, decimalPart } =
|
|
212
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
213
|
+
|
|
214
|
+
// Apply option defaults
|
|
215
|
+
const {
|
|
216
|
+
gender = 'masculine',
|
|
217
|
+
negativeWord = NEGATIVE
|
|
218
|
+
} = options
|
|
184
219
|
|
|
185
220
|
const parts = []
|
|
186
221
|
|
|
187
222
|
if (isNegative) {
|
|
188
|
-
parts.push(
|
|
223
|
+
parts.push(negativeWord)
|
|
189
224
|
}
|
|
190
225
|
|
|
191
|
-
parts.push(integerToWords(integerPart,
|
|
226
|
+
parts.push(integerToWords(integerPart, gender))
|
|
192
227
|
|
|
193
228
|
if (decimalPart) {
|
|
194
229
|
parts.push(DECIMAL_SEP)
|
|
195
|
-
parts.push(decimalPartToWords(decimalPart,
|
|
230
|
+
parts.push(decimalPartToWords(decimalPart, gender))
|
|
196
231
|
}
|
|
197
232
|
|
|
198
233
|
return parts.join(' ')
|
|
199
234
|
}
|
|
200
235
|
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// ORDINAL: toOrdinal(value, options?)
|
|
238
|
+
// ============================================================================
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Gets the Arabic ordinal form for a number.
|
|
242
|
+
*
|
|
243
|
+
* Arabic ordinals 1-10 have special forms, beyond 10 use cardinal + position.
|
|
244
|
+
*
|
|
245
|
+
* @param {bigint} n - Positive integer to convert
|
|
246
|
+
* @param {string} gender - 'masculine' or 'feminine'
|
|
247
|
+
* @returns {string} Arabic ordinal words
|
|
248
|
+
*/
|
|
249
|
+
function integerToOrdinal (n, gender) {
|
|
250
|
+
const ordinals = gender === 'feminine' ? ORDINAL_FEM : ORDINAL_MASC
|
|
251
|
+
|
|
252
|
+
// Special ordinals for 1-10
|
|
253
|
+
if (n >= 1n && n <= 10n) {
|
|
254
|
+
return ordinals[Number(n) - 1]
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// For 11 and above, use cardinal form with "ال" prefix for definiteness
|
|
258
|
+
const cardinal = integerToWords(n, gender)
|
|
259
|
+
return 'ال' + cardinal
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Converts a numeric value to Arabic ordinal words.
|
|
264
|
+
*
|
|
265
|
+
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
266
|
+
* @param {Object} [options] - Optional configuration
|
|
267
|
+
* @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
|
|
268
|
+
* @returns {string} The number as ordinal words
|
|
269
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
270
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* toOrdinal(1) // 'الأول'
|
|
274
|
+
* toOrdinal(1, {gender: 'feminine'}) // 'الأولى'
|
|
275
|
+
* toOrdinal(3) // 'الثالث'
|
|
276
|
+
*/
|
|
277
|
+
function toOrdinal (value, options) {
|
|
278
|
+
options = validateOptions(options)
|
|
279
|
+
const integerPart = parseOrdinalValue(value)
|
|
280
|
+
const { gender = 'masculine' } = options
|
|
281
|
+
return integerToOrdinal(integerPart, gender)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// ============================================================================
|
|
285
|
+
// CURRENCY: toCurrency(value, options?)
|
|
286
|
+
// ============================================================================
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Gets the appropriate currency word form based on number.
|
|
290
|
+
*
|
|
291
|
+
* Arabic has complex pluralization:
|
|
292
|
+
* - 1: singular
|
|
293
|
+
* - 2: dual
|
|
294
|
+
* - 3-10: plural form 1
|
|
295
|
+
* - 11+: plural form 2 (different ending)
|
|
296
|
+
*/
|
|
297
|
+
function getRiyalForm (n) {
|
|
298
|
+
if (n === 1n) return RIYAL_SINGULAR
|
|
299
|
+
if (n === 2n) return RIYAL_DUAL
|
|
300
|
+
if (n >= 3n && n <= 10n) return RIYAL_PLURAL_3_10
|
|
301
|
+
return RIYAL_PLURAL_11
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function getHalalaForm (n) {
|
|
305
|
+
if (n === 1n) return HALALA_SINGULAR
|
|
306
|
+
if (n === 2n) return HALALA_DUAL
|
|
307
|
+
if (n >= 3n && n <= 10n) return HALALA_PLURAL_3_10
|
|
308
|
+
return HALALA_PLURAL_11
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Converts a numeric value to Arabic currency words (Saudi Riyal).
|
|
313
|
+
*
|
|
314
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
315
|
+
* @returns {string} The amount in Arabic currency words
|
|
316
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
317
|
+
* @throws {Error} If value is not a valid number format
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* toCurrency(42.50) // 'اثنان وأربعون ريالاً وخمسون هللة'
|
|
321
|
+
* toCurrency(1) // 'ريال واحد'
|
|
322
|
+
* toCurrency(0.01) // 'هللة واحدة'
|
|
323
|
+
*/
|
|
324
|
+
function toCurrency (value) {
|
|
325
|
+
const { isNegative, dollars: riyals, cents: halalas } = parseCurrencyValue(value)
|
|
326
|
+
|
|
327
|
+
// Build result
|
|
328
|
+
let result = ''
|
|
329
|
+
if (isNegative) result = NEGATIVE + ' '
|
|
330
|
+
|
|
331
|
+
// Riyals part - show if non-zero, or if no halalas
|
|
332
|
+
if (riyals > 0n || halalas === 0n) {
|
|
333
|
+
// Special case for 1 and 2: currency word comes first
|
|
334
|
+
if (riyals === 1n) {
|
|
335
|
+
result += RIYAL_SINGULAR + ' ' + ONES_MASC[0]
|
|
336
|
+
} else if (riyals === 2n) {
|
|
337
|
+
result += RIYAL_DUAL
|
|
338
|
+
} else {
|
|
339
|
+
const riyalWord = integerToWords(riyals, 'masculine')
|
|
340
|
+
result += riyalWord + ' ' + getRiyalForm(riyals)
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Halalas part
|
|
345
|
+
if (halalas > 0n) {
|
|
346
|
+
if (riyals > 0n) {
|
|
347
|
+
result += ' ' + AND
|
|
348
|
+
}
|
|
349
|
+
// Special case for 1 and 2: currency word comes first
|
|
350
|
+
if (halalas === 1n) {
|
|
351
|
+
result += HALALA_SINGULAR + ' ' + ONES_FEM[0]
|
|
352
|
+
} else if (halalas === 2n) {
|
|
353
|
+
result += HALALA_DUAL
|
|
354
|
+
} else {
|
|
355
|
+
const halalaWord = integerToWords(halalas, 'feminine')
|
|
356
|
+
result += halalaWord + ' ' + getHalalaForm(halalas)
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return result
|
|
361
|
+
}
|
|
362
|
+
|
|
201
363
|
// ============================================================================
|
|
202
364
|
// Exports
|
|
203
365
|
// ============================================================================
|
|
204
366
|
|
|
205
|
-
export {
|
|
367
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/az-AZ.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Azerbaijani words.
|
|
3
|
+
*
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @returns {string} The number in Azerbaijani words
|
|
6
|
+
*/
|
|
7
|
+
export function toCardinal(value: number | string | bigint): string;
|
|
8
|
+
/**
|
|
9
|
+
* Converts a numeric value to Azerbaijani 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) // 'birinci'
|
|
18
|
+
* toOrdinal(2) // 'ikinci'
|
|
19
|
+
* toOrdinal(21) // 'iyirmibirinci'
|
|
20
|
+
*/
|
|
21
|
+
export function toOrdinal(value: number | string | bigint): string;
|
|
22
|
+
/**
|
|
23
|
+
* Converts a numeric value to Azerbaijani currency words (Manat).
|
|
24
|
+
*
|
|
25
|
+
* Uses manat and qəpik (100 qəpik = 1 manat).
|
|
26
|
+
*
|
|
27
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
28
|
+
* @returns {string} The amount in Azerbaijani 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) // 'qırx iki manat'
|
|
34
|
+
* toCurrency(1.50) // 'bir manat əlli qəpik'
|
|
35
|
+
* toCurrency(-5) // 'mənfi beş manat'
|
|
36
|
+
*/
|
|
37
|
+
export function toCurrency(value: number | string | bigint): string;
|
package/src/az-AZ.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azerbaijani (Azerbaijan) language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: az-AZ | Azerbaijani as used in Azerbaijan
|
|
5
|
+
*
|
|
6
|
+
* Key features:
|
|
7
|
+
* - Turkic language patterns
|
|
8
|
+
* - Implicit "bir" (one) omission before hundreds and thousands
|
|
9
|
+
* - Short scale naming
|
|
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 = ['', 'bir', 'iki', 'üç', 'dörd', 'beş', 'altı', 'yeddi', 'səkkiz', 'doqquz']
|
|
21
|
+
const TEENS = ['on', 'on bir', 'on iki', 'on üç', 'on dörd', 'on beş', 'on altı', 'on yeddi', 'on səkkiz', 'on doqquz']
|
|
22
|
+
const TENS = ['', '', 'iyirmi', 'otuz', 'qırx', 'əlli', 'altmış', 'yetmiş', 'səksən', 'doxsan']
|
|
23
|
+
|
|
24
|
+
const HUNDRED = 'yüz'
|
|
25
|
+
const THOUSAND = 'min'
|
|
26
|
+
|
|
27
|
+
const ZERO = 'sıfır'
|
|
28
|
+
const NEGATIVE = 'mənfi'
|
|
29
|
+
const DECIMAL_SEP = 'nöqtə'
|
|
30
|
+
|
|
31
|
+
// Short scale
|
|
32
|
+
const SCALE_WORDS = ['', THOUSAND, 'milyon', 'milyar', 'trilyon', 'katrilyon', 'kentilyon']
|
|
33
|
+
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Ordinal Vocabulary
|
|
36
|
+
// ============================================================================
|
|
37
|
+
|
|
38
|
+
// Azerbaijani ordinals use -(i/ı/u/ü)nci/ncı/ncu/ncü suffix with vowel harmony
|
|
39
|
+
// Special forms for 1-10
|
|
40
|
+
const ORDINAL_SPECIAL = {
|
|
41
|
+
1: 'birinci',
|
|
42
|
+
2: 'ikinci',
|
|
43
|
+
3: 'üçüncü',
|
|
44
|
+
4: 'dördüncü',
|
|
45
|
+
5: 'beşinci',
|
|
46
|
+
6: 'altıncı',
|
|
47
|
+
7: 'yeddinci',
|
|
48
|
+
8: 'səkkizinci',
|
|
49
|
+
9: 'doqquzuncu',
|
|
50
|
+
10: 'onuncu'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Currency Vocabulary (Azerbaijani Manat)
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
const MANAT = 'manat'
|
|
58
|
+
const QEPIK = 'qəpik' // subunit (100 qəpik = 1 manat)
|
|
59
|
+
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Precomputed Lookup Table
|
|
62
|
+
// ============================================================================
|
|
63
|
+
|
|
64
|
+
function buildSegment (n) {
|
|
65
|
+
if (n === 0) return ''
|
|
66
|
+
|
|
67
|
+
const ones = n % 10
|
|
68
|
+
const tensDigit = Math.trunc(n / 10) % 10
|
|
69
|
+
const hundredsDigit = Math.trunc(n / 100)
|
|
70
|
+
|
|
71
|
+
const parts = []
|
|
72
|
+
|
|
73
|
+
if (hundredsDigit > 0) {
|
|
74
|
+
if (hundredsDigit === 1) {
|
|
75
|
+
parts.push(HUNDRED)
|
|
76
|
+
} else {
|
|
77
|
+
parts.push(ONES[hundredsDigit] + ' ' + HUNDRED)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (tensDigit === 1) {
|
|
82
|
+
parts.push(TEENS[ones])
|
|
83
|
+
} else {
|
|
84
|
+
if (tensDigit > 1) {
|
|
85
|
+
parts.push(TENS[tensDigit])
|
|
86
|
+
}
|
|
87
|
+
if (ones > 0) {
|
|
88
|
+
parts.push(ONES[ones])
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return parts.join(' ')
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// Conversion Functions
|
|
97
|
+
// ============================================================================
|
|
98
|
+
|
|
99
|
+
function integerToWords (n) {
|
|
100
|
+
if (n === 0n) return ZERO
|
|
101
|
+
|
|
102
|
+
if (n < 1000n) {
|
|
103
|
+
return buildSegment(Number(n))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return buildLargeNumberWords(n)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function buildLargeNumberWords (n) {
|
|
110
|
+
const numStr = n.toString()
|
|
111
|
+
const len = numStr.length
|
|
112
|
+
|
|
113
|
+
const segments = []
|
|
114
|
+
const segmentSize = 3
|
|
115
|
+
|
|
116
|
+
const remainderLen = len % segmentSize
|
|
117
|
+
let pos = 0
|
|
118
|
+
if (remainderLen > 0) {
|
|
119
|
+
segments.push(Number(numStr.slice(0, remainderLen)))
|
|
120
|
+
pos = remainderLen
|
|
121
|
+
}
|
|
122
|
+
while (pos < len) {
|
|
123
|
+
segments.push(Number(numStr.slice(pos, pos + segmentSize)))
|
|
124
|
+
pos += segmentSize
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const parts = []
|
|
128
|
+
let scaleIndex = segments.length - 1
|
|
129
|
+
|
|
130
|
+
for (let i = 0; i < segments.length; i++) {
|
|
131
|
+
const segment = segments[i]
|
|
132
|
+
|
|
133
|
+
if (segment !== 0) {
|
|
134
|
+
const scaleWord = SCALE_WORDS[scaleIndex] || ''
|
|
135
|
+
|
|
136
|
+
if (scaleIndex === 0) {
|
|
137
|
+
parts.push(buildSegment(segment))
|
|
138
|
+
} else if (scaleIndex === 1 && segment === 1) {
|
|
139
|
+
// Omit "bir" before thousand
|
|
140
|
+
parts.push(scaleWord)
|
|
141
|
+
} else {
|
|
142
|
+
parts.push(buildSegment(segment) + ' ' + scaleWord)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
scaleIndex--
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return parts.join(' ')
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function decimalPartToWords (decimalPart) {
|
|
153
|
+
let result = ''
|
|
154
|
+
let i = 0
|
|
155
|
+
|
|
156
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
157
|
+
if (result) result += ' '
|
|
158
|
+
result += ZERO
|
|
159
|
+
i++
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const remainder = decimalPart.slice(i)
|
|
163
|
+
if (remainder) {
|
|
164
|
+
if (result) result += ' '
|
|
165
|
+
result += integerToWords(BigInt(remainder))
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return result
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Converts a numeric value to Azerbaijani words.
|
|
173
|
+
*
|
|
174
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
175
|
+
* @returns {string} The number in Azerbaijani words
|
|
176
|
+
*/
|
|
177
|
+
function toCardinal (value) {
|
|
178
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
179
|
+
|
|
180
|
+
let result = ''
|
|
181
|
+
|
|
182
|
+
if (isNegative) {
|
|
183
|
+
result = NEGATIVE + ' '
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
result += integerToWords(integerPart)
|
|
187
|
+
|
|
188
|
+
if (decimalPart) {
|
|
189
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return result
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// ORDINAL: toOrdinal(value)
|
|
197
|
+
// ============================================================================
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Determines the ordinal suffix based on Azerbaijani vowel harmony.
|
|
201
|
+
* @param {string} word - The cardinal word
|
|
202
|
+
* @returns {string} The appropriate suffix
|
|
203
|
+
*/
|
|
204
|
+
function getOrdinalSuffix (word) {
|
|
205
|
+
// Azerbaijani vowel harmony: back vowels (a,ı,o,u) vs front vowels (ə,e,i,ö,ü)
|
|
206
|
+
const backVowels = 'aıou'
|
|
207
|
+
const frontVowels = 'əeiöü'
|
|
208
|
+
|
|
209
|
+
// Scan from end for last vowel
|
|
210
|
+
for (let i = word.length - 1; i >= 0; i--) {
|
|
211
|
+
const char = word[i]
|
|
212
|
+
if (backVowels.includes(char)) {
|
|
213
|
+
// Back vowels: -ıncı (after a,ı) or -uncu (after o,u)
|
|
214
|
+
if ('ou'.includes(char)) return 'uncu'
|
|
215
|
+
return 'ıncı'
|
|
216
|
+
}
|
|
217
|
+
if (frontVowels.includes(char)) {
|
|
218
|
+
// Front vowels: -inci (after ə,e,i) or -üncü (after ö,ü)
|
|
219
|
+
if ('öü'.includes(char)) return 'üncü'
|
|
220
|
+
return 'inci'
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return 'inci' // default
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Converts a non-negative integer to Azerbaijani ordinal words.
|
|
228
|
+
*
|
|
229
|
+
* Azerbaijani ordinals: birinci (1st), ikinci (2nd), üçüncü (3rd), etc.
|
|
230
|
+
* Uses vowel harmony for suffix selection.
|
|
231
|
+
*
|
|
232
|
+
* @param {bigint} n - Positive integer to convert
|
|
233
|
+
* @returns {string} Azerbaijani ordinal words
|
|
234
|
+
*/
|
|
235
|
+
function integerToOrdinal (n) {
|
|
236
|
+
// Special forms for 1-10
|
|
237
|
+
if (n >= 1n && n <= 10n) {
|
|
238
|
+
return ORDINAL_SPECIAL[Number(n)]
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// For numbers > 10, get cardinal without spaces and add appropriate suffix
|
|
242
|
+
const cardinal = integerToWords(n).replace(/ /g, '')
|
|
243
|
+
const suffix = getOrdinalSuffix(cardinal)
|
|
244
|
+
return cardinal + suffix
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Converts a numeric value to Azerbaijani ordinal words.
|
|
249
|
+
*
|
|
250
|
+
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
251
|
+
* @returns {string} The number as ordinal words
|
|
252
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
253
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* toOrdinal(1) // 'birinci'
|
|
257
|
+
* toOrdinal(2) // 'ikinci'
|
|
258
|
+
* toOrdinal(21) // 'iyirmibirinci'
|
|
259
|
+
*/
|
|
260
|
+
function toOrdinal (value) {
|
|
261
|
+
const integerPart = parseOrdinalValue(value)
|
|
262
|
+
return integerToOrdinal(integerPart)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ============================================================================
|
|
266
|
+
// CURRENCY: toCurrency(value)
|
|
267
|
+
// ============================================================================
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Converts a numeric value to Azerbaijani currency words (Manat).
|
|
271
|
+
*
|
|
272
|
+
* Uses manat and qəpik (100 qəpik = 1 manat).
|
|
273
|
+
*
|
|
274
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
275
|
+
* @returns {string} The amount in Azerbaijani currency words
|
|
276
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
277
|
+
* @throws {Error} If value is not a valid number format
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* toCurrency(42) // 'qırx iki manat'
|
|
281
|
+
* toCurrency(1.50) // 'bir manat əlli qəpik'
|
|
282
|
+
* toCurrency(-5) // 'mənfi beş manat'
|
|
283
|
+
*/
|
|
284
|
+
function toCurrency (value) {
|
|
285
|
+
const { isNegative, dollars: manat, cents: qepik } = parseCurrencyValue(value)
|
|
286
|
+
|
|
287
|
+
let result = ''
|
|
288
|
+
if (isNegative) {
|
|
289
|
+
result = NEGATIVE + ' '
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Manat part
|
|
293
|
+
if (manat > 0n || qepik === 0n) {
|
|
294
|
+
result += integerToWords(manat) + ' ' + MANAT
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Qəpik part
|
|
298
|
+
if (qepik > 0n) {
|
|
299
|
+
if (manat > 0n) {
|
|
300
|
+
result += ' '
|
|
301
|
+
}
|
|
302
|
+
result += integerToWords(qepik) + ' ' + QEPIK
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return result
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// ============================================================================
|
|
309
|
+
// Exports
|
|
310
|
+
// ============================================================================
|
|
311
|
+
|
|
312
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/bn-BD.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Bengali words.
|
|
3
|
+
*
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @returns {string} The number in Bengali words
|
|
6
|
+
*/
|
|
7
|
+
export function toCardinal(value: number | string | bigint): string;
|
|
8
|
+
/**
|
|
9
|
+
* Converts a numeric value to Bengali 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) // 'প্রথম'
|
|
18
|
+
* toOrdinal(2) // 'দ্বিতীয়'
|
|
19
|
+
* toOrdinal(3) // 'তৃতীয়'
|
|
20
|
+
* toOrdinal(10) // 'দশতম'
|
|
21
|
+
*/
|
|
22
|
+
export function toOrdinal(value: number | string | bigint): string;
|
|
23
|
+
/**
|
|
24
|
+
* Converts a numeric value to Bengali currency words (Bangladeshi Taka).
|
|
25
|
+
*
|
|
26
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
27
|
+
* @returns {string} The amount in Bengali currency words
|
|
28
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
29
|
+
* @throws {Error} If value is not a valid number format
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* toCurrency(42.50) // 'বেয়াল্লিশ টাকা পঞ্চাশ পয়সা'
|
|
33
|
+
* toCurrency(1) // 'এক টাকা'
|
|
34
|
+
* toCurrency(0.01) // 'এক পয়সা'
|
|
35
|
+
*/
|
|
36
|
+
export function toCurrency(value: number | string | bigint): string;
|