UNPKG

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