@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
132 lines • 20.9 kB
JavaScript
import { Inject, Injectable } from '@angular/core';
import { OptionsService } from '../common';
import { CachedLocaleDictionaryService } from './cached-locale-dictionary.service';
import { PluginsResolveService } from '../plugins';
import { LOCALE_PATH } from './locale.path';
import { LANGUAGES } from './languages';
import { BehaviorSubject, combineLatest, defer, of } from 'rxjs';
import { catchError, distinctUntilChanged, map, shareReplay, switchMap, tap } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
import { getDictionaryWithTrimmedKeys } from './translation-utils';
import * as i0 from "@angular/core";
import * as i1 from "../common";
import * as i2 from "./cached-locale-dictionary.service";
import * as i3 from "../plugins";
import * as i4 from "@ngx-translate/core";
/**
* A service to load translations from different sources.
* It combines translations from the app, user-defined translations, and plugins.
* It also caches translations to avoid unnecessary requests.
*
* Is used instead of the default TranslateLoader functionality that ngx-translate provides as otherwise only the first translations from TranslateLoader observable would have been picked up.
* This would have been problematic, as we can only load the plugin translations after the login and we need to have at least the basic translations already on the login screen.
*/
export class TranslationLoaderService {
constructor(optionsService, cachedLocaleDictionaryService, pluginResolverService, translateService, path = null, languages = null) {
this.optionsService = optionsService;
this.cachedLocaleDictionaryService = cachedLocaleDictionaryService;
this.pluginResolverService = pluginResolverService;
this.translateService = translateService;
this.path = path;
this.languages = languages;
this.cache = new Map();
this.reloadTrigger$ = new BehaviorSubject(null);
this.translateService.onLangChange
.pipe(map(event => event.lang), distinctUntilChanged(), switchMap(lang => this.getTranslation(lang).pipe(map(translations => ({ lang, translations })))))
.subscribe(({ lang, translations }) => {
this.translateService.setTranslation(lang, translations, true);
});
}
getTranslation(lang) {
const translations$ = combineLatest([
defer(() => this.getTranslationsFromApp(lang)),
defer(() => this.getUserDefinedTranslations(lang)),
defer(() => this.optionsService.get$('langsDetails', {})),
defer(() => this.getTranslationsForPugins(lang))
]).pipe(map(([appTranslations, userDefinedTranslations, langsDetails, pluginTranslations]) => {
const translationsFromBranding = (langsDetails && langsDetails[lang]) || {};
return {
...appTranslations,
...pluginTranslations,
...translationsFromBranding,
...userDefinedTranslations
};
}), tap(dictionary => {
this.cachedLocaleDictionaryService.cachedDictionary[lang] = dictionary;
}), map(dictionary => getDictionaryWithTrimmedKeys(dictionary)), catchError(() => of({})));
return this.reloadTrigger$.pipe(switchMap(() => translations$));
}
triggerReload() {
this.clearCache();
this.reloadTrigger$.next();
}
clearCache() {
this.cache.clear();
}
getTranslationsForPugins(lang) {
return this.pluginResolverService.contextPathsFromWhereRemotesHaveBeenLoaded$.pipe(switchMap(plugins => {
// no need to load translations for self scoped plugins
plugins = plugins.filter(plugin => plugin !== this.optionsService.contextPath);
if (!plugins.length) {
return of({});
}
return combineLatest(plugins.map(plugin => this.getTranslationsForPlugin(lang, plugin))).pipe(map(translations => {
return translations.reduce((acc, translation) => ({ ...acc, ...translation }), {});
}));
}));
}
getTranslationsForPlugin(lang, pluginId) {
const url = `/apps/${pluginId}/${lang}.json`;
return this.getTranslationFromPath(url, lang);
}
getTranslationsFromApp(lang) {
const path = this.path || '';
let url = `${path}${lang}.json`;
if (this.languages && this.languages[lang] && this.languages[lang].url) {
url = this.languages[lang].url;
}
return this.getTranslationFromPath(url, lang);
}
getUserDefinedTranslations(lang) {
const url = `/apps/public/user-defined-translations/${lang}.json`;
return this.getTranslationFromPath(url, lang);
}
getTranslationFromPath(path, lang) {
if (this.cache.has(path)) {
return this.cache.get(path);
}
const observable = defer(async () => {
try {
const fetchResponse = await fetch(path);
if (!fetchResponse.ok) {
throw new Error(`Unexpected response status: ${fetchResponse.status}`);
}
const responseBody = await fetchResponse.json();
if (responseBody[lang]) {
return responseBody[lang];
}
}
catch (e) {
console.warn(`Failed to fetch translations from ${path}`);
}
return {};
}).pipe(shareReplay(1));
this.cache.set(path, observable);
return observable;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationLoaderService, deps: [{ token: i1.OptionsService }, { token: i2.CachedLocaleDictionaryService }, { token: i3.PluginsResolveService }, { token: i4.TranslateService }, { token: LOCALE_PATH }, { token: LANGUAGES }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationLoaderService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationLoaderService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i1.OptionsService }, { type: i2.CachedLocaleDictionaryService }, { type: i3.PluginsResolveService }, { type: i4.TranslateService }, { type: undefined, decorators: [{
type: Inject,
args: [LOCALE_PATH]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [LANGUAGES]
}] }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRpb24tbG9hZGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9jb3JlL2kxOG4vdHJhbnNsYXRpb24tbG9hZGVyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMzQyxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNuRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBYyxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDN0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7O0FBRW5FOzs7Ozs7O0dBT0c7QUFJSCxNQUFNLE9BQU8sd0JBQXdCO0lBSW5DLFlBQ1UsY0FBOEIsRUFDOUIsNkJBQTRELEVBQzVELHFCQUE0QyxFQUM1QyxnQkFBa0MsRUFDYixPQUFlLElBQUksRUFDckIsWUFBd0QsSUFBSTtRQUwvRSxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsa0NBQTZCLEdBQTdCLDZCQUE2QixDQUErQjtRQUM1RCwwQkFBcUIsR0FBckIscUJBQXFCLENBQXVCO1FB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QUMsRUFBRSxDQUFDO2dCQUNYLE9BQU8sQ0FBQyxJQUFJLENBQUMscUNBQXFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDNUQsQ0FBQztZQUNELE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNqQyxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDOytHQTdIVSx3QkFBd0Isa0tBU3pCLFdBQVcsYUFDWCxTQUFTO21IQVZSLHdCQUF3QixjQUZ2QixNQUFNOzs0RkFFUCx3QkFBd0I7a0JBSHBDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFVSSxNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixNQUFNOzJCQUFDLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9wdGlvbnNTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7IENhY2hlZExvY2FsZURpY3Rpb25hcnlTZXJ2aWNlIH0gZnJvbSAnLi9jYWNoZWQtbG9jYWxlLWRpY3Rpb25hcnkuc2VydmljZSc7XG5pbXBvcnQgeyBQbHVnaW5zUmVzb2x2ZVNlcnZpY2UgfSBmcm9tICcuLi9wbHVnaW5zJztcbmltcG9ydCB7IExPQ0FMRV9QQVRIIH0gZnJvbSAnLi9sb2NhbGUucGF0aCc7XG5pbXBvcnQgeyBMQU5HVUFHRVMgfSBmcm9tICcuL2xhbmd1YWdlcyc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIGRlZmVyLCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZGlzdGluY3RVbnRpbENoYW5nZWQsIG1hcCwgc2hhcmVSZXBsYXksIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgZ2V0RGljdGlvbmFyeVdpdGhUcmltbWVkS2V5cyB9IGZyb20gJy4vdHJhbnNsYXRpb24tdXRpbHMnO1xuXG4vKipcbiAqIEEgc2VydmljZSB0byBsb2FkIHRyYW5zbGF0aW9ucyBmcm9tIGRpZmZlcmVudCBzb3VyY2VzLlxuICogSXQgY29tYmluZXMgdHJhbnNsYXRpb25zIGZyb20gdGhlIGFwcCwgdXNlci1kZWZpbmVkIHRyYW5zbGF0aW9ucywgYW5kIHBsdWdpbnMuXG4gKiBJdCBhbHNvIGNhY2hlcyB0cmFuc2xhdGlvbnMgdG8gYXZvaWQgdW5uZWNlc3NhcnkgcmVxdWVzdHMuXG4gKlxuICogSXMgdXNlZCBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IFRyYW5zbGF0ZUxvYWRlciBmdW5jdGlvbmFsaXR5IHRoYXQgbmd4LXRyYW5zbGF0ZSBwcm92aWRlcyBhcyBvdGhlcndpc2Ugb25seSB0aGUgZmlyc3QgdHJhbnNsYXRpb25zIGZyb20gVHJhbnNsYXRlTG9hZGVyIG9ic2VydmFibGUgd291bGQgaGF2ZSBiZWVuIHBpY2tlZCB1cC5cbiAqIFRoaXMgd291bGQgaGF2ZSBiZWVuIHByb2JsZW1hdGljLCBhcyB3ZSBjYW4gb25seSBsb2FkIHRoZSBwbHVnaW4gdHJhbnNsYXRpb25zIGFmdGVyIHRoZSBsb2dpbiBhbmQgd2UgbmVlZCB0byBoYXZlIGF0IGxlYXN0IHRoZSBiYXNpYyB0cmFuc2xhdGlvbnMgYWxyZWFkeSBvbiB0aGUgbG9naW4gc2NyZWVuLlxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUcmFuc2xhdGlvbkxvYWRlclNlcnZpY2Uge1xuICBwcml2YXRlIGNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIE9ic2VydmFibGU8eyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfT4+KCk7XG4gIHByaXZhdGUgcmVsb2FkVHJpZ2dlciQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHZvaWQ+KG51bGwpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgb3B0aW9uc1NlcnZpY2U6IE9wdGlvbnNTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2FjaGVkTG9jYWxlRGljdGlvbmFyeVNlcnZpY2U6IENhY2hlZExvY2FsZURpY3Rpb25hcnlTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGx1Z2luUmVzb2x2ZXJTZXJ2aWNlOiBQbHVnaW5zUmVzb2x2ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIEBJbmplY3QoTE9DQUxFX1BBVEgpIHByaXZhdGUgcGF0aDogc3RyaW5nID0gbnVsbCxcbiAgICBASW5qZWN0KExBTkdVQUdFUykgcHJpdmF0ZSBsYW5ndWFnZXM6IHsgW2tleTogc3RyaW5nXTogeyB1cmw/OiBzdHJpbmcgfSB9IHwgbnVsbCA9IG51bGxcbiAgKSB7XG4gICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLm9uTGFuZ0NoYW5nZVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcChldmVudCA9PiBldmVudC5sYW5nKSxcbiAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgc3dpdGNoTWFwKGxhbmcgPT5cbiAgICAgICAgICB0aGlzLmdldFRyYW5zbGF0aW9uKGxhbmcpLnBpcGUobWFwKHRyYW5zbGF0aW9ucyA9PiAoeyBsYW5nLCB0cmFuc2xhdGlvbnMgfSkpKVxuICAgICAgICApXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCh7IGxhbmcsIHRyYW5zbGF0aW9ucyB9KSA9PiB7XG4gICAgICAgIHRoaXMudHJhbnNsYXRlU2VydmljZS5zZXRUcmFuc2xhdGlvbihsYW5nLCB0cmFuc2xhdGlvbnMsIHRydWUpO1xuICAgICAgfSk7XG4gIH1cblxuICBnZXRUcmFuc2xhdGlvbihsYW5nOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0+IHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnMkID0gY29tYmluZUxhdGVzdChbXG4gICAgICBkZWZlcigoKSA9PiB0aGlzLmdldFRyYW5zbGF0aW9uc0Zyb21BcHAobGFuZykpLFxuICAgICAgZGVmZXIoKCkgPT4gdGhpcy5nZXRVc2VyRGVmaW5lZFRyYW5zbGF0aW9ucyhsYW5nKSksXG4gICAgICBkZWZlcigoKSA9PiB0aGlzLm9wdGlvbnNTZXJ2aWNlLmdldCQoJ2xhbmdzRGV0YWlscycsIHt9KSksXG4gICAgICBkZWZlcigoKSA9PiB0aGlzLmdldFRyYW5zbGF0aW9uc0ZvclB1Z2lucyhsYW5nKSlcbiAgICBdKS5waXBlKFxuICAgICAgbWFwKChbYXBwVHJhbnNsYXRpb25zLCB1c2VyRGVmaW5lZFRyYW5zbGF0aW9ucywgbGFuZ3NEZXRhaWxzLCBwbHVnaW5UcmFuc2xhdGlvbnNdKSA9PiB7XG4gICAgICAgIGNvbnN0IHRyYW5zbGF0aW9uc0Zyb21CcmFuZGluZyA9IChsYW5nc0RldGFpbHMgJiYgbGFuZ3NEZXRhaWxzW2xhbmddKSB8fCB7fTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5hcHBUcmFuc2xhdGlvbnMsXG4gICAgICAgICAgLi4ucGx1Z2luVHJhbnNsYXRpb25zLFxuICAgICAgICAgIC4uLnRyYW5zbGF0aW9uc0Zyb21CcmFuZGluZyxcbiAgICAgICAgICAuLi51c2VyRGVmaW5lZFRyYW5zbGF0aW9uc1xuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgICB0YXAoZGljdGlvbmFyeSA9PiB7XG4gICAgICAgIHRoaXMuY2FjaGVkTG9jYWxlRGljdGlvbmFyeVNlcnZpY2UuY2FjaGVkRGljdGlvbmFyeVtsYW5nXSA9IGRpY3Rpb25hcnk7XG4gICAgICB9KSxcbiAgICAgIG1hcChkaWN0aW9uYXJ5ID0+IGdldERpY3Rpb25hcnlXaXRoVHJpbW1lZEtleXMoZGljdGlvbmFyeSkpLFxuICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZih7fSkpXG4gICAgKTtcblxuICAgIHJldHVybiB0aGlzLnJlbG9hZFRyaWdnZXIkLnBpcGUoc3dpdGNoTWFwKCgpID0+IHRyYW5zbGF0aW9ucyQpKTtcbiAgfVxuXG4gIHRyaWdnZXJSZWxvYWQoKSB7XG4gICAgdGhpcy5jbGVhckNhY2hlKCk7XG4gICAgdGhpcy5yZWxvYWRUcmlnZ2VyJC5uZXh0KCk7XG4gIH1cblxuICBjbGVhckNhY2hlKCkge1xuICAgIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRUcmFuc2xhdGlvbnNGb3JQdWdpbnMobGFuZzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMucGx1Z2luUmVzb2x2ZXJTZXJ2aWNlLmNvbnRleHRQYXRoc0Zyb21XaGVyZVJlbW90ZXNIYXZlQmVlbkxvYWRlZCQucGlwZShcbiAgICAgIHN3aXRjaE1hcChwbHVnaW5zID0+IHtcbiAgICAgICAgLy8gbm8gbmVlZCB0byBsb2FkIHRyYW5zbGF0aW9ucyBmb3Igc2VsZiBzY29wZWQgcGx1Z2luc1xuICAgICAgICBwbHVnaW5zID0gcGx1Z2lucy5maWx0ZXIocGx1Z2luID0+IHBsdWdpbiAhPT0gdGhpcy5vcHRpb25zU2VydmljZS5jb250ZXh0UGF0aCk7XG4gICAgICAgIGlmICghcGx1Z2lucy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gb2Yoe30pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KFxuICAgICAgICAgIHBsdWdpbnMubWFwKHBsdWdpbiA9PiB0aGlzLmdldFRyYW5zbGF0aW9uc0ZvclBsdWdpbihsYW5nLCBwbHVnaW4pKVxuICAgICAgICApLnBpcGUoXG4gICAgICAgICAgbWFwKHRyYW5zbGF0aW9ucyA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNsYXRpb25zLnJlZHVjZSgoYWNjLCB0cmFuc2xhdGlvbikgPT4gKHsgLi4uYWNjLCAuLi50cmFuc2xhdGlvbiB9KSwge30pO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0VHJhbnNsYXRpb25zRm9yUGx1Z2luKGxhbmc6IHN0cmluZywgcGx1Z2luSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHVybCA9IGAvYXBwcy8ke3BsdWdpbklkfS8ke2xhbmd9Lmpzb25gO1xuICAgIHJldHVybiB0aGlzLmdldFRyYW5zbGF0aW9uRnJvbVBhdGgodXJsLCBsYW5nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRUcmFuc2xhdGlvbnNGcm9tQXBwKGxhbmc6IHN0cmluZykge1xuICAgIGNvbnN0IHBhdGggPSB0aGlzLnBhdGggfHwgJyc7XG4gICAgbGV0IHVybCA9IGAke3BhdGh9JHtsYW5nfS5qc29uYDtcbiAgICBpZiAodGhpcy5sYW5ndWFnZXMgJiYgdGhpcy5sYW5ndWFnZXNbbGFuZ10gJiYgdGhpcy5sYW5ndWFnZXNbbGFuZ10udXJsKSB7XG4gICAgICB1cmwgPSB0aGlzLmxhbmd1YWdlc1tsYW5nXS51cmw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ2V0VHJhbnNsYXRpb25Gcm9tUGF0aCh1cmwsIGxhbmcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFVzZXJEZWZpbmVkVHJhbnNsYXRpb25zKGxhbmc6IHN0cmluZykge1xuICAgIGNvbnN0IHVybCA9IGAvYXBwcy9wdWJsaWMvdXNlci1kZWZpbmVkLXRyYW5zbGF0aW9ucy8ke2xhbmd9Lmpzb25gO1xuICAgIHJldHVybiB0aGlzLmdldFRyYW5zbGF0aW9uRnJvbVBhdGgodXJsLCBsYW5nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRUcmFuc2xhdGlvbkZyb21QYXRoKFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBsYW5nOiBzdHJpbmdcbiAgKTogT2JzZXJ2YWJsZTx7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9PiB7XG4gICAgaWYgKHRoaXMuY2FjaGUuaGFzKHBhdGgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXQocGF0aCk7XG4gICAgfVxuICAgIGNvbnN0IG9ic2VydmFibGUgPSBkZWZlcihhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBmZXRjaFJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocGF0aCk7XG4gICAgICAgIGlmICghZmV0Y2hSZXNwb25zZS5vaykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCByZXNwb25zZSBzdGF0dXM6ICR7ZmV0Y2hSZXNwb25zZS5zdGF0dXN9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZUJvZHkgPSBhd2FpdCBmZXRjaFJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgICBpZiAocmVzcG9uc2VCb2R5W2xhbmddKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlQm9keVtsYW5nXTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYEZhaWxlZCB0byBmZXRjaCB0cmFuc2xhdGlvbnMgZnJvbSAke3BhdGh9YCk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge307XG4gICAgfSkucGlwZShzaGFyZVJlcGxheSgxKSk7XG4gICAgdGhpcy5jYWNoZS5zZXQocGF0aCwgb2JzZXJ2YWJsZSk7XG4gICAgcmV0dXJuIG9ic2VydmFibGU7XG4gIH1cbn1cbiJdfQ==