n2words 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/LICENSE +1 -1
- package/README.md +64 -184
- package/dist/am-ET.js +2 -0
- package/dist/am-ET.umd.js +2 -0
- package/dist/am-Latn-ET.js +2 -0
- package/dist/am-Latn-ET.umd.js +2 -0
- package/dist/ar-SA.js +2 -0
- package/dist/ar-SA.umd.js +2 -0
- package/dist/az-AZ.js +2 -0
- package/dist/az-AZ.umd.js +2 -0
- package/dist/bn-BD.js +2 -0
- package/dist/bn-BD.umd.js +2 -0
- package/dist/cs-CZ.js +2 -0
- package/dist/cs-CZ.umd.js +2 -0
- package/dist/da-DK.js +2 -0
- package/dist/da-DK.umd.js +2 -0
- package/dist/de-DE.js +2 -0
- package/dist/de-DE.umd.js +2 -0
- package/dist/el-GR.js +2 -0
- package/dist/el-GR.umd.js +2 -0
- package/dist/en-AU.js +2 -0
- package/dist/en-AU.umd.js +2 -0
- package/dist/en-BD.js +2 -0
- package/dist/en-BD.umd.js +2 -0
- package/dist/en-CA.js +2 -0
- package/dist/en-CA.umd.js +2 -0
- package/dist/en-GB.js +2 -0
- package/dist/en-GB.umd.js +2 -0
- package/dist/en-GH.js +2 -0
- package/dist/en-GH.umd.js +2 -0
- package/dist/en-IE.js +2 -0
- package/dist/en-IE.umd.js +2 -0
- package/dist/en-IN.js +2 -0
- package/dist/en-IN.umd.js +2 -0
- package/dist/en-KE.js +2 -0
- package/dist/en-KE.umd.js +2 -0
- package/dist/en-MY.js +2 -0
- package/dist/en-MY.umd.js +2 -0
- package/dist/en-NG.js +2 -0
- package/dist/en-NG.umd.js +2 -0
- package/dist/en-NZ.js +2 -0
- package/dist/en-NZ.umd.js +2 -0
- package/dist/en-PH.js +2 -0
- package/dist/en-PH.umd.js +2 -0
- package/dist/en-PK.js +2 -0
- package/dist/en-PK.umd.js +2 -0
- package/dist/en-SG.js +2 -0
- package/dist/en-SG.umd.js +2 -0
- package/dist/en-US.js +2 -0
- package/dist/en-US.umd.js +2 -0
- package/dist/en-ZA.js +2 -0
- package/dist/en-ZA.umd.js +2 -0
- package/dist/es-ES.js +2 -0
- package/dist/es-ES.umd.js +2 -0
- package/dist/es-MX.js +2 -0
- package/dist/es-MX.umd.js +2 -0
- package/dist/es-US.js +2 -0
- package/dist/es-US.umd.js +2 -0
- package/dist/fa-IR.js +2 -0
- package/dist/fa-IR.umd.js +2 -0
- package/dist/fi-FI.js +2 -0
- package/dist/fi-FI.umd.js +2 -0
- package/dist/fil-PH.js +2 -0
- package/dist/fil-PH.umd.js +2 -0
- package/dist/fr-BE.js +2 -0
- package/dist/fr-BE.umd.js +2 -0
- package/dist/fr-FR.js +2 -0
- package/dist/fr-FR.umd.js +2 -0
- package/dist/gu-IN.js +2 -0
- package/dist/gu-IN.umd.js +2 -0
- package/dist/ha-NG.js +2 -0
- package/dist/ha-NG.umd.js +2 -0
- package/dist/hbo-IL.js +2 -0
- package/dist/hbo-IL.umd.js +2 -0
- package/dist/he-IL.js +2 -0
- package/dist/he-IL.umd.js +2 -0
- package/dist/hi-IN.js +2 -0
- package/dist/hi-IN.umd.js +2 -0
- package/dist/hr-HR.js +2 -0
- package/dist/hr-HR.umd.js +2 -0
- package/dist/hu-HU.js +2 -0
- package/dist/hu-HU.umd.js +2 -0
- package/dist/id-ID.js +2 -0
- package/dist/id-ID.umd.js +2 -0
- package/dist/it-IT.js +2 -0
- package/dist/it-IT.umd.js +2 -0
- package/dist/ja-JP.js +2 -0
- package/dist/ja-JP.umd.js +2 -0
- package/dist/ka-GE.js +2 -0
- package/dist/ka-GE.umd.js +2 -0
- package/dist/kn-IN.js +2 -0
- package/dist/kn-IN.umd.js +2 -0
- package/dist/ko-KR.js +2 -0
- package/dist/ko-KR.umd.js +2 -0
- package/dist/lt-LT.js +2 -0
- package/dist/lt-LT.umd.js +2 -0
- package/dist/lv-LV.js +2 -0
- package/dist/lv-LV.umd.js +2 -0
- package/dist/mr-IN.js +2 -0
- package/dist/mr-IN.umd.js +2 -0
- package/dist/ms-MY.js +2 -0
- package/dist/ms-MY.umd.js +2 -0
- package/dist/nb-NO.js +2 -0
- package/dist/nb-NO.umd.js +2 -0
- package/dist/nl-NL.js +2 -0
- package/dist/nl-NL.umd.js +2 -0
- package/dist/pa-IN.js +2 -0
- package/dist/pa-IN.umd.js +2 -0
- package/dist/pl-PL.js +2 -0
- package/dist/pl-PL.umd.js +2 -0
- package/dist/pt-PT.js +2 -0
- package/dist/pt-PT.umd.js +2 -0
- package/dist/ro-RO.js +2 -0
- package/dist/ro-RO.umd.js +2 -0
- package/dist/ru-RU.js +2 -0
- package/dist/ru-RU.umd.js +2 -0
- package/dist/sr-Cyrl-RS.js +2 -0
- package/dist/sr-Cyrl-RS.umd.js +2 -0
- package/dist/sr-Latn-RS.js +2 -0
- package/dist/sr-Latn-RS.umd.js +2 -0
- package/dist/sv-SE.js +2 -0
- package/dist/sv-SE.umd.js +2 -0
- package/dist/sw-KE.js +2 -0
- package/dist/sw-KE.umd.js +2 -0
- package/dist/ta-IN.js +2 -0
- package/dist/ta-IN.umd.js +2 -0
- package/dist/te-IN.js +2 -0
- package/dist/te-IN.umd.js +2 -0
- package/dist/th-TH.js +2 -0
- package/dist/th-TH.umd.js +2 -0
- package/dist/tr-TR.js +2 -0
- package/dist/tr-TR.umd.js +2 -0
- package/dist/uk-UA.js +2 -0
- package/dist/uk-UA.umd.js +2 -0
- package/dist/ur-PK.js +2 -0
- package/dist/ur-PK.umd.js +2 -0
- package/dist/vi-VN.js +2 -0
- package/dist/vi-VN.umd.js +2 -0
- package/dist/yo-NG.js +2 -0
- package/dist/yo-NG.umd.js +2 -0
- package/dist/zh-Hans-CN.js +2 -0
- package/dist/zh-Hans-CN.umd.js +2 -0
- package/dist/zh-Hant-TW.js +2 -0
- package/dist/zh-Hant-TW.umd.js +2 -0
- package/package.json +47 -82
- package/src/am-ET.d.ts +40 -0
- package/src/am-ET.js +269 -0
- package/src/am-Latn-ET.d.ts +35 -0
- package/src/am-Latn-ET.js +264 -0
- package/src/ar-SA.d.ts +49 -0
- package/{lib/languages/ar.js → src/ar-SA.js} +177 -15
- package/src/az-AZ.d.ts +37 -0
- package/src/az-AZ.js +312 -0
- package/src/bn-BD.d.ts +36 -0
- package/{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-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/pl-PL.js
ADDED
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polish (Poland) language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: pl-PL | Polish as used in Poland
|
|
5
|
+
*
|
|
6
|
+
* Polish-specific rules:
|
|
7
|
+
* - Three-form pluralization: 1 = singular, 2-4 = few, 5+ = many
|
|
8
|
+
* - Gender agreement (masculine/feminine for numbers < 1000)
|
|
9
|
+
* - Omit "jeden" before scale words (tysiąc, milion, etc.)
|
|
10
|
+
* - Irregular hundreds: dwieście, trzysta, czterysta, pięćset...
|
|
11
|
+
* - Long scale with -ard forms: miliard, biliard, tryliard
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
15
|
+
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
16
|
+
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
17
|
+
import { validateOptions } from './utils/validate-options.js'
|
|
18
|
+
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Vocabulary (module-level constants)
|
|
21
|
+
// ============================================================================
|
|
22
|
+
|
|
23
|
+
const ONES_MASC = ['', 'jeden', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć', 'siedem', 'osiem', 'dziewięć']
|
|
24
|
+
const ONES_FEM = ['', 'jedna', 'dwie', 'trzy', 'cztery', 'pięć', 'sześć', 'siedem', 'osiem', 'dziewięć']
|
|
25
|
+
|
|
26
|
+
const TEENS = ['dziesięć', 'jedenaście', 'dwanaście', 'trzynaście', 'czternaście', 'piętnaście', 'szesnaście', 'siedemnaście', 'osiemnaście', 'dziewiętnaście']
|
|
27
|
+
|
|
28
|
+
const TENS = ['', '', 'dwadzieścia', 'trzydzieści', 'czterdzieści', 'pięćdziesiąt', 'sześćdziesiąt', 'siedemdziesiąt', 'osiemdziesiąt', 'dziewięćdziesiąt']
|
|
29
|
+
|
|
30
|
+
// Irregular hundreds
|
|
31
|
+
const HUNDREDS = ['', 'sto', 'dwieście', 'trzysta', 'czterysta', 'pięćset', 'sześćset', 'siedemset', 'osiemset', 'dziewięćset']
|
|
32
|
+
|
|
33
|
+
// Scale words: [singular, few (2-4), many (5+)]
|
|
34
|
+
const PLURAL_FORMS = {
|
|
35
|
+
1: ['tysiąc', 'tysiące', 'tysięcy'],
|
|
36
|
+
2: ['milion', 'miliony', 'milionów'],
|
|
37
|
+
3: ['miliard', 'miliardy', 'miliardów'],
|
|
38
|
+
4: ['bilion', 'biliony', 'bilionów'],
|
|
39
|
+
5: ['biliard', 'biliardy', 'biliardów'],
|
|
40
|
+
6: ['trylion', 'tryliony', 'trylionów'],
|
|
41
|
+
7: ['tryliard', 'tryliardy', 'tryliardów'],
|
|
42
|
+
8: ['kwadrylion', 'kwadryliony', 'kwadrylionów'],
|
|
43
|
+
9: ['kwaryliard', 'kwadryliardy', 'kwadryliardów'],
|
|
44
|
+
10: ['kwintylion', 'kwintyliony', 'kwintylionów']
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const ZERO = 'zero'
|
|
48
|
+
const NEGATIVE = 'minus'
|
|
49
|
+
const DECIMAL_SEP = 'przecinek'
|
|
50
|
+
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// Ordinal Vocabulary
|
|
53
|
+
// ============================================================================
|
|
54
|
+
|
|
55
|
+
// Polish ordinals (masculine nominative singular)
|
|
56
|
+
// 1-9: special forms
|
|
57
|
+
const ORDINAL_ONES = ['', 'pierwszy', 'drugi', 'trzeci', 'czwarty', 'piąty', 'szósty', 'siódmy', 'ósmy', 'dziewiąty']
|
|
58
|
+
|
|
59
|
+
// Teens ordinals
|
|
60
|
+
const ORDINAL_TEENS = ['dziesiąty', 'jedenasty', 'dwunasty', 'trzynasty', 'czternasty', 'piętnasty', 'szesnasty', 'siedemnasty', 'osiemnasty', 'dziewiętnasty']
|
|
61
|
+
|
|
62
|
+
// Tens ordinals (for exact tens)
|
|
63
|
+
const ORDINAL_TENS = ['', '', 'dwudziesty', 'trzydziesty', 'czterdziesty', 'pięćdziesiąty', 'sześćdziesiąty', 'siedemdziesiąty', 'osiemdziesiąty', 'dziewięćdziesiąty']
|
|
64
|
+
|
|
65
|
+
// Hundreds ordinals (for exact hundreds)
|
|
66
|
+
const ORDINAL_HUNDREDS = ['', 'setny', 'dwusetny', 'trzechsetny', 'czterechsetny', 'pięćsetny', 'sześćsetny', 'siedemsetny', 'osiemsetny', 'dziewięćsetny']
|
|
67
|
+
|
|
68
|
+
// Scale ordinals (1000, million, etc.)
|
|
69
|
+
const ORDINAL_SCALES = ['tysięczny', 'milionowy', 'miliardowy', 'bilionowy', 'biliardowy', 'trylionowy', 'tryliardowy']
|
|
70
|
+
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Currency Vocabulary (Polish Złoty)
|
|
73
|
+
// ============================================================================
|
|
74
|
+
|
|
75
|
+
// Złoty forms: [singular, few (2-4), many (5+)]
|
|
76
|
+
const ZLOTY_FORMS = ['złoty', 'złote', 'złotych']
|
|
77
|
+
// Grosz forms: [singular, few (2-4), many (5+)]
|
|
78
|
+
const GROSZ_FORMS = ['grosz', 'grosze', 'groszy']
|
|
79
|
+
|
|
80
|
+
// ============================================================================
|
|
81
|
+
// Segment Building
|
|
82
|
+
// ============================================================================
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Builds segment word for 0-999 (masculine form).
|
|
86
|
+
* @param {number} n - Segment value
|
|
87
|
+
* @returns {string} Polish word
|
|
88
|
+
*/
|
|
89
|
+
function buildSegment (n) {
|
|
90
|
+
if (n === 0) return ''
|
|
91
|
+
|
|
92
|
+
const ones = n % 10
|
|
93
|
+
const tens = Math.trunc(n / 10) % 10
|
|
94
|
+
const hundreds = Math.trunc(n / 100)
|
|
95
|
+
|
|
96
|
+
const parts = []
|
|
97
|
+
|
|
98
|
+
// Hundreds
|
|
99
|
+
if (hundreds > 0) {
|
|
100
|
+
parts.push(HUNDREDS[hundreds])
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Tens and ones
|
|
104
|
+
if (tens === 1) {
|
|
105
|
+
// Teens (10-19)
|
|
106
|
+
parts.push(TEENS[ones])
|
|
107
|
+
} else {
|
|
108
|
+
if (tens >= 2) {
|
|
109
|
+
parts.push(TENS[tens])
|
|
110
|
+
}
|
|
111
|
+
if (ones > 0) {
|
|
112
|
+
parts.push(ONES_MASC[ones])
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return parts.join(' ')
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Builds segment word for 0-999 (feminine form - only differs in ones).
|
|
121
|
+
* @param {number} n - Segment value
|
|
122
|
+
* @returns {string} Polish word
|
|
123
|
+
*/
|
|
124
|
+
function buildSegmentFeminine (n) {
|
|
125
|
+
if (n === 0) return ''
|
|
126
|
+
|
|
127
|
+
const ones = n % 10
|
|
128
|
+
const tens = Math.trunc(n / 10) % 10
|
|
129
|
+
const hundreds = Math.trunc(n / 100)
|
|
130
|
+
|
|
131
|
+
const parts = []
|
|
132
|
+
|
|
133
|
+
// Hundreds
|
|
134
|
+
if (hundreds > 0) {
|
|
135
|
+
parts.push(HUNDREDS[hundreds])
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Tens and ones - feminine for ones only
|
|
139
|
+
if (tens === 1) {
|
|
140
|
+
parts.push(TEENS[ones])
|
|
141
|
+
} else {
|
|
142
|
+
if (tens >= 2) {
|
|
143
|
+
parts.push(TENS[tens])
|
|
144
|
+
}
|
|
145
|
+
if (ones > 0) {
|
|
146
|
+
parts.push(ONES_FEM[ones])
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return parts.join(' ')
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ============================================================================
|
|
154
|
+
// Helper Functions
|
|
155
|
+
// ============================================================================
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Polish pluralization: 1 = singular, 2-4 = few, else = many.
|
|
159
|
+
* Special case: 11-19 always use many form.
|
|
160
|
+
*
|
|
161
|
+
* @param {bigint} n - Number to pluralize
|
|
162
|
+
* @param {string[]} forms - [singular, few, many]
|
|
163
|
+
* @returns {string} Correct plural form
|
|
164
|
+
*/
|
|
165
|
+
function pluralize (n, forms) {
|
|
166
|
+
if (n === 1n) {
|
|
167
|
+
return forms[0]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const lastDigit = n % 10n
|
|
171
|
+
const lastTwoDigits = n % 100n
|
|
172
|
+
|
|
173
|
+
// Teens (11-19) always use many form
|
|
174
|
+
// 2-4 use few form (but not 12-14)
|
|
175
|
+
if (lastDigit >= 2n && lastDigit <= 4n && (lastTwoDigits < 10n || lastTwoDigits > 20n)) {
|
|
176
|
+
return forms[1]
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return forms[2]
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ============================================================================
|
|
183
|
+
// Conversion Functions
|
|
184
|
+
// ============================================================================
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Converts a non-negative integer to Polish words.
|
|
188
|
+
*
|
|
189
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
190
|
+
* @param {Object} options - Conversion options
|
|
191
|
+
* @returns {string} Polish words
|
|
192
|
+
*/
|
|
193
|
+
function integerToWords (n, gender) {
|
|
194
|
+
if (n === 0n) return ZERO
|
|
195
|
+
|
|
196
|
+
// Fast path: numbers < 1000
|
|
197
|
+
if (n < 1000n) {
|
|
198
|
+
return gender === 'feminine' ? buildSegmentFeminine(Number(n)) : buildSegment(Number(n))
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Fast path: numbers < 1,000,000 (thousands)
|
|
202
|
+
if (n < 1_000_000n) {
|
|
203
|
+
const thousands = Number(n / 1000n)
|
|
204
|
+
const remainder = Number(n % 1000n)
|
|
205
|
+
|
|
206
|
+
const scaleWord = pluralize(BigInt(thousands), PLURAL_FORMS[1])
|
|
207
|
+
|
|
208
|
+
let result
|
|
209
|
+
if (thousands === 1) {
|
|
210
|
+
// Omit "jeden" before tysiąc
|
|
211
|
+
result = scaleWord
|
|
212
|
+
} else {
|
|
213
|
+
result = buildSegment(thousands) + ' ' + scaleWord
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (remainder > 0) {
|
|
217
|
+
result += ' ' + buildSegment(remainder)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return result
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
224
|
+
return buildLargeNumberWords(n, gender)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Builds words for numbers >= 1,000,000.
|
|
229
|
+
* Uses BigInt division for faster segment extraction.
|
|
230
|
+
*
|
|
231
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
232
|
+
* @param {Object} options - Conversion options
|
|
233
|
+
* @returns {string} Polish words
|
|
234
|
+
*/
|
|
235
|
+
function buildLargeNumberWords (n, gender) {
|
|
236
|
+
// Extract segments using BigInt division (faster than string slicing)
|
|
237
|
+
// Segments stored least-significant first (index 0 = ones, 1 = thousands, etc.)
|
|
238
|
+
const segmentValues = []
|
|
239
|
+
let temp = n
|
|
240
|
+
while (temp > 0n) {
|
|
241
|
+
segmentValues.push(temp % 1000n)
|
|
242
|
+
temp = temp / 1000n
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Build result string directly
|
|
246
|
+
let result = ''
|
|
247
|
+
|
|
248
|
+
for (let i = segmentValues.length - 1; i >= 0; i--) {
|
|
249
|
+
const segment = segmentValues[i]
|
|
250
|
+
if (segment === 0n) continue
|
|
251
|
+
|
|
252
|
+
const segmentWord = buildSegment(Number(segment))
|
|
253
|
+
|
|
254
|
+
if (result) result += ' '
|
|
255
|
+
|
|
256
|
+
if (i === 0) {
|
|
257
|
+
// Units segment
|
|
258
|
+
result += segmentWord
|
|
259
|
+
} else {
|
|
260
|
+
// Scale word needed
|
|
261
|
+
const forms = PLURAL_FORMS[i]
|
|
262
|
+
if (forms) {
|
|
263
|
+
const scaleWord = pluralize(segment, forms)
|
|
264
|
+
|
|
265
|
+
if (segment === 1n) {
|
|
266
|
+
// Omit "jeden" before scale words
|
|
267
|
+
result += scaleWord
|
|
268
|
+
} else {
|
|
269
|
+
result += segmentWord + ' ' + scaleWord
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return result
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Converts decimal digits to Polish words.
|
|
280
|
+
*
|
|
281
|
+
* @param {string} decimalPart - Decimal digits (without the point)
|
|
282
|
+
* @param {Object} options - Conversion options
|
|
283
|
+
* @returns {string} Polish words for decimal part
|
|
284
|
+
*/
|
|
285
|
+
function decimalPartToWords (decimalPart, gender) {
|
|
286
|
+
let result = ''
|
|
287
|
+
|
|
288
|
+
// Handle leading zeros
|
|
289
|
+
let i = 0
|
|
290
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
291
|
+
if (result) result += ' '
|
|
292
|
+
result += ZERO
|
|
293
|
+
i++
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Convert remainder as a single number
|
|
297
|
+
const remainder = decimalPart.slice(i)
|
|
298
|
+
if (remainder) {
|
|
299
|
+
if (result) result += ' '
|
|
300
|
+
result += integerToWords(BigInt(remainder), gender)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return result
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Converts a numeric value to Polish words.
|
|
308
|
+
*
|
|
309
|
+
* This is the main public API. It accepts any valid numeric input
|
|
310
|
+
* (number, string, or bigint) and handles parsing internally.
|
|
311
|
+
*
|
|
312
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
313
|
+
* @param {Object} [options] - Conversion options
|
|
314
|
+
* @param {string} [options.gender='masculine'] - Gender for numbers < 1000
|
|
315
|
+
* @returns {string} The number in Polish 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
|
+
* toCardinal(1) // 'jeden'
|
|
321
|
+
* toCardinal(1, { gender: 'feminine' }) // 'jedna'
|
|
322
|
+
* toCardinal(1000) // 'tysiąc'
|
|
323
|
+
* toCardinal(2000) // 'dwa tysiące'
|
|
324
|
+
*/
|
|
325
|
+
function toCardinal (value, options) {
|
|
326
|
+
options = validateOptions(options)
|
|
327
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
328
|
+
|
|
329
|
+
// Apply option defaults
|
|
330
|
+
const { gender = 'masculine' } = options
|
|
331
|
+
|
|
332
|
+
let result = ''
|
|
333
|
+
|
|
334
|
+
if (isNegative) {
|
|
335
|
+
result = NEGATIVE + ' '
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
result += integerToWords(integerPart, gender)
|
|
339
|
+
|
|
340
|
+
if (decimalPart) {
|
|
341
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, gender)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return result
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ============================================================================
|
|
348
|
+
// ORDINAL: toOrdinal(value)
|
|
349
|
+
// ============================================================================
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Builds ordinal for a 0-99 segment when it's the final (ordinal) part.
|
|
353
|
+
* Returns ordinal form: "pierwszy", "dwudziesty pierwszy", etc.
|
|
354
|
+
*
|
|
355
|
+
* @param {number} n - Number 0-99
|
|
356
|
+
* @returns {string} Ordinal words
|
|
357
|
+
*/
|
|
358
|
+
function buildOrdinalTensOnes (n) {
|
|
359
|
+
if (n === 0) return ''
|
|
360
|
+
|
|
361
|
+
const onesDigit = n % 10
|
|
362
|
+
const tensDigit = Math.trunc(n / 10)
|
|
363
|
+
|
|
364
|
+
if (tensDigit === 0) {
|
|
365
|
+
// Single digit: pierwszy, drugi, etc.
|
|
366
|
+
return ORDINAL_ONES[onesDigit]
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (tensDigit === 1) {
|
|
370
|
+
// Teens: dziesiąty, jedenasty, etc.
|
|
371
|
+
return ORDINAL_TEENS[onesDigit]
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Tens >= 20
|
|
375
|
+
if (onesDigit === 0) {
|
|
376
|
+
// Round tens: dwudziesty, trzydziesty, etc.
|
|
377
|
+
return ORDINAL_TENS[tensDigit]
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Compound: dwudziesty pierwszy, trzydziesty drugi, etc.
|
|
381
|
+
return ORDINAL_TENS[tensDigit] + ' ' + ORDINAL_ONES[onesDigit]
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Converts a positive integer to Polish ordinal words (masculine nominative).
|
|
386
|
+
*
|
|
387
|
+
* In Polish ordinals, only the LAST component becomes ordinal.
|
|
388
|
+
* E.g., 121 = "sto dwudziesty pierwszy" (one hundred twenty-first)
|
|
389
|
+
*
|
|
390
|
+
* @param {bigint} n - Positive integer to convert
|
|
391
|
+
* @returns {string} Ordinal Polish words
|
|
392
|
+
*/
|
|
393
|
+
function integerToOrdinal (n) {
|
|
394
|
+
// Fast path: numbers < 100
|
|
395
|
+
if (n < 100n) {
|
|
396
|
+
return buildOrdinalTensOnes(Number(n))
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Fast path: numbers < 1000
|
|
400
|
+
if (n < 1000n) {
|
|
401
|
+
const num = Number(n)
|
|
402
|
+
const hundredsDigit = Math.trunc(num / 100)
|
|
403
|
+
const remainder = num % 100
|
|
404
|
+
|
|
405
|
+
if (remainder === 0) {
|
|
406
|
+
// Exact hundreds: setny, dwusetny, etc.
|
|
407
|
+
return ORDINAL_HUNDREDS[hundredsDigit]
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Has remainder: cardinal hundreds + ordinal remainder
|
|
411
|
+
return HUNDREDS[hundredsDigit] + ' ' + buildOrdinalTensOnes(remainder)
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Fast path: numbers < 1,000,000
|
|
415
|
+
if (n < 1_000_000n) {
|
|
416
|
+
const thousands = Number(n / 1000n)
|
|
417
|
+
const remainder = Number(n % 1000n)
|
|
418
|
+
|
|
419
|
+
if (remainder === 0) {
|
|
420
|
+
// Exact thousands: tysięczny, etc.
|
|
421
|
+
if (thousands === 1) {
|
|
422
|
+
return ORDINAL_SCALES[0]
|
|
423
|
+
}
|
|
424
|
+
// For larger thousands, use cardinal + tysięczny
|
|
425
|
+
return buildSegment(thousands) + ' ' + ORDINAL_SCALES[0]
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Has remainder: cardinal thousands + ordinal remainder
|
|
429
|
+
const scaleWord = pluralize(BigInt(thousands), PLURAL_FORMS[1])
|
|
430
|
+
const thousandsWord = thousands === 1 ? '' : buildSegment(thousands) + ' '
|
|
431
|
+
return thousandsWord + scaleWord + ' ' + integerToOrdinal(BigInt(remainder))
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
435
|
+
return buildLargeOrdinal(n)
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Builds ordinal words for numbers >= 1,000,000.
|
|
440
|
+
* All segments except the final one are cardinal; final segment is ordinal.
|
|
441
|
+
*
|
|
442
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
443
|
+
* @returns {string} Ordinal Polish words
|
|
444
|
+
*/
|
|
445
|
+
function buildLargeOrdinal (n) {
|
|
446
|
+
const numStr = n.toString()
|
|
447
|
+
const len = numStr.length
|
|
448
|
+
|
|
449
|
+
// Extract segments (most-significant first)
|
|
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 last non-zero segment
|
|
465
|
+
let lastNonZeroIdx = segments.length - 1
|
|
466
|
+
while (lastNonZeroIdx >= 0 && segments[lastNonZeroIdx] === 0) {
|
|
467
|
+
lastNonZeroIdx--
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const parts = []
|
|
471
|
+
let scaleIndex = segments.length - 1
|
|
472
|
+
|
|
473
|
+
for (let i = 0; i < segments.length; i++) {
|
|
474
|
+
const segment = segments[i]
|
|
475
|
+
|
|
476
|
+
if (segment !== 0) {
|
|
477
|
+
const isLastNonZero = (i === lastNonZeroIdx)
|
|
478
|
+
|
|
479
|
+
if (scaleIndex === 0) {
|
|
480
|
+
// Units position (no scale)
|
|
481
|
+
if (isLastNonZero) {
|
|
482
|
+
parts.push(integerToOrdinal(BigInt(segment)))
|
|
483
|
+
} else {
|
|
484
|
+
parts.push(buildSegment(segment))
|
|
485
|
+
}
|
|
486
|
+
} else {
|
|
487
|
+
// Has scale word
|
|
488
|
+
if (isLastNonZero) {
|
|
489
|
+
// This scale position is the final ordinal
|
|
490
|
+
if (segment === 1) {
|
|
491
|
+
parts.push(ORDINAL_SCALES[scaleIndex - 1])
|
|
492
|
+
} else {
|
|
493
|
+
// Use cardinal segment + ordinal scale
|
|
494
|
+
parts.push(buildSegment(segment) + ' ' + ORDINAL_SCALES[scaleIndex - 1])
|
|
495
|
+
}
|
|
496
|
+
} else {
|
|
497
|
+
// Not the final segment: use cardinal
|
|
498
|
+
const forms = PLURAL_FORMS[scaleIndex]
|
|
499
|
+
const scaleWord = forms ? pluralize(BigInt(segment), forms) : ''
|
|
500
|
+
if (segment === 1) {
|
|
501
|
+
parts.push(scaleWord)
|
|
502
|
+
} else {
|
|
503
|
+
parts.push(buildSegment(segment) + ' ' + scaleWord)
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
scaleIndex--
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
return parts.join(' ')
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Converts a numeric value to Polish ordinal words (masculine nominative).
|
|
517
|
+
*
|
|
518
|
+
* @param {number | string | bigint} value - The numeric value to convert (must be a positive integer)
|
|
519
|
+
* @returns {string} The number as ordinal words (e.g., "pierwszy", "czterdziesty drugi")
|
|
520
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
521
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* toOrdinal(1) // 'pierwszy'
|
|
525
|
+
* toOrdinal(2) // 'drugi'
|
|
526
|
+
* toOrdinal(3) // 'trzeci'
|
|
527
|
+
* toOrdinal(21) // 'dwudziesty pierwszy'
|
|
528
|
+
* toOrdinal(42) // 'czterdziesty drugi'
|
|
529
|
+
* toOrdinal(100) // 'setny'
|
|
530
|
+
* toOrdinal(1000) // 'tysięczny'
|
|
531
|
+
*/
|
|
532
|
+
function toOrdinal (value) {
|
|
533
|
+
const integerPart = parseOrdinalValue(value)
|
|
534
|
+
return integerToOrdinal(integerPart)
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// ============================================================================
|
|
538
|
+
// CURRENCY: toCurrency(value)
|
|
539
|
+
// ============================================================================
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Converts a numeric value to Polish currency words (Polish Złoty).
|
|
543
|
+
*
|
|
544
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
545
|
+
* @returns {string} The amount in Polish currency words
|
|
546
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
547
|
+
* @throws {Error} If value is not a valid number format
|
|
548
|
+
*
|
|
549
|
+
* @example
|
|
550
|
+
* toCurrency(42) // 'czterdzieści dwa złote'
|
|
551
|
+
* toCurrency(1) // 'jeden złoty'
|
|
552
|
+
* toCurrency(1.50) // 'jeden złoty pięćdziesiąt groszy'
|
|
553
|
+
* toCurrency(-5) // 'minus pięć złotych'
|
|
554
|
+
*/
|
|
555
|
+
function toCurrency (value) {
|
|
556
|
+
const { isNegative, dollars: zloty, cents: grosze } = parseCurrencyValue(value)
|
|
557
|
+
|
|
558
|
+
let result = ''
|
|
559
|
+
if (isNegative) {
|
|
560
|
+
result = NEGATIVE + ' '
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Złoty part (masculine)
|
|
564
|
+
if (zloty > 0n || grosze === 0n) {
|
|
565
|
+
result += integerToWords(zloty, 'masculine')
|
|
566
|
+
result += ' ' + pluralize(zloty, ZLOTY_FORMS)
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Grosze part (masculine)
|
|
570
|
+
if (grosze > 0n) {
|
|
571
|
+
if (zloty > 0n) {
|
|
572
|
+
result += ' '
|
|
573
|
+
}
|
|
574
|
+
result += integerToWords(grosze, 'masculine')
|
|
575
|
+
result += ' ' + pluralize(grosze, GROSZ_FORMS)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return result
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// ============================================================================
|
|
582
|
+
// Public API
|
|
583
|
+
// ============================================================================
|
|
584
|
+
|
|
585
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/pt-PT.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Portuguese 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 Portuguese 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(21) // 'vinte e um'
|
|
14
|
+
* toCardinal(100) // 'cem'
|
|
15
|
+
* toCardinal(1000000) // 'um milhão'
|
|
16
|
+
*/
|
|
17
|
+
export function toCardinal(value: number | string | bigint): string;
|
|
18
|
+
/**
|
|
19
|
+
* Converts a number to Portuguese ordinal words.
|
|
20
|
+
*
|
|
21
|
+
* @param {number | string | bigint} value - The number to convert
|
|
22
|
+
* @returns {string} Portuguese ordinal words
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* toOrdinal(1) // 'primeiro'
|
|
26
|
+
* toOrdinal(21) // 'vigésimo primeiro'
|
|
27
|
+
* toOrdinal(100) // 'centésimo'
|
|
28
|
+
*/
|
|
29
|
+
export function toOrdinal(value: number | string | bigint): string;
|
|
30
|
+
/**
|
|
31
|
+
* Converts a number to Portuguese currency words (Euro).
|
|
32
|
+
*
|
|
33
|
+
* @param {number | string | bigint} value - The amount to convert
|
|
34
|
+
* @param {Object} [options]
|
|
35
|
+
* @param {boolean} [options.and=true] - Include "e" between euros and cents
|
|
36
|
+
* @returns {string} Portuguese currency words
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* toCurrency(42.50) // 'quarenta e dois euros e cinquenta cêntimos'
|
|
40
|
+
* toCurrency(1) // 'um euro'
|
|
41
|
+
* toCurrency(0.01) // 'um cêntimo'
|
|
42
|
+
*/
|
|
43
|
+
export function toCurrency(value: number | string | bigint, options?: {
|
|
44
|
+
and?: boolean | undefined;
|
|
45
|
+
}): string;
|