@ogs-gmbh/ngx-translate
Version:
A lightweight, REST-based Angular i18n library designed for seamless internationalization with minimal setup. It supports dynamic language switching & flexible translation management via RESTful APIs.
236 lines • 61.3 kB
JavaScript
import { HttpRequestStatus } from "@ogs-gmbh/ngx-http";
import { BehaviorSubject, EMPTY, Subject, catchError, combineLatestWith, distinctUntilChanged, filter, map, of, switchMap, tap } from "rxjs";
import { Injectable, SkipSelf, inject } from "@angular/core";
import { findScopeInMultiScopedFile, findTokenInScopedFiles, parseMultiScopedFile, splitMultiScopedFile } from "../utils/file.util";
import { resolveScope, translateTokenByScopedFile, translateTokenByScopedFiles } from "../utils/translate.util";
import { HttpClient } from "@angular/common/http";
import { TRANSLATION_CONFIG_TOKEN } from "../tokens/config.token";
import { TranslationHttpSerivce } from "./translation-http.serivce";
import { TranslationNotDefinedError } from "../errors/translation-not-defined.error";
import { TranslationStoreService } from "./translation-store.service";
import * as i0 from "@angular/core";
export class TranslationService {
_httpClient = inject(HttpClient);
_translationConfig = inject(TRANSLATION_CONFIG_TOKEN);
_translationStoreService = inject(TranslationStoreService);
_translationHttpService = inject(TranslationHttpSerivce);
_isHttpLoading = new BehaviorSubject(null);
_isHttpLoading$ = this._isHttpLoading.asObservable();
isHttpLoading$() {
return this._isHttpLoading$.pipe(distinctUntilChanged(), filter((isHttpLoading) => isHttpLoading !== null));
}
_preloadWithRef$(httpClient, translationStoreService, translationHttpService, _locale, scopeName, httpOptions) {
if ((typeof scopeName === "string" || scopeName === null) && translationStoreService.hasScopedFile(scopeName))
return EMPTY;
if (Array.isArray(scopeName) && translationStoreService.hasScopedFiles(scopeName))
return EMPTY;
if ((typeof scopeName === "string" || scopeName === null) && translationStoreService.isScopeNameInNotifierScopes(scopeName))
return EMPTY;
if (Array.isArray(scopeName) && translationStoreService.areScopeNamesInNotifierScopes(scopeName))
return EMPTY;
if (typeof scopeName === "string" || scopeName === null) {
return translationHttpService.getWithRef$(httpClient, scopeName, httpOptions).pipe(tap((scopedFile) => {
translationStoreService.setScopedFile(scopeName, scopedFile);
}), map(() => void 0));
}
else {
const existingScopes = translationStoreService.getExistingScopes(scopeName);
if (existingScopes.length === scopeName.length)
return EMPTY;
const extinctScopes = scopeName.filter((_scopeName) => !existingScopes.includes(_scopeName));
if (extinctScopes.length === 0)
return EMPTY;
return translationHttpService.getWithRef$(httpClient, extinctScopes, httpOptions).pipe(tap((multiScopedFile) => {
const parsedMultiScopedFiles = parseMultiScopedFile(multiScopedFile);
parsedMultiScopedFiles.forEach((parsedScopedFile) => {
translationStoreService.setScopedFile(parsedScopedFile.scopeName, parsedScopedFile.file);
});
}), map(() => void 0));
}
}
translateTokenByLocale$(token, value, scopeName, httpOptions) {
return this._translationStoreService.getLocale$().pipe(switchMap((locale) => this._translateWithRef$(this._httpClient, this._translationStoreService, this._translationHttpService, locale, token, value, this._resolveScope(scopeName), httpOptions)));
}
translateTokenByCurrentLocale$(token, value, scopeName, httpOptions) {
const currentLocale = this._translationStoreService.getCurrentLocale();
return this._translateWithRef$(this._httpClient, this._translationStoreService, this._translationHttpService, currentLocale, token, value, scopeName, httpOptions);
}
preloadByLocale(httpClient, translationStoreService, translationHttpService, scopeName, httpOptions) {
return translationStoreService.getLocale$().pipe(switchMap((locale) => this._preloadWithRef$(httpClient, translationStoreService, translationHttpService, locale, scopeName, httpOptions)));
}
preloadByCurrentLocale(httpClient, translationStoreService, translationHttpService, scopeName, httpOptions) {
const currentLocale = translationStoreService.getCurrentLocale();
return this._preloadWithRef$(httpClient, translationStoreService, translationHttpService, currentLocale, scopeName, httpOptions);
}
_resolveScope(scopeName) {
return resolveScope(this._translationConfig, scopeName);
}
_translateBySourceLocale(token, value) {
if (!value)
throw new TranslationNotDefinedError(token);
return of(value);
}
_translateByStore(scope, token) {
if (typeof scope === "string" || scope === null) {
const scopedFile = this._translationStoreService.getScopedFile(scope);
const _translatedToken = translateTokenByScopedFile(scopedFile, token);
if (_translatedToken === undefined)
throw new TranslationNotDefinedError(token);
return of(_translatedToken);
}
let translatedToken;
scope.map((_scope) => this._translationStoreService.getScopedFile(_scope))
.some((scopedFile) => {
if (scopedFile === undefined)
return false;
const _translatedToken = translateTokenByScopedFile(scopedFile, token);
if (_translatedToken === undefined)
return false;
translatedToken = _translatedToken;
return true;
});
if (translatedToken === undefined)
throw new TranslationNotDefinedError(token);
return of(translatedToken);
}
_getScopedFileByNotifier(scope) {
const currentNotifier = new Subject();
this._translationStoreService.addNotifierToNotifierScope(scope, currentNotifier);
return currentNotifier.asObservable();
}
_getScopedFileByAddingNotifier(scope) {
const currentNotifier = new Subject();
this._translationStoreService.addNotifierScope({
scope,
notifiers: [currentNotifier]
});
return currentNotifier;
}
_getScopedFileByHttpWithRef$(httpClient, translationStoreService, translationHttpService, scope, httpOptions) {
if (typeof scope === "string" || scope === null)
translationStoreService.addNotifierScope({ scope, notifiers: null });
else
translationStoreService.addNotifierScopes(scope.map((_scope) => ({ scope: _scope, notifiers: null })));
this._isHttpLoading.next(HttpRequestStatus.PENDING);
return translationHttpService.getWithRef$(httpClient, scope, httpOptions).pipe(catchError(() => {
this._isHttpLoading.next(HttpRequestStatus.ERROR);
this._isHttpLoading.next(null);
if (typeof scope === "string" || scope === null)
translationStoreService.isScopeNameInNotifierScopes(scope) && translationStoreService.removeNotifierScope(scope);
else {
scope.forEach((_scope) => {
if (!translationStoreService.isScopeNameInNotifierScopes(_scope))
return;
translationStoreService.removeNotifierScope(_scope);
});
}
return of();
}), tap((genericScopedFile) => {
this._isHttpLoading.next(HttpRequestStatus.SUCCESS);
this._isHttpLoading.next(null);
if (typeof scope === "string" || scope === null) {
translationStoreService.setScopedFile(scope, genericScopedFile);
const notifierScope = translationStoreService.getNotiferScope(scope);
if (notifierScope === undefined)
return;
notifierScope.notifiers?.forEach((notifier) => {
notifier.next(genericScopedFile);
});
translationStoreService.removeNotifierScope(scope);
return;
}
scope.forEach((_scope) => {
const parsedScopedFile = findScopeInMultiScopedFile(genericScopedFile, _scope);
const notifierScope = translationStoreService.getNotiferScope(_scope);
if (notifierScope === undefined)
return;
notifierScope.notifiers?.forEach((notifier) => {
notifier.next(parsedScopedFile);
});
translationStoreService.removeNotifierScope(_scope);
});
}));
}
_translateWithRef$(httpClient, translationStoreService, translationHttpService, locale, token, value, scopeName, httpOptions) {
let resolvedScopes;
const sourceLocale = this._translationStoreService.getSourceLocale();
if (sourceLocale !== undefined && sourceLocale === this._translationStoreService.getCurrentLocale())
return this._translateBySourceLocale(token, value);
if (typeof scopeName === "string" || scopeName === null) {
resolvedScopes = this._resolveScope(scopeName);
if (translationStoreService.hasScopedFile(resolvedScopes))
return this._translateByStore(resolvedScopes, token);
}
else {
resolvedScopes = this._resolveScope(scopeName);
if (translationStoreService.hasScopedFiles(resolvedScopes))
return this._translateByStore(resolvedScopes, token);
}
if (typeof resolvedScopes === "string" || resolvedScopes === null) {
if (translationStoreService.isScopeNameInNotifierScopes(resolvedScopes)) {
return this._getScopedFileByNotifier(resolvedScopes)
.pipe(map((scopedFile) => {
const translatedToken = translateTokenByScopedFile(scopedFile, token);
if (translatedToken === undefined)
throw new TranslationNotDefinedError(token, value);
return translatedToken;
}));
}
}
else {
const existingScopes = translationStoreService.getExistingNotifierScopes(resolvedScopes);
const extinctScopes = resolvedScopes.filter((resolvedScope) => !existingScopes.includes(resolvedScope));
const existingNotifiers = existingScopes.map((existingScope) => this._getScopedFileByNotifier(existingScope));
const extinctScopesHttp = this._getScopedFileByHttpWithRef$(httpClient, translationStoreService, translationHttpService, extinctScopes, httpOptions)
.pipe(tap((multiScopedFile) => {
const castedMultiScopedFile = multiScopedFile;
const parsedMultiScopedFile = parseMultiScopedFile(castedMultiScopedFile);
parsedMultiScopedFile.forEach((_parsedMultiScopedFile) => {
translationStoreService.setScopedFile(_parsedMultiScopedFile.scopeName, _parsedMultiScopedFile.file);
});
}), map((multiScopedFile) => {
const castedMultiScopedFile = multiScopedFile;
const splittedMultiScopedFiles = splitMultiScopedFile(castedMultiScopedFile);
return findTokenInScopedFiles(splittedMultiScopedFiles, token);
}));
return extinctScopesHttp.pipe(combineLatestWith(...existingNotifiers), map((scopedFiles) => {
const translatedToken = translateTokenByScopedFiles(scopedFiles, token);
if (translatedToken === undefined)
throw new TranslationNotDefinedError(token, value);
return translatedToken;
}));
}
return of(locale).pipe(switchMap(() => (typeof resolvedScopes === "string" || resolvedScopes === null
? this._getScopedFileByHttpWithRef$(httpClient, translationStoreService, translationHttpService, resolvedScopes, httpOptions).pipe(map((scopedFile) => {
translationStoreService.setScopedFile(resolvedScopes, scopedFile);
const translatedToken = translateTokenByScopedFile(scopedFile, token);
if (translatedToken === undefined)
throw new TranslationNotDefinedError(token, value);
return translatedToken;
}))
: this._getScopedFileByHttpWithRef$(httpClient, translationStoreService, translationHttpService, resolvedScopes, httpOptions).pipe(tap((multiScopedFile) => {
const parsedMultiScopedFile = parseMultiScopedFile(multiScopedFile);
parsedMultiScopedFile.forEach((_parsedMultiScopedFile) => {
translationStoreService.setScopedFile(_parsedMultiScopedFile.scopeName, _parsedMultiScopedFile.file);
});
}), map((multiScopedFile) => {
const splittedMultiScopedFiles = splitMultiScopedFile(multiScopedFile);
const foundScopedFile = findTokenInScopedFiles(splittedMultiScopedFiles, token);
const translatedToken = translateTokenByScopedFile(foundScopedFile, token);
if (translatedToken === undefined)
throw new TranslationNotDefinedError(token, value);
return translatedToken;
})))));
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationService, providedIn: "root" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationService, decorators: [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], propDecorators: { _httpClient: [{
type: SkipSelf
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zZXJ2aWNlcy90cmFuc2xhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBa0MsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RixPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBYyxPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDekosT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRzdELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxzQkFBc0IsRUFBRSxvQkFBb0IsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3BJLE9BQU8sRUFBRSxZQUFZLEVBQUUsMEJBQTBCLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDcEUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDckYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7O0FBS3RFLE1BQU0sT0FBTyxrQkFBa0I7SUFFWixXQUFXLEdBQWUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRTdDLGtCQUFrQixHQUE0QixNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUUvRSx3QkFBd0IsR0FBNEIsTUFB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QUFDLENBQUM7Z0JBRXJELE9BQU8sZUFBZSxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxDQUNILENBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO3dHQS9nQlUsa0JBQWtCOzRHQUFsQixrQkFBa0IsY0FGakIsTUFBTTs7NEZBRVAsa0JBQWtCO2tCQUg5QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjs4QkFHa0IsV0FBVztzQkFEM0IsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBSZXF1ZXN0U3RhdHVzLCBIdHRwT3B0aW9ucywgSHR0cEhlYWRlcnNPcHRpb24gfSBmcm9tIFwiQG9ncy1nbWJoL25neC1odHRwXCI7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIEVNUFRZLCBPYnNlcnZhYmxlLCBTdWJqZWN0LCBjYXRjaEVycm9yLCBjb21iaW5lTGF0ZXN0V2l0aCwgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgbWFwLCBvZiwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgU2tpcFNlbGYsIGluamVjdCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBMb2NhbGVDb25maWcsIFNwZWNpZmljVHJhbnNsYXRlQ29uZmlnIH0gZnJvbSBcIi4uL3R5cGVzL2NvbmZpZy50eXBlXCI7XG5pbXBvcnQgeyBNdWx0aVNjb3BlZEZpbGUsIE5vdGlmaWVyU2NvcGUsIFBhcnNlZE11bHRpU2NvcGVkRmlsZSwgUGFyc2VkTXVsdGlTY29wZWRGaWxlcywgU2NvcGVkRmlsZSB9IGZyb20gXCIuLi90eXBlcy9zdG9yZS50eXBlXCI7XG5pbXBvcnQgeyBmaW5kU2NvcGVJbk11bHRpU2NvcGVkRmlsZSwgZmluZFRva2VuSW5TY29wZWRGaWxlcywgcGFyc2VNdWx0aVNjb3BlZEZpbGUsIHNwbGl0TXVsdGlTY29wZWRGaWxlIH0gZnJvbSBcIi4uL3V0aWxzL2ZpbGUudXRpbFwiO1xuaW1wb3J0IHsgcmVzb2x2ZVNjb3BlLCB0cmFuc2xhdGVUb2tlbkJ5U2NvcGVkRmlsZSwgdHJhbnNsYXRlVG9rZW5CeVNjb3BlZEZpbGVzIH0gZnJvbSBcIi4uL3V0aWxzL3RyYW5zbGF0ZS51dGlsXCI7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vbi9odHRwXCI7XG5pbXBvcnQgeyBUUkFOU0xBVElPTl9DT05GSUdfVE9LRU4gfSBmcm9tIFwiLi4vdG9rZW5zL2NvbmZpZy50b2tlblwiO1xuaW1wb3J0IHsgVHJhbnNsYXRpb25IdHRwU2VyaXZjZSB9IGZyb20gXCIuL3RyYW5zbGF0aW9uLWh0dHAuc2VyaXZjZVwiO1xuaW1wb3J0IHsgVHJhbnNsYXRpb25Ob3REZWZpbmVkRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3JzL3RyYW5zbGF0aW9uLW5vdC1kZWZpbmVkLmVycm9yXCI7XG5pbXBvcnQgeyBUcmFuc2xhdGlvblN0b3JlU2VydmljZSB9IGZyb20gXCIuL3RyYW5zbGF0aW9uLXN0b3JlLnNlcnZpY2VcIjtcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiBcInJvb3RcIlxufSlcbmV4cG9ydCBjbGFzcyBUcmFuc2xhdGlvblNlcnZpY2Uge1xuICBAU2tpcFNlbGYoKVxuICBwcml2YXRlIHJlYWRvbmx5IF9odHRwQ2xpZW50OiBIdHRwQ2xpZW50ID0gaW5qZWN0KEh0dHBDbGllbnQpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX3RyYW5zbGF0aW9uQ29uZmlnOiBTcGVjaWZpY1RyYW5zbGF0ZUNvbmZpZyA9IGluamVjdChUUkFOU0xBVElPTl9DT05GSUdfVE9LRU4pO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX3RyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlOiBUcmFuc2xhdGlvblN0b3JlU2VydmljZSA9IGluamVjdChUcmFuc2xhdGlvblN0b3JlU2VydmljZSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfdHJhbnNsYXRpb25IdHRwU2VydmljZTogVHJhbnNsYXRpb25IdHRwU2VyaXZjZSA9IGluamVjdChUcmFuc2xhdGlvbkh0dHBTZXJpdmNlKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9pc0h0dHBMb2FkaW5nOiBCZWhhdmlvclN1YmplY3Q8SHR0cFJlcXVlc3RTdGF0dXMgfCBudWxsPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SHR0cFJlcXVlc3RTdGF0dXMgfCBudWxsPihudWxsKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9pc0h0dHBMb2FkaW5nJDogT2JzZXJ2YWJsZTxIdHRwUmVxdWVzdFN0YXR1cyB8IG51bGw+ID0gdGhpcy5faXNIdHRwTG9hZGluZy5hc09ic2VydmFibGUoKTtcblxuICAvKipcbiAgICogR2V0dGVyIGZvciBnZXR0aW5nIGFuIE9ic2VydmFibGUsIHRoYXQgd2lsbCBlbWl0IG9ubHkgd2hlbiBhIEhUVFAtUmVxdWVzdCBpcyBtYWRlXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPEh0dHBSZXF1ZXN0U3RhdHVzIHwgbnVsbD59IC0gQW4gb2JzZXJ2YWJsZSB3aXRoIHRoZSBIdHRwUmVxdWVzdFN0YXR1cyBpZiBIVFRQIGlzIGN1cnJlbnRseSB1bmRlciB1c2UuIE90aGVyd2lzZSBhbiBvYnNlcnZhYmxlIHdpdGggbnVsbCBpbnNpZGUuXG4gICAqL1xuICBwdWJsaWMgaXNIdHRwTG9hZGluZyQgKCk6IE9ic2VydmFibGU8SHR0cFJlcXVlc3RTdGF0dXMgfCBudWxsPiB7XG4gICAgcmV0dXJuIHRoaXMuX2lzSHR0cExvYWRpbmckLnBpcGUoXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgZmlsdGVyKChpc0h0dHBMb2FkaW5nOiBIdHRwUmVxdWVzdFN0YXR1cyB8IG51bGwpOiBib29sZWFuID0+IGlzSHR0cExvYWRpbmcgIT09IG51bGwpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVsb2FkIG11bHRpcGxlIHRyYW5zbGF0aW9ucyB3aXRoIHJlZmVyZW5jZXMgdG8gdGhlIHJlcXVpcmVkIHNlcnZpY2VzXG4gICAqIEBwYXJhbSB7SHR0cENsaWVudH0gaHR0cENsaWVudCAtIFRoZSBIdHRwQ2xpZW50LCB0aGF0J2xsIGJlIHVzZWRcbiAgICogQHBhcmFtIHtUcmFuc2xhdGlvblN0b3JlU2VydmljZX0gdHJhbnNsYXRpb25TdG9yZVNlcnZpY2UgLSBUaGUgVHJhbnNsYXRpb25TdG9yZVNlcnZpY2UsIHRoYXQnbGwgYmUgdXNlZFxuICAgKiBAcGFyYW0ge1RyYW5zbGF0aW9uSHR0cFNlcml2Y2V9IHRyYW5zbGF0aW9uSHR0cFNlcnZpY2UgLSBUaGUgVHJhbnNsYXRpb25IdHRwU2VydmljZSwgdGhhdCdsbCBiZSB1c2VkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBfbG9jYWxlIC0gVGhlIGxvY2FsZSwgdGhhdCBzaG91bGQgYmUgcHJlbG9hZGVkXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVsbH0gc2NvcGVOYW1lIC0gVGhlIHNjb3BlIG5hbWUgZm9yIHRoZSBsb29rdXAgb2YgdGhlIHRyYW5zbGF0aW9uXG4gICAqIEBwYXJhbSB7SHR0cE9wdGlvbnMgfCB1bmRlZmluZWR9IGh0dHBPcHRpb25zIC0gQWRkaXRpb25hbCBIVFRQIE9wdGlvbnMgZm9yIHRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPHZvaWQ+fSAtIEFuIG9ic2VydmFibGUgdG8gaGFuZGxlIHRoZSBzdGF0dXNcbiAgICovXG4gIC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHNlc2xpbnQvY2xhc3MtbWV0aG9kcy11c2UtdGhpcywgQHRzZXNsaW50L21heC1wYXJhbXMgKi9cbiAgcHVibGljIF9wcmVsb2FkV2l0aFJlZiQgKFxuICAgIGh0dHBDbGllbnQ6IFJlYWRvbmx5PEh0dHBDbGllbnQ+LFxuICAgIHRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlOiBSZWFkb25seTxUcmFuc2xhdGlvblN0b3JlU2VydmljZT4sXG4gICAgdHJhbnNsYXRpb25IdHRwU2VydmljZTogUmVhZG9ubHk8VHJhbnNsYXRpb25IdHRwU2VyaXZjZT4sXG4gICAgX2xvY2FsZTogTG9jYWxlQ29uZmlnLFxuICAgIHNjb3BlTmFtZTogUmVhZG9ubHlBcnJheTxzdHJpbmcgfCBudWxsPiB8IHN0cmluZyB8IG51bGwsXG4gICAgaHR0cE9wdGlvbnM/OiBIdHRwT3B0aW9uczxuZXZlciwgSHR0cEhlYWRlcnNPcHRpb24sIG5ldmVyPlxuICApOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICAvKlxuICAgICAqIEhhbmRsZSByZXNvbHZlIGJ5IHN0b3JlXG4gICAgICogQ2hlY2sgaWYgYWxsIHNjb3BlcyBhcmUgaW4gc3RvcmVcbiAgICAgKi9cbiAgICBpZiAoKHR5cGVvZiBzY29wZU5hbWUgPT09IFwic3RyaW5nXCIgfHwgc2NvcGVOYW1lID09PSBudWxsKSAmJiB0cmFuc2xhdGlvblN0b3JlU2VydmljZS5oYXNTY29wZWRGaWxlKHNjb3BlTmFtZSkpXG4gICAgICByZXR1cm4gRU1QVFk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzY29wZU5hbWUpICYmIHRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmhhc1Njb3BlZEZpbGVzKHNjb3BlTmFtZSkpXG4gICAgICByZXR1cm4gRU1QVFk7XG5cbiAgICAvLyBDaGVjayBpZiBzY29wZXMgYXJlIGluIG5vdGlmZXIgc2NvcGVzXG4gICAgaWYgKCh0eXBlb2Ygc2NvcGVOYW1lID09PSBcInN0cmluZ1wiIHx8IHNjb3BlTmFtZSA9PT0gbnVsbCkgJiYgdHJhbnNsYXRpb25TdG9yZVNlcnZpY2UuaXNTY29wZU5hbWVJbk5vdGlmaWVyU2NvcGVzKHNjb3BlTmFtZSkpXG4gICAgICByZXR1cm4gRU1QVFk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzY29wZU5hbWUpICYmIHRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmFyZVNjb3BlTmFtZXNJbk5vdGlmaWVyU2NvcGVzKHNjb3BlTmFtZSBhcyBSZWFkb25seUFycmF5PHN0cmluZyB8IG51bGw+KSlcbiAgICAgIHJldHVybiBFTVBUWTtcblxuICAgIC8vIENoZWNrIGlmIHNjb3BlcyBhcmUgbm90IGluIHN0b3JlXG4gICAgaWYgKHR5cGVvZiBzY29wZU5hbWUgPT09IFwic3RyaW5nXCIgfHwgc2NvcGVOYW1lID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gdHJhbnNsYXRpb25IdHRwU2VydmljZS5nZXRXaXRoUmVmJDxTY29wZWRGaWxlPihcbiAgICAgICAgaHR0cENsaWVudCxcbiAgICAgICAgc2NvcGVOYW1lLFxuICAgICAgICBodHRwT3B0aW9uc1xuICAgICAgKS5waXBlKFxuICAgICAgICB0YXAoKHNjb3BlZEZpbGU6IFNjb3BlZEZpbGUpOiB2b2lkID0+IHtcbiAgICAgICAgICB0cmFuc2xhdGlvblN0b3JlU2VydmljZS5zZXRTY29wZWRGaWxlKHNjb3BlTmFtZSwgc2NvcGVkRmlsZSk7XG4gICAgICAgIH0pLFxuICAgICAgICBtYXAoKCk6IHZvaWQgPT4gdm9pZCAwKVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZXhpc3RpbmdTY29wZXM6IEFycmF5PHN0cmluZyB8IG51bGw+ID0gdHJhbnNsYXRpb25TdG9yZVNlcnZpY2UuZ2V0RXhpc3RpbmdTY29wZXMoc2NvcGVOYW1lKTtcblxuICAgICAgaWYgKGV4aXN0aW5nU2NvcGVzLmxlbmd0aCA9PT0gc2NvcGVOYW1lLmxlbmd0aClcbiAgICAgICAgcmV0dXJuIEVNUFRZO1xuXG4gICAgICBjb25zdCBleHRpbmN0U2NvcGVzOiBBcnJheTxzdHJpbmcgfCBudWxsPiA9IHNjb3BlTmFtZS5maWx0ZXIoKF9zY29wZU5hbWU6IHN0cmluZyB8IG51bGwpOiBib29sZWFuID0+ICFleGlzdGluZ1Njb3Blcy5pbmNsdWRlcyhfc2NvcGVOYW1lKSk7XG5cbiAgICAgIGlmIChleHRpbmN0U2NvcGVzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgcmV0dXJuIEVNUFRZO1xuXG4gICAgICByZXR1cm4gdHJhbnNsYXRpb25IdHRwU2VydmljZS5nZXRXaXRoUmVmJDxNdWx0aVNjb3BlZEZpbGU+KFxuICAgICAgICBodHRwQ2xpZW50LFxuICAgICAgICBleHRpbmN0U2NvcGVzLFxuICAgICAgICBodHRwT3B0aW9uc1xuICAgICAgKS5waXBlKFxuICAgICAgICB0YXAoKG11bHRpU2NvcGVkRmlsZTogTXVsdGlTY29wZWRGaWxlKTogdm9pZCA9PiB7XG4gICAgICAgICAgY29uc3QgcGFyc2VkTXVsdGlTY29wZWRGaWxlczogUGFyc2VkTXVsdGlTY29wZWRGaWxlcyA9IHBhcnNlTXVsdGlTY29wZWRGaWxlKG11bHRpU2NvcGVkRmlsZSk7XG5cbiAgICAgICAgICBwYXJzZWRNdWx0aVNjb3BlZEZpbGVzLmZvckVhY2goKHBhcnNlZFNjb3BlZEZpbGU6IFBhcnNlZE11bHRpU2NvcGVkRmlsZSk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgdHJhbnNsYXRpb25TdG9yZVNlcnZpY2Uuc2V0U2NvcGVkRmlsZShwYXJzZWRTY29wZWRGaWxlLnNjb3BlTmFtZSwgcGFyc2VkU2NvcGVkRmlsZS5maWxlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICAgIG1hcCgoKTogdm9pZCA9PiB2b2lkIDApXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2xhdGVzIGEgdG9rZW4gYnkgdGhlIGxvY2FsZSByZWFjdGl2ZVxcXG4gICAqIElmIHRoZSBsb2NhbGUgY2hhbmdlcywgYSBuZXcgdHJhbnNsYXRpb24gYmFzZWQgb24gdGhlIG5ldyBsb2NhbGUgd2lsbCBiZSBlbWl0dGVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9rZW4gLSBUaGUgdG9rZW4gdG8gcmVzb2x2ZSB0aGUgdHJhbnNsYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHNjb3BlTmFtZSAtIEEgc2NvcGUgbmFtZSB0byByZXNvbHZlIHRoZSBsb29rdXBcbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHZhbHVlIC0gVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIHRyYW5zbGF0aW9uXG4gICAqIEBwYXJhbSB7SHR0cE9wdGlvbnMgfCB1bmRlZmluZWR9IGh0dHBPcHRpb25zIC0gQWRkaXRpb25hbCBIVFRQIE9wdGlvbnMgZm9yIHRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPHN0cmluZz59IC0gQW4gb2JzZXJ2YWJsZSB3aXRoIHRoZSBjdXJyZW50IHRyYW5zbGF0aW9uIGFzIHN0cmluZ1xuICAgKi9cbiAgcHVibGljIHRyYW5zbGF0ZVRva2VuQnlMb2NhbGUkIChcbiAgICB0b2tlbjogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcsXG4gICAgc2NvcGVOYW1lPzogUmVhZG9ubHlBcnJheTxzdHJpbmcgfCBudWxsPiB8IHN0cmluZyB8IG51bGwsXG4gICAgaHR0cE9wdGlvbnM/OiBIdHRwT3B0aW9uczxuZXZlciwgSHR0cEhlYWRlcnNPcHRpb24sIG5ldmVyPlxuICApOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLl90cmFuc2xhdGlvblN0b3JlU2VydmljZS5nZXRMb2NhbGUkKCkucGlwZShzd2l0Y2hNYXAoKGxvY2FsZTogTG9jYWxlQ29uZmlnKTogT2JzZXJ2YWJsZTxzdHJpbmc+ID0+IHRoaXMuX3RyYW5zbGF0ZVdpdGhSZWYkKFxuICAgICAgdGhpcy5faHR0cENsaWVudCxcbiAgICAgIHRoaXMuX3RyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLFxuICAgICAgdGhpcy5fdHJhbnNsYXRpb25IdHRwU2VydmljZSxcbiAgICAgIGxvY2FsZSxcbiAgICAgIHRva2VuLFxuICAgICAgdmFsdWUsXG4gICAgICB0aGlzLl9yZXNvbHZlU2NvcGUoc2NvcGVOYW1lKSxcbiAgICAgIGh0dHBPcHRpb25zXG4gICAgKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zbGF0ZXMgYSB0b2tlbiBieSB0aGUgY3VycmVudCBsb2NhbGVcXFxuICAgKiBJZiB0aGUgbG9jYWxlIGNoYW5nZXMsIG5vIG5ldyB0cmFuc2xhdGlvbiB3aWxsIGJlIGVtaXR0ZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlbiAtIFRoZSB0b2tlbiB0byByZXNvbHZlIHRoZSB0cmFuc2xhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZyB8IHVuZGVmaW5lZH0gc2NvcGVOYW1lIC0gQSBzY29wZSBuYW1lIHRvIHJlc29sdmUgdGhlIGxvb2t1cFxuICAgKiBAcGFyYW0ge3N0cmluZyB8IHVuZGVmaW5lZH0gdmFsdWUgLSBUaGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGUgdHJhbnNsYXRpb25cbiAgICogQHBhcmFtIHtIdHRwT3B0aW9ucyB8IHVuZGVmaW5lZH0gaHR0cE9wdGlvbnMgLSBBZGRpdGlvbmFsIEhUVFAgT3B0aW9ucyBmb3IgdGhlIHJlcXVlc3RcbiAgICogQHJldHVybnMge09ic2VydmFibGU8c3RyaW5nPn0gLSBBbiBvYnNlcnZhYmxlIHdpdGggdGhlIGN1cnJlbnQgdHJhbnNsYXRpb24gYXMgc3RyaW5nXG4gICAqL1xuICBwdWJsaWMgdHJhbnNsYXRlVG9rZW5CeUN1cnJlbnRMb2NhbGUkIChcbiAgICB0b2tlbjogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcsXG4gICAgc2NvcGVOYW1lPzogUmVhZG9ubHlBcnJheTxzdHJpbmcgfCBudWxsPiB8IHN0cmluZyB8IG51bGwsXG4gICAgaHR0cE9wdGlvbnM/OiBIdHRwT3B0aW9uczxuZXZlciwgSHR0cEhlYWRlcnNPcHRpb24sIG5ldmVyPlxuICApOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIGNvbnN0IGN1cnJlbnRMb2NhbGU6IExvY2FsZUNvbmZpZyA9IHRoaXMuX3RyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmdldEN1cnJlbnRMb2NhbGUoKTtcblxuICAgIHJldHVybiB0aGlzLl90cmFuc2xhdGVXaXRoUmVmJChcbiAgICAgIHRoaXMuX2h0dHBDbGllbnQsXG4gICAgICB0aGlzLl90cmFuc2xhdGlvblN0b3JlU2VydmljZSxcbiAgICAgIHRoaXMuX3RyYW5zbGF0aW9uSHR0cFNlcnZpY2UsXG4gICAgICBjdXJyZW50TG9jYWxlLFxuICAgICAgdG9rZW4sXG4gICAgICB2YWx1ZSxcbiAgICAgIHNjb3BlTmFtZSxcbiAgICAgIGh0dHBPcHRpb25zXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVsb2FkIHRyYW5zbGF0aW9ucyBieSBsb2NhbGUgcmVhY3RpdmUuXG4gICAqL1xuICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHRzZXNsaW50L21heC1wYXJhbXMgKi9cbiAgcHVibGljIHByZWxvYWRCeUxvY2FsZSAoXG4gICAgaHR0cENsaWVudDogUmVhZG9ubHk8SHR0cENsaWVudD4sXG4gICAgdHJhbnNsYXRpb25TdG9yZVNlcnZpY2U6IFJlYWRvbmx5PFRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlPixcbiAgICB0cmFuc2xhdGlvbkh0dHBTZXJ2aWNlOiBSZWFkb25seTxUcmFuc2xhdGlvbkh0dHBTZXJpdmNlPixcbiAgICBzY29wZU5hbWU6IHN0cmluZyB8IG51bGwgfCBSZWFkb25seUFycmF5PHN0cmluZyB8IG51bGw+LFxuICAgIGh0dHBPcHRpb25zPzogSHR0cE9wdGlvbnM8bmV2ZXIsIEh0dHBIZWFkZXJzT3B0aW9uLCBuZXZlcj5cbiAgKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmdldExvY2FsZSQoKS5waXBlKHN3aXRjaE1hcCgobG9jYWxlOiBMb2NhbGVDb25maWcpOiBPYnNlcnZhYmxlPHZvaWQ+ID0+IHRoaXMuX3ByZWxvYWRXaXRoUmVmJChcbiAgICAgIGh0dHBDbGllbnQsXG4gICAgICB0cmFuc2xhdGlvblN0b3JlU2VydmljZSxcbiAgICAgIHRyYW5zbGF0aW9uSHR0cFNlcnZpY2UsXG4gICAgICBsb2NhbGUsXG4gICAgICBzY29wZU5hbWUsXG4gICAgICBodHRwT3B0aW9uc1xuICAgICkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVsb2FkIHRyYW5zbGF0aW9ucyBieSBjdXJyZW50IGxvY2FsZS5cbiAgICovXG4gIC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHNlc2xpbnQvbWF4LXBhcmFtcyAqL1xuICBwdWJsaWMgcHJlbG9hZEJ5Q3VycmVudExvY2FsZSAoXG4gICAgaHR0cENsaWVudDogUmVhZG9ubHk8SHR0cENsaWVudD4sXG4gICAgdHJhbnNsYXRpb25TdG9yZVNlcnZpY2U6IFJlYWRvbmx5PFRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlPixcbiAgICB0cmFuc2xhdGlvbkh0dHBTZXJ2aWNlOiBSZWFkb25seTxUcmFuc2xhdGlvbkh0dHBTZXJpdmNlPixcbiAgICBzY29wZU5hbWU6IHN0cmluZyB8IG51bGwgfCBSZWFkb25seUFycmF5PHN0cmluZyB8IG51bGw+LFxuICAgIGh0dHBPcHRpb25zPzogSHR0cE9wdGlvbnM8bmV2ZXIsIEh0dHBIZWFkZXJzT3B0aW9uLCBuZXZlcj5cbiAgKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgY29uc3QgY3VycmVudExvY2FsZTogTG9jYWxlQ29uZmlnID0gdHJhbnNsYXRpb25TdG9yZVNlcnZpY2UuZ2V0Q3VycmVudExvY2FsZSgpO1xuXG4gICAgcmV0dXJuIHRoaXMuX3ByZWxvYWRXaXRoUmVmJChcbiAgICAgIGh0dHBDbGllbnQsXG4gICAgICB0cmFuc2xhdGlvblN0b3JlU2VydmljZSxcbiAgICAgIHRyYW5zbGF0aW9uSHR0cFNlcnZpY2UsXG4gICAgICBjdXJyZW50TG9jYWxlLFxuICAgICAgc2NvcGVOYW1lLFxuICAgICAgaHR0cE9wdGlvbnNcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgc2NvcGUocykgaGllcmFyY2hpY2FsbHlcbiAgICogQHBhcmFtIHtBcnJheTxzdHJpbmcgfCBudWxsPiB8IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWR9IHNjb3BlTmFtZSAtIFNjb3BlIG5hbWUocyksIHRoYXQgc2hvdWxkIGJlIHJlc29sdmVkXG4gICAqIEByZXR1cm5zIHtBcnJheTxzdHJpbmcgfCBudWxsPiB8IHN0cmluZyB8IG51bGx9IC0gYmFzZWQgb24gdHlwZVxuICAgKi9cbiAgcHJpdmF0ZSBfcmVzb2x2ZVNjb3BlPFQgZXh0ZW5kcyBSZWFkb25seUFycmF5PHN0cmluZyB8IG51bGw+IHwgc3RyaW5nIHwgbnVsbD4oc2NvcGVOYW1lPzogVCk6IFQge1xuICAgIHJldHVybiByZXNvbHZlU2NvcGUodGhpcy5fdHJhbnNsYXRpb25Db25maWcsIHNjb3BlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhbnNsYXRlIHRva2VuIGJ5IHNvdXJjZSBsb2NhbGVcbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHZhbHVlIC0gVGhlIHZhbHVlLCB0aGF0IHNob3VsZCBiZSB0cmFuc2xhdGVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlbiAtIFRoZSB0b2tlbiwgdGhhdCBpcyBkZWZpbmVkIGZvciB0aGUgdmFsdWVcbiAgICogQHJldHVybnMge09ic2VydmFibGU8c3RyaW5nPn0gLSBBbiBvYnNlcnZhYmxlIHdpdGggdGhlIHRyYW5zbGF0aW9uIGFzIHZhbHVlXG4gICAqL1xuICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHRzZXNsaW50L2NsYXNzLW1ldGhvZHMtdXNlLXRoaXMgKi9cbiAgcHJpdmF0ZSBfdHJhbnNsYXRlQnlTb3VyY2VMb2NhbGUgKHRva2VuOiBzdHJpbmcsIHZhbHVlPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICBpZiAoIXZhbHVlKVxuICAgICAgdGhyb3cgbmV3IFRyYW5zbGF0aW9uTm90RGVmaW5lZEVycm9yKHRva2VuKTtcblxuICAgIHJldHVybiBvZih2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhbnNsYXRlIHRva2VuIGJ5IHJlc29sdmluZyBpdCBmcm9tIHRoZSBzdG9yYWdlXFxcbiAgICogVGhlIGZpcnN0IG1hdGNoaW5nIHRyYW5zbGF0aW9uIHdpbGwgYmUgdXNlZCBpZiBzY29wZSBpcyBwcm92aWRlZCBoZXJlIGFzIGFuIEFycmF5LlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IHNjb3BlIC0gVGhlIHNjb3BlLCB0aGF0IHdpbGwgYmUgbG9va2VkIHVwXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlbiAtIFRoZSB0b2tlbiwgdGhhdCBpcyBkZWZpbmVkIGZvciB0aGUgdmFsdWVcbiAgICogQHJldHVybnMge09ic2VydmFibGU8c3RyaW5nPn0gLSBBbiBvYnNlcnZhYmxlIHdpdGggdGhlIHRyYW5zbGF0aW9uIGFzIHZhbHVlXG4gICAqL1xuICBwcml2YXRlIF90cmFuc2xhdGVCeVN0b3JlIChzY29wZTogUmVhZG9ubHlBcnJheTxzdHJpbmcgfCBudWxsPiB8IHN0cmluZyB8IG51bGwsIHRva2VuOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIGlmICh0eXBlb2Ygc2NvcGUgPT09IFwic3RyaW5nXCIgfHwgc2NvcGUgPT09IG51bGwpIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHNlc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG4gICAgICBjb25zdCBzY29wZWRGaWxlOiBTY29wZWRGaWxlID0gdGhpcy5fdHJhbnNsYXRpb25TdG9yZVNlcnZpY2UuZ2V0U2NvcGVkRmlsZShzY29wZSkhO1xuICAgICAgY29uc3QgX3RyYW5zbGF0ZWRUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdHJhbnNsYXRlVG9rZW5CeVNjb3BlZEZpbGUoc2NvcGVkRmlsZSwgdG9rZW4pO1xuXG4gICAgICBpZiAoX3RyYW5zbGF0ZWRUb2tlbiA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgVHJhbnNsYXRpb25Ob3REZWZpbmVkRXJyb3IodG9rZW4pO1xuXG4gICAgICByZXR1cm4gb2YoX3RyYW5zbGF0ZWRUb2tlbik7XG4gICAgfVxuXG4gICAgbGV0IHRyYW5zbGF0ZWRUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgc2NvcGUubWFwKChfc2NvcGU6IHN0cmluZyB8IG51bGwpOiBTY29wZWRGaWxlIHwgdW5kZWZpbmVkID0+IHRoaXMuX3RyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmdldFNjb3BlZEZpbGUoX3Njb3BlKSlcbiAgICAgIC5zb21lKChzY29wZWRGaWxlOiBTY29wZWRGaWxlIHwgdW5kZWZpbmVkKTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGlmIChzY29wZWRGaWxlID09PSB1bmRlZmluZWQpIHJldHVybiBmYWxzZTtcblxuICAgICAgICBjb25zdCBfdHJhbnNsYXRlZFRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB0cmFuc2xhdGVUb2tlbkJ5U2NvcGVkRmlsZShzY29wZWRGaWxlLCB0b2tlbik7XG5cbiAgICAgICAgaWYgKF90cmFuc2xhdGVkVG9rZW4gPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIHRyYW5zbGF0ZWRUb2tlbiA9IF90cmFuc2xhdGVkVG9rZW47XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KTtcblxuICAgIGlmICh0cmFuc2xhdGVkVG9rZW4gPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFRyYW5zbGF0aW9uTm90RGVmaW5lZEVycm9yKHRva2VuKTtcblxuICAgIHJldHVybiBvZih0cmFuc2xhdGVkVG9rZW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBzY29wZWQgZmlsZSBieSBub3RpZmllclxcXG4gICAqIFRoZSByZXNvbHZlZCBzY29wZWQgZ290IHJlcXVlc3RlZCBieSBIVFRQXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bGx9IHNjb3BlIC0gVGhlIHNjb3BlIHRvIGlkZW50aWZ5IHRoZSBub3RpZmllciBieS4gc3RyaW5nIGlzIGFuIGV4cGxpY2l0IHNjb3BlIGFuZCBudWxsIGlzIHRoZSBnbG9iYWwgc2NvcGVcbiAgICogQHJldHVybnMge09ic2VydmFibGU8U2NvcGVkRmlsZT59IC0gQW4gb2JzZXJ2YWJsZSBhcyB0aGUgbmV3IG5vdGlmaWVyLlxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0U2NvcGVkRmlsZUJ5Tm90aWZpZXIgKHNjb3BlOiBzdHJpbmcgfCBudWxsKTogT2JzZXJ2YWJsZTxTY29wZWRGaWxlPiB7XG4gICAgY29uc3QgY3VycmVudE5vdGlmaWVyOiBTdWJqZWN0PFNjb3BlZEZpbGU+ID0gbmV3IFN1YmplY3Q8U2NvcGVkRmlsZT4oKTtcblxuICAgIHRoaXMuX3RyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmFkZE5vdGlmaWVyVG9Ob3RpZmllclNjb3BlKHNjb3BlLCBjdXJyZW50Tm90aWZpZXIpO1xuXG4gICAgcmV0dXJuIGN1cnJlbnROb3RpZmllci5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc2NvcGVkIGZpbGUgYnkgYWRkaW5nIGEgbm90aWZpZXJcXFxuICAgKiBUaGUgcmVzb2x2ZWQgc2NvcGUgc2hvdWxkIGJlIHJlcXVlc3RlZCBieSBIVFRQXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVsbH0gc2NvcGUgLSBUaGUgc2NvcGUgdG8gaWRlbnRpZnkgdGhlIG5vdGlmaWVyIGJ5LiBzdHJpbmcgaXMgYW4gZXhwbGljaXQgc2NvcGUgYW5kIG51bGwgaXMgdGhlIGdsb2JhbCBzb2NwZS5cbiAgICogQHJldHVybnMge09ic2VydmFibGU8U2NvcGVkRmlsZT59IC0gQW4gb2JzZXJ2YWJsZSBhcyB0aGUgbmV3IG5vdGlmaWVyLlxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0U2NvcGVkRmlsZUJ5QWRkaW5nTm90aWZpZXIgKHNjb3BlOiBzdHJpbmcgfCBudWxsKTogT2JzZXJ2YWJsZTxTY29wZWRGaWxlPiB7XG4gICAgY29uc3QgY3VycmVudE5vdGlmaWVyOiBTdWJqZWN0PFNjb3BlZEZpbGU+ID0gbmV3IFN1YmplY3Q8U2NvcGVkRmlsZT4oKTtcblxuICAgIHRoaXMuX3RyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmFkZE5vdGlmaWVyU2NvcGUoe1xuICAgICAgc2NvcGUsXG4gICAgICBub3RpZmllcnM6IFsgY3VycmVudE5vdGlmaWVyIF1cbiAgICB9KTtcblxuICAgIHJldHVybiBjdXJyZW50Tm90aWZpZXI7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgKG11bHRpLSlzY29wZWQgZmlsZSBieSBIVFRQXG4gICAqIEBwYXJhbSB7SHR0cENsaWVudH0gaHR0cENsaWVudCAtIFRoZSBIdHRwQ2xpZW50LCB0aGF0J2xsIGJlIHVzZWRcbiAgICogQHBhcmFtIHtUcmFuc2xhdGlvblN0b3JlU2VydmljZX0gdHJhbnNsYXRpb25TdG9yZVNlcnZpY2UgLSBUaGUgVHJhbnNsYXRpb25TdG9yZVNlcnZpY2UsIHRoYXQnbGwgYmUgdXNlZFxuICAgKiBAcGFyYW0ge1RyYW5zbGF0aW9uSHR0cFNlcml2Y2V9IHRyYW5zbGF0aW9uSHR0cFNlcnZpY2UgLSBUaGUgVHJhbnNsYXRpb25IdHRwU2VydmljZSwgdGhhdCdsbCBiZSB1c2VkXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nIHwgbnVsbD59IHNjb3BlIC0gVGhlIHNjb3BlIGFzIEFycmF5LCB3aGVyZSBzdHJpbmcgaXMgYW4gZXhwbGljaXQgc2NvcGUgYW5kIG51bGwgaXMgdGhlIGdsb2JhbCBzY29wZVxuICAgKiBAcGFyYW0ge0h0dHBPcHRpb25zIHwgdW5kZWZpbmVkfSBodHRwT3B0aW9ucyAtIEFkZGl0aW9uYWwgSFRUUCBPcHRpb25zIGZvciB0aGUgcmVxdWVzdFxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gLSBBbiBvYnNlcnZhYmxlIHdpdGggdGhlIChtdWx0aS0pc2NvcGVkIGZpbGUgaW5zaWRlXG4gICAqL1xuICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHRzZXNsaW50L21heC1wYXJhbXMgKi9cbiAgcHJpdmF0ZSBfZ2V0U2NvcGVkRmlsZUJ5SHR0cFdpdGhSZWYkPFQgZXh0ZW5kcyBSZWFkb25seUFycmF5PHN0cmluZyB8IG51bGw+IHwgc3RyaW5nIHwgbnVsbD4oXG4gICAgaHR0cENsaWVudDogUmVhZG9ubHk8SHR0cENsaWVudD4sXG4gICAgdHJhbnNsYXRpb25TdG9yZVNlcnZpY2U6IFJlYWRvbmx5PFRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlPixcbiAgICB0cmFuc2xhdGlvbkh0dHBTZXJ2aWNlOiBSZWFkb25seTxUcmFuc2xhdGlvbkh0dHBTZXJpdmNlPixcbiAgICBzY29wZTogVCxcbiAgICBodHRwT3B0aW9ucz86IEh0dHBPcHRpb25zPG5ldmVyLCBIdHRwSGVhZGVyc09wdGlvbiwgbmV2ZXI+XG4gICk6IE9ic2VydmFibGU8VCBleHRlbmRzIFJlYWRvbmx5QXJyYXk8c3RyaW5nIHwgbnVsbD4gPyBNdWx0aVNjb3BlZEZpbGUgOiBTY29wZWRGaWxlPiB7XG4gICAgaWYgKHR5cGVvZiBzY29wZSA9PT0gXCJzdHJpbmdcIiB8fCBzY29wZSA9PT0gbnVsbClcbiAgICAgIHRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmFkZE5vdGlmaWVyU2NvcGUoeyBzY29wZSwgbm90aWZpZXJzOiBudWxsIH0pO1xuICAgIGVsc2VcbiAgICAgIHRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmFkZE5vdGlmaWVyU2NvcGVzKHNjb3BlLm1hcCgoX3Njb3BlOiBzdHJpbmcgfCBudWxsKTogTm90aWZpZXJTY29wZSA9PiAoeyBzY29wZTogX3Njb3BlLCBub3RpZmllcnM6IG51bGwgfSkpKTtcblxuXG4gICAgdGhpcy5faXNIdHRwTG9hZGluZy5uZXh0KEh0dHBSZXF1ZXN0U3RhdHVzLlBFTkRJTkcpO1xuXG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uSHR0cFNlcnZpY2UuZ2V0V2l0aFJlZiQ8VCBleHRlbmRzIFJlYWRvbmx5QXJyYXk8c3RyaW5nIHwgbnVsbD4gPyBNdWx0aVNjb3BlZEZpbGUgOiBTY29wZWRGaWxlPihodHRwQ2xpZW50LCBzY29wZSwgaHR0cE9wdGlvbnMpLnBpcGUoXG4gICAgICBjYXRjaEVycm9yKCgpOiBPYnNlcnZhYmxlPG5ldmVyPiA9PiB7XG4gICAgICAgIHRoaXMuX2lzSHR0cExvYWRpbmcubmV4dChIdHRwUmVxdWVzdFN0YXR1cy5FUlJPUik7XG4gICAgICAgIHRoaXMuX2lzSHR0cExvYWRpbmcubmV4dChudWxsKTtcblxuICAgICAgICBpZiAodHlwZW9mIHNjb3BlID09PSBcInN0cmluZ1wiIHx8IHNjb3BlID09PSBudWxsKVxuICAgICAgICAgIHRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlLmlzU2NvcGVOYW1lSW5Ob3RpZmllclNjb3BlcyhzY29wZSkgJiYgdHJhbnNsYXRpb25TdG9yZVNlcnZpY2UucmVtb3ZlTm90aWZpZXJTY29wZShzY29wZSk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHNjb3BlLmZvckVhY2goKF9zY29wZTogc3RyaW5nIHwgbnVsbCk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgaWYgKCF0cmFuc2xhdGlvblN0b3JlU2VydmljZS5pc1Njb3BlTmFtZUluTm90aWZpZXJTY29wZXMoX3Njb3BlKSlcbiAgICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgICAgICB0cmFuc2xhdGlvblN0b3JlU2VydmljZS5yZW1vdmVOb3RpZmllclNjb3BlKF9zY29wZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb2YoKTtcbiAgICAgIH0pLFxuICAgICAgdGFwKChnZW5lcmljU2NvcGVkRmlsZTogVCBleHRlbmRzIFJlYWRvbmx5QXJyYXk8c3RyaW5nIHwgbnVsbD4gPyBNdWx0aVNjb3BlZEZpbGUgOiBTY29wZWRGaWxlKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMuX2lzSHR0cExvYWRpbmcubmV4dChIdHRwUmVxdWVzdFN0YXR1cy5TVUNDRVNTKTtcbiAgICAgICAgdGhpcy5faXNIdHRwTG9hZGluZy5uZXh0KG51bGwpO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygc2NvcGUgPT09IFwic3RyaW5nXCIgfHwgc2NvcGUgPT09IG51bGwpIHtcbiAgICAgICAgICB0cmFuc2xhdGlvblN0b3JlU2VydmljZS5zZXRTY29wZWRGaWxlKHNjb3Bl