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/de-DE.js
ADDED
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* German (Germany) language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: de-DE | German as used in Germany
|
|
5
|
+
*
|
|
6
|
+
* Key features:
|
|
7
|
+
* - Inverted tens-ones order: "einundzwanzig" (one-and-twenty) for 21-99
|
|
8
|
+
* - Compound words without spaces below million level
|
|
9
|
+
* - Three forms of 1: "eins" (standalone), "ein" (before hundert/tausend), "eine" (before Million+)
|
|
10
|
+
* - Scale pluralization: Million → Millionen, Milliarde → Milliarden
|
|
11
|
+
* - Spaces only around million+ scale words
|
|
12
|
+
* - BigInt modulo for efficient segment extraction
|
|
13
|
+
*/
|
|
14
|
+
|
|
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'
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Vocabulary (module-level constants)
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
// Ones words (1-9), index 0 unused
|
|
25
|
+
const ONES = ['', 'eins', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun']
|
|
26
|
+
|
|
27
|
+
// "ein" form for use before hundert/und
|
|
28
|
+
const EIN = 'ein'
|
|
29
|
+
|
|
30
|
+
// Teens (10-19)
|
|
31
|
+
const TEENS = ['zehn', 'elf', 'zwölf', 'dreizehn', 'vierzehn', 'fünfzehn', 'sechzehn', 'siebzehn', 'achtzehn', 'neunzehn']
|
|
32
|
+
|
|
33
|
+
// Tens (20-90)
|
|
34
|
+
const TENS = ['', '', 'zwanzig', 'dreißig', 'vierzig', 'fünfzig', 'sechzig', 'siebzig', 'achtzig', 'neunzig']
|
|
35
|
+
|
|
36
|
+
// Scale words (index 0 = thousand, 1 = million, etc.)
|
|
37
|
+
const SCALES = ['tausend', 'Million', 'Milliarde', 'Billion', 'Billiarde', 'Trillion', 'Trilliarde', 'Quadrillion', 'Quadrilliarde']
|
|
38
|
+
|
|
39
|
+
// Pluralized scale words (million+)
|
|
40
|
+
const SCALES_PLURAL = ['tausend', 'Millionen', 'Milliarden', 'Billionen', 'Billiarden', 'Trillionen', 'Trilliarden', 'Quadrillionen', 'Quadrilliarden']
|
|
41
|
+
|
|
42
|
+
const HUNDRED = 'hundert'
|
|
43
|
+
const ZERO = 'null'
|
|
44
|
+
const NEGATIVE = 'minus'
|
|
45
|
+
const DECIMAL_SEP = 'komma'
|
|
46
|
+
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// Ordinal Vocabulary
|
|
49
|
+
// ============================================================================
|
|
50
|
+
|
|
51
|
+
// Ordinal ones (1-9): erste, zweite, dritte, vierte...
|
|
52
|
+
// Note: 1st (erste), 3rd (dritte), 7th (siebte), 8th (achte) are irregular
|
|
53
|
+
const ORDINAL_ONES = ['', 'erste', 'zweite', 'dritte', 'vierte', 'fünfte', 'sechste', 'siebte', 'achte', 'neunte']
|
|
54
|
+
|
|
55
|
+
// Ordinal teens: zehnte, elfte, zwölfte...
|
|
56
|
+
const ORDINAL_TEENS = ['zehnte', 'elfte', 'zwölfte', 'dreizehnte', 'vierzehnte', 'fünfzehnte', 'sechzehnte', 'siebzehnte', 'achtzehnte', 'neunzehnte']
|
|
57
|
+
|
|
58
|
+
// Ordinal tens: zwanzigste, dreißigste...
|
|
59
|
+
const ORDINAL_TENS = ['', '', 'zwanzigste', 'dreißigste', 'vierzigste', 'fünfzigste', 'sechzigste', 'siebzigste', 'achtzigste', 'neunzigste']
|
|
60
|
+
|
|
61
|
+
// Ordinal scale suffixes: -ste for 20+
|
|
62
|
+
const ORDINAL_SUFFIX = 'ste'
|
|
63
|
+
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// Currency Vocabulary (Euro)
|
|
66
|
+
// ============================================================================
|
|
67
|
+
|
|
68
|
+
const EURO = 'Euro'
|
|
69
|
+
const CENT = 'Cent'
|
|
70
|
+
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Segment Building
|
|
73
|
+
// ============================================================================
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Builds segment word for 0-999 (standalone form, uses "eins").
|
|
77
|
+
* German inverts ones and tens: "einundzwanzig" = one-and-twenty
|
|
78
|
+
*
|
|
79
|
+
* @param {number} n - Number 0-999
|
|
80
|
+
* @returns {string} German words for the segment
|
|
81
|
+
*/
|
|
82
|
+
function buildSegment (n) {
|
|
83
|
+
if (n === 0) return ''
|
|
84
|
+
|
|
85
|
+
const ones = n % 10
|
|
86
|
+
const tens = Math.trunc(n / 10) % 10
|
|
87
|
+
const hundreds = Math.trunc(n / 100)
|
|
88
|
+
|
|
89
|
+
let result = ''
|
|
90
|
+
|
|
91
|
+
// Hundreds: "ein" before hundert, not "eins"
|
|
92
|
+
if (hundreds > 0) {
|
|
93
|
+
result += (hundreds === 1 ? EIN : ONES[hundreds]) + HUNDRED
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Tens and ones
|
|
97
|
+
if (tens === 1) {
|
|
98
|
+
// Teens
|
|
99
|
+
result += TEENS[ones]
|
|
100
|
+
} else if (tens >= 2 && ones > 0) {
|
|
101
|
+
// Inverted: "einundzwanzig" (one-and-twenty)
|
|
102
|
+
// Use "ein" before "und", not "eins"
|
|
103
|
+
result += (ones === 1 ? EIN : ONES[ones]) + 'und' + TENS[tens]
|
|
104
|
+
} else if (tens >= 2) {
|
|
105
|
+
// Just tens
|
|
106
|
+
result += TENS[tens]
|
|
107
|
+
} else if (ones > 0) {
|
|
108
|
+
// Just ones (no tens, possibly after hundreds)
|
|
109
|
+
// Use "eins" for standalone/after hundreds
|
|
110
|
+
result += ONES[ones]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return result
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Builds segment word for use before "tausend".
|
|
118
|
+
* Uses "ein" instead of "eins" for 1.
|
|
119
|
+
*
|
|
120
|
+
* @param {number} n - Number 0-999
|
|
121
|
+
* @returns {string} German words for thousand context
|
|
122
|
+
*/
|
|
123
|
+
function buildSegmentForThousand (n) {
|
|
124
|
+
if (n === 0) return ''
|
|
125
|
+
if (n === 1) return EIN // "eintausend"
|
|
126
|
+
|
|
127
|
+
const ones = n % 10
|
|
128
|
+
const tens = Math.trunc(n / 10) % 10
|
|
129
|
+
const hundreds = Math.trunc(n / 100)
|
|
130
|
+
|
|
131
|
+
let result = ''
|
|
132
|
+
|
|
133
|
+
if (hundreds > 0) {
|
|
134
|
+
result += (hundreds === 1 ? EIN : ONES[hundreds]) + HUNDRED
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (tens === 1) {
|
|
138
|
+
result += TEENS[ones]
|
|
139
|
+
} else if (tens >= 2 && ones > 0) {
|
|
140
|
+
result += (ones === 1 ? EIN : ONES[ones]) + 'und' + TENS[tens]
|
|
141
|
+
} else if (tens >= 2) {
|
|
142
|
+
result += TENS[tens]
|
|
143
|
+
} else if (ones > 0 && hundreds > 0) {
|
|
144
|
+
result += ONES[ones]
|
|
145
|
+
} else if (ones > 0) {
|
|
146
|
+
result += ONES[ones]
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return result
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ============================================================================
|
|
153
|
+
// Conversion Functions
|
|
154
|
+
// ============================================================================
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Converts a non-negative integer to German words.
|
|
158
|
+
*
|
|
159
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
160
|
+
* @returns {string} German words
|
|
161
|
+
*/
|
|
162
|
+
function integerToWords (n) {
|
|
163
|
+
if (n === 0n) return ZERO
|
|
164
|
+
|
|
165
|
+
// Fast path: numbers < 1000
|
|
166
|
+
if (n < 1000n) {
|
|
167
|
+
return buildSegment(Number(n))
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Fast path: numbers < 1,000,000
|
|
171
|
+
if (n < 1_000_000n) {
|
|
172
|
+
const thousands = Number(n / 1000n)
|
|
173
|
+
const remainder = Number(n % 1000n)
|
|
174
|
+
|
|
175
|
+
// Compound: "eintausendzweihundert" (no spaces)
|
|
176
|
+
let result = buildSegmentForThousand(thousands) + SCALES[0]
|
|
177
|
+
|
|
178
|
+
if (remainder > 0) {
|
|
179
|
+
result += buildSegment(remainder)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return result
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
186
|
+
return buildLargeNumberWords(n)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Builds words for numbers >= 1,000,000.
|
|
191
|
+
*
|
|
192
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
193
|
+
* @returns {string} German words
|
|
194
|
+
*/
|
|
195
|
+
function buildLargeNumberWords (n) {
|
|
196
|
+
const numStr = n.toString()
|
|
197
|
+
const len = numStr.length
|
|
198
|
+
|
|
199
|
+
// Build segments of 3 digits from right to left
|
|
200
|
+
const segments = []
|
|
201
|
+
const segmentSize = 3
|
|
202
|
+
|
|
203
|
+
const remainderLen = len % segmentSize
|
|
204
|
+
let pos = 0
|
|
205
|
+
if (remainderLen > 0) {
|
|
206
|
+
segments.push(Number(numStr.slice(0, remainderLen)))
|
|
207
|
+
pos = remainderLen
|
|
208
|
+
}
|
|
209
|
+
while (pos < len) {
|
|
210
|
+
segments.push(Number(numStr.slice(pos, pos + segmentSize)))
|
|
211
|
+
pos += segmentSize
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Convert segments to words
|
|
215
|
+
const parts = []
|
|
216
|
+
let scaleIndex = segments.length - 1
|
|
217
|
+
|
|
218
|
+
for (let i = 0; i < segments.length; i++) {
|
|
219
|
+
const segment = segments[i]
|
|
220
|
+
|
|
221
|
+
if (segment !== 0) {
|
|
222
|
+
if (scaleIndex === 0) {
|
|
223
|
+
// Units segment (no scale word)
|
|
224
|
+
parts.push({ words: buildSegment(segment), isScale: false, scaleLevel: 0 })
|
|
225
|
+
} else if (scaleIndex === 1) {
|
|
226
|
+
// Thousands: compound without space
|
|
227
|
+
const segWords = buildSegmentForThousand(segment)
|
|
228
|
+
parts.push({ words: segWords + SCALES[0], isScale: false, scaleLevel: 1 })
|
|
229
|
+
} else {
|
|
230
|
+
// Million+ : space around scale word
|
|
231
|
+
let segWords
|
|
232
|
+
if (segment === 1) {
|
|
233
|
+
segWords = 'eine' // "eine Million"
|
|
234
|
+
} else {
|
|
235
|
+
segWords = buildSegment(segment)
|
|
236
|
+
}
|
|
237
|
+
const scaleWord = segment === 1 ? SCALES[scaleIndex - 1] : SCALES_PLURAL[scaleIndex - 1]
|
|
238
|
+
parts.push({ words: segWords, isScale: false, scaleLevel: scaleIndex })
|
|
239
|
+
parts.push({ words: scaleWord, isScale: true, scaleLevel: scaleIndex })
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
scaleIndex--
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Join with German spacing rules: space around million+ scale words
|
|
247
|
+
return joinGermanParts(parts)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Joins parts with German spacing rules.
|
|
252
|
+
* Spaces only around million+ scale words.
|
|
253
|
+
*
|
|
254
|
+
* @param {Array} parts - Parts with metadata
|
|
255
|
+
* @returns {string} Joined string
|
|
256
|
+
*/
|
|
257
|
+
function joinGermanParts (parts) {
|
|
258
|
+
if (parts.length === 0) return ZERO
|
|
259
|
+
|
|
260
|
+
let result = ''
|
|
261
|
+
|
|
262
|
+
for (let i = 0; i < parts.length; i++) {
|
|
263
|
+
const part = parts[i]
|
|
264
|
+
const prevPart = i > 0 ? parts[i - 1] : null
|
|
265
|
+
|
|
266
|
+
// Add space before if:
|
|
267
|
+
// - Current is a million+ scale word
|
|
268
|
+
// - Previous was a million+ scale word
|
|
269
|
+
if (i > 0) {
|
|
270
|
+
const needsSpace = part.isScale || (prevPart && prevPart.isScale)
|
|
271
|
+
if (needsSpace) {
|
|
272
|
+
result += ' '
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
result += part.words
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return result
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Converts decimal digits to German words.
|
|
284
|
+
*
|
|
285
|
+
* @param {string} decimalPart - Decimal digits (without the point)
|
|
286
|
+
* @returns {string} German words for decimal part
|
|
287
|
+
*/
|
|
288
|
+
function decimalPartToWords (decimalPart) {
|
|
289
|
+
let result = ''
|
|
290
|
+
|
|
291
|
+
// Handle leading zeros
|
|
292
|
+
let i = 0
|
|
293
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
294
|
+
if (result) result += ' '
|
|
295
|
+
result += ZERO
|
|
296
|
+
i++
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Convert remainder as a single number
|
|
300
|
+
const remainder = decimalPart.slice(i)
|
|
301
|
+
if (remainder) {
|
|
302
|
+
if (result) result += ' '
|
|
303
|
+
result += integerToWords(BigInt(remainder))
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return result
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Converts a numeric value to German words.
|
|
311
|
+
*
|
|
312
|
+
* This is the main public API. It accepts any valid numeric input
|
|
313
|
+
* (number, string, or bigint) and handles parsing internally.
|
|
314
|
+
*
|
|
315
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
316
|
+
* @returns {string} The number in German words
|
|
317
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
318
|
+
* @throws {Error} If value is not a valid number format
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* toCardinal(21) // 'einundzwanzig'
|
|
322
|
+
* toCardinal(1000) // 'eintausend'
|
|
323
|
+
* toCardinal(1000000) // 'eine Million'
|
|
324
|
+
*/
|
|
325
|
+
function toCardinal (value) {
|
|
326
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
327
|
+
|
|
328
|
+
let result = ''
|
|
329
|
+
|
|
330
|
+
if (isNegative) {
|
|
331
|
+
result = NEGATIVE + ' '
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
result += integerToWords(integerPart)
|
|
335
|
+
|
|
336
|
+
if (decimalPart) {
|
|
337
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return result
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// ============================================================================
|
|
344
|
+
// ORDINAL: toOrdinal(value)
|
|
345
|
+
// ============================================================================
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Builds ordinal segment for 0-999.
|
|
349
|
+
* Only the final component becomes ordinal.
|
|
350
|
+
* Uses -te for 1-19, -ste for 20+.
|
|
351
|
+
*
|
|
352
|
+
* @param {number} n - Number 0-999
|
|
353
|
+
* @param {boolean} isFinal - Whether this is the final segment (gets ordinal suffix)
|
|
354
|
+
* @returns {string} German ordinal words for this segment
|
|
355
|
+
*/
|
|
356
|
+
function buildOrdinalSegment (n, isFinal) {
|
|
357
|
+
if (n === 0) return ''
|
|
358
|
+
|
|
359
|
+
const ones = n % 10
|
|
360
|
+
const tens = Math.trunc(n / 10) % 10
|
|
361
|
+
const hundreds = Math.trunc(n / 100)
|
|
362
|
+
|
|
363
|
+
let result = ''
|
|
364
|
+
|
|
365
|
+
// Hundreds part (cardinal form)
|
|
366
|
+
if (hundreds > 0) {
|
|
367
|
+
result += (hundreds === 1 ? EIN : ONES[hundreds]) + HUNDRED
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Tens and ones
|
|
371
|
+
if (tens === 1) {
|
|
372
|
+
// Teens: 10-19
|
|
373
|
+
if (isFinal) {
|
|
374
|
+
result += ORDINAL_TEENS[ones]
|
|
375
|
+
} else {
|
|
376
|
+
result += TEENS[ones]
|
|
377
|
+
}
|
|
378
|
+
} else if (tens >= 2 && ones > 0) {
|
|
379
|
+
// Compound: einundzwanzig → einundzwanzigste
|
|
380
|
+
if (isFinal) {
|
|
381
|
+
result += (ones === 1 ? EIN : ONES[ones]) + 'und' + ORDINAL_TENS[tens]
|
|
382
|
+
} else {
|
|
383
|
+
result += (ones === 1 ? EIN : ONES[ones]) + 'und' + TENS[tens]
|
|
384
|
+
}
|
|
385
|
+
} else if (tens >= 2) {
|
|
386
|
+
// Just tens: zwanzig → zwanzigste
|
|
387
|
+
if (isFinal) {
|
|
388
|
+
result += ORDINAL_TENS[tens]
|
|
389
|
+
} else {
|
|
390
|
+
result += TENS[tens]
|
|
391
|
+
}
|
|
392
|
+
} else if (ones > 0) {
|
|
393
|
+
// Just ones: eins → erste
|
|
394
|
+
if (isFinal) {
|
|
395
|
+
result += ORDINAL_ONES[ones]
|
|
396
|
+
} else {
|
|
397
|
+
result += ONES[ones]
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// If final and only hundreds (100, 200, etc.), add ordinal suffix
|
|
402
|
+
if (isFinal && hundreds > 0 && tens === 0 && ones === 0) {
|
|
403
|
+
result += ORDINAL_SUFFIX
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return result
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Converts integer to German ordinal words.
|
|
411
|
+
*
|
|
412
|
+
* @param {bigint} n - Positive integer
|
|
413
|
+
* @returns {string} German ordinal words
|
|
414
|
+
*/
|
|
415
|
+
function integerToOrdinal (n) {
|
|
416
|
+
// Fast path: numbers < 1000
|
|
417
|
+
if (n < 1000n) {
|
|
418
|
+
return buildOrdinalSegment(Number(n), true)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Fast path: numbers < 1,000,000
|
|
422
|
+
if (n < 1_000_000n) {
|
|
423
|
+
const thousands = Number(n / 1000n)
|
|
424
|
+
const remainder = Number(n % 1000n)
|
|
425
|
+
|
|
426
|
+
if (remainder === 0) {
|
|
427
|
+
// Exact thousands: "eintausendste", "zweitausendste"
|
|
428
|
+
return buildSegmentForThousand(thousands) + SCALES[0] + ORDINAL_SUFFIX
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Has remainder: cardinal thousands + ordinal remainder
|
|
432
|
+
return buildSegmentForThousand(thousands) + SCALES[0] + buildOrdinalSegment(remainder, true)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// For larger numbers, use scale decomposition
|
|
436
|
+
return buildLargeOrdinal(n)
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Builds ordinal words for numbers >= 1,000,000.
|
|
441
|
+
*
|
|
442
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
443
|
+
* @returns {string} German ordinal words
|
|
444
|
+
*/
|
|
445
|
+
function buildLargeOrdinal (n) {
|
|
446
|
+
const numStr = n.toString()
|
|
447
|
+
const len = numStr.length
|
|
448
|
+
|
|
449
|
+
// Build segments of 3 digits from right to left
|
|
450
|
+
const segments = []
|
|
451
|
+
const segmentSize = 3
|
|
452
|
+
|
|
453
|
+
const remainderLen = len % segmentSize
|
|
454
|
+
let pos = 0
|
|
455
|
+
if (remainderLen > 0) {
|
|
456
|
+
segments.push(Number(numStr.slice(0, remainderLen)))
|
|
457
|
+
pos = remainderLen
|
|
458
|
+
}
|
|
459
|
+
while (pos < len) {
|
|
460
|
+
segments.push(Number(numStr.slice(pos, pos + segmentSize)))
|
|
461
|
+
pos += segmentSize
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Find the lowest non-zero segment (highest index = lowest scale level)
|
|
465
|
+
let lowestNonZeroIdx = 0
|
|
466
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
467
|
+
if (segments[i] !== 0) {
|
|
468
|
+
lowestNonZeroIdx = i
|
|
469
|
+
break
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Convert segments to words
|
|
474
|
+
const parts = []
|
|
475
|
+
let scaleIndex = segments.length - 1
|
|
476
|
+
|
|
477
|
+
for (let i = 0; i < segments.length; i++) {
|
|
478
|
+
const segment = segments[i]
|
|
479
|
+
const isLowestSegment = (i === lowestNonZeroIdx)
|
|
480
|
+
|
|
481
|
+
if (segment !== 0) {
|
|
482
|
+
if (scaleIndex === 0) {
|
|
483
|
+
// Units segment
|
|
484
|
+
parts.push({ words: buildOrdinalSegment(segment, true), isScale: false, scaleLevel: 0 })
|
|
485
|
+
} else if (scaleIndex === 1) {
|
|
486
|
+
// Thousands
|
|
487
|
+
const segWords = buildSegmentForThousand(segment)
|
|
488
|
+
if (isLowestSegment) {
|
|
489
|
+
parts.push({ words: segWords + SCALES[0] + ORDINAL_SUFFIX, isScale: false, scaleLevel: 1 })
|
|
490
|
+
} else {
|
|
491
|
+
parts.push({ words: segWords + SCALES[0], isScale: false, scaleLevel: 1 })
|
|
492
|
+
}
|
|
493
|
+
} else {
|
|
494
|
+
// Million+
|
|
495
|
+
let segWords
|
|
496
|
+
if (segment === 1) {
|
|
497
|
+
segWords = 'eine'
|
|
498
|
+
} else {
|
|
499
|
+
segWords = buildSegment(segment)
|
|
500
|
+
}
|
|
501
|
+
const scaleWord = segment === 1 ? SCALES[scaleIndex - 1] : SCALES_PLURAL[scaleIndex - 1]
|
|
502
|
+
parts.push({ words: segWords, isScale: false, scaleLevel: scaleIndex })
|
|
503
|
+
if (isLowestSegment) {
|
|
504
|
+
parts.push({ words: scaleWord + ORDINAL_SUFFIX, isScale: true, scaleLevel: scaleIndex })
|
|
505
|
+
} else {
|
|
506
|
+
parts.push({ words: scaleWord, isScale: true, scaleLevel: scaleIndex })
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
scaleIndex--
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
return joinGermanParts(parts)
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Converts a numeric value to German ordinal words.
|
|
519
|
+
*
|
|
520
|
+
* German ordinals add -te for 1-19 and -ste for 20+.
|
|
521
|
+
* Irregular forms: erste (1st), dritte (3rd), siebte (7th), achte (8th).
|
|
522
|
+
*
|
|
523
|
+
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
524
|
+
* @returns {string} The number as ordinal words
|
|
525
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
526
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* toOrdinal(1) // 'erste'
|
|
530
|
+
* toOrdinal(2) // 'zweite'
|
|
531
|
+
* toOrdinal(3) // 'dritte'
|
|
532
|
+
* toOrdinal(21) // 'einundzwanzigste'
|
|
533
|
+
* toOrdinal(100) // 'einhundertste'
|
|
534
|
+
* toOrdinal(1000) // 'eintausendste'
|
|
535
|
+
*/
|
|
536
|
+
function toOrdinal (value) {
|
|
537
|
+
const integerPart = parseOrdinalValue(value)
|
|
538
|
+
return integerToOrdinal(integerPart)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// ============================================================================
|
|
542
|
+
// CURRENCY: toCurrency(value, options?)
|
|
543
|
+
// ============================================================================
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Converts a numeric value to German currency words (Euro).
|
|
547
|
+
*
|
|
548
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
549
|
+
* @param {Object} [options] - Optional configuration
|
|
550
|
+
* @param {boolean} [options.and=true] - Use "und" between euros and cents
|
|
551
|
+
* @returns {string} The amount in German currency words
|
|
552
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
553
|
+
* @throws {Error} If value is not a valid number format
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* toCurrency(42.50) // 'zweiundvierzig Euro und fünfzig Cent'
|
|
557
|
+
* toCurrency(1) // 'ein Euro'
|
|
558
|
+
* toCurrency(0.99) // 'neunundneunzig Cent'
|
|
559
|
+
* toCurrency(0.01) // 'ein Cent'
|
|
560
|
+
* toCurrency(42.50, { and: false }) // 'zweiundvierzig Euro fünfzig Cent'
|
|
561
|
+
*/
|
|
562
|
+
function toCurrency (value, options) {
|
|
563
|
+
options = validateOptions(options)
|
|
564
|
+
const { isNegative, dollars: euros, cents } = parseCurrencyValue(value)
|
|
565
|
+
const { and: useAnd = true } = options
|
|
566
|
+
|
|
567
|
+
// Build result
|
|
568
|
+
let result = ''
|
|
569
|
+
if (isNegative) result = NEGATIVE + ' '
|
|
570
|
+
|
|
571
|
+
// Euros part
|
|
572
|
+
if (euros > 0n || cents === 0n) {
|
|
573
|
+
// Use "ein" instead of "eins" before Euro
|
|
574
|
+
if (euros === 1n) {
|
|
575
|
+
result += EIN
|
|
576
|
+
} else {
|
|
577
|
+
result += integerToWords(euros)
|
|
578
|
+
}
|
|
579
|
+
result += ' ' + EURO
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Cents part
|
|
583
|
+
if (cents > 0n) {
|
|
584
|
+
if (euros > 0n) {
|
|
585
|
+
result += useAnd ? ' und ' : ' '
|
|
586
|
+
}
|
|
587
|
+
// Use "ein" instead of "eins" before Cent
|
|
588
|
+
if (cents === 1n) {
|
|
589
|
+
result += EIN
|
|
590
|
+
} else {
|
|
591
|
+
result += integerToWords(cents)
|
|
592
|
+
}
|
|
593
|
+
result += ' ' + CENT
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
return result
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// ============================================================================
|
|
600
|
+
// Public API
|
|
601
|
+
// ============================================================================
|
|
602
|
+
|
|
603
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/el-GR.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Greek words.
|
|
3
|
+
*
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @returns {string} The number in Greek 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) // 'είκοσι ένα'
|
|
11
|
+
* toCardinal(1000) // 'χίλια'
|
|
12
|
+
* toCardinal('3.14') // 'τρία κόμμα ένα τέσσερα'
|
|
13
|
+
*/
|
|
14
|
+
export function toCardinal(value: number | string | bigint): string;
|
|
15
|
+
/**
|
|
16
|
+
* Converts a numeric value to Greek ordinal words.
|
|
17
|
+
*
|
|
18
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
19
|
+
* @returns {string} The ordinal in Greek words
|
|
20
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
21
|
+
* @throws {Error} If value is not a positive integer
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* toOrdinal(1) // 'πρώτος'
|
|
25
|
+
* toOrdinal(21) // 'εικοστός πρώτος'
|
|
26
|
+
*/
|
|
27
|
+
export function toOrdinal(value: number | string | bigint): string;
|
|
28
|
+
/**
|
|
29
|
+
* Converts a numeric value to Greek Euro currency words.
|
|
30
|
+
*
|
|
31
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
32
|
+
* @returns {string} The currency in Greek words
|
|
33
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
34
|
+
* @throws {Error} If value is not a valid number format
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* toCurrency(1) // 'ένα ευρώ'
|
|
38
|
+
* toCurrency(2.50) // 'δύο ευρώ πενήντα λεπτά'
|
|
39
|
+
*/
|
|
40
|
+
export function toCurrency(value: number | string | bigint): string;
|