'use strict'; const compileMessage = require('@lingui/message-utils/compileMessage'); const isString = (s) => typeof s === "string"; const isFunction = (f) => typeof f === "function"; const cache = /* @__PURE__ */ new Map(); function normalizeLocales(locales) { const out = Array.isArray(locales) ? locales : [locales]; return [...out, "en"]; } function date(locales, value, format) { const _locales = normalizeLocales(locales); const formatter = getMemoized( () => cacheKey("date", _locales, format), () => new Intl.DateTimeFormat(_locales, format) ); return formatter.format(isString(value) ? new Date(value) : value); } function number(locales, value, format) { const _locales = normalizeLocales(locales); const formatter = getMemoized( () => cacheKey("number", _locales, format), () => new Intl.NumberFormat(_locales, format) ); return formatter.format(value); } function plural(locales, ordinal, value, { offset = 0, ...rules }) { const _locales = normalizeLocales(locales); const plurals = ordinal ? getMemoized( () => cacheKey("plural-ordinal", _locales), () => new Intl.PluralRules(_locales, { type: "ordinal" }) ) : getMemoized( () => cacheKey("plural-cardinal", _locales), () => new Intl.PluralRules(_locales, { type: "cardinal" }) ); return rules[value] ?? rules[plurals.select(value - offset)] ?? rules.other; } function getMemoized(getKey, construct) { const key = getKey(); let formatter = cache.get(key); if (!formatter) { formatter = construct(); cache.set(key, formatter); } return formatter; } function cacheKey(type, locales, options) { const localeKey = locales.join("-"); return `${type}-${localeKey}-${JSON.stringify(options)}`; } const formats = { __proto__: null, date: date, number: number, plural: plural }; const UNICODE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/g; const getDefaultFormats = (locale, locales, formats = {}) => { locales = locales || locale; const style = (format) => isString(format) ? formats[format] || { style: format } : format; const replaceOctothorpe = (value, message) => { const numberFormat = Object.keys(formats).length ? style("number") : {}; const valueStr = number(locales, value, numberFormat); return message.replace("#", valueStr); }; return { plural: (value, cases) => { const { offset = 0 } = cases; const message = plural(locales, false, value, cases); return replaceOctothorpe(value - offset, message); }, selectordinal: (value, cases) => { const { offset = 0 } = cases; const message = plural(locales, true, value, cases); return replaceOctothorpe(value - offset, message); }, select: (value, rules) => rules[value] ?? rules.other, number: (value, format) => number(locales, value, style(format)), date: (value, format) => date(locales, value, style(format)), undefined: (value) => value }; }; function interpolate(translation, locale, locales) { return (values, formats = {}) => { const formatters = getDefaultFormats(locale, locales, formats); const formatMessage = (message) => { if (!Array.isArray(message)) return message; return message.reduce((message2, token) => { if (isString(token)) return message2 + token; const [name, type, format] = token; let interpolatedFormat = {}; if (format != null && !isString(format)) { Object.keys(format).forEach((key) => { interpolatedFormat[key] = formatMessage(format[key]); }); } else { interpolatedFormat = format; } const value = formatters[type](values[name], interpolatedFormat); if (value == null) return message2; return message2 + value; }, ""); }; const result = formatMessage(translation); if (isString(result) && UNICODE_REGEX.test(result)) return JSON.parse(`"${result.trim()}"`); if (isString(result)) return result.trim(); return result; }; } class EventEmitter { constructor() { this._events = {}; } on(event, listener) { if (!this._hasEvent(event)) this._events[event] = []; this._events[event].push(listener); return () => this.removeListener(event, listener); } removeListener(event, listener) { if (!this._hasEvent(event)) return; const index = this._events[event].indexOf(listener); if (~index) this._events[event].splice(index, 1); } emit(event, ...args) { if (!this._hasEvent(event)) return; this._events[event].map((listener) => listener.apply(this, args)); } _hasEvent(event) { return Array.isArray(this._events[event]); } } class I18n extends EventEmitter { constructor(params) { super(); /** * Alias for {@see I18n._} */ this.t = this._.bind(this); this._messages = {}; this._localeData = {}; if (params.missing != null) this._missing = params.missing; if (params.messages != null) this.load(params.messages); if (params.localeData != null) this.loadLocaleData(params.localeData); if (params.locale != null || params.locales != null) { this.activate(params.locale, params.locales); } } get locale() { return this._locale; } get locales() { return this._locales; } get messages() { return this._messages[this._locale] ?? {}; } /** * @deprecated this has no effect. Please remove this from the code. Deprecated in v4 */ get localeData() { return this._localeData[this._locale] ?? {}; } _loadLocaleData(locale, localeData) { if (this._localeData[locale] == null) { this._localeData[locale] = localeData; } else { Object.assign(this._localeData[locale], localeData); } } /** * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4 */ loadLocaleData(localeOrAllData, localeData) { if (localeData != null) { this._loadLocaleData(localeOrAllData, localeData); } else { Object.keys(localeOrAllData).forEach( (locale) => this._loadLocaleData(locale, localeOrAllData[locale]) ); } this.emit("change"); } _load(locale, messages) { if (this._messages[locale] == null) { this._messages[locale] = messages; } else { Object.assign(this._messages[locale], messages); } } load(localeOrMessages, messages) { if (messages != null) { this._load(localeOrMessages, messages); } else { Object.keys(localeOrMessages).forEach( (locale) => this._load(locale, localeOrMessages[locale]) ); } this.emit("change"); } /** * @param options {@link LoadAndActivateOptions} */ loadAndActivate({ locale, locales, messages }) { this._locale = locale; this._locales = locales || void 0; this._messages[this._locale] = messages; this.emit("change"); } activate(locale, locales) { if (process.env.NODE_ENV !== "production") { if (!this._messages[locale]) { console.warn(`Messages for locale "${locale}" not loaded.`); } } this._locale = locale; this._locales = locales; this.emit("change"); } _(id, values = {}, { message, formats } = {}) { if (!isString(id)) { values = id.values || values; message = id.message; id = id.id; } const messageMissing = !this.messages[id]; const missing = this._missing; if (missing && messageMissing) { return isFunction(missing) ? missing(this._locale, id) : missing; } if (messageMissing) { this.emit("missing", { id, locale: this._locale }); } let translation = this.messages[id] || message || id; if (process.env.NODE_ENV !== "production") { translation = isString(translation) ? compileMessage.compileMessage(translation) : translation; } if (isString(translation) && UNICODE_REGEX.test(translation)) return JSON.parse(`"${translation}"`); if (isString(translation)) return translation; return interpolate( translation, this._locale, this._locales )(values, formats); } date(value, format) { return date(this._locales || this._locale, value, format); } number(value, format) { return number(this._locales || this._locale, value, format); } } function setupI18n(params = {}) { return new I18n(params); } const i18n = setupI18n(); exports.I18n = I18n; exports.formats = formats; exports.i18n = i18n; exports.setupI18n = setupI18n;