1package nnh
2
3import (
4	"math"
5	"strconv"
6	"time"
7
8	"github.com/go-playground/locales"
9	"github.com/go-playground/locales/currency"
10)
11
12type nnh struct {
13	locale                 string
14	pluralsCardinal        []locales.PluralRule
15	pluralsOrdinal         []locales.PluralRule
16	pluralsRange           []locales.PluralRule
17	decimal                string
18	group                  string
19	minus                  string
20	percent                string
21	perMille               string
22	timeSeparator          string
23	inifinity              string
24	currencies             []string // idx = enum of currency code
25	currencyPositivePrefix string
26	currencyNegativePrefix string
27	monthsAbbreviated      []string
28	monthsNarrow           []string
29	monthsWide             []string
30	daysAbbreviated        []string
31	daysNarrow             []string
32	daysShort              []string
33	daysWide               []string
34	periodsAbbreviated     []string
35	periodsNarrow          []string
36	periodsShort           []string
37	periodsWide            []string
38	erasAbbreviated        []string
39	erasNarrow             []string
40	erasWide               []string
41	timezones              map[string]string
42}
43
44// New returns a new instance of translator for the 'nnh' locale
45func New() locales.Translator {
46	return &nnh{
47		locale:                 "nnh",
48		pluralsCardinal:        []locales.PluralRule{2, 6},
49		pluralsOrdinal:         nil,
50		pluralsRange:           nil,
51		decimal:                ",",
52		group:                  ".",
53		percent:                "%",
54		timeSeparator:          ":",
55		currencies:             []string{"ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK", "AON", "AOR", "ARA", "ARL", "ARM", "ARP", "ARS", "ATS", "AUD", "AWG", "AZM", "AZN", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF", "BEL", "BGL", "BGM", "BGN", "BGO", "BHD", "BIF", "BMD", "BND", "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ", "BSD", "BTN", "BUK", "BWP", "BYB", "BYN", "BYR", "BZD", "CAD", "CDF", "CHE", "CHF", "CHW", "CLE", "CLF", "CLP", "CNH", "CNX", "CNY", "COP", "COU", "CRC", "CSD", "CSK", "CUC", "CUP", "CVE", "CYP", "CZK", "DDM", "DEM", "DJF", "DKK", "DOP", "DZD", "ECS", "ECV", "EEK", "EGP", "ERN", "ESA", "ESB", "ESP", "ETB", "EUR", "FIM", "FJD", "FKP", "FRF", "GBP", "GEK", "GEL", "GHC", "GHS", "GIP", "GMD", "GNF", "GNS", "GQE", "GRD", "GTQ", "GWE", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IDR", "IEP", "ILP", "ILR", "ILS", "INR", "IQD", "IRR", "ISJ", "ISK", "ITL", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LTT", "LUC", "LUF", "LUL", "LVL", "LVR", "LYD", "MAD", "MAF", "MCF", "MDC", "MDL", "MGA", "MGF", "MKD", "MKN", "MLF", "MMK", "MNT", "MOP", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MXN", "MXP", "MXV", "MYR", "MZE", "MZM", "MZN", "NAD", "NGN", "NIC", "NIO", "NLG", "NOK", "NPR", "NZD", "OMR", "PAB", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLZ", "PTE", "PYG", "QAR", "RHD", "ROL", "RON", "RSD", "RUB", "RUR", "RWF", "SAR", "SBD", "SCR", "SDD", "SDG", "SDP", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRD", "SRG", "SSP", "STD", "STN", "SUR", "SVC", "SYP", "SZL", "THB", "TJR", "TJS", "TMM", "TMT", "TND", "TOP", "TPE", "TRL", "TRY", "TTD", "TWD", "TZS", "UAH", "UAK", "UGS", "UGX", "USD", "USN", "USS", "UYI", "UYP", "UYU", "UZS", "VEB", "VEF", "VND", "VNN", "VUV", "WST", "FCFA", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XEU", "XFO", "XFU", "XOF", "XPD", "XPF", "XPT", "XRE", "XSU", "XTS", "XUA", "XXX", "YDD", "YER", "YUD", "YUM", "YUN", "YUR", "ZAL", "ZAR", "ZMK", "ZMW", "ZRN", "ZRZ", "ZWD", "ZWL", "ZWR"},
56		currencyPositivePrefix: " ",
57		currencyNegativePrefix: " ",
58		monthsAbbreviated:      []string{"", "saŋ tsetsɛ̀ɛ lùm", "saŋ kàg ngwóŋ", "saŋ lepyè shúm", "saŋ cÿó", "saŋ tsɛ̀ɛ cÿó", "saŋ njÿoláʼ", "saŋ tyɛ̀b tyɛ̀b mbʉ̀ŋ", "saŋ mbʉ̀ŋ", "saŋ ngwɔ̀ʼ mbÿɛ", "saŋ tàŋa tsetsáʼ", "saŋ mejwoŋó", "saŋ lùm"},
59		monthsWide:             []string{"", "saŋ tsetsɛ̀ɛ lùm", "saŋ kàg ngwóŋ", "saŋ lepyè shúm", "saŋ cÿó", "saŋ tsɛ̀ɛ cÿó", "saŋ njÿoláʼ", "saŋ tyɛ̀b tyɛ̀b mbʉ̀ŋ", "saŋ mbʉ̀ŋ", "saŋ ngwɔ̀ʼ mbÿɛ", "saŋ tàŋa tsetsáʼ", "saŋ mejwoŋó", "saŋ lùm"},
60		daysAbbreviated:        []string{"lyɛʼɛ́ sẅíŋtè", "mvfò lyɛ̌ʼ", "mbɔ́ɔntè mvfò lyɛ̌ʼ", "tsètsɛ̀ɛ lyɛ̌ʼ", "mbɔ́ɔntè tsetsɛ̀ɛ lyɛ̌ʼ", "mvfò màga lyɛ̌ʼ", "màga lyɛ̌ʼ"},
61		daysShort:              []string{"lyɛʼɛ́ sẅíŋtè", "mvfò lyɛ̌ʼ", "mbɔ́ɔntè mvfò lyɛ̌ʼ", "tsètsɛ̀ɛ lyɛ̌ʼ", "mbɔ́ɔntè tsetsɛ̀ɛ lyɛ̌ʼ", "mvfò màga lyɛ̌ʼ", "màga lyɛ̌ʼ"},
62		daysWide:               []string{"lyɛʼɛ́ sẅíŋtè", "mvfò lyɛ̌ʼ", "mbɔ́ɔntè mvfò lyɛ̌ʼ", "tsètsɛ̀ɛ lyɛ̌ʼ", "mbɔ́ɔntè tsetsɛ̀ɛ lyɛ̌ʼ", "mvfò màga lyɛ̌ʼ", "màga lyɛ̌ʼ"},
63		periodsAbbreviated:     []string{"mbaʼámbaʼ", "ncwònzém"},
64		periodsWide:            []string{"mbaʼámbaʼ", "ncwònzém"},
65		erasAbbreviated:        []string{"m.z.Y.", "m.g.n.Y."},
66		erasNarrow:             []string{"", ""},
67		erasWide:               []string{"mé zyé Yěsô", "mé gÿo ńzyé Yěsô"},
68		timezones:              map[string]string{"CHADT": "CHADT", "AEDT": "AEDT", "WAT": "WAT", "TMT": "TMT", "∅∅∅": "∅∅∅", "WARST": "WARST", "HNNOMX": "HNNOMX", "CLT": "CLT", "HAST": "HAST", "CHAST": "CHAST", "MESZ": "MESZ", "LHST": "LHST", "ART": "ART", "PST": "PST", "MEZ": "MEZ", "TMST": "TMST", "HNCU": "HNCU", "CST": "CST", "AWST": "AWST", "AEST": "AEST", "ECT": "ECT", "HADT": "HADT", "ADT": "ADT", "WESZ": "WESZ", "NZST": "NZST", "HEEG": "HEEG", "ACWDT": "ACWDT", "HENOMX": "HENOMX", "ARST": "ARST", "JST": "JST", "EDT": "EDT", "HNEG": "HNEG", "HNOG": "HNOG", "HNT": "HNT", "VET": "VET", "HNPM": "HNPM", "WITA": "WITA", "SRT": "SRT", "AKDT": "AKDT", "MYT": "MYT", "UYST": "UYST", "WIT": "WIT", "CDT": "CDT", "BOT": "BOT", "MDT": "MDT", "OESZ": "OESZ", "ChST": "ChST", "HNPMX": "HNPMX", "JDT": "JDT", "BT": "BT", "CAT": "CAT", "LHDT": "LHDT", "WART": "WART", "CLST": "CLST", "COST": "COST", "GYT": "GYT", "HECU": "HECU", "SGT": "SGT", "IST": "IST", "EAT": "EAT", "AWDT": "AWDT", "AST": "AST", "WEZ": "WEZ", "ACDT": "ACDT", "OEZ": "OEZ", "GMT": "GMT", "AKST": "AKST", "COT": "COT", "NZDT": "NZDT", "HKT": "HKT", "ACWST": "ACWST", "HKST": "HKST", "HEPM": "HEPM", "PDT": "PDT", "HEPMX": "HEPMX", "ACST": "ACST", "HEOG": "HEOG", "HAT": "HAT", "UYT": "UYT", "SAST": "SAST", "GFT": "GFT", "EST": "EST", "WAST": "WAST", "WIB": "WIB", "MST": "MST"},
69	}
70}
71
72// Locale returns the current translators string locale
73func (nnh *nnh) Locale() string {
74	return nnh.locale
75}
76
77// PluralsCardinal returns the list of cardinal plural rules associated with 'nnh'
78func (nnh *nnh) PluralsCardinal() []locales.PluralRule {
79	return nnh.pluralsCardinal
80}
81
82// PluralsOrdinal returns the list of ordinal plural rules associated with 'nnh'
83func (nnh *nnh) PluralsOrdinal() []locales.PluralRule {
84	return nnh.pluralsOrdinal
85}
86
87// PluralsRange returns the list of range plural rules associated with 'nnh'
88func (nnh *nnh) PluralsRange() []locales.PluralRule {
89	return nnh.pluralsRange
90}
91
92// CardinalPluralRule returns the cardinal PluralRule given 'num' and digits/precision of 'v' for 'nnh'
93func (nnh *nnh) CardinalPluralRule(num float64, v uint64) locales.PluralRule {
94
95	n := math.Abs(num)
96
97	if n == 1 {
98		return locales.PluralRuleOne
99	}
100
101	return locales.PluralRuleOther
102}
103
104// OrdinalPluralRule returns the ordinal PluralRule given 'num' and digits/precision of 'v' for 'nnh'
105func (nnh *nnh) OrdinalPluralRule(num float64, v uint64) locales.PluralRule {
106	return locales.PluralRuleUnknown
107}
108
109// RangePluralRule returns the ordinal PluralRule given 'num1', 'num2' and digits/precision of 'v1' and 'v2' for 'nnh'
110func (nnh *nnh) RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) locales.PluralRule {
111	return locales.PluralRuleUnknown
112}
113
114// MonthAbbreviated returns the locales abbreviated month given the 'month' provided
115func (nnh *nnh) MonthAbbreviated(month time.Month) string {
116	return nnh.monthsAbbreviated[month]
117}
118
119// MonthsAbbreviated returns the locales abbreviated months
120func (nnh *nnh) MonthsAbbreviated() []string {
121	return nnh.monthsAbbreviated[1:]
122}
123
124// MonthNarrow returns the locales narrow month given the 'month' provided
125func (nnh *nnh) MonthNarrow(month time.Month) string {
126	return nnh.monthsNarrow[month]
127}
128
129// MonthsNarrow returns the locales narrow months
130func (nnh *nnh) MonthsNarrow() []string {
131	return nil
132}
133
134// MonthWide returns the locales wide month given the 'month' provided
135func (nnh *nnh) MonthWide(month time.Month) string {
136	return nnh.monthsWide[month]
137}
138
139// MonthsWide returns the locales wide months
140func (nnh *nnh) MonthsWide() []string {
141	return nnh.monthsWide[1:]
142}
143
144// WeekdayAbbreviated returns the locales abbreviated weekday given the 'weekday' provided
145func (nnh *nnh) WeekdayAbbreviated(weekday time.Weekday) string {
146	return nnh.daysAbbreviated[weekday]
147}
148
149// WeekdaysAbbreviated returns the locales abbreviated weekdays
150func (nnh *nnh) WeekdaysAbbreviated() []string {
151	return nnh.daysAbbreviated
152}
153
154// WeekdayNarrow returns the locales narrow weekday given the 'weekday' provided
155func (nnh *nnh) WeekdayNarrow(weekday time.Weekday) string {
156	return nnh.daysNarrow[weekday]
157}
158
159// WeekdaysNarrow returns the locales narrow weekdays
160func (nnh *nnh) WeekdaysNarrow() []string {
161	return nnh.daysNarrow
162}
163
164// WeekdayShort returns the locales short weekday given the 'weekday' provided
165func (nnh *nnh) WeekdayShort(weekday time.Weekday) string {
166	return nnh.daysShort[weekday]
167}
168
169// WeekdaysShort returns the locales short weekdays
170func (nnh *nnh) WeekdaysShort() []string {
171	return nnh.daysShort
172}
173
174// WeekdayWide returns the locales wide weekday given the 'weekday' provided
175func (nnh *nnh) WeekdayWide(weekday time.Weekday) string {
176	return nnh.daysWide[weekday]
177}
178
179// WeekdaysWide returns the locales wide weekdays
180func (nnh *nnh) WeekdaysWide() []string {
181	return nnh.daysWide
182}
183
184// Decimal returns the decimal point of number
185func (nnh *nnh) Decimal() string {
186	return nnh.decimal
187}
188
189// Group returns the group of number
190func (nnh *nnh) Group() string {
191	return nnh.group
192}
193
194// Group returns the minus sign of number
195func (nnh *nnh) Minus() string {
196	return nnh.minus
197}
198
199// FmtNumber returns 'num' with digits/precision of 'v' for 'nnh' and handles both Whole and Real numbers based on 'v'
200func (nnh *nnh) FmtNumber(num float64, v uint64) string {
201
202	s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
203	l := len(s) + 1 + 1*len(s[:len(s)-int(v)-1])/3
204	count := 0
205	inWhole := v == 0
206	b := make([]byte, 0, l)
207
208	for i := len(s) - 1; i >= 0; i-- {
209
210		if s[i] == '.' {
211			b = append(b, nnh.decimal[0])
212			inWhole = true
213			continue
214		}
215
216		if inWhole {
217			if count == 3 {
218				b = append(b, nnh.group[0])
219				count = 1
220			} else {
221				count++
222			}
223		}
224
225		b = append(b, s[i])
226	}
227
228	if num < 0 {
229		b = append(b, nnh.minus[0])
230	}
231
232	// reverse
233	for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
234		b[i], b[j] = b[j], b[i]
235	}
236
237	return string(b)
238}
239
240// FmtPercent returns 'num' with digits/precision of 'v' for 'nnh' and handles both Whole and Real numbers based on 'v'
241// NOTE: 'num' passed into FmtPercent is assumed to be in percent already
242func (nnh *nnh) FmtPercent(num float64, v uint64) string {
243	return strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
244}
245
246// FmtCurrency returns the currency representation of 'num' with digits/precision of 'v' for 'nnh'
247func (nnh *nnh) FmtCurrency(num float64, v uint64, currency currency.Type) string {
248
249	s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
250	symbol := nnh.currencies[currency]
251	l := len(s) + len(symbol) + 3 + 1*len(s[:len(s)-int(v)-1])/3
252	count := 0
253	inWhole := v == 0
254	b := make([]byte, 0, l)
255
256	for i := len(s) - 1; i >= 0; i-- {
257
258		if s[i] == '.' {
259			b = append(b, nnh.decimal[0])
260			inWhole = true
261			continue
262		}
263
264		if inWhole {
265			if count == 3 {
266				b = append(b, nnh.group[0])
267				count = 1
268			} else {
269				count++
270			}
271		}
272
273		b = append(b, s[i])
274	}
275
276	for j := len(symbol) - 1; j >= 0; j-- {
277		b = append(b, symbol[j])
278	}
279
280	for j := len(nnh.currencyPositivePrefix) - 1; j >= 0; j-- {
281		b = append(b, nnh.currencyPositivePrefix[j])
282	}
283
284	if num < 0 {
285		b = append(b, nnh.minus[0])
286	}
287
288	// reverse
289	for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
290		b[i], b[j] = b[j], b[i]
291	}
292
293	if int(v) < 2 {
294
295		if v == 0 {
296			b = append(b, nnh.decimal...)
297		}
298
299		for i := 0; i < 2-int(v); i++ {
300			b = append(b, '0')
301		}
302	}
303
304	return string(b)
305}
306
307// FmtAccounting returns the currency representation of 'num' with digits/precision of 'v' for 'nnh'
308// in accounting notation.
309func (nnh *nnh) FmtAccounting(num float64, v uint64, currency currency.Type) string {
310
311	s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
312	symbol := nnh.currencies[currency]
313	l := len(s) + len(symbol) + 3 + 1*len(s[:len(s)-int(v)-1])/3
314	count := 0
315	inWhole := v == 0
316	b := make([]byte, 0, l)
317
318	for i := len(s) - 1; i >= 0; i-- {
319
320		if s[i] == '.' {
321			b = append(b, nnh.decimal[0])
322			inWhole = true
323			continue
324		}
325
326		if inWhole {
327			if count == 3 {
328				b = append(b, nnh.group[0])
329				count = 1
330			} else {
331				count++
332			}
333		}
334
335		b = append(b, s[i])
336	}
337
338	if num < 0 {
339
340		for j := len(symbol) - 1; j >= 0; j-- {
341			b = append(b, symbol[j])
342		}
343
344		for j := len(nnh.currencyNegativePrefix) - 1; j >= 0; j-- {
345			b = append(b, nnh.currencyNegativePrefix[j])
346		}
347
348		b = append(b, nnh.minus[0])
349
350	} else {
351
352		for j := len(symbol) - 1; j >= 0; j-- {
353			b = append(b, symbol[j])
354		}
355
356		for j := len(nnh.currencyPositivePrefix) - 1; j >= 0; j-- {
357			b = append(b, nnh.currencyPositivePrefix[j])
358		}
359
360	}
361
362	// reverse
363	for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
364		b[i], b[j] = b[j], b[i]
365	}
366
367	if int(v) < 2 {
368
369		if v == 0 {
370			b = append(b, nnh.decimal...)
371		}
372
373		for i := 0; i < 2-int(v); i++ {
374			b = append(b, '0')
375		}
376	}
377
378	return string(b)
379}
380
381// FmtDateShort returns the short date representation of 't' for 'nnh'
382func (nnh *nnh) FmtDateShort(t time.Time) string {
383
384	b := make([]byte, 0, 32)
385
386	if t.Day() < 10 {
387		b = append(b, '0')
388	}
389
390	b = strconv.AppendInt(b, int64(t.Day()), 10)
391	b = append(b, []byte{0x2f}...)
392
393	if t.Month() < 10 {
394		b = append(b, '0')
395	}
396
397	b = strconv.AppendInt(b, int64(t.Month()), 10)
398
399	b = append(b, []byte{0x2f}...)
400
401	if t.Year() > 9 {
402		b = append(b, strconv.Itoa(t.Year())[2:]...)
403	} else {
404		b = append(b, strconv.Itoa(t.Year())[1:]...)
405	}
406
407	return string(b)
408}
409
410// FmtDateMedium returns the medium date representation of 't' for 'nnh'
411func (nnh *nnh) FmtDateMedium(t time.Time) string {
412
413	b := make([]byte, 0, 32)
414
415	b = strconv.AppendInt(b, int64(t.Day()), 10)
416	b = append(b, []byte{0x20}...)
417	b = append(b, nnh.monthsAbbreviated[t.Month()]...)
418	b = append(b, []byte{0x2c, 0x20}...)
419
420	if t.Year() > 0 {
421		b = strconv.AppendInt(b, int64(t.Year()), 10)
422	} else {
423		b = strconv.AppendInt(b, int64(-t.Year()), 10)
424	}
425
426	return string(b)
427}
428
429// FmtDateLong returns the long date representation of 't' for 'nnh'
430func (nnh *nnh) FmtDateLong(t time.Time) string {
431
432	b := make([]byte, 0, 32)
433
434	b = append(b, []byte{0x6c, 0x79, 0xc9, 0x9b}...)
435	b = append(b, []byte{0xcc, 0x8c, 0xca, 0xbc, 0x20}...)
436	b = strconv.AppendInt(b, int64(t.Day()), 10)
437	b = append(b, []byte{0x20, 0x6e, 0x61}...)
438	b = append(b, []byte{0x20}...)
439	b = append(b, nnh.monthsWide[t.Month()]...)
440	b = append(b, []byte{0x2c, 0x20}...)
441
442	if t.Year() > 0 {
443		b = strconv.AppendInt(b, int64(t.Year()), 10)
444	} else {
445		b = strconv.AppendInt(b, int64(-t.Year()), 10)
446	}
447
448	return string(b)
449}
450
451// FmtDateFull returns the full date representation of 't' for 'nnh'
452func (nnh *nnh) FmtDateFull(t time.Time) string {
453
454	b := make([]byte, 0, 32)
455
456	b = append(b, nnh.daysWide[t.Weekday()]...)
457	b = append(b, []byte{0x20, 0x2c, 0x20, 0x6c, 0x79, 0xc9, 0x9b}...)
458	b = append(b, []byte{0xcc, 0x8c, 0xca, 0xbc, 0x20}...)
459	b = strconv.AppendInt(b, int64(t.Day()), 10)
460	b = append(b, []byte{0x20, 0x6e, 0x61}...)
461	b = append(b, []byte{0x20}...)
462	b = append(b, nnh.monthsWide[t.Month()]...)
463	b = append(b, []byte{0x2c, 0x20}...)
464
465	if t.Year() > 0 {
466		b = strconv.AppendInt(b, int64(t.Year()), 10)
467	} else {
468		b = strconv.AppendInt(b, int64(-t.Year()), 10)
469	}
470
471	return string(b)
472}
473
474// FmtTimeShort returns the short time representation of 't' for 'nnh'
475func (nnh *nnh) FmtTimeShort(t time.Time) string {
476
477	b := make([]byte, 0, 32)
478
479	return string(b)
480}
481
482// FmtTimeMedium returns the medium time representation of 't' for 'nnh'
483func (nnh *nnh) FmtTimeMedium(t time.Time) string {
484
485	b := make([]byte, 0, 32)
486
487	return string(b)
488}
489
490// FmtTimeLong returns the long time representation of 't' for 'nnh'
491func (nnh *nnh) FmtTimeLong(t time.Time) string {
492
493	b := make([]byte, 0, 32)
494
495	return string(b)
496}
497
498// FmtTimeFull returns the full time representation of 't' for 'nnh'
499func (nnh *nnh) FmtTimeFull(t time.Time) string {
500
501	b := make([]byte, 0, 32)
502
503	return string(b)
504}
505