From 8ee6be30ebda4b8ce592c2fa4ec0688ecde420bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Tue, 4 Apr 2023 09:39:07 +0200 Subject: [PATCH] add vue-i18n dependecy --- Makefile | 1 + lnbits/helpers.py | 1 + lnbits/static/vendor/vue-i18n.js | 2312 ++++++++++++++++++++++++++++++ package-lock.json | 6 + package.json | 1 + tools/build.py | 1 + 6 files changed, 2322 insertions(+) create mode 100644 lnbits/static/vendor/vue-i18n.js diff --git a/Makefile b/Makefile index 25add4fca..1f08db53f 100644 --- a/Makefile +++ b/Makefile @@ -89,3 +89,4 @@ updatevendor: cp ./node_modules/quasar/dist/quasar.css ./lnbits/static/vendor/ cp ./node_modules/chart.js/dist/Chart.css ./lnbits/static/vendor/ cp ./node_modules/vue-qrcode-reader/dist/vue-qrcode-reader.css ./lnbits/static/vendor/ + cp ./node_modules/vue-i18n/dist/vue-i18n.js ./lnbits/static/vendor/ diff --git a/lnbits/helpers.py b/lnbits/helpers.py index 184a8f857..6a44ffbad 100644 --- a/lnbits/helpers.py +++ b/lnbits/helpers.py @@ -23,6 +23,7 @@ vendored_js = [ "/static/vendor/vue-router.js", "/static/vendor/vue-qrcode-reader.browser.js", "/static/vendor/vue-qrcode.js", + "/static/vendor/vue-i18n.js", "/static/vendor/vuex.js", "/static/vendor/quasar.ie.polyfills.umd.min.js", "/static/vendor/quasar.umd.js", diff --git a/lnbits/static/vendor/vue-i18n.js b/lnbits/static/vendor/vue-i18n.js new file mode 100644 index 000000000..545386059 --- /dev/null +++ b/lnbits/static/vendor/vue-i18n.js @@ -0,0 +1,2312 @@ +/*! + * vue-i18n v8.28.2 + * (c) 2022 kazuya kawaguchi + * Released under the MIT License. + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.VueI18n = factory()); +}(this, (function () { 'use strict'; + + /* */ + + /** + * constants + */ + + var numberFormatKeys = [ + 'compactDisplay', + 'currency', + 'currencyDisplay', + 'currencySign', + 'localeMatcher', + 'notation', + 'numberingSystem', + 'signDisplay', + 'style', + 'unit', + 'unitDisplay', + 'useGrouping', + 'minimumIntegerDigits', + 'minimumFractionDigits', + 'maximumFractionDigits', + 'minimumSignificantDigits', + 'maximumSignificantDigits' + ]; + + var dateTimeFormatKeys = [ + 'dateStyle', + 'timeStyle', + 'calendar', + 'localeMatcher', + "hour12", + "hourCycle", + "timeZone", + "formatMatcher", + 'weekday', + 'era', + 'year', + 'month', + 'day', + 'hour', + 'minute', + 'second', + 'timeZoneName' ]; + + /** + * utilities + */ + + function warn (msg, err) { + if (typeof console !== 'undefined') { + console.warn('[vue-i18n] ' + msg); + /* istanbul ignore if */ + if (err) { + console.warn(err.stack); + } + } + } + + function error (msg, err) { + if (typeof console !== 'undefined') { + console.error('[vue-i18n] ' + msg); + /* istanbul ignore if */ + if (err) { + console.error(err.stack); + } + } + } + + var isArray = Array.isArray; + + function isObject (obj) { + return obj !== null && typeof obj === 'object' + } + + function isBoolean (val) { + return typeof val === 'boolean' + } + + function isString (val) { + return typeof val === 'string' + } + + var toString = Object.prototype.toString; + var OBJECT_STRING = '[object Object]'; + function isPlainObject (obj) { + return toString.call(obj) === OBJECT_STRING + } + + function isNull (val) { + return val === null || val === undefined + } + + function isFunction (val) { + return typeof val === 'function' + } + + function parseArgs () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var locale = null; + var params = null; + if (args.length === 1) { + if (isObject(args[0]) || isArray(args[0])) { + params = args[0]; + } else if (typeof args[0] === 'string') { + locale = args[0]; + } + } else if (args.length === 2) { + if (typeof args[0] === 'string') { + locale = args[0]; + } + /* istanbul ignore if */ + if (isObject(args[1]) || isArray(args[1])) { + params = args[1]; + } + } + + return { locale: locale, params: params } + } + + function looseClone (obj) { + return JSON.parse(JSON.stringify(obj)) + } + + function remove (arr, item) { + if (arr.delete(item)) { + return arr + } + } + + function arrayFrom (arr) { + var ret = []; + arr.forEach(function (a) { return ret.push(a); }); + return ret + } + + function includes (arr, item) { + return !!~arr.indexOf(item) + } + + var hasOwnProperty = Object.prototype.hasOwnProperty; + function hasOwn (obj, key) { + return hasOwnProperty.call(obj, key) + } + + function merge (target) { + var arguments$1 = arguments; + + var output = Object(target); + for (var i = 1; i < arguments.length; i++) { + var source = arguments$1[i]; + if (source !== undefined && source !== null) { + var key = (void 0); + for (key in source) { + if (hasOwn(source, key)) { + if (isObject(source[key])) { + output[key] = merge(output[key], source[key]); + } else { + output[key] = source[key]; + } + } + } + } + } + return output + } + + function looseEqual (a, b) { + if (a === b) { return true } + var isObjectA = isObject(a); + var isObjectB = isObject(b); + if (isObjectA && isObjectB) { + try { + var isArrayA = isArray(a); + var isArrayB = isArray(b); + if (isArrayA && isArrayB) { + return a.length === b.length && a.every(function (e, i) { + return looseEqual(e, b[i]) + }) + } else if (!isArrayA && !isArrayB) { + var keysA = Object.keys(a); + var keysB = Object.keys(b); + return keysA.length === keysB.length && keysA.every(function (key) { + return looseEqual(a[key], b[key]) + }) + } else { + /* istanbul ignore next */ + return false + } + } catch (e) { + /* istanbul ignore next */ + return false + } + } else if (!isObjectA && !isObjectB) { + return String(a) === String(b) + } else { + return false + } + } + + /** + * Sanitizes html special characters from input strings. For mitigating risk of XSS attacks. + * @param rawText The raw input from the user that should be escaped. + */ + function escapeHtml(rawText) { + return rawText + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') + } + + /** + * Escapes html tags and special symbols from all provided params which were returned from parseArgs().params. + * This method performs an in-place operation on the params object. + * + * @param {any} params Parameters as provided from `parseArgs().params`. + * May be either an array of strings or a string->any map. + * + * @returns The manipulated `params` object. + */ + function escapeParams(params) { + if(params != null) { + Object.keys(params).forEach(function (key) { + if(typeof(params[key]) == 'string') { + params[key] = escapeHtml(params[key]); + } + }); + } + return params + } + + /* */ + + function extend (Vue) { + if (!Vue.prototype.hasOwnProperty('$i18n')) { + // $FlowFixMe + Object.defineProperty(Vue.prototype, '$i18n', { + get: function get () { return this._i18n } + }); + } + + Vue.prototype.$t = function (key) { + var values = [], len = arguments.length - 1; + while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ]; + + var i18n = this.$i18n; + return i18n._t.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this ].concat( values )) + }; + + Vue.prototype.$tc = function (key, choice) { + var values = [], len = arguments.length - 2; + while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ]; + + var i18n = this.$i18n; + return i18n._tc.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this, choice ].concat( values )) + }; + + Vue.prototype.$te = function (key, locale) { + var i18n = this.$i18n; + return i18n._te(key, i18n.locale, i18n._getMessages(), locale) + }; + + Vue.prototype.$d = function (value) { + var ref; + + var args = [], len = arguments.length - 1; + while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ]; + return (ref = this.$i18n).d.apply(ref, [ value ].concat( args )) + }; + + Vue.prototype.$n = function (value) { + var ref; + + var args = [], len = arguments.length - 1; + while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ]; + return (ref = this.$i18n).n.apply(ref, [ value ].concat( args )) + }; + } + + /* */ + + /** + * Mixin + * + * If `bridge` mode, empty mixin is returned, + * else regulary mixin implementation is returned. + */ + function defineMixin (bridge) { + if ( bridge === void 0 ) bridge = false; + + function mounted () { + if (this !== this.$root && this.$options.__INTLIFY_META__ && this.$el) { + this.$el.setAttribute('data-intlify', this.$options.__INTLIFY_META__); + } + } + + return bridge + ? { mounted: mounted } // delegate `vue-i18n-bridge` mixin implementation + : { // regulary + beforeCreate: function beforeCreate () { + var options = this.$options; + options.i18n = options.i18n || ((options.__i18nBridge || options.__i18n) ? {} : null); + + if (options.i18n) { + if (options.i18n instanceof VueI18n) { + // init locale messages via custom blocks + if ((options.__i18nBridge || options.__i18n)) { + try { + var localeMessages = options.i18n && options.i18n.messages ? options.i18n.messages : {}; + var _i18n = options.__i18nBridge || options.__i18n; + _i18n.forEach(function (resource) { + localeMessages = merge(localeMessages, JSON.parse(resource)); + }); + Object.keys(localeMessages).forEach(function (locale) { + options.i18n.mergeLocaleMessage(locale, localeMessages[locale]); + }); + } catch (e) { + { + error("Cannot parse locale messages via custom blocks.", e); + } + } + } + this._i18n = options.i18n; + this._i18nWatcher = this._i18n.watchI18nData(); + } else if (isPlainObject(options.i18n)) { + var rootI18n = this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n + ? this.$root.$i18n + : null; + // component local i18n + if (rootI18n) { + options.i18n.root = this.$root; + options.i18n.formatter = rootI18n.formatter; + options.i18n.fallbackLocale = rootI18n.fallbackLocale; + options.i18n.formatFallbackMessages = rootI18n.formatFallbackMessages; + options.i18n.silentTranslationWarn = rootI18n.silentTranslationWarn; + options.i18n.silentFallbackWarn = rootI18n.silentFallbackWarn; + options.i18n.pluralizationRules = rootI18n.pluralizationRules; + options.i18n.preserveDirectiveContent = rootI18n.preserveDirectiveContent; + } + + // init locale messages via custom blocks + if ((options.__i18nBridge || options.__i18n)) { + try { + var localeMessages$1 = options.i18n && options.i18n.messages ? options.i18n.messages : {}; + var _i18n$1 = options.__i18nBridge || options.__i18n; + _i18n$1.forEach(function (resource) { + localeMessages$1 = merge(localeMessages$1, JSON.parse(resource)); + }); + options.i18n.messages = localeMessages$1; + } catch (e) { + { + warn("Cannot parse locale messages via custom blocks.", e); + } + } + } + + var ref = options.i18n; + var sharedMessages = ref.sharedMessages; + if (sharedMessages && isPlainObject(sharedMessages)) { + options.i18n.messages = merge(options.i18n.messages, sharedMessages); + } + + this._i18n = new VueI18n(options.i18n); + this._i18nWatcher = this._i18n.watchI18nData(); + + if (options.i18n.sync === undefined || !!options.i18n.sync) { + this._localeWatcher = this.$i18n.watchLocale(); + } + + if (rootI18n) { + rootI18n.onComponentInstanceCreated(this._i18n); + } + } else { + { + warn("Cannot be interpreted 'i18n' option."); + } + } + } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) { + // root i18n + this._i18n = this.$root.$i18n; + } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) { + // parent i18n + this._i18n = options.parent.$i18n; + } + }, + + beforeMount: function beforeMount () { + var options = this.$options; + options.i18n = options.i18n || ((options.__i18nBridge || options.__i18n) ? {} : null); + + if (options.i18n) { + if (options.i18n instanceof VueI18n) { + // init locale messages via custom blocks + this._i18n.subscribeDataChanging(this); + this._subscribing = true; + } else if (isPlainObject(options.i18n)) { + this._i18n.subscribeDataChanging(this); + this._subscribing = true; + } else { + { + warn("Cannot be interpreted 'i18n' option."); + } + } + } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) { + this._i18n.subscribeDataChanging(this); + this._subscribing = true; + } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) { + this._i18n.subscribeDataChanging(this); + this._subscribing = true; + } + }, + + mounted: mounted, + + beforeDestroy: function beforeDestroy () { + if (!this._i18n) { return } + + var self = this; + this.$nextTick(function () { + if (self._subscribing) { + self._i18n.unsubscribeDataChanging(self); + delete self._subscribing; + } + + if (self._i18nWatcher) { + self._i18nWatcher(); + self._i18n.destroyVM(); + delete self._i18nWatcher; + } + + if (self._localeWatcher) { + self._localeWatcher(); + delete self._localeWatcher; + } + }); + } + } + } + + /* */ + + var interpolationComponent = { + name: 'i18n', + functional: true, + props: { + tag: { + type: [String, Boolean, Object], + default: 'span' + }, + path: { + type: String, + required: true + }, + locale: { + type: String + }, + places: { + type: [Array, Object] + } + }, + render: function render (h, ref) { + var data = ref.data; + var parent = ref.parent; + var props = ref.props; + var slots = ref.slots; + + var $i18n = parent.$i18n; + if (!$i18n) { + { + warn('Cannot find VueI18n instance!'); + } + return + } + + var path = props.path; + var locale = props.locale; + var places = props.places; + var params = slots(); + var children = $i18n.i( + path, + locale, + onlyHasDefaultPlace(params) || places + ? useLegacyPlaces(params.default, places) + : params + ); + + var tag = (!!props.tag && props.tag !== true) || props.tag === false ? props.tag : 'span'; + return tag ? h(tag, data, children) : children + } + }; + + function onlyHasDefaultPlace (params) { + var prop; + for (prop in params) { + if (prop !== 'default') { return false } + } + return Boolean(prop) + } + + function useLegacyPlaces (children, places) { + var params = places ? createParamsFromPlaces(places) : {}; + + if (!children) { return params } + + // Filter empty text nodes + children = children.filter(function (child) { + return child.tag || child.text.trim() !== '' + }); + + var everyPlace = children.every(vnodeHasPlaceAttribute); + if (everyPlace) { + warn('`place` attribute is deprecated in next major version. Please switch to Vue slots.'); + } + + return children.reduce( + everyPlace ? assignChildPlace : assignChildIndex, + params + ) + } + + function createParamsFromPlaces (places) { + { + warn('`places` prop is deprecated in next major version. Please switch to Vue slots.'); + } + + return Array.isArray(places) + ? places.reduce(assignChildIndex, {}) + : Object.assign({}, places) + } + + function assignChildPlace (params, child) { + if (child.data && child.data.attrs && child.data.attrs.place) { + params[child.data.attrs.place] = child; + } + return params + } + + function assignChildIndex (params, child, index) { + params[index] = child; + return params + } + + function vnodeHasPlaceAttribute (vnode) { + return Boolean(vnode.data && vnode.data.attrs && vnode.data.attrs.place) + } + + /* */ + + var numberComponent = { + name: 'i18n-n', + functional: true, + props: { + tag: { + type: [String, Boolean, Object], + default: 'span' + }, + value: { + type: Number, + required: true + }, + format: { + type: [String, Object] + }, + locale: { + type: String + } + }, + render: function render (h, ref) { + var props = ref.props; + var parent = ref.parent; + var data = ref.data; + + var i18n = parent.$i18n; + + if (!i18n) { + { + warn('Cannot find VueI18n instance!'); + } + return null + } + + var key = null; + var options = null; + + if (isString(props.format)) { + key = props.format; + } else if (isObject(props.format)) { + if (props.format.key) { + key = props.format.key; + } + + // Filter out number format options only + options = Object.keys(props.format).reduce(function (acc, prop) { + var obj; + + if (includes(numberFormatKeys, prop)) { + return Object.assign({}, acc, ( obj = {}, obj[prop] = props.format[prop], obj )) + } + return acc + }, null); + } + + var locale = props.locale || i18n.locale; + var parts = i18n._ntp(props.value, locale, key, options); + + var values = parts.map(function (part, index) { + var obj; + + var slot = data.scopedSlots && data.scopedSlots[part.type]; + return slot ? slot(( obj = {}, obj[part.type] = part.value, obj.index = index, obj.parts = parts, obj )) : part.value + }); + + var tag = (!!props.tag && props.tag !== true) || props.tag === false ? props.tag : 'span'; + return tag + ? h(tag, { + attrs: data.attrs, + 'class': data['class'], + staticClass: data.staticClass + }, values) + : values + } + }; + + /* */ + + function bind (el, binding, vnode) { + if (!assert(el, vnode)) { return } + + t(el, binding, vnode); + } + + function update (el, binding, vnode, oldVNode) { + if (!assert(el, vnode)) { return } + + var i18n = vnode.context.$i18n; + if (localeEqual(el, vnode) && + (looseEqual(binding.value, binding.oldValue) && + looseEqual(el._localeMessage, i18n.getLocaleMessage(i18n.locale)))) { return } + + t(el, binding, vnode); + } + + function unbind (el, binding, vnode, oldVNode) { + var vm = vnode.context; + if (!vm) { + warn('Vue instance does not exists in VNode context'); + return + } + + var i18n = vnode.context.$i18n || {}; + if (!binding.modifiers.preserve && !i18n.preserveDirectiveContent) { + el.textContent = ''; + } + el._vt = undefined; + delete el['_vt']; + el._locale = undefined; + delete el['_locale']; + el._localeMessage = undefined; + delete el['_localeMessage']; + } + + function assert (el, vnode) { + var vm = vnode.context; + if (!vm) { + warn('Vue instance does not exists in VNode context'); + return false + } + + if (!vm.$i18n) { + warn('VueI18n instance does not exists in Vue instance'); + return false + } + + return true + } + + function localeEqual (el, vnode) { + var vm = vnode.context; + return el._locale === vm.$i18n.locale + } + + function t (el, binding, vnode) { + var ref$1, ref$2; + + var value = binding.value; + + var ref = parseValue(value); + var path = ref.path; + var locale = ref.locale; + var args = ref.args; + var choice = ref.choice; + if (!path && !locale && !args) { + warn('value type not supported'); + return + } + + if (!path) { + warn('`path` is required in v-t directive'); + return + } + + var vm = vnode.context; + if (choice != null) { + el._vt = el.textContent = (ref$1 = vm.$i18n).tc.apply(ref$1, [ path, choice ].concat( makeParams(locale, args) )); + } else { + el._vt = el.textContent = (ref$2 = vm.$i18n).t.apply(ref$2, [ path ].concat( makeParams(locale, args) )); + } + el._locale = vm.$i18n.locale; + el._localeMessage = vm.$i18n.getLocaleMessage(vm.$i18n.locale); + } + + function parseValue (value) { + var path; + var locale; + var args; + var choice; + + if (isString(value)) { + path = value; + } else if (isPlainObject(value)) { + path = value.path; + locale = value.locale; + args = value.args; + choice = value.choice; + } + + return { path: path, locale: locale, args: args, choice: choice } + } + + function makeParams (locale, args) { + var params = []; + + locale && params.push(locale); + if (args && (Array.isArray(args) || isPlainObject(args))) { + params.push(args); + } + + return params + } + + var Vue; + + function install (_Vue, options) { + if ( options === void 0 ) options = { bridge: false }; + + /* istanbul ignore if */ + if (install.installed && _Vue === Vue) { + warn('already installed.'); + return + } + install.installed = true; + + Vue = _Vue; + + var version = (Vue.version && Number(Vue.version.split('.')[0])) || -1; + /* istanbul ignore if */ + if (version < 2) { + warn(("vue-i18n (" + (install.version) + ") need to use Vue 2.0 or later (Vue: " + (Vue.version) + ").")); + return + } + + extend(Vue); + Vue.mixin(defineMixin(options.bridge)); + Vue.directive('t', { bind: bind, update: update, unbind: unbind }); + Vue.component(interpolationComponent.name, interpolationComponent); + Vue.component(numberComponent.name, numberComponent); + + // use simple mergeStrategies to prevent i18n instance lose '__proto__' + var strats = Vue.config.optionMergeStrategies; + strats.i18n = function (parentVal, childVal) { + return childVal === undefined + ? parentVal + : childVal + }; + } + + /* */ + + var BaseFormatter = function BaseFormatter () { + this._caches = Object.create(null); + }; + + BaseFormatter.prototype.interpolate = function interpolate (message, values) { + if (!values) { + return [message] + } + var tokens = this._caches[message]; + if (!tokens) { + tokens = parse(message); + this._caches[message] = tokens; + } + return compile(tokens, values) + }; + + + + var RE_TOKEN_LIST_VALUE = /^(?:\d)+/; + var RE_TOKEN_NAMED_VALUE = /^(?:\w)+/; + + function parse (format) { + var tokens = []; + var position = 0; + + var text = ''; + while (position < format.length) { + var char = format[position++]; + if (char === '{') { + if (text) { + tokens.push({ type: 'text', value: text }); + } + + text = ''; + var sub = ''; + char = format[position++]; + while (char !== undefined && char !== '}') { + sub += char; + char = format[position++]; + } + var isClosed = char === '}'; + + var type = RE_TOKEN_LIST_VALUE.test(sub) + ? 'list' + : isClosed && RE_TOKEN_NAMED_VALUE.test(sub) + ? 'named' + : 'unknown'; + tokens.push({ value: sub, type: type }); + } else if (char === '%') { + // when found rails i18n syntax, skip text capture + if (format[(position)] !== '{') { + text += char; + } + } else { + text += char; + } + } + + text && tokens.push({ type: 'text', value: text }); + + return tokens + } + + function compile (tokens, values) { + var compiled = []; + var index = 0; + + var mode = Array.isArray(values) + ? 'list' + : isObject(values) + ? 'named' + : 'unknown'; + if (mode === 'unknown') { return compiled } + + while (index < tokens.length) { + var token = tokens[index]; + switch (token.type) { + case 'text': + compiled.push(token.value); + break + case 'list': + compiled.push(values[parseInt(token.value, 10)]); + break + case 'named': + if (mode === 'named') { + compiled.push((values)[token.value]); + } else { + { + warn(("Type of token '" + (token.type) + "' and format of value '" + mode + "' don't match!")); + } + } + break + case 'unknown': + { + warn("Detect 'unknown' type of token!"); + } + break + } + index++; + } + + return compiled + } + + /* */ + + /** + * Path parser + * - Inspired: + * Vue.js Path parser + */ + + // actions + var APPEND = 0; + var PUSH = 1; + var INC_SUB_PATH_DEPTH = 2; + var PUSH_SUB_PATH = 3; + + // states + var BEFORE_PATH = 0; + var IN_PATH = 1; + var BEFORE_IDENT = 2; + var IN_IDENT = 3; + var IN_SUB_PATH = 4; + var IN_SINGLE_QUOTE = 5; + var IN_DOUBLE_QUOTE = 6; + var AFTER_PATH = 7; + var ERROR = 8; + + var pathStateMachine = []; + + pathStateMachine[BEFORE_PATH] = { + 'ws': [BEFORE_PATH], + 'ident': [IN_IDENT, APPEND], + '[': [IN_SUB_PATH], + 'eof': [AFTER_PATH] + }; + + pathStateMachine[IN_PATH] = { + 'ws': [IN_PATH], + '.': [BEFORE_IDENT], + '[': [IN_SUB_PATH], + 'eof': [AFTER_PATH] + }; + + pathStateMachine[BEFORE_IDENT] = { + 'ws': [BEFORE_IDENT], + 'ident': [IN_IDENT, APPEND], + '0': [IN_IDENT, APPEND], + 'number': [IN_IDENT, APPEND] + }; + + pathStateMachine[IN_IDENT] = { + 'ident': [IN_IDENT, APPEND], + '0': [IN_IDENT, APPEND], + 'number': [IN_IDENT, APPEND], + 'ws': [IN_PATH, PUSH], + '.': [BEFORE_IDENT, PUSH], + '[': [IN_SUB_PATH, PUSH], + 'eof': [AFTER_PATH, PUSH] + }; + + pathStateMachine[IN_SUB_PATH] = { + "'": [IN_SINGLE_QUOTE, APPEND], + '"': [IN_DOUBLE_QUOTE, APPEND], + '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH], + ']': [IN_PATH, PUSH_SUB_PATH], + 'eof': ERROR, + 'else': [IN_SUB_PATH, APPEND] + }; + + pathStateMachine[IN_SINGLE_QUOTE] = { + "'": [IN_SUB_PATH, APPEND], + 'eof': ERROR, + 'else': [IN_SINGLE_QUOTE, APPEND] + }; + + pathStateMachine[IN_DOUBLE_QUOTE] = { + '"': [IN_SUB_PATH, APPEND], + 'eof': ERROR, + 'else': [IN_DOUBLE_QUOTE, APPEND] + }; + + /** + * Check if an expression is a literal value. + */ + + var literalValueRE = /^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/; + function isLiteral (exp) { + return literalValueRE.test(exp) + } + + /** + * Strip quotes from a string + */ + + function stripQuotes (str) { + var a = str.charCodeAt(0); + var b = str.charCodeAt(str.length - 1); + return a === b && (a === 0x22 || a === 0x27) + ? str.slice(1, -1) + : str + } + + /** + * Determine the type of a character in a keypath. + */ + + function getPathCharType (ch) { + if (ch === undefined || ch === null) { return 'eof' } + + var code = ch.charCodeAt(0); + + switch (code) { + case 0x5B: // [ + case 0x5D: // ] + case 0x2E: // . + case 0x22: // " + case 0x27: // ' + return ch + + case 0x5F: // _ + case 0x24: // $ + case 0x2D: // - + return 'ident' + + case 0x09: // Tab + case 0x0A: // Newline + case 0x0D: // Return + case 0xA0: // No-break space + case 0xFEFF: // Byte Order Mark + case 0x2028: // Line Separator + case 0x2029: // Paragraph Separator + return 'ws' + } + + return 'ident' + } + + /** + * Format a subPath, return its plain form if it is + * a literal string or number. Otherwise prepend the + * dynamic indicator (*). + */ + + function formatSubPath (path) { + var trimmed = path.trim(); + // invalid leading 0 + if (path.charAt(0) === '0' && isNaN(path)) { return false } + + return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed + } + + /** + * Parse a string path into an array of segments + */ + + function parse$1 (path) { + var keys = []; + var index = -1; + var mode = BEFORE_PATH; + var subPathDepth = 0; + var c; + var key; + var newChar; + var type; + var transition; + var action; + var typeMap; + var actions = []; + + actions[PUSH] = function () { + if (key !== undefined) { + keys.push(key); + key = undefined; + } + }; + + actions[APPEND] = function () { + if (key === undefined) { + key = newChar; + } else { + key += newChar; + } + }; + + actions[INC_SUB_PATH_DEPTH] = function () { + actions[APPEND](); + subPathDepth++; + }; + + actions[PUSH_SUB_PATH] = function () { + if (subPathDepth > 0) { + subPathDepth--; + mode = IN_SUB_PATH; + actions[APPEND](); + } else { + subPathDepth = 0; + if (key === undefined) { return false } + key = formatSubPath(key); + if (key === false) { + return false + } else { + actions[PUSH](); + } + } + }; + + function maybeUnescapeQuote () { + var nextChar = path[index + 1]; + if ((mode === IN_SINGLE_QUOTE && nextChar === "'") || + (mode === IN_DOUBLE_QUOTE && nextChar === '"')) { + index++; + newChar = '\\' + nextChar; + actions[APPEND](); + return true + } + } + + while (mode !== null) { + index++; + c = path[index]; + + if (c === '\\' && maybeUnescapeQuote()) { + continue + } + + type = getPathCharType(c); + typeMap = pathStateMachine[mode]; + transition = typeMap[type] || typeMap['else'] || ERROR; + + if (transition === ERROR) { + return // parse error + } + + mode = transition[0]; + action = actions[transition[1]]; + if (action) { + newChar = transition[2]; + newChar = newChar === undefined + ? c + : newChar; + if (action() === false) { + return + } + } + + if (mode === AFTER_PATH) { + return keys + } + } + } + + + + + + var I18nPath = function I18nPath () { + this._cache = Object.create(null); + }; + + /** + * External parse that check for a cache hit first + */ + I18nPath.prototype.parsePath = function parsePath (path) { + var hit = this._cache[path]; + if (!hit) { + hit = parse$1(path); + if (hit) { + this._cache[path] = hit; + } + } + return hit || [] + }; + + /** + * Get path value from path string + */ + I18nPath.prototype.getPathValue = function getPathValue (obj, path) { + if (!isObject(obj)) { return null } + + var paths = this.parsePath(path); + if (paths.length === 0) { + return null + } else { + var length = paths.length; + var last = obj; + var i = 0; + while (i < length) { + var value = last[paths[i]]; + if (value === undefined || value === null) { + return null + } + last = value; + i++; + } + + return last + } + }; + + /* */ + + + + var htmlTagMatcher = /<\/?[\w\s="/.':;#-\/]+>/; + var linkKeyMatcher = /(?:@(?:\.[a-zA-Z]+)?:(?:[\w\-_|./]+|\([\w\-_:|./]+\)))/g; + var linkKeyPrefixMatcher = /^@(?:\.([a-zA-Z]+))?:/; + var bracketsMatcher = /[()]/g; + var defaultModifiers = { + 'upper': function (str) { return str.toLocaleUpperCase(); }, + 'lower': function (str) { return str.toLocaleLowerCase(); }, + 'capitalize': function (str) { return ("" + (str.charAt(0).toLocaleUpperCase()) + (str.substr(1))); } + }; + + var defaultFormatter = new BaseFormatter(); + + var VueI18n = function VueI18n (options) { + var this$1 = this; + if ( options === void 0 ) options = {}; + + // Auto install if it is not done yet and `window` has `Vue`. + // To allow users to avoid auto-installation in some cases, + // this code should be placed here. See #290 + /* istanbul ignore if */ + if (!Vue && typeof window !== 'undefined' && window.Vue) { + install(window.Vue); + } + + var locale = options.locale || 'en-US'; + var fallbackLocale = options.fallbackLocale === false + ? false + : options.fallbackLocale || 'en-US'; + var messages = options.messages || {}; + var dateTimeFormats = options.dateTimeFormats || options.datetimeFormats || {}; + var numberFormats = options.numberFormats || {}; + + this._vm = null; + this._formatter = options.formatter || defaultFormatter; + this._modifiers = options.modifiers || {}; + this._missing = options.missing || null; + this._root = options.root || null; + this._sync = options.sync === undefined ? true : !!options.sync; + this._fallbackRoot = options.fallbackRoot === undefined + ? true + : !!options.fallbackRoot; + this._fallbackRootWithEmptyString = options.fallbackRootWithEmptyString === undefined + ? true + : !!options.fallbackRootWithEmptyString; + this._formatFallbackMessages = options.formatFallbackMessages === undefined + ? false + : !!options.formatFallbackMessages; + this._silentTranslationWarn = options.silentTranslationWarn === undefined + ? false + : options.silentTranslationWarn; + this._silentFallbackWarn = options.silentFallbackWarn === undefined + ? false + : !!options.silentFallbackWarn; + this._dateTimeFormatters = {}; + this._numberFormatters = {}; + this._path = new I18nPath(); + this._dataListeners = new Set(); + this._componentInstanceCreatedListener = options.componentInstanceCreatedListener || null; + this._preserveDirectiveContent = options.preserveDirectiveContent === undefined + ? false + : !!options.preserveDirectiveContent; + this.pluralizationRules = options.pluralizationRules || {}; + this._warnHtmlInMessage = options.warnHtmlInMessage || 'off'; + this._postTranslation = options.postTranslation || null; + this._escapeParameterHtml = options.escapeParameterHtml || false; + + if ('__VUE_I18N_BRIDGE__' in options) { + this.__VUE_I18N_BRIDGE__ = options.__VUE_I18N_BRIDGE__; + } + + /** + * @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)` + * @param choicesLength {number} an overall amount of available choices + * @returns a final choice index + */ + this.getChoiceIndex = function (choice, choicesLength) { + var thisPrototype = Object.getPrototypeOf(this$1); + if (thisPrototype && thisPrototype.getChoiceIndex) { + var prototypeGetChoiceIndex = (thisPrototype.getChoiceIndex); + return (prototypeGetChoiceIndex).call(this$1, choice, choicesLength) + } + + // Default (old) getChoiceIndex implementation - english-compatible + var defaultImpl = function (_choice, _choicesLength) { + _choice = Math.abs(_choice); + + if (_choicesLength === 2) { + return _choice + ? _choice > 1 + ? 1 + : 0 + : 1 + } + + return _choice ? Math.min(_choice, 2) : 0 + }; + + if (this$1.locale in this$1.pluralizationRules) { + return this$1.pluralizationRules[this$1.locale].apply(this$1, [choice, choicesLength]) + } else { + return defaultImpl(choice, choicesLength) + } + }; + + + this._exist = function (message, key) { + if (!message || !key) { return false } + if (!isNull(this$1._path.getPathValue(message, key))) { return true } + // fallback for flat key + if (message[key]) { return true } + return false + }; + + if (this._warnHtmlInMessage === 'warn' || this._warnHtmlInMessage === 'error') { + Object.keys(messages).forEach(function (locale) { + this$1._checkLocaleMessage(locale, this$1._warnHtmlInMessage, messages[locale]); + }); + } + + this._initVM({ + locale: locale, + fallbackLocale: fallbackLocale, + messages: messages, + dateTimeFormats: dateTimeFormats, + numberFormats: numberFormats + }); + }; + + var prototypeAccessors = { vm: { configurable: true },messages: { configurable: true },dateTimeFormats: { configurable: true },numberFormats: { configurable: true },availableLocales: { configurable: true },locale: { configurable: true },fallbackLocale: { configurable: true },formatFallbackMessages: { configurable: true },missing: { configurable: true },formatter: { configurable: true },silentTranslationWarn: { configurable: true },silentFallbackWarn: { configurable: true },preserveDirectiveContent: { configurable: true },warnHtmlInMessage: { configurable: true },postTranslation: { configurable: true },sync: { configurable: true } }; + + VueI18n.prototype._checkLocaleMessage = function _checkLocaleMessage (locale, level, message) { + var paths = []; + + var fn = function (level, locale, message, paths) { + if (isPlainObject(message)) { + Object.keys(message).forEach(function (key) { + var val = message[key]; + if (isPlainObject(val)) { + paths.push(key); + paths.push('.'); + fn(level, locale, val, paths); + paths.pop(); + paths.pop(); + } else { + paths.push(key); + fn(level, locale, val, paths); + paths.pop(); + } + }); + } else if (isArray(message)) { + message.forEach(function (item, index) { + if (isPlainObject(item)) { + paths.push(("[" + index + "]")); + paths.push('.'); + fn(level, locale, item, paths); + paths.pop(); + paths.pop(); + } else { + paths.push(("[" + index + "]")); + fn(level, locale, item, paths); + paths.pop(); + } + }); + } else if (isString(message)) { + var ret = htmlTagMatcher.test(message); + if (ret) { + var msg = "Detected HTML in message '" + message + "' of keypath '" + (paths.join('')) + "' at '" + locale + "'. Consider component interpolation with '' to avoid XSS. See https://bit.ly/2ZqJzkp"; + if (level === 'warn') { + warn(msg); + } else if (level === 'error') { + error(msg); + } + } + } + }; + + fn(level, locale, message, paths); + }; + + VueI18n.prototype._initVM = function _initVM (data) { + var silent = Vue.config.silent; + Vue.config.silent = true; + this._vm = new Vue({ data: data, __VUE18N__INSTANCE__: true }); + Vue.config.silent = silent; + }; + + VueI18n.prototype.destroyVM = function destroyVM () { + this._vm.$destroy(); + }; + + VueI18n.prototype.subscribeDataChanging = function subscribeDataChanging (vm) { + this._dataListeners.add(vm); + }; + + VueI18n.prototype.unsubscribeDataChanging = function unsubscribeDataChanging (vm) { + remove(this._dataListeners, vm); + }; + + VueI18n.prototype.watchI18nData = function watchI18nData () { + var this$1 = this; + return this._vm.$watch('$data', function () { + var listeners = arrayFrom(this$1._dataListeners); + var i = listeners.length; + while(i--) { + Vue.nextTick(function () { + listeners[i] && listeners[i].$forceUpdate(); + }); + } + }, { deep: true }) + }; + + VueI18n.prototype.watchLocale = function watchLocale (composer) { + if (!composer) { + /* istanbul ignore if */ + if (!this._sync || !this._root) { return null } + var target = this._vm; + return this._root.$i18n.vm.$watch('locale', function (val) { + target.$set(target, 'locale', val); + target.$forceUpdate(); + }, { immediate: true }) + } else { + // deal with vue-i18n-bridge + if (!this.__VUE_I18N_BRIDGE__) { return null } + var self = this; + var target$1 = this._vm; + return this.vm.$watch('locale', function (val) { + target$1.$set(target$1, 'locale', val); + if (self.__VUE_I18N_BRIDGE__ && composer) { + composer.locale.value = val; + } + target$1.$forceUpdate(); + }, { immediate: true }) + } + }; + + VueI18n.prototype.onComponentInstanceCreated = function onComponentInstanceCreated (newI18n) { + if (this._componentInstanceCreatedListener) { + this._componentInstanceCreatedListener(newI18n, this); + } + }; + + prototypeAccessors.vm.get = function () { return this._vm }; + + prototypeAccessors.messages.get = function () { return looseClone(this._getMessages()) }; + prototypeAccessors.dateTimeFormats.get = function () { return looseClone(this._getDateTimeFormats()) }; + prototypeAccessors.numberFormats.get = function () { return looseClone(this._getNumberFormats()) }; + prototypeAccessors.availableLocales.get = function () { return Object.keys(this.messages).sort() }; + + prototypeAccessors.locale.get = function () { return this._vm.locale }; + prototypeAccessors.locale.set = function (locale) { + this._vm.$set(this._vm, 'locale', locale); + }; + + prototypeAccessors.fallbackLocale.get = function () { return this._vm.fallbackLocale }; + prototypeAccessors.fallbackLocale.set = function (locale) { + this._localeChainCache = {}; + this._vm.$set(this._vm, 'fallbackLocale', locale); + }; + + prototypeAccessors.formatFallbackMessages.get = function () { return this._formatFallbackMessages }; + prototypeAccessors.formatFallbackMessages.set = function (fallback) { this._formatFallbackMessages = fallback; }; + + prototypeAccessors.missing.get = function () { return this._missing }; + prototypeAccessors.missing.set = function (handler) { this._missing = handler; }; + + prototypeAccessors.formatter.get = function () { return this._formatter }; + prototypeAccessors.formatter.set = function (formatter) { this._formatter = formatter; }; + + prototypeAccessors.silentTranslationWarn.get = function () { return this._silentTranslationWarn }; + prototypeAccessors.silentTranslationWarn.set = function (silent) { this._silentTranslationWarn = silent; }; + + prototypeAccessors.silentFallbackWarn.get = function () { return this._silentFallbackWarn }; + prototypeAccessors.silentFallbackWarn.set = function (silent) { this._silentFallbackWarn = silent; }; + + prototypeAccessors.preserveDirectiveContent.get = function () { return this._preserveDirectiveContent }; + prototypeAccessors.preserveDirectiveContent.set = function (preserve) { this._preserveDirectiveContent = preserve; }; + + prototypeAccessors.warnHtmlInMessage.get = function () { return this._warnHtmlInMessage }; + prototypeAccessors.warnHtmlInMessage.set = function (level) { + var this$1 = this; + + var orgLevel = this._warnHtmlInMessage; + this._warnHtmlInMessage = level; + if (orgLevel !== level && (level === 'warn' || level === 'error')) { + var messages = this._getMessages(); + Object.keys(messages).forEach(function (locale) { + this$1._checkLocaleMessage(locale, this$1._warnHtmlInMessage, messages[locale]); + }); + } + }; + + prototypeAccessors.postTranslation.get = function () { return this._postTranslation }; + prototypeAccessors.postTranslation.set = function (handler) { this._postTranslation = handler; }; + + prototypeAccessors.sync.get = function () { return this._sync }; + prototypeAccessors.sync.set = function (val) { this._sync = val; }; + + VueI18n.prototype._getMessages = function _getMessages () { return this._vm.messages }; + VueI18n.prototype._getDateTimeFormats = function _getDateTimeFormats () { return this._vm.dateTimeFormats }; + VueI18n.prototype._getNumberFormats = function _getNumberFormats () { return this._vm.numberFormats }; + + VueI18n.prototype._warnDefault = function _warnDefault (locale, key, result, vm, values, interpolateMode) { + if (!isNull(result)) { return result } + if (this._missing) { + var missingRet = this._missing.apply(null, [locale, key, vm, values]); + if (isString(missingRet)) { + return missingRet + } + } else { + if (!this._isSilentTranslationWarn(key)) { + warn( + "Cannot translate the value of keypath '" + key + "'. " + + 'Use the value of keypath as default.' + ); + } + } + + if (this._formatFallbackMessages) { + var parsedArgs = parseArgs.apply(void 0, values); + return this._render(key, interpolateMode, parsedArgs.params, key) + } else { + return key + } + }; + + VueI18n.prototype._isFallbackRoot = function _isFallbackRoot (val) { + return (this._fallbackRootWithEmptyString? !val : isNull(val)) && !isNull(this._root) && this._fallbackRoot + }; + + VueI18n.prototype._isSilentFallbackWarn = function _isSilentFallbackWarn (key) { + return this._silentFallbackWarn instanceof RegExp + ? this._silentFallbackWarn.test(key) + : this._silentFallbackWarn + }; + + VueI18n.prototype._isSilentFallback = function _isSilentFallback (locale, key) { + return this._isSilentFallbackWarn(key) && (this._isFallbackRoot() || locale !== this.fallbackLocale) + }; + + VueI18n.prototype._isSilentTranslationWarn = function _isSilentTranslationWarn (key) { + return this._silentTranslationWarn instanceof RegExp + ? this._silentTranslationWarn.test(key) + : this._silentTranslationWarn + }; + + VueI18n.prototype._interpolate = function _interpolate ( + locale, + message, + key, + host, + interpolateMode, + values, + visitedLinkStack + ) { + if (!message) { return null } + + var pathRet = this._path.getPathValue(message, key); + if (isArray(pathRet) || isPlainObject(pathRet)) { return pathRet } + + var ret; + if (isNull(pathRet)) { + /* istanbul ignore else */ + if (isPlainObject(message)) { + ret = message[key]; + if (!(isString(ret) || isFunction(ret))) { + if (!this._isSilentTranslationWarn(key) && !this._isSilentFallback(locale, key)) { + warn(("Value of key '" + key + "' is not a string or function !")); + } + return null + } + } else { + return null + } + } else { + /* istanbul ignore else */ + if (isString(pathRet) || isFunction(pathRet)) { + ret = pathRet; + } else { + if (!this._isSilentTranslationWarn(key) && !this._isSilentFallback(locale, key)) { + warn(("Value of key '" + key + "' is not a string or function!")); + } + return null + } + } + + // Check for the existence of links within the translated string + if (isString(ret) && (ret.indexOf('@:') >= 0 || ret.indexOf('@.') >= 0)) { + ret = this._link(locale, message, ret, host, 'raw', values, visitedLinkStack); + } + + return this._render(ret, interpolateMode, values, key) + }; + + VueI18n.prototype._link = function _link ( + locale, + message, + str, + host, + interpolateMode, + values, + visitedLinkStack + ) { + var ret = str; + + // Match all the links within the local + // We are going to replace each of + // them with its translation + var matches = ret.match(linkKeyMatcher); + + // eslint-disable-next-line no-autofix/prefer-const + for (var idx in matches) { + // ie compatible: filter custom array + // prototype method + if (!matches.hasOwnProperty(idx)) { + continue + } + var link = matches[idx]; + var linkKeyPrefixMatches = link.match(linkKeyPrefixMatcher); + var linkPrefix = linkKeyPrefixMatches[0]; + var formatterName = linkKeyPrefixMatches[1]; + + // Remove the leading @:, @.case: and the brackets + var linkPlaceholder = link.replace(linkPrefix, '').replace(bracketsMatcher, ''); + + if (includes(visitedLinkStack, linkPlaceholder)) { + { + warn(("Circular reference found. \"" + link + "\" is already visited in the chain of " + (visitedLinkStack.reverse().join(' <- ')))); + } + return ret + } + visitedLinkStack.push(linkPlaceholder); + + // Translate the link + var translated = this._interpolate( + locale, message, linkPlaceholder, host, + interpolateMode === 'raw' ? 'string' : interpolateMode, + interpolateMode === 'raw' ? undefined : values, + visitedLinkStack + ); + + if (this._isFallbackRoot(translated)) { + if (!this._isSilentTranslationWarn(linkPlaceholder)) { + warn(("Fall back to translate the link placeholder '" + linkPlaceholder + "' with root locale.")); + } + /* istanbul ignore if */ + if (!this._root) { throw Error('unexpected error') } + var root = this._root.$i18n; + translated = root._translate( + root._getMessages(), root.locale, root.fallbackLocale, + linkPlaceholder, host, interpolateMode, values + ); + } + translated = this._warnDefault( + locale, linkPlaceholder, translated, host, + isArray(values) ? values : [values], + interpolateMode + ); + + if (this._modifiers.hasOwnProperty(formatterName)) { + translated = this._modifiers[formatterName](translated); + } else if (defaultModifiers.hasOwnProperty(formatterName)) { + translated = defaultModifiers[formatterName](translated); + } + + visitedLinkStack.pop(); + + // Replace the link with the translated + ret = !translated ? ret : ret.replace(link, translated); + } + + return ret + }; + + VueI18n.prototype._createMessageContext = function _createMessageContext (values, formatter, path, interpolateMode) { + var this$1 = this; + + var _list = isArray(values) ? values : []; + var _named = isObject(values) ? values : {}; + var list = function (index) { return _list[index]; }; + var named = function (key) { return _named[key]; }; + var messages = this._getMessages(); + var locale = this.locale; + + return { + list: list, + named: named, + values: values, + formatter: formatter, + path: path, + messages: messages, + locale: locale, + linked: function (linkedKey) { return this$1._interpolate(locale, messages[locale] || {}, linkedKey, null, interpolateMode, undefined, [linkedKey]); } + } + }; + + VueI18n.prototype._render = function _render (message, interpolateMode, values, path) { + if (isFunction(message)) { + return message( + this._createMessageContext(values, this._formatter || defaultFormatter, path, interpolateMode) + ) + } + + var ret = this._formatter.interpolate(message, values, path); + + // If the custom formatter refuses to work - apply the default one + if (!ret) { + ret = defaultFormatter.interpolate(message, values, path); + } + + // if interpolateMode is **not** 'string' ('row'), + // return the compiled data (e.g. ['foo', VNode, 'bar']) with formatter + return interpolateMode === 'string' && !isString(ret) ? ret.join('') : ret + }; + + VueI18n.prototype._appendItemToChain = function _appendItemToChain (chain, item, blocks) { + var follow = false; + if (!includes(chain, item)) { + follow = true; + if (item) { + follow = item[item.length - 1] !== '!'; + item = item.replace(/!/g, ''); + chain.push(item); + if (blocks && blocks[item]) { + follow = blocks[item]; + } + } + } + return follow + }; + + VueI18n.prototype._appendLocaleToChain = function _appendLocaleToChain (chain, locale, blocks) { + var follow; + var tokens = locale.split('-'); + do { + var item = tokens.join('-'); + follow = this._appendItemToChain(chain, item, blocks); + tokens.splice(-1, 1); + } while (tokens.length && (follow === true)) + return follow + }; + + VueI18n.prototype._appendBlockToChain = function _appendBlockToChain (chain, block, blocks) { + var follow = true; + for (var i = 0; (i < block.length) && (isBoolean(follow)); i++) { + var locale = block[i]; + if (isString(locale)) { + follow = this._appendLocaleToChain(chain, locale, blocks); + } + } + return follow + }; + + VueI18n.prototype._getLocaleChain = function _getLocaleChain (start, fallbackLocale) { + if (start === '') { return [] } + + if (!this._localeChainCache) { + this._localeChainCache = {}; + } + + var chain = this._localeChainCache[start]; + if (!chain) { + if (!fallbackLocale) { + fallbackLocale = this.fallbackLocale; + } + chain = []; + + // first block defined by start + var block = [start]; + + // while any intervening block found + while (isArray(block)) { + block = this._appendBlockToChain( + chain, + block, + fallbackLocale + ); + } + + // last block defined by default + var defaults; + if (isArray(fallbackLocale)) { + defaults = fallbackLocale; + } else if (isObject(fallbackLocale)) { + /* $FlowFixMe */ + if (fallbackLocale['default']) { + defaults = fallbackLocale['default']; + } else { + defaults = null; + } + } else { + defaults = fallbackLocale; + } + + // convert defaults to array + if (isString(defaults)) { + block = [defaults]; + } else { + block = defaults; + } + if (block) { + this._appendBlockToChain( + chain, + block, + null + ); + } + this._localeChainCache[start] = chain; + } + return chain + }; + + VueI18n.prototype._translate = function _translate ( + messages, + locale, + fallback, + key, + host, + interpolateMode, + args + ) { + var chain = this._getLocaleChain(locale, fallback); + var res; + for (var i = 0; i < chain.length; i++) { + var step = chain[i]; + res = + this._interpolate(step, messages[step], key, host, interpolateMode, args, [key]); + if (!isNull(res)) { + if (step !== locale && "development" !== 'production' && !this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) { + warn(("Fall back to translate the keypath '" + key + "' with '" + step + "' locale.")); + } + return res + } + } + return null + }; + + VueI18n.prototype._t = function _t (key, _locale, messages, host) { + var ref; + + var values = [], len = arguments.length - 4; + while ( len-- > 0 ) values[ len ] = arguments[ len + 4 ]; + if (!key) { return '' } + + var parsedArgs = parseArgs.apply(void 0, values); + if(this._escapeParameterHtml) { + parsedArgs.params = escapeParams(parsedArgs.params); + } + + var locale = parsedArgs.locale || _locale; + + var ret = this._translate( + messages, locale, this.fallbackLocale, key, + host, 'string', parsedArgs.params + ); + if (this._isFallbackRoot(ret)) { + if (!this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) { + warn(("Fall back to translate the keypath '" + key + "' with root locale.")); + } + /* istanbul ignore if */ + if (!this._root) { throw Error('unexpected error') } + return (ref = this._root).$t.apply(ref, [ key ].concat( values )) + } else { + ret = this._warnDefault(locale, key, ret, host, values, 'string'); + if (this._postTranslation && ret !== null && ret !== undefined) { + ret = this._postTranslation(ret, key); + } + return ret + } + }; + + VueI18n.prototype.t = function t (key) { + var ref; + + var values = [], len = arguments.length - 1; + while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ]; + return (ref = this)._t.apply(ref, [ key, this.locale, this._getMessages(), null ].concat( values )) + }; + + VueI18n.prototype._i = function _i (key, locale, messages, host, values) { + var ret = + this._translate(messages, locale, this.fallbackLocale, key, host, 'raw', values); + if (this._isFallbackRoot(ret)) { + if (!this._isSilentTranslationWarn(key)) { + warn(("Fall back to interpolate the keypath '" + key + "' with root locale.")); + } + if (!this._root) { throw Error('unexpected error') } + return this._root.$i18n.i(key, locale, values) + } else { + return this._warnDefault(locale, key, ret, host, [values], 'raw') + } + }; + + VueI18n.prototype.i = function i (key, locale, values) { + /* istanbul ignore if */ + if (!key) { return '' } + + if (!isString(locale)) { + locale = this.locale; + } + + return this._i(key, locale, this._getMessages(), null, values) + }; + + VueI18n.prototype._tc = function _tc ( + key, + _locale, + messages, + host, + choice + ) { + var ref; + + var values = [], len = arguments.length - 5; + while ( len-- > 0 ) values[ len ] = arguments[ len + 5 ]; + if (!key) { return '' } + if (choice === undefined) { + choice = 1; + } + + var predefined = { 'count': choice, 'n': choice }; + var parsedArgs = parseArgs.apply(void 0, values); + parsedArgs.params = Object.assign(predefined, parsedArgs.params); + values = parsedArgs.locale === null ? [parsedArgs.params] : [parsedArgs.locale, parsedArgs.params]; + return this.fetchChoice((ref = this)._t.apply(ref, [ key, _locale, messages, host ].concat( values )), choice) + }; + + VueI18n.prototype.fetchChoice = function fetchChoice (message, choice) { + /* istanbul ignore if */ + if (!message || !isString(message)) { return null } + var choices = message.split('|'); + + choice = this.getChoiceIndex(choice, choices.length); + if (!choices[choice]) { return message } + return choices[choice].trim() + }; + + VueI18n.prototype.tc = function tc (key, choice) { + var ref; + + var values = [], len = arguments.length - 2; + while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ]; + return (ref = this)._tc.apply(ref, [ key, this.locale, this._getMessages(), null, choice ].concat( values )) + }; + + VueI18n.prototype._te = function _te (key, locale, messages) { + var args = [], len = arguments.length - 3; + while ( len-- > 0 ) args[ len ] = arguments[ len + 3 ]; + + var _locale = parseArgs.apply(void 0, args).locale || locale; + return this._exist(messages[_locale], key) + }; + + VueI18n.prototype.te = function te (key, locale) { + return this._te(key, this.locale, this._getMessages(), locale) + }; + + VueI18n.prototype.getLocaleMessage = function getLocaleMessage (locale) { + return looseClone(this._vm.messages[locale] || {}) + }; + + VueI18n.prototype.setLocaleMessage = function setLocaleMessage (locale, message) { + if (this._warnHtmlInMessage === 'warn' || this._warnHtmlInMessage === 'error') { + this._checkLocaleMessage(locale, this._warnHtmlInMessage, message); + } + this._vm.$set(this._vm.messages, locale, message); + }; + + VueI18n.prototype.mergeLocaleMessage = function mergeLocaleMessage (locale, message) { + if (this._warnHtmlInMessage === 'warn' || this._warnHtmlInMessage === 'error') { + this._checkLocaleMessage(locale, this._warnHtmlInMessage, message); + } + this._vm.$set(this._vm.messages, locale, merge( + typeof this._vm.messages[locale] !== 'undefined' && Object.keys(this._vm.messages[locale]).length + ? Object.assign({}, this._vm.messages[locale]) + : {}, + message + )); + }; + + VueI18n.prototype.getDateTimeFormat = function getDateTimeFormat (locale) { + return looseClone(this._vm.dateTimeFormats[locale] || {}) + }; + + VueI18n.prototype.setDateTimeFormat = function setDateTimeFormat (locale, format) { + this._vm.$set(this._vm.dateTimeFormats, locale, format); + this._clearDateTimeFormat(locale, format); + }; + + VueI18n.prototype.mergeDateTimeFormat = function mergeDateTimeFormat (locale, format) { + this._vm.$set(this._vm.dateTimeFormats, locale, merge(this._vm.dateTimeFormats[locale] || {}, format)); + this._clearDateTimeFormat(locale, format); + }; + + VueI18n.prototype._clearDateTimeFormat = function _clearDateTimeFormat (locale, format) { + // eslint-disable-next-line no-autofix/prefer-const + for (var key in format) { + var id = locale + "__" + key; + + if (!this._dateTimeFormatters.hasOwnProperty(id)) { + continue + } + + delete this._dateTimeFormatters[id]; + } + }; + + VueI18n.prototype._localizeDateTime = function _localizeDateTime ( + value, + locale, + fallback, + dateTimeFormats, + key, + options + ) { + var _locale = locale; + var formats = dateTimeFormats[_locale]; + + var chain = this._getLocaleChain(locale, fallback); + for (var i = 0; i < chain.length; i++) { + var current = _locale; + var step = chain[i]; + formats = dateTimeFormats[step]; + _locale = step; + // fallback locale + if (isNull(formats) || isNull(formats[key])) { + if (step !== locale && "development" !== 'production' && !this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) { + warn(("Fall back to '" + step + "' datetime formats from '" + current + "' datetime formats.")); + } + } else { + break + } + } + + if (isNull(formats) || isNull(formats[key])) { + return null + } else { + var format = formats[key]; + + var formatter; + if (options) { + formatter = new Intl.DateTimeFormat(_locale, Object.assign({}, format, options)); + } else { + var id = _locale + "__" + key; + formatter = this._dateTimeFormatters[id]; + if (!formatter) { + formatter = this._dateTimeFormatters[id] = new Intl.DateTimeFormat(_locale, format); + } + } + + return formatter.format(value) + } + }; + + VueI18n.prototype._d = function _d (value, locale, key, options) { + /* istanbul ignore if */ + if (!VueI18n.availabilities.dateTimeFormat) { + warn('Cannot format a Date value due to not supported Intl.DateTimeFormat.'); + return '' + } + + if (!key) { + var dtf = !options ? new Intl.DateTimeFormat(locale) : new Intl.DateTimeFormat(locale, options); + return dtf.format(value) + } + + var ret = + this._localizeDateTime(value, locale, this.fallbackLocale, this._getDateTimeFormats(), key, options); + if (this._isFallbackRoot(ret)) { + if (!this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) { + warn(("Fall back to datetime localization of root: key '" + key + "'.")); + } + /* istanbul ignore if */ + if (!this._root) { throw Error('unexpected error') } + return this._root.$i18n.d(value, key, locale) + } else { + return ret || '' + } + }; + + VueI18n.prototype.d = function d (value) { + var args = [], len = arguments.length - 1; + while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ]; + + var locale = this.locale; + var key = null; + var options = null; + + if (args.length === 1) { + if (isString(args[0])) { + key = args[0]; + } else if (isObject(args[0])) { + if (args[0].locale) { + locale = args[0].locale; + } + if (args[0].key) { + key = args[0].key; + } + } + + options = Object.keys(args[0]).reduce(function (acc, key) { + var obj; + + if (includes(dateTimeFormatKeys, key)) { + return Object.assign({}, acc, ( obj = {}, obj[key] = args[0][key], obj )) + } + return acc + }, null); + + } else if (args.length === 2) { + if (isString(args[0])) { + key = args[0]; + } + if (isString(args[1])) { + locale = args[1]; + } + } + + return this._d(value, locale, key, options) + }; + + VueI18n.prototype.getNumberFormat = function getNumberFormat (locale) { + return looseClone(this._vm.numberFormats[locale] || {}) + }; + + VueI18n.prototype.setNumberFormat = function setNumberFormat (locale, format) { + this._vm.$set(this._vm.numberFormats, locale, format); + this._clearNumberFormat(locale, format); + }; + + VueI18n.prototype.mergeNumberFormat = function mergeNumberFormat (locale, format) { + this._vm.$set(this._vm.numberFormats, locale, merge(this._vm.numberFormats[locale] || {}, format)); + this._clearNumberFormat(locale, format); + }; + + VueI18n.prototype._clearNumberFormat = function _clearNumberFormat (locale, format) { + // eslint-disable-next-line no-autofix/prefer-const + for (var key in format) { + var id = locale + "__" + key; + + if (!this._numberFormatters.hasOwnProperty(id)) { + continue + } + + delete this._numberFormatters[id]; + } + }; + + VueI18n.prototype._getNumberFormatter = function _getNumberFormatter ( + value, + locale, + fallback, + numberFormats, + key, + options + ) { + var _locale = locale; + var formats = numberFormats[_locale]; + + var chain = this._getLocaleChain(locale, fallback); + for (var i = 0; i < chain.length; i++) { + var current = _locale; + var step = chain[i]; + formats = numberFormats[step]; + _locale = step; + // fallback locale + if (isNull(formats) || isNull(formats[key])) { + if (step !== locale && "development" !== 'production' && !this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) { + warn(("Fall back to '" + step + "' number formats from '" + current + "' number formats.")); + } + } else { + break + } + } + + if (isNull(formats) || isNull(formats[key])) { + return null + } else { + var format = formats[key]; + + var formatter; + if (options) { + // If options specified - create one time number formatter + formatter = new Intl.NumberFormat(_locale, Object.assign({}, format, options)); + } else { + var id = _locale + "__" + key; + formatter = this._numberFormatters[id]; + if (!formatter) { + formatter = this._numberFormatters[id] = new Intl.NumberFormat(_locale, format); + } + } + return formatter + } + }; + + VueI18n.prototype._n = function _n (value, locale, key, options) { + /* istanbul ignore if */ + if (!VueI18n.availabilities.numberFormat) { + { + warn('Cannot format a Number value due to not supported Intl.NumberFormat.'); + } + return '' + } + + if (!key) { + var nf = !options ? new Intl.NumberFormat(locale) : new Intl.NumberFormat(locale, options); + return nf.format(value) + } + + var formatter = this._getNumberFormatter(value, locale, this.fallbackLocale, this._getNumberFormats(), key, options); + var ret = formatter && formatter.format(value); + if (this._isFallbackRoot(ret)) { + if (!this._isSilentTranslationWarn(key) && !this._isSilentFallbackWarn(key)) { + warn(("Fall back to number localization of root: key '" + key + "'.")); + } + /* istanbul ignore if */ + if (!this._root) { throw Error('unexpected error') } + return this._root.$i18n.n(value, Object.assign({}, { key: key, locale: locale }, options)) + } else { + return ret || '' + } + }; + + VueI18n.prototype.n = function n (value) { + var args = [], len = arguments.length - 1; + while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ]; + + var locale = this.locale; + var key = null; + var options = null; + + if (args.length === 1) { + if (isString(args[0])) { + key = args[0]; + } else if (isObject(args[0])) { + if (args[0].locale) { + locale = args[0].locale; + } + if (args[0].key) { + key = args[0].key; + } + + // Filter out number format options only + options = Object.keys(args[0]).reduce(function (acc, key) { + var obj; + + if (includes(numberFormatKeys, key)) { + return Object.assign({}, acc, ( obj = {}, obj[key] = args[0][key], obj )) + } + return acc + }, null); + } + } else if (args.length === 2) { + if (isString(args[0])) { + key = args[0]; + } + if (isString(args[1])) { + locale = args[1]; + } + } + + return this._n(value, locale, key, options) + }; + + VueI18n.prototype._ntp = function _ntp (value, locale, key, options) { + /* istanbul ignore if */ + if (!VueI18n.availabilities.numberFormat) { + { + warn('Cannot format to parts a Number value due to not supported Intl.NumberFormat.'); + } + return [] + } + + if (!key) { + var nf = !options ? new Intl.NumberFormat(locale) : new Intl.NumberFormat(locale, options); + return nf.formatToParts(value) + } + + var formatter = this._getNumberFormatter(value, locale, this.fallbackLocale, this._getNumberFormats(), key, options); + var ret = formatter && formatter.formatToParts(value); + if (this._isFallbackRoot(ret)) { + if (!this._isSilentTranslationWarn(key)) { + warn(("Fall back to format number to parts of root: key '" + key + "' .")); + } + /* istanbul ignore if */ + if (!this._root) { throw Error('unexpected error') } + return this._root.$i18n._ntp(value, locale, key, options) + } else { + return ret || [] + } + }; + + Object.defineProperties( VueI18n.prototype, prototypeAccessors ); + + var availabilities; + // $FlowFixMe + Object.defineProperty(VueI18n, 'availabilities', { + get: function get () { + if (!availabilities) { + var intlDefined = typeof Intl !== 'undefined'; + availabilities = { + dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined', + numberFormat: intlDefined && typeof Intl.NumberFormat !== 'undefined' + }; + } + + return availabilities + } + }); + + VueI18n.install = install; + VueI18n.version = '8.28.2'; + + return VueI18n; + +}))); diff --git a/package-lock.json b/package-lock.json index 727d5102a..ecab1dd5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "quasar": "1.13.2", "underscore": "^1.13.6", "vue": "2.6.12", + "vue-i18n": "^8.28.2", "vue-qrcode-reader": "2.2", "vue-router": "3.4.3", "vuex": "3.5.1" @@ -536,6 +537,11 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.12.tgz", "integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==" }, + "node_modules/vue-i18n": { + "version": "8.28.2", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.28.2.tgz", + "integrity": "sha512-C5GZjs1tYlAqjwymaaCPDjCyGo10ajUphiwA922jKt9n7KPpqR7oM1PCwYzhB/E7+nT3wfdG3oRre5raIT1rKA==" + }, "node_modules/vue-qrcode-reader": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/vue-qrcode-reader/-/vue-qrcode-reader-2.2.0.tgz", diff --git a/package.json b/package.json index 113f3257b..f7f4b7a04 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "quasar": "1.13.2", "underscore": "^1.13.6", "vue": "2.6.12", + "vue-i18n": "^8.28.2", "vue-qrcode-reader": "2.2", "vue-router": "3.4.3", "vuex": "3.5.1" diff --git a/tools/build.py b/tools/build.py index 0c6ae3cb5..372e0f1dc 100644 --- a/tools/build.py +++ b/tools/build.py @@ -13,6 +13,7 @@ vendored_js = [ "/static/vendor/vue-router.js", "/static/vendor/vue-qrcode-reader.browser.js", "/static/vendor/vue-qrcode.js", + "/static/vendor/vue-i18n.js", "/static/vendor/vuex.js", "/static/vendor/quasar.ie.polyfills.umd.min.js", "/static/vendor/quasar.umd.js",