n2words 1.24.0 → 3.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 (280) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +183 -156
  3. package/dist/languages/am-Latn.js +3 -0
  4. package/dist/languages/am-Latn.js.map +1 -0
  5. package/dist/languages/am.js +3 -0
  6. package/dist/languages/am.js.map +1 -0
  7. package/dist/languages/ar.js +3 -2
  8. package/dist/languages/ar.js.map +1 -1
  9. package/dist/languages/az.js +3 -2
  10. package/dist/languages/az.js.map +1 -1
  11. package/dist/languages/bn.js +3 -2
  12. package/dist/languages/bn.js.map +1 -1
  13. package/dist/languages/cs.js +3 -2
  14. package/dist/languages/cs.js.map +1 -1
  15. package/dist/languages/da.js +3 -2
  16. package/dist/languages/da.js.map +1 -1
  17. package/dist/languages/de.js +3 -2
  18. package/dist/languages/de.js.map +1 -1
  19. package/dist/languages/el.js +3 -2
  20. package/dist/languages/el.js.map +1 -1
  21. package/dist/languages/en.js +3 -2
  22. package/dist/languages/en.js.map +1 -1
  23. package/dist/languages/es.js +3 -2
  24. package/dist/languages/es.js.map +1 -1
  25. package/dist/languages/fa.js +3 -2
  26. package/dist/languages/fa.js.map +1 -1
  27. package/dist/languages/fi.js +3 -0
  28. package/dist/languages/fi.js.map +1 -0
  29. package/dist/languages/fil.js +3 -2
  30. package/dist/languages/fil.js.map +1 -1
  31. package/dist/languages/fr-BE.js +3 -2
  32. package/dist/languages/fr-BE.js.map +1 -1
  33. package/dist/languages/fr.js +3 -2
  34. package/dist/languages/fr.js.map +1 -1
  35. package/dist/languages/gu.js +3 -2
  36. package/dist/languages/gu.js.map +1 -1
  37. package/dist/languages/ha.js +3 -0
  38. package/dist/languages/ha.js.map +1 -0
  39. package/dist/languages/hbo.js +3 -0
  40. package/dist/languages/hbo.js.map +1 -0
  41. package/dist/languages/he.js +3 -2
  42. package/dist/languages/he.js.map +1 -1
  43. package/dist/languages/hi.js +3 -2
  44. package/dist/languages/hi.js.map +1 -1
  45. package/dist/languages/hr.js +3 -2
  46. package/dist/languages/hr.js.map +1 -1
  47. package/dist/languages/hu.js +3 -2
  48. package/dist/languages/hu.js.map +1 -1
  49. package/dist/languages/id.js +3 -2
  50. package/dist/languages/id.js.map +1 -1
  51. package/dist/languages/it.js +3 -2
  52. package/dist/languages/it.js.map +1 -1
  53. package/dist/languages/ja.js +3 -2
  54. package/dist/languages/ja.js.map +1 -1
  55. package/dist/languages/kn.js +3 -2
  56. package/dist/languages/kn.js.map +1 -1
  57. package/dist/languages/ko.js +3 -2
  58. package/dist/languages/ko.js.map +1 -1
  59. package/dist/languages/lt.js +3 -2
  60. package/dist/languages/lt.js.map +1 -1
  61. package/dist/languages/lv.js +3 -2
  62. package/dist/languages/lv.js.map +1 -1
  63. package/dist/languages/mr.js +3 -2
  64. package/dist/languages/mr.js.map +1 -1
  65. package/dist/languages/ms.js +3 -2
  66. package/dist/languages/ms.js.map +1 -1
  67. package/dist/languages/nb.js +3 -2
  68. package/dist/languages/nb.js.map +1 -1
  69. package/dist/languages/nl.js +3 -2
  70. package/dist/languages/nl.js.map +1 -1
  71. package/dist/languages/pa.js +3 -0
  72. package/dist/languages/pa.js.map +1 -0
  73. package/dist/languages/pl.js +3 -2
  74. package/dist/languages/pl.js.map +1 -1
  75. package/dist/languages/pt.js +3 -2
  76. package/dist/languages/pt.js.map +1 -1
  77. package/dist/languages/ro.js +3 -2
  78. package/dist/languages/ro.js.map +1 -1
  79. package/dist/languages/ru.js +3 -2
  80. package/dist/languages/ru.js.map +1 -1
  81. package/dist/languages/sr-Cyrl.js +3 -0
  82. package/dist/languages/sr-Cyrl.js.map +1 -0
  83. package/dist/languages/sr-Latn.js +3 -2
  84. package/dist/languages/sr-Latn.js.map +1 -1
  85. package/dist/languages/sv.js +3 -2
  86. package/dist/languages/sv.js.map +1 -1
  87. package/dist/languages/sw.js +3 -2
  88. package/dist/languages/sw.js.map +1 -1
  89. package/dist/languages/ta.js +3 -2
  90. package/dist/languages/ta.js.map +1 -1
  91. package/dist/languages/te.js +3 -2
  92. package/dist/languages/te.js.map +1 -1
  93. package/dist/languages/th.js +3 -2
  94. package/dist/languages/th.js.map +1 -1
  95. package/dist/languages/tr.js +3 -2
  96. package/dist/languages/tr.js.map +1 -1
  97. package/dist/languages/uk.js +3 -2
  98. package/dist/languages/uk.js.map +1 -1
  99. package/dist/languages/ur.js +3 -2
  100. package/dist/languages/ur.js.map +1 -1
  101. package/dist/languages/vi.js +3 -2
  102. package/dist/languages/vi.js.map +1 -1
  103. package/dist/languages/zh-Hans.js +3 -2
  104. package/dist/languages/zh-Hans.js.map +1 -1
  105. package/dist/languages/zh-Hant.js +3 -0
  106. package/dist/languages/zh-Hant.js.map +1 -0
  107. package/dist/n2words.js +3 -2
  108. package/dist/n2words.js.map +1 -1
  109. package/lib/languages/am-Latn.d.ts +7 -0
  110. package/lib/languages/am-Latn.js +164 -0
  111. package/lib/languages/am.d.ts +7 -0
  112. package/lib/languages/am.js +164 -0
  113. package/lib/languages/ar.d.ts +17 -0
  114. package/lib/languages/ar.js +171 -209
  115. package/lib/languages/az.d.ts +7 -0
  116. package/lib/languages/az.js +167 -49
  117. package/lib/languages/bn.d.ts +7 -0
  118. package/lib/languages/bn.js +142 -123
  119. package/lib/languages/cs.d.ts +18 -0
  120. package/lib/languages/cs.js +303 -176
  121. package/lib/languages/da.d.ts +14 -0
  122. package/lib/languages/da.js +267 -139
  123. package/lib/languages/de.d.ts +17 -0
  124. package/lib/languages/de.js +310 -113
  125. package/lib/languages/el.d.ts +14 -0
  126. package/lib/languages/el.js +225 -98
  127. package/lib/languages/en.d.ts +17 -0
  128. package/lib/languages/en.js +235 -102
  129. package/lib/languages/es.d.ts +21 -0
  130. package/lib/languages/es.js +307 -125
  131. package/lib/languages/fa.d.ts +7 -0
  132. package/lib/languages/fa.js +115 -108
  133. package/lib/languages/fi.d.ts +14 -0
  134. package/lib/languages/fi.js +245 -0
  135. package/lib/languages/fil.d.ts +7 -0
  136. package/lib/languages/fil.js +199 -139
  137. package/lib/languages/fr-BE.d.ts +11 -0
  138. package/lib/languages/fr-BE.js +287 -48
  139. package/lib/languages/fr.d.ts +21 -0
  140. package/lib/languages/fr.js +343 -119
  141. package/lib/languages/gu.d.ts +7 -0
  142. package/lib/languages/gu.js +125 -144
  143. package/lib/languages/ha.d.ts +7 -0
  144. package/lib/languages/ha.js +230 -0
  145. package/lib/languages/hbo.d.ts +13 -0
  146. package/lib/languages/hbo.js +300 -0
  147. package/lib/languages/he.d.ts +13 -0
  148. package/lib/languages/he.js +230 -283
  149. package/lib/languages/hi.d.ts +7 -0
  150. package/lib/languages/hi.js +142 -123
  151. package/lib/languages/hr.d.ts +11 -0
  152. package/lib/languages/hr.js +190 -129
  153. package/lib/languages/hu.d.ts +7 -0
  154. package/lib/languages/hu.js +194 -133
  155. package/lib/languages/id.d.ts +7 -0
  156. package/lib/languages/id.js +167 -140
  157. package/lib/languages/it.d.ts +19 -0
  158. package/lib/languages/it.js +337 -108
  159. package/lib/languages/ja.d.ts +17 -0
  160. package/lib/languages/ja.js +224 -155
  161. package/lib/languages/kn.d.ts +7 -0
  162. package/lib/languages/kn.js +128 -62
  163. package/lib/languages/ko.d.ts +14 -0
  164. package/lib/languages/ko.js +250 -70
  165. package/lib/languages/lt.d.ts +18 -0
  166. package/lib/languages/lt.js +287 -148
  167. package/lib/languages/lv.d.ts +18 -0
  168. package/lib/languages/lv.js +291 -123
  169. package/lib/languages/mr.d.ts +7 -0
  170. package/lib/languages/mr.js +125 -144
  171. package/lib/languages/ms.d.ts +7 -0
  172. package/lib/languages/ms.js +171 -112
  173. package/lib/languages/nb.d.ts +14 -0
  174. package/lib/languages/nb.js +275 -100
  175. package/lib/languages/nl.d.ts +26 -0
  176. package/lib/languages/nl.js +307 -174
  177. package/lib/languages/pa.d.ts +7 -0
  178. package/lib/languages/pa.js +163 -0
  179. package/lib/languages/pl.d.ts +22 -0
  180. package/lib/languages/pl.js +299 -158
  181. package/lib/languages/pt.d.ts +17 -0
  182. package/lib/languages/pt.js +279 -120
  183. package/lib/languages/ro.d.ts +18 -0
  184. package/lib/languages/ro.js +214 -337
  185. package/lib/languages/ru.d.ts +11 -0
  186. package/lib/languages/ru.js +219 -95
  187. package/lib/languages/sr-Cyrl.d.ts +11 -0
  188. package/lib/languages/sr-Cyrl.js +215 -0
  189. package/lib/languages/sr-Latn.d.ts +11 -0
  190. package/lib/languages/sr-Latn.js +190 -132
  191. package/lib/languages/sv.d.ts +14 -0
  192. package/lib/languages/sv.js +280 -103
  193. package/lib/languages/sw.d.ts +7 -0
  194. package/lib/languages/sw.js +135 -103
  195. package/lib/languages/ta.d.ts +7 -0
  196. package/lib/languages/ta.js +133 -205
  197. package/lib/languages/te.d.ts +7 -0
  198. package/lib/languages/te.js +148 -213
  199. package/lib/languages/th.d.ts +7 -0
  200. package/lib/languages/th.js +139 -101
  201. package/lib/languages/tr.d.ts +18 -0
  202. package/lib/languages/tr.js +246 -66
  203. package/lib/languages/uk.d.ts +11 -0
  204. package/lib/languages/uk.js +197 -101
  205. package/lib/languages/ur.d.ts +7 -0
  206. package/lib/languages/ur.js +160 -123
  207. package/lib/languages/vi.d.ts +17 -0
  208. package/lib/languages/vi.js +287 -164
  209. package/lib/languages/zh-Hans.d.ts +11 -0
  210. package/lib/languages/zh-Hans.js +159 -142
  211. package/lib/languages/zh-Hant.d.ts +11 -0
  212. package/lib/languages/zh-Hant.js +202 -0
  213. package/lib/n2words.d.ts +53 -0
  214. package/lib/n2words.js +91 -227
  215. package/lib/utils/is-plain-object.d.ts +13 -0
  216. package/lib/utils/is-plain-object.js +17 -0
  217. package/lib/utils/parse-numeric.d.ts +17 -0
  218. package/lib/utils/parse-numeric.js +108 -0
  219. package/lib/utils/validate-options.d.ts +8 -0
  220. package/lib/utils/validate-options.js +16 -0
  221. package/package.json +118 -67
  222. package/dist/languages/pa-Guru.js +0 -2
  223. package/dist/languages/pa-Guru.js.map +0 -1
  224. package/lib/classes/abstract-language.js +0 -261
  225. package/lib/classes/greedy-scale-language.js +0 -195
  226. package/lib/classes/slavic-language.js +0 -251
  227. package/lib/classes/south-asian-language.js +0 -161
  228. package/lib/classes/turkic-language.js +0 -63
  229. package/lib/languages/pa-Guru.js +0 -126
  230. package/typings/classes/abstract-language.d.ts +0 -144
  231. package/typings/classes/greedy-scale-language.d.ts +0 -148
  232. package/typings/classes/slavic-language.d.ts +0 -145
  233. package/typings/classes/south-asian-language.d.ts +0 -101
  234. package/typings/classes/turkic-language.d.ts +0 -42
  235. package/typings/languages/ar.d.ts +0 -93
  236. package/typings/languages/az.d.ts +0 -25
  237. package/typings/languages/bn.d.ts +0 -1
  238. package/typings/languages/cs.d.ts +0 -120
  239. package/typings/languages/da.d.ts +0 -53
  240. package/typings/languages/de.d.ts +0 -26
  241. package/typings/languages/el.d.ts +0 -11
  242. package/typings/languages/en.d.ts +0 -30
  243. package/typings/languages/es.d.ts +0 -43
  244. package/typings/languages/fa.d.ts +0 -81
  245. package/typings/languages/fil.d.ts +0 -12
  246. package/typings/languages/fr-BE.d.ts +0 -41
  247. package/typings/languages/fr.d.ts +0 -43
  248. package/typings/languages/gu.d.ts +0 -12
  249. package/typings/languages/he.d.ts +0 -197
  250. package/typings/languages/hi.d.ts +0 -1
  251. package/typings/languages/hr.d.ts +0 -110
  252. package/typings/languages/hu.d.ts +0 -37
  253. package/typings/languages/id.d.ts +0 -69
  254. package/typings/languages/it.d.ts +0 -51
  255. package/typings/languages/ja.d.ts +0 -58
  256. package/typings/languages/kn.d.ts +0 -11
  257. package/typings/languages/ko.d.ts +0 -25
  258. package/typings/languages/lt.d.ts +0 -110
  259. package/typings/languages/lv.d.ts +0 -99
  260. package/typings/languages/mr.d.ts +0 -12
  261. package/typings/languages/ms.d.ts +0 -37
  262. package/typings/languages/nb.d.ts +0 -27
  263. package/typings/languages/nl.d.ts +0 -65
  264. package/typings/languages/pa-Guru.d.ts +0 -1
  265. package/typings/languages/pl.d.ts +0 -116
  266. package/typings/languages/pt.d.ts +0 -39
  267. package/typings/languages/ro.d.ts +0 -229
  268. package/typings/languages/ru.d.ts +0 -108
  269. package/typings/languages/sr-Latn.d.ts +0 -98
  270. package/typings/languages/sv.d.ts +0 -30
  271. package/typings/languages/sw.d.ts +0 -1
  272. package/typings/languages/ta.d.ts +0 -1
  273. package/typings/languages/te.d.ts +0 -1
  274. package/typings/languages/th.d.ts +0 -1
  275. package/typings/languages/tr.d.ts +0 -46
  276. package/typings/languages/uk.d.ts +0 -117
  277. package/typings/languages/ur.d.ts +0 -1
  278. package/typings/languages/vi.d.ts +0 -116
  279. package/typings/languages/zh-Hans.d.ts +0 -57
  280. package/typings/n2words.d.ts +0 -177
