n2words 1.13.0 → 1.14.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.
- package/.eslintrc.json +2 -2
- package/README.md +1 -1
- package/bench.mjs +94 -0
- package/dist/n2words.js +1 -1
- package/examples/node.mjs +10 -0
- package/lib/classes/AbstractLanguage.mjs +151 -0
- package/lib/classes/BaseLanguage.mjs +174 -0
- package/lib/i18n/AR.mjs +19 -9
- package/lib/i18n/AZ.mjs +42 -37
- package/lib/i18n/CZ.mjs +78 -69
- package/lib/i18n/DE.mjs +54 -49
- package/lib/i18n/DK.mjs +56 -50
- package/lib/i18n/EN.mjs +64 -53
- package/lib/i18n/ES.mjs +61 -55
- package/lib/i18n/FA.mjs +74 -63
- package/lib/i18n/FR.mjs +52 -47
- package/lib/i18n/HE.mjs +75 -23
- package/lib/i18n/HR.mjs +82 -70
- package/lib/i18n/HU.mjs +80 -75
- package/lib/i18n/ID.mjs +27 -20
- package/lib/i18n/IT.mjs +26 -17
- package/lib/i18n/KO.mjs +36 -31
- package/lib/i18n/LT.mjs +80 -67
- package/lib/i18n/LV.mjs +68 -57
- package/lib/i18n/NL.mjs +72 -61
- package/lib/i18n/NO.mjs +56 -51
- package/lib/i18n/PL.mjs +79 -67
- package/lib/i18n/PT.mjs +50 -44
- package/lib/i18n/RU.mjs +152 -122
- package/lib/i18n/SR.mjs +82 -70
- package/lib/i18n/TR.mjs +44 -42
- package/lib/i18n/UK.mjs +13 -6
- package/lib/i18n/VI.mjs +31 -24
- package/lib/i18n/ZH.mjs +38 -32
- package/lib/n2words.mjs +32 -106
- package/package.json +16 -10
- package/webpack.config.js +1 -1
- package/lib/classes/N2WordsAbs.mjs +0 -72
- package/lib/classes/N2WordsBase.mjs +0 -105
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* eslint-disable import/no-nodejs-modules */
|
|
2
|
+
import n2words from '../lib/i18n/EN.mjs';
|
|
3
|
+
import * as readline from 'node:readline/promises';
|
|
4
|
+
import {stdin as input, stdout as output} from 'node:process';
|
|
5
|
+
|
|
6
|
+
const rl = readline.createInterface({input, output});
|
|
7
|
+
|
|
8
|
+
console.log(n2words(await rl.question('Value to convert? ')));
|
|
9
|
+
|
|
10
|
+
rl.close();
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates new language class that processes decimals separately.
|
|
3
|
+
* Requires implementing `toCardinal`.
|
|
4
|
+
*/
|
|
5
|
+
export default class {
|
|
6
|
+
#negativeWord;
|
|
7
|
+
#separatorWord;
|
|
8
|
+
#zero;
|
|
9
|
+
#spaceSeparator;
|
|
10
|
+
#wholeNumber;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {object} options Options for class.
|
|
14
|
+
* @param {string} [options.negativeWord = ''] Word that precedes a negative number (if any).
|
|
15
|
+
* @param {string} options.separatorWord Word that separates cardinal numbers (i.e. "and").
|
|
16
|
+
* @param {string} options.zero Word for 0 (i.e. "zero").
|
|
17
|
+
* @param {string} [options.spaceSeparator = ' '] Character that separates words.
|
|
18
|
+
*/
|
|
19
|
+
constructor(options) {
|
|
20
|
+
// Merge supplied options with defaults
|
|
21
|
+
options = Object.assign({
|
|
22
|
+
negativeWord: '',
|
|
23
|
+
separatorWord: undefined,
|
|
24
|
+
zeroWord: undefined,
|
|
25
|
+
spaceSeparator: ' '
|
|
26
|
+
}, options);
|
|
27
|
+
|
|
28
|
+
// Make options available to class
|
|
29
|
+
this.#negativeWord = options.negativeWord;
|
|
30
|
+
this.#separatorWord = options.separatorWord;
|
|
31
|
+
this.#zero = options.zero;
|
|
32
|
+
this.#spaceSeparator = options.spaceSeparator;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @returns {string} Word that precedes a negative number (if any).
|
|
37
|
+
*/
|
|
38
|
+
get negativeWord() {
|
|
39
|
+
return this.#negativeWord;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @returns {string} Word that separates cardinal numbers (i.e. "and").
|
|
44
|
+
*/
|
|
45
|
+
get separatorWord() {
|
|
46
|
+
return this.#separatorWord;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @returns {string} Word for 0 (i.e. "zero").
|
|
51
|
+
*/
|
|
52
|
+
get zero() {
|
|
53
|
+
return this.#zero;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @returns {string} Character that separates words.
|
|
58
|
+
*/
|
|
59
|
+
get spaceSeparator() {
|
|
60
|
+
return this.#spaceSeparator;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @returns {number} Input value without decimal.
|
|
65
|
+
*/
|
|
66
|
+
get wholeNumber() {
|
|
67
|
+
return this.#wholeNumber;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Convert decimal number to a string array of cardinal numbers.
|
|
72
|
+
* @param {number} decimal Decimal number to convert.
|
|
73
|
+
* @returns {string} Value in written format.
|
|
74
|
+
*/
|
|
75
|
+
decimalToCardinal(decimal) {
|
|
76
|
+
const words = [];
|
|
77
|
+
|
|
78
|
+
// Split decimal portion into an array of characters in reverse
|
|
79
|
+
const chars = decimal.split('').reverse();
|
|
80
|
+
|
|
81
|
+
// Loop through array (from the end) adding words to output array
|
|
82
|
+
while (chars.pop() == '0') {
|
|
83
|
+
words.push(this.zero);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Add decimal number to word array
|
|
87
|
+
return words.concat(this.toCardinal(BigInt(decimal)));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Converts a number to written form.
|
|
92
|
+
* @param {number|string} value Number to be convert.
|
|
93
|
+
* @throws {Error} Value must be a valid number.
|
|
94
|
+
* @returns {string} Value in written format.
|
|
95
|
+
*/
|
|
96
|
+
floatToCardinal(value) {
|
|
97
|
+
// Validate user input value
|
|
98
|
+
if (typeof value == 'number') {
|
|
99
|
+
if (Number.isNaN(value)) {
|
|
100
|
+
throw new Error('NaN is not an accepted number.');
|
|
101
|
+
}
|
|
102
|
+
value = value.toString();
|
|
103
|
+
} else if (typeof value == 'string') {
|
|
104
|
+
value = value.trim();
|
|
105
|
+
if (value.length == 0 || Number.isNaN(Number(value))) {
|
|
106
|
+
throw new Error('"' + value + '" is not a valid number.');
|
|
107
|
+
}
|
|
108
|
+
} else if (typeof value != 'bigint') {
|
|
109
|
+
throw new TypeError('Invalid variable type: ' + typeof value);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let words = [];
|
|
113
|
+
let wholeNumber;
|
|
114
|
+
let decimalNumber;
|
|
115
|
+
|
|
116
|
+
// If negative number add negative word
|
|
117
|
+
if (value < 0) {
|
|
118
|
+
words.push(this.negativeWord);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Split value decimal (if any) (excluding BigInt)
|
|
122
|
+
if (typeof value == 'bigint') {
|
|
123
|
+
wholeNumber = value;
|
|
124
|
+
} else {
|
|
125
|
+
const splitValue = value.split('.');
|
|
126
|
+
wholeNumber = BigInt(splitValue[0]);
|
|
127
|
+
decimalNumber = splitValue[1];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Convert whole number to positive (if negative)
|
|
131
|
+
if (wholeNumber < 0) {
|
|
132
|
+
wholeNumber = -wholeNumber;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// NOTE: Only needed for CZ
|
|
136
|
+
this.#wholeNumber = wholeNumber;
|
|
137
|
+
|
|
138
|
+
// Add whole number in written form
|
|
139
|
+
words = words.concat(this.toCardinal(wholeNumber));
|
|
140
|
+
|
|
141
|
+
// Add decimal number in written form (if any)
|
|
142
|
+
if (decimalNumber) {
|
|
143
|
+
words.push(this.separatorWord);
|
|
144
|
+
|
|
145
|
+
words = words.concat(this.decimalToCardinal(decimalNumber));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Join words with spaces
|
|
149
|
+
return words.join(this.spaceSeparator);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import AbstractLanguage from './AbstractLanguage.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates new common language class that uses a highest matching word value algorithm.
|
|
5
|
+
* Number matching word {@link cards} must be provided for this to work.
|
|
6
|
+
* See {@link AbstractLanguage} for further requirements.
|
|
7
|
+
* @classdesc Common class for (mostly european) languages.
|
|
8
|
+
*/
|
|
9
|
+
export default class extends AbstractLanguage {
|
|
10
|
+
#cards;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {object} options Options for class.
|
|
14
|
+
* @param {string} [options.negativeWord = ''] Word that precedes a negative number (if any).
|
|
15
|
+
* @param {string} options.separatorWord Word that separates cardinal numbers (i.e. "and").
|
|
16
|
+
* @param {string} options.zero Word for 0 (i.e. "zero").
|
|
17
|
+
* @param {string} [options.spaceSeparator = ' '] Character that separates words.
|
|
18
|
+
* @param {Array} cards Array of number matching "cards" from highest-to-lowest.
|
|
19
|
+
*/
|
|
20
|
+
constructor(options, cards) {
|
|
21
|
+
super(options);
|
|
22
|
+
|
|
23
|
+
this.#cards = cards;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get array of number matching "cards" from highest-to-lowest.
|
|
28
|
+
* First element in card array is the number to match while the second is the word to use.
|
|
29
|
+
* @example
|
|
30
|
+
* [
|
|
31
|
+
* ...
|
|
32
|
+
* [100, 'hundred'],
|
|
33
|
+
* ...
|
|
34
|
+
* [1, 'one'],
|
|
35
|
+
* ]
|
|
36
|
+
* @returns {Array} Array of number matching "cards" from highest-to-lowest.
|
|
37
|
+
*/
|
|
38
|
+
get cards() {
|
|
39
|
+
return this.#cards;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get word for number if it matches a language card.
|
|
44
|
+
* @param {number} number Card number value.
|
|
45
|
+
* @returns {string|undefined} Return card word or undefined if no card.
|
|
46
|
+
*/
|
|
47
|
+
getCardWord(number) {
|
|
48
|
+
// Get matching card from number
|
|
49
|
+
const card = this.cards.find(_card => _card[0] == number);
|
|
50
|
+
|
|
51
|
+
// Return card word or undefined if no card found
|
|
52
|
+
return (Array.isArray(card) ? card[1] : undefined);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get array of card matches.
|
|
57
|
+
* @param {number} value The number value to convert to cardinal form.
|
|
58
|
+
* @returns {object} Word sets (and pairs) from value.
|
|
59
|
+
* @todo Simplify return object.
|
|
60
|
+
*/
|
|
61
|
+
toCardMatches(value) {
|
|
62
|
+
const out = [];
|
|
63
|
+
let remaining = value;
|
|
64
|
+
|
|
65
|
+
do {
|
|
66
|
+
// Find card with highest matching number
|
|
67
|
+
const card = this.cards.find(card => {
|
|
68
|
+
return remaining >= card[0];
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
let quantity; // Quantity of card set values
|
|
72
|
+
|
|
73
|
+
// Calculate quantity and remaining value
|
|
74
|
+
// Override variables for 0 as math will fail
|
|
75
|
+
if (remaining == 0) {
|
|
76
|
+
quantity = 1;
|
|
77
|
+
remaining = 0;
|
|
78
|
+
} else {
|
|
79
|
+
quantity = remaining / card[0];
|
|
80
|
+
remaining = remaining % card[0];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Is value perfect match of card number?
|
|
84
|
+
if (quantity == 1) {
|
|
85
|
+
/** @todo Merge word set pairs together (if possible) to simplify return object */
|
|
86
|
+
out.push({
|
|
87
|
+
[this.getCardWord(1)]: 1,
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
/** @todo Understand the logic for this */
|
|
91
|
+
/*if (quantity == remaining) {
|
|
92
|
+
return [(quantity * this.getCardWord(card[0]), quantity * card[0])];
|
|
93
|
+
}*/
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @todo Remove reciprocating calls.
|
|
97
|
+
*/
|
|
98
|
+
out.push(this.toCardMatches(quantity));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Add matching word set to output list
|
|
102
|
+
out.push({
|
|
103
|
+
[card[1]]: card[0],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
while (remaining > 0);
|
|
107
|
+
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
scanNum(value) {
|
|
112
|
+
return value.split('').map(v => this.getCardWord(Number(v)));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
clean(words) {
|
|
116
|
+
let out = words;
|
|
117
|
+
|
|
118
|
+
// Loop through word sets while array size is greater or less than 1
|
|
119
|
+
/** @todo Change logic to work in for loop to better understand loop intentions */
|
|
120
|
+
while (words.length != 1) {
|
|
121
|
+
out = [];
|
|
122
|
+
const left = words[0];
|
|
123
|
+
const right = words[1];
|
|
124
|
+
|
|
125
|
+
// Are the first & second word sets arrays?
|
|
126
|
+
if (!Array.isArray(left) && !Array.isArray(right)) {
|
|
127
|
+
// Merge word set pair and add to output array
|
|
128
|
+
out.push(this.merge(left, right));
|
|
129
|
+
|
|
130
|
+
/** @todo Understand */
|
|
131
|
+
if (words.slice(2).length > 0) {
|
|
132
|
+
out.push(words.slice(2));
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
// Loop through
|
|
136
|
+
for (let i = 0; i < words.length; i++) {
|
|
137
|
+
const elem = words[i];
|
|
138
|
+
|
|
139
|
+
if (Array.isArray(elem)) {
|
|
140
|
+
if (elem.length == 1) out.push(elem[0]);
|
|
141
|
+
else out.push(this.clean(elem));
|
|
142
|
+
} else {
|
|
143
|
+
out.push(elem);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
words = out;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return out[0];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
postClean(out0) {
|
|
155
|
+
return out0.trimRight();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Convert a whole number to written format.
|
|
160
|
+
* @param {number} value The number value to convert to cardinal form.
|
|
161
|
+
* @returns {string} Value in written format.
|
|
162
|
+
*/
|
|
163
|
+
toCardinal(value) {
|
|
164
|
+
// Convert value to word sets
|
|
165
|
+
const words = this.toCardMatches(value);
|
|
166
|
+
|
|
167
|
+
// Process word sets
|
|
168
|
+
const preWords = Object.keys(this.clean(words))[0];
|
|
169
|
+
|
|
170
|
+
// Process word sets some more and return result
|
|
171
|
+
/** @todo Look into language functions/events */
|
|
172
|
+
return this.postClean(preWords);
|
|
173
|
+
}
|
|
174
|
+
}
|
package/lib/i18n/AR.mjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import AbstractLanguage from '../classes/AbstractLanguage.mjs';
|
|
2
2
|
|
|
3
|
-
export class
|
|
3
|
+
export class Arabic extends AbstractLanguage {
|
|
4
4
|
constructor() {
|
|
5
|
-
super(
|
|
5
|
+
super({
|
|
6
|
+
negativeWord: 'ناقص',
|
|
7
|
+
separatorWord: 'فاصلة',
|
|
8
|
+
zero: 'صفر'
|
|
9
|
+
});
|
|
6
10
|
|
|
7
11
|
this.integerValue = 0;
|
|
8
12
|
this.decimalValue = 0;
|
|
9
|
-
this.negativeWord = 'ناقص';
|
|
10
|
-
this.separatorWord = 'فاصلة';
|
|
11
13
|
this.number = 0;
|
|
12
|
-
this.zero = 'صفر';
|
|
13
14
|
// this.isCurrencyPartNameFeminine = true
|
|
14
15
|
// this.isCurrencyNameFeminine = false
|
|
15
16
|
this.arabicOnes = [
|
|
@@ -93,7 +94,10 @@ export class N2WordsAR extends N2WordsAbs {
|
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
toCardinal(number) {
|
|
96
|
-
|
|
97
|
+
/** @todo Convert class to work with BigInt */
|
|
98
|
+
number = Number(number);
|
|
99
|
+
|
|
100
|
+
if (number == 0) {
|
|
97
101
|
return this.zero;
|
|
98
102
|
}
|
|
99
103
|
let tempNumber = number;
|
|
@@ -133,6 +137,12 @@ export class N2WordsAR extends N2WordsAbs {
|
|
|
133
137
|
}
|
|
134
138
|
}
|
|
135
139
|
|
|
136
|
-
|
|
137
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Converts a value to cardinal (written) form.
|
|
142
|
+
* @param {number|string} value Number to be convert.
|
|
143
|
+
* @throws {Error} Value cannot be invalid.
|
|
144
|
+
* @returns {string} Value in cardinal (written) format.
|
|
145
|
+
*/
|
|
146
|
+
export default function(value) {
|
|
147
|
+
return new Arabic().floatToCardinal(value);
|
|
138
148
|
}
|
package/lib/i18n/AZ.mjs
CHANGED
|
@@ -1,40 +1,39 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BaseLanguage from '../classes/BaseLanguage.mjs';
|
|
2
2
|
|
|
3
|
-
export class N2WordsAZ extends
|
|
3
|
+
export class N2WordsAZ extends BaseLanguage {
|
|
4
4
|
constructor() {
|
|
5
|
-
super(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
];
|
|
5
|
+
super({
|
|
6
|
+
negativeWord: 'mənfi',
|
|
7
|
+
separatorWord: 'nöqtə',
|
|
8
|
+
zero: 'sıfır'
|
|
9
|
+
},[
|
|
10
|
+
[1000000000000000000n, 'kentilyon'],
|
|
11
|
+
[1000000000000000n, 'katrilyon'],
|
|
12
|
+
[1000000000000n, 'trilyon'],
|
|
13
|
+
[1000000000n, 'milyar'],
|
|
14
|
+
[1000000n, 'milyon'],
|
|
15
|
+
[1000n, 'min'],
|
|
16
|
+
[100n, 'yüz'],
|
|
17
|
+
[90n, 'doxsan'],
|
|
18
|
+
[80n, 'səksən'],
|
|
19
|
+
[70n, 'yetmiş'],
|
|
20
|
+
[60n, 'altmış'],
|
|
21
|
+
[50n, 'əlli'],
|
|
22
|
+
[40n, 'qırx'],
|
|
23
|
+
[30n, 'otuz'],
|
|
24
|
+
[20n, 'iyirmi'],
|
|
25
|
+
[10n, 'on'],
|
|
26
|
+
[9n, 'doqquz'],
|
|
27
|
+
[8n, 'səkkiz'],
|
|
28
|
+
[7n, 'yeddi'],
|
|
29
|
+
[6n, 'altı'],
|
|
30
|
+
[5n, 'beş'],
|
|
31
|
+
[4n, 'dörd'],
|
|
32
|
+
[3n, 'üç'],
|
|
33
|
+
[2n, 'iki'],
|
|
34
|
+
[1n, 'bir'],
|
|
35
|
+
[0n, 'sıfır']
|
|
36
|
+
]);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
merge(lPair, rPair) {
|
|
@@ -52,6 +51,12 @@ export class N2WordsAZ extends N2WordsBase {
|
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Converts a value to cardinal (written) form.
|
|
56
|
+
* @param {number|string} value Number to be convert.
|
|
57
|
+
* @throws {Error} Value cannot be invalid.
|
|
58
|
+
* @returns {string} Value in cardinal (written) format.
|
|
59
|
+
*/
|
|
60
|
+
export default function(value) {
|
|
61
|
+
return new N2WordsAZ().floatToCardinal(value);
|
|
57
62
|
}
|
package/lib/i18n/CZ.mjs
CHANGED
|
@@ -1,97 +1,100 @@
|
|
|
1
1
|
import {N2WordsRU} from './RU.mjs';
|
|
2
2
|
|
|
3
3
|
export class N2WordsCZ extends N2WordsRU {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
ones = {
|
|
5
|
+
1: 'jedna',
|
|
6
|
+
2: 'dva',
|
|
7
|
+
3: 'tři',
|
|
8
|
+
4: 'čtyři',
|
|
9
|
+
5: 'pět',
|
|
10
|
+
6: 'šest',
|
|
11
|
+
7: 'sedm',
|
|
12
|
+
8: 'osm',
|
|
13
|
+
9: 'devět'
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
tens = {
|
|
17
|
+
0: 'deset',
|
|
18
|
+
1: 'jedenáct',
|
|
19
|
+
2: 'dvanáct',
|
|
20
|
+
3: 'třináct',
|
|
21
|
+
4: 'čtrnáct',
|
|
22
|
+
5: 'patnáct',
|
|
23
|
+
6: 'šestnáct',
|
|
24
|
+
7: 'sedmnáct',
|
|
25
|
+
8: 'osmnáct',
|
|
26
|
+
9: 'devatenáct'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
twenties = {
|
|
30
|
+
2: 'dvacet',
|
|
31
|
+
3: 'třicet',
|
|
32
|
+
4: 'čtyřicet',
|
|
33
|
+
5: 'padesát',
|
|
34
|
+
6: 'šedesát',
|
|
35
|
+
7: 'sedmdesát',
|
|
36
|
+
8: 'osmdesát',
|
|
37
|
+
9: 'devadesát'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
hundreds = {
|
|
41
|
+
1: 'sto',
|
|
42
|
+
2: 'dvě stě',
|
|
43
|
+
3: 'tři sta',
|
|
44
|
+
4: 'čtyři sta',
|
|
45
|
+
5: 'pět set',
|
|
46
|
+
6: 'šest set',
|
|
47
|
+
7: 'sedm set',
|
|
48
|
+
8: 'osm set',
|
|
49
|
+
9: 'devět set'
|
|
50
|
+
};
|
|
6
51
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
4: 'čtrnáct',
|
|
26
|
-
5: 'patnáct',
|
|
27
|
-
6: 'šestnáct',
|
|
28
|
-
7: 'sedmnáct',
|
|
29
|
-
8: 'osmnáct',
|
|
30
|
-
9: 'devatenáct'
|
|
31
|
-
};
|
|
32
|
-
this.twenties = {
|
|
33
|
-
2: 'dvacet',
|
|
34
|
-
3: 'třicet',
|
|
35
|
-
4: 'čtyřicet',
|
|
36
|
-
5: 'padesát',
|
|
37
|
-
6: 'šedesát',
|
|
38
|
-
7: 'sedmdesát',
|
|
39
|
-
8: 'osmdesát',
|
|
40
|
-
9: 'devadesát'
|
|
41
|
-
};
|
|
42
|
-
this.hundreds = {
|
|
43
|
-
1: 'sto',
|
|
44
|
-
2: 'dvě stě',
|
|
45
|
-
3: 'tři sta',
|
|
46
|
-
4: 'čtyři sta',
|
|
47
|
-
5: 'pět set',
|
|
48
|
-
6: 'šest set',
|
|
49
|
-
7: 'sedm set',
|
|
50
|
-
8: 'osm set',
|
|
51
|
-
9: 'devět set'
|
|
52
|
-
};
|
|
53
|
-
this.thousands = {
|
|
54
|
-
1: ['tisíc', 'tisíce', 'tisíc'], // 10^ 3
|
|
55
|
-
2: ['milion', 'miliony', 'milionů'], // 10^ 6
|
|
56
|
-
3: ['miliarda', 'miliardy', 'miliard'], // 10^ 9
|
|
57
|
-
4: ['bilion', 'biliony', 'bilionů'], // 10^ 12
|
|
58
|
-
5: ['biliarda', 'biliardy', 'biliard'], // 10^ 15
|
|
59
|
-
6: ['trilion', 'triliony', 'trilionů'], // 10^ 18
|
|
60
|
-
7: ['triliarda', 'triliardy', 'triliard'], // 10^ 21
|
|
61
|
-
8: ['kvadrilion', 'kvadriliony', 'kvadrilionů'], // 10^ 24
|
|
62
|
-
9: ['kvadriliarda', 'kvadriliardy', 'kvadriliard'], // 10^ 27
|
|
63
|
-
10: ['quintillion', 'quintilliony', 'quintillionů'], // 10^ 30
|
|
64
|
-
};
|
|
52
|
+
thousands = {
|
|
53
|
+
1: ['tisíc', 'tisíce', 'tisíc'], // 10^ 3
|
|
54
|
+
2: ['milion', 'miliony', 'milionů'], // 10^ 6
|
|
55
|
+
3: ['miliarda', 'miliardy', 'miliard'], // 10^ 9
|
|
56
|
+
4: ['bilion', 'biliony', 'bilionů'], // 10^ 12
|
|
57
|
+
5: ['biliarda', 'biliardy', 'biliard'], // 10^ 15
|
|
58
|
+
6: ['trilion', 'triliony', 'trilionů'], // 10^ 18
|
|
59
|
+
7: ['triliarda', 'triliardy', 'triliard'], // 10^ 21
|
|
60
|
+
8: ['kvadrilion', 'kvadriliony', 'kvadrilionů'], // 10^ 24
|
|
61
|
+
9: ['kvadriliarda', 'kvadriliardy', 'kvadriliard'], // 10^ 27
|
|
62
|
+
10: ['quintillion', 'quintilliony', 'quintillionů'], // 10^ 30
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
constructor() {
|
|
66
|
+
super({
|
|
67
|
+
negativeWord: 'mínus',
|
|
68
|
+
zero: 'nula'
|
|
69
|
+
});
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
get separatorWord() {
|
|
68
|
-
if (this.
|
|
73
|
+
if (this.wholeNumber == 0n || this.wholeNumber == 1n) {
|
|
69
74
|
return 'celá';
|
|
70
|
-
} else if (this.
|
|
75
|
+
} else if (this.wholeNumber >= 2n && this.wholeNumber <= 4n) {
|
|
71
76
|
return 'celé';
|
|
72
77
|
} else {
|
|
73
78
|
return 'celých';
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
set separatorWord(value) {}
|
|
78
|
-
|
|
79
82
|
pluralize(n, forms) {
|
|
80
83
|
let form = 2;
|
|
81
84
|
if (n == 1) {
|
|
82
85
|
form = 0;
|
|
83
|
-
} else if (((n %
|
|
86
|
+
} else if (((n % 10n < 5n) && (n % 10n > 1n)) && (n % 100n < 10n || n % 100n > 20n)) {
|
|
84
87
|
form = 1;
|
|
85
88
|
}
|
|
86
89
|
return forms[form];
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
toCardinal(number) {
|
|
90
|
-
if (
|
|
93
|
+
if (number == 0) {
|
|
91
94
|
return this.zero;
|
|
92
95
|
}
|
|
93
96
|
const words = [];
|
|
94
|
-
const chunks = this.splitByX(
|
|
97
|
+
const chunks = this.splitByX(number.toString(), 3);
|
|
95
98
|
let i = chunks.length;
|
|
96
99
|
for (let j = 0; j < chunks.length; j++) {
|
|
97
100
|
const x = chunks[j];
|
|
@@ -119,6 +122,12 @@ export class N2WordsCZ extends N2WordsRU {
|
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
124
|
|
|
122
|
-
|
|
123
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Converts a value to cardinal (written) form.
|
|
127
|
+
* @param {number|string} value Number to be convert.
|
|
128
|
+
* @throws {Error} Value cannot be invalid.
|
|
129
|
+
* @returns {string} Value in cardinal (written) format.
|
|
130
|
+
*/
|
|
131
|
+
export default function(value) {
|
|
132
|
+
return new N2WordsCZ().floatToCardinal(value);
|
|
124
133
|
}
|