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,113 @@
1
+ import { SlavicLanguage } from '../classes/slavic-language.js'
2
+
3
+ /**
4
+ * Serbian language converter (Cyrillic script).
5
+ *
6
+ * Supports:
7
+ * - Three-form pluralization (one/few/many)
8
+ * - Gender agreement (један/једна, два/две)
9
+ * - Cyrillic script representation
10
+ */
11
+ export class SerbianCyrillic extends SlavicLanguage {
12
+ negativeWord = 'минус'
13
+ decimalSeparatorWord = 'запета'
14
+ zeroWord = 'нула'
15
+
16
+ onesWords = {
17
+ 1: 'један',
18
+ 2: 'два',
19
+ 3: 'три',
20
+ 4: 'четири',
21
+ 5: 'пет',
22
+ 6: 'шест',
23
+ 7: 'седам',
24
+ 8: 'осам',
25
+ 9: 'девет'
26
+ }
27
+
28
+ onesFeminineWords = {
29
+ 1: 'једна',
30
+ 2: 'две',
31
+ 3: 'три',
32
+ 4: 'четири',
33
+ 5: 'пет',
34
+ 6: 'шест',
35
+ 7: 'седам',
36
+ 8: 'осам',
37
+ 9: 'девет'
38
+ }
39
+
40
+ teensWords = {
41
+ 0: 'десет',
42
+ 1: 'једанаест',
43
+ 2: 'дванаест',
44
+ 3: 'тринаест',
45
+ 4: 'четрнаест',
46
+ 5: 'петнаест',
47
+ 6: 'шеснаест',
48
+ 7: 'седамнаест',
49
+ 8: 'осамнаест',
50
+ 9: 'деветнаест'
51
+ }
52
+
53
+ twentiesWords = {
54
+ 2: 'двадесет',
55
+ 3: 'тридесет',
56
+ 4: 'четрдесет',
57
+ 5: 'педесет',
58
+ 6: 'шездесет',
59
+ 7: 'седамдесет',
60
+ 8: 'осамдесет',
61
+ 9: 'деведесет'
62
+ }
63
+
64
+ hundredsWords = {
65
+ 1: 'сто',
66
+ 2: 'двеста',
67
+ 3: 'триста',
68
+ 4: 'четиристо',
69
+ 5: 'петсто',
70
+ 6: 'шесто',
71
+ 7: 'седамсто',
72
+ 8: 'осамсто',
73
+ 9: 'девестo'
74
+ }
75
+
76
+ pluralForms = {
77
+ 1: ['хиљада', 'хиљаде', 'хиљада'], // 10 ^ 3
78
+ 2: ['милион', 'милиона', 'милиона'], // 10 ^ 6
79
+ 3: ['милијарда', 'милијарде', 'милијарда'], // 10 ^ 9
80
+ 4: ['билион', 'билиона', 'билиона'], // 10 ^ 12
81
+ 5: ['билијарда', 'билијарде', 'билијарда'], // 10 ^ 15
82
+ 6: ['трилион', 'трилиона', 'трилиона'], // 10 ^ 18
83
+ 7: ['трилијарда', 'трилијарде', 'трилијарда'], // 10 ^ 21
84
+ 8: ['квадрилион', 'квадрилиона', 'квадрилиона'], // 10 ^ 24
85
+ 9: ['квадрилијарда', 'квадрилијарде', 'квадрилијарда'], // 10 ^ 27
86
+ 10: ['квинтилион', 'квинтилиона', 'квинтилиона'] // 10 ^ 30
87
+ }
88
+
89
+ /**
90
+ * Maps segment indices to whether they are grammatically feminine.
91
+ * In Serbian, thousands (index 1) are feminine, others are masculine.
92
+ * @type {Object.<number, boolean>}
93
+ */
94
+ scaleGenders = {
95
+ 1: true // thousands are feminine (others default to false)
96
+ }
97
+
98
+ /** Selects Serbian plural form: 1 = singular, 2-4 = few, else = many. */
99
+ pluralize (n, forms) {
100
+ const lastDigit = n % 10n
101
+ const lastTwoDigits = n % 100n
102
+
103
+ if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit === 1n) {
104
+ return forms[0]
105
+ }
106
+
107
+ if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit > 1n && lastDigit < 5n) {
108
+ return forms[1]
109
+ }
110
+
111
+ return forms[2]
112
+ }
113
+ }
@@ -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
+ * Serbian Latin language converter.
3
+ *
4
+ * Supports:
5
+ * - Three-form pluralization (one/few/many)
6
+ * - Gender agreement (jedan/jedna, dva/dve)
7
+ * - Latin script representation
7
8
  */
