@ngneat/transloco
Version:
The internationalization (i18n) library for Angular
169 lines • 24.6 kB
JavaScript
import { ChangeDetectorRef, Directive, ElementRef, inject, Input, Renderer2, TemplateRef, ViewContainerRef, } from '@angular/core';
import { forkJoin, switchMap } from 'rxjs';
import { TemplateHandler } from './template-handler';
import { TRANSLOCO_LANG } from './transloco-lang';
import { TRANSLOCO_LOADING_TEMPLATE } from './transloco-loading-template';
import { TRANSLOCO_SCOPE } from './transloco-scope';
import { TranslocoService } from './transloco.service';
import { listenOrNotOperator, resolveInlineLoader, shouldListenToLangChanges, } from './shared';
import { LangResolver } from './lang-resolver';
import { ScopeResolver } from './scope-resolver';
import * as i0 from "@angular/core";
export class TranslocoDirective {
service = inject(TranslocoService);
tpl = inject(TemplateRef, {
optional: true,
});
providerLang = inject(TRANSLOCO_LANG, { optional: true });
providerScope = inject(TRANSLOCO_SCOPE, { optional: true });
providedLoadingTpl = inject(TRANSLOCO_LOADING_TEMPLATE, {
optional: true,
});
cdr = inject(ChangeDetectorRef);
host = inject(ElementRef);
vcr = inject(ViewContainerRef);
renderer = inject(Renderer2);
subscription = null;
view;
translationMemo = {};
key;
params = {};
inlineScope;
inlineRead;
inlineLang;
inlineTpl;
currentLang;
loaderTplHandler;
// Whether we already rendered the view once
initialized = false;
path;
langResolver = new LangResolver();
scopeResolver = new ScopeResolver(this.service);
strategy = this.tpl === null ? 'attribute' : 'structural';
static ngTemplateContextGuard(dir, ctx) {
return true;
}
ngOnInit() {
const listenToLangChange = shouldListenToLangChanges(this.service, this.providerLang || this.inlineLang);
this.subscription = this.service.langChanges$
.pipe(switchMap((activeLang) => {
const lang = this.langResolver.resolve({
inline: this.inlineLang,
provider: this.providerLang,
active: activeLang,
});
return Array.isArray(this.providerScope)
? forkJoin(this.providerScope.map((providerScope) => this.resolveScope(lang, providerScope)))
: this.resolveScope(lang, this.providerScope);
}), listenOrNotOperator(listenToLangChange))
.subscribe(() => {
this.currentLang = this.langResolver.resolveLangBasedOnScope(this.path);
this.strategy === 'attribute'
? this.attributeStrategy()
: this.structuralStrategy(this.currentLang, this.inlineRead);
this.cdr.markForCheck();
this.initialized = true;
});
if (!this.initialized) {
const loadingContent = this.resolveLoadingContent();
if (loadingContent) {
this.loaderTplHandler = new TemplateHandler(loadingContent, this.vcr);
this.loaderTplHandler.attachView();
}
}
}
ngOnChanges(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
if (this.strategy === 'attribute') {
const notInit = Object.keys(changes).some((v) => !changes[v].firstChange);
notInit && this.attributeStrategy();
}
}
attributeStrategy() {
this.detachLoader();
this.renderer.setProperty(this.host.nativeElement, 'innerText', this.service.translate(this.key, this.params, this.currentLang));
}
structuralStrategy(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,
});
}
}
getTranslateFn(lang, read) {
return (key, params) => {
const withRead = read ? `${read}.${key}` : key;
const withParams = params
? `${withRead}${JSON.stringify(params)}`
: withRead;
if (Object.prototype.hasOwnProperty.call(this.translationMemo, withParams)) {
return this.translationMemo[withParams].value;
}
this.translationMemo[withParams] = {
params,
value: this.service.translate(withRead, params, lang),
};
return this.translationMemo[withParams].value;
};
}
resolveLoadingContent() {
return this.inlineTpl || this.providedLoadingTpl;
}
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
// Caretaker note: it's important to clean up references to subscriptions since they save the `next`
// callback within its `destination` property, preventing classes from being GC'd.
this.subscription = null;
}
}
detachLoader() {
this.loaderTplHandler?.detachView();
}
resolveScope(lang, providerScope) {
const resolvedScope = this.scopeResolver.resolve({
inline: this.inlineScope,
provider: providerScope,
});
this.path = this.langResolver.resolveLangPath(lang, resolvedScope);
const inlineLoader = resolveInlineLoader(providerScope, resolvedScope);
return this.service._loadDependencies(this.path, inlineLoader);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: TranslocoDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: TranslocoDirective, isStandalone: true, selector: "[transloco]", inputs: { key: ["transloco", "key"], params: ["translocoParams", "params"], inlineScope: ["translocoScope", "inlineScope"], inlineRead: ["translocoRead", "inlineRead"], inlineLang: ["translocoLang", "inlineLang"], inlineTpl: ["translocoLoadingTpl", "inlineTpl"] }, usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: TranslocoDirective, decorators: [{
type: Directive,
args: [{
selector: '[transloco]',
standalone: true,
}]
}], propDecorators: { key: [{
type: Input,
args: ['transloco']
}], params: [{
type: Input,
args: ['translocoParams']
}], inlineScope: [{
type: Input,
args: ['translocoScope']
}], inlineRead: [{
type: Input,
args: ['translocoRead']
}], inlineLang: [{
type: Input,
args: ['translocoLang']
}], inlineTpl: [{
type: Input,
args: ['translocoLoadingTpl']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsb2NvLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvdHJhbnNsb2NvL3NyYy9saWIvdHJhbnNsb2NvLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBRVYsTUFBTSxFQUNOLEtBQUssRUFJTCxTQUFTLEVBRVQsV0FBVyxFQUNYLGdCQUFnQixHQUNqQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsUUFBUSxFQUE0QixTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFckUsT0FBTyxFQUFXLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFdkQsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixtQkFBbUIsRUFDbkIseUJBQXlCLEdBQzFCLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7O0FBWWpELE1BQU0sT0FBTyxrQkFBa0I7SUFDckIsT0FBTyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ25DLEdBQUcsR0FBRyxNQUFNLENBQTJCLFdBQVcsRUFBRTtRQUMxRCxRQUFRLEVBQUUsSUFBSTtLQUNmLENBQUMsQ0FBQztJQUNLLFlBQVksR0FBRyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFB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QWtCOzJGQUFsQixrQkFBa0I7OzJGQUFsQixrQkFBa0I7a0JBSjlCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGFBQWE7b0JBQ3ZCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjs4QkF5QnFCLEdBQUc7c0JBQXRCLEtBQUs7dUJBQUMsV0FBVztnQkFDUSxNQUFNO3NCQUEvQixLQUFLO3VCQUFDLGlCQUFpQjtnQkFDQyxXQUFXO3NCQUFuQyxLQUFLO3VCQUFDLGdCQUFnQjtnQkFDQyxVQUFVO3NCQUFqQyxLQUFLO3VCQUFDLGVBQWU7Z0JBQ0UsVUFBVTtzQkFBakMsS0FBSzt1QkFBQyxlQUFlO2dCQUNRLFNBQVM7c0JBQXRDLEtBQUs7dUJBQUMscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRW1iZWRkZWRWaWV3UmVmLFxuICBpbmplY3QsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q29udGFpbmVyUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZvcmtKb2luLCBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24sIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBDb250ZW50LCBUZW1wbGF0ZUhhbmRsZXIgfSBmcm9tICcuL3RlbXBsYXRlLWhhbmRsZXInO1xuaW1wb3J0IHsgVFJBTlNMT0NPX0xBTkcgfSBmcm9tICcuL3RyYW5zbG9jby1sYW5nJztcbmltcG9ydCB7IFRSQU5TTE9DT19MT0FESU5HX1RFTVBMQVRFIH0gZnJvbSAnLi90cmFuc2xvY28tbG9hZGluZy10ZW1wbGF0ZSc7XG5pbXBvcnQgeyBUUkFOU0xPQ09fU0NPUEUgfSBmcm9tICcuL3RyYW5zbG9jby1zY29wZSc7XG5pbXBvcnQgeyBUcmFuc2xvY29TZXJ2aWNlIH0gZnJvbSAnLi90cmFuc2xvY28uc2VydmljZSc7XG5pbXBvcnQgeyBIYXNoTWFwLCBPckFycmF5LCBUcmFuc2xhdGlvbiwgVHJhbnNsb2NvU2NvcGUgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7XG4gIGxpc3Rlbk9yTm90T3BlcmF0b3IsXG4gIHJlc29sdmVJbmxpbmVMb2FkZXIsXG4gIHNob3VsZExpc3RlblRvTGFuZ0NoYW5nZXMsXG59IGZyb20gJy4vc2hhcmVkJztcbmltcG9ydCB7IExhbmdSZXNvbHZlciB9IGZyb20gJy4vbGFuZy1yZXNvbHZlcic7XG5pbXBvcnQgeyBTY29wZVJlc29sdmVyIH0gZnJvbSAnLi9zY29wZS1yZXNvbHZlcic7XG5cbnR5cGUgVHJhbnNsYXRlRm4gPSAoa2V5OiBzdHJpbmcsIHBhcmFtcz86IEhhc2hNYXApID0+IGFueTtcbmludGVyZmFjZSBWaWV3Q29udGV4dCB7XG4gICRpbXBsaWNpdDogVHJhbnNsYXRlRm47XG4gIGN1cnJlbnRMYW5nOiBzdHJpbmc7XG59XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1t0cmFuc2xvY29dJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgVHJhbnNsb2NvRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XG4gIHByaXZhdGUgc2VydmljZSA9IGluamVjdChUcmFuc2xvY29TZXJ2aWNlKTtcbiAgcHJpdmF0ZSB0cGwgPSBpbmplY3Q8VGVtcGxhdGVSZWY8Vmlld0NvbnRleHQ+PihUZW1wbGF0ZVJlZiwge1xuICAgIG9wdGlvbmFsOiB0cnVlLFxuICB9KTtcbiAgcHJpdmF0ZSBwcm92aWRlckxhbmcgPSBpbmplY3QoVFJBTlNMT0NPX0xBTkcsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgcHJvdmlkZXJTY29wZTogT3JBcnJheTxUcmFuc2xvY29TY29wZT4gfCBudWxsID0gaW5qZWN0KFxuICAgIFRSQU5TTE9DT19TQ09QRSxcbiAgICB7IG9wdGlvbmFsOiB0cnVlIH1cbiAgKTtcbiAgcHJpdmF0ZSBwcm92aWRlZExvYWRpbmdUcGwgPSBpbmplY3QoVFJBTlNMT0NPX0xPQURJTkdfVEVNUExBVEUsIHtcbiAgICBvcHRpb25hbDogdHJ1ZSxcbiAgfSk7XG4gIHByaXZhdGUgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgcHJpdmF0ZSBob3N0ID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuICBwcml2YXRlIHZjciA9IGluamVjdChWaWV3Q29udGFpbmVyUmVmKTtcbiAgcHJpdmF0ZSByZW5kZXJlciA9IGluamVjdChSZW5kZXJlcjIpO1xuXG4gIHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gIHZpZXc6IEVtYmVkZGVkVmlld1JlZjxWaWV3Q29udGV4dD4gfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSB0cmFuc2xhdGlvbk1lbW86IFJlY29yZDxzdHJpbmcsIHsgdmFsdWU6IGFueTsgcGFyYW1zPzogSGFzaE1hcCB9PiA9XG4gICAge307XG5cbiAgQElucHV0KCd0cmFuc2xvY28nKSBrZXk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCd0cmFuc2xvY29QYXJhbXMnKSBwYXJhbXM6IEhhc2hNYXAgPSB7fTtcbiAgQElucHV0KCd0cmFuc2xvY29TY29wZScpIGlubGluZVNjb3BlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgndHJhbnNsb2NvUmVhZCcpIGlubGluZVJlYWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCd0cmFuc2xvY29MYW5nJykgaW5saW5lTGFuZzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoJ3RyYW5zbG9jb0xvYWRpbmdUcGwnKSBpbmxpbmVUcGw6IENvbnRlbnQgfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBjdXJyZW50TGFuZzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIGxvYWRlclRwbEhhbmRsZXI6IFRlbXBsYXRlSGFuZGxlciB8IHVuZGVmaW5lZDtcbiAgLy8gV2hldGhlciB3ZSBhbHJlYWR5IHJlbmRlcmVkIHRoZSB2aWV3IG9uY2VcbiAgcHJpdmF0ZSBpbml0aWFsaXplZCA9IGZhbHNlO1xuICBwcml2YXRlIHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBsYW5nUmVzb2x2ZXIgPSBuZXcgTGFuZ1Jlc29sdmVyKCk7XG4gIHByaXZhdGUgc2NvcGVSZXNvbHZlciA9IG5ldyBTY29wZVJlc29sdmVyKHRoaXMuc2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyYXRlZ3kgPSB0aGlzLnRwbCA9PT0gbnVsbCA/ICdhdHRyaWJ1dGUnIDogJ3N0cnVjdHVyYWwnO1xuXG4gIHN0YXRpYyBuZ1RlbXBsYXRlQ29udGV4dEd1YXJkKFxuICAgIGRpcjogVHJhbnNsb2NvRGlyZWN0aXZlLFxuICAgIGN0eDogdW5rbm93blxuICApOiBjdHggaXMgVmlld0NvbnRleHQge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgY29uc3QgbGlzdGVuVG9MYW5nQ2hhbmdlID0gc2hvdWxkTGlzdGVuVG9MYW5nQ2hhbmdlcyhcbiAgICAgIHRoaXMuc2VydmljZSxcbiAgICAgIHRoaXMucHJvdmlkZXJMYW5nIHx8IHRoaXMuaW5saW5lTGFuZ1xuICAgICk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbiA9IHRoaXMuc2VydmljZS5sYW5nQ2hhbmdlcyRcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKGFjdGl2ZUxhbmcpID0+IHtcbiAgICAgICAgICBjb25zdCBsYW5nID0gdGhpcy5sYW5nUmVzb2x2ZXIucmVzb2x2ZSh7XG4gICAgICAgICAgICBpbmxpbmU6IHRoaXMuaW5saW5lTGFuZyxcbiAgICAgICAgICAgIHByb3ZpZGVyOiB0aGlzLnByb3ZpZGVyTGFuZyxcbiAgICAgICAgICAgIGFjdGl2ZTogYWN0aXZlTGFuZyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiBBcnJheS5pc0FycmF5KHRoaXMucHJvdmlkZXJTY29wZSlcbiAgICAgICAgICAgID8gZm9ya0pvaW4oXG4gICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlclNjb3BlLm1hcCgocHJvdmlkZXJTY29wZSkgPT5cbiAgICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZVNjb3BlKGxhbmcsIHByb3ZpZGVyU2NvcGUpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICA6IHRoaXMucmVzb2x2ZVNjb3BlKGxhbmcsIHRoaXMucHJvdmlkZXJTY29wZSk7XG4gICAgICAgIH0pLFxuICAgICAgICBsaXN0ZW5Pck5vdE9wZXJhdG9yKGxpc3RlblRvTGFuZ0NoYW5nZSlcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLmN1cnJlbnRMYW5nID0gdGhpcy5sYW5nUmVzb2x2ZXIucmVzb2x2ZUxhbmdCYXNlZE9uU2NvcGUoXG4gICAgICAgICAgdGhpcy5wYXRoIVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmF0ZWd5ID09PSAnYXR0cmlidXRlJ1xuICAgICAgICAgID8gdGhpcy5hdHRyaWJ1dGVTdHJhdGVneSgpXG4gICAgICAgICAgOiB0aGlzLnN0cnVjdHVyYWxTdHJhdGVneSh0aGlzLmN1cnJlbnRMYW5nLCB0aGlzLmlubGluZVJlYWQpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgICB9KTtcblxuICAgIGlmICghdGhpcy5pbml0aWFsaXplZCkge1xuICAgICAgY29uc3QgbG9hZGluZ0NvbnRlbnQgPSB0aGlzLnJlc29sdmVMb2FkaW5nQ29udGVudCgpO1xuICAgICAgaWYgKGxvYWRpbmdDb250ZW50KSB7XG4gICAgICAgIHRoaXMubG9hZGVyVHBsSGFuZGxlciA9IG5ldyBUZW1wbGF0ZUhhbmRsZXIobG9hZGluZ0NvbnRlbnQsIHRoaXMudmNyKTtcbiAgICAgICAgdGhpcy5sb2FkZXJUcGxIYW5kbGVyLmF0dGFjaFZpZXcoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgLy8gV2UgbmVlZCB0byBzdXBwb3J0IGR5bmFtaWMga2V5cy9wYXJhbXMsIHNvIGlmIHRoaXMgaXMgbm90IHRoZSBmaXJzdCBjaGFuZ2UgQ0QgY3ljbGVcbiAgICAvLyB3ZSBuZWVkIHRvIHJ1biB0aGUgZnVuY3Rpb24gYWdhaW4gaW4gb3JkZXIgdG8gdXBkYXRlIHRoZSB2YWx1ZVxuICAgIGlmICh0aGlzLnN0cmF0ZWd5ID09PSAnYXR0cmlidXRlJykge1xuICAgICAgY29uc3Qgbm90SW5pdCA9IE9iamVjdC5rZXlzKGNoYW5nZXMpLnNvbWUoKHYpID0+ICFjaGFuZ2VzW3ZdLmZpcnN0Q2hhbmdlKTtcbiAgICAgIG5vdEluaXQgJiYgdGhpcy5hdHRyaWJ1dGVTdHJhdGVneSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXR0cmlidXRlU3RyYXRlZ3koKSB7XG4gICAgdGhpcy5kZXRhY2hMb2FkZXIoKTtcbiAgICB0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KFxuICAgICAgdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQsXG4gICAgICAnaW5uZXJUZXh0JyxcbiAgICAgIHRoaXMuc2VydmljZS50cmFuc2xhdGUodGhpcy5rZXkhLCB0aGlzLnBhcmFtcywgdGhpcy5jdXJyZW50TGFuZylcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdHJ1Y3R1cmFsU3RyYXRlZ3kobGFuZzogc3RyaW5nLCByZWFkPzogc3RyaW5nKSB7XG4gICAgdGhpcy50cmFuc2xhdGlvbk1lbW8gPSB7fTtcblxuICAgIGlmICh0aGlzLnZpZXcpIHtcbiAgICAgIC8vIHdoZW4gdGhlIGxhbmcgY2hhbmdlcyB3ZSBuZWVkIHRvIGNoYW5nZSB0aGUgcmVmZXJlbmNlIHNvIEFuZ3VsYXIgd2lsbCB1cGRhdGUgdGhlIHZpZXdcbiAgICAgIHRoaXMudmlldy5jb250ZXh0WyckaW1wbGljaXQnXSA9IHRoaXMuZ2V0VHJhbnNsYXRlRm4obGFuZywgcmVhZCk7XG4gICAgICB0aGlzLnZpZXcuY29udGV4dFsnY3VycmVudExhbmcnXSA9IHRoaXMuY3VycmVudExhbmchO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRldGFjaExvYWRlcigpO1xuICAgICAgdGhpcy52aWV3ID0gdGhpcy52Y3IuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMudHBsISwge1xuICAgICAgICAkaW1wbGljaXQ6IHRoaXMuZ2V0VHJhbnNsYXRlRm4obGFuZywgcmVhZCksXG4gICAgICAgIGN1cnJlbnRMYW5nOiB0aGlzLmN1cnJlbnRMYW5nISxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRUcmFuc2xhdGVGbihcbiAgICBsYW5nOiBzdHJpbmcsXG4gICAgcmVhZDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gICk6IFRyYW5zbGF0ZUZuIHtcbiAgICByZXR1cm4gKGtleTogc3RyaW5nLCBwYXJhbXM/OiBIYXNoTWFwKSA9PiB7XG4gICAgICBjb25zdCB3aXRoUmVhZCA9IHJlYWQgPyBgJHtyZWFkfS4ke2tleX1gIDoga2V5O1xuICAgICAgY29uc3Qgd2l0aFBhcmFtcyA9IHBhcmFtc1xuICAgICAgICA/IGAke3dpdGhSZWFkfSR7SlNPTi5zdHJpbmdpZnkocGFyYW1zKX1gXG4gICAgICAgIDogd2l0aFJlYWQ7XG5cbiAgICAgIGlmIChcbiAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMudHJhbnNsYXRpb25NZW1vLCB3aXRoUGFyYW1zKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRyYW5zbGF0aW9uTWVtb1t3aXRoUGFyYW1zXS52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy50cmFuc2xhdGlvbk1lbW9bd2l0aFBhcmFtc10gPSB7XG4gICAgICAgIHBhcmFtcyxcbiAgICAgICAgdmFsdWU6IHRoaXMuc2VydmljZS50cmFuc2xhdGUod2l0aFJlYWQsIHBhcmFtcywgbGFuZyksXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gdGhpcy50cmFuc2xhdGlvbk1lbW9bd2l0aFBhcmFtc10udmFsdWU7XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZUxvYWRpbmdDb250ZW50KCkge1xuICAgIHJldHVybiB0aGlzLmlubGluZVRwbCB8fCB0aGlzLnByb3ZpZGVkTG9hZGluZ1RwbDtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIC8vIENhcmV0YWtlciBub3RlOiBpdCdzIGltcG9ydGFudCB0byBjbGVhbiB1cCByZWZlcmVuY2VzIHRvIHN1YnNjcmlwdGlvbnMgc2luY2UgdGhleSBzYXZlIHRoZSBgbmV4dGBcbiAgICAgIC8vIGNhbGxiYWNrIHdpdGhpbiBpdHMgYGRlc3RpbmF0aW9uYCBwcm9wZXJ0eSwgcHJldmVudGluZyBjbGFzc2VzIGZyb20gYmVpbmcgR0MnZC5cbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRldGFjaExvYWRlcigpIHtcbiAgICB0aGlzLmxvYWRlclRwbEhhbmRsZXI/LmRldGFjaFZpZXcoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZVNjb3BlKFxuICAgIGxhbmc6IHN0cmluZyxcbiAgICBwcm92aWRlclNjb3BlOiBUcmFuc2xvY29TY29wZSB8IG51bGxcbiAgKTogT2JzZXJ2YWJsZTxUcmFuc2xhdGlvbiB8IFRyYW5zbGF0aW9uW10+IHtcbiAgICBjb25zdCByZXNvbHZlZFNjb3BlID0gdGhpcy5zY29wZVJlc29sdmVyLnJlc29sdmUoe1xuICAgICAgaW5saW5lOiB0aGlzLmlubGluZVNjb3BlLFxuICAgICAgcHJvdmlkZXI6IHByb3ZpZGVyU2NvcGUsXG4gICAgfSk7XG4gICAgdGhpcy5wYXRoID0gdGhpcy5sYW5nUmVzb2x2ZXIucmVzb2x2ZUxhbmdQYXRoKGxhbmcsIHJlc29sdmVkU2NvcGUpO1xuICAgIGNvbnN0IGlubGluZUxvYWRlciA9IHJlc29sdmVJbmxpbmVMb2FkZXIocHJvdmlkZXJTY29wZSwgcmVzb2x2ZWRTY29wZSk7XG5cbiAgICByZXR1cm4gdGhpcy5zZXJ2aWNlLl9sb2FkRGVwZW5kZW5jaWVzKHRoaXMucGF0aCwgaW5saW5lTG9hZGVyKTtcbiAgfVxufVxuIl19