n2words 1.23.1 → 2.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.
Files changed (322) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +317 -59
  3. package/dist/ArabicConverter.js +3 -0
  4. package/dist/ArabicConverter.js.map +1 -0
  5. package/dist/AzerbaijaniConverter.js +3 -0
  6. package/dist/AzerbaijaniConverter.js.map +1 -0
  7. package/dist/BanglaConverter.js +3 -0
  8. package/dist/BanglaConverter.js.map +1 -0
  9. package/dist/BiblicalHebrewConverter.js +3 -0
  10. package/dist/BiblicalHebrewConverter.js.map +1 -0
  11. package/dist/CroatianConverter.js +3 -0
  12. package/dist/CroatianConverter.js.map +1 -0
  13. package/dist/CzechConverter.js +3 -0
  14. package/dist/CzechConverter.js.map +1 -0
  15. package/dist/DanishConverter.js +3 -0
  16. package/dist/DanishConverter.js.map +1 -0
  17. package/dist/DutchConverter.js +3 -0
  18. package/dist/DutchConverter.js.map +1 -0
  19. package/dist/EnglishConverter.js +3 -0
  20. package/dist/EnglishConverter.js.map +1 -0
  21. package/dist/FilipinoConverter.js +3 -0
  22. package/dist/FilipinoConverter.js.map +1 -0
  23. package/dist/FrenchBelgiumConverter.js +3 -0
  24. package/dist/FrenchBelgiumConverter.js.map +1 -0
  25. package/dist/FrenchConverter.js +3 -0
  26. package/dist/FrenchConverter.js.map +1 -0
  27. package/dist/GermanConverter.js +3 -0
  28. package/dist/GermanConverter.js.map +1 -0
  29. package/dist/GreekConverter.js +3 -0
  30. package/dist/GreekConverter.js.map +1 -0
  31. package/dist/GujaratiConverter.js +3 -0
  32. package/dist/GujaratiConverter.js.map +1 -0
  33. package/dist/HebrewConverter.js +3 -0
  34. package/dist/HebrewConverter.js.map +1 -0
  35. package/dist/HindiConverter.js +3 -0
  36. package/dist/HindiConverter.js.map +1 -0
  37. package/dist/HungarianConverter.js +3 -0
  38. package/dist/HungarianConverter.js.map +1 -0
  39. package/dist/IndonesianConverter.js +3 -0
  40. package/dist/IndonesianConverter.js.map +1 -0
  41. package/dist/ItalianConverter.js +3 -0
  42. package/dist/ItalianConverter.js.map +1 -0
  43. package/dist/JapaneseConverter.js +3 -0
  44. package/dist/JapaneseConverter.js.map +1 -0
  45. package/dist/KannadaConverter.js +3 -0
  46. package/dist/KannadaConverter.js.map +1 -0
  47. package/dist/KoreanConverter.js +3 -0
  48. package/dist/KoreanConverter.js.map +1 -0
  49. package/dist/LatvianConverter.js +3 -0
  50. package/dist/LatvianConverter.js.map +1 -0
  51. package/dist/LithuanianConverter.js +3 -0
  52. package/dist/LithuanianConverter.js.map +1 -0
  53. package/dist/MalayConverter.js +3 -0
  54. package/dist/MalayConverter.js.map +1 -0
  55. package/dist/MarathiConverter.js +3 -0
  56. package/dist/MarathiConverter.js.map +1 -0
  57. package/dist/NorwegianBokmalConverter.js +3 -0
  58. package/dist/NorwegianBokmalConverter.js.map +1 -0
  59. package/dist/PersianConverter.js +3 -0
  60. package/dist/PersianConverter.js.map +1 -0
  61. package/dist/PolishConverter.js +3 -0
  62. package/dist/PolishConverter.js.map +1 -0
  63. package/dist/PortugueseConverter.js +3 -0
  64. package/dist/PortugueseConverter.js.map +1 -0
  65. package/dist/PunjabiConverter.js +3 -0
  66. package/dist/PunjabiConverter.js.map +1 -0
  67. package/dist/RomanianConverter.js +3 -0
  68. package/dist/RomanianConverter.js.map +1 -0
  69. package/dist/RussianConverter.js +3 -0
  70. package/dist/RussianConverter.js.map +1 -0
  71. package/dist/SerbianCyrillicConverter.js +3 -0
  72. package/dist/SerbianCyrillicConverter.js.map +1 -0
  73. package/dist/SerbianLatinConverter.js +3 -0
  74. package/dist/SerbianLatinConverter.js.map +1 -0
  75. package/dist/SimplifiedChineseConverter.js +3 -0
  76. package/dist/SimplifiedChineseConverter.js.map +1 -0
  77. package/dist/SpanishConverter.js +3 -0
  78. package/dist/SpanishConverter.js.map +1 -0
  79. package/dist/SwahiliConverter.js +3 -0
  80. package/dist/SwahiliConverter.js.map +1 -0
  81. package/dist/SwedishConverter.js +3 -0
  82. package/dist/SwedishConverter.js.map +1 -0
  83. package/dist/TamilConverter.js +3 -0
  84. package/dist/TamilConverter.js.map +1 -0
  85. package/dist/TeluguConverter.js +3 -0
  86. package/dist/TeluguConverter.js.map +1 -0
  87. package/dist/ThaiConverter.js +3 -0
  88. package/dist/ThaiConverter.js.map +1 -0
  89. package/dist/TraditionalChineseConverter.js +3 -0
  90. package/dist/TraditionalChineseConverter.js.map +1 -0
  91. package/dist/TurkishConverter.js +3 -0
  92. package/dist/TurkishConverter.js.map +1 -0
  93. package/dist/UkrainianConverter.js +3 -0
  94. package/dist/UkrainianConverter.js.map +1 -0
  95. package/dist/UrduConverter.js +3 -0
  96. package/dist/UrduConverter.js.map +1 -0
  97. package/dist/VietnameseConverter.js +3 -0
  98. package/dist/VietnameseConverter.js.map +1 -0
  99. package/dist/n2words.js +3 -2
  100. package/dist/n2words.js.map +1 -1
  101. package/lib/classes/abstract-language.d.ts +158 -34
  102. package/lib/classes/abstract-language.js +223 -115
  103. package/lib/classes/greedy-scale-language.d.ts +109 -0
  104. package/lib/classes/greedy-scale-language.js +201 -0
  105. package/lib/classes/slavic-language.d.ts +148 -0
  106. package/lib/classes/slavic-language.js +281 -0
  107. package/lib/classes/south-asian-language.d.ts +70 -0
  108. package/lib/classes/south-asian-language.js +154 -0
  109. package/lib/classes/turkic-language.d.ts +26 -0
  110. package/lib/classes/turkic-language.js +59 -0
  111. package/lib/languages/ar.d.ts +30 -0
  112. package/lib/languages/ar.js +159 -0
  113. package/lib/languages/az.d.ts +12 -0
  114. package/lib/languages/az.js +42 -0
  115. package/lib/languages/bn.d.ts +11 -0
  116. package/lib/languages/bn.js +131 -0
  117. package/lib/languages/cs.d.ts +88 -0
  118. package/lib/languages/cs.js +143 -0
  119. package/lib/languages/da.d.ts +15 -0
  120. package/lib/languages/da.js +120 -0
  121. package/lib/languages/de.d.ts +14 -0
  122. package/lib/languages/de.js +101 -0
  123. package/lib/languages/el.d.ts +14 -0
  124. package/lib/languages/el.js +90 -0
  125. package/lib/languages/en.d.ts +16 -0
  126. package/lib/languages/en.js +86 -0
  127. package/lib/languages/es.d.ts +15 -0
  128. package/lib/languages/es.js +121 -0
  129. package/lib/languages/fa.d.ts +47 -0
  130. package/lib/languages/fa.js +144 -0
  131. package/lib/languages/fil.d.ts +16 -0
  132. package/lib/languages/fil.js +121 -0
  133. package/lib/languages/fr-BE.d.ts +11 -0
  134. package/lib/languages/fr-BE.js +25 -0
  135. package/lib/languages/fr.d.ts +15 -0
  136. package/lib/languages/fr.js +106 -0
  137. package/lib/languages/gu.d.ts +11 -0
  138. package/lib/languages/gu.js +132 -0
  139. package/lib/languages/hbo.d.ts +113 -0
  140. package/lib/languages/hbo.js +251 -0
  141. package/lib/languages/he.d.ts +80 -0
  142. package/lib/languages/he.js +206 -0
  143. package/lib/languages/hi.d.ts +11 -0
  144. package/lib/languages/hi.js +131 -0
  145. package/lib/languages/hr.d.ts +80 -0
  146. package/lib/languages/hr.js +113 -0
  147. package/lib/languages/hu.d.ts +22 -0
  148. package/lib/languages/hu.js +137 -0
  149. package/lib/languages/id.d.ts +37 -0
  150. package/lib/languages/id.js +159 -0
  151. package/lib/languages/it.d.ts +37 -0
  152. package/lib/languages/it.js +132 -0
  153. package/lib/languages/ja.d.ts +17 -0
  154. package/lib/languages/ja.js +137 -0
  155. package/lib/languages/kn.d.ts +11 -0
  156. package/lib/languages/kn.js +42 -0
  157. package/lib/languages/ko.d.ts +14 -0
  158. package/lib/languages/ko.js +55 -0
  159. package/lib/{i18n/pl.d.ts → languages/lt.d.ts} +18 -15
  160. package/lib/languages/lt.js +136 -0
  161. package/lib/{i18n/lt.d.ts → languages/lv.d.ts} +16 -14
  162. package/lib/languages/lv.js +130 -0
  163. package/lib/languages/mr.d.ts +11 -0
  164. package/lib/languages/mr.js +132 -0
  165. package/lib/languages/ms.d.ts +31 -0
  166. package/lib/languages/ms.js +150 -0
  167. package/lib/languages/nb.d.ts +12 -0
  168. package/lib/languages/nb.js +100 -0
  169. package/lib/languages/nl.d.ts +16 -0
  170. package/lib/languages/nl.js +155 -0
  171. package/lib/languages/pa.d.ts +11 -0
  172. package/lib/languages/pa.js +131 -0
  173. package/lib/{i18n/uk.d.ts → languages/pl.d.ts} +16 -14
  174. package/lib/languages/pl.js +110 -0
  175. package/lib/languages/pt.d.ts +29 -0
  176. package/lib/languages/pt.js +112 -0
  177. package/lib/languages/ro.d.ts +158 -0
  178. package/lib/languages/ro.js +273 -0
  179. package/lib/languages/ru.d.ts +85 -0
  180. package/lib/languages/ru.js +96 -0
  181. package/lib/languages/sr-Cyrl.d.ts +80 -0
  182. package/lib/languages/sr-Cyrl.js +113 -0
  183. package/lib/{i18n/cz.d.ts → languages/sr-Latn.d.ts} +26 -14
  184. package/lib/languages/sr-Latn.js +113 -0
  185. package/lib/languages/sv.d.ts +14 -0
  186. package/lib/languages/sv.js +90 -0
  187. package/lib/languages/sw.d.ts +39 -0
  188. package/lib/languages/sw.js +126 -0
  189. package/lib/languages/ta.d.ts +20 -0
  190. package/lib/languages/ta.js +226 -0
  191. package/lib/languages/te.d.ts +22 -0
  192. package/lib/languages/te.js +219 -0
  193. package/lib/languages/th.d.ts +17 -0
  194. package/lib/languages/th.js +117 -0
  195. package/lib/languages/tr.d.ts +12 -0
  196. package/lib/languages/tr.js +56 -0
  197. package/lib/languages/uk.d.ts +85 -0
  198. package/lib/{i18n → languages}/uk.js +33 -32
  199. package/lib/languages/ur.d.ts +11 -0
  200. package/lib/languages/ur.js +131 -0
  201. package/lib/{i18n → languages}/vi.d.ts +15 -13
  202. package/lib/languages/vi.js +147 -0
  203. package/lib/languages/zh-Hans.d.ts +21 -0
  204. package/lib/languages/zh-Hans.js +111 -0
  205. package/lib/languages/zh-Hant.d.ts +21 -0
  206. package/lib/languages/zh-Hant.js +111 -0
  207. package/lib/n2words.d.ts +207 -7
  208. package/lib/n2words.js +535 -81
  209. package/package.json +126 -79
  210. package/dist/ar.js +0 -2
  211. package/dist/ar.js.map +0 -1
  212. package/dist/az.js +0 -2
  213. package/dist/az.js.map +0 -1
  214. package/dist/cz.js +0 -2
  215. package/dist/cz.js.map +0 -1
  216. package/dist/de.js +0 -2
  217. package/dist/de.js.map +0 -1
  218. package/dist/dk.js +0 -2
  219. package/dist/dk.js.map +0 -1
  220. package/dist/en.js +0 -2
  221. package/dist/en.js.map +0 -1
  222. package/dist/es.js +0 -2
  223. package/dist/es.js.map +0 -1
  224. package/dist/fa.js +0 -2
  225. package/dist/fa.js.map +0 -1
  226. package/dist/fr-BE.js +0 -2
  227. package/dist/fr-BE.js.map +0 -1
  228. package/dist/fr.js +0 -2
  229. package/dist/fr.js.map +0 -1
  230. package/dist/he.js +0 -2
  231. package/dist/he.js.map +0 -1
  232. package/dist/hr.js +0 -2
  233. package/dist/hr.js.map +0 -1
  234. package/dist/hu.js +0 -2
  235. package/dist/hu.js.map +0 -1
  236. package/dist/id.js +0 -2
  237. package/dist/id.js.map +0 -1
  238. package/dist/it.js +0 -2
  239. package/dist/it.js.map +0 -1
  240. package/dist/ko.js +0 -2
  241. package/dist/ko.js.map +0 -1
  242. package/dist/lt.js +0 -2
  243. package/dist/lt.js.map +0 -1
  244. package/dist/lv.js +0 -2
  245. package/dist/lv.js.map +0 -1
  246. package/dist/n2words.d.ts +0 -2
  247. package/dist/nl.js +0 -2
  248. package/dist/nl.js.map +0 -1
  249. package/dist/no.js +0 -2
  250. package/dist/no.js.map +0 -1
  251. package/dist/pl.js +0 -2
  252. package/dist/pl.js.map +0 -1
  253. package/dist/pt.js +0 -2
  254. package/dist/pt.js.map +0 -1
  255. package/dist/ro.js +0 -2
  256. package/dist/ro.js.map +0 -1
  257. package/dist/ru.js +0 -2
  258. package/dist/ru.js.map +0 -1
  259. package/dist/sr.js +0 -2
  260. package/dist/sr.js.map +0 -1
  261. package/dist/tr.js +0 -2
  262. package/dist/tr.js.map +0 -1
  263. package/dist/uk.js +0 -2
  264. package/dist/uk.js.map +0 -1
  265. package/dist/vi.js +0 -2
  266. package/dist/vi.js.map +0 -1
  267. package/dist/zh.js +0 -2
  268. package/dist/zh.js.map +0 -1
  269. package/lib/classes/base-language.d.ts +0 -58
  270. package/lib/classes/base-language.js +0 -172
  271. package/lib/i18n/ar.d.ts +0 -41
  272. package/lib/i18n/ar.js +0 -209
  273. package/lib/i18n/az.d.ts +0 -15
  274. package/lib/i18n/az.js +0 -66
  275. package/lib/i18n/cz.js +0 -135
  276. package/lib/i18n/de.d.ts +0 -17
  277. package/lib/i18n/de.js +0 -103
  278. package/lib/i18n/dk.d.ts +0 -14
  279. package/lib/i18n/dk.js +0 -110
  280. package/lib/i18n/en.d.ts +0 -22
  281. package/lib/i18n/en.js +0 -86
  282. package/lib/i18n/es.d.ts +0 -16
  283. package/lib/i18n/es.js +0 -110
  284. package/lib/i18n/fa.d.ts +0 -54
  285. package/lib/i18n/fa.js +0 -106
  286. package/lib/i18n/fr-BE.d.ts +0 -11
  287. package/lib/i18n/fr-BE.js +0 -20
  288. package/lib/i18n/fr.d.ts +0 -15
  289. package/lib/i18n/fr.js +0 -99
  290. package/lib/i18n/he.d.ts +0 -61
  291. package/lib/i18n/he.js +0 -132
  292. package/lib/i18n/hr.d.ts +0 -68
  293. package/lib/i18n/hr.js +0 -129
  294. package/lib/i18n/hu.d.ts +0 -17
  295. package/lib/i18n/hu.js +0 -135
  296. package/lib/i18n/id.d.ts +0 -43
  297. package/lib/i18n/id.js +0 -156
  298. package/lib/i18n/it.d.ts +0 -29
  299. package/lib/i18n/it.js +0 -137
  300. package/lib/i18n/ko.d.ts +0 -15
  301. package/lib/i18n/ko.js +0 -56
  302. package/lib/i18n/lt.js +0 -138
  303. package/lib/i18n/lv.d.ts +0 -57
  304. package/lib/i18n/lv.js +0 -120
  305. package/lib/i18n/nl.d.ts +0 -20
  306. package/lib/i18n/nl.js +0 -125
  307. package/lib/i18n/no.d.ts +0 -15
  308. package/lib/i18n/no.js +0 -77
  309. package/lib/i18n/pl.js +0 -126
  310. package/lib/i18n/pt.d.ts +0 -26
  311. package/lib/i18n/pt.js +0 -118
  312. package/lib/i18n/ro.d.ts +0 -109
  313. package/lib/i18n/ro.js +0 -360
  314. package/lib/i18n/ru.d.ts +0 -30
  315. package/lib/i18n/ru.js +0 -198
  316. package/lib/i18n/sr.d.ts +0 -56
  317. package/lib/i18n/sr.js +0 -127
  318. package/lib/i18n/tr.d.ts +0 -15
  319. package/lib/i18n/tr.js +0 -64
  320. package/lib/i18n/vi.js +0 -151
  321. package/lib/i18n/zh.d.ts +0 -18
  322. package/lib/i18n/zh.js +0 -78
