UNPKG

81.6 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 typeof define === 'function' && define.amd ? define(factory) :
4 (global = global || self, global.i18next = factory());
5}(this, function () { 'use strict';
6
7 function _typeof(obj) {
8 "@babel/helpers - typeof";
9
10 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
11 _typeof = function _typeof(obj) {
12 return typeof obj;
13 };
14 } else {
15 _typeof = function _typeof(obj) {
16 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
17 };
18 }
19
20 return _typeof(obj);
21 }
22
23 function _defineProperty(obj, key, value) {
24 if (key in obj) {
25 Object.defineProperty(obj, key, {
26 value: value,
27 enumerable: true,
28 configurable: true,
29 writable: true
30 });
31 } else {
32 obj[key] = value;
33 }
34
35 return obj;
36 }
37
38 function _objectSpread(target) {
39 for (var i = 1; i < arguments.length; i++) {
40 var source = arguments[i] != null ? Object(arguments[i]) : {};
41 var ownKeys = Object.keys(source);
42
43 if (typeof Object.getOwnPropertySymbols === 'function') {
44 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
45 return Object.getOwnPropertyDescriptor(source, sym).enumerable;
46 }));
47 }
48
49 ownKeys.forEach(function (key) {
50 _defineProperty(target, key, source[key]);
51 });
52 }
53
54 return target;
55 }
56
57 function _classCallCheck(instance, Constructor) {
58 if (!(instance instanceof Constructor)) {
59 throw new TypeError("Cannot call a class as a function");
60 }
61 }
62
63 function _defineProperties(target, props) {
64 for (var i = 0; i < props.length; i++) {
65 var descriptor = props[i];
66 descriptor.enumerable = descriptor.enumerable || false;
67 descriptor.configurable = true;
68 if ("value" in descriptor) descriptor.writable = true;
69 Object.defineProperty(target, descriptor.key, descriptor);
70 }
71 }
72
73 function _createClass(Constructor, protoProps, staticProps) {
74 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
75 if (staticProps) _defineProperties(Constructor, staticProps);
76 return Constructor;
77 }
78
79 function _assertThisInitialized(self) {
80 if (self === void 0) {
81 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
82 }
83
84 return self;
85 }
86
87 function _possibleConstructorReturn(self, call) {
88 if (call && (_typeof(call) === "object" || typeof call === "function")) {
89 return call;
90 }
91
92 return _assertThisInitialized(self);
93 }
94
95 function _getPrototypeOf(o) {
96 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
97 return o.__proto__ || Object.getPrototypeOf(o);
98 };
99 return _getPrototypeOf(o);
100 }
101
102 function _setPrototypeOf(o, p) {
103 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
104 o.__proto__ = p;
105 return o;
106 };
107
108 return _setPrototypeOf(o, p);
109 }
110
111 function _inherits(subClass, superClass) {
112 if (typeof superClass !== "function" && superClass !== null) {
113 throw new TypeError("Super expression must either be null or a function");
114 }
115
116 subClass.prototype = Object.create(superClass && superClass.prototype, {
117 constructor: {
118 value: subClass,
119 writable: true,
120 configurable: true
121 }
122 });
123 if (superClass) _setPrototypeOf(subClass, superClass);
124 }
125
126 var consoleLogger = {
127 type: 'logger',
128 log: function log(args) {
129 this.output('log', args);
130 },
131 warn: function warn(args) {
132 this.output('warn', args);
133 },
134 error: function error(args) {
135 this.output('error', args);
136 },
137 output: function output(type, args) {
138 if (console && console[type]) console[type].apply(console, args);
139 }
140 };
141
142 var Logger = function () {
143 function Logger(concreteLogger) {
144 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
145
146 _classCallCheck(this, Logger);
147
148 this.init(concreteLogger, options);
149 }
150
151 _createClass(Logger, [{
152 key: "init",
153 value: function init(concreteLogger) {
154 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
155 this.prefix = options.prefix || 'i18next:';
156 this.logger = concreteLogger || consoleLogger;
157 this.options = options;
158 this.debug = options.debug;
159 }
160 }, {
161 key: "setDebug",
162 value: function setDebug(bool) {
163 this.debug = bool;
164 }
165 }, {
166 key: "log",
167 value: function log() {
168 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
169 args[_key] = arguments[_key];
170 }
171
172 return this.forward(args, 'log', '', true);
173 }
174 }, {
175 key: "warn",
176 value: function warn() {
177 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
178 args[_key2] = arguments[_key2];
179 }
180
181 return this.forward(args, 'warn', '', true);
182 }
183 }, {
184 key: "error",
185 value: function error() {
186 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
187 args[_key3] = arguments[_key3];
188 }
189
190 return this.forward(args, 'error', '');
191 }
192 }, {
193 key: "deprecate",
194 value: function deprecate() {
195 for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
196 args[_key4] = arguments[_key4];
197 }
198
199 return this.forward(args, 'warn', 'WARNING DEPRECATED: ', true);
200 }
201 }, {
202 key: "forward",
203 value: function forward(args, lvl, prefix, debugOnly) {
204 if (debugOnly && !this.debug) return null;
205 if (typeof args[0] === 'string') args[0] = "".concat(prefix).concat(this.prefix, " ").concat(args[0]);
206 return this.logger[lvl](args);
207 }
208 }, {
209 key: "create",
210 value: function create(moduleName) {
211 return new Logger(this.logger, _objectSpread({}, {
212 prefix: "".concat(this.prefix, ":").concat(moduleName, ":")
213 }, this.options));
214 }
215 }]);
216
217 return Logger;
218 }();
219
220 var baseLogger = new Logger();
221
222 var EventEmitter = function () {
223 function EventEmitter() {
224 _classCallCheck(this, EventEmitter);
225
226 this.observers = {};
227 }
228
229 _createClass(EventEmitter, [{
230 key: "on",
231 value: function on(events, listener) {
232 var _this = this;
233
234 events.split(' ').forEach(function (event) {
235 _this.observers[event] = _this.observers[event] || [];
236
237 _this.observers[event].push(listener);
238 });
239 return this;
240 }
241 }, {
242 key: "off",
243 value: function off(event, listener) {
244 if (!this.observers[event]) return;
245
246 if (!listener) {
247 delete this.observers[event];
248 return;
249 }
250
251 this.observers[event] = this.observers[event].filter(function (l) {
252 return l !== listener;
253 });
254 }
255 }, {
256 key: "emit",
257 value: function emit(event) {
258 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
259 args[_key - 1] = arguments[_key];
260 }
261
262 if (this.observers[event]) {
263 var cloned = [].concat(this.observers[event]);
264 cloned.forEach(function (observer) {
265 observer.apply(void 0, args);
266 });
267 }
268
269 if (this.observers['*']) {
270 var _cloned = [].concat(this.observers['*']);
271
272 _cloned.forEach(function (observer) {
273 observer.apply(observer, [event].concat(args));
274 });
275 }
276 }
277 }]);
278
279 return EventEmitter;
280 }();
281
282 function defer() {
283 var res;
284 var rej;
285 var promise = new Promise(function (resolve, reject) {
286 res = resolve;
287 rej = reject;
288 });
289 promise.resolve = res;
290 promise.reject = rej;
291 return promise;
292 }
293 function makeString(object) {
294 if (object == null) return '';
295 return '' + object;
296 }
297 function copy(a, s, t) {
298 a.forEach(function (m) {
299 if (s[m]) t[m] = s[m];
300 });
301 }
302
303 function getLastOfPath(object, path, Empty) {
304 function cleanKey(key) {
305 return key && key.indexOf('###') > -1 ? key.replace(/###/g, '.') : key;
306 }
307
308 function canNotTraverseDeeper() {
309 return !object || typeof object === 'string';
310 }
311
312 var stack = typeof path !== 'string' ? [].concat(path) : path.split('.');
313
314 while (stack.length > 1) {
315 if (canNotTraverseDeeper()) return {};
316 var key = cleanKey(stack.shift());
317 if (!object[key] && Empty) object[key] = new Empty();
318 object = object[key];
319 }
320
321 if (canNotTraverseDeeper()) return {};
322 return {
323 obj: object,
324 k: cleanKey(stack.shift())
325 };
326 }
327
328 function setPath(object, path, newValue) {
329 var _getLastOfPath = getLastOfPath(object, path, Object),
330 obj = _getLastOfPath.obj,
331 k = _getLastOfPath.k;
332
333 obj[k] = newValue;
334 }
335 function pushPath(object, path, newValue, concat) {
336 var _getLastOfPath2 = getLastOfPath(object, path, Object),
337 obj = _getLastOfPath2.obj,
338 k = _getLastOfPath2.k;
339
340 obj[k] = obj[k] || [];
341 if (concat) obj[k] = obj[k].concat(newValue);
342 if (!concat) obj[k].push(newValue);
343 }
344 function getPath(object, path) {
345 var _getLastOfPath3 = getLastOfPath(object, path),
346 obj = _getLastOfPath3.obj,
347 k = _getLastOfPath3.k;
348
349 if (!obj) return undefined;
350 return obj[k];
351 }
352 function getPathWithDefaults(data, defaultData, key) {
353 var value = getPath(data, key);
354
355 if (value !== undefined) {
356 return value;
357 }
358
359 return getPath(defaultData, key);
360 }
361 function deepExtend(target, source, overwrite) {
362 for (var prop in source) {
363 if (prop !== '__proto__') {
364 if (prop in target) {
365 if (typeof target[prop] === 'string' || target[prop] instanceof String || typeof source[prop] === 'string' || source[prop] instanceof String) {
366 if (overwrite) target[prop] = source[prop];
367 } else {
368 deepExtend(target[prop], source[prop], overwrite);
369 }
370 } else {
371 target[prop] = source[prop];
372 }
373 }
374 }
375
376 return target;
377 }
378 function regexEscape(str) {
379 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
380 }
381 var _entityMap = {
382 '&': '&amp;',
383 '<': '&lt;',
384 '>': '&gt;',
385 '"': '&quot;',
386 "'": '&#39;',
387 '/': '&#x2F;'
388 };
389 function escape(data) {
390 if (typeof data === 'string') {
391 return data.replace(/[&<>"'\/]/g, function (s) {
392 return _entityMap[s];
393 });
394 }
395
396 return data;
397 }
398 var isIE10 = typeof window !== 'undefined' && window.navigator && window.navigator.userAgent && window.navigator.userAgent.indexOf('MSIE') > -1;
399
400 var ResourceStore = function (_EventEmitter) {
401 _inherits(ResourceStore, _EventEmitter);
402
403 function ResourceStore(data) {
404 var _this;
405
406 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
407 ns: ['translation'],
408 defaultNS: 'translation'
409 };
410
411 _classCallCheck(this, ResourceStore);
412
413 _this = _possibleConstructorReturn(this, _getPrototypeOf(ResourceStore).call(this));
414
415 if (isIE10) {
416 EventEmitter.call(_assertThisInitialized(_this));
417 }
418
419 _this.data = data || {};
420 _this.options = options;
421
422 if (_this.options.keySeparator === undefined) {
423 _this.options.keySeparator = '.';
424 }
425
426 return _this;
427 }
428
429 _createClass(ResourceStore, [{
430 key: "addNamespaces",
431 value: function addNamespaces(ns) {
432 if (this.options.ns.indexOf(ns) < 0) {
433 this.options.ns.push(ns);
434 }
435 }
436 }, {
437 key: "removeNamespaces",
438 value: function removeNamespaces(ns) {
439 var index = this.options.ns.indexOf(ns);
440
441 if (index > -1) {
442 this.options.ns.splice(index, 1);
443 }
444 }
445 }, {
446 key: "getResource",
447 value: function getResource(lng, ns, key) {
448 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
449 var keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
450 var path = [lng, ns];
451 if (key && typeof key !== 'string') path = path.concat(key);
452 if (key && typeof key === 'string') path = path.concat(keySeparator ? key.split(keySeparator) : key);
453
454 if (lng.indexOf('.') > -1) {
455 path = lng.split('.');
456 }
457
458 return getPath(this.data, path);
459 }
460 }, {
461 key: "addResource",
462 value: function addResource(lng, ns, key, value) {
463 var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
464 silent: false
465 };
466 var keySeparator = this.options.keySeparator;
467 if (keySeparator === undefined) keySeparator = '.';
468 var path = [lng, ns];
469 if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
470
471 if (lng.indexOf('.') > -1) {
472 path = lng.split('.');
473 value = ns;
474 ns = path[1];
475 }
476
477 this.addNamespaces(ns);
478 setPath(this.data, path, value);
479 if (!options.silent) this.emit('added', lng, ns, key, value);
480 }
481 }, {
482 key: "addResources",
483 value: function addResources(lng, ns, resources) {
484 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
485 silent: false
486 };
487
488 for (var m in resources) {
489 if (typeof resources[m] === 'string' || Object.prototype.toString.apply(resources[m]) === '[object Array]') this.addResource(lng, ns, m, resources[m], {
490 silent: true
491 });
492 }
493
494 if (!options.silent) this.emit('added', lng, ns, resources);
495 }
496 }, {
497 key: "addResourceBundle",
498 value: function addResourceBundle(lng, ns, resources, deep, overwrite) {
499 var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
500 silent: false
501 };
502 var path = [lng, ns];
503
504 if (lng.indexOf('.') > -1) {
505 path = lng.split('.');
506 deep = resources;
507 resources = ns;
508 ns = path[1];
509 }
510
511 this.addNamespaces(ns);
512 var pack = getPath(this.data, path) || {};
513
514 if (deep) {
515 deepExtend(pack, resources, overwrite);
516 } else {
517 pack = _objectSpread({}, pack, resources);
518 }
519
520 setPath(this.data, path, pack);
521 if (!options.silent) this.emit('added', lng, ns, resources);
522 }
523 }, {
524 key: "removeResourceBundle",
525 value: function removeResourceBundle(lng, ns) {
526 if (this.hasResourceBundle(lng, ns)) {
527 delete this.data[lng][ns];
528 }
529
530 this.removeNamespaces(ns);
531 this.emit('removed', lng, ns);
532 }
533 }, {
534 key: "hasResourceBundle",
535 value: function hasResourceBundle(lng, ns) {
536 return this.getResource(lng, ns) !== undefined;
537 }
538 }, {
539 key: "getResourceBundle",
540 value: function getResourceBundle(lng, ns) {
541 if (!ns) ns = this.options.defaultNS;
542 if (this.options.compatibilityAPI === 'v1') return _objectSpread({}, {}, this.getResource(lng, ns));
543 return this.getResource(lng, ns);
544 }
545 }, {
546 key: "getDataByLanguage",
547 value: function getDataByLanguage(lng) {
548 return this.data[lng];
549 }
550 }, {
551 key: "toJSON",
552 value: function toJSON() {
553 return this.data;
554 }
555 }]);
556
557 return ResourceStore;
558 }(EventEmitter);
559
560 var postProcessor = {
561 processors: {},
562 addPostProcessor: function addPostProcessor(module) {
563 this.processors[module.name] = module;
564 },
565 handle: function handle(processors, value, key, options, translator) {
566 var _this = this;
567
568 processors.forEach(function (processor) {
569 if (_this.processors[processor]) value = _this.processors[processor].process(value, key, options, translator);
570 });
571 return value;
572 }
573 };
574
575 var checkedLoadedFor = {};
576
577 var Translator = function (_EventEmitter) {
578 _inherits(Translator, _EventEmitter);
579
580 function Translator(services) {
581 var _this;
582
583 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
584
585 _classCallCheck(this, Translator);
586
587 _this = _possibleConstructorReturn(this, _getPrototypeOf(Translator).call(this));
588
589 if (isIE10) {
590 EventEmitter.call(_assertThisInitialized(_this));
591 }
592
593 copy(['resourceStore', 'languageUtils', 'pluralResolver', 'interpolator', 'backendConnector', 'i18nFormat', 'utils'], services, _assertThisInitialized(_this));
594 _this.options = options;
595
596 if (_this.options.keySeparator === undefined) {
597 _this.options.keySeparator = '.';
598 }
599
600 _this.logger = baseLogger.create('translator');
601 return _this;
602 }
603
604 _createClass(Translator, [{
605 key: "changeLanguage",
606 value: function changeLanguage(lng) {
607 if (lng) this.language = lng;
608 }
609 }, {
610 key: "exists",
611 value: function exists(key) {
612 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
613 interpolation: {}
614 };
615 var resolved = this.resolve(key, options);
616 return resolved && resolved.res !== undefined;
617 }
618 }, {
619 key: "extractFromKey",
620 value: function extractFromKey(key, options) {
621 var nsSeparator = options.nsSeparator !== undefined ? options.nsSeparator : this.options.nsSeparator;
622 if (nsSeparator === undefined) nsSeparator = ':';
623 var keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
624 var namespaces = options.ns || this.options.defaultNS;
625
626 if (nsSeparator && key.indexOf(nsSeparator) > -1) {
627 var m = key.match(this.interpolator.nestingRegexp);
628
629 if (m && m.length > 0) {
630 return {
631 key: key,
632 namespaces: namespaces
633 };
634 }
635
636 var parts = key.split(nsSeparator);
637 if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift();
638 key = parts.join(keySeparator);
639 }
640
641 if (typeof namespaces === 'string') namespaces = [namespaces];
642 return {
643 key: key,
644 namespaces: namespaces
645 };
646 }
647 }, {
648 key: "translate",
649 value: function translate(keys, options, lastKey) {
650 var _this2 = this;
651
652 if (_typeof(options) !== 'object' && this.options.overloadTranslationOptionHandler) {
653 options = this.options.overloadTranslationOptionHandler(arguments);
654 }
655
656 if (!options) options = {};
657 if (keys === undefined || keys === null) return '';
658 if (!Array.isArray(keys)) keys = [String(keys)];
659 var keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
660
661 var _this$extractFromKey = this.extractFromKey(keys[keys.length - 1], options),
662 key = _this$extractFromKey.key,
663 namespaces = _this$extractFromKey.namespaces;
664
665 var namespace = namespaces[namespaces.length - 1];
666 var lng = options.lng || this.language;
667 var appendNamespaceToCIMode = options.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode;
668
669 if (lng && lng.toLowerCase() === 'cimode') {
670 if (appendNamespaceToCIMode) {
671 var nsSeparator = options.nsSeparator || this.options.nsSeparator;
672 return namespace + nsSeparator + key;
673 }
674
675 return key;
676 }
677
678 var resolved = this.resolve(keys, options);
679 var res = resolved && resolved.res;
680 var resUsedKey = resolved && resolved.usedKey || key;
681 var resExactUsedKey = resolved && resolved.exactUsedKey || key;
682 var resType = Object.prototype.toString.apply(res);
683 var noObject = ['[object Number]', '[object Function]', '[object RegExp]'];
684 var joinArrays = options.joinArrays !== undefined ? options.joinArrays : this.options.joinArrays;
685 var handleAsObjectInI18nFormat = !this.i18nFormat || this.i18nFormat.handleAsObject;
686 var handleAsObject = typeof res !== 'string' && typeof res !== 'boolean' && typeof res !== 'number';
687
688 if (handleAsObjectInI18nFormat && res && handleAsObject && noObject.indexOf(resType) < 0 && !(typeof joinArrays === 'string' && resType === '[object Array]')) {
689 if (!options.returnObjects && !this.options.returnObjects) {
690 this.logger.warn('accessing an object - but returnObjects options is not enabled!');
691 return this.options.returnedObjectHandler ? this.options.returnedObjectHandler(resUsedKey, res, options) : "key '".concat(key, " (").concat(this.language, ")' returned an object instead of string.");
692 }
693
694 if (keySeparator) {
695 var resTypeIsArray = resType === '[object Array]';
696 var copy$$1 = resTypeIsArray ? [] : {};
697 var newKeyToUse = resTypeIsArray ? resExactUsedKey : resUsedKey;
698
699 for (var m in res) {
700 if (Object.prototype.hasOwnProperty.call(res, m)) {
701 var deepKey = "".concat(newKeyToUse).concat(keySeparator).concat(m);
702 copy$$1[m] = this.translate(deepKey, _objectSpread({}, options, {
703 joinArrays: false,
704 ns: namespaces
705 }));
706 if (copy$$1[m] === deepKey) copy$$1[m] = res[m];
707 }
708 }
709
710 res = copy$$1;
711 }
712 } else if (handleAsObjectInI18nFormat && typeof joinArrays === 'string' && resType === '[object Array]') {
713 res = res.join(joinArrays);
714 if (res) res = this.extendTranslation(res, keys, options, lastKey);
715 } else {
716 var usedDefault = false;
717 var usedKey = false;
718
719 if (!this.isValidLookup(res) && options.defaultValue !== undefined) {
720 usedDefault = true;
721
722 if (options.count !== undefined) {
723 var suffix = this.pluralResolver.getSuffix(lng, options.count);
724 res = options["defaultValue".concat(suffix)];
725 }
726
727 if (!res) res = options.defaultValue;
728 }
729
730 if (!this.isValidLookup(res)) {
731 usedKey = true;
732 res = key;
733 }
734
735 var updateMissing = options.defaultValue && options.defaultValue !== res && this.options.updateMissing;
736
737 if (usedKey || usedDefault || updateMissing) {
738 this.logger.log(updateMissing ? 'updateKey' : 'missingKey', lng, namespace, key, updateMissing ? options.defaultValue : res);
739
740 if (keySeparator) {
741 var fk = this.resolve(key, _objectSpread({}, options, {
742 keySeparator: false
743 }));
744 if (fk && fk.res) this.logger.warn('Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.');
745 }
746
747 var lngs = [];
748 var fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng, options.lng || this.language);
749
750 if (this.options.saveMissingTo === 'fallback' && fallbackLngs && fallbackLngs[0]) {
751 for (var i = 0; i < fallbackLngs.length; i++) {
752 lngs.push(fallbackLngs[i]);
753 }
754 } else if (this.options.saveMissingTo === 'all') {
755 lngs = this.languageUtils.toResolveHierarchy(options.lng || this.language);
756 } else {
757 lngs.push(options.lng || this.language);
758 }
759
760 var send = function send(l, k) {
761 if (_this2.options.missingKeyHandler) {
762 _this2.options.missingKeyHandler(l, namespace, k, updateMissing ? options.defaultValue : res, updateMissing, options);
763 } else if (_this2.backendConnector && _this2.backendConnector.saveMissing) {
764 _this2.backendConnector.saveMissing(l, namespace, k, updateMissing ? options.defaultValue : res, updateMissing, options);
765 }
766
767 _this2.emit('missingKey', l, namespace, k, res);
768 };
769
770 if (this.options.saveMissing) {
771 var needsPluralHandling = options.count !== undefined && typeof options.count !== 'string';
772
773 if (this.options.saveMissingPlurals && needsPluralHandling) {
774 lngs.forEach(function (l) {
775 var plurals = _this2.pluralResolver.getPluralFormsOfKey(l, key);
776
777 plurals.forEach(function (p) {
778 return send([l], p);
779 });
780 });
781 } else {
782 send(lngs, key);
783 }
784 }
785 }
786
787 res = this.extendTranslation(res, keys, options, resolved, lastKey);
788 if (usedKey && res === key && this.options.appendNamespaceToMissingKey) res = "".concat(namespace, ":").concat(key);
789 if (usedKey && this.options.parseMissingKeyHandler) res = this.options.parseMissingKeyHandler(res);
790 }
791
792 return res;
793 }
794 }, {
795 key: "extendTranslation",
796 value: function extendTranslation(res, key, options, resolved, lastKey) {
797 var _this3 = this;
798
799 if (this.i18nFormat && this.i18nFormat.parse) {
800 res = this.i18nFormat.parse(res, options, resolved.usedLng, resolved.usedNS, resolved.usedKey, {
801 resolved: resolved
802 });
803 } else if (!options.skipInterpolation) {
804 if (options.interpolation) this.interpolator.init(_objectSpread({}, options, {
805 interpolation: _objectSpread({}, this.options.interpolation, options.interpolation)
806 }));
807 var skipOnVariables = options.interpolation && options.interpolation.skipOnVariables || this.options.interpolation.skipOnVariables;
808 var nestBef;
809
810 if (skipOnVariables) {
811 var nb = res.match(this.interpolator.nestingRegexp);
812 nestBef = nb && nb.length;
813 }
814
815 var data = options.replace && typeof options.replace !== 'string' ? options.replace : options;
816 if (this.options.interpolation.defaultVariables) data = _objectSpread({}, this.options.interpolation.defaultVariables, data);
817 res = this.interpolator.interpolate(res, data, options.lng || this.language, options);
818
819 if (skipOnVariables) {
820 var na = res.match(this.interpolator.nestingRegexp);
821 var nestAft = na && na.length;
822 if (nestBef < nestAft) options.nest = false;
823 }
824
825 if (options.nest !== false) res = this.interpolator.nest(res, function () {
826 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
827 args[_key] = arguments[_key];
828 }
829
830 if (lastKey && lastKey[0] === args[0]) {
831 _this3.logger.warn("It seems you are nesting recursively key: ".concat(args[0], " in key: ").concat(key[0]));
832
833 return null;
834 }
835
836 return _this3.translate.apply(_this3, args.concat([key]));
837 }, options);
838 if (options.interpolation) this.interpolator.reset();
839 }
840
841 var postProcess = options.postProcess || this.options.postProcess;
842 var postProcessorNames = typeof postProcess === 'string' ? [postProcess] : postProcess;
843
844 if (res !== undefined && res !== null && postProcessorNames && postProcessorNames.length && options.applyPostProcessor !== false) {
845 res = postProcessor.handle(postProcessorNames, res, key, this.options && this.options.postProcessPassResolved ? _objectSpread({
846 i18nResolved: resolved
847 }, options) : options, this);
848 }
849
850 return res;
851 }
852 }, {
853 key: "resolve",
854 value: function resolve(keys) {
855 var _this4 = this;
856
857 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
858 var found;
859 var usedKey;
860 var exactUsedKey;
861 var usedLng;
862 var usedNS;
863 if (typeof keys === 'string') keys = [keys];
864 keys.forEach(function (k) {
865 if (_this4.isValidLookup(found)) return;
866
867 var extracted = _this4.extractFromKey(k, options);
868
869 var key = extracted.key;
870 usedKey = key;
871 var namespaces = extracted.namespaces;
872 if (_this4.options.fallbackNS) namespaces = namespaces.concat(_this4.options.fallbackNS);
873 var needsPluralHandling = options.count !== undefined && typeof options.count !== 'string';
874 var needsContextHandling = options.context !== undefined && typeof options.context === 'string' && options.context !== '';
875 var codes = options.lngs ? options.lngs : _this4.languageUtils.toResolveHierarchy(options.lng || _this4.language, options.fallbackLng);
876 namespaces.forEach(function (ns) {
877 if (_this4.isValidLookup(found)) return;
878 usedNS = ns;
879
880 if (!checkedLoadedFor["".concat(codes[0], "-").concat(ns)] && _this4.utils && _this4.utils.hasLoadedNamespace && !_this4.utils.hasLoadedNamespace(usedNS)) {
881 checkedLoadedFor["".concat(codes[0], "-").concat(ns)] = true;
882
883 _this4.logger.warn("key \"".concat(usedKey, "\" for languages \"").concat(codes.join(', '), "\" won't get resolved as namespace \"").concat(usedNS, "\" was not yet loaded"), 'This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!');
884 }
885
886 codes.forEach(function (code) {
887 if (_this4.isValidLookup(found)) return;
888 usedLng = code;
889 var finalKey = key;
890 var finalKeys = [finalKey];
891
892 if (_this4.i18nFormat && _this4.i18nFormat.addLookupKeys) {
893 _this4.i18nFormat.addLookupKeys(finalKeys, key, code, ns, options);
894 } else {
895 var pluralSuffix;
896 if (needsPluralHandling) pluralSuffix = _this4.pluralResolver.getSuffix(code, options.count);
897 if (needsPluralHandling && needsContextHandling) finalKeys.push(finalKey + pluralSuffix);
898 if (needsContextHandling) finalKeys.push(finalKey += "".concat(_this4.options.contextSeparator).concat(options.context));
899 if (needsPluralHandling) finalKeys.push(finalKey += pluralSuffix);
900 }
901
902 var possibleKey;
903
904 while (possibleKey = finalKeys.pop()) {
905 if (!_this4.isValidLookup(found)) {
906 exactUsedKey = possibleKey;
907 found = _this4.getResource(code, ns, possibleKey, options);
908 }
909 }
910 });
911 });
912 });
913 return {
914 res: found,
915 usedKey: usedKey,
916 exactUsedKey: exactUsedKey,
917 usedLng: usedLng,
918 usedNS: usedNS
919 };
920 }
921 }, {
922 key: "isValidLookup",
923 value: function isValidLookup(res) {
924 return res !== undefined && !(!this.options.returnNull && res === null) && !(!this.options.returnEmptyString && res === '');
925 }
926 }, {
927 key: "getResource",
928 value: function getResource(code, ns, key) {
929 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
930 if (this.i18nFormat && this.i18nFormat.getResource) return this.i18nFormat.getResource(code, ns, key, options);
931 return this.resourceStore.getResource(code, ns, key, options);
932 }
933 }]);
934
935 return Translator;
936 }(EventEmitter);
937
938 function capitalize(string) {
939 return string.charAt(0).toUpperCase() + string.slice(1);
940 }
941
942 var LanguageUtil = function () {
943 function LanguageUtil(options) {
944 _classCallCheck(this, LanguageUtil);
945
946 this.options = options;
947 this.whitelist = this.options.supportedLngs || false;
948 this.supportedLngs = this.options.supportedLngs || false;
949 this.logger = baseLogger.create('languageUtils');
950 }
951
952 _createClass(LanguageUtil, [{
953 key: "getScriptPartFromCode",
954 value: function getScriptPartFromCode(code) {
955 if (!code || code.indexOf('-') < 0) return null;
956 var p = code.split('-');
957 if (p.length === 2) return null;
958 p.pop();
959 if (p[p.length - 1].toLowerCase() === 'x') return null;
960 return this.formatLanguageCode(p.join('-'));
961 }
962 }, {
963 key: "getLanguagePartFromCode",
964 value: function getLanguagePartFromCode(code) {
965 if (!code || code.indexOf('-') < 0) return code;
966 var p = code.split('-');
967 return this.formatLanguageCode(p[0]);
968 }
969 }, {
970 key: "formatLanguageCode",
971 value: function formatLanguageCode(code) {
972 if (typeof code === 'string' && code.indexOf('-') > -1) {
973 var specialCases = ['hans', 'hant', 'latn', 'cyrl', 'cans', 'mong', 'arab'];
974 var p = code.split('-');
975
976 if (this.options.lowerCaseLng) {
977 p = p.map(function (part) {
978 return part.toLowerCase();
979 });
980 } else if (p.length === 2) {
981 p[0] = p[0].toLowerCase();
982 p[1] = p[1].toUpperCase();
983 if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase());
984 } else if (p.length === 3) {
985 p[0] = p[0].toLowerCase();
986 if (p[1].length === 2) p[1] = p[1].toUpperCase();
987 if (p[0] !== 'sgn' && p[2].length === 2) p[2] = p[2].toUpperCase();
988 if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase());
989 if (specialCases.indexOf(p[2].toLowerCase()) > -1) p[2] = capitalize(p[2].toLowerCase());
990 }
991
992 return p.join('-');
993 }
994
995 return this.options.cleanCode || this.options.lowerCaseLng ? code.toLowerCase() : code;
996 }
997 }, {
998 key: "isWhitelisted",
999 value: function isWhitelisted(code) {
1000 this.logger.deprecate('languageUtils.isWhitelisted', 'function "isWhitelisted" will be renamed to "isSupportedCode" in the next major - please make sure to rename it\'s usage asap.');
1001 return this.isSupportedCode(code);
1002 }
1003 }, {
1004 key: "isSupportedCode",
1005 value: function isSupportedCode(code) {
1006 if (this.options.load === 'languageOnly' || this.options.nonExplicitSupportedLngs) {
1007 code = this.getLanguagePartFromCode(code);
1008 }
1009
1010 return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.indexOf(code) > -1;
1011 }
1012 }, {
1013 key: "getBestMatchFromCodes",
1014 value: function getBestMatchFromCodes(codes) {
1015 var _this = this;
1016
1017 if (!codes) return null;
1018 var found;
1019 codes.forEach(function (code) {
1020 if (found) return;
1021
1022 var cleanedLng = _this.formatLanguageCode(code);
1023
1024 if (!_this.options.supportedLngs || _this.isSupportedCode(cleanedLng)) found = cleanedLng;
1025 });
1026
1027 if (!found && this.options.supportedLngs) {
1028 codes.forEach(function (code) {
1029 if (found) return;
1030
1031 var lngOnly = _this.getLanguagePartFromCode(code);
1032
1033 if (_this.isSupportedCode(lngOnly)) return found = lngOnly;
1034 found = _this.options.supportedLngs.find(function (supportedLng) {
1035 if (supportedLng.indexOf(lngOnly) === 0) return supportedLng;
1036 });
1037 });
1038 }
1039
1040 if (!found) found = this.getFallbackCodes(this.options.fallbackLng)[0];
1041 return found;
1042 }
1043 }, {
1044 key: "getFallbackCodes",
1045 value: function getFallbackCodes(fallbacks, code) {
1046 if (!fallbacks) return [];
1047 if (typeof fallbacks === 'string') fallbacks = [fallbacks];
1048 if (Object.prototype.toString.apply(fallbacks) === '[object Array]') return fallbacks;
1049 if (!code) return fallbacks["default"] || [];
1050 var found = fallbacks[code];
1051 if (!found) found = fallbacks[this.getScriptPartFromCode(code)];
1052 if (!found) found = fallbacks[this.formatLanguageCode(code)];
1053 if (!found) found = fallbacks[this.getLanguagePartFromCode(code)];
1054 if (!found) found = fallbacks["default"];
1055 return found || [];
1056 }
1057 }, {
1058 key: "toResolveHierarchy",
1059 value: function toResolveHierarchy(code, fallbackCode) {
1060 var _this2 = this;
1061
1062 var fallbackCodes = this.getFallbackCodes(fallbackCode || this.options.fallbackLng || [], code);
1063 var codes = [];
1064
1065 var addCode = function addCode(c) {
1066 if (!c) return;
1067
1068 if (_this2.isSupportedCode(c)) {
1069 codes.push(c);
1070 } else {
1071 _this2.logger.warn("rejecting language code not found in supportedLngs: ".concat(c));
1072 }
1073 };
1074
1075 if (typeof code === 'string' && code.indexOf('-') > -1) {
1076 if (this.options.load !== 'languageOnly') addCode(this.formatLanguageCode(code));
1077 if (this.options.load !== 'languageOnly' && this.options.load !== 'currentOnly') addCode(this.getScriptPartFromCode(code));
1078 if (this.options.load !== 'currentOnly') addCode(this.getLanguagePartFromCode(code));
1079 } else if (typeof code === 'string') {
1080 addCode(this.formatLanguageCode(code));
1081 }
1082
1083 fallbackCodes.forEach(function (fc) {
1084 if (codes.indexOf(fc) < 0) addCode(_this2.formatLanguageCode(fc));
1085 });
1086 return codes;
1087 }
1088 }]);
1089
1090 return LanguageUtil;
1091 }();
1092
1093 var sets = [{
1094 lngs: ['ach', 'ak', 'am', 'arn', 'br', 'fil', 'gun', 'ln', 'mfe', 'mg', 'mi', 'oc', 'pt', 'pt-BR', 'tg', 'ti', 'tr', 'uz', 'wa'],
1095 nr: [1, 2],
1096 fc: 1
1097 }, {
1098 lngs: ['af', 'an', 'ast', 'az', 'bg', 'bn', 'ca', 'da', 'de', 'dev', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fi', 'fo', 'fur', 'fy', 'gl', 'gu', 'ha', 'hi', 'hu', 'hy', 'ia', 'it', 'kn', 'ku', 'lb', 'mai', 'ml', 'mn', 'mr', 'nah', 'nap', 'nb', 'ne', 'nl', 'nn', 'no', 'nso', 'pa', 'pap', 'pms', 'ps', 'pt-PT', 'rm', 'sco', 'se', 'si', 'so', 'son', 'sq', 'sv', 'sw', 'ta', 'te', 'tk', 'ur', 'yo'],
1099 nr: [1, 2],
1100 fc: 2
1101 }, {
1102 lngs: ['ay', 'bo', 'cgg', 'fa', 'ht', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky', 'lo', 'ms', 'sah', 'su', 'th', 'tt', 'ug', 'vi', 'wo', 'zh'],
1103 nr: [1],
1104 fc: 3
1105 }, {
1106 lngs: ['be', 'bs', 'cnr', 'dz', 'hr', 'ru', 'sr', 'uk'],
1107 nr: [1, 2, 5],
1108 fc: 4
1109 }, {
1110 lngs: ['ar'],
1111 nr: [0, 1, 2, 3, 11, 100],
1112 fc: 5
1113 }, {
1114 lngs: ['cs', 'sk'],
1115 nr: [1, 2, 5],
1116 fc: 6
1117 }, {
1118 lngs: ['csb', 'pl'],
1119 nr: [1, 2, 5],
1120 fc: 7
1121 }, {
1122 lngs: ['cy'],
1123 nr: [1, 2, 3, 8],
1124 fc: 8
1125 }, {
1126 lngs: ['fr'],
1127 nr: [1, 2],
1128 fc: 9
1129 }, {
1130 lngs: ['ga'],
1131 nr: [1, 2, 3, 7, 11],
1132 fc: 10
1133 }, {
1134 lngs: ['gd'],
1135 nr: [1, 2, 3, 20],
1136 fc: 11
1137 }, {
1138 lngs: ['is'],
1139 nr: [1, 2],
1140 fc: 12
1141 }, {
1142 lngs: ['jv'],
1143 nr: [0, 1],
1144 fc: 13
1145 }, {
1146 lngs: ['kw'],
1147 nr: [1, 2, 3, 4],
1148 fc: 14
1149 }, {
1150 lngs: ['lt'],
1151 nr: [1, 2, 10],
1152 fc: 15
1153 }, {
1154 lngs: ['lv'],
1155 nr: [1, 2, 0],
1156 fc: 16
1157 }, {
1158 lngs: ['mk'],
1159 nr: [1, 2],
1160 fc: 17
1161 }, {
1162 lngs: ['mnk'],
1163 nr: [0, 1, 2],
1164 fc: 18
1165 }, {
1166 lngs: ['mt'],
1167 nr: [1, 2, 11, 20],
1168 fc: 19
1169 }, {
1170 lngs: ['or'],
1171 nr: [2, 1],
1172 fc: 2
1173 }, {
1174 lngs: ['ro'],
1175 nr: [1, 2, 20],
1176 fc: 20
1177 }, {
1178 lngs: ['sl'],
1179 nr: [5, 1, 2, 3],
1180 fc: 21
1181 }, {
1182 lngs: ['he', 'iw'],
1183 nr: [1, 2, 20, 21],
1184 fc: 22
1185 }];
1186 var _rulesPluralsTypes = {
1187 1: function _(n) {
1188 return Number(n > 1);
1189 },
1190 2: function _(n) {
1191 return Number(n != 1);
1192 },
1193 3: function _(n) {
1194 return 0;
1195 },
1196 4: function _(n) {
1197 return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
1198 },
1199 5: function _(n) {
1200 return Number(n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5);
1201 },
1202 6: function _(n) {
1203 return Number(n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2);
1204 },
1205 7: function _(n) {
1206 return Number(n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
1207 },
1208 8: function _(n) {
1209 return Number(n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3);
1210 },
1211 9: function _(n) {
1212 return Number(n >= 2);
1213 },
1214 10: function _(n) {
1215 return Number(n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4);
1216 },
1217 11: function _(n) {
1218 return Number(n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3);
1219 },
1220 12: function _(n) {
1221 return Number(n % 10 != 1 || n % 100 == 11);
1222 },
1223 13: function _(n) {
1224 return Number(n !== 0);
1225 },
1226 14: function _(n) {
1227 return Number(n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3);
1228 },
1229 15: function _(n) {
1230 return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
1231 },
1232 16: function _(n) {
1233 return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n !== 0 ? 1 : 2);
1234 },
1235 17: function _(n) {
1236 return Number(n == 1 || n % 10 == 1 && n % 100 != 11 ? 0 : 1);
1237 },
1238 18: function _(n) {
1239 return Number(n == 0 ? 0 : n == 1 ? 1 : 2);
1240 },
1241 19: function _(n) {
1242 return Number(n == 1 ? 0 : n == 0 || n % 100 > 1 && n % 100 < 11 ? 1 : n % 100 > 10 && n % 100 < 20 ? 2 : 3);
1243 },
1244 20: function _(n) {
1245 return Number(n == 1 ? 0 : n == 0 || n % 100 > 0 && n % 100 < 20 ? 1 : 2);
1246 },
1247 21: function _(n) {
1248 return Number(n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0);
1249 },
1250 22: function _(n) {
1251 return Number(n == 1 ? 0 : n == 2 ? 1 : (n < 0 || n > 10) && n % 10 == 0 ? 2 : 3);
1252 }
1253 };
1254
1255 function createRules() {
1256 var rules = {};
1257 sets.forEach(function (set) {
1258 set.lngs.forEach(function (l) {
1259 rules[l] = {
1260 numbers: set.nr,
1261 plurals: _rulesPluralsTypes[set.fc]
1262 };
1263 });
1264 });
1265 return rules;
1266 }
1267
1268 var PluralResolver = function () {
1269 function PluralResolver(languageUtils) {
1270 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1271
1272 _classCallCheck(this, PluralResolver);
1273
1274 this.languageUtils = languageUtils;
1275 this.options = options;
1276 this.logger = baseLogger.create('pluralResolver');
1277 this.rules = createRules();
1278 }
1279
1280 _createClass(PluralResolver, [{
1281 key: "addRule",
1282 value: function addRule(lng, obj) {
1283 this.rules[lng] = obj;
1284 }
1285 }, {
1286 key: "getRule",
1287 value: function getRule(code) {
1288 return this.rules[code] || this.rules[this.languageUtils.getLanguagePartFromCode(code)];
1289 }
1290 }, {
1291 key: "needsPlural",
1292 value: function needsPlural(code) {
1293 var rule = this.getRule(code);
1294 return rule && rule.numbers.length > 1;
1295 }
1296 }, {
1297 key: "getPluralFormsOfKey",
1298 value: function getPluralFormsOfKey(code, key) {
1299 var _this = this;
1300
1301 var ret = [];
1302 var rule = this.getRule(code);
1303 if (!rule) return ret;
1304 rule.numbers.forEach(function (n) {
1305 var suffix = _this.getSuffix(code, n);
1306
1307 ret.push("".concat(key).concat(suffix));
1308 });
1309 return ret;
1310 }
1311 }, {
1312 key: "getSuffix",
1313 value: function getSuffix(code, count) {
1314 var _this2 = this;
1315
1316 var rule = this.getRule(code);
1317
1318 if (rule) {
1319 var idx = rule.noAbs ? rule.plurals(count) : rule.plurals(Math.abs(count));
1320 var suffix = rule.numbers[idx];
1321
1322 if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
1323 if (suffix === 2) {
1324 suffix = 'plural';
1325 } else if (suffix === 1) {
1326 suffix = '';
1327 }
1328 }
1329
1330 var returnSuffix = function returnSuffix() {
1331 return _this2.options.prepend && suffix.toString() ? _this2.options.prepend + suffix.toString() : suffix.toString();
1332 };
1333
1334 if (this.options.compatibilityJSON === 'v1') {
1335 if (suffix === 1) return '';
1336 if (typeof suffix === 'number') return "_plural_".concat(suffix.toString());
1337 return returnSuffix();
1338 } else if (this.options.compatibilityJSON === 'v2') {
1339 return returnSuffix();
1340 } else if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
1341 return returnSuffix();
1342 }
1343
1344 return this.options.prepend && idx.toString() ? this.options.prepend + idx.toString() : idx.toString();
1345 }
1346
1347 this.logger.warn("no plural rule found for: ".concat(code));
1348 return '';
1349 }
1350 }]);
1351
1352 return PluralResolver;
1353 }();
1354
1355 var Interpolator = function () {
1356 function Interpolator() {
1357 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1358
1359 _classCallCheck(this, Interpolator);
1360
1361 this.logger = baseLogger.create('interpolator');
1362 this.options = options;
1363
1364 this.format = options.interpolation && options.interpolation.format || function (value) {
1365 return value;
1366 };
1367
1368 this.init(options);
1369 }
1370
1371 _createClass(Interpolator, [{
1372 key: "init",
1373 value: function init() {
1374 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1375 if (!options.interpolation) options.interpolation = {
1376 escapeValue: true
1377 };
1378 var iOpts = options.interpolation;
1379 this.escape = iOpts.escape !== undefined ? iOpts.escape : escape;
1380 this.escapeValue = iOpts.escapeValue !== undefined ? iOpts.escapeValue : true;
1381 this.useRawValueToEscape = iOpts.useRawValueToEscape !== undefined ? iOpts.useRawValueToEscape : false;
1382 this.prefix = iOpts.prefix ? regexEscape(iOpts.prefix) : iOpts.prefixEscaped || '{{';
1383 this.suffix = iOpts.suffix ? regexEscape(iOpts.suffix) : iOpts.suffixEscaped || '}}';
1384 this.formatSeparator = iOpts.formatSeparator ? iOpts.formatSeparator : iOpts.formatSeparator || ',';
1385 this.unescapePrefix = iOpts.unescapeSuffix ? '' : iOpts.unescapePrefix || '-';
1386 this.unescapeSuffix = this.unescapePrefix ? '' : iOpts.unescapeSuffix || '';
1387 this.nestingPrefix = iOpts.nestingPrefix ? regexEscape(iOpts.nestingPrefix) : iOpts.nestingPrefixEscaped || regexEscape('$t(');
1388 this.nestingSuffix = iOpts.nestingSuffix ? regexEscape(iOpts.nestingSuffix) : iOpts.nestingSuffixEscaped || regexEscape(')');
1389 this.nestingOptionsSeparator = iOpts.nestingOptionsSeparator ? iOpts.nestingOptionsSeparator : iOpts.nestingOptionsSeparator || ',';
1390 this.maxReplaces = iOpts.maxReplaces ? iOpts.maxReplaces : 1000;
1391 this.alwaysFormat = iOpts.alwaysFormat !== undefined ? iOpts.alwaysFormat : false;
1392 this.resetRegExp();
1393 }
1394 }, {
1395 key: "reset",
1396 value: function reset() {
1397 if (this.options) this.init(this.options);
1398 }
1399 }, {
1400 key: "resetRegExp",
1401 value: function resetRegExp() {
1402 var regexpStr = "".concat(this.prefix, "(.+?)").concat(this.suffix);
1403 this.regexp = new RegExp(regexpStr, 'g');
1404 var regexpUnescapeStr = "".concat(this.prefix).concat(this.unescapePrefix, "(.+?)").concat(this.unescapeSuffix).concat(this.suffix);
1405 this.regexpUnescape = new RegExp(regexpUnescapeStr, 'g');
1406 var nestingRegexpStr = "".concat(this.nestingPrefix, "(.+?)").concat(this.nestingSuffix);
1407 this.nestingRegexp = new RegExp(nestingRegexpStr, 'g');
1408 }
1409 }, {
1410 key: "interpolate",
1411 value: function interpolate(str, data, lng, options) {
1412 var _this = this;
1413
1414 var match;
1415 var value;
1416 var replaces;
1417 var defaultData = this.options && this.options.interpolation && this.options.interpolation.defaultVariables || {};
1418
1419 function regexSafe(val) {
1420 return val.replace(/\$/g, '$$$$');
1421 }
1422
1423 var handleFormat = function handleFormat(key) {
1424 if (key.indexOf(_this.formatSeparator) < 0) {
1425 var path = getPathWithDefaults(data, defaultData, key);
1426 return _this.alwaysFormat ? _this.format(path, undefined, lng) : path;
1427 }
1428
1429 var p = key.split(_this.formatSeparator);
1430 var k = p.shift().trim();
1431 var f = p.join(_this.formatSeparator).trim();
1432 return _this.format(getPathWithDefaults(data, defaultData, k), f, lng, options);
1433 };
1434
1435 this.resetRegExp();
1436 var missingInterpolationHandler = options && options.missingInterpolationHandler || this.options.missingInterpolationHandler;
1437 var skipOnVariables = options && options.interpolation && options.interpolation.skipOnVariables || this.options.interpolation.skipOnVariables;
1438 var todos = [{
1439 regex: this.regexpUnescape,
1440 safeValue: function safeValue(val) {
1441 return regexSafe(val);
1442 }
1443 }, {
1444 regex: this.regexp,
1445 safeValue: function safeValue(val) {
1446 return _this.escapeValue ? regexSafe(_this.escape(val)) : regexSafe(val);
1447 }
1448 }];
1449 todos.forEach(function (todo) {
1450 replaces = 0;
1451
1452 while (match = todo.regex.exec(str)) {
1453 value = handleFormat(match[1].trim());
1454
1455 if (value === undefined) {
1456 if (typeof missingInterpolationHandler === 'function') {
1457 var temp = missingInterpolationHandler(str, match, options);
1458 value = typeof temp === 'string' ? temp : '';
1459 } else if (skipOnVariables) {
1460 value = match[0];
1461 continue;
1462 } else {
1463 _this.logger.warn("missed to pass in variable ".concat(match[1], " for interpolating ").concat(str));
1464
1465 value = '';
1466 }
1467 } else if (typeof value !== 'string' && !_this.useRawValueToEscape) {
1468 value = makeString(value);
1469 }
1470
1471 str = str.replace(match[0], todo.safeValue(value));
1472 todo.regex.lastIndex = 0;
1473 replaces++;
1474
1475 if (replaces >= _this.maxReplaces) {
1476 break;
1477 }
1478 }
1479 });
1480 return str;
1481 }
1482 }, {
1483 key: "nest",
1484 value: function nest(str, fc) {
1485 var _this2 = this;
1486
1487 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1488 var match;
1489 var value;
1490
1491 var clonedOptions = _objectSpread({}, options);
1492
1493 clonedOptions.applyPostProcessor = false;
1494 delete clonedOptions.defaultValue;
1495
1496 function handleHasOptions(key, inheritedOptions) {
1497 var sep = this.nestingOptionsSeparator;
1498 if (key.indexOf(sep) < 0) return key;
1499 var c = key.split(new RegExp("".concat(sep, "[ ]*{")));
1500 var optionsString = "{".concat(c[1]);
1501 key = c[0];
1502 optionsString = this.interpolate(optionsString, clonedOptions);
1503 optionsString = optionsString.replace(/'/g, '"');
1504
1505 try {
1506 clonedOptions = JSON.parse(optionsString);
1507 if (inheritedOptions) clonedOptions = _objectSpread({}, inheritedOptions, clonedOptions);
1508 } catch (e) {
1509 this.logger.warn("failed parsing options string in nesting for key ".concat(key), e);
1510 return "".concat(key).concat(sep).concat(optionsString);
1511 }
1512
1513 delete clonedOptions.defaultValue;
1514 return key;
1515 }
1516
1517 while (match = this.nestingRegexp.exec(str)) {
1518 var formatters = [];
1519 var doReduce = false;
1520
1521 if (match[0].includes(this.formatSeparator) && !/{.*}/.test(match[1])) {
1522 var r = match[1].split(this.formatSeparator).map(function (elem) {
1523 return elem.trim();
1524 });
1525 match[1] = r.shift();
1526 formatters = r;
1527 doReduce = true;
1528 }
1529
1530 value = fc(handleHasOptions.call(this, match[1].trim(), clonedOptions), clonedOptions);
1531 if (value && match[0] === str && typeof value !== 'string') return value;
1532 if (typeof value !== 'string') value = makeString(value);
1533
1534 if (!value) {
1535 this.logger.warn("missed to resolve ".concat(match[1], " for nesting ").concat(str));
1536 value = '';
1537 }
1538
1539 if (doReduce) {
1540 value = formatters.reduce(function (v, f) {
1541 return _this2.format(v, f, options.lng, options);
1542 }, value.trim());
1543 }
1544
1545 str = str.replace(match[0], value);
1546 this.regexp.lastIndex = 0;
1547 }
1548
1549 return str;
1550 }
1551 }]);
1552
1553 return Interpolator;
1554 }();
1555
1556 function remove(arr, what) {
1557 var found = arr.indexOf(what);
1558
1559 while (found !== -1) {
1560 arr.splice(found, 1);
1561 found = arr.indexOf(what);
1562 }
1563 }
1564
1565 var Connector = function (_EventEmitter) {
1566 _inherits(Connector, _EventEmitter);
1567
1568 function Connector(backend, store, services) {
1569 var _this;
1570
1571 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1572
1573 _classCallCheck(this, Connector);
1574
1575 _this = _possibleConstructorReturn(this, _getPrototypeOf(Connector).call(this));
1576
1577 if (isIE10) {
1578 EventEmitter.call(_assertThisInitialized(_this));
1579 }
1580
1581 _this.backend = backend;
1582 _this.store = store;
1583 _this.services = services;
1584 _this.languageUtils = services.languageUtils;
1585 _this.options = options;
1586 _this.logger = baseLogger.create('backendConnector');
1587 _this.state = {};
1588 _this.queue = [];
1589
1590 if (_this.backend && _this.backend.init) {
1591 _this.backend.init(services, options.backend, options);
1592 }
1593
1594 return _this;
1595 }
1596
1597 _createClass(Connector, [{
1598 key: "queueLoad",
1599 value: function queueLoad(languages, namespaces, options, callback) {
1600 var _this2 = this;
1601
1602 var toLoad = [];
1603 var pending = [];
1604 var toLoadLanguages = [];
1605 var toLoadNamespaces = [];
1606 languages.forEach(function (lng) {
1607 var hasAllNamespaces = true;
1608 namespaces.forEach(function (ns) {
1609 var name = "".concat(lng, "|").concat(ns);
1610
1611 if (!options.reload && _this2.store.hasResourceBundle(lng, ns)) {
1612 _this2.state[name] = 2;
1613 } else if (_this2.state[name] < 0) ; else if (_this2.state[name] === 1) {
1614 if (pending.indexOf(name) < 0) pending.push(name);
1615 } else {
1616 _this2.state[name] = 1;
1617 hasAllNamespaces = false;
1618 if (pending.indexOf(name) < 0) pending.push(name);
1619 if (toLoad.indexOf(name) < 0) toLoad.push(name);
1620 if (toLoadNamespaces.indexOf(ns) < 0) toLoadNamespaces.push(ns);
1621 }
1622 });
1623 if (!hasAllNamespaces) toLoadLanguages.push(lng);
1624 });
1625
1626 if (toLoad.length || pending.length) {
1627 this.queue.push({
1628 pending: pending,
1629 loaded: {},
1630 errors: [],
1631 callback: callback
1632 });
1633 }
1634
1635 return {
1636 toLoad: toLoad,
1637 pending: pending,
1638 toLoadLanguages: toLoadLanguages,
1639 toLoadNamespaces: toLoadNamespaces
1640 };
1641 }
1642 }, {
1643 key: "loaded",
1644 value: function loaded(name, err, data) {
1645 var s = name.split('|');
1646 var lng = s[0];
1647 var ns = s[1];
1648 if (err) this.emit('failedLoading', lng, ns, err);
1649
1650 if (data) {
1651 this.store.addResourceBundle(lng, ns, data);
1652 }
1653
1654 this.state[name] = err ? -1 : 2;
1655 var loaded = {};
1656 this.queue.forEach(function (q) {
1657 pushPath(q.loaded, [lng], ns);
1658 remove(q.pending, name);
1659 if (err) q.errors.push(err);
1660
1661 if (q.pending.length === 0 && !q.done) {
1662 Object.keys(q.loaded).forEach(function (l) {
1663 if (!loaded[l]) loaded[l] = [];
1664
1665 if (q.loaded[l].length) {
1666 q.loaded[l].forEach(function (ns) {
1667 if (loaded[l].indexOf(ns) < 0) loaded[l].push(ns);
1668 });
1669 }
1670 });
1671 q.done = true;
1672
1673 if (q.errors.length) {
1674 q.callback(q.errors);
1675 } else {
1676 q.callback();
1677 }
1678 }
1679 });
1680 this.emit('loaded', loaded);
1681 this.queue = this.queue.filter(function (q) {
1682 return !q.done;
1683 });
1684 }
1685 }, {
1686 key: "read",
1687 value: function read(lng, ns, fcName) {
1688 var _this3 = this;
1689
1690 var tried = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
1691 var wait = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 350;
1692 var callback = arguments.length > 5 ? arguments[5] : undefined;
1693 if (!lng.length) return callback(null, {});
1694 return this.backend[fcName](lng, ns, function (err, data) {
1695 if (err && data && tried < 5) {
1696 setTimeout(function () {
1697 _this3.read.call(_this3, lng, ns, fcName, tried + 1, wait * 2, callback);
1698 }, wait);
1699 return;
1700 }
1701
1702 callback(err, data);
1703 });
1704 }
1705 }, {
1706 key: "prepareLoading",
1707 value: function prepareLoading(languages, namespaces) {
1708 var _this4 = this;
1709
1710 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1711 var callback = arguments.length > 3 ? arguments[3] : undefined;
1712
1713 if (!this.backend) {
1714 this.logger.warn('No backend was added via i18next.use. Will not load resources.');
1715 return callback && callback();
1716 }
1717
1718 if (typeof languages === 'string') languages = this.languageUtils.toResolveHierarchy(languages);
1719 if (typeof namespaces === 'string') namespaces = [namespaces];
1720 var toLoad = this.queueLoad(languages, namespaces, options, callback);
1721
1722 if (!toLoad.toLoad.length) {
1723 if (!toLoad.pending.length) callback();
1724 return null;
1725 }
1726
1727 toLoad.toLoad.forEach(function (name) {
1728 _this4.loadOne(name);
1729 });
1730 }
1731 }, {
1732 key: "load",
1733 value: function load(languages, namespaces, callback) {
1734 this.prepareLoading(languages, namespaces, {}, callback);
1735 }
1736 }, {
1737 key: "reload",
1738 value: function reload(languages, namespaces, callback) {
1739 this.prepareLoading(languages, namespaces, {
1740 reload: true
1741 }, callback);
1742 }
1743 }, {
1744 key: "loadOne",
1745 value: function loadOne(name) {
1746 var _this5 = this;
1747
1748 var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
1749 var s = name.split('|');
1750 var lng = s[0];
1751 var ns = s[1];
1752 this.read(lng, ns, 'read', undefined, undefined, function (err, data) {
1753 if (err) _this5.logger.warn("".concat(prefix, "loading namespace ").concat(ns, " for language ").concat(lng, " failed"), err);
1754 if (!err && data) _this5.logger.log("".concat(prefix, "loaded namespace ").concat(ns, " for language ").concat(lng), data);
1755
1756 _this5.loaded(name, err, data);
1757 });
1758 }
1759 }, {
1760 key: "saveMissing",
1761 value: function saveMissing(languages, namespace, key, fallbackValue, isUpdate) {
1762 var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
1763
1764 if (this.services.utils && this.services.utils.hasLoadedNamespace && !this.services.utils.hasLoadedNamespace(namespace)) {
1765 this.logger.warn("did not save key \"".concat(key, "\" as the namespace \"").concat(namespace, "\" was not yet loaded"), 'This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!');
1766 return;
1767 }
1768
1769 if (key === undefined || key === null || key === '') return;
1770
1771 if (this.backend && this.backend.create) {
1772 this.backend.create(languages, namespace, key, fallbackValue, null, _objectSpread({}, options, {
1773 isUpdate: isUpdate
1774 }));
1775 }
1776
1777 if (!languages || !languages[0]) return;
1778 this.store.addResource(languages[0], namespace, key, fallbackValue);
1779 }
1780 }]);
1781
1782 return Connector;
1783 }(EventEmitter);
1784
1785 function get() {
1786 return {
1787 debug: false,
1788 initImmediate: true,
1789 ns: ['translation'],
1790 defaultNS: ['translation'],
1791 fallbackLng: ['dev'],
1792 fallbackNS: false,
1793 whitelist: false,
1794 nonExplicitWhitelist: false,
1795 supportedLngs: false,
1796 nonExplicitSupportedLngs: false,
1797 load: 'all',
1798 preload: false,
1799 simplifyPluralSuffix: true,
1800 keySeparator: '.',
1801 nsSeparator: ':',
1802 pluralSeparator: '_',
1803 contextSeparator: '_',
1804 partialBundledLanguages: false,
1805 saveMissing: false,
1806 updateMissing: false,
1807 saveMissingTo: 'fallback',
1808 saveMissingPlurals: true,
1809 missingKeyHandler: false,
1810 missingInterpolationHandler: false,
1811 postProcess: false,
1812 postProcessPassResolved: false,
1813 returnNull: true,
1814 returnEmptyString: true,
1815 returnObjects: false,
1816 joinArrays: false,
1817 returnedObjectHandler: false,
1818 parseMissingKeyHandler: false,
1819 appendNamespaceToMissingKey: false,
1820 appendNamespaceToCIMode: false,
1821 overloadTranslationOptionHandler: function handle(args) {
1822 var ret = {};
1823 if (_typeof(args[1]) === 'object') ret = args[1];
1824 if (typeof args[1] === 'string') ret.defaultValue = args[1];
1825 if (typeof args[2] === 'string') ret.tDescription = args[2];
1826
1827 if (_typeof(args[2]) === 'object' || _typeof(args[3]) === 'object') {
1828 var options = args[3] || args[2];
1829 Object.keys(options).forEach(function (key) {
1830 ret[key] = options[key];
1831 });
1832 }
1833
1834 return ret;
1835 },
1836 interpolation: {
1837 escapeValue: true,
1838 format: function format(value, _format, lng, options) {
1839 return value;
1840 },
1841 prefix: '{{',
1842 suffix: '}}',
1843 formatSeparator: ',',
1844 unescapePrefix: '-',
1845 nestingPrefix: '$t(',
1846 nestingSuffix: ')',
1847 nestingOptionsSeparator: ',',
1848 maxReplaces: 1000,
1849 skipOnVariables: false
1850 }
1851 };
1852 }
1853 function transformOptions(options) {
1854 if (typeof options.ns === 'string') options.ns = [options.ns];
1855 if (typeof options.fallbackLng === 'string') options.fallbackLng = [options.fallbackLng];
1856 if (typeof options.fallbackNS === 'string') options.fallbackNS = [options.fallbackNS];
1857
1858 if (options.whitelist) {
1859 if (options.whitelist && options.whitelist.indexOf('cimode') < 0) {
1860 options.whitelist = options.whitelist.concat(['cimode']);
1861 }
1862
1863 options.supportedLngs = options.whitelist;
1864 }
1865
1866 if (options.nonExplicitWhitelist) {
1867 options.nonExplicitSupportedLngs = options.nonExplicitWhitelist;
1868 }
1869
1870 if (options.supportedLngs && options.supportedLngs.indexOf('cimode') < 0) {
1871 options.supportedLngs = options.supportedLngs.concat(['cimode']);
1872 }
1873
1874 return options;
1875 }
1876
1877 function noop() {}
1878
1879 var I18n = function (_EventEmitter) {
1880 _inherits(I18n, _EventEmitter);
1881
1882 function I18n() {
1883 var _this;
1884
1885 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1886 var callback = arguments.length > 1 ? arguments[1] : undefined;
1887
1888 _classCallCheck(this, I18n);
1889
1890 _this = _possibleConstructorReturn(this, _getPrototypeOf(I18n).call(this));
1891
1892 if (isIE10) {
1893 EventEmitter.call(_assertThisInitialized(_this));
1894 }
1895
1896 _this.options = transformOptions(options);
1897 _this.services = {};
1898 _this.logger = baseLogger;
1899 _this.modules = {
1900 external: []
1901 };
1902
1903 if (callback && !_this.isInitialized && !options.isClone) {
1904 if (!_this.options.initImmediate) {
1905 _this.init(options, callback);
1906
1907 return _possibleConstructorReturn(_this, _assertThisInitialized(_this));
1908 }
1909
1910 setTimeout(function () {
1911 _this.init(options, callback);
1912 }, 0);
1913 }
1914
1915 return _this;
1916 }
1917
1918 _createClass(I18n, [{
1919 key: "init",
1920 value: function init() {
1921 var _this2 = this;
1922
1923 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1924 var callback = arguments.length > 1 ? arguments[1] : undefined;
1925
1926 if (typeof options === 'function') {
1927 callback = options;
1928 options = {};
1929 }
1930
1931 if (options.whitelist && !options.supportedLngs) {
1932 this.logger.deprecate('whitelist', 'option "whitelist" will be renamed to "supportedLngs" in the next major - please make sure to rename this option asap.');
1933 }
1934
1935 if (options.nonExplicitWhitelist && !options.nonExplicitSupportedLngs) {
1936 this.logger.deprecate('whitelist', 'options "nonExplicitWhitelist" will be renamed to "nonExplicitSupportedLngs" in the next major - please make sure to rename this option asap.');
1937 }
1938
1939 this.options = _objectSpread({}, get(), this.options, transformOptions(options));
1940 this.format = this.options.interpolation.format;
1941 if (!callback) callback = noop;
1942
1943 function createClassOnDemand(ClassOrObject) {
1944 if (!ClassOrObject) return null;
1945 if (typeof ClassOrObject === 'function') return new ClassOrObject();
1946 return ClassOrObject;
1947 }
1948
1949 if (!this.options.isClone) {
1950 if (this.modules.logger) {
1951 baseLogger.init(createClassOnDemand(this.modules.logger), this.options);
1952 } else {
1953 baseLogger.init(null, this.options);
1954 }
1955
1956 var lu = new LanguageUtil(this.options);
1957 this.store = new ResourceStore(this.options.resources, this.options);
1958 var s = this.services;
1959 s.logger = baseLogger;
1960 s.resourceStore = this.store;
1961 s.languageUtils = lu;
1962 s.pluralResolver = new PluralResolver(lu, {
1963 prepend: this.options.pluralSeparator,
1964 compatibilityJSON: this.options.compatibilityJSON,
1965 simplifyPluralSuffix: this.options.simplifyPluralSuffix
1966 });
1967 s.interpolator = new Interpolator(this.options);
1968 s.utils = {
1969 hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
1970 };
1971 s.backendConnector = new Connector(createClassOnDemand(this.modules.backend), s.resourceStore, s, this.options);
1972 s.backendConnector.on('*', function (event) {
1973 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1974 args[_key - 1] = arguments[_key];
1975 }
1976
1977 _this2.emit.apply(_this2, [event].concat(args));
1978 });
1979
1980 if (this.modules.languageDetector) {
1981 s.languageDetector = createClassOnDemand(this.modules.languageDetector);
1982 s.languageDetector.init(s, this.options.detection, this.options);
1983 }
1984
1985 if (this.modules.i18nFormat) {
1986 s.i18nFormat = createClassOnDemand(this.modules.i18nFormat);
1987 if (s.i18nFormat.init) s.i18nFormat.init(this);
1988 }
1989
1990 this.translator = new Translator(this.services, this.options);
1991 this.translator.on('*', function (event) {
1992 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
1993 args[_key2 - 1] = arguments[_key2];
1994 }
1995
1996 _this2.emit.apply(_this2, [event].concat(args));
1997 });
1998 this.modules.external.forEach(function (m) {
1999 if (m.init) m.init(_this2);
2000 });
2001 }
2002
2003 if (!this.modules.languageDetector && !this.options.lng) {
2004 this.logger.warn('init: no languageDetector is used and no lng is defined');
2005 }
2006
2007 var storeApi = ['getResource', 'addResource', 'addResources', 'addResourceBundle', 'removeResourceBundle', 'hasResourceBundle', 'getResourceBundle', 'getDataByLanguage'];
2008 storeApi.forEach(function (fcName) {
2009 _this2[fcName] = function () {
2010 var _this2$store;
2011
2012 return (_this2$store = _this2.store)[fcName].apply(_this2$store, arguments);
2013 };
2014 });
2015 var deferred = defer();
2016
2017 var load = function load() {
2018 _this2.changeLanguage(_this2.options.lng, function (err, t) {
2019 _this2.isInitialized = true;
2020
2021 _this2.logger.log('initialized', _this2.options);
2022
2023 _this2.emit('initialized', _this2.options);
2024
2025 deferred.resolve(t);
2026 callback(err, t);
2027 });
2028 };
2029
2030 if (this.options.resources || !this.options.initImmediate) {
2031 load();
2032 } else {
2033 setTimeout(load, 0);
2034 }
2035
2036 return deferred;
2037 }
2038 }, {
2039 key: "loadResources",
2040 value: function loadResources(language) {
2041 var _this3 = this;
2042
2043 var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
2044 var usedCallback = callback;
2045 var usedLng = typeof language === 'string' ? language : this.language;
2046 if (typeof language === 'function') usedCallback = language;
2047
2048 if (!this.options.resources || this.options.partialBundledLanguages) {
2049 if (usedLng && usedLng.toLowerCase() === 'cimode') return usedCallback();
2050 var toLoad = [];
2051
2052 var append = function append(lng) {
2053 if (!lng) return;
2054
2055 var lngs = _this3.services.languageUtils.toResolveHierarchy(lng);
2056
2057 lngs.forEach(function (l) {
2058 if (toLoad.indexOf(l) < 0) toLoad.push(l);
2059 });
2060 };
2061
2062 if (!usedLng) {
2063 var fallbacks = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
2064 fallbacks.forEach(function (l) {
2065 return append(l);
2066 });
2067 } else {
2068 append(usedLng);
2069 }
2070
2071 if (this.options.preload) {
2072 this.options.preload.forEach(function (l) {
2073 return append(l);
2074 });
2075 }
2076
2077 this.services.backendConnector.load(toLoad, this.options.ns, usedCallback);
2078 } else {
2079 usedCallback(null);
2080 }
2081 }
2082 }, {
2083 key: "reloadResources",
2084 value: function reloadResources(lngs, ns, callback) {
2085 var deferred = defer();
2086 if (!lngs) lngs = this.languages;
2087 if (!ns) ns = this.options.ns;
2088 if (!callback) callback = noop;
2089 this.services.backendConnector.reload(lngs, ns, function (err) {
2090 deferred.resolve();
2091 callback(err);
2092 });
2093 return deferred;
2094 }
2095 }, {
2096 key: "use",
2097 value: function use(module) {
2098 if (!module) throw new Error('You are passing an undefined module! Please check the object you are passing to i18next.use()');
2099 if (!module.type) throw new Error('You are passing a wrong module! Please check the object you are passing to i18next.use()');
2100
2101 if (module.type === 'backend') {
2102 this.modules.backend = module;
2103 }
2104
2105 if (module.type === 'logger' || module.log && module.warn && module.error) {
2106 this.modules.logger = module;
2107 }
2108
2109 if (module.type === 'languageDetector') {
2110 this.modules.languageDetector = module;
2111 }
2112
2113 if (module.type === 'i18nFormat') {
2114 this.modules.i18nFormat = module;
2115 }
2116
2117 if (module.type === 'postProcessor') {
2118 postProcessor.addPostProcessor(module);
2119 }
2120
2121 if (module.type === '3rdParty') {
2122 this.modules.external.push(module);
2123 }
2124
2125 return this;
2126 }
2127 }, {
2128 key: "changeLanguage",
2129 value: function changeLanguage(lng, callback) {
2130 var _this4 = this;
2131
2132 this.isLanguageChangingTo = lng;
2133 var deferred = defer();
2134 this.emit('languageChanging', lng);
2135
2136 var done = function done(err, l) {
2137 if (l) {
2138 _this4.language = l;
2139 _this4.languages = _this4.services.languageUtils.toResolveHierarchy(l);
2140
2141 _this4.translator.changeLanguage(l);
2142
2143 _this4.isLanguageChangingTo = undefined;
2144
2145 _this4.emit('languageChanged', l);
2146
2147 _this4.logger.log('languageChanged', l);
2148 } else {
2149 _this4.isLanguageChangingTo = undefined;
2150 }
2151
2152 deferred.resolve(function () {
2153 return _this4.t.apply(_this4, arguments);
2154 });
2155 if (callback) callback(err, function () {
2156 return _this4.t.apply(_this4, arguments);
2157 });
2158 };
2159
2160 var setLng = function setLng(lngs) {
2161 var l = typeof lngs === 'string' ? lngs : _this4.services.languageUtils.getBestMatchFromCodes(lngs);
2162
2163 if (l) {
2164 if (!_this4.language) {
2165 _this4.language = l;
2166 _this4.languages = _this4.services.languageUtils.toResolveHierarchy(l);
2167 }
2168
2169 if (!_this4.translator.language) _this4.translator.changeLanguage(l);
2170 if (_this4.services.languageDetector) _this4.services.languageDetector.cacheUserLanguage(l);
2171 }
2172
2173 _this4.loadResources(l, function (err) {
2174 done(err, l);
2175 });
2176 };
2177
2178 if (!lng && this.services.languageDetector && !this.services.languageDetector.async) {
2179 setLng(this.services.languageDetector.detect());
2180 } else if (!lng && this.services.languageDetector && this.services.languageDetector.async) {
2181 this.services.languageDetector.detect(setLng);
2182 } else {
2183 setLng(lng);
2184 }
2185
2186 return deferred;
2187 }
2188 }, {
2189 key: "getFixedT",
2190 value: function getFixedT(lng, ns) {
2191 var _this5 = this;
2192
2193 var fixedT = function fixedT(key, opts) {
2194 var options;
2195
2196 if (_typeof(opts) !== 'object') {
2197 for (var _len3 = arguments.length, rest = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) {
2198 rest[_key3 - 2] = arguments[_key3];
2199 }
2200
2201 options = _this5.options.overloadTranslationOptionHandler([key, opts].concat(rest));
2202 } else {
2203 options = _objectSpread({}, opts);
2204 }
2205
2206 options.lng = options.lng || fixedT.lng;
2207 options.lngs = options.lngs || fixedT.lngs;
2208 options.ns = options.ns || fixedT.ns;
2209 return _this5.t(key, options);
2210 };
2211
2212 if (typeof lng === 'string') {
2213 fixedT.lng = lng;
2214 } else {
2215 fixedT.lngs = lng;
2216 }
2217
2218 fixedT.ns = ns;
2219 return fixedT;
2220 }
2221 }, {
2222 key: "t",
2223 value: function t() {
2224 var _this$translator;
2225
2226 return this.translator && (_this$translator = this.translator).translate.apply(_this$translator, arguments);
2227 }
2228 }, {
2229 key: "exists",
2230 value: function exists() {
2231 var _this$translator2;
2232
2233 return this.translator && (_this$translator2 = this.translator).exists.apply(_this$translator2, arguments);
2234 }
2235 }, {
2236 key: "setDefaultNamespace",
2237 value: function setDefaultNamespace(ns) {
2238 this.options.defaultNS = ns;
2239 }
2240 }, {
2241 key: "hasLoadedNamespace",
2242 value: function hasLoadedNamespace(ns) {
2243 var _this6 = this;
2244
2245 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2246
2247 if (!this.isInitialized) {
2248 this.logger.warn('hasLoadedNamespace: i18next was not initialized', this.languages);
2249 return false;
2250 }
2251
2252 if (!this.languages || !this.languages.length) {
2253 this.logger.warn('hasLoadedNamespace: i18n.languages were undefined or empty', this.languages);
2254 return false;
2255 }
2256
2257 var lng = this.languages[0];
2258 var fallbackLng = this.options ? this.options.fallbackLng : false;
2259 var lastLng = this.languages[this.languages.length - 1];
2260 if (lng.toLowerCase() === 'cimode') return true;
2261
2262 var loadNotPending = function loadNotPending(l, n) {
2263 var loadState = _this6.services.backendConnector.state["".concat(l, "|").concat(n)];
2264
2265 return loadState === -1 || loadState === 2;
2266 };
2267
2268 if (options.precheck) {
2269 var preResult = options.precheck(this, loadNotPending);
2270 if (preResult !== undefined) return preResult;
2271 }
2272
2273 if (this.hasResourceBundle(lng, ns)) return true;
2274 if (!this.services.backendConnector.backend) return true;
2275 if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
2276 return false;
2277 }
2278 }, {
2279 key: "loadNamespaces",
2280 value: function loadNamespaces(ns, callback) {
2281 var _this7 = this;
2282
2283 var deferred = defer();
2284
2285 if (!this.options.ns) {
2286 callback && callback();
2287 return Promise.resolve();
2288 }
2289
2290 if (typeof ns === 'string') ns = [ns];
2291 ns.forEach(function (n) {
2292 if (_this7.options.ns.indexOf(n) < 0) _this7.options.ns.push(n);
2293 });
2294 this.loadResources(function (err) {
2295 deferred.resolve();
2296 if (callback) callback(err);
2297 });
2298 return deferred;
2299 }
2300 }, {
2301 key: "loadLanguages",
2302 value: function loadLanguages(lngs, callback) {
2303 var deferred = defer();
2304 if (typeof lngs === 'string') lngs = [lngs];
2305 var preloaded = this.options.preload || [];
2306 var newLngs = lngs.filter(function (lng) {
2307 return preloaded.indexOf(lng) < 0;
2308 });
2309
2310 if (!newLngs.length) {
2311 if (callback) callback();
2312 return Promise.resolve();
2313 }
2314
2315 this.options.preload = preloaded.concat(newLngs);
2316 this.loadResources(function (err) {
2317 deferred.resolve();
2318 if (callback) callback(err);
2319 });
2320 return deferred;
2321 }
2322 }, {
2323 key: "dir",
2324 value: function dir(lng) {
2325 if (!lng) lng = this.languages && this.languages.length > 0 ? this.languages[0] : this.language;
2326 if (!lng) return 'rtl';
2327 var rtlLngs = ['ar', 'shu', 'sqr', 'ssh', 'xaa', 'yhd', 'yud', 'aao', 'abh', 'abv', 'acm', 'acq', 'acw', 'acx', 'acy', 'adf', 'ads', 'aeb', 'aec', 'afb', 'ajp', 'apc', 'apd', 'arb', 'arq', 'ars', 'ary', 'arz', 'auz', 'avl', 'ayh', 'ayl', 'ayn', 'ayp', 'bbz', 'pga', 'he', 'iw', 'ps', 'pbt', 'pbu', 'pst', 'prp', 'prd', 'ug', 'ur', 'ydd', 'yds', 'yih', 'ji', 'yi', 'hbo', 'men', 'xmn', 'fa', 'jpr', 'peo', 'pes', 'prs', 'dv', 'sam'];
2328 return rtlLngs.indexOf(this.services.languageUtils.getLanguagePartFromCode(lng)) >= 0 ? 'rtl' : 'ltr';
2329 }
2330 }, {
2331 key: "createInstance",
2332 value: function createInstance() {
2333 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2334 var callback = arguments.length > 1 ? arguments[1] : undefined;
2335 return new I18n(options, callback);
2336 }
2337 }, {
2338 key: "cloneInstance",
2339 value: function cloneInstance() {
2340 var _this8 = this;
2341
2342 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2343 var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
2344
2345 var mergedOptions = _objectSpread({}, this.options, options, {
2346 isClone: true
2347 });
2348
2349 var clone = new I18n(mergedOptions);
2350 var membersToCopy = ['store', 'services', 'language'];
2351 membersToCopy.forEach(function (m) {
2352 clone[m] = _this8[m];
2353 });
2354 clone.services = _objectSpread({}, this.services);
2355 clone.services.utils = {
2356 hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
2357 };
2358 clone.translator = new Translator(clone.services, clone.options);
2359 clone.translator.on('*', function (event) {
2360 for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
2361 args[_key4 - 1] = arguments[_key4];
2362 }
2363
2364 clone.emit.apply(clone, [event].concat(args));
2365 });
2366 clone.init(mergedOptions, callback);
2367 clone.translator.options = clone.options;
2368 clone.translator.backendConnector.services.utils = {
2369 hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
2370 };
2371 return clone;
2372 }
2373 }]);
2374
2375 return I18n;
2376 }(EventEmitter);
2377
2378 var i18next = new I18n();
2379
2380 return i18next;
2381
2382}));