n2words 1.23.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +317 -59
- package/dist/ArabicConverter.js +3 -0
- package/dist/ArabicConverter.js.map +1 -0
- package/dist/AzerbaijaniConverter.js +3 -0
- package/dist/AzerbaijaniConverter.js.map +1 -0
- package/dist/BanglaConverter.js +3 -0
- package/dist/BanglaConverter.js.map +1 -0
- package/dist/BiblicalHebrewConverter.js +3 -0
- package/dist/BiblicalHebrewConverter.js.map +1 -0
- package/dist/CroatianConverter.js +3 -0
- package/dist/CroatianConverter.js.map +1 -0
- package/dist/CzechConverter.js +3 -0
- package/dist/CzechConverter.js.map +1 -0
- package/dist/DanishConverter.js +3 -0
- package/dist/DanishConverter.js.map +1 -0
- package/dist/DutchConverter.js +3 -0
- package/dist/DutchConverter.js.map +1 -0
- package/dist/EnglishConverter.js +3 -0
- package/dist/EnglishConverter.js.map +1 -0
- package/dist/FilipinoConverter.js +3 -0
- package/dist/FilipinoConverter.js.map +1 -0
- package/dist/FrenchBelgiumConverter.js +3 -0
- package/dist/FrenchBelgiumConverter.js.map +1 -0
- package/dist/FrenchConverter.js +3 -0
- package/dist/FrenchConverter.js.map +1 -0
- package/dist/GermanConverter.js +3 -0
- package/dist/GermanConverter.js.map +1 -0
- package/dist/GreekConverter.js +3 -0
- package/dist/GreekConverter.js.map +1 -0
- package/dist/GujaratiConverter.js +3 -0
- package/dist/GujaratiConverter.js.map +1 -0
- package/dist/HebrewConverter.js +3 -0
- package/dist/HebrewConverter.js.map +1 -0
- package/dist/HindiConverter.js +3 -0
- package/dist/HindiConverter.js.map +1 -0
- package/dist/HungarianConverter.js +3 -0
- package/dist/HungarianConverter.js.map +1 -0
- package/dist/IndonesianConverter.js +3 -0
- package/dist/IndonesianConverter.js.map +1 -0
- package/dist/ItalianConverter.js +3 -0
- package/dist/ItalianConverter.js.map +1 -0
- package/dist/JapaneseConverter.js +3 -0
- package/dist/JapaneseConverter.js.map +1 -0
- package/dist/KannadaConverter.js +3 -0
- package/dist/KannadaConverter.js.map +1 -0
- package/dist/KoreanConverter.js +3 -0
- package/dist/KoreanConverter.js.map +1 -0
- package/dist/LatvianConverter.js +3 -0
- package/dist/LatvianConverter.js.map +1 -0
- package/dist/LithuanianConverter.js +3 -0
- package/dist/LithuanianConverter.js.map +1 -0
- package/dist/MalayConverter.js +3 -0
- package/dist/MalayConverter.js.map +1 -0
- package/dist/MarathiConverter.js +3 -0
- package/dist/MarathiConverter.js.map +1 -0
- package/dist/NorwegianBokmalConverter.js +3 -0
- package/dist/NorwegianBokmalConverter.js.map +1 -0
- package/dist/PersianConverter.js +3 -0
- package/dist/PersianConverter.js.map +1 -0
- package/dist/PolishConverter.js +3 -0
- package/dist/PolishConverter.js.map +1 -0
- package/dist/PortugueseConverter.js +3 -0
- package/dist/PortugueseConverter.js.map +1 -0
- package/dist/PunjabiConverter.js +3 -0
- package/dist/PunjabiConverter.js.map +1 -0
- package/dist/RomanianConverter.js +3 -0
- package/dist/RomanianConverter.js.map +1 -0
- package/dist/RussianConverter.js +3 -0
- package/dist/RussianConverter.js.map +1 -0
- package/dist/SerbianCyrillicConverter.js +3 -0
- package/dist/SerbianCyrillicConverter.js.map +1 -0
- package/dist/SerbianLatinConverter.js +3 -0
- package/dist/SerbianLatinConverter.js.map +1 -0
- package/dist/SimplifiedChineseConverter.js +3 -0
- package/dist/SimplifiedChineseConverter.js.map +1 -0
- package/dist/SpanishConverter.js +3 -0
- package/dist/SpanishConverter.js.map +1 -0
- package/dist/SwahiliConverter.js +3 -0
- package/dist/SwahiliConverter.js.map +1 -0
- package/dist/SwedishConverter.js +3 -0
- package/dist/SwedishConverter.js.map +1 -0
- package/dist/TamilConverter.js +3 -0
- package/dist/TamilConverter.js.map +1 -0
- package/dist/TeluguConverter.js +3 -0
- package/dist/TeluguConverter.js.map +1 -0
- package/dist/ThaiConverter.js +3 -0
- package/dist/ThaiConverter.js.map +1 -0
- package/dist/TraditionalChineseConverter.js +3 -0
- package/dist/TraditionalChineseConverter.js.map +1 -0
- package/dist/TurkishConverter.js +3 -0
- package/dist/TurkishConverter.js.map +1 -0
- package/dist/UkrainianConverter.js +3 -0
- package/dist/UkrainianConverter.js.map +1 -0
- package/dist/UrduConverter.js +3 -0
- package/dist/UrduConverter.js.map +1 -0
- package/dist/VietnameseConverter.js +3 -0
- package/dist/VietnameseConverter.js.map +1 -0
- package/dist/n2words.js +3 -2
- package/dist/n2words.js.map +1 -1
- package/lib/classes/abstract-language.d.ts +158 -34
- package/lib/classes/abstract-language.js +223 -115
- package/lib/classes/greedy-scale-language.d.ts +109 -0
- package/lib/classes/greedy-scale-language.js +201 -0
- package/lib/classes/slavic-language.d.ts +148 -0
- package/lib/classes/slavic-language.js +281 -0
- package/lib/classes/south-asian-language.d.ts +70 -0
- package/lib/classes/south-asian-language.js +154 -0
- package/lib/classes/turkic-language.d.ts +26 -0
- package/lib/classes/turkic-language.js +59 -0
- package/lib/languages/ar.d.ts +30 -0
- package/lib/languages/ar.js +159 -0
- package/lib/languages/az.d.ts +12 -0
- package/lib/languages/az.js +42 -0
- package/lib/languages/bn.d.ts +11 -0
- package/lib/languages/bn.js +131 -0
- package/lib/languages/cs.d.ts +88 -0
- package/lib/languages/cs.js +143 -0
- package/lib/languages/da.d.ts +15 -0
- package/lib/languages/da.js +120 -0
- package/lib/languages/de.d.ts +14 -0
- package/lib/languages/de.js +101 -0
- package/lib/languages/el.d.ts +14 -0
- package/lib/languages/el.js +90 -0
- package/lib/languages/en.d.ts +16 -0
- package/lib/languages/en.js +86 -0
- package/lib/languages/es.d.ts +15 -0
- package/lib/languages/es.js +121 -0
- package/lib/languages/fa.d.ts +47 -0
- package/lib/languages/fa.js +144 -0
- package/lib/languages/fil.d.ts +16 -0
- package/lib/languages/fil.js +121 -0
- package/lib/languages/fr-BE.d.ts +11 -0
- package/lib/languages/fr-BE.js +25 -0
- package/lib/languages/fr.d.ts +15 -0
- package/lib/languages/fr.js +106 -0
- package/lib/languages/gu.d.ts +11 -0
- package/lib/languages/gu.js +132 -0
- package/lib/languages/hbo.d.ts +113 -0
- package/lib/languages/hbo.js +251 -0
- package/lib/languages/he.d.ts +80 -0
- package/lib/languages/he.js +206 -0
- package/lib/languages/hi.d.ts +11 -0
- package/lib/languages/hi.js +131 -0
- package/lib/languages/hr.d.ts +80 -0
- package/lib/languages/hr.js +113 -0
- package/lib/languages/hu.d.ts +22 -0
- package/lib/languages/hu.js +137 -0
- package/lib/languages/id.d.ts +37 -0
- package/lib/languages/id.js +159 -0
- package/lib/languages/it.d.ts +37 -0
- package/lib/languages/it.js +132 -0
- package/lib/languages/ja.d.ts +17 -0
- package/lib/languages/ja.js +137 -0
- package/lib/languages/kn.d.ts +11 -0
- package/lib/languages/kn.js +42 -0
- package/lib/languages/ko.d.ts +14 -0
- package/lib/languages/ko.js +55 -0
- package/lib/{i18n/pl.d.ts → languages/lt.d.ts} +18 -15
- package/lib/languages/lt.js +136 -0
- package/lib/{i18n/lt.d.ts → languages/lv.d.ts} +16 -14
- package/lib/languages/lv.js +130 -0
- package/lib/languages/mr.d.ts +11 -0
- package/lib/languages/mr.js +132 -0
- package/lib/languages/ms.d.ts +31 -0
- package/lib/languages/ms.js +150 -0
- package/lib/languages/nb.d.ts +12 -0
- package/lib/languages/nb.js +100 -0
- package/lib/languages/nl.d.ts +16 -0
- package/lib/languages/nl.js +155 -0
- package/lib/languages/pa.d.ts +11 -0
- package/lib/languages/pa.js +131 -0
- package/lib/{i18n/uk.d.ts → languages/pl.d.ts} +16 -14
- package/lib/languages/pl.js +110 -0
- package/lib/languages/pt.d.ts +29 -0
- package/lib/languages/pt.js +112 -0
- package/lib/languages/ro.d.ts +158 -0
- package/lib/languages/ro.js +273 -0
- package/lib/languages/ru.d.ts +85 -0
- package/lib/languages/ru.js +96 -0
- package/lib/languages/sr-Cyrl.d.ts +80 -0
- package/lib/languages/sr-Cyrl.js +113 -0
- package/lib/{i18n/cz.d.ts → languages/sr-Latn.d.ts} +26 -14
- package/lib/languages/sr-Latn.js +113 -0
- package/lib/languages/sv.d.ts +14 -0
- package/lib/languages/sv.js +90 -0
- package/lib/languages/sw.d.ts +39 -0
- package/lib/languages/sw.js +126 -0
- package/lib/languages/ta.d.ts +20 -0
- package/lib/languages/ta.js +226 -0
- package/lib/languages/te.d.ts +22 -0
- package/lib/languages/te.js +219 -0
- package/lib/languages/th.d.ts +17 -0
- package/lib/languages/th.js +117 -0
- package/lib/languages/tr.d.ts +12 -0
- package/lib/languages/tr.js +56 -0
- package/lib/languages/uk.d.ts +85 -0
- package/lib/{i18n → languages}/uk.js +33 -32
- package/lib/languages/ur.d.ts +11 -0
- package/lib/languages/ur.js +131 -0
- package/lib/{i18n → languages}/vi.d.ts +15 -13
- package/lib/languages/vi.js +147 -0
- package/lib/languages/zh-Hans.d.ts +21 -0
- package/lib/languages/zh-Hans.js +111 -0
- package/lib/languages/zh-Hant.d.ts +21 -0
- package/lib/languages/zh-Hant.js +111 -0
- package/lib/n2words.d.ts +207 -7
- package/lib/n2words.js +535 -81
- package/package.json +126 -79
- package/dist/ar.js +0 -2
- package/dist/ar.js.map +0 -1
- package/dist/az.js +0 -2
- package/dist/az.js.map +0 -1
- package/dist/cz.js +0 -2
- package/dist/cz.js.map +0 -1
- package/dist/de.js +0 -2
- package/dist/de.js.map +0 -1
- package/dist/dk.js +0 -2
- package/dist/dk.js.map +0 -1
- package/dist/en.js +0 -2
- package/dist/en.js.map +0 -1
- package/dist/es.js +0 -2
- package/dist/es.js.map +0 -1
- package/dist/fa.js +0 -2
- package/dist/fa.js.map +0 -1
- package/dist/fr-BE.js +0 -2
- package/dist/fr-BE.js.map +0 -1
- package/dist/fr.js +0 -2
- package/dist/fr.js.map +0 -1
- package/dist/he.js +0 -2
- package/dist/he.js.map +0 -1
- package/dist/hr.js +0 -2
- package/dist/hr.js.map +0 -1
- package/dist/hu.js +0 -2
- package/dist/hu.js.map +0 -1
- package/dist/id.js +0 -2
- package/dist/id.js.map +0 -1
- package/dist/it.js +0 -2
- package/dist/it.js.map +0 -1
- package/dist/ko.js +0 -2
- package/dist/ko.js.map +0 -1
- package/dist/lt.js +0 -2
- package/dist/lt.js.map +0 -1
- package/dist/lv.js +0 -2
- package/dist/lv.js.map +0 -1
- package/dist/n2words.d.ts +0 -2
- package/dist/nl.js +0 -2
- package/dist/nl.js.map +0 -1
- package/dist/no.js +0 -2
- package/dist/no.js.map +0 -1
- package/dist/pl.js +0 -2
- package/dist/pl.js.map +0 -1
- package/dist/pt.js +0 -2
- package/dist/pt.js.map +0 -1
- package/dist/ro.js +0 -2
- package/dist/ro.js.map +0 -1
- package/dist/ru.js +0 -2
- package/dist/ru.js.map +0 -1
- package/dist/sr.js +0 -2
- package/dist/sr.js.map +0 -1
- package/dist/tr.js +0 -2
- package/dist/tr.js.map +0 -1
- package/dist/uk.js +0 -2
- package/dist/uk.js.map +0 -1
- package/dist/vi.js +0 -2
- package/dist/vi.js.map +0 -1
- package/dist/zh.js +0 -2
- package/dist/zh.js.map +0 -1
- package/lib/classes/base-language.d.ts +0 -58
- package/lib/classes/base-language.js +0 -172
- package/lib/i18n/ar.d.ts +0 -41
- package/lib/i18n/ar.js +0 -209
- package/lib/i18n/az.d.ts +0 -15
- package/lib/i18n/az.js +0 -66
- package/lib/i18n/cz.js +0 -135
- package/lib/i18n/de.d.ts +0 -17
- package/lib/i18n/de.js +0 -103
- package/lib/i18n/dk.d.ts +0 -14
- package/lib/i18n/dk.js +0 -110
- package/lib/i18n/en.d.ts +0 -22
- package/lib/i18n/en.js +0 -86
- package/lib/i18n/es.d.ts +0 -16
- package/lib/i18n/es.js +0 -110
- package/lib/i18n/fa.d.ts +0 -54
- package/lib/i18n/fa.js +0 -106
- package/lib/i18n/fr-BE.d.ts +0 -11
- package/lib/i18n/fr-BE.js +0 -20
- package/lib/i18n/fr.d.ts +0 -15
- package/lib/i18n/fr.js +0 -99
- package/lib/i18n/he.d.ts +0 -61
- package/lib/i18n/he.js +0 -132
- package/lib/i18n/hr.d.ts +0 -68
- package/lib/i18n/hr.js +0 -129
- package/lib/i18n/hu.d.ts +0 -17
- package/lib/i18n/hu.js +0 -135
- package/lib/i18n/id.d.ts +0 -43
- package/lib/i18n/id.js +0 -156
- package/lib/i18n/it.d.ts +0 -29
- package/lib/i18n/it.js +0 -137
- package/lib/i18n/ko.d.ts +0 -15
- package/lib/i18n/ko.js +0 -56
- package/lib/i18n/lt.js +0 -138
- package/lib/i18n/lv.d.ts +0 -57
- package/lib/i18n/lv.js +0 -120
- package/lib/i18n/nl.d.ts +0 -20
- package/lib/i18n/nl.js +0 -125
- package/lib/i18n/no.d.ts +0 -15
- package/lib/i18n/no.js +0 -77
- package/lib/i18n/pl.js +0 -126
- package/lib/i18n/pt.d.ts +0 -26
- package/lib/i18n/pt.js +0 -118
- package/lib/i18n/ro.d.ts +0 -109
- package/lib/i18n/ro.js +0 -360
- package/lib/i18n/ru.d.ts +0 -30
- package/lib/i18n/ru.js +0 -198
- package/lib/i18n/sr.d.ts +0 -56
- package/lib/i18n/sr.js +0 -127
- package/lib/i18n/tr.d.ts +0 -15
- package/lib/i18n/tr.js +0 -64
- package/lib/i18n/vi.js +0 -151
- package/lib/i18n/zh.d.ts +0 -18
- package/lib/i18n/zh.js +0 -78
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { AbstractLanguage } from '../classes/abstract-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Italian language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Phonetic contractions (vowel elision: "ventotto" not "ventiotto")
|
|
8
|
+
* - Accentuation rules for "tre" in compounds ("ventitré")
|
|
9
|
+
* - Custom word construction for irregular patterns
|
|
10
|
+
*/
|
|
11
|
+
export class Italian extends AbstractLanguage {
|
|
12
|
+
negativeWord = 'meno'
|
|
13
|
+
decimalSeparatorWord = 'virgola'
|
|
14
|
+
zeroWord = 'zero'
|
|
15
|
+
|
|
16
|
+
onesWords = [
|
|
17
|
+
this.zeroWord, 'uno', 'due', 'tre', 'quattro', 'cinque', 'sei', 'sette', 'otto',
|
|
18
|
+
'nove', 'dieci', 'undici', 'dodici', 'tredici', 'quattordici', 'quindici',
|
|
19
|
+
'sedici', 'diciassette', 'diciotto', 'diciannove'
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
tensWords = { 2: 'venti', 3: 'trenta', 4: 'quaranta', 6: 'sessanta' }
|
|
23
|
+
|
|
24
|
+
exponentPrefixes = [this.zeroWord, 'm', 'b', 'tr', 'quadr', 'quint', 'sest', 'sett', 'ott', 'nov', 'dec']
|
|
25
|
+
|
|
26
|
+
/** Adds accent to final "tre" in compound words (ventitré). */
|
|
27
|
+
accentuate (string) {
|
|
28
|
+
const splittedString = string.split(' ')
|
|
29
|
+
|
|
30
|
+
const result = splittedString.map(word => {
|
|
31
|
+
return word.slice(-3) === 'tre' && word.length > 3 ? word.replaceAll('tré', 'tre').slice(0, -3) + 'tré' : word.replaceAll('tré', 'tre')
|
|
32
|
+
})
|
|
33
|
+
return result.join(' ')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Omits word if it represents zero. */
|
|
37
|
+
omitIfZero (numberToString) {
|
|
38
|
+
return numberToString === this.zeroWord ? '' : numberToString
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Removes duplicate vowels for phonetic contractions. */
|
|
42
|
+
phoneticContraction (string) {
|
|
43
|
+
return string.replaceAll('oo', 'o').replaceAll('ao', 'o').replaceAll('io', 'o').replaceAll('au', 'u').replaceAll('iu', 'u')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Converts tens (20-99) with phonetic contractions. */
|
|
47
|
+
tensToCardinal (number) {
|
|
48
|
+
const tens = Math.floor(number / 10)
|
|
49
|
+
const units = number % 10
|
|
50
|
+
const prefix = Object.prototype.hasOwnProperty.call(this.tensWords, tens) ? this.tensWords[tens] : this.onesWords[tens].slice(0, -1) + 'anta'
|
|
51
|
+
const postfix = this.omitIfZero(this.onesWords[units])
|
|
52
|
+
return this.phoneticContraction(prefix + postfix)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Converts hundreds (100-999) with "cento" composition. */
|
|
56
|
+
hundredsToCardinal (number) {
|
|
57
|
+
const hundreds = Math.floor(number / 100)
|
|
58
|
+
let prefix = 'cento'
|
|
59
|
+
if (hundreds !== 1) {
|
|
60
|
+
prefix = this.onesWords[hundreds] + prefix
|
|
61
|
+
}
|
|
62
|
+
const postfix = this.omitIfZero(this.integerToWords(number % 100))
|
|
63
|
+
return this.phoneticContraction(prefix + postfix)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Converts thousands (1000-999999) with "mille/mila" composition. */
|
|
67
|
+
thousandsToCardinal (number) {
|
|
68
|
+
const thousands = Math.floor(number / 1000)
|
|
69
|
+
const prefix = thousands === 1 ? 'mille' : this.integerToWords(thousands) + 'mila'
|
|
70
|
+
const postfix = this.omitIfZero(this.integerToWords(number % 1000))
|
|
71
|
+
return prefix + postfix
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Converts exponent length to Italian scale word (milione, miliardo, etc.). */
|
|
75
|
+
exponentLengthToString (exponentLength) {
|
|
76
|
+
const prefix = this.exponentPrefixes[Math.floor(exponentLength / 6)]
|
|
77
|
+
return exponentLength % 6 === 0 ? prefix + 'ilione' : prefix + 'iliardo'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Converts large numbers (millions and above) with exponent-based naming. */
|
|
81
|
+
bigNumberToCardinal (number) {
|
|
82
|
+
const digits = [...number.toString()]
|
|
83
|
+
|
|
84
|
+
let preDigits = digits.length % 3
|
|
85
|
+
if (preDigits === 0) {
|
|
86
|
+
preDigits = 3
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const multiplier = digits.slice(0, preDigits) // first `preDigits` elements
|
|
90
|
+
const exponent = digits.slice(preDigits) // without the first `preDigits` elements
|
|
91
|
+
|
|
92
|
+
let prefix, postfix
|
|
93
|
+
let infix = this.exponentLengthToString(exponent.length)
|
|
94
|
+
|
|
95
|
+
if (multiplier.join('') === '1') {
|
|
96
|
+
prefix = 'un '
|
|
97
|
+
} else {
|
|
98
|
+
prefix = this.integerToWords(Math.trunc(Number(multiplier.join(''))))
|
|
99
|
+
infix = ' ' + infix.slice(0, -1) + 'i' // without last element
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const isSetsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value))
|
|
103
|
+
if (isSetsEqual(new Set(exponent), new Set(['0']))) {
|
|
104
|
+
postfix = ''
|
|
105
|
+
} else {
|
|
106
|
+
postfix = this.integerToWords(Math.trunc(exponent.join('')))
|
|
107
|
+
|
|
108
|
+
infix += (postfix.includes(' e ') ? ', ' : ' e ')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return prefix + infix + postfix
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Converts integer part using Italian custom algorithm with accentuation. */
|
|
115
|
+
integerToWords (integerPart) {
|
|
116
|
+
let words = ''
|
|
117
|
+
|
|
118
|
+
if (integerPart < 20) {
|
|
119
|
+
words = this.onesWords[integerPart]
|
|
120
|
+
} else if (integerPart < 100) {
|
|
121
|
+
words = this.tensToCardinal(Number(integerPart))
|
|
122
|
+
} else if (integerPart < 1000) {
|
|
123
|
+
words = this.hundredsToCardinal(Number(integerPart))
|
|
124
|
+
} else if (integerPart < 1_000_000) {
|
|
125
|
+
words = this.thousandsToCardinal(Number(integerPart))
|
|
126
|
+
} else {
|
|
127
|
+
words = this.bigNumberToCardinal(integerPart)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return this.accentuate(words)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Japanese language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Kanji numerals (一, 二, 三, etc.)
|
|
6
|
+
* - Grouping by 万 (10,000) instead of 1,000
|
|
7
|
+
* - Special 一 (one) omission rules (十, 百, 千 but 一万, 一億)
|
|
8
|
+
*/
|
|
9
|
+
export class Japanese extends AbstractLanguage {
|
|
10
|
+
onesWords: string[];
|
|
11
|
+
scaleWords: string[];
|
|
12
|
+
/** Converts a segment of up to 4 digits to Japanese kanji with 一 omission rules. */
|
|
13
|
+
segmentToWords(num: any): string;
|
|
14
|
+
/** Converts integer part using Japanese 万-based grouping system. */
|
|
15
|
+
integerToWords(integerPart: any): string;
|
|
16
|
+
}
|
|
17
|
+
import { AbstractLanguage } from '../classes/abstract-language.js';
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { AbstractLanguage } from '../classes/abstract-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Japanese language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Kanji numerals (一, 二, 三, etc.)
|
|
8
|
+
* - Grouping by 万 (10,000) instead of 1,000
|
|
9
|
+
* - Special 一 (one) omission rules (十, 百, 千 but 一万, 一億)
|
|
10
|
+
*/
|
|
11
|
+
export class Japanese extends AbstractLanguage {
|
|
12
|
+
negativeWord = 'マイナス'
|
|
13
|
+
decimalSeparatorWord = '点'
|
|
14
|
+
zeroWord = '零'
|
|
15
|
+
wordSeparator = '' // Japanese doesn't use spaces between characters
|
|
16
|
+
usePerDigitDecimals = true // Enable digit-by-digit decimal conversion
|
|
17
|
+
|
|
18
|
+
// Ones words used for group conversion (1-9)
|
|
19
|
+
onesWords = ['一', '二', '三', '四', '五', '六', '七', '八', '九']
|
|
20
|
+
|
|
21
|
+
// Scale words for grouping by 10^4
|
|
22
|
+
scaleWords = [
|
|
23
|
+
'', // 10^0 (ones)
|
|
24
|
+
'万', // 10^4 (man)
|
|
25
|
+
'億', // 10^8 (oku)
|
|
26
|
+
'兆', // 10^12 (chō)
|
|
27
|
+
'京', // 10^16 (kei)
|
|
28
|
+
'垓', // 10^20 (gai)
|
|
29
|
+
'秭', // 10^24 (jo/shi)
|
|
30
|
+
'穣', // 10^28 (jō)
|
|
31
|
+
'溝', // 10^32 (kō)
|
|
32
|
+
'澗', // 10^36 (kan)
|
|
33
|
+
'正', // 10^40 (sei)
|
|
34
|
+
'載', // 10^44 (sai)
|
|
35
|
+
'極', // 10^48 (goku)
|
|
36
|
+
'恒河沙', // 10^52 (gōgasha)
|
|
37
|
+
'阿僧祇', // 10^56 (asōgi)
|
|
38
|
+
'那由他', // 10^60 (nayuta)
|
|
39
|
+
'不可思議', // 10^64 (fukashigi)
|
|
40
|
+
'無量大数' // 10^68 (muryōtaisū)
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
/** Converts a segment of up to 4 digits to Japanese kanji with 一 omission rules. */
|
|
44
|
+
segmentToWords (num) {
|
|
45
|
+
if (num === 0n) return ''
|
|
46
|
+
|
|
47
|
+
const thousands = num / 1000n
|
|
48
|
+
const hundreds = (num % 1000n) / 100n
|
|
49
|
+
const tens = (num % 100n) / 10n
|
|
50
|
+
const ones = num % 10n
|
|
51
|
+
|
|
52
|
+
let result = ''
|
|
53
|
+
|
|
54
|
+
// Thousands (千)
|
|
55
|
+
if (thousands > 0n) {
|
|
56
|
+
// Always omit 一 before 千 when thousands === 1
|
|
57
|
+
if (thousands === 1n) {
|
|
58
|
+
result += '千'
|
|
59
|
+
} else {
|
|
60
|
+
result += this.onesWords[Number(thousands) - 1] + '千'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Hundreds (百)
|
|
65
|
+
if (hundreds > 0n) {
|
|
66
|
+
// Always omit 一 before 百 when hundreds === 1
|
|
67
|
+
if (hundreds === 1n) {
|
|
68
|
+
result += '百'
|
|
69
|
+
} else {
|
|
70
|
+
result += this.onesWords[Number(hundreds) - 1] + '百'
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Tens (十)
|
|
75
|
+
if (tens > 0n) {
|
|
76
|
+
// Always omit 一 before 十 when tens === 1
|
|
77
|
+
if (tens === 1n) {
|
|
78
|
+
result += '十'
|
|
79
|
+
} else {
|
|
80
|
+
result += this.onesWords[Number(tens) - 1] + '十'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Ones
|
|
85
|
+
if (ones > 0n) {
|
|
86
|
+
result += this.onesWords[Number(ones) - 1]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return result
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Converts integer part using Japanese 万-based grouping system. */
|
|
93
|
+
integerToWords (integerPart) {
|
|
94
|
+
if (integerPart === 0n) {
|
|
95
|
+
return this.zeroWord
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let temp = integerPart
|
|
99
|
+
let scaleIndex = 0
|
|
100
|
+
const groups = []
|
|
101
|
+
|
|
102
|
+
// Split into groups of 4 digits (万-based system)
|
|
103
|
+
while (temp > 0n) {
|
|
104
|
+
const group = temp % 10000n
|
|
105
|
+
if (group > 0n) {
|
|
106
|
+
groups.push({ value: group, scale: scaleIndex })
|
|
107
|
+
}
|
|
108
|
+
temp = temp / 10000n
|
|
109
|
+
scaleIndex++
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Reverse to process from highest to lowest
|
|
113
|
+
groups.reverse()
|
|
114
|
+
|
|
115
|
+
let result = ''
|
|
116
|
+
|
|
117
|
+
for (let i = 0; i < groups.length; i++) {
|
|
118
|
+
const { value, scale } = groups[i]
|
|
119
|
+
|
|
120
|
+
const groupStr = this.segmentToWords(value)
|
|
121
|
+
|
|
122
|
+
// For scales >= 1 (万 and above), always add the scale word
|
|
123
|
+
if (scale >= 1) {
|
|
124
|
+
// Special case: if group is 1 and scale >= 1, we need 一 before the scale
|
|
125
|
+
if (value === 1n) {
|
|
126
|
+
result += '一' + this.scaleWords[scale]
|
|
127
|
+
} else {
|
|
128
|
+
result += groupStr + this.scaleWords[scale]
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
result += groupStr
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return result
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kannada language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Indian numbering system (ಸಾವಿರ, ಲಕ್ಷ, ಕೋಟಿ)
|
|
6
|
+
* - Kannada script
|
|
7
|
+
* - Complete word forms for 0-99
|
|
8
|
+
*/
|
|
9
|
+
export class Kannada extends SouthAsianLanguage {
|
|
10
|
+
}
|
|
11
|
+
import { SouthAsianLanguage } from '../classes/south-asian-language.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SouthAsianLanguage } from '../classes/south-asian-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Kannada language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Indian numbering system (ಸಾವಿರ, ಲಕ್ಷ, ಕೋಟಿ)
|
|
8
|
+
* - Kannada script
|
|
9
|
+
* - Complete word forms for 0-99
|
|
10
|
+
*/
|
|
11
|
+
export class Kannada extends SouthAsianLanguage {
|
|
12
|
+
negativeWord = 'ಋಣಾತ್ಮಕ'
|
|
13
|
+
decimalSeparatorWord = 'ದಶಮಾಂಶ'
|
|
14
|
+
zeroWord = 'ಸೊನ್ನೆ'
|
|
15
|
+
hundredWord = 'ನೂರು'
|
|
16
|
+
usePerDigitDecimals = true
|
|
17
|
+
|
|
18
|
+
belowHundredWords = [
|
|
19
|
+
'ಸೊನ್ನೆ', 'ಒಂದು', 'ಎರಡು', 'ಮೂರು', 'ನಾಲ್ಕು', 'ಐದು', 'ಆರು', 'ಏಳು', 'ಎಂಟು', 'ಒಂಬತ್ತು',
|
|
20
|
+
'ಹತ್ತು', 'ಹನ್ನೊಂದು', 'ಹನ್ನೆರಡು', 'ಹದಿಮೂರು', 'ಹದಿನಾಲ್ಕು', 'ಹದಿನೈದು', 'ಹದಿನಾರು', 'ಹದಿನೇಳು', 'ಹದಿನೆಂಟು', 'ಹತ್ತೊಂಬತ್ತು',
|
|
21
|
+
'ಇಪ್ಪತ್ತು', 'ಇಪ್ಪತ್ತೊಂದು', 'ಇಪ್ಪತ್ತೆರಡು', 'ಇಪ್ಪತ್ತಮೂರು', 'ಇಪ್ಪತ್ತನಾಲ್ಕು', 'ಇಪ್ಪತ್ತೈದು', 'ಇಪ್ಪತ್ತಾರು', 'ಇಪ್ಪತ್ತೇಳು', 'ಇಪ್ಪತ್ತೆಂಟು', 'ಇಪ್ಪತ್ತೊಂಬತ್ತು',
|
|
22
|
+
'ಮೂವತ್ತು', 'ಮೂವತ್ತೊಂದು', 'ಮೂವತ್ತೆರಡು', 'ಮೂವತ್ತಮೂರು', 'ಮೂವತ್ತನಾಲ್ಕು', 'ಮೂವತ್ತೈದು', 'ಮೂವತ್ತಾರು', 'ಮೂವತ್ತೇಳು', 'ಮೂವತ್ತೆಂಟು', 'ಮೂವತ್ತೊಂಬತ್ತು',
|
|
23
|
+
'ನಲವತ್ತು', 'ನಲವತ್ತೊಂದು', 'ನಲವತ್ತೆರಡು', 'ನಲವತ್ತಮೂರು', 'ನಲವತ್ತನಾಲ್ಕು', 'ನಲವತ್ತೈದು', 'ನಲವತ್ತಾರು', 'ನಲವತ್ತೇಳು', 'ನಲವತ್ತೆಂಟು', 'ನಲವತ್ತೊಂಬತ್ತು',
|
|
24
|
+
'ಐವತ್ತು', 'ಐವತ್ತೊಂದು', 'ಐವತ್ತೆರಡು', 'ಐವತ್ತಮೂರು', 'ಐವತ್ತನಾಲ್ಕು', 'ಐವತ್ತೈದು', 'ಐವತ್ತಾರು', 'ಐವತ್ತೇಳು', 'ಐವತ್ತೆಂಟು', 'ಐವತ್ತೊಂಬತ್ತು',
|
|
25
|
+
'ಅರವತ್ತು', 'ಅರವತ್ತೊಂದು', 'ಅರವತ್ತೆರಡು', 'ಅರವತ್ತಮೂರು', 'ಅರವತ್ತನಾಲ್ಕು', 'ಅರವತ್ತೈದು', 'ಅರವತ್ತಾರು', 'ಅರವತ್ತೇಳು', 'ಅರವತ್ತೆಂಟು', 'ಅರವತ್ತೊಂಬತ್ತು',
|
|
26
|
+
'ಎಪ್ಪತ್ತು', 'ಎಪ್ಪತ್ತೊಂದು', 'ಎಪ್ಪತ್ತೆರಡು', 'ಎಪ್ಪತ್ತಮೂರು', 'ಎಪ್ಪತ್ತನಾಲ್ಕು', 'ಎಪ್ಪತ್ತೈದು', 'ಎಪ್ಪತ್ತಾರು', 'ಎಪ್ಪತ್ತೇಳು', 'ಎಪ್ಪತ್ತೆಂಟು', 'ಎಪ್ಪತ್ತೊಂಬತ್ತು',
|
|
27
|
+
'ಎಂಬತ್ತು', 'ಎಂಬತ್ತೊಂದು', 'ಎಂಬತ್ತೆರಡು', 'ಎಂಬತ್ತಮೂರು', 'ಎಂಬತ್ತನಾಲ್ಕು', 'ಎಂಬತ್ತೈದು', 'ಎಂಬತ್ತಾರು', 'ಎಂಬತ್ತೇಳು', 'ಎಂಬತ್ತೆಂಟು', 'ಎಂಬತ್ತೊಂಬತ್ತು',
|
|
28
|
+
'ತೊಂಬತ್ತು', 'ತೊಂಬತ್ತೊಂದು', 'ತೊಂಬತ್ತೆರಡು', 'ತೊಂಬತ್ತಮೂರು', 'ತೊಂಬತ್ತನಾಲ್ಕು', 'ತೊಂಬತ್ತೈದು', 'ತೊಂಬತ್ತಾರು', 'ತೊಂಬತ್ತೇಳು', 'ತೊಂಬತ್ತೆಂಟು', 'ತೊಂಬತ್ತೊಂಬತ್ತು'
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
scaleWords = [
|
|
32
|
+
'', // units
|
|
33
|
+
'ಸಾವಿರ', // thousand (1,000)
|
|
34
|
+
'ಲಕ್ಷ', // lakh (100,000)
|
|
35
|
+
'ಕೋಟಿ', // crore (10,000,000)
|
|
36
|
+
'ಅಬ್ಜ', // arab (1,000,000,000)
|
|
37
|
+
'ಖರ್ವ', // kharab (100,000,000,000)
|
|
38
|
+
'ನೀಲ', // neel (10,000,000,000,000)
|
|
39
|
+
'ಪದ್ಮ', // padma (1,000,000,000,000,000)
|
|
40
|
+
'ಶಂಖ' // shankh (100,000,000,000,000,000)
|
|
41
|
+
]
|
|
42
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Korean language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Hangul numerals (일, 이, 삼, etc.)
|
|
6
|
+
* - Grouping by 만 (10,000) system
|
|
7
|
+
* - Implicit '일' (one) omission before multipliers
|
|
8
|
+
*/
|
|
9
|
+
export class Korean extends GreedyScaleLanguage {
|
|
10
|
+
scaleWords: (string | bigint)[][];
|
|
11
|
+
/** Combines two word-sets according to Korean grammar rules. */
|
|
12
|
+
combineWordSets(preceding: any, following: any): any;
|
|
13
|
+
}
|
|
14
|
+
import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Korean language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Hangul numerals (일, 이, 삼, etc.)
|
|
8
|
+
* - Grouping by 만 (10,000) system
|
|
9
|
+
* - Implicit '일' (one) omission before multipliers
|
|
10
|
+
*/
|
|
11
|
+
export class Korean extends GreedyScaleLanguage {
|
|
12
|
+
negativeWord = '마이너스'
|
|
13
|
+
decimalSeparatorWord = '점'
|
|
14
|
+
zeroWord = '영'
|
|
15
|
+
|
|
16
|
+
scaleWords = [
|
|
17
|
+
[10_000_000_000_000_000_000_000_000_000n, '양'],
|
|
18
|
+
[1_000_000_000_000_000_000_000_000n, '자'],
|
|
19
|
+
[100_000_000_000_000_000_000n, '해'],
|
|
20
|
+
[10_000_000_000_000_000n, '경'],
|
|
21
|
+
[1_000_000_000_000n, '조'],
|
|
22
|
+
[100_000_000n, '억'],
|
|
23
|
+
[10_000n, '만'],
|
|
24
|
+
[1000n, '천'],
|
|
25
|
+
[100n, '백'],
|
|
26
|
+
[10n, '십'],
|
|
27
|
+
[9n, '구'],
|
|
28
|
+
[8n, '팔'],
|
|
29
|
+
[7n, '칠'],
|
|
30
|
+
[6n, '육'],
|
|
31
|
+
[5n, '오'],
|
|
32
|
+
[4n, '사'],
|
|
33
|
+
[3n, '삼'],
|
|
34
|
+
[2n, '이'],
|
|
35
|
+
[1n, '일'],
|
|
36
|
+
[0n, '영']
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
/** Combines two word-sets according to Korean grammar rules. */
|
|
40
|
+
combineWordSets (preceding, following) {
|
|
41
|
+
const precedingWord = Object.keys(preceding)[0]
|
|
42
|
+
const followingWord = Object.keys(following)[0]
|
|
43
|
+
const precedingValue = Object.values(preceding)[0] // BigInt
|
|
44
|
+
const followingValue = Object.values(following)[0] // BigInt
|
|
45
|
+
|
|
46
|
+
// Implicit "일": omit 1 before multipliers up to 만 (10,000)
|
|
47
|
+
if (precedingValue === 1n && followingValue <= 10_000n) return following
|
|
48
|
+
// Concatenate (no space) for small numbers less than 만
|
|
49
|
+
if (precedingValue < 10_000n && precedingValue > followingValue) return { [`${precedingWord}${followingWord}`]: precedingValue + followingValue }
|
|
50
|
+
// Space-separate for large numbers (>= 만) when adding
|
|
51
|
+
if (precedingValue >= 10_000n && precedingValue > followingValue) return { [`${precedingWord} ${followingWord}`]: precedingValue + followingValue }
|
|
52
|
+
// Multiply for all scale combinations
|
|
53
|
+
return { [`${precedingWord}${followingWord}`]: precedingValue * followingValue }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Lithuanian language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Three-form pluralization (one/few/many)
|
|
6
|
+
* - Gender agreement (vienas/viena, du/dvi)
|
|
7
|
+
* - Baltic declension patterns
|
|
7
8
|
*/
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
ones: {
|
|
9
|
+
export class Lithuanian extends SlavicLanguage {
|
|
10
|
+
onesWords: {
|
|
11
11
|
1: string;
|
|
12
12
|
2: string;
|
|
13
13
|
3: string;
|
|
@@ -18,8 +18,7 @@ export class N2WordsPL extends N2WordsRU {
|
|
|
18
18
|
8: string;
|
|
19
19
|
9: string;
|
|
20
20
|
};
|
|
21
|
-
|
|
22
|
-
0: string;
|
|
21
|
+
onesFeminineWords: {
|
|
23
22
|
1: string;
|
|
24
23
|
2: string;
|
|
25
24
|
3: string;
|
|
@@ -30,7 +29,9 @@ export class N2WordsPL extends N2WordsRU {
|
|
|
30
29
|
8: string;
|
|
31
30
|
9: string;
|
|
32
31
|
};
|
|
33
|
-
|
|
32
|
+
teensWords: {
|
|
33
|
+
0: string;
|
|
34
|
+
1: string;
|
|
34
35
|
2: string;
|
|
35
36
|
3: string;
|
|
36
37
|
4: string;
|
|
@@ -40,8 +41,7 @@ export class N2WordsPL extends N2WordsRU {
|
|
|
40
41
|
8: string;
|
|
41
42
|
9: string;
|
|
42
43
|
};
|
|
43
|
-
|
|
44
|
-
1: string;
|
|
44
|
+
twentiesWords: {
|
|
45
45
|
2: string;
|
|
46
46
|
3: string;
|
|
47
47
|
4: string;
|
|
@@ -51,7 +51,8 @@ export class N2WordsPL extends N2WordsRU {
|
|
|
51
51
|
8: string;
|
|
52
52
|
9: string;
|
|
53
53
|
};
|
|
54
|
-
|
|
54
|
+
hundredsWords: string[];
|
|
55
|
+
pluralForms: {
|
|
55
56
|
1: string[];
|
|
56
57
|
2: string[];
|
|
57
58
|
3: string[];
|
|
@@ -63,5 +64,7 @@ export class N2WordsPL extends N2WordsRU {
|
|
|
63
64
|
9: string[];
|
|
64
65
|
10: string[];
|
|
65
66
|
};
|
|
67
|
+
pluralize(n: any, forms: any): any;
|
|
68
|
+
integerToWords(integerPart: any): string;
|
|
66
69
|
}
|
|
67
|
-
import {
|
|
70
|
+
import { SlavicLanguage } from '../classes/slavic-language.js';
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { SlavicLanguage } from '../classes/slavic-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Lithuanian language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Three-form pluralization (one/few/many)
|
|
8
|
+
* - Gender agreement (vienas/viena, du/dvi)
|
|
9
|
+
* - Baltic declension patterns
|
|
10
|
+
*/
|
|
11
|
+
export class Lithuanian extends SlavicLanguage {
|
|
12
|
+
negativeWord = 'minus'
|
|
13
|
+
decimalSeparatorWord = 'kablelis'
|
|
14
|
+
zeroWord = 'nulis'
|
|
15
|
+
|
|
16
|
+
onesWords = {
|
|
17
|
+
1: 'vienas',
|
|
18
|
+
2: 'du',
|
|
19
|
+
3: 'trys',
|
|
20
|
+
4: 'keturi',
|
|
21
|
+
5: 'penki',
|
|
22
|
+
6: 'šeši',
|
|
23
|
+
7: 'septyni',
|
|
24
|
+
8: 'aštuoni',
|
|
25
|
+
9: 'devyni'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
onesFeminineWords = {
|
|
29
|
+
1: 'viena',
|
|
30
|
+
2: 'dvi',
|
|
31
|
+
3: 'trys',
|
|
32
|
+
4: 'keturios',
|
|
33
|
+
5: 'penkios',
|
|
34
|
+
6: 'šešios',
|
|
35
|
+
7: 'septynios',
|
|
36
|
+
8: 'aštuonios',
|
|
37
|
+
9: 'devynios'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
teensWords = {
|
|
41
|
+
0: 'dešimt',
|
|
42
|
+
1: 'vienuolika',
|
|
43
|
+
2: 'dvylika',
|
|
44
|
+
3: 'trylika',
|
|
45
|
+
4: 'keturiolika',
|
|
46
|
+
5: 'penkiolika',
|
|
47
|
+
6: 'šešiolika',
|
|
48
|
+
7: 'septyniolika',
|
|
49
|
+
8: 'aštuoniolika',
|
|
50
|
+
9: 'devyniolika'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
twentiesWords = {
|
|
54
|
+
2: 'dvidešimt',
|
|
55
|
+
3: 'trisdešimt',
|
|
56
|
+
4: 'keturiasdešimt',
|
|
57
|
+
5: 'penkiasdešimt',
|
|
58
|
+
6: 'šešiasdešimt',
|
|
59
|
+
7: 'septyniasdešimt',
|
|
60
|
+
8: 'aštuoniasdešimt',
|
|
61
|
+
9: 'devyniasdešimt'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
hundredsWords = ['šimtas', 'šimtai']
|
|
65
|
+
|
|
66
|
+
pluralForms = {
|
|
67
|
+
1: ['tūkstantis', 'tūkstančiai', 'tūkstančių'],
|
|
68
|
+
2: ['milijonas', 'milijonai', 'milijonų'],
|
|
69
|
+
3: ['milijardas', 'milijardai', 'milijardų'],
|
|
70
|
+
4: ['trilijonas', 'trilijonai', 'trilijonų'],
|
|
71
|
+
5: ['kvadrilijonas', 'kvadrilijonai', 'kvadrilijonų'],
|
|
72
|
+
6: ['kvintilijonas', 'kvintilijonai', 'kvintilijonų'],
|
|
73
|
+
7: ['sikstilijonas', 'sikstilijonai', 'sikstilijonų'],
|
|
74
|
+
8: ['septilijonas', 'septilijonai', 'septilijonų'],
|
|
75
|
+
9: ['oktilijonas', 'oktilijonai', 'oktilijonų'],
|
|
76
|
+
10: ['naintilijonas', 'naintilijonai', 'naintilijonų']
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
pluralize (n, forms) {
|
|
80
|
+
if (n === 0n) {
|
|
81
|
+
return forms[2]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const [n1, n2] = this.extractDigits(n)
|
|
85
|
+
|
|
86
|
+
if (n2 === 1n || n1 === 0n) {
|
|
87
|
+
return forms[2]
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (n1 === 1n) {
|
|
91
|
+
return forms[0]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return forms[1]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
integerToWords (integerPart) {
|
|
98
|
+
if (integerPart === 0n) {
|
|
99
|
+
return this.zeroWord
|
|
100
|
+
}
|
|
101
|
+
const words = []
|
|
102
|
+
const segments = this.splitToSegments(integerPart.toString(), 3)
|
|
103
|
+
let index = segments.length
|
|
104
|
+
for (const x of segments) {
|
|
105
|
+
index = index - 1
|
|
106
|
+
if (x === 0n) {
|
|
107
|
+
continue
|
|
108
|
+
}
|
|
109
|
+
const [n1, n2, n3] = this.extractDigits(x)
|
|
110
|
+
if (n3 > 0n) {
|
|
111
|
+
words.push(this.onesWords[n3])
|
|
112
|
+
if (n3 > 1n) {
|
|
113
|
+
words.push(this.hundredsWords[1])
|
|
114
|
+
} else {
|
|
115
|
+
words.push(this.hundredsWords[0])
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (n2 > 1n) {
|
|
119
|
+
words.push(this.twentiesWords[n2])
|
|
120
|
+
}
|
|
121
|
+
if (n2 === 1n) {
|
|
122
|
+
words.push(this.teensWords[n1])
|
|
123
|
+
} else if (n1 > 0n) {
|
|
124
|
+
if ((index === 1 || (this.options.gender === 'feminine' && index === 0)) && integerPart < 1000n) {
|
|
125
|
+
words.push(this.onesFeminineWords[n1])
|
|
126
|
+
} else {
|
|
127
|
+
words.push(this.onesWords[n1])
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (index > 0) {
|
|
131
|
+
words.push(this.pluralize(x, this.pluralForms[index]))
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return words.join(' ')
|
|
135
|
+
}
|
|
136
|
+
}
|