@@ -0,0 +1,155 @@
1
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
2
+
3
+ /**
4
+ * Dutch language converter.
5
+ *
6
+ * Supports:
7
+ * - Optional "en" (and) separator for tens
8
+ * - Optional comma before hundreds
9
+ * - Compound word formation without hyphenation
10
+ */
11
+ export class Dutch extends GreedyScaleLanguage {
12
+ negativeWord = 'min'
13
+ decimalSeparatorWord = 'komma'
14
+ zeroWord = 'nul'
15
+
16
+ scaleWords = [
17
+ [1_000_000_000_000_000_000_000_000_000n, 'quadriljard'],
18
+ [1_000_000_000_000_000_000_000_000n, 'quadriljoen'],
19
+ [1_000_000_000_000_000_000_000n, 'triljard'],
20
+ [1_000_000_000_000_000_000n, 'triljoen'],
21
+ [1_000_000_000_000_000n, 'biljard'],
22
+ [1_000_000_000_000n, 'biljoen'],
23
+ [1_000_000_000n, 'miljard'],
24
+ [1_000_000n, 'miljoen'],
25
+ [1000n, 'duizend'],
26
+ [100n, 'honderd'],
27
+ [90n, 'negentig'],
28
+ [80n, 'tachtig'],
29
+ [70n, 'zeventig'],
30
+ [60n, 'zestig'],
31
+ [50n, 'vijftig'],
32
+ [40n, 'veertig'],
33
+ [30n, 'dertig'],
34
+ [20n, 'twintig'],
35
+ [19n, 'negentien'],
36
+ [18n, 'achttien'],
37
+ [17n, 'zeventien'],
38
+ [16n, 'zestien'],
39
+ [15n, 'vijftien'],
40
+ [14n, 'veertien'],
41
+ [13n, 'dertien'],
42
+ [12n, 'twaalf'],
43
+ [11n, 'elf'],
44
+ [10n, 'tien'],
45
+ [9n, 'negen'],
46
+ [8n, 'acht'],
47
+ [7n, 'zeven'],
48
+ [6n, 'zes'],
49
+ [5n, 'vijf'],
50
+ [4n, 'vier'],
51
+ [3n, 'drie'],
52
+ [2n, 'twee'],
53
+ [1n, 'één'],
54
+ [0n, 'nul']
55
+ ]
56
+
57
+ constructor (options = {}) {
58
+ super()
59
+
60
+ this.setOptions({
61
+ includeOptionalAnd: false,
62
+ noHundredPairing: false,
63
+ accentOne: true
64
+ }, options)
65
+
66
+ if (!this.options.accentOne) {
67
+ this.scaleWords[this.scaleWords.length - 2][1] = 'een'
68
+ }
69
+ }
70
+
71
+ /** Combines two word-sets according to Dutch grammar rules. */
72
+ combineWordSets (preceding, following) {
73
+ let precedingWord = Object.keys(preceding)[0]
74
+ let followingWord = Object.keys(following)[0]
75
+ const precedingValue = Object.values(preceding)[0] // BigInt
76
+ const followingValue = Object.values(following)[0] // BigInt
77
+
78
+ // Implicit "een": omit before large multipliers ("miljoen" not "een miljoen")
79
+ if (precedingValue === 1n) {
80
+ if (followingValue < 1_000_000n) {
81
+ return following
82
+ }
83
+ precedingWord = this.options.accentOne ? 'één' : 'een'
84
+ }
85
+
86
+ // Handle multiplication and spacing
87
+ if (followingValue > precedingValue) {
88
+ let hadSpace = false
89
+ // Large scale words (millions+): add space before multiplier
90
+ if (followingValue >= 1_000_000n) {
91
+ precedingWord += ' '
92
+ hadSpace = true
93
+ } else if (followingValue > 100n) {
94
+ // Hundreds and above: add space after multiplier
95
+ followingWord += ' '
96
+ hadSpace = true
97
+ }
98
+ // Convert 'één' to 'een' in compounds (when no space or accentOne disabled)
99
+ if (!hadSpace || !this.options.accentOne) {
100
+ precedingWord = precedingWord.replace(/één/g, 'een')
101
+ followingWord = followingWord.replace(/één/g, 'een')
102
+ }
103
+ return { [`${precedingWord}${followingWord}`]: precedingValue * followingValue }
104
+ }
105
+
106
+ // Track if we're adding a space (which keeps words separate)
107
+ let hasSpace = false
108
+
109
+ if (followingValue < 10n && precedingValue > 10n && precedingValue < 100n) {
110
+ const temporary = followingWord
111
+ followingWord = precedingWord
112
+ const andTxt = temporary.endsWith('e') ? 'ën' : 'en'
113
+ precedingWord = `${temporary}${andTxt}`
114
+ } else if (followingValue < 13n && precedingValue < 1000n && this.options.includeOptionalAnd) {
115
+ precedingWord = `${precedingWord}en`
116
+ } else if (followingValue < 13n && precedingValue >= 1000n && this.options.includeOptionalAnd) {
117
+ followingWord = ` en ${followingWord}`
118
+ hasSpace = true
119
+ } else if (precedingValue >= 1_000_000n) {
120
+ precedingWord += ' '
121
+ hasSpace = true
122
+ } else if (precedingValue === 1000n) {
123
+ precedingWord += ' '
124
+ hasSpace = true
125
+ }
126
+
127
+ // Convert 'één' to 'een' in direct compounds (no space)
128
+ // Keep 'één' only if there's a space AND accentOne=true
129
+ if (!hasSpace) {
130
+ precedingWord = precedingWord.replace(/één/g, 'een')
131
+ followingWord = followingWord.replace(/één/g, 'een')
132
+ } else if (!this.options.accentOne) {
133
+ precedingWord = precedingWord.replace(/één/g, 'een')
134
+ followingWord = followingWord.replace(/één/g, 'een')
135
+ }
136
+
137
+ return { [`${precedingWord}${followingWord}`]: precedingValue + followingValue }
138
+ }
139
+
140
+ integerToWords (integerPart) {
141
+ if (integerPart >= 1100n && integerPart < 10_000n && !this.options.noHundredPairing) {
142
+ const high = integerPart / 100n
143
+ const low = integerPart % 100n
144
+ if (high % 10n !== 0n) {
145
+ let result = super.integerToWords(high) + 'honderd'
146
+ if (low) {
147
+ result +=
148
+ (this.options.includeOptionalAnd ? ' en ' : ' ') + super.integerToWords(low)
149
+ }
150
+ return result
151
+ }
152
+ }
153
+ return super.integerToWords(integerPart)
154
+ }
155
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Punjabi language converter.
3
+ *
4
+ * Supports:
5
+ * - Indian numbering system (ਹਜ਼ਾਰ, ਲੱਖ, ਕਰੋੜ)
6
+ * - Gurmukhi script
7
+ * - Complete word forms for 0-99
8
+ */
9
+ export class Punjabi extends SouthAsianLanguage {
10
+ }
11
+ import { SouthAsianLanguage } from '../classes/south-asian-language.js';
@@ -0,0 +1,131 @@
1
+ import { SouthAsianLanguage } from '../classes/south-asian-language.js'
2
+
3
+ /**
4
+ * Punjabi language converter.
5
+ *
6
+ * Supports:
7
+ * - Indian numbering system (ਹਜ਼ਾਰ, ਲੱਖ, ਕਰੋੜ)
8
+ * - Gurmukhi script
9
+ * - Complete word forms for 0-99
10
+ */
11
+ export class Punjabi extends SouthAsianLanguage {
12
+ negativeWord = 'ਮਾਇਨਸ'
13
+ decimalSeparatorWord = 'ਦਸ਼ਮਲਵ'
14
+ zeroWord = 'ਸਿਫ਼ਰ'
15
+ hundredWord = 'ਸੌ'
16
+
17
+ belowHundredWords = [
18
+ 'ਸਿਫ਼ਰ',
19
+ 'ਇੱਕ',
20
+ 'ਦੋ',
21
+ 'ਤਿੰਨ',
22
+ 'ਚਾਰ',
23
+ 'ਪੰਜ',
24
+ 'ਛੇ',
25
+ 'ਸੱਤ',
26
+ 'ਅੱਠ',
27
+ 'ਨੌਂ',
28
+ 'ਦੱਸ',
29
+ 'ਗਿਆਰਾਂ',
30
+ 'ਬਾਰਾਂ',
31
+ 'ਤੇਰਾਂ',
32
+ 'ਚੌਦਾਂ',
33
+ 'ਪੰਦਰਾਂ',
34
+ 'ਸੋਲਾਂ',
35
+ 'ਸਤਾਰਾਂ',
36
+ 'ਅਠਾਰਾਂ',
37
+ 'ਉੱਨੀ',
38
+ 'ਵੀਹ',
39
+ 'ਇੱਕੀ',
40
+ 'ਬਾਈ',
41
+ 'ਤੇਈ',
42
+ 'ਚੌਬੀ',
43
+ 'ਪੱਚੀ',
44
+ 'ਛੱਬੀ',
45
+ 'ਸਤਾਈ',
46
+ 'ਅਠਾਈ',
47
+ 'ਉਨੱਤੀ',
48
+ 'ਤੀਹ',
49
+ 'ਇਕੱਤੀ',
50
+ 'ਬੱਤੀ',
51
+ 'ਤੇਤੀ',
52
+ 'ਚੌਂਤੀ',
53
+ 'ਪੈਂਤੀ',
54
+ 'ਛੱਤੀ',
55
+ 'ਸੈਂਤੀ',
56
+ 'ਅਠੱਤੀ',
57
+ 'ਉਨਤਾਲੀ',
58
+ 'ਚਾਲੀ',
59
+ 'ਇਕਤਾਲੀ',
60
+ 'ਬਿਆਲੀ',
61
+ 'ਤਿਰਤਾਲੀ',
62
+ 'ਚੁਵਾਲੀ',
63
+ 'ਪੰਤਾਲੀ',
64
+ 'ਛਿਆਲੀ',
65
+ 'ਸੈਂਤਾਲੀ',
66
+ 'ਅਠਤਾਲੀ',
67
+ 'ਉਨੰਜਾ',
68
+ 'ਪੰਜਾਹ',
69
+ 'ਇਕਵੰਜਾ',
70
+ 'ਬਵੰਜਾ',
71
+ 'ਤਰਵੰਜਾ',
72
+ 'ਚੁਰਵੰਜਾ',
73
+ 'ਪੰਜਵੰਜਾ',
74
+ 'ਛਪੰਜਾ',
75
+ 'ਸੱਤਵੰਜਾ',
76
+ 'ਅਠਵੰਜਾ',
77
+ 'ਉਨਾਹਠ',
78
+ 'ਸੱਠ',
79
+ 'ਇਕਾਹਠ',
80
+ 'ਬਾਹਠ',
81
+ 'ਤਰਸਠ',
82
+ 'ਚੌਂਸਠ',
83
+ 'ਪੈਂਸਠ',
84
+ 'ਛਿਆਸਠ',
85
+ 'ਸੜਸਠ',
86
+ 'ਅੜਸਠ',
87
+ 'ਉਣਹੱਤਰ',
88
+ 'ਸਤੱਰ',
89
+ 'ਇਕਹੱਤਰ',
90
+ 'ਬਹੱਤਰ',
91
+ 'ਤਹੱਤਰ',
92
+ 'ਚੌਹੱਤਰ',
93
+ 'ਪੰਝਹੱਤਰ',
94
+ 'ਛਿਹੱਤਰ',
95
+ 'ਸਤੱਤਰ',
96
+ 'ਅਠੱਤਰ',
97
+ 'ਉਨਾਸੀ',
98
+ 'ਅੱਸੀ',
99
+ 'ਇਕਿਆਸੀ',
100
+ 'ਬਿਆਸੀ',
101
+ 'ਤਰਿਆਸੀ',
102
+ 'ਚੌਰਿਆਸੀ',
103
+ 'ਪਚਾਸੀ',
104
+ 'ਛਿਆਸੀ',
105
+ 'ਸੱਤਾਸੀ',
106
+ 'ਅਠਾਸੀ',
107
+ 'ਨਵਾਸੀ',
108
+ 'ਨੱਬੇ',
109
+ 'ਇਕਾਨਵੇਂ',
110
+ 'ਬਾਨਵੇਂ',
111
+ 'ਤਰਾਨਵੇਂ',
112
+ 'ਚੁਰਾਨਵੇਂ',
113
+ 'ਪੰਚਾਨਵੇਂ',
114
+ 'ਛਿਆਨਵੇਂ',
115
+ 'ਸਤਾਨਵੇਂ',
116
+ 'ਅਠਾਨਵੇਂ',
117
+ 'ਨਿਨਾਨਵੇਂ'
118
+ ]
119
+
120
+ scaleWords = [
121
+ '',
122
+ 'ਹਜ਼ਾਰ',
123
+ 'ਲੱਖ',
124
+ 'ਕਰੋੜ',
125
+ 'ਅਰਬ',
126
+ 'ਖਰਬ',
127
+ 'ਨੀਲ',
128
+ 'ਪਦਮ',
129
+ 'ਸ਼ੰਖ'
130
+ ]
131
+ }
@@ -1,13 +1,13 @@
1
1
  /**
2
- * Converts a value to cardinal (written) form.
3
- * @param {number|string|bigint} value Number to be convert.
4
- * @param {object} [options] Options for class.
5
- * @returns {string} Value in cardinal (written) format.
6
- * @throws {Error} Value cannot be invalid.
2
+ * Polish language converter.
3
+ *
4
+ * Supports:
5
+ * - Three-form pluralization (one/few/many)
6
+ * - Polish-specific declension patterns
7
+ * - Distinctive Polish phonology and orthography
7
8
  */
8
- export default function floatToCardinal(value: number | string | bigint, options?: object): string;
9
- export class N2WordsUK extends N2WordsRU {
10
- ones: {
9
+ export class Polish extends SlavicLanguage {
10
+ onesWords: {
11
11
  1: string;
12
12
  2: string;
13
13
  3: string;
@@ -18,7 +18,7 @@ export class N2WordsUK extends N2WordsRU {
18
18
  8: string;
19
19
  9: string;
20
20
  };
21
- onesFeminine: {
21
+ onesFeminineWords: {
22
22
  1: string;
23
23
  2: string;
24
24
  3: string;
@@ -29,7 +29,7 @@ export class N2WordsUK extends N2WordsRU {
29
29
  8: string;
30
30
  9: string;
31
31
  };
32
- tens: {
32
+ teensWords: {
33
33
  0: string;
34
34
  1: string;
35
35
  2: string;
@@ -41,7 +41,7 @@ export class N2WordsUK extends N2WordsRU {
41
41
  8: string;
42
42
  9: string;
43
43
  };
44
- twenties: {
44
+ twentiesWords: {
45
45
  2: string;
46
46
  3: string;
47
47
  4: string;
@@ -51,7 +51,7 @@ export class N2WordsUK extends N2WordsRU {
51
51
  8: string;
52
52
  9: string;
53
53
  };
54
- hundreds: {
54
+ hundredsWords: {
55
55
  1: string;
56
56
  2: string;
57
57
  3: string;
@@ -62,7 +62,7 @@ export class N2WordsUK extends N2WordsRU {
62
62
  8: string;
63
63
  9: string;
64
64
  };
65
- thousands: {
65
+ pluralForms: {
66
66
  1: string[];
67
67
  2: string[];
68
68
  3: string[];
@@ -74,5 +74,7 @@ export class N2WordsUK extends N2WordsRU {
74
74
  9: string[];
75
75
  10: string[];
76
76
  };
77
+ /** Implements Polish-specific three-form pluralization rules. */
78
+ pluralize(n: any, forms: any): any;
77
79
  }
78
- import { N2WordsRU } from './ru.js';
80
+ import { SlavicLanguage } from '../classes/slavic-language.js';
@@ -0,0 +1,110 @@
1
+ import { SlavicLanguage } from '../classes/slavic-language.js'
2
+
3
+ /**
4
+ * Polish language converter.
5
+ *
6
+ * Supports:
7
+ * - Three-form pluralization (one/few/many)
8
+ * - Polish-specific declension patterns
9
+ * - Distinctive Polish phonology and orthography
10
+ */
11
+ export class Polish extends SlavicLanguage {
12
+ negativeWord = 'minus'
13
+ decimalSeparatorWord = 'przecinek'
14
+ zeroWord = 'zero'
15
+
16
+ onesWords = {
17
+ 1: 'jeden',
18
+ 2: 'dwa',
19
+ 3: 'trzy',
20
+ 4: 'cztery',
21
+ 5: 'pięć',
22
+ 6: 'sześć',
23
+ 7: 'siedem',
24
+ 8: 'osiem',
25
+ 9: 'dziewięć'
26
+ }
27
+
28
+ onesFeminineWords = {
29
+ 1: 'jedna',
30
+ 2: 'dwie',
31
+ 3: 'trzy',
32
+ 4: 'cztery',
33
+ 5: 'pięć',
34
+ 6: 'sześć',
35
+ 7: 'siedem',
36
+ 8: 'osiem',
37
+ 9: 'dziewięć'
38
+ }
39
+
40
+ teensWords = {
41
+ 0: 'dziesięć',
42
+ 1: 'jedenaście',
43
+ 2: 'dwanaście',
44
+ 3: 'trzynaście',
45
+ 4: 'czternaście',
46
+ 5: 'piętnaście',
47
+ 6: 'szesnaście',
48
+ 7: 'siedemnaście',
49
+ 8: 'osiemnaście',
50
+ 9: 'dziewiętnaście'
51
+ }
52
+
53
+ twentiesWords = {
54
+ 2: 'dwadzieścia',
55
+ 3: 'trzydzieści',
56
+ 4: 'czterdzieści',
57
+ 5: 'pięćdziesiąt',
58
+ 6: 'sześćdziesiąt',
59
+ 7: 'siedemdziesiąt',
60
+ 8: 'osiemdziesiąt',
61
+ 9: 'dziewięćdziesiąt'
62
+ }
63
+
64
+ hundredsWords = {
65
+ 1: 'sto',
66
+ 2: 'dwieście',
67
+ 3: 'trzysta',
68
+ 4: 'czterysta',
69
+ 5: 'pięćset',
70
+ 6: 'sześćset',
71
+ 7: 'siedemset',
72
+ 8: 'osiemset',
73
+ 9: 'dziewięćset'
74
+ }
75
+
76
+ pluralForms = {
77
+ 1: ['tysiąc', 'tysiące', 'tysięcy'], // 10^ 3
78
+ 2: ['milion', 'miliony', 'milionów'], // 10^ 6
79
+ 3: ['miliard', 'miliardy', 'miliardów'], // 10^ 9
80
+ 4: ['bilion', 'biliony', 'bilionów'], // 10^ 12
81
+ 5: ['biliard', 'biliardy', 'biliardów'], // 10^ 15
82
+ 6: ['trylion', 'tryliony', 'trylionów'], // 10^ 18
83
+ 7: ['tryliard', 'tryliardy', 'tryliardów'], // 10^ 21
84
+ 8: ['kwadrylion', 'kwadryliony', 'kwadrylionów'], // 10^ 24
85
+ 9: ['kwaryliard', 'kwadryliardy', 'kwadryliardów'], // 10^ 27
86
+ 10: ['kwintylion', 'kwintyliony', 'kwintylionów'] // 10^ 30
87
+ }
88
+
89
+ /**
90
+ * Polish omits "one" before scale words.
91
+ * e.g., 1000 is "tysiąc" not "jeden tysiąc"
92
+ */
93
+ omitOneBeforeScale = true
94
+
95
+ /** Implements Polish-specific three-form pluralization rules. */
96
+ pluralize (n, forms) {
97
+ if (n === 1n) {
98
+ return forms[0]
99
+ }
100
+
101
+ const lastDigit = n % 10n
102
+ const lastTwoDigits = n % 100n
103
+
104
+ if (lastDigit < 5n && lastDigit > 1n && (lastTwoDigits < 10n || lastTwoDigits > 20n)) {
105
+ return forms[1]
106
+ }
107
+
108
+ return forms[2]
109
+ }
110
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * (European) Portuguese language converter.
3
+ *
4
+ * Supports:
5
+ * - Gender-aware hundreds (duzentos, trezentos)
6
+ * - "e" (and) conjunction for number combinations
7
+ * - Post-processing to normalize word flow
8
+ */
9
+ export class Portuguese extends GreedyScaleLanguage {
10
+ static POSTCLEAN_REGEX: RegExp;
11
+ scaleWords: (string | bigint)[][];
12
+ hundredsWords: {
13
+ 1: string;
14
+ 2: string;
15
+ 3: string;
16
+ 4: string;
17
+ 5: string;
18
+ 6: string;
19
+ 7: string;
20
+ 8: string;
21
+ 9: string;
22
+ };
23
+ finalizeWords(words: any): any;
24
+ /** Combines two word-sets according to Portuguese grammar rules. */
25
+ combineWordSets(preceding: any, following: any): {
26
+ [x: string]: any;
27
+ };
28
+ }
29
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
@@ -0,0 +1,112 @@
1
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
2
+
3
+ /**
4
+ * (European) Portuguese language converter.
5
+ *
6
+ * Supports:
7
+ * - Gender-aware hundreds (duzentos, trezentos)
8
+ * - "e" (and) conjunction for number combinations
9
+ * - Post-processing to normalize word flow
10
+ */
11
+ export class Portuguese extends GreedyScaleLanguage {
12
+ negativeWord = 'menos'
13
+ decimalSeparatorWord = 'vírgula'
14
+ zeroWord = 'zero'
15
+
16
+ scaleWords = [
17
+ [1_000_000_000_000_000_000_000_000n, 'quatrilião'],
18
+ [1_000_000_000_000_000_000n, 'trilião'],
19
+ [1_000_000_000_000n, 'bilião'],
20
+ [1_000_000n, 'milião'],
21
+ [1000n, 'mil'],
22
+ [100n, 'cem'],
23
+ [90n, 'noventa'],
24
+ [80n, 'oitenta'],
25
+ [70n, 'setenta'],
26
+ [60n, 'sessenta'],
27
+ [50n, 'cinquenta'],
28
+ [40n, 'quarenta'],
29
+ [30n, 'trinta'],
30
+ [20n, 'vinte'],
31
+ [19n, 'dezanove'],
32
+ [18n, 'dezoito'],
33
+ [17n, 'dezassete'],
34
+ [16n, 'dezasseis'],
35
+ [15n, 'quinze'],
36
+ [14n, 'catorze'],
37
+ [13n, 'treze'],
38
+ [12n, 'doze'],
39
+ [11n, 'onze'],
40
+ [10n, 'dez'],
41
+ [9n, 'nove'],
42
+ [8n, 'oito'],
43
+ [7n, 'sete'],
44
+ [6n, 'seis'],
45
+ [5n, 'cinco'],
46
+ [4n, 'quatro'],
47
+ [3n, 'três'],
48
+ [2n, 'dois'],
49
+ [1n, 'um'],
50
+ [0n, 'zero']
51
+ ]
52
+
53
+ hundredsWords = {
54
+ 1: 'cento',
55
+ 2: 'duzentos',
56
+ 3: 'trezentos',
57
+ 4: 'quatrocentos',
58
+ 5: 'quinhentos',
59
+ 6: 'seiscentos',
60
+ 7: 'setecentos',
61
+ 8: 'oitocentos',
62
+ 9: 'novecentos'
63
+ }
64
+
65
+ // Pre-compiled regex patterns for postClean - avoid recompilation
66
+ static POSTCLEAN_REGEX = / e (.*entos?) (?=.*e)/g
67
+
68
+ finalizeWords (words) {
69
+ return words.replaceAll(Portuguese.POSTCLEAN_REGEX, ' $1 ')
70
+ }
71
+
72
+ /** Combines two word-sets according to Portuguese grammar rules. */
73
+ combineWordSets (preceding, following) {
74
+ // Extract words and numeric values
75
+ let precedingWord = Object.keys(preceding)[0]
76
+ let followingWord = Object.keys(following)[0]
77
+ const precedingValue = Object.values(preceding)[0] // BigInt
78
+ const followingValue = Object.values(following)[0] // BigInt
79
+
80
+ // Implicit "um": omit before millions ("um milhão" → "milhão")
81
+ if (precedingValue === 1n) {
82
+ if (followingValue < 1_000_000n) return { [followingWord]: followingValue }
83
+ precedingWord = 'um'
84
+ } else if (precedingValue === 100n && followingValue % 1000n !== 0n) {
85
+ // Special handling: "cem" (100) becomes "cento" when followed by non-thousands
86
+ precedingWord = 'cento'
87
+ }
88
+
89
+ if (followingValue < precedingValue) {
90
+ return { [`${precedingWord} e ${followingWord}`]: precedingValue + followingValue }
91
+ }
92
+
93
+ // Handle "milião" -> "milhão" conversion
94
+ if (followingWord === 'milião') followingWord = 'milhão'
95
+
96
+ // Pluralization logic for large numbers
97
+ if (precedingValue > 1n) {
98
+ if (followingValue % 1_000_000_000n === 0n) {
99
+ followingWord = followingWord.replace('bilião', 'biliões')
100
+ } else if (followingValue % 1_000_000n === 0n) {
101
+ followingWord = followingWord.replace('milhão', 'milhões')
102
+ }
103
+ }
104
+
105
+ if (followingValue === 100n) {
106
+ precedingWord = this.hundredsWords[precedingValue]
107
+ return { [`${precedingWord}`]: precedingValue * followingValue }
108
+ }
109
+
110
+ return { [`${precedingWord} ${followingWord}`]: precedingValue * followingValue }
111
+ }
112
+ }