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,83 +1,263 @@
1
- import GreedyScaleLanguage from '../classes/greedy-scale-language.js'
1
+ /**
2
+ * Korean language converter - Functional Implementation
3
+ *
4
+ * A performance-optimized number-to-words converter using precomputed lookup tables.
5
+ *
6
+ * Key features:
7
+ * - Myriad-based (만) grouping - 4 digits
8
+ * - Implicit '일' (one) omission before scale words
9
+ * - Space separation after 만+ scales
10
+ * - Hangul numerals
11
+ */
12
+
13
+ import { parseNumericValue } from '../utils/parse-numeric.js'
14
+
15
+ // ============================================================================
16
+ // Vocabulary (module-level constants)
17
+ // ============================================================================
18
+
19
+ const ONES = ['', '일', '이', '삼', '사', '오', '육', '칠', '팔', '구']
20
+
21
+ const TEN = '십'
22
+ const HUNDRED = '백'
23
+ const THOUSAND = '천'
24
+
25
+ const ZERO = '영'
26
+ const NEGATIVE = '마이너스'
27
+ const DECIMAL_SEP = '점'
28
+
29
+ // Myriad scale words (powers of 10,000)
30
+ // 만 (10^4), 억 (10^8), 조 (10^12), 경 (10^16), etc.
31
+ const SCALES = ['만', '억', '조', '경', '해', '자', '양']
32
+
33
+ // ============================================================================
34
+ // Precomputed Lookup Tables (built once at module load)
35
+ // ============================================================================
36
+
37
+ /**
38
+ * Builds segment word for 0-9999 (4-digit myriad segment).
39
+ * Korean omits "일" before 십, 백, 천.
40
+ */
41
+ function buildSegment (n) {
42
+ if (n === 0) return ''
43
+
44
+ const ones = n % 10
45
+ const tens = Math.floor(n / 10) % 10
46
+ const hundreds = Math.floor(n / 100) % 10
47
+ const thousands = Math.floor(n / 1000)
48
+
49
+ let result = ''
50
+
51
+ // Thousands
52
+ if (thousands > 0) {
53
+ if (thousands === 1) {
54
+ result += THOUSAND
55
+ } else {
56
+ result += ONES[thousands] + THOUSAND
57
+ }
58
+ }
59
+
60
+ // Hundreds
61
+ if (hundreds > 0) {
62
+ if (hundreds === 1) {
63
+ result += HUNDRED
64
+ } else {
65
+ result += ONES[hundreds] + HUNDRED
66
+ }
67
+ }
68
+
69
+ // Tens
70
+ if (tens > 0) {
71
+ if (tens === 1) {
72
+ result += TEN
73
+ } else {
74
+ result += ONES[tens] + TEN
75
+ }
76
+ }
77
+
78
+ // Ones
79
+ if (ones > 0) {
80
+ result += ONES[ones]
81
+ }
82
+
83
+ return result
84
+ }
85
+
86
+ // Precompute all 10000 segment words (0-9999) for myriad grouping
87
+ const SEGMENTS = new Array(10000)
88
+
89
+ for (let i = 0; i < 10000; i++) {
90
+ SEGMENTS[i] = buildSegment(i)
91
+ }
92
+
93
+ // ============================================================================
94
+ // Conversion Functions
95
+ // ============================================================================
96
+
97
+ /**
98
+ * Converts a non-negative integer to Korean words.
99
+ *
100
+ * @param {bigint} n - Non-negative integer to convert
101
+ * @returns {string} Korean words
102
+ */
103
+ function integerToWords (n) {
104
+ if (n === 0n) return ZERO
105
+
106
+ // Fast path: numbers < 10000 (direct lookup)
107
+ if (n < 10000n) {
108
+ return SEGMENTS[Number(n)]
109
+ }
110
+
111
+ // For numbers >= 10000, use myriad decomposition
112
+ return buildLargeNumberWords(n)
113
+ }
114
+
115
+ /**
116
+ * Builds words for numbers >= 10000.
117
+ * Uses myriad (만) grouping - 4 digits per segment.
118
+ *
119
+ * @param {bigint} n - Number >= 10000
120
+ * @returns {string} Korean words
121
+ */
122
+ function buildLargeNumberWords (n) {
123
+ const numStr = n.toString()
124
+ const len = numStr.length
125
+
126
+ // Build segments of 4 digits from right to left
127
+ const segments = []
128
+ const segmentSize = 4
129
+
130
+ const remainderLen = len % segmentSize
131
+ let pos = 0
132
+ if (remainderLen > 0) {
133
+ segments.push(Number(numStr.slice(0, remainderLen)))
134
+ pos = remainderLen
135
+ }
136
+ while (pos < len) {
137
+ segments.push(Number(numStr.slice(pos, pos + segmentSize)))
138
+ pos += segmentSize
139
+ }
140
+
141
+ // Convert segments to words
142
+ const parts = []
143
+ let scaleIndex = segments.length - 1
144
+
145
+ for (let i = 0; i < segments.length; i++) {
146
+ const segment = segments[i]
147
+
148
+ if (segment !== 0) {
149
+ if (scaleIndex === 0) {
150
+ // Units segment (no scale word)
151
+ parts.push({ word: SEGMENTS[segment], isScale: false })
152
+ } else {
153
+ // Segment with scale word
154
+ const scaleWord = SCALES[scaleIndex - 1]
155
+
156
+ // Korean omits segment when it's 1 before scale words
157
+ if (segment === 1) {
158
+ parts.push({ word: scaleWord, isScale: true })
159
+ } else {
160
+ parts.push({ word: SEGMENTS[segment], isScale: false })
161
+ parts.push({ word: scaleWord, isScale: true })
162
+ }
163
+ }
164
+ }
165
+
166
+ scaleIndex--
167
+ }
168
+
169
+ // Join with Korean spacing rules
170
+ return joinKoreanParts(parts)
171
+ }
2
172
 
