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
package/src/en-CA.js
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canadian English language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: en-CA | English as used in Canada
|
|
5
|
+
*
|
|
6
|
+
* Exports:
|
|
7
|
+
* - toCardinal(value, options?) - Cardinal numbers: 42 → "forty-two"
|
|
8
|
+
* - toOrdinal(value) - Ordinal numbers: 42 → "forty-second"
|
|
9
|
+
* - toCurrency(value, options?) - Currency: 42.50 → "forty-two dollars and fifty cents"
|
|
10
|
+
*
|
|
11
|
+
* Canadian English conventions:
|
|
12
|
+
* - Follows British English style for number words
|
|
13
|
+
* - "and" after hundreds: "one hundred and twenty-three" (default)
|
|
14
|
+
* - "and" before final segment: "one million and one" (default)
|
|
15
|
+
* - Hyphenated tens-ones: "twenty-one", "forty-two"
|
|
16
|
+
* - Western numbering system (short scale: billion = 10^9)
|
|
17
|
+
* - Optional hundred-pairing: 1500 → "fifteen hundred" (colloquial)
|
|
18
|
+
* - Optional "and" omission: 101 → "one hundred one" (American style)
|
|
19
|
+
* - Currency: Canadian Dollar (CAD) - dollar/dollars, cent/cents
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
23
|
+
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
24
|
+
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
25
|
+
import { validateOptions } from './utils/validate-options.js'
|
|
26
|
+
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// VOCABULARY
|
|
29
|
+
// ============================================================================
|
|
30
|
+
|
|
31
|
+
// Cardinal vocabulary
|
|
32
|
+
const ONES = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
|
|
33
|
+
const TEENS = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen']
|
|
34
|
+
const TENS = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']
|
|
35
|
+
const SCALES = [
|
|
36
|
+
'thousand', 'million', 'billion', 'trillion', 'quadrillion',
|
|
37
|
+
'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion',
|
|
38
|
+
'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quattuordecillion',
|
|
39
|
+
'quindecillion', 'sexdecillion', 'septendecillion', 'octodecillion', 'novemdecillion',
|
|
40
|
+
'vigintillion'
|
|
41
|
+
]
|
|
42
|
+
const HUNDRED = 'hundred'
|
|
43
|
+
const ZERO = 'zero'
|
|
44
|
+
const NEGATIVE = 'minus'
|
|
45
|
+
const DECIMAL_SEP = 'point'
|
|
46
|
+
|
|
47
|
+
// Ordinal vocabulary
|
|
48
|
+
const ORDINAL_ONES = ['', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth']
|
|
49
|
+
const ORDINAL_TEENS = ['tenth', 'eleventh', 'twelfth', 'thirteenth', 'fourteenth', 'fifteenth', 'sixteenth', 'seventeenth', 'eighteenth', 'nineteenth']
|
|
50
|
+
const ORDINAL_TENS = ['', '', 'twentieth', 'thirtieth', 'fortieth', 'fiftieth', 'sixtieth', 'seventieth', 'eightieth', 'ninetieth']
|
|
51
|
+
|
|
52
|
+
// Currency vocabulary (Canadian Dollar)
|
|
53
|
+
const DOLLAR = 'dollar'
|
|
54
|
+
const DOLLARS = 'dollars'
|
|
55
|
+
const CENT = 'cent'
|
|
56
|
+
const CENTS = 'cents'
|
|
57
|
+
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// SHARED HELPERS
|
|
60
|
+
// ============================================================================
|
|
61
|
+
|
|
62
|
+
// Reusable result object to avoid allocation per call
|
|
63
|
+
const segmentResult = { word: '', hasHundred: false }
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Builds words for a 0-999 segment.
|
|
67
|
+
*
|
|
68
|
+
* @param {number} n - Number 0-999
|
|
69
|
+
* @param {boolean} useAnd - Whether to use "and" after hundreds
|
|
70
|
+
* @returns {{ word: string, hasHundred: boolean }}
|
|
71
|
+
*/
|
|
72
|
+
function buildSegment (n, useAnd) {
|
|
73
|
+
if (n === 0) {
|
|
74
|
+
segmentResult.word = ''
|
|
75
|
+
segmentResult.hasHundred = false
|
|
76
|
+
return segmentResult
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const ones = n % 10
|
|
80
|
+
const tens = Math.trunc(n / 10) % 10
|
|
81
|
+
const hundreds = Math.trunc(n / 100)
|
|
82
|
+
|
|
83
|
+
// Build tens-ones part first
|
|
84
|
+
let tensOnes = ''
|
|
85
|
+
if (tens === 1) {
|
|
86
|
+
tensOnes = TEENS[ones]
|
|
87
|
+
} else if (tens >= 2) {
|
|
88
|
+
tensOnes = ones > 0 ? TENS[tens] + '-' + ONES[ones] : TENS[tens]
|
|
89
|
+
} else if (ones > 0) {
|
|
90
|
+
tensOnes = ONES[ones]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Hundreds place
|
|
94
|
+
if (hundreds > 0) {
|
|
95
|
+
if (tensOnes) {
|
|
96
|
+
const connector = useAnd ? ' and ' : ' '
|
|
97
|
+
segmentResult.word = ONES[hundreds] + ' ' + HUNDRED + connector + tensOnes
|
|
98
|
+
} else {
|
|
99
|
+
segmentResult.word = ONES[hundreds] + ' ' + HUNDRED
|
|
100
|
+
}
|
|
101
|
+
segmentResult.hasHundred = true
|
|
102
|
+
} else {
|
|
103
|
+
segmentResult.word = tensOnes
|
|
104
|
+
segmentResult.hasHundred = false
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return segmentResult
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ============================================================================
|
|
111
|
+
// CARDINAL: toCardinal(value, options?)
|
|
112
|
+
// ============================================================================
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Converts a non-negative integer to English words.
|
|
116
|
+
*
|
|
117
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
118
|
+
* @param {boolean} hundredPairing - Use hundred-pairing for 1100-9999
|
|
119
|
+
* @param {boolean} useAnd - Use "and" after hundreds and before final segment
|
|
120
|
+
* @returns {string} English words
|
|
121
|
+
*/
|
|
122
|
+
function integerToWords (n, hundredPairing, useAnd) {
|
|
123
|
+
if (n === 0n) return ZERO
|
|
124
|
+
|
|
125
|
+
// Fast path: numbers < 1000
|
|
126
|
+
if (n < 1000n) {
|
|
127
|
+
return buildSegment(Number(n), useAnd).word
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Hundred-pairing: 1100-9999 → "eleven hundred" to "ninety-nine hundred ninety-nine"
|
|
131
|
+
if (hundredPairing && n >= 1100n && n <= 9999n) {
|
|
132
|
+
const num = Number(n)
|
|
133
|
+
const highPart = Math.trunc(num / 100)
|
|
134
|
+
const lowPart = num % 100
|
|
135
|
+
|
|
136
|
+
const { word: highWord } = buildSegment(highPart, useAnd)
|
|
137
|
+
let result = highWord + ' ' + HUNDRED
|
|
138
|
+
|
|
139
|
+
if (lowPart > 0) {
|
|
140
|
+
const { word: lowWord } = buildSegment(lowPart, useAnd)
|
|
141
|
+
// Add "and" before remainder if useAnd is true
|
|
142
|
+
if (useAnd) {
|
|
143
|
+
result += ' and'
|
|
144
|
+
}
|
|
145
|
+
result += ' ' + lowWord
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return result
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Fast path: numbers < 1,000,000
|
|
152
|
+
if (n < 1_000_000n) {
|
|
153
|
+
const thousands = Number(n / 1000n)
|
|
154
|
+
const remainder = Number(n % 1000n)
|
|
155
|
+
|
|
156
|
+
const { word: thousandsWord } = buildSegment(thousands, useAnd)
|
|
157
|
+
let result = thousandsWord + ' ' + SCALES[0]
|
|
158
|
+
|
|
159
|
+
if (remainder > 0) {
|
|
160
|
+
const { word: remainderWord, hasHundred } = buildSegment(remainder, useAnd)
|
|
161
|
+
// Add "and" before remainder if useAnd is true and remainder has no hundred
|
|
162
|
+
if (useAnd && !hasHundred) {
|
|
163
|
+
result += ' and'
|
|
164
|
+
}
|
|
165
|
+
result += ' ' + remainderWord
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return result
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
172
|
+
return buildLargeNumberWords(n, useAnd)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Builds words for numbers >= 1,000,000.
|
|
177
|
+
* Uses BigInt division for faster segment extraction.
|
|
178
|
+
*
|
|
179
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
180
|
+
* @param {boolean} useAnd - Use "and" after hundreds and before final segment
|
|
181
|
+
* @returns {string} English words
|
|
182
|
+
*/
|
|
183
|
+
function buildLargeNumberWords (n, useAnd) {
|
|
184
|
+
// Extract segments using BigInt division
|
|
185
|
+
// Segments are stored least-significant first (index 0 = ones, 1 = thousands, etc.)
|
|
186
|
+
const segments = []
|
|
187
|
+
let temp = n
|
|
188
|
+
while (temp > 0n) {
|
|
189
|
+
segments.push(Number(temp % 1000n))
|
|
190
|
+
temp = temp / 1000n
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Find the first (smallest index) non-zero segment - this is processed last
|
|
194
|
+
let firstNonZeroIdx = -1
|
|
195
|
+
if (useAnd) {
|
|
196
|
+
for (let i = 0; i < segments.length; i++) {
|
|
197
|
+
if (segments[i] !== 0) {
|
|
198
|
+
firstNonZeroIdx = i
|
|
199
|
+
break
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Build result string (process from most-significant to least)
|
|
205
|
+
let result = ''
|
|
206
|
+
let prevWasScale = false
|
|
207
|
+
|
|
208
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
209
|
+
const segment = segments[i]
|
|
210
|
+
if (segment === 0) continue
|
|
211
|
+
|
|
212
|
+
const { word, hasHundred } = buildSegment(segment, useAnd)
|
|
213
|
+
const isLastSegment = (i === firstNonZeroIdx)
|
|
214
|
+
|
|
215
|
+
// Add "and" only before FINAL segment if it follows scale and doesn't have hundred
|
|
216
|
+
if (useAnd && result && isLastSegment && prevWasScale && !hasHundred) {
|
|
217
|
+
result += ' and'
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Add segment word
|
|
221
|
+
if (result) result += ' '
|
|
222
|
+
result += word
|
|
223
|
+
|
|
224
|
+
// Add scale word (i=0 is units, i=1 is thousands, etc.)
|
|
225
|
+
if (i > 0) {
|
|
226
|
+
result += ' ' + SCALES[i - 1]
|
|
227
|
+
prevWasScale = true
|
|
228
|
+
} else {
|
|
229
|
+
prevWasScale = false
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return result
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Converts decimal digits to English words.
|
|
238
|
+
*
|
|
239
|
+
* @param {string} decimalPart - Decimal digits (without the point)
|
|
240
|
+
* @param {boolean} useAnd - Use "and" in number conversion
|
|
241
|
+
* @returns {string} English words for decimal part
|
|
242
|
+
*/
|
|
243
|
+
function decimalPartToWords (decimalPart, useAnd) {
|
|
244
|
+
let result = ''
|
|
245
|
+
|
|
246
|
+
// Handle leading zeros
|
|
247
|
+
let i = 0
|
|
248
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
249
|
+
if (result) result += ' '
|
|
250
|
+
result += ZERO
|
|
251
|
+
i++
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Convert remainder as a single number
|
|
255
|
+
const remainder = decimalPart.slice(i)
|
|
256
|
+
if (remainder) {
|
|
257
|
+
if (result) result += ' '
|
|
258
|
+
result += integerToWords(BigInt(remainder), false, useAnd)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return result
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Converts a numeric value to Canadian English words.
|
|
266
|
+
*
|
|
267
|
+
* This is the main public API. It accepts any valid numeric input
|
|
268
|
+
* (number, string, or bigint) and handles parsing internally.
|
|
269
|
+
*
|
|
270
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
271
|
+
* @param {Object} [options] - Optional configuration
|
|
272
|
+
* @param {boolean} [options.hundredPairing=false] - Use hundred-pairing for 1100-9999 (e.g., "fifteen hundred" instead of "one thousand five hundred")
|
|
273
|
+
* @param {boolean} [options.and=true] - Use "and" after hundreds and before final small numbers (default: true, Canadian/British style)
|
|
274
|
+
* @returns {string} The number in Canadian English words
|
|
275
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
276
|
+
* @throws {Error} If value is not a valid number format
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* toCardinal(42) // 'forty-two'
|
|
280
|
+
* toCardinal(101) // 'one hundred and one'
|
|
281
|
+
* toCardinal(101, { and: false }) // 'one hundred one'
|
|
282
|
+
* toCardinal(1500) // 'one thousand five hundred'
|
|
283
|
+
* toCardinal(1500, { hundredPairing: true }) // 'fifteen hundred'
|
|
284
|
+
*/
|
|
285
|
+
function toCardinal (value, options) {
|
|
286
|
+
options = validateOptions(options)
|
|
287
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
288
|
+
|
|
289
|
+
// Extract options with defaults (Canadian English uses "and" like British English)
|
|
290
|
+
const { hundredPairing = false, and: useAnd = true } = options
|
|
291
|
+
|
|
292
|
+
let result = ''
|
|
293
|
+
|
|
294
|
+
if (isNegative) {
|
|
295
|
+
result = NEGATIVE + ' '
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
result += integerToWords(integerPart, hundredPairing, useAnd)
|
|
299
|
+
|
|
300
|
+
if (decimalPart) {
|
|
301
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, useAnd)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return result
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ============================================================================
|
|
308
|
+
// ORDINAL: toOrdinal(value)
|
|
309
|
+
// ============================================================================
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Builds ordinal words for a 0-999 segment (final segment only).
|
|
313
|
+
* Returns ordinal form: "first", "twenty-third", "one hundred forty-fifth"
|
|
314
|
+
*
|
|
315
|
+
* @param {number} n - Number 0-999
|
|
316
|
+
* @returns {string} Ordinal words for this segment
|
|
317
|
+
*/
|
|
318
|
+
function buildOrdinalSegment (n) {
|
|
319
|
+
const ones = n % 10
|
|
320
|
+
const tens = Math.trunc(n / 10) % 10
|
|
321
|
+
const hundreds = Math.trunc(n / 100)
|
|
322
|
+
|
|
323
|
+
// Build ordinal for tens-ones portion
|
|
324
|
+
let tensOnesOrdinal = ''
|
|
325
|
+
if (tens === 1) {
|
|
326
|
+
// Teens: 10-19 → "tenth" through "nineteenth"
|
|
327
|
+
tensOnesOrdinal = ORDINAL_TEENS[ones]
|
|
328
|
+
} else if (tens >= 2) {
|
|
329
|
+
if (ones > 0) {
|
|
330
|
+
// Compound: "twenty-first", "thirty-second", etc.
|
|
331
|
+
tensOnesOrdinal = TENS[tens] + '-' + ORDINAL_ONES[ones]
|
|
332
|
+
} else {
|
|
333
|
+
// Round tens: "twentieth", "thirtieth", etc.
|
|
334
|
+
tensOnesOrdinal = ORDINAL_TENS[tens]
|
|
335
|
+
}
|
|
336
|
+
} else if (ones > 0) {
|
|
337
|
+
// Single digit: "first", "second", etc.
|
|
338
|
+
tensOnesOrdinal = ORDINAL_ONES[ones]
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Hundreds place
|
|
342
|
+
if (hundreds > 0) {
|
|
343
|
+
if (tensOnesOrdinal) {
|
|
344
|
+
// "one hundred twenty-first"
|
|
345
|
+
return ONES[hundreds] + ' ' + HUNDRED + ' ' + tensOnesOrdinal
|
|
346
|
+
} else {
|
|
347
|
+
// "one hundredth", "two hundredth", etc.
|
|
348
|
+
return ONES[hundreds] + ' hundredth'
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return tensOnesOrdinal
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Converts a positive integer to ordinal words.
|
|
357
|
+
* Generates ordinals directly without string manipulation.
|
|
358
|
+
*
|
|
359
|
+
* @param {bigint} n - Positive integer to convert
|
|
360
|
+
* @returns {string} Ordinal English words
|
|
361
|
+
*/
|
|
362
|
+
function integerToOrdinal (n) {
|
|
363
|
+
// Fast path: numbers < 1000
|
|
364
|
+
if (n < 1000n) {
|
|
365
|
+
return buildOrdinalSegment(Number(n))
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Fast path: numbers < 1,000,000
|
|
369
|
+
if (n < 1_000_000n) {
|
|
370
|
+
const thousands = Number(n / 1000n)
|
|
371
|
+
const remainder = Number(n % 1000n)
|
|
372
|
+
|
|
373
|
+
if (remainder === 0) {
|
|
374
|
+
// Exact thousands: "one thousandth", "five thousandth"
|
|
375
|
+
return buildSegment(thousands, false).word + ' ' + SCALES[0] + 'th'
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Has remainder: cardinal thousands + ordinal remainder
|
|
379
|
+
const { word: thousandsWord } = buildSegment(thousands, false)
|
|
380
|
+
return thousandsWord + ' ' + SCALES[0] + ' ' + buildOrdinalSegment(remainder)
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
384
|
+
return buildLargeOrdinal(n)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Builds ordinal words for numbers >= 1,000,000.
|
|
389
|
+
* All segments except the final one are cardinal; final segment is ordinal.
|
|
390
|
+
*
|
|
391
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
392
|
+
* @returns {string} Ordinal English words
|
|
393
|
+
*/
|
|
394
|
+
function buildLargeOrdinal (n) {
|
|
395
|
+
// Extract segments (least-significant first)
|
|
396
|
+
const segments = []
|
|
397
|
+
let temp = n
|
|
398
|
+
while (temp > 0n) {
|
|
399
|
+
segments.push(Number(temp % 1000n))
|
|
400
|
+
temp = temp / 1000n
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Find the lowest non-zero segment (this gets ordinal treatment)
|
|
404
|
+
let lowestNonZeroIdx = 0
|
|
405
|
+
for (let i = 0; i < segments.length; i++) {
|
|
406
|
+
if (segments[i] !== 0) {
|
|
407
|
+
lowestNonZeroIdx = i
|
|
408
|
+
break
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Build result (most-significant to least)
|
|
413
|
+
let result = ''
|
|
414
|
+
|
|
415
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
416
|
+
const segment = segments[i]
|
|
417
|
+
if (segment === 0) continue
|
|
418
|
+
|
|
419
|
+
const isLowestSegment = (i === lowestNonZeroIdx)
|
|
420
|
+
|
|
421
|
+
if (result) result += ' '
|
|
422
|
+
|
|
423
|
+
if (isLowestSegment) {
|
|
424
|
+
// Final non-zero segment gets ordinal treatment
|
|
425
|
+
if (i === 0) {
|
|
426
|
+
// Units position: use ordinal segment
|
|
427
|
+
result += buildOrdinalSegment(segment)
|
|
428
|
+
} else {
|
|
429
|
+
// Scale position with no remainder below: "one millionth"
|
|
430
|
+
result += buildSegment(segment, false).word + ' ' + SCALES[i - 1] + 'th'
|
|
431
|
+
}
|
|
432
|
+
} else {
|
|
433
|
+
// Non-final segments are cardinal
|
|
434
|
+
result += buildSegment(segment, false).word
|
|
435
|
+
if (i > 0) {
|
|
436
|
+
result += ' ' + SCALES[i - 1]
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return result
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Converts a numeric value to Canadian English ordinal words.
|
|
446
|
+
*
|
|
447
|
+
* @param {number | string | bigint} value - The numeric value to convert (must be a positive integer)
|
|
448
|
+
* @returns {string} The number as ordinal words (e.g., "first", "forty-second")
|
|
449
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
450
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* toOrdinal(1) // 'first'
|
|
454
|
+
* toOrdinal(2) // 'second'
|
|
455
|
+
* toOrdinal(3) // 'third'
|
|
456
|
+
* toOrdinal(21) // 'twenty-first'
|
|
457
|
+
* toOrdinal(42) // 'forty-second'
|
|
458
|
+
* toOrdinal(100) // 'one hundredth'
|
|
459
|
+
* toOrdinal(101) // 'one hundred first'
|
|
460
|
+
* toOrdinal(1000) // 'one thousandth'
|
|
461
|
+
*/
|
|
462
|
+
function toOrdinal (value) {
|
|
463
|
+
const integerPart = parseOrdinalValue(value)
|
|
464
|
+
return integerToOrdinal(integerPart)
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// ============================================================================
|
|
468
|
+
// CURRENCY: toCurrency(value, options?)
|
|
469
|
+
// ============================================================================
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Converts a numeric value to Canadian English currency words.
|
|
473
|
+
*
|
|
474
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
475
|
+
* @param {Object} [options] - Optional configuration
|
|
476
|
+
* @param {boolean} [options.and=true] - Use "and" between dollars and cents (e.g., "one dollar and fifty cents")
|
|
477
|
+
* @returns {string} The amount in Canadian English currency words
|
|
478
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
479
|
+
* @throws {Error} If value is not a valid number format
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* toCurrency(42.50) // 'forty-two dollars and fifty cents'
|
|
483
|
+
* toCurrency(1) // 'one dollar'
|
|
484
|
+
* toCurrency(0.99) // 'ninety-nine cents'
|
|
485
|
+
* toCurrency(42.50, { and: false }) // 'forty-two dollars fifty cents'
|
|
486
|
+
*/
|
|
487
|
+
function toCurrency (value, options) {
|
|
488
|
+
options = validateOptions(options)
|
|
489
|
+
const { isNegative, dollars, cents } = parseCurrencyValue(value)
|
|
490
|
+
const { and: useAnd = true } = options
|
|
491
|
+
|
|
492
|
+
// Build result
|
|
493
|
+
let result = ''
|
|
494
|
+
if (isNegative) result = NEGATIVE + ' '
|
|
495
|
+
|
|
496
|
+
// Dollars part (show if non-zero, or if no cents)
|
|
497
|
+
if (dollars > 0n || cents === 0n) {
|
|
498
|
+
result += integerToWords(dollars, false, false)
|
|
499
|
+
result += ' ' + (dollars === 1n ? DOLLAR : DOLLARS)
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Cents part
|
|
503
|
+
if (cents > 0n) {
|
|
504
|
+
if (dollars > 0n) {
|
|
505
|
+
result += useAnd ? ' and ' : ' '
|
|
506
|
+
}
|
|
507
|
+
result += integerToWords(cents, false, false)
|
|
508
|
+
result += ' ' + (cents === 1n ? CENT : CENTS)
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return result
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// ============================================================================
|
|
515
|
+
// EXPORTS
|
|
516
|
+
// ============================================================================
|
|
517
|
+
|
|
518
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/en-GB.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to English words.
|
|
3
|
+
*
|
|
4
|
+
* This is the main public API. It accepts any valid numeric input
|
|
5
|
+
* (number, string, or bigint) and handles parsing internally.
|
|
6
|
+
*
|
|
7
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
8
|
+
* @returns {string} The number in English words
|
|
9
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
10
|
+
* @throws {Error} If value is not a valid number format
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* toCardinal(42) // 'forty-two'
|
|
14
|
+
* toCardinal(-3.14) // 'minus three point fourteen'
|
|
15
|
+
* toCardinal('1000000') // 'one million'
|
|
16
|
+
*/
|
|
17
|
+
export function toCardinal(value: number | string | bigint): string;
|
|
18
|
+
/**
|
|
19
|
+
* Converts a numeric value to British English ordinal words.
|
|
20
|
+
*
|
|
21
|
+
* @param {number | string | bigint} value - The numeric value to convert (must be a positive integer)
|
|
22
|
+
* @returns {string} The number as ordinal words (e.g., "first", "forty-second")
|
|
23
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
24
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* toOrdinal(1) // 'first'
|
|
28
|
+
* toOrdinal(2) // 'second'
|
|
29
|
+
* toOrdinal(3) // 'third'
|
|
30
|
+
* toOrdinal(21) // 'twenty-first'
|
|
31
|
+
* toOrdinal(42) // 'forty-second'
|
|
32
|
+
* toOrdinal(100) // 'one hundredth'
|
|
33
|
+
* toOrdinal(101) // 'one hundred first'
|
|
34
|
+
* toOrdinal(1000) // 'one thousandth'
|
|
35
|
+
*/
|
|
36
|
+
export function toOrdinal(value: number | string | bigint): string;
|
|
37
|
+
/**
|
|
38
|
+
* Converts a numeric value to British English currency words.
|
|
39
|
+
*
|
|
40
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
41
|
+
* @param {Object} [options] - Optional configuration
|
|
42
|
+
* @param {boolean} [options.and=true] - Use "and" between pounds and pence (e.g., "one pound and fifty pence")
|
|
43
|
+
* @returns {string} The amount in British English currency words
|
|
44
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
45
|
+
* @throws {Error} If value is not a valid number format
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* toCurrency(42.50) // 'forty-two pounds and fifty pence'
|
|
49
|
+
* toCurrency(1) // 'one pound'
|
|
50
|
+
* toCurrency(0.99) // 'ninety-nine pence'
|
|
51
|
+
* toCurrency(0.01) // 'one penny'
|
|
52
|
+
* toCurrency(42.50, { and: false }) // 'forty-two pounds fifty pence'
|
|
53
|
+
*/
|
|
54
|
+
export function toCurrency(value: number | string | bigint, options?: {
|
|
55
|
+
and?: boolean | undefined;
|
|
56
|
+
}): string;
|