UNPKG

45.4 kBJavaScriptView Raw
1/*!
2 * vue-i18n v8.8.1
3 * (c) 2019 kazuya kawaguchi
4 * Released under the MIT License.
5 */
6/* */
7
8/**
9 * utilities
10 */
11
12function warn (msg, err) {
13 if (typeof console !== 'undefined') {
14 console.warn('[vue-i18n] ' + msg);
15 /* istanbul ignore if */
16 if (err) {
17 console.warn(err.stack);
18 }
19 }
20}
21
22function isObject (obj) {
23 return obj !== null && typeof obj === 'object'
24}
25
26var toString = Object.prototype.toString;
27var OBJECT_STRING = '[object Object]';
28function isPlainObject (obj) {
29 return toString.call(obj) === OBJECT_STRING
30}
31
32function isNull (val) {
33 return val === null || val === undefined
34}
35
36function parseArgs () {
37 var args = [], len = arguments.length;
38 while ( len-- ) args[ len ] = arguments[ len ];
39
40 var locale = null;
41 var params = null;
42 if (args.length === 1) {
43 if (isObject(args[0]) || Array.isArray(args[0])) {
44 params = args[0];
45 } else if (typeof args[0] === 'string') {
46 locale = args[0];
47 }
48 } else if (args.length === 2) {
49 if (typeof args[0] === 'string') {
50 locale = args[0];
51 }
52 /* istanbul ignore if */
53 if (isObject(args[1]) || Array.isArray(args[1])) {
54 params = args[1];
55 }
56 }
57
58 return { locale: locale, params: params }
59}
60
61function looseClone (obj) {
62 return JSON.parse(JSON.stringify(obj))
63}
64
65function remove (arr, item) {
66 if (arr.length) {
67 var index = arr.indexOf(item);
68 if (index > -1) {
69 return arr.splice(index, 1)
70 }
71 }
72}
73
74var hasOwnProperty = Object.prototype.hasOwnProperty;
75function hasOwn (obj, key) {
76 return hasOwnProperty.call(obj, key)
77}
78
79function merge (target) {
80 var arguments$1 = arguments;
81
82 var output = Object(target);
83 for (var i = 1; i < arguments.length; i++) {
84 var source = arguments$1[i];
85 if (source !== undefined && source !== null) {
86 var key = (void 0);
87 for (key in source) {
88 if (hasOwn(source, key)) {
89 if (isObject(source[key])) {
90 output[key] = merge(output[key], source[key]);
91 } else {
92 output[key] = source[key];
93 }
94 }
95 }
96 }
97 }
98 return output
99}
100
101function looseEqual (a, b) {
102 if (a === b) { return true }
103 var isObjectA = isObject(a);
104 var isObjectB = isObject(b);
105 if (isObjectA && isObjectB) {
106 try {
107 var isArrayA = Array.isArray(a);
108 var isArrayB = Array.isArray(b);
109 if (isArrayA && isArrayB) {
110 return a.length === b.length && a.every(function (e, i) {
111 return looseEqual(e, b[i])
112 })
113 } else if (!isArrayA && !isArrayB) {
114 var keysA = Object.keys(a);
115 var keysB = Object.keys(b);
116 return keysA.length === keysB.length && keysA.every(function (key) {
117 return looseEqual(a[key], b[key])
118 })
119 } else {
120 /* istanbul ignore next */
121 return false
122 }
123 } catch (e) {
124 /* istanbul ignore next */
125 return false
126 }
127 } else if (!isObjectA && !isObjectB) {
128 return String(a) === String(b)
129 } else {
130 return false
131 }
132}
133
134/* */
135
136function extend (Vue) {
137 if (!Vue.prototype.hasOwnProperty('$i18n')) {
138 // $FlowFixMe
139 Object.defineProperty(Vue.prototype, '$i18n', {
140 get: function get () { return this._i18n }
141 });
142 }
143
144 Vue.prototype.$t = function (key) {
145 var values = [], len = arguments.length - 1;
146 while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
147
148 var i18n = this.$i18n;
149 return i18n._t.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this ].concat( values ))
150 };
151
152 Vue.prototype.$tc = function (key, choice) {
153 var values = [], len = arguments.length - 2;
154 while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ];
155
156 var i18n = this.$i18n;
157 return i18n._tc.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this, choice ].concat( values ))
158 };
159
160 Vue.prototype.$te = function (key, locale) {
161 var i18n = this.$i18n;
162 return i18n._te(key, i18n.locale, i18n._getMessages(), locale)
163 };
164
165 Vue.prototype.$d = function (value) {
166 var ref;
167
168 var args = [], len = arguments.length - 1;
169 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
170 return (ref = this.$i18n).d.apply(ref, [ value ].concat( args ))
171 };
172
173 Vue.prototype.$n = function (value) {
174 var ref;
175
176 var args = [], len = arguments.length - 1;
177 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
178 return (ref = this.$i18n).n.apply(ref, [ value ].concat( args ))
179 };
180}
181
182/* */
183
184var mixin = {
185 beforeCreate: function beforeCreate () {
186 var options = this.$options;
187 options.i18n = options.i18n || (options.__i18n ? {} : null);
188
189 if (options.i18n) {
190 if (options.i18n instanceof VueI18n) {
191 // init locale messages via custom blocks
192 if (options.__i18n) {
193 try {
194 var localeMessages = {};
195 options.__i18n.forEach(function (resource) {
196 localeMessages = merge(localeMessages, JSON.parse(resource));
197 });
198 Object.keys(localeMessages).forEach(function (locale) {
199 options.i18n.mergeLocaleMessage(locale, localeMessages[locale]);
200 });
201 } catch (e) {
202 if (process.env.NODE_ENV !== 'production') {
203 warn("Cannot parse locale messages via custom blocks.", e);
204 }
205 }
206 }
207 this._i18n = options.i18n;
208 this._i18nWatcher = this._i18n.watchI18nData();
209 this._i18n.subscribeDataChanging(this);
210 this._subscribing = true;
211 } else if (isPlainObject(options.i18n)) {
212 // component local i18n
213 if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
214 options.i18n.root = this.$root;
215 options.i18n.formatter = this.$root.$i18n.formatter;
216 options.i18n.fallbackLocale = this.$root.$i18n.fallbackLocale;
217 options.i18n.silentTranslationWarn = this.$root.$i18n.silentTranslationWarn;
218 options.i18n.silentFallbackWarn = this.$root.$i18n.silentFallbackWarn;
219 options.i18n.pluralizationRules = this.$root.$i18n.pluralizationRules;
220 options.i18n.preserveDirectiveContent = this.$root.$i18n.preserveDirectiveContent;
221 }
222
223 // init locale messages via custom blocks
224 if (options.__i18n) {
225 try {
226 var localeMessages$1 = {};
227 options.__i18n.forEach(function (resource) {
228 localeMessages$1 = merge(localeMessages$1, JSON.parse(resource));
229 });
230 options.i18n.messages = localeMessages$1;
231 } catch (e) {
232 if (process.env.NODE_ENV !== 'production') {
233 warn("Cannot parse locale messages via custom blocks.", e);
234 }
235 }
236 }
237
238 this._i18n = new VueI18n(options.i18n);
239 this._i18nWatcher = this._i18n.watchI18nData();
240 this._i18n.subscribeDataChanging(this);
241 this._subscribing = true;
242
243 if (options.i18n.sync === undefined || !!options.i18n.sync) {
244 this._localeWatcher = this.$i18n.watchLocale();
245 }
246 } else {
247 if (process.env.NODE_ENV !== 'production') {
248 warn("Cannot be interpreted 'i18n' option.");
249 }
250 }
251 } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
252 // root i18n
253 this._i18n = this.$root.$i18n;
254 this._i18n.subscribeDataChanging(this);
255 this._subscribing = true;
256 } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) {
257 // parent i18n
258 this._i18n = options.parent.$i18n;
259 this._i18n.subscribeDataChanging(this);
260 this._subscribing = true;
261 }
262 },
263
264 beforeDestroy: function beforeDestroy () {
265 if (!this._i18n) { return }
266
267 var self = this;
268 this.$nextTick(function () {
269 if (self._subscribing) {
270 self._i18n.unsubscribeDataChanging(self);
271 delete self._subscribing;
272 }
273
274 if (self._i18nWatcher) {
275 self._i18nWatcher();
276 delete self._i18nWatcher;
277 }
278
279 if (self._localeWatcher) {
280 self._localeWatcher();
281 delete self._localeWatcher;
282 }
283
284 self._i18n = null;
285 });
286 }
287};
288
289/* */
290
291var component = {
292 name: 'i18n',
293 functional: true,
294 props: {
295 tag: {
296 type: String,
297 default: 'span'
298 },
299 path: {
300 type: String,
301 required: true
302 },
303 locale: {
304 type: String
305 },
306 places: {
307 type: [Array, Object]
308 }
309 },
310 render: function render (h, ref) {
311 var props = ref.props;
312 var data = ref.data;
313 var children = ref.children;
314 var parent = ref.parent;
315
316 var i18n = parent.$i18n;
317
318 children = (children || []).filter(function (child) {
319 return child.tag || (child.text = child.text.trim())
320 });
321
322 if (!i18n) {
323 if (process.env.NODE_ENV !== 'production') {
324 warn('Cannot find VueI18n instance!');
325 }
326 return children
327 }
328
329 var path = props.path;
330 var locale = props.locale;
331
332 var params = {};
333 var places = props.places || {};
334
335 var hasPlaces = Array.isArray(places)
336 ? places.length > 0
337 : Object.keys(places).length > 0;
338
339 var everyPlace = children.every(function (child) {
340 if (child.data && child.data.attrs) {
341 var place = child.data.attrs.place;
342 return (typeof place !== 'undefined') && place !== ''
343 }
344 });
345
346 if (process.env.NODE_ENV !== 'production' && hasPlaces && children.length > 0 && !everyPlace) {
347 warn('If places prop is set, all child elements must have place prop set.');
348 }
349
350 if (Array.isArray(places)) {
351 places.forEach(function (el, i) {
352 params[i] = el;
353 });
354 } else {
355 Object.keys(places).forEach(function (key) {
356 params[key] = places[key];
357 });
358 }
359
360 children.forEach(function (child, i) {
361 var key = everyPlace
362 ? ("" + (child.data.attrs.place))
363 : ("" + i);
364 params[key] = child;
365 });
366
367 return h(props.tag, data, i18n.i(path, locale, params))
368 }
369};
370
371/* */
372
373function bind (el, binding, vnode) {
374 if (!assert(el, vnode)) { return }
375
376 t(el, binding, vnode);
377}
378
379function update (el, binding, vnode, oldVNode) {
380 if (!assert(el, vnode)) { return }
381
382 var i18n = vnode.context.$i18n;
383 if (localeEqual(el, vnode) &&
384 (looseEqual(binding.value, binding.oldValue) &&
385 looseEqual(el._localeMessage, i18n.getLocaleMessage(i18n.locale)))) { return }
386
387 t(el, binding, vnode);
388}
389
390function unbind (el, binding, vnode, oldVNode) {
391 var vm = vnode.context;
392 if (!vm) {
393 warn('Vue instance does not exists in VNode context');
394 return
395 }
396
397 var i18n = vnode.context.$i18n || {};
398 if (!binding.modifiers.preserve && !i18n.preserveDirectiveContent) {
399 el.textContent = '';
400 }
401 el._vt = undefined;
402 delete el['_vt'];
403 el._locale = undefined;
404 delete el['_locale'];
405 el._localeMessage = undefined;
406 delete el['_localeMessage'];
407}
408
409function assert (el, vnode) {
410 var vm = vnode.context;
411 if (!vm) {
412 warn('Vue instance does not exists in VNode context');
413 return false
414 }
415
416 if (!vm.$i18n) {
417 warn('VueI18n instance does not exists in Vue instance');
418 return false
419 }
420
421 return true
422}
423
424function localeEqual (el, vnode) {
425 var vm = vnode.context;
426 return el._locale === vm.$i18n.locale
427}
428
429function t (el, binding, vnode) {
430 var ref$1, ref$2;
431
432 var value = binding.value;
433
434 var ref = parseValue(value);
435 var path = ref.path;
436 var locale = ref.locale;
437 var args = ref.args;
438 var choice = ref.choice;
439 if (!path && !locale && !args) {
440 warn('value type not supported');
441 return
442 }
443
444 if (!path) {
445 warn('`path` is required in v-t directive');
446 return
447 }
448
449 var vm = vnode.context;
450 if (choice) {
451 el._vt = el.textContent = (ref$1 = vm.$i18n).tc.apply(ref$1, [ path, choice ].concat( makeParams(locale, args) ));
452 } else {
453 el._vt = el.textContent = (ref$2 = vm.$i18n).t.apply(ref$2, [ path ].concat( makeParams(locale, args) ));
454 }
455 el._locale = vm.$i18n.locale;
456 el._localeMessage = vm.$i18n.getLocaleMessage(vm.$i18n.locale);
457}
458
459function parseValue (value) {
460 var path;
461 var locale;
462 var args;
463 var choice;
464
465 if (typeof value === 'string') {
466 path = value;
467 } else if (isPlainObject(value)) {
468 path = value.path;
469 locale = value.locale;
470 args = value.args;
471 choice = value.choice;
472 }
473
474 return { path: path, locale: locale, args: args, choice: choice }
475}
476
477function makeParams (locale, args) {
478 var params = [];
479
480 locale && params.push(locale);
481 if (args && (Array.isArray(args) || isPlainObject(args))) {
482 params.push(args);
483 }
484
485 return params
486}
487
488var Vue;
489
490function install (_Vue) {
491 /* istanbul ignore if */
492 if (process.env.NODE_ENV !== 'production' && install.installed && _Vue === Vue) {
493 warn('already installed.');
494 return
495 }
496 install.installed = true;
497
498 Vue = _Vue;
499
500 var version = (Vue.version && Number(Vue.version.split('.')[0])) || -1;
501 /* istanbul ignore if */
502 if (process.env.NODE_ENV !== 'production' && version < 2) {
503 warn(("vue-i18n (" + (install.version) + ") need to use Vue 2.0 or later (Vue: " + (Vue.version) + ")."));
504 return
505 }
506
507 extend(Vue);
508 Vue.mixin(mixin);
509 Vue.directive('t', { bind: bind, update: update, unbind: unbind });
510 Vue.component(component.name, component);
511
512 // use simple mergeStrategies to prevent i18n instance lose '__proto__'
513 var strats = Vue.config.optionMergeStrategies;
514 strats.i18n = function (parentVal, childVal) {
515 return childVal === undefined
516 ? parentVal
517 : childVal
518 };
519}
520
521/* */
522
523var BaseFormatter = function BaseFormatter () {
524 this._caches = Object.create(null);
525};
526
527BaseFormatter.prototype.interpolate = function interpolate (message, values) {
528 if (!values) {
529 return [message]
530 }
531 var tokens = this._caches[message];
532 if (!tokens) {
533 tokens = parse(message);
534 this._caches[message] = tokens;
535 }
536 return compile(tokens, values)
537};
538
539
540
541var RE_TOKEN_LIST_VALUE = /^(?:\d)+/;
542var RE_TOKEN_NAMED_VALUE = /^(?:\w)+/;
543
544function parse (format) {
545 var tokens = [];
546 var position = 0;
547
548 var text = '';
549 while (position < format.length) {
550 var char = format[position++];
551 if (char === '{') {
552 if (text) {
553 tokens.push({ type: 'text', value: text });
554 }
555
556 text = '';
557 var sub = '';
558 char = format[position++];
559 while (char !== undefined && char !== '}') {
560 sub += char;
561 char = format[position++];
562 }
563 var isClosed = char === '}';
564
565 var type = RE_TOKEN_LIST_VALUE.test(sub)
566 ? 'list'
567 : isClosed && RE_TOKEN_NAMED_VALUE.test(sub)
568 ? 'named'
569 : 'unknown';
570 tokens.push({ value: sub, type: type });
571 } else if (char === '%') {
572 // when found rails i18n syntax, skip text capture
573 if (format[(position)] !== '{') {
574 text += char;
575 }
576 } else {
577 text += char;
578 }
579 }
580
581 text && tokens.push({ type: 'text', value: text });
582
583 return tokens
584}
585
586function compile (tokens, values) {
587 var compiled = [];
588 var index = 0;
589
590 var mode = Array.isArray(values)
591 ? 'list'
592 : isObject(values)
593 ? 'named'
594 : 'unknown';
595 if (mode === 'unknown') { return compiled }
596
597 while (index < tokens.length) {
598 var token = tokens[index];
599 switch (token.type) {
600 case 'text':
601 compiled.push(token.value);
602 break
603 case 'list':
604 compiled.push(values[parseInt(token.value, 10)]);
605 break
606 case 'named':
607 if (mode === 'named') {
608 compiled.push((values)[token.value]);
609 } else {
610 if (process.env.NODE_ENV !== 'production') {
611 warn(("Type of token '" + (token.type) + "' and format of value '" + mode + "' don't match!"));
612 }
613 }
614 break
615 case 'unknown':
616 if (process.env.NODE_ENV !== 'production') {
617 warn("Detect 'unknown' type of token!");
618 }
619 break
620 }
621 index++;
622 }
623
624 return compiled
625}
626
627/* */
628
629/**
630 * Path parser
631 * - Inspired:
632 * Vue.js Path parser
633 */
634
635// actions
636var APPEND = 0;
637var PUSH = 1;
638var INC_SUB_PATH_DEPTH = 2;
639var PUSH_SUB_PATH = 3;
640
641// states
642var BEFORE_PATH = 0;
643var IN_PATH = 1;
644var BEFORE_IDENT = 2;
645var IN_IDENT = 3;
646var IN_SUB_PATH = 4;
647var IN_SINGLE_QUOTE = 5;
648var IN_DOUBLE_QUOTE = 6;
649var AFTER_PATH = 7;
650var ERROR = 8;
651
652var pathStateMachine = [];
653
654pathStateMachine[BEFORE_PATH] = {
655 'ws': [BEFORE_PATH],
656 'ident': [IN_IDENT, APPEND],
657 '[': [IN_SUB_PATH],
658 'eof': [AFTER_PATH]
659};
660
661pathStateMachine[IN_PATH] = {
662 'ws': [IN_PATH],
663 '.': [BEFORE_IDENT],
664 '[': [IN_SUB_PATH],
665 'eof': [AFTER_PATH]
666};
667
668pathStateMachine[BEFORE_IDENT] = {
669 'ws': [BEFORE_IDENT],
670 'ident': [IN_IDENT, APPEND],
671 '0': [IN_IDENT, APPEND],
672 'number': [IN_IDENT, APPEND]
673};
674
675pathStateMachine[IN_IDENT] = {
676 'ident': [IN_IDENT, APPEND],
677 '0': [IN_IDENT, APPEND],
678 'number': [IN_IDENT, APPEND],
679 'ws': [IN_PATH, PUSH],
680 '.': [BEFORE_IDENT, PUSH],
681 '[': [IN_SUB_PATH, PUSH],
682 'eof': [AFTER_PATH, PUSH]
683};
684
685pathStateMachine[IN_SUB_PATH] = {
686 "'": [IN_SINGLE_QUOTE, APPEND],
687 '"': [IN_DOUBLE_QUOTE, APPEND],
688 '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
689 ']': [IN_PATH, PUSH_SUB_PATH],
690 'eof': ERROR,
691 'else': [IN_SUB_PATH, APPEND]
692};
693
694pathStateMachine[IN_SINGLE_QUOTE] = {
695 "'": [IN_SUB_PATH, APPEND],
696 'eof': ERROR,
697 'else': [IN_SINGLE_QUOTE, APPEND]
698};
699
700pathStateMachine[IN_DOUBLE_QUOTE] = {
701 '"': [IN_SUB_PATH, APPEND],
702 'eof': ERROR,
703 'else': [IN_DOUBLE_QUOTE, APPEND]
704};
705
706/**
707 * Check if an expression is a literal value.
708 */
709
710var literalValueRE = /^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;
711function isLiteral (exp) {
712 return literalValueRE.test(exp)
713}
714
715/**
716 * Strip quotes from a string
717 */
718
719function stripQuotes (str) {
720 var a = str.charCodeAt(0);
721 var b = str.charCodeAt(str.length - 1);
722 return a === b && (a === 0x22 || a === 0x27)
723 ? str.slice(1, -1)
724 : str
725}
726
727/**
728 * Determine the type of a character in a keypath.
729 */
730
731function getPathCharType (ch) {
732 if (ch === undefined || ch === null) { return 'eof' }
733
734 var code = ch.charCodeAt(0);
735
736 switch (code) {
737 case 0x5B: // [
738 case 0x5D: // ]
739 case 0x2E: // .
740 case 0x22: // "
741 case 0x27: // '
742 return ch
743
744 case 0x5F: // _
745 case 0x24: // $
746 case 0x2D: // -
747 return 'ident'
748
749 case 0x20: // Space
750 case 0x09: // Tab
751 case 0x0A: // Newline
752 case 0x0D: // Return
753 case 0xA0: // No-break space
754 case 0xFEFF: // Byte Order Mark
755 case 0x2028: // Line Separator
756 case 0x2029: // Paragraph Separator
757 return 'ws'
758 }
759
760 return 'ident'
761}
762
763/**
764 * Format a subPath, return its plain form if it is
765 * a literal string or number. Otherwise prepend the
766 * dynamic indicator (*).
767 */
768
769function formatSubPath (path) {
770 var trimmed = path.trim();
771 // invalid leading 0
772 if (path.charAt(0) === '0' && isNaN(path)) { return false }
773
774 return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed
775}
776
777/**
778 * Parse a string path into an array of segments
779 */
780
781function parse$1 (path) {
782 var keys = [];
783 var index = -1;
784 var mode = BEFORE_PATH;
785 var subPathDepth = 0;
786 var c;
787 var key;
788 var newChar;
789 var type;
790 var transition;
791 var action;
792 var typeMap;
793 var actions = [];
794
795 actions[PUSH] = function () {
796 if (key !== undefined) {
797 keys.push(key);
798 key = undefined;
799 }
800 };
801
802 actions[APPEND] = function () {
803 if (key === undefined) {
804 key = newChar;
805 } else {
806 key += newChar;
807 }
808 };
809
810 actions[INC_SUB_PATH_DEPTH] = function () {
811 actions[APPEND]();
812 subPathDepth++;
813 };
814
815 actions[PUSH_SUB_PATH] = function () {
816 if (subPathDepth > 0) {
817 subPathDepth--;
818 mode = IN_SUB_PATH;
819 actions[APPEND]();
820 } else {
821 subPathDepth = 0;
822 key = formatSubPath(key);
823 if (key === false) {
824 return false
825 } else {
826 actions[PUSH]();
827 }
828 }
829 };
830
831 function maybeUnescapeQuote () {
832 var nextChar = path[index + 1];
833 if ((mode === IN_SINGLE_QUOTE && nextChar === "'") ||
834 (mode === IN_DOUBLE_QUOTE && nextChar === '"')) {
835 index++;
836 newChar = '\\' + nextChar;
837 actions[APPEND]();
838 return true
839 }
840 }
841
842 while (mode !== null) {
843 index++;
844 c = path[index];
845
846 if (c === '\\' && maybeUnescapeQuote()) {
847 continue
848 }
849
850 type = getPathCharType(c);
851 typeMap = pathStateMachine[mode];
852 transition = typeMap[type] || typeMap['else'] || ERROR;
853
854 if (transition === ERROR) {
855 return // parse error
856 }
857
858 mode = transition[0];
859 action = actions[transition[1]];
860 if (action) {
861 newChar = transition[2];
862 newChar = newChar === undefined
863 ? c
864 : newChar;
865 if (action() === false) {
866 return
867 }
868 }
869
870 if (mode === AFTER_PATH) {
871 return keys
872 }
873 }
874}
875
876
877
878
879
880var I18nPath = function I18nPath () {
881 this._cache = Object.create(null);
882};
883
884/**
885 * External parse that check for a cache hit first
886 */
887I18nPath.prototype.parsePath = function parsePath (path) {
888 var hit = this._cache[path];
889 if (!hit) {
890 hit = parse$1(path);
891 if (hit) {
892 this._cache[path] = hit;
893 }
894 }
895 return hit || []
896};
897
898/**
899 * Get path value from path string
900 */
901I18nPath.prototype.getPathValue = function getPathValue (obj, path) {
902 if (!isObject(obj)) { return null }
903
904 var paths = this.parsePath(path);
905 if (paths.length === 0) {
906 return null
907 } else {
908 var length = paths.length;
909 var last = obj;
910 var i = 0;
911 while (i < length) {
912 var value = last[paths[i]];
913 if (value === undefined) {
914 return null
915 }
916 last = value;
917 i++;
918 }
919
920 return last
921 }
922};
923
924/* */
925
926
927
928var numberFormatKeys = [
929 'style',
930 'currency',
931 'currencyDisplay',
932 'useGrouping',
933 'minimumIntegerDigits',
934 'minimumFractionDigits',
935 'maximumFractionDigits',
936 'minimumSignificantDigits',
937 'maximumSignificantDigits',
938 'localeMatcher',
939 'formatMatcher'
940];
941var linkKeyMatcher = /(?:@(?:\.[a-z]+)?:(?:[\w\-_|.]+|\([\w\-_|.]+\)))/g;
942var linkKeyPrefixMatcher = /^@(?:\.([a-z]+))?:/;
943var bracketsMatcher = /[()]/g;
944var formatters = {
945 'upper': function (str) { return str.toLocaleUpperCase(); },
946 'lower': function (str) { return str.toLocaleLowerCase(); }
947};
948
949var defaultFormatter = new BaseFormatter();
950
951var VueI18n = function VueI18n (options) {
952 var this$1 = this;
953 if ( options === void 0 ) options = {};
954
955 // Auto install if it is not done yet and `window` has `Vue`.
956 // To allow users to avoid auto-installation in some cases,
957 // this code should be placed here. See #290
958 /* istanbul ignore if */
959 if (!Vue && typeof window !== 'undefined' && window.Vue) {
960 install(window.Vue);
961 }
962
963 var locale = options.locale || 'en-US';
964 var fallbackLocale = options.fallbackLocale || 'en-US';
965 var messages = options.messages || {};
966 var dateTimeFormats = options.dateTimeFormats || {};
967 var numberFormats = options.numberFormats || {};
968
969 this._vm = null;
970 this._formatter = options.formatter || defaultFormatter;
971 this._missing = options.missing || null;
972 this._root = options.root || null;
973 this._sync = options.sync === undefined ? true : !!options.sync;
974 this._fallbackRoot = options.fallbackRoot === undefined
975 ? true
976 : !!options.fallbackRoot;
977 this._silentTranslationWarn = options.silentTranslationWarn === undefined
978 ? false
979 : !!options.silentTranslationWarn;
980 this._silentFallbackWarn = options.silentFallbackWarn === undefined
981 ? false
982 : !!options.silentFallbackWarn;
983 this._dateTimeFormatters = {};
984 this._numberFormatters = {};
985 this._path = new I18nPath();
986 this._dataListeners = [];
987 this._preserveDirectiveContent = options.preserveDirectiveContent === undefined
988 ? false
989 : !!options.preserveDirectiveContent;
990 this.pluralizationRules = options.pluralizationRules || {};
991
992 this._exist = function (message, key) {
993 if (!message || !key) { return false }
994 if (this$1._path.getPathValue(message, key)) { return true }
995 // fallback for flat key
996 if (message[key]) { return true }
997 return false
998 };
999
1000 this._initVM({
1001 locale: locale,
1002 fallbackLocale: fallbackLocale,
1003 messages: messages,
1004 dateTimeFormats: dateTimeFormats,
1005 numberFormats: numberFormats
1006 });
1007};
1008
1009var prototypeAccessors = { vm: { configurable: true },messages: { configurable: true },dateTimeFormats: { configurable: true },numberFormats: { configurable: true },locale: { configurable: true },fallbackLocale: { configurable: true },missing: { configurable: true },formatter: { configurable: true },silentTranslationWarn: { configurable: true },silentFallbackWarn: { configurable: true },preserveDirectiveContent: { configurable: true } };
1010
1011VueI18n.prototype._initVM = function _initVM (data) {
1012 var silent = Vue.config.silent;
1013 Vue.config.silent = true;
1014 this._vm = new Vue({ data: data });
1015 Vue.config.silent = silent;
1016};
1017
1018VueI18n.prototype.subscribeDataChanging = function subscribeDataChanging (vm) {
1019 this._dataListeners.push(vm);
1020};
1021
1022VueI18n.prototype.unsubscribeDataChanging = function unsubscribeDataChanging (vm) {
1023 remove(this._dataListeners, vm);
1024};
1025
1026VueI18n.prototype.watchI18nData = function watchI18nData () {
1027 var self = this;
1028 return this._vm.$watch('$data', function () {
1029 var i = self._dataListeners.length;
1030 while (i--) {
1031 Vue.nextTick(function () {
1032 self._dataListeners[i] && self._dataListeners[i].$forceUpdate();
1033 });
1034 }
1035 }, { deep: true })
1036};
1037
1038VueI18n.prototype.watchLocale = function watchLocale () {
1039 /* istanbul ignore if */
1040 if (!this._sync || !this._root) { return null }
1041 var target = this._vm;
1042 return this._root.$i18n.vm.$watch('locale', function (val) {
1043 target.$set(target, 'locale', val);
1044 target.$forceUpdate();
1045 }, { immediate: true })
1046};
1047
1048prototypeAccessors.vm.get = function () { return this._vm };
1049
1050prototypeAccessors.messages.get = function () { return looseClone(this._getMessages()) };
1051prototypeAccessors.dateTimeFormats.get = function () { return looseClone(this._getDateTimeFormats()) };
1052prototypeAccessors.numberFormats.get = function () { return looseClone(this._getNumberFormats()) };
1053
1054prototypeAccessors.locale.get = function () { return this._vm.locale };
1055prototypeAccessors.locale.set = function (locale) {
1056 this._vm.$set(this._vm, 'locale', locale);
1057};
1058
1059prototypeAccessors.fallbackLocale.get = function () { return this._vm.fallbackLocale };
1060prototypeAccessors.fallbackLocale.set = function (locale) {
1061 this._vm.$set(this._vm, 'fallbackLocale', locale);
1062};
1063
1064prototypeAccessors.missing.get = function () { return this._missing };
1065prototypeAccessors.missing.set = function (handler) { this._missing = handler; };
1066
1067prototypeAccessors.formatter.get = function () { return this._formatter };
1068prototypeAccessors.formatter.set = function (formatter) { this._formatter = formatter; };
1069
1070prototypeAccessors.silentTranslationWarn.get = function () { return this._silentTranslationWarn };
1071prototypeAccessors.silentTranslationWarn.set = function (silent) { this._silentTranslationWarn = silent; };
1072
1073prototypeAccessors.silentFallbackWarn.get = function () { return this._silentFallbackWarn };
1074prototypeAccessors.silentFallbackWarn.set = function (silent) { this._silentFallbackWarn = silent; };
1075
1076prototypeAccessors.preserveDirectiveContent.get = function () { return this._preserveDirectiveContent };
1077prototypeAccessors.preserveDirectiveContent.set = function (preserve) { this._preserveDirectiveContent = preserve; };
1078
1079VueI18n.prototype._getMessages = function _getMessages () { return this._vm.messages };
1080VueI18n.prototype._getDateTimeFormats = function _getDateTimeFormats () { return this._vm.dateTimeFormats };
1081VueI18n.prototype._getNumberFormats = function _getNumberFormats () { return this._vm.numberFormats };
1082
1083VueI18n.prototype._warnDefault = function _warnDefault (locale, key, result, vm, values) {
1084 if (!isNull(result)) { return result }
1085 if (this._missing) {
1086 var missingRet = this._missing.apply(null, [locale, key, vm, values]);
1087 if (typeof missingRet === 'string') {
1088 return missingRet
1089 }
1090 } else {
1091 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
1092 warn(
1093 "Cannot translate the value of keypath '" + key + "'. " +
1094 'Use the value of keypath as default.'
1095 );
1096 }
1097 }
1098 return key
1099};
1100
1101VueI18n.prototype._isFallbackRoot = function _isFallbackRoot (val) {
1102 return !val && !isNull(this._root) && this._fallbackRoot
1103};
1104
1105VueI18n.prototype._isSilentFallback = function _isSilentFallback (locale) {
1106 return this._silentFallbackWarn && (this._isFallbackRoot() || locale !== this.fallbackLocale)
1107};
1108
1109VueI18n.prototype._interpolate = function _interpolate (
1110 locale,
1111 message,
1112 key,
1113 host,
1114 interpolateMode,
1115 values,
1116 visitedLinkStack
1117) {
1118 if (!message) { return null }
1119
1120 var pathRet = this._path.getPathValue(message, key);
1121 if (Array.isArray(pathRet) || isPlainObject(pathRet)) { return pathRet }
1122
1123 var ret;
1124 if (isNull(pathRet)) {
1125 /* istanbul ignore else */
1126 if (isPlainObject(message)) {
1127 ret = message[key];
1128 if (typeof ret !== 'string') {
1129 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn && !this._isSilentFallback(locale)) {
1130 warn(("Value of key '" + key + "' is not a string!"));
1131 }
1132 return null
1133 }
1134 } else {
1135 return null
1136 }
1137 } else {
1138 /* istanbul ignore else */
1139 if (typeof pathRet === 'string') {
1140 ret = pathRet;
1141 } else {
1142 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn && !this._isSilentFallback(locale)) {
1143 warn(("Value of key '" + key + "' is not a string!"));
1144 }
1145 return null
1146 }
1147 }
1148
1149 // Check for the existence of links within the translated string
1150 if (ret.indexOf('@:') >= 0 || ret.indexOf('@.') >= 0) {
1151 ret = this._link(locale, message, ret, host, 'raw', values, visitedLinkStack);
1152 }
1153
1154 return this._render(ret, interpolateMode, values, key)
1155};
1156
1157VueI18n.prototype._link = function _link (
1158 locale,
1159 message,
1160 str,
1161 host,
1162 interpolateMode,
1163 values,
1164 visitedLinkStack
1165) {
1166 var this$1 = this;
1167
1168 var ret = str;
1169
1170 // Match all the links within the local
1171 // We are going to replace each of
1172 // them with its translation
1173 var matches = ret.match(linkKeyMatcher);
1174 for (var idx in matches) {
1175 // ie compatible: filter custom array
1176 // prototype method
1177 if (!matches.hasOwnProperty(idx)) {
1178 continue
1179 }
1180 var link = matches[idx];
1181 var linkKeyPrefixMatches = link.match(linkKeyPrefixMatcher);
1182 var linkPrefix = linkKeyPrefixMatches[0];
1183 var formatterName = linkKeyPrefixMatches[1];
1184
1185 // Remove the leading @:, @.case: and the brackets
1186 var linkPlaceholder = link.replace(linkPrefix, '').replace(bracketsMatcher, '');
1187
1188 if (visitedLinkStack.includes(linkPlaceholder)) {
1189 if (process.env.NODE_ENV !== 'production') {
1190 warn(("Circular reference found. \"" + link + "\" is already visited in the chain of " + (visitedLinkStack.reverse().join(' <- '))));
1191 }
1192 return ret
1193 }
1194 visitedLinkStack.push(linkPlaceholder);
1195
1196 // Translate the link
1197 var translated = this$1._interpolate(
1198 locale, message, linkPlaceholder, host,
1199 interpolateMode === 'raw' ? 'string' : interpolateMode,
1200 interpolateMode === 'raw' ? undefined : values,
1201 visitedLinkStack
1202 );
1203
1204 if (this$1._isFallbackRoot(translated)) {
1205 if (process.env.NODE_ENV !== 'production' && !this$1._silentTranslationWarn) {
1206 warn(("Fall back to translate the link placeholder '" + linkPlaceholder + "' with root locale."));
1207 }
1208 /* istanbul ignore if */
1209 if (!this$1._root) { throw Error('unexpected error') }
1210 var root = this$1._root.$i18n;
1211 translated = root._translate(
1212 root._getMessages(), root.locale, root.fallbackLocale,
1213 linkPlaceholder, host, interpolateMode, values
1214 );
1215 }
1216 translated = this$1._warnDefault(
1217 locale, linkPlaceholder, translated, host,
1218 Array.isArray(values) ? values : [values]
1219 );
1220 if (formatters.hasOwnProperty(formatterName)) {
1221 translated = formatters[formatterName](translated);
1222 }
1223
1224 visitedLinkStack.pop();
1225
1226 // Replace the link with the translated
1227 ret = !translated ? ret : ret.replace(link, translated);
1228 }
1229
1230 return ret
1231};
1232
1233VueI18n.prototype._render = function _render (message, interpolateMode, values, path) {
1234 var ret = this._formatter.interpolate(message, values, path);
1235
1236 // If the custom formatter refuses to work - apply the default one
1237 if (!ret) {
1238 ret = defaultFormatter.interpolate(message, values, path);
1239 }
1240
1241 // if interpolateMode is **not** 'string' ('row'),
1242 // return the compiled data (e.g. ['foo', VNode, 'bar']) with formatter
1243 return interpolateMode === 'string' ? ret.join('') : ret
1244};
1245
1246VueI18n.prototype._translate = function _translate (
1247 messages,
1248 locale,
1249 fallback,
1250 key,
1251 host,
1252 interpolateMode,
1253 args
1254) {
1255 var res =
1256 this._interpolate(locale, messages[locale], key, host, interpolateMode, args, [key]);
1257 if (!isNull(res)) { return res }
1258
1259 res = this._interpolate(fallback, messages[fallback], key, host, interpolateMode, args, [key]);
1260 if (!isNull(res)) {
1261 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn && !this._silentFallbackWarn) {
1262 warn(("Fall back to translate the keypath '" + key + "' with '" + fallback + "' locale."));
1263 }
1264 return res
1265 } else {
1266 return null
1267 }
1268};
1269
1270VueI18n.prototype._t = function _t (key, _locale, messages, host) {
1271 var ref;
1272
1273 var values = [], len = arguments.length - 4;
1274 while ( len-- > 0 ) values[ len ] = arguments[ len + 4 ];
1275 if (!key) { return '' }
1276
1277 var parsedArgs = parseArgs.apply(void 0, values);
1278 var locale = parsedArgs.locale || _locale;
1279
1280 var ret = this._translate(
1281 messages, locale, this.fallbackLocale, key,
1282 host, 'string', parsedArgs.params
1283 );
1284 if (this._isFallbackRoot(ret)) {
1285 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn && !this._silentFallbackWarn) {
1286 warn(("Fall back to translate the keypath '" + key + "' with root locale."));
1287 }
1288 /* istanbul ignore if */
1289 if (!this._root) { throw Error('unexpected error') }
1290 return (ref = this._root).$t.apply(ref, [ key ].concat( values ))
1291 } else {
1292 return this._warnDefault(locale, key, ret, host, values)
1293 }
1294};
1295
1296VueI18n.prototype.t = function t (key) {
1297 var ref;
1298
1299 var values = [], len = arguments.length - 1;
1300 while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
1301 return (ref = this)._t.apply(ref, [ key, this.locale, this._getMessages(), null ].concat( values ))
1302};
1303
1304VueI18n.prototype._i = function _i (key, locale, messages, host, values) {
1305 var ret =
1306 this._translate(messages, locale, this.fallbackLocale, key, host, 'raw', values);
1307 if (this._isFallbackRoot(ret)) {
1308 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
1309 warn(("Fall back to interpolate the keypath '" + key + "' with root locale."));
1310 }
1311 if (!this._root) { throw Error('unexpected error') }
1312 return this._root.$i18n.i(key, locale, values)
1313 } else {
1314 return this._warnDefault(locale, key, ret, host, [values])
1315 }
1316};
1317
1318VueI18n.prototype.i = function i (key, locale, values) {
1319 /* istanbul ignore if */
1320 if (!key) { return '' }
1321
1322 if (typeof locale !== 'string') {
1323 locale = this.locale;
1324 }
1325
1326 return this._i(key, locale, this._getMessages(), null, values)
1327};
1328
1329VueI18n.prototype._tc = function _tc (
1330 key,
1331 _locale,
1332 messages,
1333 host,
1334 choice
1335) {
1336 var ref;
1337
1338 var values = [], len = arguments.length - 5;
1339 while ( len-- > 0 ) values[ len ] = arguments[ len + 5 ];
1340 if (!key) { return '' }
1341 if (choice === undefined) {
1342 choice = 1;
1343 }
1344
1345 var predefined = { 'count': choice, 'n': choice };
1346 var parsedArgs = parseArgs.apply(void 0, values);
1347 parsedArgs.params = Object.assign(predefined, parsedArgs.params);
1348 values = parsedArgs.locale === null ? [parsedArgs.params] : [parsedArgs.locale, parsedArgs.params];
1349 return this.fetchChoice((ref = this)._t.apply(ref, [ key, _locale, messages, host ].concat( values )), choice)
1350};
1351
1352VueI18n.prototype.fetchChoice = function fetchChoice (message, choice) {
1353 /* istanbul ignore if */
1354 if (!message && typeof message !== 'string') { return null }
1355 var choices = message.split('|');
1356
1357 choice = this.getChoiceIndex(choice, choices.length);
1358 if (!choices[choice]) { return message }
1359 return choices[choice].trim()
1360};
1361
1362/**
1363 * @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
1364 * @param choicesLength {number} an overall amount of available choices
1365 * @returns a final choice index
1366*/
1367VueI18n.prototype.getChoiceIndex = function getChoiceIndex (choice, choicesLength) {
1368 // Default (old) getChoiceIndex implementation - english-compatible
1369 var defaultImpl = function (_choice, _choicesLength) {
1370 _choice = Math.abs(_choice);
1371
1372 if (_choicesLength === 2) {
1373 return _choice
1374 ? _choice > 1
1375 ? 1
1376 : 0
1377 : 1
1378 }
1379
1380 return _choice ? Math.min(_choice, 2) : 0
1381 };
1382
1383 if (this.locale in this.pluralizationRules) {
1384 return this.pluralizationRules[this.locale].apply(this, [choice, choicesLength])
1385 } else {
1386 return defaultImpl(choice, choicesLength)
1387 }
1388};
1389
1390VueI18n.prototype.tc = function tc (key, choice) {
1391 var ref;
1392
1393 var values = [], len = arguments.length - 2;
1394 while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ];
1395 return (ref = this)._tc.apply(ref, [ key, this.locale, this._getMessages(), null, choice ].concat( values ))
1396};
1397
1398VueI18n.prototype._te = function _te (key, locale, messages) {
1399 var args = [], len = arguments.length - 3;
1400 while ( len-- > 0 ) args[ len ] = arguments[ len + 3 ];
1401
1402 var _locale = parseArgs.apply(void 0, args).locale || locale;
1403 return this._exist(messages[_locale], key)
1404};
1405
1406VueI18n.prototype.te = function te (key, locale) {
1407 return this._te(key, this.locale, this._getMessages(), locale)
1408};
1409
1410VueI18n.prototype.getLocaleMessage = function getLocaleMessage (locale) {
1411 return looseClone(this._vm.messages[locale] || {})
1412};
1413
1414VueI18n.prototype.setLocaleMessage = function setLocaleMessage (locale, message) {
1415 this._vm.$set(this._vm.messages, locale, message);
1416};
1417
1418VueI18n.prototype.mergeLocaleMessage = function mergeLocaleMessage (locale, message) {
1419 this._vm.$set(this._vm.messages, locale, merge(this._vm.messages[locale] || {}, message));
1420};
1421
1422VueI18n.prototype.getDateTimeFormat = function getDateTimeFormat (locale) {
1423 return looseClone(this._vm.dateTimeFormats[locale] || {})
1424};
1425
1426VueI18n.prototype.setDateTimeFormat = function setDateTimeFormat (locale, format) {
1427 this._vm.$set(this._vm.dateTimeFormats, locale, format);
1428};
1429
1430VueI18n.prototype.mergeDateTimeFormat = function mergeDateTimeFormat (locale, format) {
1431 this._vm.$set(this._vm.dateTimeFormats, locale, merge(this._vm.dateTimeFormats[locale] || {}, format));
1432};
1433
1434VueI18n.prototype._localizeDateTime = function _localizeDateTime (
1435 value,
1436 locale,
1437 fallback,
1438 dateTimeFormats,
1439 key
1440) {
1441 var _locale = locale;
1442 var formats = dateTimeFormats[_locale];
1443
1444 // fallback locale
1445 if (isNull(formats) || isNull(formats[key])) {
1446 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
1447 warn(("Fall back to '" + fallback + "' datetime formats from '" + locale + " datetime formats."));
1448 }
1449 _locale = fallback;
1450 formats = dateTimeFormats[_locale];
1451 }
1452
1453 if (isNull(formats) || isNull(formats[key])) {
1454 return null
1455 } else {
1456 var format = formats[key];
1457 var id = _locale + "__" + key;
1458 var formatter = this._dateTimeFormatters[id];
1459 if (!formatter) {
1460 formatter = this._dateTimeFormatters[id] = new Intl.DateTimeFormat(_locale, format);
1461 }
1462 return formatter.format(value)
1463 }
1464};
1465
1466VueI18n.prototype._d = function _d (value, locale, key) {
1467 /* istanbul ignore if */
1468 if (process.env.NODE_ENV !== 'production' && !VueI18n.availabilities.dateTimeFormat) {
1469 warn('Cannot format a Date value due to not supported Intl.DateTimeFormat.');
1470 return ''
1471 }
1472
1473 if (!key) {
1474 return new Intl.DateTimeFormat(locale).format(value)
1475 }
1476
1477 var ret =
1478 this._localizeDateTime(value, locale, this.fallbackLocale, this._getDateTimeFormats(), key);
1479 if (this._isFallbackRoot(ret)) {
1480 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
1481 warn(("Fall back to datetime localization of root: key '" + key + "' ."));
1482 }
1483 /* istanbul ignore if */
1484 if (!this._root) { throw Error('unexpected error') }
1485 return this._root.$i18n.d(value, key, locale)
1486 } else {
1487 return ret || ''
1488 }
1489};
1490
1491VueI18n.prototype.d = function d (value) {
1492 var args = [], len = arguments.length - 1;
1493 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
1494
1495 var locale = this.locale;
1496 var key = null;
1497
1498 if (args.length === 1) {
1499 if (typeof args[0] === 'string') {
1500 key = args[0];
1501 } else if (isObject(args[0])) {
1502 if (args[0].locale) {
1503 locale = args[0].locale;
1504 }
1505 if (args[0].key) {
1506 key = args[0].key;
1507 }
1508 }
1509 } else if (args.length === 2) {
1510 if (typeof args[0] === 'string') {
1511 key = args[0];
1512 }
1513 if (typeof args[1] === 'string') {
1514 locale = args[1];
1515 }
1516 }
1517
1518 return this._d(value, locale, key)
1519};
1520
1521VueI18n.prototype.getNumberFormat = function getNumberFormat (locale) {
1522 return looseClone(this._vm.numberFormats[locale] || {})
1523};
1524
1525VueI18n.prototype.setNumberFormat = function setNumberFormat (locale, format) {
1526 this._vm.$set(this._vm.numberFormats, locale, format);
1527};
1528
1529VueI18n.prototype.mergeNumberFormat = function mergeNumberFormat (locale, format) {
1530 this._vm.$set(this._vm.numberFormats, locale, merge(this._vm.numberFormats[locale] || {}, format));
1531};
1532
1533VueI18n.prototype._localizeNumber = function _localizeNumber (
1534 value,
1535 locale,
1536 fallback,
1537 numberFormats,
1538 key,
1539 options
1540) {
1541 var _locale = locale;
1542 var formats = numberFormats[_locale];
1543
1544 // fallback locale
1545 if (isNull(formats) || isNull(formats[key])) {
1546 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
1547 warn(("Fall back to '" + fallback + "' number formats from '" + locale + " number formats."));
1548 }
1549 _locale = fallback;
1550 formats = numberFormats[_locale];
1551 }
1552
1553 if (isNull(formats) || isNull(formats[key])) {
1554 return null
1555 } else {
1556 var format = formats[key];
1557
1558 var formatter;
1559 if (options) {
1560 // If options specified - create one time number formatter
1561 formatter = new Intl.NumberFormat(_locale, Object.assign({}, format, options));
1562 } else {
1563 var id = _locale + "__" + key;
1564 formatter = this._numberFormatters[id];
1565 if (!formatter) {
1566 formatter = this._numberFormatters[id] = new Intl.NumberFormat(_locale, format);
1567 }
1568 }
1569 return formatter.format(value)
1570 }
1571};
1572
1573VueI18n.prototype._n = function _n (value, locale, key, options) {
1574 /* istanbul ignore if */
1575 if (!VueI18n.availabilities.numberFormat) {
1576 if (process.env.NODE_ENV !== 'production') {
1577 warn('Cannot format a Number value due to not supported Intl.NumberFormat.');
1578 }
1579 return ''
1580 }
1581
1582 if (!key) {
1583 var nf = !options ? new Intl.NumberFormat(locale) : new Intl.NumberFormat(locale, options);
1584 return nf.format(value)
1585 }
1586
1587 var ret =
1588 this._localizeNumber(value, locale, this.fallbackLocale, this._getNumberFormats(), key, options);
1589 if (this._isFallbackRoot(ret)) {
1590 if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
1591 warn(("Fall back to number localization of root: key '" + key + "' ."));
1592 }
1593 /* istanbul ignore if */
1594 if (!this._root) { throw Error('unexpected error') }
1595 return this._root.$i18n.n(value, Object.assign({}, { key: key, locale: locale }, options))
1596 } else {
1597 return ret || ''
1598 }
1599};
1600
1601VueI18n.prototype.n = function n (value) {
1602 var args = [], len = arguments.length - 1;
1603 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
1604
1605 var locale = this.locale;
1606 var key = null;
1607 var options = null;
1608
1609 if (args.length === 1) {
1610 if (typeof args[0] === 'string') {
1611 key = args[0];
1612 } else if (isObject(args[0])) {
1613 if (args[0].locale) {
1614 locale = args[0].locale;
1615 }
1616 if (args[0].key) {
1617 key = args[0].key;
1618 }
1619
1620 // Filter out number format options only
1621 options = Object.keys(args[0]).reduce(function (acc, key) {
1622 var obj;
1623
1624 if (numberFormatKeys.includes(key)) {
1625 return Object.assign({}, acc, ( obj = {}, obj[key] = args[0][key], obj ))
1626 }
1627 return acc
1628 }, null);
1629 }
1630 } else if (args.length === 2) {
1631 if (typeof args[0] === 'string') {
1632 key = args[0];
1633 }
1634 if (typeof args[1] === 'string') {
1635 locale = args[1];
1636 }
1637 }
1638
1639 return this._n(value, locale, key, options)
1640};
1641
1642Object.defineProperties( VueI18n.prototype, prototypeAccessors );
1643
1644var availabilities;
1645// $FlowFixMe
1646Object.defineProperty(VueI18n, 'availabilities', {
1647 get: function get () {
1648 if (!availabilities) {
1649 var intlDefined = typeof Intl !== 'undefined';
1650 availabilities = {
1651 dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined',
1652 numberFormat: intlDefined && typeof Intl.NumberFormat !== 'undefined'
1653 };
1654 }
1655
1656 return availabilities
1657 }
1658});
1659
1660VueI18n.install = install;
1661VueI18n.version = '8.8.1';
1662
1663export default VueI18n;