@@ -1,229 +1,164 @@
1
- import AbstractLanguage from '../classes/abstract-language.js'
2
-
3
- class Telugu extends AbstractLanguage {
4
- negativeWord = 'మైనస్'
5
- decimalSeparatorWord = 'పాయింట్'
6
- zeroWord = 'సున్నా'
7
- convertDecimalsPerDigit = true // Enable digit-by-digit decimal conversion
8
- belowHundred = [
9
- 'సున్నా',
10
- 'ఒకటి',
11
- 'రెండు',
12
- 'మూడు',
13
- 'నాలుగు',
14
- 'ఐదు',
15
- 'ఆరు',
16
- 'ఏడు',
17
- 'ఎనిమిది',
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
- hundreds = [
112
- '',
113
- 'వంద',
114
- 'రెండు వందలు',
115
- 'మూడు వందలు',
116
- 'నాలుగు వందలు',
117
- 'ఐదు వందలు',
118
- 'ఆరు వందలు',
119
- 'ఏడు వందలు',
120
- 'ఎనిమిది వందలు',
121
- 'తొమ్మిది వందలు'
122
- ]
123
-
124
- // Digits map 1–9 for decimal reading
125
- digits = [
126
- 'ఒకటి',
127
- 'రెండు',
128
- 'మూడు',
129
- 'నాలుగు',
130
- 'ఐదు',
131
- 'ఆరు',
132
- 'ఏడు',
133
- 'ఎనిమిది',
134
- 'తొమ్మిది'
135
- ]
136
-
137
- scales = [
138
- '',
139
- 'వెయ్యి',
140
- 'లక్ష',
141
- 'కోటి',
142
- 'అరబ్',
143
- 'ఖరబ్',
144
- 'నిల్',
145
- 'పడ్మ',
146
- 'శంకు'
147
- ]
148
-
149
- /**
150
- * Convert numbers below 100 to Telugu words.
151
- *
152
- * @param {number} number The number to convert (0-99).
153
- * @returns {string} The Telugu representation.
154
- */
155
- convertBelowHundred (number) {
156
- return this.belowHundred[number]
1
+ /**
2
+ * Telugu language converter - Functional Implementation
3
+ *
4
+ * Self-contained converter for South Asian numbering.
5
+ *
6
+ * Key features:
7
+ * - Indian numbering system (వెయ్యి, లక్ష, కోటి)
8
+ * - Telugu script
9
+ * - 3-2-2 grouping pattern
10
+ * - Complete word forms for 0-99
11
+ * - Per-digit decimal reading
12
+ */
13
+
14
+ import { parseNumericValue } from '../utils/parse-numeric.js'
15
+
16
+ // ============================================================================
17
+ // Vocabulary
18
+ // ============================================================================
19
+
20
+ const ZERO = 'సున్నా'
21
+ const NEGATIVE = 'మైనస్'
22
+ const DECIMAL_SEP = 'పాయింట్'
23
+
24
+ const BELOW_HUNDRED = [
25
+ 'సున్నా', 'ఒకటి', 'రెండు', 'మూడు', 'నాలుగు', 'ఐదు', 'ఆరు', 'ఏడు', 'ఎనిమిది', 'తొమ్మిది',
26
+ 'పది', 'పదకొండు', 'పన్నెండు', 'పదమూడు', 'పద్నాలుగు', 'పదిహేను', 'పదహారు', 'పదిహేడు', 'పద్దెనిమిది', 'పంతొమ్మిది',
27
+ 'ఇరవై', 'ఇరవై ఒక్కటి', 'ఇరవై రెండు', 'ఇరవై మూడు', 'ఇరవై నాలుగు', 'ఇరవై ఐదు', 'ఇరవై ఆరు', 'ఇరవై ఏడు', 'ఇరవై ఎనిమిది', 'ఇరవై తొమ్మిది',
28
+ 'ముప్పై', 'ముప్పై ఒకటి', 'ముప్పై రెండు', 'ముప్పై మూడు', 'ముప్పై నాలుగు', 'ముప్పై ఐదు', 'ముప్పై ఆరు', 'ముప్పై ఏడు', 'ముప్పై ఎనిమిది', 'ముప్పై తొమ్మిది',
29
+ 'నలభై', 'నలభై ఒకటి', 'నలభై రెండు', 'నలభై మూడు', 'నలభై నాలుగు', 'నలభై ఐదు', 'నలభై ఆరు', 'నలభై ఏడు', 'నలభై ఎనిమిది', 'నలభై తొమ్మిది',
30
+ 'యాభై', 'యాభై ఒకటి', 'యాభై రెండు', 'యాభై మూడు', 'యాభై నాలుగు', 'యాభై ఐదు', 'యాభై ఆరు', 'యాభై ఏడు', 'యాభై ఎనిమిది', 'యాభై తొమ్మిది',
31
+ 'అరవై', 'అరవై ఒకటి', 'అరవై రెండు', 'అరవై మూడు', 'అరవై నాలుగు', 'అరవై ఐదు', 'అరవై ఆరు', 'అరవై ఏడు', 'అరవై ఎనిమిది', 'అరవై తొమ్మిది',
32
+ 'డెబ్బై', 'డెబ్బై ఒకటి', 'డెబ్బై రెండు', 'డెబ్బై మూడు', 'డెబ్బై నాలుగు', 'డెబ్బై ఐదు', 'డెబ్బై ఆరు', 'డెబ్బై ఏడు', 'డెబ్బై ఎనిమిది', 'డెబ్బై తొమ్మిది',
33
+ 'ఎనభై', 'ఎనభై ఒకటి', 'ఎనభై రెండు', 'ఎనభై మూడు', 'ఎనభై నాలుగు', 'ఎనభై ఐదు', 'ఎనభై ఆరు', 'ఎనభై ఏడు', 'ఎనభై ఎనిమిది', 'ఎనభై తొమ్మిది',
34
+ 'తొంభై', 'తొంభై ఒకటి', 'తొంభై రెండు', 'తొంభై మూడు', 'తొంభై నాలుగు', 'తొంభై ఐదు', 'తొంభై ఆరు', 'తొంభై ఏడు', 'తొంభై ఎనిమిది', 'తొంభై తొమ్మిది'
35
+ ]
36
+
37
+ // ============================================================================
38
+ // Vocabulary (continued)
39
+ // ============================================================================
40
+
41
+ const HUNDREDS = ['', 'వంద', 'రెండు వందలు', 'మూడు వందలు', 'నాలుగు వందలు', 'ఐదు వందలు', 'ఆరు వందలు', 'ఏడు వందలు', 'ఎనిమిది వందలు', 'తొమ్మిది వందలు']
42
+
43
+ // Ones for decimal reading
44
+ const ONES = ['ఒకటి', 'రెండు', 'మూడు', 'నాలుగు', 'ఐదు', 'ఆరు', 'ఏడు', 'ఎనిమిది', 'తొమ్మిది']
45
+
46
+ // Scale words: index 0 = units, 1 = thousand, 2 = lakh, etc.
47
+ const SCALE_WORDS = ['', 'వెయ్యి', 'లక్ష', 'కోటి', 'అరబ్', 'ఖరబ్', 'నిల్', 'పడ్మ', 'శంకు']
48
+
49
+ // ============================================================================
50
+ // Conversion Functions
51
+ // ============================================================================
52
+
53
+ /**
54
+ * Converts 0-999 to Telugu words.
55
+ */
56
+ function convertBelowThousand (n) {
57
+ if (n === 0) return ''
58
+ if (n < 100) return BELOW_HUNDRED[n]
59
+
60
+ const hundreds = Math.trunc(n / 100)
61
+ const remainder = n % 100
62
+
63
+ if (remainder === 0) {
64
+ return HUNDREDS[hundreds]
157
65
  }
66
+ return HUNDREDS[hundreds] + ' ' + BELOW_HUNDRED[remainder]
67
+ }
158
68
 
159
- /**
160
- * Convert numbers below 1000 to Telugu words.
161
- *
162
- * @param {number} number The number to convert (0-999).
163
- * @returns {string} The Telugu representation.
164
- */
165
- convertBelowThousand (number) {
166
- if (number === 0) return ''
167
- if (number < 100) return this.convertBelowHundred(number)
168
-
169
- const hundreds = Math.trunc(number / 100)
170
- const remainder = number % 100
171
- const parts = [this.hundreds[hundreds]]
172
-
173
- if (remainder > 0) {
174
- parts.push(this.convertBelowHundred(remainder))
175
- }
69
+ /**
70
+ * Converts a non-negative integer to Telugu words.
71
+ * Uses recursive approach for Indian 3-2-2 grouping pattern.
72
+ *
73
+ * @param {bigint} n - Non-negative integer to convert
74
+ * @returns {string} Telugu words
75
+ */
76
+ function integerToWords (n) {
77
+ if (n === 0n) return ZERO
78
+
79
+ // Fast path: numbers < 1000 (direct lookup)
80
+ if (n < 1000n) {
81
+ return convertBelowThousand(Number(n))
82
+ }
176
83
 
177
- return parts.join(' ').trim()
84
+ return buildLargeNumberWords(n, 0)
85
+ }
86
+
87
+ /**
88
+ * Recursively builds words for numbers >= 1000.
89
+ * Indian grouping: first 3 digits, then 2-digit groups.
90
+ *
91
+ * @param {bigint} n - Number to convert
92
+ * @param {number} scale - Current scale index (0=units, 1=thousands, etc.)
93
+ * @returns {string} Telugu words
94
+ */
95
+ function buildLargeNumberWords (n, scale) {
96
+ if (n === 0n) return ''
97
+
98
+ // Determine divisor: 1000 for first split, 100 for rest
99
+ const divisor = scale === 0 ? 1000n : 100n
100
+ const segment = Number(n % divisor)
101
+ const rest = n / divisor
102
+
103
+ // Build higher segments first (recursive)
104
+ let result = ''
105
+ if (rest > 0n) {
106
+ result = buildLargeNumberWords(rest, scale + 1)
178
107
  }
179
108
 
180
- /**
181
- * Split a number using Indian-style grouping (3-2-2 digits from right).
182
- *
183
- * @param {bigint} number The number to split.
184
- * @returns {number[]} Array of number groups.
185
- */
186
- splitIndian (number) {
187
- const numStr = number.toString()
188
- if (numStr.length <= 3) return [Number(numStr)]
189
-
190
- const groups = []
191
- const last3 = numStr.slice(-3)
192
- groups.unshift(Number(last3))
193
-
194
- let remaining = numStr.slice(0, -3)
195
- while (remaining.length > 0) {
196
- const group = remaining.slice(-2)
197
- groups.unshift(Number(group))
198
- remaining = remaining.slice(0, -2)
109
+ // Add current segment
110
+ if (segment > 0) {
111
+ if (result) result += ' '
112
+
113
+ if (scale === 0) {
114
+ // Units segment (0-999)
115
+ result += convertBelowThousand(segment)
116
+ } else {
117
+ // Scale segments (0-99)
118
+ const groupWords = (segment === 1) ? 'ఒక' : BELOW_HUNDRED[segment]
119
+ result += groupWords + ' ' + SCALE_WORDS[scale]
199
120
  }
121
+ }
122
+
123
+ return result
124
+ }
200
125
 
201
- return groups
126
+ function decimalPartToWords (decimalPart) {
127
+ // Per-digit decimal reading
128
+ const digits = []
129
+ for (const char of decimalPart) {
130
+ const d = parseInt(char, 10)
131
+ digits.push(d === 0 ? ZERO : ONES[d - 1])
202
132
  }
133
+ return digits.join(' ')
134
+ }
203
135
 
204
- convertWholePart (number) {
205
- if (number === 0n) return this.zeroWord
136
+ /**
137
+ * Converts a numeric value to Telugu words.
138
+ *
139
+ * @param {number | string | bigint} value - The numeric value to convert
140
+ * @returns {string} The number in Telugu words
141
+ */
142
+ function toWords (value) {
143
+ const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
206
144
 
207
- const groups = this.splitIndian(number)
208
- const groupCount = groups.length
209
- const words = []
145
+ let result = ''
210
146
 
211
- for (let i = 0; i < groupCount; i++) {
212
- const groupValue = groups[i]
213
- if (groupValue === 0) continue
147
+ if (isNegative) {
148
+ result = NEGATIVE + ' '
149
+ }
214
150
 
215
- const scaleIndex = groupCount - i - 1
216
- const groupWords = (groupValue === 1 && scaleIndex > 0) ? 'ఒక' : this.convertBelowThousand(groupValue)
217
- words.push(groupWords)
218
- if (scaleIndex > 0 && this.scales[scaleIndex]) {
219
- words.push(this.scales[scaleIndex])
220
- }
221
- }
151
+ result += integerToWords(integerPart)
222
152
 
223
- return words.join(' ').trim()
153
+ if (decimalPart) {
154
+ result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
224
155
  }
225
- }
226
156
 
227
- export default function convertToWords (value, options = {}) {
228
- return new Telugu(options).convertToWords(value)
157
+ return result
229
158
  }
159
+
160
+ // ============================================================================
161
+ // Exports
162
+ // ============================================================================
163
+
164
+ export { toWords }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Converts a numeric value to Thai words.
3
+ *
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @returns {string} The number in Thai words
6
+ */
7
+ export function toWords(value: number | string | bigint): string;
@@ -1,123 +1,161 @@
1
- import AbstractLanguage from '../classes/abstract-language.js'
2
-
3
- class Thai extends AbstractLanguage {
4
- negativeWord = 'ลบ'
5
- decimalSeparatorWord = 'จุด'
6
- zeroWord = 'ศูนย์'
7
- wordSeparator = ''
8
- convertDecimalsPerDigit = true // Enable digit-by-digit decimal conversion
9
-
10
- // Digits map 1–9
11
- digits = ['หนึ่ง', 'สอง', 'สาม', 'สี่', 'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า']
12
-
13
- /**
14
- * Convert numbers below one million to Thai words.
15
- *
16
- * @param {number} number The number to convert (0-999999).
17
- * @returns {string} The Thai representation.
18
- */
19
- convertBelowMillion (number) {
20
- if (number === 0) return ''
21
-
22
- let value = number
23
- const parts = []
24
-
25
- const hundredThousands = Math.trunc(value / 100000)
26
- value %= 100000
27
- const tenThousands = Math.trunc(value / 10000)
28
- value %= 10000
29
- const thousands = Math.trunc(value / 1000)
30
- value %= 1000
31
- const hundreds = Math.trunc(value / 100)
32
- value %= 100
33
- const tens = Math.trunc(value / 10)
34
- const ones = value % 10
35
-
36
- if (hundredThousands > 0) {
37
- parts.push(this.digits[hundredThousands - 1] + 'แสน')
38
- }
1
+ /**
2
+ * Thai language converter - Functional Implementation
3
+ *
4
+ * Self-contained converter with precomputed lookup tables.
5
+ *
6
+ * Key features:
7
+ * - No word separators (continuous Thai script)
8
+ * - Million-based grouping (ล้าน)
9
+ * - Special handling for 1 as "เอ็ด" in compounds
10
+ * - 20 is "ยี่สิบ" (not "สองสิบ")
11
+ * - Per-digit decimal reading
12
+ */
13
+
14
+ import { parseNumericValue } from '../utils/parse-numeric.js'
15
+
16
+ // ============================================================================
17
+ // Vocabulary
18
+ // ============================================================================
19
+
20
+ const ONES = ['หนึ่ง', 'สอง', 'สาม', 'สี่', 'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า']
21
+
22
+ const ZERO = 'ศูนย์'
23
+ const NEGATIVE = 'ลบ'
24
+ const DECIMAL_SEP = 'จุด'
25
+
26
+ // ============================================================================
27
+ // Conversion Functions
28
+ // ============================================================================
29
+
30
+ function convertBelowMillion (n) {
31
+ if (n === 0) return ''
32
+
33
+ let value = n
34
+ const parts = []
35
+
36
+ const hundredThousands = Math.trunc(value / 100000)
37
+ value %= 100000
38
+ const tenThousands = Math.trunc(value / 10000)
39
+ value %= 10000
40
+ const thousands = Math.trunc(value / 1000)
41
+ value %= 1000
42
+ const hundreds = Math.trunc(value / 100)
43
+ value %= 100
44
+ const tens = Math.trunc(value / 10)
45
+ const ones = value % 10
46
+
47
+ if (hundredThousands > 0) {
48
+ parts.push(ONES[hundredThousands - 1] + 'แสน')
49
+ }
39
50
 
40
- if (tenThousands > 0) {
41
- if (tenThousands === 1) {
42
- parts.push('หนึ่งหมื่น')
43
- } else {
44
- parts.push(this.digits[tenThousands - 1] + 'หมื่น')
45
- }
51
+ if (tenThousands > 0) {
52
+ if (tenThousands === 1) {
53
+ parts.push('หนึ่งหมื่น')
54
+ } else {
55
+ parts.push(ONES[tenThousands - 1] + 'หมื่น')
46
56
  }
57
+ }
47
58
 
48
- if (thousands > 0) {
49
- parts.push(this.digits[thousands - 1] + 'พัน')
50
- }
59
+ if (thousands > 0) {
60
+ parts.push(ONES[thousands - 1] + 'พัน')
61
+ }
51
62
 
52
- if (hundreds > 0) {
53
- parts.push(this.digits[hundreds - 1] + 'ร้อย')
54
- }
63
+ if (hundreds > 0) {
64
+ parts.push(ONES[hundreds - 1] + 'ร้อย')
65
+ }
55
66
 
56
- if (tens > 0) {
57
- if (tens === 1) {
58
- parts.push('สิบ')
59
- } else if (tens === 2) {
60
- parts.push('ยี่สิบ')
61
- } else {
62
- parts.push(this.digits[tens - 1] + 'สิบ')
63
- }
67
+ if (tens > 0) {
68
+ if (tens === 1) {
69
+ parts.push('สิบ')
70
+ } else if (tens === 2) {
71
+ parts.push('ยี่สิบ')
72
+ } else {
73
+ parts.push(ONES[tens - 1] + 'สิบ')
64
74
  }
75
+ }
65
76
 
66
- if (ones > 0) {
67
- const hasHigher = hundredThousands > 0 || tenThousands > 0 || thousands > 0 || hundreds > 0 || tens > 0
68
- if (ones === 1 && (tens > 0 || hasHigher)) {
69
- parts.push('เอ็ด')
70
- } else {
71
- parts.push(this.digits[ones - 1])
72
- }
77
+ if (ones > 0) {
78
+ const hasHigher = hundredThousands > 0 || tenThousands > 0 || thousands > 0 || hundreds > 0 || tens > 0
79
+ if (ones === 1 && (tens > 0 || hasHigher)) {
80
+ parts.push('เอ็ด')
81
+ } else {
82
+ parts.push(ONES[ones - 1])
73
83
  }
74
-
75
- return parts.join('')
76
84
  }
77
85
 
78
- /**
79
- * Split a number into million-sized groups for processing.
80
- *
81
- * @param {bigint} number The number to split.
82
- * @returns {number[]} Array of number groups.
83
- */
84
- splitMillionGroups (number) {
85
- const groups = []
86
- let remaining = number
87
-
88
- const million = 1_000_000n
89
- while (remaining > 0n) {
90
- const chunk = Number(remaining % million)
91
- groups.unshift(chunk)
92
- remaining = remaining / million
93
- }
86
+ return parts.join('')
87
+ }
94
88
 
95
- return groups
89
+ function splitMillionGroups (n) {
90
+ const groups = []
91
+ let remaining = n
92
+
93
+ const million = 1_000_000n
94
+ while (remaining > 0n) {
95
+ const chunk = Number(remaining % million)
96
+ groups.unshift(chunk)
97
+ remaining = remaining / million
96
98
  }
97
99
 
98
- convertWholePart (number) {
99
- if (number === 0n) {
100
- return this.zeroWord
101
- }
100
+ return groups
101
+ }
102
102
 
103
- const groups = this.splitMillionGroups(number)
104
- const parts = []
103
+ function integerToWords (n) {
104
+ if (n === 0n) return ZERO
105
105
 
106
- for (let i = 0; i < groups.length; i++) {
107
- const groupValue = groups[i]
108
- if (groupValue === 0) continue
106
+ const groups = splitMillionGroups(n)
107
+ const parts = []
109
108
 
110
- parts.push(this.convertBelowMillion(groupValue))
111
- const remaining = groups.length - i - 1
112
- if (remaining > 0) {
113
- parts.push('ล้าน'.repeat(remaining))
114
- }
109
+ for (let i = 0; i < groups.length; i++) {
110
+ const groupValue = groups[i]
111
+ if (groupValue === 0) continue
112
+
113
+ parts.push(convertBelowMillion(groupValue))
114
+ const remaining = groups.length - i - 1
115
+ if (remaining > 0) {
116
+ parts.push('ล้าน'.repeat(remaining))
115
117
  }
118
+ }
119
+
120
+ return parts.join('')
121
+ }
116
122
 
117
- return parts.join('')
123
+ function decimalPartToWords (decimalPart) {
124
+ // Per-digit decimal reading
125
+ const digits = []
126
+ for (const char of decimalPart) {
127
+ const d = parseInt(char, 10)
128
+ digits.push(d === 0 ? ZERO : ONES[d - 1])
118
129
  }
130
+ return digits.join('')
119
131
  }
120
132
 
121
- export default function convertToWords (value, options = {}) {
122
- return new Thai(options).convertToWords(value)
133
+ /**
134
+ * Converts a numeric value to Thai words.
135
+ *
136
+ * @param {number | string | bigint} value - The numeric value to convert
137
+ * @returns {string} The number in Thai words
138
+ */
139
+ function toWords (value) {
140
+ const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
141
+
142
+ let result = ''
143
+
144
+ if (isNegative) {
145
+ result = NEGATIVE
146
+ }
147
+
148
+ result += integerToWords(integerPart)
149
+
150
+ if (decimalPart) {
151
+ result += DECIMAL_SEP + decimalPartToWords(decimalPart)
152
+ }
153
+
154
+ return result
123
155
  }
156
+
157
+ // ============================================================================
158
+ // Exports
159
+ // ============================================================================
160
+
161
+ export { toWords }