8
- export default function floatToCardinal(value: number | string | bigint, options?: object): string;
9
- export class N2WordsCZ extends N2WordsRU {
10
- ones: {
9
+ export class SerbianLatin extends SlavicLanguage {
10
+ onesWords: {
11
11
  1: string;
12
12
  2: string;
13
13
  3: string;
@@ -18,7 +18,18 @@ export class N2WordsCZ extends N2WordsRU {
18
18
  8: string;
19
19
  9: string;
20
20
  };
21
- tens: {
21
+ onesFeminineWords: {
22
+ 1: string;
23
+ 2: string;
24
+ 3: string;
25
+ 4: string;
26
+ 5: string;
27
+ 6: string;
28
+ 7: string;
29
+ 8: string;
30
+ 9: string;
31
+ };
32
+ teensWords: {
22
33
  0: string;
23
34
  1: string;
24
35
  2: string;
@@ -30,7 +41,7 @@ export class N2WordsCZ extends N2WordsRU {
30
41
  8: string;
31
42
  9: string;
32
43
  };
33
- twenties: {
44
+ twentiesWords: {
34
45
  2: string;
35
46
  3: string;
36
47
  4: string;
@@ -40,7 +51,7 @@ export class N2WordsCZ extends N2WordsRU {
40
51
  8: string;
41
52
  9: string;
42
53
  };
43
- hundreds: {
54
+ hundredsWords: {
44
55
  1: string;
45
56
  2: string;
46
57
  3: string;
@@ -51,7 +62,7 @@ export class N2WordsCZ extends N2WordsRU {
51
62
  8: string;
52
63
  9: string;
53
64
  };
54
- thousands: {
65
+ pluralForms: {
55
66
  1: string[];
56
67
  2: string[];
57
68
  3: string[];
@@ -63,6 +74,7 @@ export class N2WordsCZ extends N2WordsRU {
63
74
  9: string[];
64
75
  10: string[];
65
76
  };
66
- get separatorWord(): "celá" | "celé" | "celých";
77
+ /** Selects Serbian plural form: 1 = singular, 2-4 = few, else = many. */
78
+ pluralize(n: any, forms: any): any;
67
79
  }
68
- import { N2WordsRU } from './ru.js';
80
+ import { SlavicLanguage } from '../classes/slavic-language.js';
@@ -0,0 +1,113 @@
1
+ import { SlavicLanguage } from '../classes/slavic-language.js'
2
+
3
+ /**
4
+ * Serbian Latin language converter.
5
+ *
6
+ * Supports:
7
+ * - Three-form pluralization (one/few/many)
8
+ * - Gender agreement (jedan/jedna, dva/dve)
9
+ * - Latin script representation
10
+ */
11
+ export class SerbianLatin extends SlavicLanguage {
12
+ negativeWord = 'minus'
13
+ decimalSeparatorWord = 'zapeta'
14
+ zeroWord = 'nula'
15
+
16
+ onesWords = {
17
+ 1: 'jedan',
18
+ 2: 'dva',
19
+ 3: 'tri',
20
+ 4: 'četiri',
21
+ 5: 'pet',
22
+ 6: 'šest',
23
+ 7: 'sedam',
24
+ 8: 'osam',
25
+ 9: 'devet'
26
+ }
27
+
28
+ onesFeminineWords = {
29
+ 1: 'jedna',
30
+ 2: 'dve',
31
+ 3: 'tri',
32
+ 4: 'četiri',
33
+ 5: 'pet',
34
+ 6: 'šest',
35
+ 7: 'sedam',
36
+ 8: 'osam',
37
+ 9: 'devet'
38
+ }
39
+
40
+ teensWords = {
41
+ 0: 'deset',
42
+ 1: 'jedanaest',
43
+ 2: 'dvanaest',
44
+ 3: 'trinaest',
45
+ 4: 'četrnaest',
46
+ 5: 'petnaest',
47
+ 6: 'šesnaest',
48
+ 7: 'sedamnaest',
49
+ 8: 'osamnaest',
50
+ 9: 'devetnaest'
51
+ }
52
+
53
+ twentiesWords = {
54
+ 2: 'dvadeset',
55
+ 3: 'trideset',
56
+ 4: 'četrdeset',
57
+ 5: 'pedeset',
58
+ 6: 'šezdeset',
59
+ 7: 'sedamdeset',
60
+ 8: 'osamdeset',
61
+ 9: 'devedeset'
62
+ }
63
+
64
+ hundredsWords = {
65
+ 1: 'sto',
66
+ 2: 'dvesta',
67
+ 3: 'trista',
68
+ 4: 'četiristo',
69
+ 5: 'petsto',
70
+ 6: 'šesto',
71
+ 7: 'sedamsto',
72
+ 8: 'osamsto',
73
+ 9: 'devetsto'
74
+ }
75
+
76
+ pluralForms = {
77
+ 1: ['hiljada', 'hiljade', 'hiljada'], // 10 ^ 3
78
+ 2: ['milion', 'miliona', 'miliona'], // 10 ^ 6
79
+ 3: ['milijarda', 'milijarde', 'milijarda'], // 10 ^ 9
80
+ 4: ['bilion', 'biliona', 'biliona'], // 10 ^ 12
81
+ 5: ['bilijarda', 'bilijarde', 'bilijarda'], // 10 ^ 15
82
+ 6: ['trilion', 'triliona', 'triliona'], // 10 ^ 18
83
+ 7: ['trilijarda', 'trilijarde', 'trilijarda'], // 10 ^ 21
84
+ 8: ['kvadrilion', 'kvadriliona', 'kvadriliona'], // 10 ^ 24
85
+ 9: ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda'], // 10 ^ 27
86
+ 10: ['kvintilion', 'kvintiliona', 'kvintiliona'] // 10 ^ 30
87
+ }
88
+
89
+ /**
90
+ * Maps segment indices to whether they are grammatically feminine.
91
+ * In Serbian, thousands (index 1) are feminine, others are masculine.
92
+ * @type {Object.<number, boolean>}
93
+ */
94
+ scaleGenders = {
95
+ 1: true // thousands are feminine (others default to false)
96
+ }
97
+
98
+ /** Selects Serbian plural form: 1 = singular, 2-4 = few, else = many. */
99
+ pluralize (n, forms) {
100
+ const lastDigit = n % 10n
101
+ const lastTwoDigits = n % 100n
102
+
103
+ if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit === 1n) {
104
+ return forms[0]
105
+ }
106
+
107
+ if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit > 1n && lastDigit < 5n) {
108
+ return forms[1]
109
+ }
110
+
111
+ return forms[2]
112
+ }
113
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Swedish language converter.
3
+ *
4
+ * Supports:
5
+ * - Hyphenation for compound tens (tjugo-tre)
6
+ * - "och" (and) after hundreds
7
+ * - Space-separated larger composites
8
+ */
9
+ export class Swedish extends GreedyScaleLanguage {
10
+ scaleWords: (string | bigint)[][];
11
+ /** Combines two word-sets according to Swedish grammar rules. */
12
+ combineWordSets(preceding: any, following: any): any;
13
+ }
14
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
@@ -0,0 +1,90 @@
1
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
2
+
3
+ /**
4
+ * Swedish language converter.
5
+ *
6
+ * Supports:
7
+ * - Hyphenation for compound tens (tjugo-tre)
8
+ * - "och" (and) after hundreds
9
+ * - Space-separated larger composites
10
+ */
11
+ export class Swedish extends GreedyScaleLanguage {
12
+ negativeWord = 'minus'
13
+ decimalSeparatorWord = 'komma'
14
+ zeroWord = 'noll'
15
+ wordSeparator = ' '
16
+
17
+ scaleWords = [
18
+ [1_000_000_000_000_000_000_000_000_000n, 'kvadriljon'],
19
+ [1_000_000_000_000_000_000_000_000n, 'triljon'],
20
+ [1_000_000_000_000_000_000_000n, 'biljon'],
21
+ [1_000_000_000_000_000_000n, 'miljard'],
22
+ [1_000_000_000_000n, 'biljon'],
23
+ [1_000_000_000n, 'miljard'],
24
+ [1_000_000n, 'miljon'],
25
+ [1000n, 'tusen'],
26
+ [100n, 'hundra'],
27
+ [90n, 'nittio'],
28
+ [80n, 'åttio'],
29
+ [70n, 'sjuttio'],
30
+ [60n, 'sextio'],
31
+ [50n, 'femtio'],
32
+ [40n, 'fyrtio'],
33
+ [30n, 'trettio'],
34
+ [20n, 'tjugo'],
35
+ [19n, 'nitton'],
36
+ [18n, 'arton'],
37
+ [17n, 'sjutton'],
38
+ [16n, 'sexton'],
39
+ [15n, 'femton'],
40
+ [14n, 'fjorton'],
41
+ [13n, 'tretton'],
42
+ [12n, 'tolv'],
43
+ [11n, 'elva'],
44
+ [10n, 'tio'],
45
+ [9n, 'nio'],
46
+ [8n, 'åtta'],
47
+ [7n, 'sju'],
48
+ [6n, 'sex'],
49
+ [5n, 'fem'],
50
+ [4n, 'fyra'],
51
+ [3n, 'tre'],
52
+ [2n, 'två'],
53
+ [1n, 'ett'],
54
+ [0n, 'noll']
55
+ ]
56
+
57
+ /** Combines two word-sets according to Swedish grammar rules. */
58
+ combineWordSets (preceding, following) {
59
+ const precedingWord = Object.keys(preceding)[0]
60
+ const followingWord = Object.keys(following)[0]
61
+ const precedingValue = Object.values(preceding)[0]
62
+ const followingValue = Object.values(following)[0]
63
+
64
+ if (precedingValue === 1n && followingValue < 100n) {
65
+ return following
66
+ }
67
+
68
+ // Omit 'ett' before 'hundra' and 'tusen'
69
+ if (precedingValue === 1n && (followingValue === 100n || followingValue === 1000n)) {
70
+ return following
71
+ }
72
+
73
+ if (precedingValue < 100n && precedingValue > followingValue) {
74
+ return { [`${precedingWord}-${followingWord}`]: precedingValue + followingValue }
75
+ }
76
+
77
+ if (precedingValue >= 100n && followingValue < 100n) {
78
+ return { [`${precedingWord} och ${followingWord}`]: precedingValue + followingValue }
79
+ }
80
+
81
+ if (followingValue > precedingValue) {
82
+ if (precedingValue === 1n && followingValue >= 1_000_000n) {
83
+ return { [`en ${followingWord}`]: precedingValue * followingValue }
84
+ }
85
+ return { [`${precedingWord} ${followingWord}`]: precedingValue * followingValue }
86
+ }
87
+
88
+ return { [`${precedingWord} ${followingWord}`]: precedingValue + followingValue }
89
+ }
90
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Swahili language converter.
3
+ *
4
+ * Supports:
5
+ * - Swahili number words (moja, mbili, tatu)
6
+ * - Space-separated components
7
+ * - Simple decimal point notation
8
+ */
9
+ export class Swahili extends AbstractLanguage {
10
+ onesWords: {
11
+ 0: string;
12
+ 1: string;
13
+ 2: string;
14
+ 3: string;
15
+ 4: string;
16
+ 5: string;
17
+ 6: string;
18
+ 7: string;
19
+ 8: string;
20
+ 9: string;
21
+ };
22
+ tensWords: {
23
+ 10: string;
24
+ 20: string;
25
+ 30: string;
26
+ 40: string;
27
+ 50: string;
28
+ 60: string;
29
+ 70: string;
30
+ 80: string;
31
+ 90: string;
32
+ };
33
+ scaleWords: string[];
34
+ wordsUnder100(n: any): any;
35
+ wordsUnder1000(n: any): any;
36
+ splitBy3(number: any): number[];
37
+ integerToWords(integerPart: any): string;
38
+ }
39
+ import { AbstractLanguage } from '../classes/abstract-language.js';
@@ -0,0 +1,126 @@
1
+ import { AbstractLanguage } from '../classes/abstract-language.js'
2
+
3
+ /**
4
+ * Swahili language converter.
5
+ *
6
+ * Supports:
7
+ * - Swahili number words (moja, mbili, tatu)
8
+ * - Space-separated components
9
+ * - Simple decimal point notation
10
+ */
11
+ export class Swahili extends AbstractLanguage {
12
+ negativeWord = 'minus'
13
+ decimalSeparatorWord = 'nukta'
14
+ zeroWord = 'sifuri'
15
+
16
+ onesWords = {
17
+ 0: 'sifuri',
18
+ 1: 'moja',
19
+ 2: 'mbili',
20
+ 3: 'tatu',
21
+ 4: 'nne',
22
+ 5: 'tano',
23
+ 6: 'sita',
24
+ 7: 'saba',
25
+ 8: 'nane',
26
+ 9: 'tisa'
27
+ }
28
+
29
+ tensWords = {
30
+ 10: 'kumi',
31
+ 20: 'ishirini',
32
+ 30: 'thelathini',
33
+ 40: 'arobaini',
34
+ 50: 'hamsini',
35
+ 60: 'sitini',
36
+ 70: 'sabini',
37
+ 80: 'themanini',
38
+ 90: 'tisini'
39
+ }
40
+
41
+ scaleWords = [
42
+ '',
43
+ 'elfu',
44
+ 'milioni',
45
+ 'bilioni',
46
+ 'trilioni'
47
+ ]
48
+
49
+ wordsUnder100 (n) {
50
+ if (n < 10) return this.onesWords[n]
51
+ if (n === 10) return this.tensWords[10]
52
+ if (n < 20) {
53
+ // 11-19: 'kumi na <digit>'
54
+ return this.tensWords[10] + ' na ' + this.onesWords[n - 10]
55
+ }
56
+ const tens = Math.trunc(n / 10) * 10
57
+ const ones = n % 10
58
+ if (ones === 0) return this.tensWords[tens]
59
+ return this.tensWords[tens] + ' na ' + this.onesWords[ones]
60
+ }
61
+
62
+ wordsUnder1000 (n) {
63
+ if (n < 100) return this.wordsUnder100(n)
64
+ if (n === 100) return 'mia moja'
65
+ const hundreds = Math.trunc(n / 100)
66
+ const rest = n % 100
67
+ const parts = []
68
+
69
+ // Hundreds: 'mia <digit>'
70
+ parts.push('mia ' + this.onesWords[hundreds])
71
+ if (rest > 0) {
72
+ if (rest < 10) {
73
+ parts.push('na ' + this.onesWords[rest])
74
+ } else {
75
+ parts.push(this.wordsUnder100(rest))
76
+ }
77
+ }
78
+
79
+ return parts.join(' ')
80
+ }
81
+
82
+ splitBy3 (number) {
83
+ const s = number.toString()
84
+ if (s.length <= 3) return [Number(s)]
85
+ const groups = []
86
+ const last3 = s.slice(-3)
87
+ groups.unshift(Number(last3))
88
+ let remaining = s.slice(0, -3)
89
+ while (remaining.length > 0) {
90
+ const group = remaining.slice(-3)
91
+ groups.unshift(Number(group))
92
+ remaining = remaining.slice(0, -3)
93
+ }
94
+ return groups
95
+ }
96
+
97
+ integerToWords (integerPart) {
98
+ if (integerPart === 0n) return this.zeroWord
99
+
100
+ const groups = this.splitBy3(integerPart)
101
+ const parts = []
102
+
103
+ for (let i = 0; i < groups.length; i++) {
104
+ const val = groups[i]
105
+ if (val === 0) continue
106
+ const scaleIndex = groups.length - i - 1
107
+ // scale word
108
+ if (scaleIndex === 0) {
109
+ if (val < 10 && parts.length > 0) {
110
+ parts.push('na ' + this.onesWords[val])
111
+ } else if (val === 100 && parts.length > 0) {
112
+ // In compound numbers (e.g., 1100 -> 'elfu moja mia'), use 'mia' not 'mia moja'
113
+ parts.push('mia')
114
+ } else {
115
+ parts.push(this.wordsUnder1000(val))
116
+ }
117
+ } else {
118
+ // e.g., 'elfu moja', 'milioni mbili'
119
+ const unit = (val === 1) ? 'moja' : this.wordsUnder1000(val)
120
+ parts.push(this.scaleWords[scaleIndex] + ' ' + unit)
121
+ }
122
+ }
123
+
124
+ return parts.join(' ').trim()
125
+ }
126
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Tamil language converter.
3
+ *
4
+ * Supports:
5
+ * - Tamil numbering system
6
+ * - Tamil script
7
+ * - Complete word forms for 0-99
8
+ */
9
+ export class Tamil extends AbstractLanguage {
10
+ belowHundredWords: string[];
11
+ hundredsWords: string[];
12
+ onesWords: string[];
13
+ scaleWords: string[];
14
+ /** Convert numbers below 100 to Tamil words. */
15
+ convertBelowHundred(number: any): string;
16
+ convertBelowThousand(number: any): string;
17
+ splitIndian(number: any): number[];
18
+ integerToWords(integerPart: any): string;
19
+ }
20
+ import { AbstractLanguage } from '../classes/abstract-language.js';