3
173
  /**
4
- * Korean language converter.
174
+ * Joins parts with Korean spacing rules.
175
+ * - Concatenate without spaces within segments
176
+ * - Space after scale words before next number
5
177
  *
6
- * Features:
7
- * - Space-separated for large numbers (>= 만/10,000)
8
- * - Concatenated for smaller numbers
9
- * - Omits '일' (1) before multipliers
178
+ * @param {Array} parts - Parts with isScale metadata
179
+ * @returns {string} Joined string
10
180
  */
11
- export class Korean extends GreedyScaleLanguage {
12
- negativeWord = '마이너스'
13
- decimalSeparatorWord = '점'
14
- zeroWord = '영'
15
- scaleWordPairs = [
16
- [10_000_000_000_000_000_000_000_000_000n, '양'],
17
- [1_000_000_000_000_000_000_000_000n, '자'],
18
- [100_000_000_000_000_000_000n, '해'],
19
- [10_000_000_000_000_000n, '경'],
20
- [1_000_000_000_000n, '조'],
21
- [100_000_000n, '억'],
22
- [10_000n, '만'],
23
- [1000n, '천'],
24
- [100n, '백'],
25
- [10n, '십'],
26
- [9n, '구'],
27
- [8n, '팔'],
28
- [7n, '칠'],
29
- [6n, '육'],
30
- [5n, '오'],
31
- [4n, '사'],
32
- [3n, '삼'],
33
- [2n, '이'],
34
- [1n, '일'],
35
- [0n, '영']
36
- ]
37
-
38
- /**
39
- * Merges two adjacent word-number pairs according to Korean grammar rules.
40
- *
41
- * Korean-specific rules:
42
- * - Omits '일' (1) before multipliers <= 만 (10,000)
43
- * - Concatenates without space for small numbers (< 만)
44
- * - Separates with space for large numbers (>= 만)
45
- * - Multiplies when right > left, adds when left > right
46
- *
47
- * @param {Object} leftPair The left operand as `{ word: number }`.
48
- * @param {Object} rightPair The right operand as `{ word: number }`.
49
- * @returns {Object} Merged pair with combined word and resulting number.
50
- */
51
- mergeScales (leftPair, rightPair) {
52
- const leftWord = Object.keys(leftPair)[0]
53
- const rightWord = Object.keys(rightPair)[0]
54
- const leftNumber = Object.values(leftPair)[0] // BigInt
55
- const rightNumber = Object.values(rightPair)[0] // BigInt
56
-
57
- // Implicit "일": omit 1 before multipliers up to 만 (10,000)
58
- if (leftNumber === 1n && rightNumber <= 10_000n) return rightPair
59
- // Concatenate (no space) for small numbers less than 만
60
- if (leftNumber < 10_000n && leftNumber > rightNumber) return { [`${leftWord}${rightWord}`]: leftNumber + rightNumber }
61
- // Space-separate for large numbers (>= 만) when adding
62
- if (leftNumber >= 10_000n && leftNumber > rightNumber) return { [`${leftWord} ${rightWord}`]: leftNumber + rightNumber }
63
- // Multiply for all scale combinations
64
- return { [`${leftWord}${rightWord}`]: leftNumber * rightNumber }
181
+ function joinKoreanParts (parts) {
182
+ if (parts.length === 0) return ZERO
183
+ if (parts.length === 1) return parts[0].word
184
+
185
+ const result = []
186
+
187
+ for (let i = 0; i < parts.length; i++) {
188
+ const part = parts[i]
189
+ const prevPart = i > 0 ? parts[i - 1] : null
190
+
191
+ // Add space after scale words before next number
192
+ if (prevPart && prevPart.isScale && !part.isScale) {
193
+ result.push(' ')
194
+ }
195
+
196
+ result.push(part.word)
65
197
  }
198
+
199
+ return result.join('')
66
200
  }
67
201
 
68
202
  /**
69
- * Converts a number to Korean cardinal (written) form.
203
+ * Converts decimal digits to Korean words.
70
204
  *
71
- * @param {number|string|bigint} value The number to convert.
72
- * @param {Object} [options] Conversion options (see Korean class options).
73
- * @returns {string} The number expressed in Korean words.
74
- * @throws {TypeError} If value is NaN or invalid type.
75
- * @throws {Error} If value is an invalid number string.
205
+ * @param {string} decimalPart - Decimal digits (without the point)
206
+ * @returns {string} Korean words for decimal part (space-separated)
207
+ */
208
+ function decimalPartToWords (decimalPart) {
209
+ const parts = []
210
+
211
+ // Handle leading zeros
212
+ let i = 0
213
+ while (i < decimalPart.length && decimalPart[i] === '0') {
214
+ parts.push(ZERO)
215
+ i++
216
+ }
217
+
218
+ // Convert remainder as a single number
219
+ const remainder = decimalPart.slice(i)
220
+ if (remainder) {
221
+ parts.push(integerToWords(BigInt(remainder)))
222
+ }
223
+
224
+ return parts.join(' ')
225
+ }
226
+
227
+ /**
228
+ * Converts a numeric value to Korean words.
229
+ *
230
+ * @param {number | string | bigint} value - The numeric value to convert
231
+ * @returns {string} The number in Korean words
232
+ * @throws {TypeError} If value is not a valid numeric type
233
+ * @throws {Error} If value is not a valid number format
76
234
  *
77
235
  * @example
78
- * convertToWords(42); // '사십이'
79
- * convertToWords(10001); // '만'
236
+ * toWords(21) // '이십일'
237
+ * toWords(10000) // '만'
238
+ * toWords(1000000) // '백만'
80
239
  */
81
- export default function convertToWords (value, options = {}) {
82
- return new Korean(options).convertToWords(value)
240
+ function toWords (value) {
241
+ const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
242
+
243
+ const parts = []
244
+
245
+ if (isNegative) {
246
+ parts.push(NEGATIVE)
247
+ }
248
+
249
+ parts.push(integerToWords(integerPart))
250
+
251
+ if (decimalPart) {
252
+ parts.push(DECIMAL_SEP)
253
+ parts.push(decimalPartToWords(decimalPart))
254
+ }
255
+
256
+ return parts.join(' ')
83
257
  }
258
+
259
+ // ============================================================================
260
+ // Public API
261
+ // ============================================================================
262
+
263
+ export { toWords }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Converts a numeric value to Lithuanian words.
3
+ *
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @param {Object} [options] - Conversion options
6
+ * @param {string} [options.gender='masculine'] - Gender for numbers < 1000
7
+ * @returns {string} The number in Lithuanian words
8
+ * @throws {TypeError} If value is not a valid numeric type
9
+ * @throws {Error} If value is not a valid number format
10
+ *
11
+ * @example
12
+ * toWords(42) // 'keturiasdešimt du'
13
+ * toWords(1, { gender: 'feminine' }) // 'viena'
14
+ * toWords(1000000) // 'vienas milijonas'
15
+ */
16
+ export function toWords(value: number | string | bigint, options?: {
17
+ gender?: string | undefined;
18
+ }): string;