UNPKG

@ngneat/transloco

Version:

The internationalization (i18n) library for Angular

3,063 lines 112 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('flat'), require('rxjs/operators'), require('@angular/core'), require('rxjs')) :
    typeof define === 'function' && define.amd ? define('@ngneat/transloco', ['exports', 'flat', 'rxjs/operators', '@angular/core', 'rxjs'], factory) :
    (factory((global.ngneat = global.ngneat || {}, global.ngneat.transloco = {}),global.flat,global.rxjs.operators,global.ng.core,global.rxjs));
}(this, (function (exports,flat,operators,i0,rxjs) { 'use strict';

    flat = flat && flat.hasOwnProperty('default') ? flat['default'] : flat;

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* global Reflect, Promise */
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b)
                if (b.hasOwnProperty(p))
                    d[p] = b[p]; };
        return extendStatics(d, b);
    };
    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }
    var __assign = function () {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s)
                    if (Object.prototype.hasOwnProperty.call(s, p))
                        t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };
    function __values(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m)
            return m.call(o);
        if (o && typeof o.length === "number")
            return {
                next: function () {
                    if (o && i >= o.length)
                        o = void 0;
                    return { value: o && o[i++], done: !o };
                }
            };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    }
    function __read(o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m)
            return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
                ar.push(r.value);
        }
        catch (error) {
            e = { error: error };
        }
        finally {
            try {
                if (r && !r.done && (m = i["return"]))
                    m.call(i);
            }
            finally {
                if (e)
                    throw e.error;
            }
        }
        return ar;
    }
    function __spread() {
        for (var ar = [], i = 0; i < arguments.length; i++)
            ar = ar.concat(__read(arguments[i]));
        return ar;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco.loader.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLoader = /** @class */ (function () {
        function DefaultLoader(translations) {
            this.translations = translations;
        }
        /**
         * @param {?} lang
         * @return {?}
         */
        DefaultLoader.prototype.getTranslation = /**
         * @param {?} lang
         * @return {?}
         */
            function (lang) {
                return rxjs.of(this.translations.get(lang) || {});
            };
        return DefaultLoader;
    }());
    /** @type {?} */
    var TRANSLOCO_LOADER = new i0.InjectionToken('TRANSLOCO_LOADER');

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/helpers.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @param {?} obj
     * @param {?} path
     * @return {?}
     */
    function getValue(obj, path) {
        /* For cases where the key is like: 'general.something.thing' */
        if (obj && obj.hasOwnProperty(path)) {
            return obj[path];
        }
        return path.split('.').reduce(( /**
         * @param {?} p
         * @param {?} c
         * @return {?}
         */function (p, c) { return p && p[c]; }), obj);
    }
    /**
     * @param {?} obj
     * @param {?} prop
     * @param {?} val
     * @return {?}
     */
    function setValue(obj, prop, val) {
        obj = __assign({}, obj);
        /** @type {?} */
        var split = prop.split('.');
        /** @type {?} */
        var lastIndex = split.length - 1;
        split.reduce(( /**
         * @param {?} acc
         * @param {?} part
         * @param {?} index
         * @return {?}
         */function (acc, part, index) {
            if (index === lastIndex) {
                acc[part] = val;
            }
            else {
                acc[part] = Array.isArray(acc[part]) ? acc[part].slice() : __assign({}, acc[part]);
            }
            return acc && acc[part];
        }), obj);
        return obj;
    }
    /**
     * @param {?} collection
     * @return {?}
     */
    function size(collection) {
        if (!collection) {
            return 0;
        }
        if (Array.isArray(collection)) {
            return collection.length;
        }
        if (isObject(collection)) {
            return Object.keys(collection).length;
        }
        return !!collection ? collection.length : 0;
    }
    /**
     * @param {?} collection
     * @return {?}
     */
    function isEmpty(collection) {
        return size(collection) === 0;
    }
    /**
     * @param {?} val
     * @return {?}
     */
    function isFunction(val) {
        return typeof val === 'function';
    }
    /**
     * @param {?} val
     * @return {?}
     */
    function isString(val) {
        return typeof val === 'string';
    }
    /**
     * @param {?} val
     * @return {?}
     */
    function isNumber(val) {
        return typeof val === 'number';
    }
    /**
     * @param {?} item
     * @return {?}
     */
    function isObject(item) {
        return item && typeof item === 'object' && !Array.isArray(item);
    }
    /**
     * @param {?} val
     * @return {?}
     */
    function coerceArray(val) {
        return Array.isArray(val) ? val : [val];
    }
    /*
     * @example
     *
     * given: path-to-happiness => pathToHappiness
     * given: path_to_happiness => pathToHappiness
     * given: path-to_happiness => pathToHappiness
     *
     */
    /**
     * @param {?} str
     * @return {?}
     */
    function toCamelCase(str) {
        return str
            .replace(/(?:^\w|[A-Z]|\b\w)/g, ( /**
     * @param {?} word
     * @param {?} index
     * @return {?}
     */function (word, index) { return (index == 0 ? word.toLowerCase() : word.toUpperCase()); }))
            .replace(/\s+|_|-|\//g, '');
    }
    /**
     * @return {?}
     */
    function isBrowser() {
        return typeof window !== 'undefined';
    }
    /**
     * @param {?} value
     * @return {?}
     */
    function isNil(value) {
        return value === null || value === undefined;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    function isDefined(value) {
        return isNil(value) === false;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    function toNumber(value) {
        if (isNumber(value))
            return value;
        if (isString(value) && !isNaN(Number(value) - parseFloat(value))) {
            return Number(value);
        }
        return null;
    }
    /**
     * @param {?} item
     * @return {?}
     */
    function isScopeObject(item) {
        return item && typeof item.scope === 'string';
    }
    /**
     * @param {?} item
     * @return {?}
     */
    function hasInlineLoader(item) {
        return item && isObject(item.loader);
    }
    /**
     * @param {?} obj
     * @return {?}
     */
    function unflatten(obj) {
        return flat.unflatten(obj, { safe: true });
    }
    /**
     * @param {?} obj
     * @return {?}
     */
    function flatten(obj) {
        return flat(obj, { safe: true });
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco.config.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_CONFIG = new i0.InjectionToken('TRANSLOCO_CONFIG', {
        providedIn: 'root',
        factory: ( /**
         * @return {?}
         */function () {
            return {};
        })
    });
    /** @type {?} */
    var defaultConfig = {
        defaultLang: 'en',
        reRenderOnLangChange: false,
        prodMode: false,
        failedRetries: 2,
        availableLangs: [],
        missingHandler: {
            logMissingKey: true,
            useFallbackTranslation: false,
            allowEmpty: false
        },
        flatten: {
            aot: false
        },
        interpolation: ['{{', '}}']
    };
    /**
     * @deprecated
     * @param {?=} config
     * @return {?}
     */
    function provideTranslocoConfig(config) {
        if (config === void 0) {
            config = defaultConfig;
        }
        return {
            provide: TRANSLOCO_CONFIG,
            useValue: __assign({}, defaultConfig, config)
        };
    }
    /**
     * Sets up TranslocoConfig object.
     *
     * @param {?=} config The partial config object to load, this is optional,
     * will be spread after defaultConfig.
     * @return {?}
     */
    function translocoConfig(config) {
        if (config === void 0) {
            config = defaultConfig;
        }
        return __assign({}, defaultConfig, config);
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco.transpiler.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_TRANSPILER = new i0.InjectionToken('TRANSLOCO_TRANSPILER');
    var DefaultTranspiler = /** @class */ (function () {
        function DefaultTranspiler(userConfig) {
            this.interpolationMatcher = resolveMatcher(userConfig);
        }
        /**
         * @param {?} value
         * @param {?=} params
         * @param {?=} translation
         * @return {?}
         */
        DefaultTranspiler.prototype.transpile = /**
         * @param {?} value
         * @param {?=} params
         * @param {?=} translation
         * @return {?}
         */
            function (value, params, translation) {
                var _this = this;
                if (params === void 0) {
                    params = {};
                }
                if (isString(value)) {
                    return value.replace(this.interpolationMatcher, ( /**
                     * @param {?} _
                     * @param {?} match
                     * @return {?}
                     */function (_, match) {
                        match = match.trim();
                        if (isDefined(params[match])) {
                            return params[match];
                        }
                        return isDefined(translation[match]) ? _this.transpile(translation[match], params, translation) : '';
                    }));
                }
                else if (params) {
                    if (isObject(value)) {
                        value = this.handleObject(value, params, translation);
                    }
                    else if (Array.isArray(value)) {
                        value = this.handleArray(value, params, translation);
                    }
                }
                return value;
            };
        /**
         *
         * @example
         *
         * const en = {
         *  a: {
         *    b: {
         *      c: "Hello {{ value }}"
         *    }
         *  }
         * }
         *
         * const params =  {
         *  "b.c": { value: "Transloco "}
         * }
         *
         * service.selectTranslate('a', params);
         *
         * // the first param will be the result of `en.a`.
         * // the second param will be `params`.
         * parser.transpile(value, params, {});
         *
         *
         */
        /**
         *
         * \@example
         *
         * const en = {
         *  a: {
         *    b: {
         *      c: "Hello {{ value }}"
         *    }
         *  }
         * }
         *
         * const params =  {
         *  "b.c": { value: "Transloco "}
         * }
         *
         * service.selectTranslate('a', params);
         *
         * // the first param will be the result of `en.a`.
         * // the second param will be `params`.
         * parser.transpile(value, params, {});
         *
         *
         * @protected
         * @param {?} value
         * @param {?=} params
         * @param {?=} translation
         * @return {?}
         */
        DefaultTranspiler.prototype.handleObject = /**
         *
         * \@example
         *
         * const en = {
         *  a: {
         *    b: {
         *      c: "Hello {{ value }}"
         *    }
         *  }
         * }
         *
         * const params =  {
         *  "b.c": { value: "Transloco "}
         * }
         *
         * service.selectTranslate('a', params);
         *
         * // the first param will be the result of `en.a`.
         * // the second param will be `params`.
         * parser.transpile(value, params, {});
         *
         *
         * @protected
         * @param {?} value
         * @param {?=} params
         * @param {?=} translation
         * @return {?}
         */
            function (value, params, translation) {
                var _this = this;
                if (params === void 0) {
                    params = {};
                }
                /** @type {?} */
                var result = value;
                Object.keys(params).forEach(( /**
                 * @param {?} p
                 * @return {?}
                 */function (p) {
                    // get the value of "b.c" inside "a" => "Hello {{ value }}"
                    /** @type {?} */
                    var v = getValue(result, p);
                    // get the params of "b.c" => { value: "Transloco" }
                    /** @type {?} */
                    var getParams = getValue(params, p);
                    // transpile the value => "Hello Transloco"
                    /** @type {?} */
                    var transpiled = _this.transpile(v, getParams, translation);
                    // set "b.c" to `transpiled`
                    result = setValue(result, p, transpiled);
                }));
                return result;
            };
        /**
         * @protected
         * @param {?} value
         * @param {?=} params
         * @param {?=} translation
         * @return {?}
         */
        DefaultTranspiler.prototype.handleArray = /**
         * @protected
         * @param {?} value
         * @param {?=} params
         * @param {?=} translation
         * @return {?}
         */
            function (value, params, translation) {
                var _this = this;
                if (params === void 0) {
                    params = {};
                }
                return value.map(( /**
                 * @param {?} v
                 * @return {?}
                 */function (v) { return _this.transpile(v, params, translation); }));
            };
        /** @nocollapse */
        DefaultTranspiler.ctorParameters = function () {
            return [
                { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [TRANSLOCO_CONFIG,] }] }
            ];
        };
        return DefaultTranspiler;
    }());
    /**
     * @param {?=} userConfig
     * @return {?}
     */
    function resolveMatcher(userConfig) {
        var _a = __read(userConfig && userConfig.interpolation ? userConfig.interpolation : defaultConfig.interpolation, 2), start = _a[0], end = _a[1];
        return new RegExp(start + "(.*?)" + end, 'g');
    }
    /**
     * @param {?} argsString
     * @return {?}
     */
    function getFunctionArgs(argsString) {
        /** @type {?} */
        var splitted = argsString ? argsString.split(',') : [];
        /** @type {?} */
        var args = [];
        for (var i = 0; i < splitted.length; i++) {
            /** @type {?} */
            var value = splitted[i].trim();
            while (value[value.length - 1] === '\\') {
                i++;
                value = value.replace('\\', ',') + splitted[i];
            }
            args.push(value);
        }
        return args;
    }
    var FunctionalTranspiler = /** @class */ (function (_super) {
        __extends(FunctionalTranspiler, _super);
        function FunctionalTranspiler(injector) {
            var _this = _super.call(this) || this;
            _this.injector = injector;
            return _this;
        }
        /**
         * @param {?} value
         * @param {?=} params
         * @param {?=} translation
         * @return {?}
         */
        FunctionalTranspiler.prototype.transpile = /**
         * @param {?} value
         * @param {?=} params
         * @param {?=} translation
         * @return {?}
         */
            function (value, params, translation) {
                var _this = this;
                if (params === void 0) {
                    params = {};
                }
                /** @type {?} */
                var transpiled = value;
                if (isString(value)) {
                    transpiled = value.replace(/\[\[\s*(\w+)\((.*)\)\s*]]/g, ( /**
                     * @param {?} match
                     * @param {?} functionName
                     * @param {?} args
                     * @return {?}
                     */function (match, functionName, args) {
                        try {
                            /** @type {?} */
                            var func = _this.injector.get(functionName);
                            return func.transpile.apply(func, __spread(getFunctionArgs(args)));
                        }
                        catch (e) {
                            /** @type {?} */
                            var message = "There is an error in: '" + value + "'. \n                          Check that the you used the right syntax in your translation and that the implementation of " + functionName + " is correct.";
                            if (e.message.includes('NullInjectorError')) {
                                message = "You are using the '" + functionName + "' function in your translation but no provider was found!";
                            }
                            throw new Error(message);
                        }
                    }));
                }
                return _super.prototype.transpile.call(this, transpiled, params, translation);
            };
        FunctionalTranspiler.decorators = [
            { type: i0.Injectable }
        ];
        /** @nocollapse */
        FunctionalTranspiler.ctorParameters = function () {
            return [
                { type: i0.Injector }
            ];
        };
        return FunctionalTranspiler;
    }(DefaultTranspiler));

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco-missing-handler.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_MISSING_HANDLER = new i0.InjectionToken('TRANSLOCO_MISSING_HANDLER');
    var DefaultHandler = /** @class */ (function () {
        function DefaultHandler() {
        }
        /**
         * @param {?} key
         * @param {?} config
         * @return {?}
         */
        DefaultHandler.prototype.handle = /**
         * @param {?} key
         * @param {?} config
         * @return {?}
         */
            function (key, config) {
                if (config.missingHandler.logMissingKey && !config.prodMode) {
                    /** @type {?} */
                    var msg = "Missing translation for '" + key + "'";
                    console.warn("%c " + msg, 'font-size: 12px; color: red');
                }
                return key;
            };
        return DefaultHandler;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco.interceptor.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_INTERCEPTOR = new i0.InjectionToken('TRANSLOCO_INTERCEPTOR');
    var DefaultInterceptor = /** @class */ (function () {
        function DefaultInterceptor() {
        }
        /**
         * @param {?} translation
         * @param {?} lang
         * @return {?}
         */
        DefaultInterceptor.prototype.preSaveTranslation = /**
         * @param {?} translation
         * @param {?} lang
         * @return {?}
         */
            function (translation, lang) {
                return translation;
            };
        /**
         * @param {?} key
         * @param {?} value
         * @param {?} lang
         * @return {?}
         */
        DefaultInterceptor.prototype.preSaveTranslationKey = /**
         * @param {?} key
         * @param {?} value
         * @param {?} lang
         * @return {?}
         */
            function (key, value, lang) {
                return value;
            };
        return DefaultInterceptor;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco-fallback-strategy.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_FALLBACK_STRATEGY = new i0.InjectionToken('TRANSLOCO_FALLBACK_STRATEGY');
    var DefaultFallbackStrategy = /** @class */ (function () {
        function DefaultFallbackStrategy(userConfig) {
            this.userConfig = userConfig;
        }
        /**
         * @param {?} failedLang
         * @return {?}
         */
        DefaultFallbackStrategy.prototype.getNextLangs = /**
         * @param {?} failedLang
         * @return {?}
         */
            function (failedLang) {
                /** @type {?} */
                var fallbackLang = this.userConfig.fallbackLang;
                if (!fallbackLang) {
                    throw new Error('When using the default fallback, a fallback language must be provided in the config!');
                }
                return Array.isArray(fallbackLang) ? fallbackLang : [fallbackLang];
            };
        /** @nocollapse */
        DefaultFallbackStrategy.ctorParameters = function () {
            return [
                { type: undefined, decorators: [{ type: i0.Inject, args: [TRANSLOCO_CONFIG,] }] }
            ];
        };
        return DefaultFallbackStrategy;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/merge-config.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @param {?} defaultConfig
     * @param {?} userConfig
     * @return {?}
     */
    function mergeConfig(defaultConfig, userConfig) {
        return __assign({}, defaultConfig, userConfig, { missingHandler: __assign({}, defaultConfig.missingHandler, userConfig.missingHandler), flatten: __assign({}, defaultConfig.flatten, userConfig.flatten) });
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/shared.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /*
     * @example
     *
     * given: lazy-page/en => lazy-page
     *
     */
    /**
     * @param {?} lang
     * @return {?}
     */
    function getScopeFromLang(lang) {
        if (!lang) {
            return '';
        }
        /** @type {?} */
        var split = lang.split('/');
        split.pop();
        return split.join('/');
    }
    /*
     * @example
     *
     * given: lazy-page/en => en
     *
     */
    /**
     * @param {?} lang
     * @return {?}
     */
    function getLangFromScope(lang) {
        if (!lang) {
            return '';
        }
        /** @type {?} */
        var split = lang.split('/');
        return split.pop();
    }
    /**
     * \@example
     *
     * getPipeValue('todos|scoped', 'scoped') [true, 'todos']
     * getPipeValue('en|static', 'static') [true, 'en']
     * getPipeValue('en', 'static') [false, 'en']
     * @param {?} str
     * @param {?} value
     * @param {?=} char
     * @return {?}
     */
    function getPipeValue(str, value, char) {
        if (char === void 0) {
            char = '|';
        }
        if (isString(str)) {
            /** @type {?} */
            var splitted = str.split(char);
            /** @type {?} */
            var lastItem = splitted.pop();
            return lastItem === value ? [true, splitted.toString()] : [false, lastItem];
        }
        return [false, ''];
    }
    /**
     * @param {?} service
     * @param {?} lang
     * @return {?}
     */
    function shouldListenToLangChanges(service, lang) {
        var _a = __read(getPipeValue(lang, 'static'), 1), hasStatic = _a[0];
        if (hasStatic === false) {
            // If we didn't get 'lang|static' check if it's set in the global level
            return service.config.reRenderOnLangChange;
        }
        // We have 'lang|static' so don't listen to lang changes
        return false;
    }
    /**
     * @param {?} listenToLangChange
     * @return {?}
     */
    function listenOrNotOperator(listenToLangChange) {
        return listenToLangChange ? ( /**
         * @param {?} source
         * @return {?}
         */function (source) { return source; }) : operators.take(1);
    }
    /**
     * @param {?} inlineLoader
     * @param {?} scope
     * @return {?}
     */
    function prependScope(inlineLoader, scope) {
        return Object.keys(inlineLoader).reduce(( /**
         * @param {?} acc
         * @param {?} lang
         * @return {?}
         */function (acc, lang) {
            acc[scope + "/" + lang] = inlineLoader[lang];
            return acc;
        }), {});
    }
    /**
     * @param {?} providerScope
     * @param {?} scope
     * @return {?}
     */
    function resolveInlineLoader(providerScope, scope) {
        return hasInlineLoader(providerScope) ? prependScope(providerScope.loader, scope) : null;
    }
    /**
     * @param {?} lang
     * @return {?}
     */
    function getEventPayload(lang) {
        return {
            scope: getScopeFromLang(lang) || null,
            langName: getLangFromScope(lang),
            lang: lang
        };
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/resolve-loader.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @param {?} path
     * @param {?} mainLoader
     * @param {?} inlineLoader
     * @param {?} data
     * @return {?}
     */
    function resolveLoader(path, mainLoader, inlineLoader, data) {
        if (inlineLoader) {
            /** @type {?} */
            var pathLoader = inlineLoader[path];
            if (isFunction(pathLoader) === false) {
                throw "You're using an inline loader but didn't provide a loader for " + path;
            }
            return inlineLoader[path]().then(( /**
             * @param {?} res
             * @return {?}
             */function (res) { return (res.default ? res.default : res); }));
        }
        return mainLoader.getTranslation(path, data);
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/get-fallbacks-loaders.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @param {?} mainPath
     * @param {?} fallbackPath
     * @param {?} mainLoader
     * @param {?} inlineLoader
     * @param {?} data
     * @return {?}
     */
    function getFallbacksLoaders(mainPath, fallbackPath, mainLoader, inlineLoader, data) {
        return [mainPath, fallbackPath].map(( /**
         * @param {?} path
         * @return {?}
         */function (path) {
            /** @type {?} */
            var loader = resolveLoader(path, mainLoader, inlineLoader, data);
            return rxjs.from(loader).pipe(operators.map(( /**
             * @param {?} translation
             * @return {?}
             */function (translation) {
                return ({
                    translation: translation,
                    lang: path
                });
            })));
        }));
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco.service.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var service;
    /**
     * @template T
     * @param {?} key
     * @param {?=} params
     * @param {?=} lang
     * @return {?}
     */
    function translate(key, params, lang) {
        if (params === void 0) {
            params = {};
        }
        return service.translate(key, params, lang);
    }
    var TranslocoService = /** @class */ (function () {
        function TranslocoService(loader, parser, missingHandler, interceptor, userConfig, fallbackStrategy) {
            var _this = this;
            this.loader = loader;
            this.parser = parser;
            this.missingHandler = missingHandler;
            this.interceptor = interceptor;
            this.userConfig = userConfig;
            this.fallbackStrategy = fallbackStrategy;
            this.translations = new Map();
            this.cache = new Map();
            this.firstFallbackLang = null;
            this.availableLangs = [];
            this.isResolvedMissingOnce = false;
            this.events = new rxjs.Subject();
            this.events$ = this.events.asObservable();
            this.failedLangs = new Set();
            if (!this.loader) {
                this.loader = new DefaultLoader(this.translations);
            }
            service = this;
            this.mergedConfig = mergeConfig(defaultConfig, userConfig);
            this.setAvailableLangs(this.mergedConfig.availableLangs);
            this.setFallbackLangForMissingTranslation(this.mergedConfig);
            this.setDefaultLang(this.mergedConfig.defaultLang);
            this.lang = new rxjs.BehaviorSubject(this.getDefaultLang());
            // Don't use distinctUntilChanged as we need the ability to update
            // the value when using setTranslation or setTranslationKeys
            this.langChanges$ = this.lang.asObservable();
            /**
             * When we have a failure, we want to define the next language that succeeded as the active
             */
            this.subscription = this.events$.subscribe(( /**
             * @param {?} e
             * @return {?}
             */function (e) {
                if (e.type === 'translationLoadSuccess' && e.wasFailure) {
                    // Handle scoped lang
                    /** @type {?} */
                    var lang = getLangFromScope(e.payload.lang);
                    _this.setActiveLang(lang);
                }
            }));
        }
        Object.defineProperty(TranslocoService.prototype, "config", {
            get: /**
             * @return {?}
             */ function () {
                return this.mergedConfig;
            },
            enumerable: true,
            configurable: true
        });
        /**
         * @return {?}
         */
        TranslocoService.prototype.getDefaultLang = /**
         * @return {?}
         */
            function () {
                return this.defaultLang;
            };
        /**
         * @param {?} lang
         * @return {?}
         */
        TranslocoService.prototype.setDefaultLang = /**
         * @param {?} lang
         * @return {?}
         */
            function (lang) {
                this.defaultLang = lang;
            };
        /**
         * @return {?}
         */
        TranslocoService.prototype.getActiveLang = /**
         * @return {?}
         */
            function () {
                return this.lang.getValue();
            };
        /**
         * @template THIS
         * @this {THIS}
         * @param {?} lang
         * @return {THIS}
         */
        TranslocoService.prototype.setActiveLang = /**
         * @template THIS
         * @this {THIS}
         * @param {?} lang
         * @return {THIS}
         */
            function (lang) {
                ( /** @type {?} */(this)).parser.onLangChanged && ( /** @type {?} */(this)).parser.onLangChanged(lang);
                ( /** @type {?} */(this)).lang.next(lang);
                return ( /** @type {?} */(this));
            };
        /**
         * @param {?} langs
         * @return {?}
         */
        TranslocoService.prototype.setAvailableLangs = /**
         * @param {?} langs
         * @return {?}
         */
            function (langs) {
                this.availableLangs = langs;
            };
        /**
         * Gets the available languages.
         *
         * @returns
         * An array of the available languages. Can be either a `string[]` or a `{ id: string; label: string }[]`
         * depending on how the available languages are set in your module.
         */
        /**
         * Gets the available languages.
         *
         * @return {?}
         * An array of the available languages. Can be either a `string[]` or a `{ id: string; label: string }[]`
         * depending on how the available languages are set in your module.
         */
        TranslocoService.prototype.getAvailableLangs = /**
         * Gets the available languages.
         *
         * @return {?}
         * An array of the available languages. Can be either a `string[]` or a `{ id: string; label: string }[]`
         * depending on how the available languages are set in your module.
         */
            function () {
                return this.availableLangs;
            };
        /**
         * @param {?} path
         * @param {?=} options
         * @return {?}
         */
        TranslocoService.prototype.load = /**
         * @param {?} path
         * @param {?=} options
         * @return {?}
         */
            function (path, options) {
                var _this = this;
                if (options === void 0) {
                    options = {};
                }
                if (this.cache.has(path) === false) {
                    /** @type {?} */
                    var loadTranslation = void 0;
                    /** @type {?} */
                    var isScope = this._isLangScoped(path);
                    /** @type {?} */
                    var scope = isScope ? getScopeFromLang(path) : null;
                    if (this.useFallbackTranslation(path)) {
                        // if the path is scope the fallback should be `scope/fallbackLang`;
                        /** @type {?} */
                        var fallback = isScope ? scope + "/" + this.firstFallbackLang : this.firstFallbackLang;
                        /** @type {?} */
                        var loaders = getFallbacksLoaders(path, fallback, this.loader, options.inlineLoader, { scope: scope });
                        loadTranslation = rxjs.forkJoin(loaders);
                    }
                    else {
                        /** @type {?} */
                        var loader = resolveLoader(path, this.loader, options.inlineLoader, { scope: scope });
                        loadTranslation = rxjs.from(loader);
                    }
                    /** @type {?} */
                    var load$ = loadTranslation.pipe(operators.retry(this.config.failedRetries), operators.tap(( /**
                     * @param {?} translation
                     * @return {?}
                     */function (translation) {
                        if (Array.isArray(translation)) {
                            translation.forEach(( /**
                             * @param {?} t
                             * @return {?}
                             */function (t) {
                                _this.handleSuccess(t.lang, t.translation);
                                // Save the fallback in cache so we'll not create a redundant request
                                if (t.lang !== path) {
                                    _this.cache.set(t.lang, rxjs.of({}));
                                }
                            }));
                            return;
                        }
                        _this.handleSuccess(path, translation);
                    })), operators.catchError(( /**
                     * @return {?}
                     */function () { return _this.handleFailure(path, options); })), operators.shareReplay(1));
                    this.cache.set(path, load$);
                }
                return this.cache.get(path);
            };
        /**
         * Gets the instant translated value of a key
         *
         * @example
         *
         * translate<string>('hello')
         * translate('hello', { value: 'value' })
         * translate<string[]>(['hello', 'key'])
         * translate('hello', { }, 'en')
         * translate('scope.someKey', { }, 'en')
         */
        /**
         * Gets the instant translated value of a key
         *
         * \@example
         *
         * translate<string>('hello')
         * translate('hello', { value: 'value' })
         * translate<string[]>(['hello', 'key'])
         * translate('hello', { }, 'en')
         * translate('scope.someKey', { }, 'en')
         * @template T
         * @param {?} key
         * @param {?=} params
         * @param {?=} lang
         * @return {?}
         */
        TranslocoService.prototype.translate = /**
         * Gets the instant translated value of a key
         *
         * \@example
         *
         * translate<string>('hello')
         * translate('hello', { value: 'value' })
         * translate<string[]>(['hello', 'key'])
         * translate('hello', { }, 'en')
         * translate('scope.someKey', { }, 'en')
         * @template T
         * @param {?} key
         * @param {?=} params
         * @param {?=} lang
         * @return {?}
         */
            function (key, params, lang) {
                var _this = this;
                if (params === void 0) {
                    params = {};
                }
                if (lang === void 0) {
                    lang = this.getActiveLang();
                }
                if (!key)
                    return ( /** @type {?} */(key));
                var _a = this.resolveLangAndScope(lang), scope = _a.scope, resolveLang = _a.resolveLang;
                if (Array.isArray(key)) {
                    return ( /** @type {?} */(key.map(( /**
                     * @param {?} k
                     * @return {?}
                     */function (k) { return _this.translate(scope ? scope + "." + k : k, params, resolveLang); }))));
                }
                key = scope ? scope + "." + key : key;
                /** @type {?} */
                var translation = this.getTranslation(resolveLang);
                /** @type {?} */
                var value = translation[key];
                if (!value) {
                    return this._handleMissingKey(key, value, params);
                }
                return this.parser.transpile(value, params, translation);
            };
        /**
         * Gets the translated value of a key as observable
         *
         * @example
         *
         * selectTranslate<string>('hello').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, 'es').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, 'todos').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, { scope: 'todos' }).subscribe(value => ...)
         *
         */
        /**
         * Gets the translated value of a key as observable
         *
         * \@example
         *
         * selectTranslate<string>('hello').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, 'es').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, 'todos').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, { scope: 'todos' }).subscribe(value => ...)
         *
         * @template T
         * @param {?} key
         * @param {?=} params
         * @param {?=} lang
         * @param {?=} _isObject
         * @return {?}
         */
        TranslocoService.prototype.selectTranslate = /**
         * Gets the translated value of a key as observable
         *
         * \@example
         *
         * selectTranslate<string>('hello').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, 'es').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, 'todos').subscribe(value => ...)
         * selectTranslate<string>('hello', {}, { scope: 'todos' }).subscribe(value => ...)
         *
         * @template T
         * @param {?} key
         * @param {?=} params
         * @param {?=} lang
         * @param {?=} _isObject
         * @return {?}
         */
            function (key, params, lang, _isObject) {
                var _this = this;
                if (_isObject === void 0) {
                    _isObject = false;
                }
                /** @type {?} */
                var inlineLoader = null;
                /** @type {?} */
                var load = ( /**
                 * @param {?} lang
                 * @param {?=} options
                 * @return {?}
                 */function (lang, options) {
                    return _this.load(lang, options).pipe(operators.map(( /**
                     * @return {?}
                     */function () { return (_isObject ? _this.translateObject(key, params, lang) : _this.translate(key, params, lang)); })));
                });
                if (isNil(lang)) {
                    return this.langChanges$.pipe(operators.switchMap(( /**
                     * @param {?} lang
                     * @return {?}
                     */function (lang) { return load(lang); })));
                }
                if (isScopeObject(lang)) {
                    // it's a scope object.
                    /** @type {?} */
                    var providerScope = ( /** @type {?} */(lang));
                    lang = providerScope.scope;
                    inlineLoader = resolveInlineLoader(providerScope, providerScope.scope);
                }
                lang = ( /** @type {?} */(lang));
                if (this.isLang(lang) || this.isScopeWithLang(lang)) {
                    return load(lang);
                }
                // it's a scope
                /** @type {?} */
                var scope = lang;
                return this.langChanges$.pipe(operators.switchMap(( /**
                 * @param {?} lang
                 * @return {?}
                 */function (lang) { return load(scope + "/" + lang, { inlineLoader: inlineLoader }); })));
            };
        /**
         * Whether the scope with lang
         *
         * @example
         *
         * todos/en => true
         * todos => false
         */
        /**
         * Whether the scope with lang
         *
         * \@example
         *
         * todos/en => true
         * todos => false
         * @private
         * @param {?} lang
         * @return {?}
         */
        TranslocoService.prototype.isScopeWithLang = /**
         * Whether the scope with lang
         *
         * \@example
         *
         * todos/en => true
         * todos => false
         * @private
         * @param {?} lang
         * @return {?}
         */
            function (lang) {
                return this.isLang(getLangFromScope(lang));
            };
        /**
         * @template T
         * @param {?} key
         * @param {?=} params
         * @param {?=} lang
         * @return {?}
         */
        TranslocoService.prototype.translateObject = /**
         * @template T
         * @param {?} key
         * @param {?=} params
         * @param {?=} lang
         * @return {?}
         */
            function (key, params, lang) {
                var _this = this;
                if (lang === void 0) {
                    lang = this.getActiveLang();
                }
                var e_1, _a;
                if (isString(key) || Array.isArray(key)) {
                    if (Array.isArray(key)) {
                        return ( /** @type {?} */(key.map(( /**
                         * @param {?} k
                         * @return {?}
                         */function (k) { return _this.translateObject(scope_1 ? scope_1 + "." + k : k, params, resolveLang_1); }))));
                    }
                    var _b = this.resolveLangAndScope(lang), resolveLang_1 = _b.resolveLang, scope_1 = _b.scope;
                    /** @type {?} */
                    var translation = this.getTranslation(resolveLang_1);
                    key = scope_1 ? scope_1 + "." + key : key;
                    /** @type {?} */
                    var value = unflatten(this.getObjectByKey(translation, key));
                    /* If an empty object was returned we want to try and translate the key as a string and not an object */
                    return isEmpty(value) ? this.translate(key, params, lang) : this.parser.transpile(value, params, translation);
                }
                /** @type {?} */
                var translations = [];
                try {
                    for (var _c = __values(this.getEntries(key)), _d = _c.next(); !_d.done; _d = _c.next()) {
                        var _e = __read(_d.value, 2), _key = _e[0], _params = _e[1];
                        translations.push(this.translateObject(_key, _params, lang));
                    }
                }
                catch (e_1_1) {
                    e_1 = { error: e_1_1 };
                }
                finally {
                    try {
                        if (_d && !_d.done && (_a = _c.return))
                            _a.call(_c);
                    }
                    finally {
                        if (e_1)
                            throw e_1.error;
                    }
                }
                return translations;
            };
        /**
         * @template T
         * @param {?} key
         * @param {?=} params
         * @param {?=} lang
         * @return {?}
         */
        TranslocoService.prototype.selectTranslateObject = /**
         * @template T
         * @param {?} key
         * @param {?=} params
         * @param {?=} lang
         * @return {?}
         */
            function (key, params, lang) {
                var _this = this;
                if (isString(key) || Array.isArray(key)) {
                    return this.selectTranslate(key, params, lang, true);
                }
                var _a = __read(this.getEntries(key)), _b = __read(_a[0], 2), firstKey = _b[0], firstParams = _b[1], rest = _a.slice(1);
                /* In order to avoid subscribing multiple times to the load language event by calling selectTranslateObject for each pair,
                 * we listen to when the first key has been translated (the language is loaded) and translate the rest synchronously */
                return this.selectTranslateObject(firstKey, firstParams, lang).pipe(operators.map(( /**
                 * @param {?} value
                 * @return {?}
                 */function (value) {
                    var e_2, _a;
                    /** @type {?} */
                    var translations = [value];
                    try {
                        for (var rest_1 = __values(rest), rest_1_1 = rest_1.next(); !rest_1_1.done; rest_1_1 = rest_1.next()) {
                            var _b = __read(rest_1_1.value, 2), _key = _b[0], _params = _b[1];
                            translations.push(_this.translateObject(_key, _params, lang));
                        }
                    }
                    catch (e_2_1) {
                        e_2 = { error: e_2_1 };
                    }
                    finally {
                        try {
                            if (rest_1_1 && !rest_1_1.done && (_a = rest_1.return))
                                _a.call(rest_1);
                        }
                        finally {
                            if (e_2)
                                throw e_2.error;
                        }
                    }
                    return translations;
                })));
            };
        /**
         * @param {?=} langOrScope
         * @return {?}
         */
        TranslocoService.prototype.getTranslation = /**
         * @param {?=} langOrScope
         * @return {?}
         */
            function (langOrScope) {
                if (langOrScope) {
                    if (this.isLang(langOrScope)) {
                        return this.translations.get(langOrScope) || {};
                    }
                    else {
                        // This is a scope, build the scope value from the translation object
                        var _a = this.resolveLangAndScope(langOrScope), scope = _a.scope, resolveLang = _a.resolveLang;
                        /** @type {?} */
                        var translation = this.translations.get(resolveLang) || {};
                        return this.getObjectByKey(translation, scope);
                    }
                }
                return this.translations;
            };
        /**
         * Gets an object of translations for a given language
         *
         * @example
         *
         * selectTranslation().subscribe() - will return the current lang translation
         * selectTranslation('es').subscribe()
         * selectTranslation('admin-page').subscribe() - will return the current lang scope translation
         * selectTranslation('admin-page/es').subscribe()
         */
        /**
         * Gets an object of translations for a given language
         *
         * \@example
         *
         * selectTranslation().subscribe() - will return the current lang translation
         * selectTranslation('es').subscribe()
         * selectTranslation('admin-page').subscribe() - will return the current lang scope translation
         * selectTranslation('admin-page/es').subscribe()
         * @param {?=} lang
         * @return {?}
         */
        TranslocoService.prototype.selectTranslation = /**
         * Gets an object of translations for a given language
         *
         * \@example
         *
         * selectTranslation().subscribe() - will return the current lang translation
         * selectTranslation('es').subscribe()
         * selectTranslation('admin-page').subscribe() - will return the current lang scope translation
         * selectTranslation('admin-page/es').subscribe()
         * @param {?=} lang
         * @return {?}
         */
            function (lang) {
                var _this = this;
                /** @type {?} */
                var language$ = this.langChanges$;
                if (lang) {
                    /** @type {?} */
                    var scopeLangSpecified = getLangFromScope(lang) !== lang;
                    if (this.isLang(lang) || scopeLangSpecified) {
                        language$ = rxjs.of(lang);
                    }
                    else {
                        language$ = this.langChanges$.pipe(operators.map(( /**
                         * @param {?} currentLang
                         * @return {?}
                         */function (currentLang) { return lang + "/" + currentLang; })));
                    }
                }
                return language$.pipe(operators.switchMap(( /**
                 * @param {?} language
                 * @return {?}
                 */function (language) {
                    return _this.load(language).pipe(operators.map(( /**
                     * @return {?}
                     */function () { return _this.getTranslation(language); })));
                })));
            };
        /**
         * Sets or merge a given translation object to current lang
         *
         * @example
         *
         * setTranslation({ ... })
         * setTranslation({ ... }, 'en')
         * setTranslation({ ... }, 'es', { merge: false } )
         * setTranslation({ ... }, 'todos/en', { merge: false } )
         */
        /**
         * Sets or merge a given translation object to current lang
         *
         * \@example
         *
         * setTranslation({ ... })
         * setTranslation({ ... }, 'en')
         * setTranslation({ ... }, 'es', { merge: false } )
         * setTranslation({ ... }, 'todos/en', { merge: false } )
         * @param {?} translation
         * @param {?=} lang
         * @param {?=} options
         * @return {?}
         */
        TranslocoService.prototype.setTranslation = /**
         * Sets or merge a given translation object to current lang
         *
         * \@example
         *
         * setTranslation({ ... })
         * setTranslation({ ... }, 'en')
         * setTranslation({ ... }, 'es', { merge: false } )
         * setTranslation({ ... }, 'todos/en', { merge: false } )
         * @param {?} translation
         * @param {?=} lang
         * @param {?=} options
         * @return {?}
         */
            function (translation, lang, options) {
                if (lang === void 0) {
                    lang = this.getActiveLang();
                }
                if (options === void 0) {
                    options = {};
                }
                var _a;
                /** @type {?} */
                var defaults = { merge: true, emitChange: true };
                /** @type {?} */
                var mergedOptions = __assign({}, defaults, options);
                /** @type {?} */
                var scope = getScopeFromLang(lang);
                /**
                 * If this isn't a scope we use the whole translation as is
                 * otherwise we need to flat the scope and use it
                 * @type {?}
                 */
                var flattenScopeOrTranslation = translation;
                // Merged the scoped language into the active language
                if (scope) {
                    /** @type {?} */
                    var key = this.getMappedScope(scope);
                    flattenScopeOrTranslation = flatten((_a = {}, _a[key] = translation, _a));
                }
                /** @type {?} */
                var currentLang = scope ? getLangFromScope(lang) : lang;
                /** @type {?} */
                var mergedTranslation = __assign({}, (mergedOptions.merge && this.getTranslation(currentLang)), flattenScopeOrTranslation);
                /** @type {?} */
                var flattenTranslation = this.mergedConfig.flatten.aot ? mergedTranslation : flatten(mergedTranslation);
                /** @type {?} */
                var withHook = this.interceptor.preSaveTranslation(flattenTranslation, currentLang);
                this.translations.set(currentLang, withHook);
                mergedOptions.emitChange && this.setActiveLang(this.getActiveLang());
            };
        /**
         * Sets translation key with given value
         *
         * @example
         *
         * setTranslationKey('key', 'value')
         * setTranslationKey('key.nested', 'value')
         * setTranslationKey('key.nested', 'value', 'en')
         * setTranslationKey('key.nested', 'value', 'en', { emitChange: false } )
         */
        /**
         * Sets translation key with given value
         *
         * \@example
         *
         * setTranslationKey('key', 'value')
         * setTranslationKey('key.nested', 'value')
         * setTranslationKey('key.nested', 'value', 'en')
         * setTranslationKey('key.nested', 'value', 'en', { emitChange: false } )
         * @param {?} key
         * @param {?} value
         * @param {?=} lang
         * @param {?=} options
         * @return {?}
         */
        TranslocoService.prototype.setTranslationKey = /**
         * Sets translation key with given value
         *
         * \@example
         *
         * setTranslationKey('key', 'value')
         * setTranslationKey('key.nested', 'value')
         * setTranslationKey('key.nested', 'value', 'en')
         * setTranslationKey('key.nested', 'value', 'en', { emitChange: false } )
         * @param {?} key
         * @param {?} value
         * @param {?=} lang
         * @param {?=} options
         * @return {?}
         */
            function (key, value, lang, 
            // Todo: Use Omit and merge options and lang to one object in v3
            options) {
                if (lang === void 0) {
                    lang = this.getActiveLang();
                }
                if (options === void 0) {
                    options = {};
                }
                var _a;
                /** @type {?} */
                var withHook = this.interceptor.preSaveTranslationKey(key, value, lang);
                /** @type {?} */
                var newValue = (_a = {},
                    _a[key] = withHook,
                    _a);
                this.setTranslation(newValue, lang, __assign({}, options, { merge: true }));
            };
        /**
         * Sets the fallback lang for the currently active language
         * @param fallbackLang
         */
        /**
         * Sets the fallback lang for the currently active language
         * @param {?} __0
         * @return {?}
         */
        TranslocoService.prototype.setFallbackLangForMissingTranslation = /**
         * Sets the fallback lang for the currently active language
         * @param {?} __0
         * @return {?}
         */
            function (_a) {
                var fallbackLang = _a.fallbackLang;
                /** @type {?} */
                var lang = Array.isArray(fallbackLang) ? fallbackLang[0] : fallbackLang;
                if (this.useFallbackTranslation(lang) && fallbackLang) {
                    this.firstFallbackLang = lang;
                }
            };
        /**
         * @internal
         */
        /**
         * \@internal
         * @param {?} key
         * @param {?} value
         * @param {?=} params
         * @return {?}
         */
        TranslocoService.prototype._handleMissingKey = /**
         * \@internal
         * @param {?} key
         * @param {?} value
         * @param {?=} params
         * @return {?}
         */
            function (key, value, params) {
                if (this.config.missingHandler.allowEmpty && value === '') {
                    return '';
                }
                if (this.useFallbackTranslation() && !this.isResolvedMissingOnce) {
                    // We need to set it to true to prevent a loop
                    this.isResolvedMissingOnce = true;
                    /** @type {?} */
                    var fallbackValue = this.translate(key, params, this.firstFallbackLang);
                    this.isResolvedMissingOnce = false;
                    return fallbackValue;
                }
                return this.missingHandler.handle(key, this.getMissingHandlerData(), params);
            };
        /**
         * @internal
         */
        /**
         * \@internal
         * @param {?} lang
         * @return {?}
         */
        TranslocoService.prototype._isLangScoped = /**
         * \@internal
         * @param {?} lang
         * @return {?}
         */
            function (lang) {
                return this.getAvailableLangsIds().indexOf(lang) === -1;
            };
        /**
         * Checks if a given string is one of the specified available languages.
         * @returns
         * True if the given string is an available language.
         * False if the given string is not an available language.
         */
        /**
         * Checks if a given string is one of the specified available languages.
         * @param {?} lang
         * @return {?}
         * True if the given string is an available language.
         * False if the given string is not an available language.
         */
        TranslocoService.prototype.isLang = /**
         * Checks if a given string is one of the specified available languages.
         * @param {?} lang
         * @return {?}
         * True if the given string is an available language.
         * False if the given string is not an available language.
         */
            function (lang) {
                return this.getAvailableLangsIds().indexOf(lang) !== -1;
            };
        /**
         * @internal
         *
         * We always want to make sure the global lang is loaded
         * before loading the scope since you can access both via the pipe/directive.
         */
        /**
         * \@internal
         *
         * We always want to make sure the global lang is loaded
         * before loading the scope since you can access both via the pipe/directive.
         * @param {?} path
         * @param {?=} inlineLoader
         * @return {?}
         */
        TranslocoService.prototype._loadDependencies = /**
         * \@internal
         *
         * We always want to make sure the global lang is loaded
         * before loading the scope since you can access both via the pipe/directive.
         * @param {?} path
         * @param {?=} inlineLoader
         * @return {?}
         */
            function (path, inlineLoader) {
                /** @type {?} */
                var mainLang = getLangFromScope(path);
                if (this._isLangScoped(path) && !this.isLoadedTranslation(mainLang)) {
                    return rxjs.combineLatest(this.load(mainLang), this.load(path, { inlineLoader: inlineLoader }));
                }
                return this.load(path, { inlineLoader: inlineLoader });
            };
        /**
         * @internal
         */
        /**
         * \@internal
         * @param {?} langOrScope
         * @return {?}
         */
        TranslocoService.prototype._completeScopeWithLang = /**
         * \@internal
         * @param {?} langOrScope
         * @return {?}
         */
            function (langOrScope) {
                if (this._isLangScoped(langOrScope) && !this.isLang(getLangFromScope(langOrScope))) {
                    return langOrScope + "/" + this.getActiveLang();
                }
                return langOrScope;
            };
        /**
         * @internal
         */
        /**
         * \@internal
         * @param {?} scope
         * @param {?} alias
         * @return {?}
         */
        TranslocoService.prototype._setScopeAlias = /**
         * \@internal
         * @param {?} scope
         * @param {?} alias
         * @return {?}
         */
            function (scope, alias) {
                if (!this.mergedConfig.scopeMapping) {
                    this.mergedConfig.scopeMapping = {};
                }
                this.mergedConfig.scopeMapping[scope] = alias;
            };
        /**
         * @return {?}
         */
        TranslocoService.prototype.ngOnDestroy = /**
         * @return {?}
         */
            function () {
                this.subscription.unsubscribe();
                // Caretaker note: since this is the root provider, it'll be destroyed when the `NgModuleRef.destroy()` is run.
                // Cached values capture `this`, thus leading to a circular reference and preventing the `TranslocoService` from
                // being GC'd. This would lead to a memory leak when server-side rendering is used since the service is created
                // and destroyed per each HTTP request, but any service is not getting GC'd.
                this.cache.clear();
            };
        /**
         * @private
         * @param {?} lang
         * @return {?}
         */
        TranslocoService.prototype.isLoadedTranslation = /**
         * @private
         * @param {?} lang
         * @return {?}
         */
            function (lang) {
                return size(this.getTranslation(lang));
            };
        /**
         * @private
         * @return {?}
         */
        TranslocoService.prototype.getAvailableLangsIds = /**
         * @private
         * @return {?}
         */
            function () {
                /** @type {?} */
                var first = this.getAvailableLangs()[0];
                if (isString(first)) {
                    return ( /** @type {?} */(this.getAvailableLangs()));
                }
                return (( /** @type {?} */(this.getAvailableLangs()))).map(( /**
                 * @param {?} l
                 * @return {?}
                 */function (l) { return l.id; }));
            };
        /**
         * @private
         * @return {?}
         */
        TranslocoService.prototype.getMissingHandlerData = /**
         * @private
         * @return {?}
         */
            function () {
                return __assign({}, this.config, { activeLang: this.getActiveLang(), availableLangs: this.availableLangs, defaultLang: this.defaultLang });
            };
        /**
         * Use a fallback translation set for missing keys of the primary language
         * This is unrelated to the fallback language (which changes the active language)
         */
        /**
         * Use a fallback translation set for missing keys of the primary language
         * This is unrelated to the fallback language (which changes the active language)
         * @private
         * @param {?=} lang
         * @return {?}
         */
        TranslocoService.prototype.useFallbackTranslation = /**
         * Use a fallback translation set for missing keys of the primary language
         * This is unrelated to the fallback language (which changes the active language)
         * @private
         * @param {?=} lang
         * @return {?}
         */
            function (lang) {
                return this.config.missingHandler.useFallbackTranslation && lang !== this.firstFallbackLang;
            };
        /**
         * @private
         * @param {?} lang
         * @param {?} translation
         * @return {?}
         */
        TranslocoService.prototype.handleSuccess = /**
         * @private
         * @param {?} lang
         * @param {?} translation
         * @return {?}
         */
            function (lang, translation) {
                var _this = this;
                this.setTranslation(translation, lang, { emitChange: false });
                this.events.next({
                    wasFailure: !!this.failedLangs.size,
                    type: 'translationLoadSuccess',
                    payload: getEventPayload(lang)
                });
                this.failedLangs.forEach(( /**
                 * @param {?} l
                 * @return {?}
                 */function (l) { return _this.cache.delete(l); }));
                this.failedLangs.clear();
            };
        /**
         * @private
         * @param {?} lang
         * @param {?} loadOptions
         * @return {?}
         */
        TranslocoService.prototype.handleFailure = /**
         * @private
         * @param {?} lang
         * @param {?} loadOptions
         * @return {?}
         */
            function (lang, loadOptions) {
                // When starting to load a first choice language, initialize
                // the failed counter and resolve the fallback langs.
                if (isNil(loadOptions.failedCounter)) {
                    loadOptions.failedCounter = 0;
                    if (!loadOptions.fallbackLangs) {
                        loadOptions.fallbackLangs = this.fallbackStrategy.getNextLangs(lang);
                    }
                }
                /** @type {?} */
                var splitted = lang.split('/');
                /** @type {?} */
                var fallbacks = loadOptions.fallbackLangs;
                /** @type {?} */
                var nextLang = fallbacks[loadOptions.failedCounter];
                this.failedLangs.add(lang);
                // This handles the case where a loaded fallback language is requested again
                if (this.cache.has(nextLang)) {
                    this.handleSuccess(nextLang, this.getTranslation(nextLang));
                    return rxjs.EMPTY;
                }
                /** @type {?} */
                var isFallbackLang = nextLang === splitted[splitted.length - 1];
                if (!nextLang || isFallbackLang) {
                    /** @type {?} */
                    var msg = "Unable to load translation and all the fallback languages";
                    if (splitted.length > 1) {
                        msg += ", did you misspelled the scope name?";
                    }
                    throw new Error(msg);
                }
                /** @type {?} */
                var resolveLang = nextLang;
                // if it's scoped lang
                if (splitted.length > 1) {
                    // We need to resolve it to:
                    // todos/langNotExists => todos/nextLang
                    splitted[splitted.length - 1] = nextLang;
                    resolveLang = splitted.join('/');
                }
                loadOptions.failedCounter++;
                this.events.next({
                    type: 'translationLoadFailure',
                    payload: getEventPayload(lang)
                });
                return this.load(resolveLang, loadOptions);
            };
        /**
         * @private
         * @param {?} scope
         * @return {?}
         */
        TranslocoService.prototype.getMappedScope = /**
         * @private
         * @param {?} scope
         * @return {?}
         */
            function (scope) {
                var _a = this.config.scopeMapping, scopeMapping = _a === void 0 ? {} : _a;
                return scopeMapping[scope] || toCamelCase(scope);
            };
        /**
         * If lang is scope we need to check the following cases:
         * todos/es => in this case we should take `es` as lang
         * todos => in this case we should set the active lang as lang
         */
        /**
         * If lang is scope we need to check the following cases:
         * todos/es => in this case we should take `es` as lang
         * todos => in this case we should set the active lang as lang
         * @private
         * @param {?} lang
         * @return {?}
         */
        TranslocoService.prototype.resolveLangAndScope = /**
         * If lang is scope we need to check the following cases:
         * todos/es => in this case we should take `es` as lang
         * todos => in this case we should set the active lang as lang
         * @private
         * @param {?} lang
         * @return {?}
         */
            function (lang) {
                /** @type {?} */
                var resolveLang = lang;
                /** @type {?} */
                var scope;
                if (this._isLangScoped(lang)) {
                    // en for example
                    /** @type {?} */
                    var langFromScope = getLangFromScope(lang);
                    // en is lang
                    /** @type {?} */
                    var hasLang = this.isLang(langFromScope);
                    // take en
                    resolveLang = hasLang ? langFromScope : this.getActiveLang();
                    // find the scope
                    scope = this.getMappedScope(hasLang ? getScopeFromLang(lang) : lang);
                }
                return { scope: scope, resolveLang: resolveLang };
            };
        /**
         * @private
         * @param {?} translation
         * @param {?} key
         * @return {?}
         */
        TranslocoService.prototype.getObjectByKey = /**
         * @private
         * @param {?} translation
         * @param {?} key
         * @return {?}
         */
            function (translation, key) {
                /** @type {?} */
                var result = {};
                /** @type {?} */
                var prefix = key + ".";
                for (var currentKey in translation) {
                    if (currentKey.startsWith(prefix)) {
                        result[currentKey.replace(prefix, '')] = translation[currentKey];
                    }
                }
                return result;
            };
        /**
         * @private
         * @param {?} key
         * @return {?}
         */
        TranslocoService.prototype.getEntries = /**
         * @private
         * @param {?} key
         * @return {?}
         */
            function (key) {
                return key instanceof Map ? key.entries() : Object.entries(key);
            };
        TranslocoService.decorators = [
            { type: i0.Injectable, args: [{ providedIn: 'root' },] }
        ];
        /** @nocollapse */
        TranslocoService.ctorParameters = function () {
            return [
                { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [TRANSLOCO_LOADER,] }] },
                { type: undefined, decorators: [{ type: i0.Inject, args: [TRANSLOCO_TRANSPILER,] }] },
                { type: undefined, decorators: [{ type: i0.Inject, args: [TRANSLOCO_MISSING_HANDLER,] }] },
                { type: undefined, decorators: [{ type: i0.Inject, args: [TRANSLOCO_INTERCEPTOR,] }] },
                { type: undefined, decorators: [{ type: i0.Inject, args: [TRANSLOCO_CONFIG,] }] },
                { type: undefined, decorators: [{ type: i0.Inject, args: [TRANSLOCO_FALLBACK_STRATEGY,] }] }
            ];
        };
        /** @nocollapse */ TranslocoService.ngInjectableDef = i0.defineInjectable({ factory: function TranslocoService_Factory() { return new TranslocoService(i0.inject(TRANSLOCO_LOADER, 8), i0.inject(TRANSLOCO_TRANSPILER), i0.inject(TRANSLOCO_MISSING_HANDLER), i0.inject(TRANSLOCO_INTERCEPTOR), i0.inject(TRANSLOCO_CONFIG), i0.inject(TRANSLOCO_FALLBACK_STRATEGY)); }, token: TranslocoService, providedIn: "root" });
        return TranslocoService;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/loader-component.component.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var TranslocoLoaderComponent = /** @class */ (function () {
        function TranslocoLoaderComponent() {
        }
        TranslocoLoaderComponent.decorators = [
            { type: i0.Component, args: [{
                        template: "\n    <div class=\"transloco-loader-template\" [innerHTML]=\"html\"></div>\n  "
                    }] }
        ];
        TranslocoLoaderComponent.propDecorators = {
            html: [{ type: i0.Input }]
        };
        return TranslocoLoaderComponent;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/template-handler.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var TemplateHandler = /** @class */ (function () {
        function TemplateHandler(view, vcr) {
            this.view = view;
            this.vcr = vcr;
            this.injector = this.vcr.injector;
        }
        /**
         * @return {?}
         */
        TemplateHandler.prototype.attachView = /**
         * @return {?}
         */
            function () {
                if (this.view instanceof i0.TemplateRef) {
                    this.vcr.createEmbeddedView(this.view);
                }
                else if (isString(this.view)) {
                    /** @type {?} */
                    var componentRef = this.createComponent(TranslocoLoaderComponent);
                    componentRef.instance.html = this.view;
                    componentRef.hostView.detectChanges();
                }
                else {
                    this.createComponent(this.view);
                }
            };
        /**
         * @return {?}
         */
        TemplateHandler.prototype.detachView = /**
         * @return {?}
         */
            function () {
                this.vcr.clear();
            };
        /**
         * @private
         * @template T
         * @param {?} cmp
         * @return {?}
         */
        TemplateHandler.prototype.createComponent = /**
         * @private
         * @template T
         * @param {?} cmp
         * @return {?}
         */
            function (cmp) {
                /** @type {?} */
                var cfr = this.injector.get(i0.ComponentFactoryResolver);
                /** @type {?} */
                var factory = cfr.resolveComponentFactory(cmp);
                return this.vcr.createComponent(factory);
            };
        return TemplateHandler;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco-lang.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_LANG = new i0.InjectionToken('TRANSLOCO_LANG');

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco-loading-template.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_LOADING_TEMPLATE = new i0.InjectionToken('TRANSLOCO_LOADING_TEMPLATE');

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco-scope.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_SCOPE = new i0.InjectionToken('TRANSLOCO_SCOPE');

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/lang-resolver.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var LangResolver = /** @class */ (function () {
        function LangResolver() {
            this.initialized = false;
        }
        // inline => provider => active
        // inline => provider => active
        /**
         * @param {?=} __0
         * @return {?}
         */
        LangResolver.prototype.resolve =
            // inline => provider => active
            /**
             * @param {?=} __0
             * @return {?}
             */
            function (_a) {
                var _b = _a === void 0 ? { inline: undefined, provider: undefined, active: undefined } : _a, inline = _b.inline, provider = _b.provider, active = _b.active;
                /** @type {?} */
                var lang = active;
                /**
                 * When the user changes the lang we need to update
                 * the view. Otherwise, the lang will remain the inline/provided lang
                 */
                if (this.initialized) {
                    lang = active;
                    return lang;
                }
                if (provider) {
                    var _c = __read(getPipeValue(provider, 'static'), 2), _ = _c[0], extracted = _c[1];
                    lang = extracted;
                }
                if (inline) {
                    var _d = __read(getPipeValue(inline, 'static'), 2), _ = _d[0], extracted = _d[1];
                    lang = extracted;
                }
                this.initialized = true;
                return lang;
            };
        /**
         *
         * Resolve the lang
         *
         * @example
         *
         * resolveLangBasedOnScope('todos/en') => en
         * resolveLangBasedOnScope('en') => en
         *
         */
        /**
         *
         * Resolve the lang
         *
         * \@example
         *
         * resolveLangBasedOnScope('todos/en') => en
         * resolveLangBasedOnScope('en') => en
         *
         * @param {?} lang
         * @return {?}
         */
        LangResolver.prototype.resolveLangBasedOnScope = /**
         *
         * Resolve the lang
         *
         * \@example
         *
         * resolveLangBasedOnScope('todos/en') => en
         * resolveLangBasedOnScope('en') => en
         *
         * @param {?} lang
         * @return {?}
         */
            function (lang) {
                /** @type {?} */
                var scope = getScopeFromLang(lang);
                return scope ? getLangFromScope(lang) : lang;
            };
        /**
         *
         * Resolve the lang path for loading
         *
         * @example
         *
         * resolveLangPath('todos', 'en') => todos/en
         * resolveLangPath('en') => en
         *
         */
        /**
         *
         * Resolve the lang path for loading
         *
         * \@example
         *
         * resolveLangPath('todos', 'en') => todos/en
         * resolveLangPath('en') => en
         *
         * @param {?} lang
         * @param {?} scope
         * @return {?}
         */
        LangResolver.prototype.resolveLangPath = /**
         *
         * Resolve the lang path for loading
         *
         * \@example
         *
         * resolveLangPath('todos', 'en') => todos/en
         * resolveLangPath('en') => en
         *
         * @param {?} lang
         * @param {?} scope
         * @return {?}
         */
            function (lang, scope) {
                return scope ? scope + "/" + lang : lang;
            };
        return LangResolver;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/scope-resolver.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var ScopeResolver = /** @class */ (function () {
        function ScopeResolver(translocoService) {
            this.translocoService = translocoService;
        }
        // inline => provider
        // inline => provider
        /**
         * @param {?=} __0
         * @return {?}
         */
        ScopeResolver.prototype.resolve =
            // inline => provider
            /**
             * @param {?=} __0
             * @return {?}
             */
            function (_a) {
                var _b = _a === void 0 ? { inline: undefined, provider: undefined } : _a, inline = _b.inline, provider = _b.provider;
                if (inline) {
                    return inline;
                }
                if (provider) {
                    if (isScopeObject(provider)) {
                        var _c = ( /** @type {?} */(provider)), scope = _c.scope, _d = _c.alias, alias = _d === void 0 ? toCamelCase(scope) : _d;
                        this.translocoService._setScopeAlias(scope, alias);
                        return scope;
                    }
                    return ( /** @type {?} */(provider));
                }
                return undefined;
            };
        return ScopeResolver;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco.directive.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var TranslocoDirective = /** @class */ (function () {
        function TranslocoDirective(translocoService, tpl, providerScope, providerLang, providedLoadingTpl, vcr, cdr, host) {
            this.translocoService = translocoService;
            this.tpl = tpl;
            this.providerScope = providerScope;
            this.providerLang = providerLang;
            this.providedLoadingTpl = providedLoadingTpl;
            this.vcr = vcr;
            this.cdr = cdr;
            this.host = host;
            this.translationMemo = {};
            this.params = {};
            this.loaderTplHandler = null;
            // Whether we already rendered the view once
            this.initialized = false;
            this.langResolver = new LangResolver();
            this.scopeResolver = new ScopeResolver(this.translocoService);
        }
        /**
         * @return {?}
         */
        TranslocoDirective.prototype.ngOnInit = /**
         * @return {?}
         */
            function () {
                var _this = this;
                /** @type {?} */
                var listenToLangChange = shouldListenToLangChanges(this.translocoService, this.providerLang || this.inlineLang);
                this.subscription = this.translocoService.langChanges$
                    .pipe(operators.switchMap(( /**
             * @param {?} activeLang
             * @return {?}
             */function (activeLang) {
                    /** @type {?} */
                    var lang = _this.langResolver.resolve({
                        inline: _this.inlineLang,
                        provider: _this.providerLang,
                        active: activeLang
                    });
                    return Array.isArray(_this.providerScope)
                        ? rxjs.forkJoin((( /** @type {?} */(_this.providerScope))).map(( /**
                         * @param {?} providerScope
                         * @return {?}
                         */function (providerScope) { return _this.resolveScope(lang, providerScope); })))
                        : _this.resolveScope(lang, _this.providerScope);
                })), listenOrNotOperator(listenToLangChange))
                    .subscribe(( /**
             * @return {?}
             */function () {
                    _this.currentLang = _this.langResolver.resolveLangBasedOnScope(_this.path);
                    _this.tpl === null ? _this.simpleStrategy() : _this.structuralStrategy(_this.currentLang, _this.inlineRead);
                    _this.cdr.markForCheck();
                    _this.initialized = true;
                }));
                /** @type {?} */
                var loadingTpl = this.getLoadingTpl();
                if (!this.initialized && loadingTpl) {
                    this.loaderTplHandler = new TemplateHandler(loadingTpl, this.vcr);
                    this.loaderTplHandler.attachView();
                }
            };
        /**
         * @param {?} changes
         * @return {?}
         */
        TranslocoDirective.prototype.ngOnChanges = /**
         * @param {?} changes
         * @return {?}
         */
            function (changes) {
                // We need to support dynamic keys/params, so if this is not the first change CD cycle
                // we need to run the function again in order to update the value
                /** @type {?} */
                var notInit = Object.keys(changes).some(( /**
                 * @param {?} v
                 * @return {?}
                 */function (v) { return changes[v].firstChange === false; }));
                notInit && this.simpleStrategy();
            };
        /**
         * @private
         * @return {?}
         */
        TranslocoDirective.prototype.simpleStrategy = /**
         * @private
         * @return {?}
         */
            function () {
                this.detachLoader();
                this.host.nativeElement.innerText = this.translocoService.translate(this.key, this.params, this.currentLang);
            };
        /**
         * @private
         * @param {?} lang
         * @param {?} read
         * @return {?}
         */
        TranslocoDirective.prototype.structuralStrategy = /**
         * @private
         * @param {?} lang
         * @param {?} read
         * @return {?}
         */
            function (lang, read) {
                this.translationMemo = {};
                if (this.view) {
                    // when the lang changes we need to change the reference so Angular will update the view
                    this.view.context['$implicit'] = this.getTranslateFn(lang, read);
                    this.view.context['currentLang'] = this.currentLang;
                }
                else {
                    this.detachLoader();
                    this.view = this.vcr.createEmbeddedView(this.tpl, {
                        $implicit: this.getTranslateFn(lang, read),
                        currentLang: this.currentLang
                    });
                }
            };
        /**
         * @protected
         * @param {?} lang
         * @param {?} read
         * @return {?}
         */
        TranslocoDirective.prototype.getTranslateFn = /**
         * @protected
         * @param {?} lang
         * @param {?} read
         * @return {?}
         */
            function (lang, read) {
                var _this = this;
                return ( /**
                 * @param {?} key
                 * @param {?} params
                 * @return {?}
                 */function (key, params) {
                    /** @type {?} */
                    var withRead = read ? read + "." + key : key;
                    /** @type {?} */
                    var withParams = params ? "" + withRead + JSON.stringify(params) : withRead;
                    if (_this.translationMemo.hasOwnProperty(withParams)) {
                        return _this.translationMemo[withParams].value;
                    }
                    _this.translationMemo[withParams] = {
                        params: params,
                        value: _this.translocoService.translate(withRead, params, lang)
                    };
                    return _this.translationMemo[withParams].value;
                });
            };
        /**
         * @private
         * @return {?}
         */
        TranslocoDirective.prototype.getLoadingTpl = /**
         * @private
         * @return {?}
         */
            function () {
                return this.inlineTpl || this.providedLoadingTpl;
            };
        /**
         * @return {?}
         */
        TranslocoDirective.prototype.ngOnDestroy = /**
         * @return {?}
         */
            function () {
                this.subscription && this.subscription.unsubscribe();
            };
        /**
         * @private
         * @return {?}
         */
        TranslocoDirective.prototype.detachLoader = /**
         * @private
         * @return {?}
         */
            function () {
                this.loaderTplHandler && this.loaderTplHandler.detachView();
            };
        /**
         * @private
         * @param {?} lang
         * @param {?} providerScope
         * @return {?}
         */
        TranslocoDirective.prototype.resolveScope = /**
         * @private
         * @param {?} lang
         * @param {?} providerScope
         * @return {?}
         */
            function (lang, providerScope) {
                /** @type {?} */
                var resolvedScope = this.scopeResolver.resolve({ inline: this.inlineScope, provider: providerScope });
                this.path = this.langResolver.resolveLangPath(lang, resolvedScope);
                /** @type {?} */
                var inlineLoader = resolveInlineLoader(providerScope, resolvedScope);
                return this.translocoService._loadDependencies(this.path, inlineLoader);
            };
        TranslocoDirective.decorators = [
            { type: i0.Directive, args: [{
                        selector: '[transloco]'
                    },] }
        ];
        /** @nocollapse */
        TranslocoDirective.ctorParameters = function () {
            return [
                { type: TranslocoService },
                { type: i0.TemplateRef, decorators: [{ type: i0.Optional }] },
                { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [TRANSLOCO_SCOPE,] }] },
                { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [TRANSLOCO_LANG,] }] },
                { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [TRANSLOCO_LOADING_TEMPLATE,] }] },
                { type: i0.ViewContainerRef },
                { type: i0.ChangeDetectorRef },
                { type: i0.ElementRef }
            ];
        };
        TranslocoDirective.propDecorators = {
            key: [{ type: i0.Input, args: ['transloco',] }],
            params: [{ type: i0.Input, args: ['translocoParams',] }],
            inlineScope: [{ type: i0.Input, args: ['translocoScope',] }],
            inlineRead: [{ type: i0.Input, args: ['translocoRead',] }],
            inlineLang: [{ type: i0.Input, args: ['translocoLang',] }],
            inlineTpl: [{ type: i0.Input, args: ['translocoLoadingTpl',] }]
        };
        return TranslocoDirective;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco.pipe.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var TranslocoPipe = /** @class */ (function () {
        function TranslocoPipe(translocoService, providerScope, providerLang, cdr) {
            this.translocoService = translocoService;
            this.providerScope = providerScope;
            this.providerLang = providerLang;
            this.cdr = cdr;
            this.subscription = null;
            this.lastValue = '';
            this.langResolver = new LangResolver();
            this.scopeResolver = new ScopeResolver(this.translocoService);
            this.listenToLangChange = shouldListenToLangChanges(this.translocoService, this.providerLang);
        }
        // null is for handling strict mode + async pipe types https://github.com/ngneat/transloco/issues/311
        // null is for handling strict mode + async pipe types https://github.com/ngneat/transloco/issues/311
        /**
         * @param {?} key
         * @param {?=} params
         * @param {?=} inlineLang
         * @return {?}
         */
        TranslocoPipe.prototype.transform =
            // null is for handling strict mode + async pipe types https://github.com/ngneat/transloco/issues/311
            /**
             * @param {?} key
             * @param {?=} params
             * @param {?=} inlineLang
             * @return {?}
             */
            function (key, params, inlineLang) {
                var _this = this;
                if (!key) {
                    return key;
                }
                /** @type {?} */
                var keyName = params ? "" + key + JSON.stringify(params) : key;
                if (keyName === this.lastKey) {
                    return this.lastValue;
                }
                this.lastKey = keyName;
                this.subscription && this.subscription.unsubscribe();
                this.subscription = this.translocoService.langChanges$
                    .pipe(operators.switchMap(( /**
             * @param {?} activeLang
             * @return {?}
             */function (activeLang) {
                    /** @type {?} */
                    var lang = _this.langResolver.resolve({
                        inline: inlineLang,
                        provider: _this.providerLang,
                        active: activeLang
                    });
                    return Array.isArray(_this.providerScope)
                        ? rxjs.forkJoin((( /** @type {?} */(_this.providerScope))).map(( /**
                         * @param {?} providerScope
                         * @return {?}
                         */function (providerScope) { return _this.resolveScope(lang, providerScope); })))
                        : _this.resolveScope(lang, _this.providerScope);
                })), listenOrNotOperator(this.listenToLangChange))
                    .subscribe(( /**
             * @return {?}
             */function () { return _this.updateValue(key, params); }));
                return this.lastValue;
            };
        /**
         * @return {?}
         */
        TranslocoPipe.prototype.ngOnDestroy = /**
         * @return {?}
         */
            function () {
                this.subscription && this.subscription.unsubscribe();
            };
        /**
         * @private
         * @param {?} key
         * @param {?=} params
         * @return {?}
         */
        TranslocoPipe.prototype.updateValue = /**
         * @private
         * @param {?} key
         * @param {?=} params
         * @return {?}
         */
            function (key, params) {
                /** @type {?} */
                var lang = this.langResolver.resolveLangBasedOnScope(this.path);
                this.lastValue = this.translocoService.translate(key, params, lang);
                this.cdr.markForCheck();
            };
        /**
         * @private
         * @param {?} lang
         * @param {?} providerScope
         * @return {?}
         */
        TranslocoPipe.prototype.resolveScope = /**
         * @private
         * @param {?} lang
         * @param {?} providerScope
         * @return {?}
         */
            function (lang, providerScope) {
                /** @type {?} */
                var resolvedScope = this.scopeResolver.resolve({ inline: undefined, provider: providerScope });
                this.path = this.langResolver.resolveLangPath(lang, resolvedScope);
                /** @type {?} */
                var inlineLoader = resolveInlineLoader(providerScope, resolvedScope);
                return this.translocoService._loadDependencies(this.path, inlineLoader);
            };
        TranslocoPipe.decorators = [
            { type: i0.Pipe, args: [{
                        name: 'transloco',
                        pure: false
                    },] }
        ];
        /** @nocollapse */
        TranslocoPipe.ctorParameters = function () {
            return [
                { type: TranslocoService },
                { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [TRANSLOCO_SCOPE,] }] },
                { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [TRANSLOCO_LANG,] }] },
                { type: i0.ChangeDetectorRef }
            ];
        };
        return TranslocoPipe;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco.module.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var defaultProviders = [
        {
            provide: TRANSLOCO_TRANSPILER,
            useClass: DefaultTranspiler,
            deps: [TRANSLOCO_CONFIG]
        },
        {
            provide: TRANSLOCO_MISSING_HANDLER,
            useClass: DefaultHandler
        },
        {
            provide: TRANSLOCO_INTERCEPTOR,
            useClass: DefaultInterceptor
        },
        {
            provide: TRANSLOCO_FALLBACK_STRATEGY,
            useClass: DefaultFallbackStrategy,
            deps: [TRANSLOCO_CONFIG]
        }
    ];
    var TranslocoModule = /** @class */ (function () {
        function TranslocoModule() {
        }
        TranslocoModule.decorators = [
            { type: i0.NgModule, args: [{
                        declarations: [TranslocoDirective, TranslocoPipe, TranslocoLoaderComponent],
                        providers: [defaultProviders],
                        exports: [TranslocoDirective, TranslocoPipe],
                        entryComponents: [TranslocoLoaderComponent]
                    },] }
        ];
        return TranslocoModule;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/transloco-testing.module.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var TRANSLOCO_TEST_LANGS = new i0.InjectionToken('TRANSLOCO_TEST_LANGS - Available testing languages');
    /** @type {?} */
    var TRANSLOCO_TEST_OPTIONS = new i0.InjectionToken('TRANSLOCO_TEST_OPTIONS - Testing options');
    var TestingLoader = /** @class */ (function () {
        function TestingLoader(langs) {
            this.langs = langs;
        }
        /**
         * @param {?} lang
         * @return {?}
         */
        TestingLoader.prototype.getTranslation = /**
         * @param {?} lang
         * @return {?}
         */
            function (lang) {
                return rxjs.of(this.langs[lang]);
            };
        TestingLoader.decorators = [
            { type: i0.Injectable }
        ];
        /** @nocollapse */
        TestingLoader.ctorParameters = function () {
            return [
                { type: undefined, decorators: [{ type: i0.Inject, args: [TRANSLOCO_TEST_LANGS,] }] }
            ];
        };
        return TestingLoader;
    }());
    /**
     * @param {?} service
     * @param {?=} langs
     * @param {?=} options
     * @return {?}
     */
    function initTranslocoService(service, langs, options) {
        if (langs === void 0) {
            langs = {};
        }
        /** @type {?} */
        var preloadAllLangs = ( /**
         * @return {?}
         */function () {
            return options.preloadLangs
                ? Promise.all(Object.keys(langs).map(( /**
                 * @param {?} lang
                 * @return {?}
                 */function (lang) { return service.load(lang).toPromise(); })))
                : Promise.resolve();
        });
        return preloadAllLangs;
    }
    var TranslocoTestingModule = /** @class */ (function () {
        function TranslocoTestingModule() {
        }
        /**
         * @param {?} options
         * @return {?}
         */
        TranslocoTestingModule.forRoot = /**
         * @param {?} options
         * @return {?}
         */
            function (options) {
                return {
                    ngModule: TranslocoTestingModule,
                    providers: [
                        {
                            provide: TRANSLOCO_TEST_LANGS,
                            useValue: options.langs
                        },
                        {
                            provide: TRANSLOCO_TEST_OPTIONS,
                            useValue: options
                        },
                        {
                            provide: i0.APP_INITIALIZER,
                            useFactory: initTranslocoService,
                            deps: [TranslocoService, TRANSLOCO_TEST_LANGS, TRANSLOCO_TEST_OPTIONS],
                            multi: true
                        },
                        {
                            provide: TRANSLOCO_LOADER,
                            useClass: TestingLoader
                        },
                        defaultProviders,
                        {
                            provide: TRANSLOCO_CONFIG,
                            useValue: translocoConfig(__assign({ prodMode: true, missingHandler: { logMissingKey: false } }, options.translocoConfig))
                        }
                    ]
                };
            };
        /** @deprecated - use forRoot instead */
        /**
         * @deprecated - use forRoot instead
         * @param {?} langs
         * @param {?=} config
         * @param {?=} options
         * @return {?}
         */
        TranslocoTestingModule.withLangs = /**
         * @deprecated - use forRoot instead
         * @param {?} langs
         * @param {?=} config
         * @param {?=} options
         * @return {?}
         */
            function (langs, config, options) {
                if (config === void 0) {
                    config = {};
                }
                if (options === void 0) {
                    options = {};
                }
                return {
                    ngModule: TranslocoTestingModule,
                    providers: [
                        {
                            provide: TRANSLOCO_TEST_LANGS,
                            useValue: langs
                        },
                        {
                            provide: TRANSLOCO_TEST_OPTIONS,
                            useValue: options
                        },
                        {
                            provide: i0.APP_INITIALIZER,
                            useFactory: initTranslocoService,
                            deps: [TranslocoService, TRANSLOCO_TEST_LANGS, TRANSLOCO_TEST_OPTIONS],
                            multi: true
                        },
                        {
                            provide: TRANSLOCO_LOADER,
                            useClass: TestingLoader
                        },
                        defaultProviders,
                        {
                            provide: TRANSLOCO_CONFIG,
                            useValue: translocoConfig(__assign({ prodMode: true, missingHandler: { logMissingKey: false } }, config))
                        }
                    ]
                };
            };
        TranslocoTestingModule.decorators = [
            { type: i0.NgModule, args: [{
                        exports: [TranslocoModule]
                    },] }
        ];
        return TranslocoTestingModule;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/browser-lang.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * Returns the language code name from the browser, e.g. "en"
     * @return {?}
     */
    function getBrowserLang() {
        /** @type {?} */
        var browserLang = getBrowserCultureLang();
        if (isBrowser() === false || !browserLang) {
            return undefined;
        }
        if (browserLang.indexOf('-') !== -1) {
            browserLang = browserLang.split('-')[0];
        }
        if (browserLang.indexOf('_') !== -1) {
            browserLang = browserLang.split('_')[0];
        }
        return browserLang;
    }
    /**
     * Returns the culture language code name from the browser, e.g. "en-US"
     * @return {?}
     */
    function getBrowserCultureLang() {
        if (isBrowser() === false) {
            return undefined;
        }
        /** @type {?} */
        var navigator = ( /** @type {?} */(window.navigator));
        /** @type {?} */
        var browserCultureLang = navigator.languages ? navigator.languages[0] : null;
        browserCultureLang = browserCultureLang || navigator.language || navigator.browserLanguage || navigator.userLanguage;
        return browserCultureLang;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: public-api.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: ngneat-transloco.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    exports.translate = translate;
    exports.TranslocoService = TranslocoService;
    exports.TranslocoDirective = TranslocoDirective;
    exports.TranslocoPipe = TranslocoPipe;
    exports.TranslocoModule = TranslocoModule;
    exports.defaultProviders = defaultProviders;
    exports.TRANSLOCO_LOADER = TRANSLOCO_LOADER;
    exports.TRANSLOCO_CONFIG = TRANSLOCO_CONFIG;
    exports.defaultConfig = defaultConfig;
    exports.provideTranslocoConfig = provideTranslocoConfig;
    exports.translocoConfig = translocoConfig;
    exports.TRANSLOCO_TRANSPILER = TRANSLOCO_TRANSPILER;
    exports.DefaultTranspiler = DefaultTranspiler;
    exports.FunctionalTranspiler = FunctionalTranspiler;
    exports.getFunctionArgs = getFunctionArgs;
    exports.TRANSLOCO_SCOPE = TRANSLOCO_SCOPE;
    exports.TRANSLOCO_LOADING_TEMPLATE = TRANSLOCO_LOADING_TEMPLATE;
    exports.TRANSLOCO_LANG = TRANSLOCO_LANG;
    exports.TestingLoader = TestingLoader;
    exports.TranslocoTestingModule = TranslocoTestingModule;
    exports.TemplateHandler = TemplateHandler;
    exports.TRANSLOCO_INTERCEPTOR = TRANSLOCO_INTERCEPTOR;
    exports.TRANSLOCO_FALLBACK_STRATEGY = TRANSLOCO_FALLBACK_STRATEGY;
    exports.DefaultFallbackStrategy = DefaultFallbackStrategy;
    exports.TRANSLOCO_MISSING_HANDLER = TRANSLOCO_MISSING_HANDLER;
    exports.getBrowserCultureLang = getBrowserCultureLang;
    exports.getBrowserLang = getBrowserLang;
    exports.getPipeValue = getPipeValue;
    exports.getLangFromScope = getLangFromScope;
    exports.getScopeFromLang = getScopeFromLang;
    exports.getValue = getValue;
    exports.setValue = setValue;
    exports.size = size;
    exports.isEmpty = isEmpty;
    exports.isFunction = isFunction;
    exports.isString = isString;
    exports.isNumber = isNumber;
    exports.isObject = isObject;
    exports.coerceArray = coerceArray;
    exports.toCamelCase = toCamelCase;
    exports.isBrowser = isBrowser;
    exports.isNil = isNil;
    exports.isDefined = isDefined;
    exports.toNumber = toNumber;
    exports.isScopeObject = isScopeObject;
    exports.hasInlineLoader = hasInlineLoader;
    exports.unflatten = unflatten;
    exports.flatten = flatten;
    exports.ɵd = TranslocoLoaderComponent;
    exports.ɵc = DefaultHandler;
    exports.ɵa = initTranslocoService;
    exports.ɵb = DefaultInterceptor;

    Object.defineProperty(exports, '__esModule', { value: true });

})));

//# sourceMappingURL=ngneat-transloco.umd.js.map