@gks101/numtowords 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +34 -0
- package/README.md +65 -68
- package/dist/core/converter.js +8 -8
- package/dist/index.cjs.js +321 -148
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +321 -148
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +321 -148
- package/dist/index.umd.js.map +1 -1
- package/dist/locales/de.js +52 -30
- package/dist/locales/en.js +49 -25
- package/dist/locales/fr.js +55 -31
- package/dist/locales/hi.js +116 -37
- package/dist/locales/in.js +46 -22
- package/dist/types/core/converter.d.ts +1 -1
- package/dist/types/core/types.d.ts +1 -1
- package/dist/types/index.d.ts +7 -7
- package/dist/types/locales/de.d.ts +1 -1
- package/dist/types/locales/en.d.ts +1 -1
- package/dist/types/locales/fr.d.ts +1 -1
- package/dist/types/locales/hi.d.ts +1 -1
- package/dist/types/locales/in.d.ts +1 -1
- package/package.json +23 -6
package/dist/index.cjs.js
CHANGED
|
@@ -21,7 +21,7 @@ function getLocale(id) {
|
|
|
21
21
|
const def = registry.get(id);
|
|
22
22
|
if (!def) {
|
|
23
23
|
throw new Error(`[numtowords] Locale "${id}" is not registered. ` +
|
|
24
|
-
`Available: ${[...registry.keys()].join(
|
|
24
|
+
`Available: ${[...registry.keys()].join(', ')}`);
|
|
25
25
|
}
|
|
26
26
|
return def;
|
|
27
27
|
}
|
|
@@ -31,10 +31,10 @@ function availableLocales() {
|
|
|
31
31
|
}
|
|
32
32
|
// ─── Defaults ────────────────────────────────────────────────────────────────
|
|
33
33
|
const DEFAULT_OPTIONS = {
|
|
34
|
-
locale:
|
|
34
|
+
locale: 'en',
|
|
35
35
|
capitalize: true,
|
|
36
36
|
useAnd: true,
|
|
37
|
-
currency:
|
|
37
|
+
currency: '',
|
|
38
38
|
};
|
|
39
39
|
// ─── Main convert function ────────────────────────────────────────────────────
|
|
40
40
|
/**
|
|
@@ -50,27 +50,27 @@ function convert(input, options) {
|
|
|
50
50
|
// ── Normalise input ────────────────────────────────────────────────────────
|
|
51
51
|
let raw = String(input).trim();
|
|
52
52
|
let negative = false;
|
|
53
|
-
if (raw.startsWith(
|
|
53
|
+
if (raw.startsWith('-')) {
|
|
54
54
|
negative = true;
|
|
55
55
|
raw = raw.slice(1);
|
|
56
56
|
}
|
|
57
57
|
// Strip commas / underscores used as separators
|
|
58
|
-
raw = raw.replace(/[,_\s]/g,
|
|
58
|
+
raw = raw.replace(/[,_\s]/g, '');
|
|
59
59
|
if (!/^\d+$/.test(raw)) {
|
|
60
60
|
throw new Error(`[numtowords] Invalid numeric input: "${input}"`);
|
|
61
61
|
}
|
|
62
62
|
// Remove leading zeros
|
|
63
|
-
raw = raw.replace(/^0+/,
|
|
63
|
+
raw = raw.replace(/^0+/, '') || '0';
|
|
64
64
|
const n = BigInt(raw);
|
|
65
65
|
// ── Delegate to locale ─────────────────────────────────────────────────────
|
|
66
66
|
const locale = getLocale(opts.locale);
|
|
67
67
|
let result = locale.convert(n, opts);
|
|
68
68
|
if (negative)
|
|
69
|
-
result =
|
|
69
|
+
result = 'Negative ' + result;
|
|
70
70
|
// ── Capitalise ─────────────────────────────────────────────────────────────
|
|
71
71
|
if (opts.capitalize) {
|
|
72
72
|
// Do not capitalise German zero (tests expect lowercase 'null')
|
|
73
|
-
if (!(n === 0n && opts.locale ===
|
|
73
|
+
if (!(n === 0n && opts.locale === 'de')) {
|
|
74
74
|
result = result.charAt(0).toUpperCase() + result.slice(1);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
@@ -83,37 +83,61 @@ function convert(input, options) {
|
|
|
83
83
|
|
|
84
84
|
// ─── Word tables ──────────────────────────────────────────────────────────────
|
|
85
85
|
const ONES$1 = [
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
'',
|
|
87
|
+
'one',
|
|
88
|
+
'two',
|
|
89
|
+
'three',
|
|
90
|
+
'four',
|
|
91
|
+
'five',
|
|
92
|
+
'six',
|
|
93
|
+
'seven',
|
|
94
|
+
'eight',
|
|
95
|
+
'nine',
|
|
96
|
+
'ten',
|
|
97
|
+
'eleven',
|
|
98
|
+
'twelve',
|
|
99
|
+
'thirteen',
|
|
100
|
+
'fourteen',
|
|
101
|
+
'fifteen',
|
|
102
|
+
'sixteen',
|
|
103
|
+
'seventeen',
|
|
104
|
+
'eighteen',
|
|
105
|
+
'nineteen',
|
|
90
106
|
];
|
|
91
107
|
const TENS$1 = [
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
'',
|
|
109
|
+
'',
|
|
110
|
+
'twenty',
|
|
111
|
+
'thirty',
|
|
112
|
+
'forty',
|
|
113
|
+
'fifty',
|
|
114
|
+
'sixty',
|
|
115
|
+
'seventy',
|
|
116
|
+
'eighty',
|
|
117
|
+
'ninety',
|
|
94
118
|
];
|
|
95
119
|
/**
|
|
96
120
|
* Scale names in the short (American/modern British) scale.
|
|
97
121
|
* Index 0 = thousands, 1 = millions, …
|
|
98
122
|
*/
|
|
99
123
|
const SCALES = [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
124
|
+
'thousand',
|
|
125
|
+
'million',
|
|
126
|
+
'billion',
|
|
127
|
+
'trillion',
|
|
128
|
+
'quadrillion',
|
|
129
|
+
'quintillion',
|
|
130
|
+
'sextillion',
|
|
131
|
+
'septillion',
|
|
132
|
+
'octillion',
|
|
133
|
+
'nonillion',
|
|
134
|
+
'decillion',
|
|
111
135
|
];
|
|
112
136
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
113
137
|
/** Convert 0–999 to words */
|
|
114
138
|
function hundredsToWords$1(n, useAnd) {
|
|
115
139
|
if (n === 0)
|
|
116
|
-
return
|
|
140
|
+
return '';
|
|
117
141
|
const parts = [];
|
|
118
142
|
const h = Math.floor(n / 100);
|
|
119
143
|
const remainder = n % 100;
|
|
@@ -123,7 +147,7 @@ function hundredsToWords$1(n, useAnd) {
|
|
|
123
147
|
if (remainder === 0) ;
|
|
124
148
|
else {
|
|
125
149
|
if (h > 0 && useAnd)
|
|
126
|
-
parts.push(
|
|
150
|
+
parts.push('and');
|
|
127
151
|
if (remainder < 20) {
|
|
128
152
|
parts.push(ONES$1[remainder]);
|
|
129
153
|
}
|
|
@@ -133,14 +157,14 @@ function hundredsToWords$1(n, useAnd) {
|
|
|
133
157
|
parts.push(o === 0 ? TENS$1[t] : `${TENS$1[t]}-${ONES$1[o]}`);
|
|
134
158
|
}
|
|
135
159
|
}
|
|
136
|
-
return parts.join(
|
|
160
|
+
return parts.join(' ');
|
|
137
161
|
}
|
|
138
162
|
// ─── Locale definition ────────────────────────────────────────────────────────
|
|
139
163
|
const en = {
|
|
140
|
-
name:
|
|
164
|
+
name: 'English',
|
|
141
165
|
convert(n, opts) {
|
|
142
166
|
if (n === 0n)
|
|
143
|
-
return
|
|
167
|
+
return 'zero';
|
|
144
168
|
const useAnd = opts.useAnd;
|
|
145
169
|
const chunks = [];
|
|
146
170
|
// Split number into groups of 3 from the right
|
|
@@ -167,21 +191,45 @@ const en = {
|
|
|
167
191
|
parts.push(`${words} ${scaleName}`);
|
|
168
192
|
}
|
|
169
193
|
}
|
|
170
|
-
return parts.join(
|
|
194
|
+
return parts.join(' ');
|
|
171
195
|
},
|
|
172
196
|
};
|
|
173
|
-
registerLocale(
|
|
197
|
+
registerLocale('en', en);
|
|
174
198
|
|
|
175
199
|
// ─── Word tables ──────────────────────────────────────────────────────────────
|
|
176
200
|
const ONES = [
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
201
|
+
'',
|
|
202
|
+
'one',
|
|
203
|
+
'two',
|
|
204
|
+
'three',
|
|
205
|
+
'four',
|
|
206
|
+
'five',
|
|
207
|
+
'six',
|
|
208
|
+
'seven',
|
|
209
|
+
'eight',
|
|
210
|
+
'nine',
|
|
211
|
+
'ten',
|
|
212
|
+
'eleven',
|
|
213
|
+
'twelve',
|
|
214
|
+
'thirteen',
|
|
215
|
+
'fourteen',
|
|
216
|
+
'fifteen',
|
|
217
|
+
'sixteen',
|
|
218
|
+
'seventeen',
|
|
219
|
+
'eighteen',
|
|
220
|
+
'nineteen',
|
|
181
221
|
];
|
|
182
222
|
const TENS = [
|
|
183
|
-
|
|
184
|
-
|
|
223
|
+
'',
|
|
224
|
+
'',
|
|
225
|
+
'twenty',
|
|
226
|
+
'thirty',
|
|
227
|
+
'forty',
|
|
228
|
+
'fifty',
|
|
229
|
+
'sixty',
|
|
230
|
+
'seventy',
|
|
231
|
+
'eighty',
|
|
232
|
+
'ninety',
|
|
185
233
|
];
|
|
186
234
|
/**
|
|
187
235
|
* Indian scale names (each 100× the previous after thousand):
|
|
@@ -192,19 +240,19 @@ const TENS = [
|
|
|
192
240
|
* …
|
|
193
241
|
*/
|
|
194
242
|
const INDIAN_SCALES = [
|
|
195
|
-
[100000000000000000n,
|
|
196
|
-
[1000000000000000n,
|
|
197
|
-
[10000000000000n,
|
|
198
|
-
[100000000000n,
|
|
199
|
-
[1000000000n,
|
|
200
|
-
[10000000n,
|
|
201
|
-
[100000n,
|
|
202
|
-
[1000n,
|
|
243
|
+
[100000000000000000n, 'shankh'], // 10^17
|
|
244
|
+
[1000000000000000n, 'padma'], // 10^15
|
|
245
|
+
[10000000000000n, 'neel'], // 10^13
|
|
246
|
+
[100000000000n, 'kharab'], // 10^11
|
|
247
|
+
[1000000000n, 'arab'], // 10^9
|
|
248
|
+
[10000000n, 'crore'], // 10^7
|
|
249
|
+
[100000n, 'lakh'], // 10^5
|
|
250
|
+
[1000n, 'thousand'],
|
|
203
251
|
];
|
|
204
252
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
205
253
|
function twoDigits(n) {
|
|
206
254
|
if (n === 0)
|
|
207
|
-
return
|
|
255
|
+
return '';
|
|
208
256
|
if (n < 20)
|
|
209
257
|
return ONES[n];
|
|
210
258
|
const t = Math.floor(n / 10);
|
|
@@ -213,7 +261,7 @@ function twoDigits(n) {
|
|
|
213
261
|
}
|
|
214
262
|
function hundredsToWords(n) {
|
|
215
263
|
if (n === 0)
|
|
216
|
-
return
|
|
264
|
+
return '';
|
|
217
265
|
const h = Math.floor(n / 100);
|
|
218
266
|
const rem = n % 100;
|
|
219
267
|
const parts = [];
|
|
@@ -222,14 +270,14 @@ function hundredsToWords(n) {
|
|
|
222
270
|
const two = twoDigits(rem);
|
|
223
271
|
if (two)
|
|
224
272
|
parts.push(two);
|
|
225
|
-
return parts.join(
|
|
273
|
+
return parts.join(' ');
|
|
226
274
|
}
|
|
227
275
|
// ─── Locale definition ────────────────────────────────────────────────────────
|
|
228
276
|
const indian = {
|
|
229
|
-
name:
|
|
277
|
+
name: 'Indian',
|
|
230
278
|
convert(n, _opts) {
|
|
231
279
|
if (n === 0n)
|
|
232
|
-
return
|
|
280
|
+
return 'zero';
|
|
233
281
|
const parts = [];
|
|
234
282
|
let remaining = n;
|
|
235
283
|
for (const [scale, name] of INDIAN_SCALES) {
|
|
@@ -246,53 +294,132 @@ const indian = {
|
|
|
246
294
|
if (remaining > 0n) {
|
|
247
295
|
parts.push(hundredsToWords(Number(remaining)));
|
|
248
296
|
}
|
|
249
|
-
return parts.join(
|
|
297
|
+
return parts.join(' ');
|
|
250
298
|
},
|
|
251
299
|
};
|
|
252
|
-
registerLocale(
|
|
300
|
+
registerLocale('in', indian);
|
|
253
301
|
|
|
254
302
|
// ─── Word tables ──────────────────────────────────────────────────────────────
|
|
255
303
|
/** 1–99 in Hindi */
|
|
256
304
|
const HINDI_ONES = {
|
|
257
|
-
1:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
305
|
+
1: 'एक',
|
|
306
|
+
2: 'दो',
|
|
307
|
+
3: 'तीन',
|
|
308
|
+
4: 'चार',
|
|
309
|
+
5: 'पाँच',
|
|
310
|
+
6: 'छह',
|
|
311
|
+
7: 'सात',
|
|
312
|
+
8: 'आठ',
|
|
313
|
+
9: 'नौ',
|
|
314
|
+
10: 'दस',
|
|
315
|
+
11: 'ग्यारह',
|
|
316
|
+
12: 'बारह',
|
|
317
|
+
13: 'तेरह',
|
|
318
|
+
14: 'चौदह',
|
|
319
|
+
15: 'पन्द्रह',
|
|
320
|
+
16: 'सोलह',
|
|
321
|
+
17: 'सत्रह',
|
|
322
|
+
18: 'अट्ठारह',
|
|
323
|
+
19: 'उन्नीस',
|
|
324
|
+
20: 'बीस',
|
|
325
|
+
21: 'इक्कीस',
|
|
326
|
+
22: 'बाईस',
|
|
327
|
+
23: 'तेईस',
|
|
328
|
+
24: 'चौबीस',
|
|
329
|
+
25: 'पच्चीस',
|
|
330
|
+
26: 'छब्बीस',
|
|
331
|
+
27: 'सत्ताईस',
|
|
332
|
+
28: 'अट्ठाईस',
|
|
333
|
+
29: 'उनतीस',
|
|
334
|
+
30: 'तीस',
|
|
335
|
+
31: 'इकतीस',
|
|
336
|
+
32: 'बत्तीस',
|
|
337
|
+
33: 'तैंतीस',
|
|
338
|
+
34: 'चौंतीस',
|
|
339
|
+
35: 'पैंतीस',
|
|
340
|
+
36: 'छत्तीस',
|
|
341
|
+
37: 'सैंतीस',
|
|
342
|
+
38: 'अड़तीस',
|
|
343
|
+
39: 'उनतालीस',
|
|
344
|
+
40: 'चालीस',
|
|
345
|
+
41: 'इकतालीस',
|
|
346
|
+
42: 'बयालीस',
|
|
347
|
+
43: 'तैंतालीस',
|
|
348
|
+
44: 'चौवालीस',
|
|
349
|
+
45: 'पैंतालीस',
|
|
350
|
+
46: 'छियालीस',
|
|
351
|
+
47: 'सैंतालीस',
|
|
352
|
+
48: 'अड़तालीस',
|
|
353
|
+
49: 'उनचास',
|
|
354
|
+
50: 'पचास',
|
|
355
|
+
51: 'इक्यावन',
|
|
356
|
+
52: 'बावन',
|
|
357
|
+
53: 'तिरपन',
|
|
358
|
+
54: 'चौवन',
|
|
359
|
+
55: 'पचपन',
|
|
360
|
+
56: 'छप्पन',
|
|
361
|
+
57: 'सत्तावन',
|
|
362
|
+
58: 'अट्ठावन',
|
|
363
|
+
59: 'उनसठ',
|
|
364
|
+
60: 'साठ',
|
|
365
|
+
61: 'इकसठ',
|
|
366
|
+
62: 'बासठ',
|
|
367
|
+
63: 'तिरसठ',
|
|
368
|
+
64: 'चौंसठ',
|
|
369
|
+
65: 'पैंसठ',
|
|
370
|
+
66: 'छियासठ',
|
|
371
|
+
67: 'सड़सठ',
|
|
372
|
+
68: 'अड़सठ',
|
|
373
|
+
69: 'उनहत्तर',
|
|
374
|
+
70: 'सत्तर',
|
|
375
|
+
71: 'इकहत्तर',
|
|
376
|
+
72: 'बहत्तर',
|
|
377
|
+
73: 'तिहत्तर',
|
|
378
|
+
74: 'चौहत्तर',
|
|
379
|
+
75: 'पचहत्तर',
|
|
380
|
+
76: 'छिहत्तर',
|
|
381
|
+
77: 'सत्तहत्तर',
|
|
382
|
+
78: 'अठहत्तर',
|
|
383
|
+
79: 'उन्यासी',
|
|
384
|
+
80: 'अस्सी',
|
|
385
|
+
81: 'इक्यासी',
|
|
386
|
+
82: 'बयासी',
|
|
387
|
+
83: 'तिरासी',
|
|
388
|
+
84: 'चौरासी',
|
|
389
|
+
85: 'पचासी',
|
|
390
|
+
86: 'छियासी',
|
|
391
|
+
87: 'सत्तासी',
|
|
392
|
+
88: 'अट्ठासी',
|
|
393
|
+
89: 'नवासी',
|
|
394
|
+
90: 'नब्बे',
|
|
395
|
+
91: 'इक्यानबे',
|
|
396
|
+
92: 'बानवे',
|
|
397
|
+
93: 'तिरानवे',
|
|
398
|
+
94: 'चौरानवे',
|
|
399
|
+
95: 'पचानवे',
|
|
400
|
+
96: 'छियानवे',
|
|
401
|
+
97: 'सत्तानवे',
|
|
402
|
+
98: 'अट्ठानवे',
|
|
403
|
+
99: 'निन्यानवे',
|
|
277
404
|
};
|
|
278
|
-
const HINDI_HUNDRED =
|
|
405
|
+
const HINDI_HUNDRED = 'सौ';
|
|
279
406
|
const INDIAN_SCALES_HI = [
|
|
280
|
-
[100000000000000000n,
|
|
281
|
-
[1000000000000000n,
|
|
282
|
-
[10000000000000n,
|
|
283
|
-
[100000000000n,
|
|
284
|
-
[1000000000n,
|
|
285
|
-
[10000000n,
|
|
286
|
-
[100000n,
|
|
287
|
-
[1000n,
|
|
407
|
+
[100000000000000000n, 'शंख'], // 10^17
|
|
408
|
+
[1000000000000000n, 'पद्म'], // 10^15
|
|
409
|
+
[10000000000000n, 'नील'], // 10^13
|
|
410
|
+
[100000000000n, 'खरब'], // 10^11
|
|
411
|
+
[1000000000n, 'अरब'], // 10^9
|
|
412
|
+
[10000000n, 'करोड़'], // 10^7
|
|
413
|
+
[100000n, 'लाख'], // 10^5
|
|
414
|
+
[1000n, 'हज़ार'], // 10^3
|
|
288
415
|
];
|
|
289
416
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
290
417
|
function upToNinetyNine$2(n) {
|
|
291
|
-
return HINDI_ONES[n] ??
|
|
418
|
+
return HINDI_ONES[n] ?? '';
|
|
292
419
|
}
|
|
293
420
|
function hundredsHindi(n) {
|
|
294
421
|
if (n === 0)
|
|
295
|
-
return
|
|
422
|
+
return '';
|
|
296
423
|
const h = Math.floor(n / 100);
|
|
297
424
|
const rem = n % 100;
|
|
298
425
|
const parts = [];
|
|
@@ -302,14 +429,14 @@ function hundredsHindi(n) {
|
|
|
302
429
|
}
|
|
303
430
|
if (rem > 0)
|
|
304
431
|
parts.push(upToNinetyNine$2(rem));
|
|
305
|
-
return parts.join(
|
|
432
|
+
return parts.join(' ');
|
|
306
433
|
}
|
|
307
434
|
// ─── Locale definition ────────────────────────────────────────────────────────
|
|
308
435
|
const hi = {
|
|
309
|
-
name:
|
|
436
|
+
name: 'Hindi',
|
|
310
437
|
convert(n, _opts) {
|
|
311
438
|
if (n === 0n)
|
|
312
|
-
return
|
|
439
|
+
return 'शून्य';
|
|
313
440
|
const parts = [];
|
|
314
441
|
let remaining = n;
|
|
315
442
|
for (const [scale, name] of INDIAN_SCALES_HI) {
|
|
@@ -323,26 +450,50 @@ const hi = {
|
|
|
323
450
|
if (remaining > 0n) {
|
|
324
451
|
parts.push(hundredsHindi(Number(remaining)));
|
|
325
452
|
}
|
|
326
|
-
return parts.join(
|
|
453
|
+
return parts.join(' ');
|
|
327
454
|
},
|
|
328
455
|
};
|
|
329
|
-
registerLocale(
|
|
456
|
+
registerLocale('hi', hi);
|
|
330
457
|
|
|
331
458
|
// ─── Word tables ──────────────────────────────────────────────────────────────
|
|
332
459
|
const ONES_DE = [
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
460
|
+
'',
|
|
461
|
+
'ein',
|
|
462
|
+
'zwei',
|
|
463
|
+
'drei',
|
|
464
|
+
'vier',
|
|
465
|
+
'fünf',
|
|
466
|
+
'sechs',
|
|
467
|
+
'sieben',
|
|
468
|
+
'acht',
|
|
469
|
+
'neun',
|
|
470
|
+
'zehn',
|
|
471
|
+
'elf',
|
|
472
|
+
'zwölf',
|
|
473
|
+
'dreizehn',
|
|
474
|
+
'vierzehn',
|
|
475
|
+
'fünfzehn',
|
|
476
|
+
'sechzehn',
|
|
477
|
+
'siebzehn',
|
|
478
|
+
'achtzehn',
|
|
479
|
+
'neunzehn',
|
|
337
480
|
];
|
|
338
481
|
const TENS_DE = [
|
|
339
|
-
|
|
340
|
-
|
|
482
|
+
'',
|
|
483
|
+
'',
|
|
484
|
+
'zwanzig',
|
|
485
|
+
'dreißig',
|
|
486
|
+
'vierzig',
|
|
487
|
+
'fünfzig',
|
|
488
|
+
'sechzig',
|
|
489
|
+
'siebzig',
|
|
490
|
+
'achtzig',
|
|
491
|
+
'neunzig',
|
|
341
492
|
];
|
|
342
493
|
/** German uses "und" between ones and tens: einundzwanzig */
|
|
343
494
|
function upToNinetyNine$1(n) {
|
|
344
495
|
if (n === 0)
|
|
345
|
-
return
|
|
496
|
+
return '';
|
|
346
497
|
if (n < 20)
|
|
347
498
|
return ONES_DE[n];
|
|
348
499
|
const t = Math.floor(n / 10);
|
|
@@ -353,42 +504,42 @@ function upToNinetyNine$1(n) {
|
|
|
353
504
|
}
|
|
354
505
|
function hundredsDE(n) {
|
|
355
506
|
if (n === 0)
|
|
356
|
-
return
|
|
507
|
+
return '';
|
|
357
508
|
const h = Math.floor(n / 100);
|
|
358
509
|
const rem = n % 100;
|
|
359
510
|
const parts = [];
|
|
360
511
|
if (h === 1)
|
|
361
|
-
parts.push(
|
|
512
|
+
parts.push('einhundert');
|
|
362
513
|
else if (h > 1)
|
|
363
514
|
parts.push(`${ONES_DE[h]}hundert`);
|
|
364
515
|
if (rem > 0)
|
|
365
516
|
parts.push(upToNinetyNine$1(rem));
|
|
366
|
-
return parts.join(
|
|
517
|
+
return parts.join('');
|
|
367
518
|
}
|
|
368
519
|
const SCALES_DE = [
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
520
|
+
'tausend',
|
|
521
|
+
'Million',
|
|
522
|
+
'Milliarde',
|
|
523
|
+
'Billion',
|
|
524
|
+
'Billiarde',
|
|
525
|
+
'Trillion',
|
|
375
526
|
];
|
|
376
527
|
/** Scales that are grammatically feminine in German (require "eine" not "ein") */
|
|
377
528
|
const FEMININE_SCALES = new Set([1, 2, 4, 6]); // indices: Million, Milliarde, Billiarde, Trillion
|
|
378
529
|
const SCALES_DE_PLURAL = [
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
530
|
+
'tausend',
|
|
531
|
+
'Millionen',
|
|
532
|
+
'Milliarden',
|
|
533
|
+
'Billionen',
|
|
534
|
+
'Billiarden',
|
|
535
|
+
'Trillionen',
|
|
385
536
|
];
|
|
386
537
|
// ─── Locale definition ────────────────────────────────────────────────────────
|
|
387
538
|
const de = {
|
|
388
|
-
name:
|
|
539
|
+
name: 'German',
|
|
389
540
|
convert(n, _opts) {
|
|
390
541
|
if (n === 0n)
|
|
391
|
-
return
|
|
542
|
+
return 'null';
|
|
392
543
|
const chunks = [];
|
|
393
544
|
let remaining = n;
|
|
394
545
|
let idx = 0;
|
|
@@ -413,52 +564,74 @@ const de = {
|
|
|
413
564
|
const scaleIdx = scale - 1;
|
|
414
565
|
const isFeminine = FEMININE_SCALES.has(scaleIdx);
|
|
415
566
|
// Replace trailing "ein" with "eine" for feminine scales
|
|
416
|
-
const adjustedWords = value === 1 && isFeminine
|
|
417
|
-
? words.replace(/ein$/, "eine")
|
|
418
|
-
: words;
|
|
567
|
+
const adjustedWords = value === 1 && isFeminine ? words.replace(/ein$/, 'eine') : words;
|
|
419
568
|
const scaleName = value === 1 ? SCALES_DE[scaleIdx] : SCALES_DE_PLURAL[scaleIdx];
|
|
420
569
|
parts.push(`${adjustedWords} ${scaleName}`);
|
|
421
570
|
}
|
|
422
571
|
}
|
|
423
|
-
return parts.join(
|
|
572
|
+
return parts.join(' ').trim();
|
|
424
573
|
},
|
|
425
574
|
};
|
|
426
|
-
registerLocale(
|
|
575
|
+
registerLocale('de', de);
|
|
427
576
|
|
|
428
577
|
// ─── Word tables ──────────────────────────────────────────────────────────────
|
|
429
578
|
const ONES_FR = [
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
579
|
+
'',
|
|
580
|
+
'un',
|
|
581
|
+
'deux',
|
|
582
|
+
'trois',
|
|
583
|
+
'quatre',
|
|
584
|
+
'cinq',
|
|
585
|
+
'six',
|
|
586
|
+
'sept',
|
|
587
|
+
'huit',
|
|
588
|
+
'neuf',
|
|
589
|
+
'dix',
|
|
590
|
+
'onze',
|
|
591
|
+
'douze',
|
|
592
|
+
'treize',
|
|
593
|
+
'quatorze',
|
|
594
|
+
'quinze',
|
|
595
|
+
'seize',
|
|
596
|
+
'dix-sept',
|
|
597
|
+
'dix-huit',
|
|
598
|
+
'dix-neuf',
|
|
434
599
|
];
|
|
435
600
|
const TENS_FR = [
|
|
436
|
-
|
|
437
|
-
|
|
601
|
+
'',
|
|
602
|
+
'',
|
|
603
|
+
'vingt',
|
|
604
|
+
'trente',
|
|
605
|
+
'quarante',
|
|
606
|
+
'cinquante',
|
|
607
|
+
'soixante',
|
|
608
|
+
'soixante',
|
|
609
|
+
'quatre-vingt',
|
|
610
|
+
'quatre-vingt',
|
|
438
611
|
];
|
|
439
612
|
/**
|
|
440
613
|
* French has irregular 70s (soixante-dix + 10–19) and 90s (quatre-vingt-dix + 10–19).
|
|
441
614
|
*/
|
|
442
615
|
function upToNinetyNine(n) {
|
|
443
616
|
if (n === 0)
|
|
444
|
-
return
|
|
617
|
+
return '';
|
|
445
618
|
if (n < 20)
|
|
446
619
|
return ONES_FR[n];
|
|
447
620
|
const t = Math.floor(n / 10);
|
|
448
621
|
const o = n % 10;
|
|
449
622
|
if (t === 7) {
|
|
450
623
|
// soixante + (10 + o)
|
|
451
|
-
return o === 0 ?
|
|
624
|
+
return o === 0 ? 'soixante-dix' : `soixante-${ONES_FR[10 + o]}`;
|
|
452
625
|
}
|
|
453
626
|
if (t === 8) {
|
|
454
627
|
// quatre-vingt(s) + o
|
|
455
628
|
if (o === 0)
|
|
456
|
-
return
|
|
629
|
+
return 'quatre-vingts';
|
|
457
630
|
return `quatre-vingt-${ONES_FR[o]}`;
|
|
458
631
|
}
|
|
459
632
|
if (t === 9) {
|
|
460
633
|
// quatre-vingt-dix + (0 + o)
|
|
461
|
-
return o === 0 ?
|
|
634
|
+
return o === 0 ? 'quatre-vingt-dix' : `quatre-vingt-${ONES_FR[10 + o]}`;
|
|
462
635
|
}
|
|
463
636
|
if (o === 0)
|
|
464
637
|
return TENS_FR[t];
|
|
@@ -468,12 +641,12 @@ function upToNinetyNine(n) {
|
|
|
468
641
|
}
|
|
469
642
|
function hundredsFR(n) {
|
|
470
643
|
if (n === 0)
|
|
471
|
-
return
|
|
644
|
+
return '';
|
|
472
645
|
const h = Math.floor(n / 100);
|
|
473
646
|
const rem = n % 100;
|
|
474
647
|
const parts = [];
|
|
475
648
|
if (h === 1) {
|
|
476
|
-
parts.push(
|
|
649
|
+
parts.push('cent');
|
|
477
650
|
}
|
|
478
651
|
else if (h > 1) {
|
|
479
652
|
parts.push(`${ONES_FR[h]} cents`);
|
|
@@ -485,30 +658,30 @@ function hundredsFR(n) {
|
|
|
485
658
|
}
|
|
486
659
|
parts.push(upToNinetyNine(rem));
|
|
487
660
|
}
|
|
488
|
-
return parts.join(
|
|
661
|
+
return parts.join(' ');
|
|
489
662
|
}
|
|
490
663
|
const SCALES_FR = [
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
664
|
+
'mille',
|
|
665
|
+
'million',
|
|
666
|
+
'milliard',
|
|
667
|
+
'billion',
|
|
668
|
+
'billiard',
|
|
669
|
+
'trillion',
|
|
497
670
|
];
|
|
498
671
|
const SCALES_FR_PLURAL = [
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
672
|
+
'mille',
|
|
673
|
+
'millions',
|
|
674
|
+
'milliards',
|
|
675
|
+
'billions',
|
|
676
|
+
'billiards',
|
|
677
|
+
'trillions',
|
|
505
678
|
];
|
|
506
679
|
// ─── Locale definition ────────────────────────────────────────────────────────
|
|
507
680
|
const fr = {
|
|
508
|
-
name:
|
|
681
|
+
name: 'French',
|
|
509
682
|
convert(n, _opts) {
|
|
510
683
|
if (n === 0n)
|
|
511
|
-
return
|
|
684
|
+
return 'zéro';
|
|
512
685
|
const chunks = [];
|
|
513
686
|
let remaining = n;
|
|
514
687
|
let idx = 0;
|
|
@@ -527,7 +700,7 @@ const fr = {
|
|
|
527
700
|
}
|
|
528
701
|
else if (scale === 1) {
|
|
529
702
|
// "mille" does not pluralise and drops "un" prefix
|
|
530
|
-
parts.push(value === 1 ?
|
|
703
|
+
parts.push(value === 1 ? 'mille' : `${words} mille`);
|
|
531
704
|
}
|
|
532
705
|
else {
|
|
533
706
|
const scaleIdx = scale - 1;
|
|
@@ -535,10 +708,10 @@ const fr = {
|
|
|
535
708
|
parts.push(`${words} ${scaleName}`);
|
|
536
709
|
}
|
|
537
710
|
}
|
|
538
|
-
return parts.join(
|
|
711
|
+
return parts.join(' ').trim();
|
|
539
712
|
},
|
|
540
713
|
};
|
|
541
|
-
registerLocale(
|
|
714
|
+
registerLocale('fr', fr);
|
|
542
715
|
|
|
543
716
|
exports.availableLocales = availableLocales;
|
|
544
717
|
exports.convert = convert;
|