@cisstech/nge
Version:
NG Essentials is a collection of libraries for Angular developers.
154 lines • 23.2 kB
JavaScript
import { HttpClient } from '@angular/common/http';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Injector, ViewChild, ViewContainerRef, inject, } from '@angular/core';
import { CompilerService } from '@cisstech/nge/services';
import { firstValueFrom } from 'rxjs';
import { NGE_DOC_RENDERERS } from '../nge-doc';
import { NgeDocService } from '../nge-doc.service';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class NgeDocRendererComponent {
constructor() {
this.injector = inject(Injector);
this.renderers = inject(NGE_DOC_RENDERERS);
this.docService = inject(NgeDocService);
this.compilerService = inject(CompilerService);
this.changeDetectorRef = inject(ChangeDetectorRef);
this.subscriptions = [];
this.loading = false;
this.noFound = false;
this.componentRefByTypes = new Map();
}
ngOnInit() {
this.subscriptions.push(this.docService.stateChanges.subscribe(this.onChangeState.bind(this)));
}
ngOnDestroy() {
this.clearViewContainer();
this.subscriptions.forEach((s) => s.unsubscribe());
}
showLoading() {
this.loading = true;
// if loading is still true after 1s then we force change detection
// This is useful to show the loading indicator only if the loading is not too fast
// so that the loading indicator does not blink.
setTimeout(() => {
if (this.loading) {
this.changeDetectorRef.markForCheck();
}
}, 1000);
}
clearViewContainer() {
const componentRefs = Array.from(this.componentRefByTypes.values());
if (this.componentRef && componentRefs.includes(this.componentRef)) {
while (this.container.length > 0) {
this.container.detach();
}
}
else {
this.componentRef?.destroy();
this.componentRef = undefined;
this.container.clear();
}
}
async onChangeState(state) {
try {
this.showLoading();
this.clearViewContainer();
if (state.currLink) {
const renderer = await state.currLink.renderer;
switch (typeof renderer) {
case 'string':
await this.renderMarkdown(renderer);
break;
case 'function':
this.componentRef = await this.compilerService.render({
type: await renderer(),
inputs: state.currLink.inputs,
container: this.container,
});
break;
}
}
}
catch (error) {
console.error(error);
}
finally {
this.loading = false;
this.noFound = !this.componentRef;
this.changeDetectorRef.markForCheck();
}
}
async renderMarkdown(data) {
if (!this.renderers?.markdown) {
throw new Error('[nge-doc]: missing markdown renderer.');
}
const renderer = this.renderers.markdown;
const type = await renderer.component();
const createInputs = async () => {
let inputs = {
data, // we assume that data is a markdown content.
};
if (!data.includes('\n')) {
// if data does not include at least two lines then it's an url
const http = this.injector.get(HttpClient, null);
if (!http) {
throw new Error('[nge-doc] When using the `file` renderer you *have to* pass the `HttpClient` as a parameter of the `forRoot` method. See README for more information');
}
inputs = {
data: await firstValueFrom(http.get(data, { responseType: 'text' })),
};
}
let customInputs = {};
if (typeof renderer.inputs === 'function') {
customInputs = await renderer.inputs(this.injector);
}
else if (typeof renderer.inputs === 'object') {
customInputs = renderer.inputs;
}
return { ...customInputs, ...inputs };
};
const markdownComponent = this.componentRefByTypes.get(type);
if (markdownComponent) {
this.attachComponent(markdownComponent, await createInputs());
return;
}
const componentRef = await this.compilerService.render({
type,
inputs: await createInputs(),
container: this.container,
});
this.componentRef = componentRef;
this.componentRefByTypes.set(type, componentRef);
}
async attachComponent(componentRef, inputs) {
this.container.insert(componentRef.hostView);
this.componentRef = componentRef;
// compute changes
const changes = {};
const { instance, changeDetectorRef } = componentRef;
Object.keys(inputs).forEach((key) => {
changes[key] = {
currentValue: inputs[key],
previousValue: instance[key],
firstChange: false,
isFirstChange: () => false,
};
instance[key] = inputs[key];
});
// call ngOnChanges
if (instance.ngOnChanges) {
await instance.ngOnChanges(changes);
}
changeDetectorRef.markForCheck();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: NgeDocRendererComponent, selector: "nge-doc-renderer", viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div class=\"loading-container\" *ngIf=\"loading\">\n <div class=\"loading-spinner\"></div>\n <div class=\"loading-text\">Loading...</div>\n</div>\n<div *ngIf=\"noFound\">\n <h1>Ooops!</h1>\n <hr />\n <p>It looks like this page doesn't exist.</p>\n</div>\n<div #container></div>\n", styles: [":host{display:block;width:100%;position:relative}.loading-container{display:flex;align-items:center;flex-direction:column;justify-content:center}.loading-spinner{border:4px solid rgba(0,0,0,.1);border-top:4px solid var(--nge-doc-primary-color);border-radius:50%;width:40px;height:40px;animation:spin 1s linear infinite;margin-bottom:20px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-text{font-family:Arial,sans-serif;font-size:18px;color:#333}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocRendererComponent, decorators: [{
type: Component,
args: [{ selector: 'nge-doc-renderer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"loading-container\" *ngIf=\"loading\">\n <div class=\"loading-spinner\"></div>\n <div class=\"loading-text\">Loading...</div>\n</div>\n<div *ngIf=\"noFound\">\n <h1>Ooops!</h1>\n <hr />\n <p>It looks like this page doesn't exist.</p>\n</div>\n<div #container></div>\n", styles: [":host{display:block;width:100%;position:relative}.loading-container{display:flex;align-items:center;flex-direction:column;justify-content:center}.loading-spinner{border:4px solid rgba(0,0,0,.1);border-top:4px solid var(--nge-doc-primary-color);border-radius:50%;width:40px;height:40px;animation:spin 1s linear infinite;margin-bottom:20px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-text{font-family:Arial,sans-serif;font-size:18px;color:#333}\n"] }]
}], propDecorators: { container: [{
type: ViewChild,
args: ['container', { read: ViewContainerRef, static: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdlL2RvYy9zcmMvcmVuZGVyZXIvcmVuZGVyZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdlL2RvYy9zcmMvcmVuZGVyZXIvcmVuZGVyZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQ2pELE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFFVCxRQUFRLEVBS1IsU0FBUyxFQUNULGdCQUFnQixFQUNoQixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUE7QUFDdEIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFBO0FBQ3hELE9BQU8sRUFBZ0IsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBZSxNQUFNLFlBQVksQ0FBQTtBQUMzRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUE7OztBQVFsRCxNQUFNLE9BQU8sdUJBQXVCO0lBTnBDO1FBT21CLGFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDM0IsY0FBUyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1FBQ3JDLGVBQVUsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUE7UUFDbEMsb0JBQWUsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUE7UUFDekMsc0JBQWlCLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUE7UUFFdEQsa0JBQWEsR0FBbUIsRUFBRSxDQUFBO1FBQ2hDLFlBQU8sR0FBRyxLQUFLLENBQUE7UUFDZixZQUFPLEdBQUcsS0FBSyxDQUFBO1FBQ2Ysd0JBQW1CLEdB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WUFBWSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUM7Z0JBQ3pCLGFBQWEsRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDO2dCQUM1QixXQUFXLEVBQUUsS0FBSztnQkFDbEIsYUFBYSxFQUFFLEdBQUcsRUFBRSxDQUFDLEtBQUs7YUFDM0IsQ0FBQTtZQUNELFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDN0IsQ0FBQyxDQUFDLENBQUE7UUFFRixtQkFBbUI7UUFDbkIsSUFBSSxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDekIsTUFBTSxRQUFRLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ3JDLENBQUM7UUFFRCxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQTtJQUNsQyxDQUFDOzhHQTdKVSx1QkFBdUI7a0dBQXZCLHVCQUF1QiwySUFjRixnQkFBZ0IsMkNDeENsRCwrUkFVQTs7MkZEZ0JhLHVCQUF1QjtrQkFObkMsU0FBUzsrQkFDRSxrQkFBa0IsbUJBR1gsdUJBQXVCLENBQUMsTUFBTTs4QkFpQi9DLFNBQVM7c0JBRFIsU0FBUzt1QkFBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCdcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb21wb25lbnRSZWYsXG4gIEluamVjdG9yLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVHlwZSxcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQgeyBDb21waWxlclNlcnZpY2UgfSBmcm9tICdAY2lzc3RlY2gvbmdlL3NlcnZpY2VzJ1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uLCBmaXJzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnXG5pbXBvcnQgeyBOR0VfRE9DX1JFTkRFUkVSUywgTmdlRG9jU3RhdGUgfSBmcm9tICcuLi9uZ2UtZG9jJ1xuaW1wb3J0IHsgTmdlRG9jU2VydmljZSB9IGZyb20gJy4uL25nZS1kb2Muc2VydmljZSdcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmdlLWRvYy1yZW5kZXJlcicsXG4gIHRlbXBsYXRlVXJsOiAncmVuZGVyZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsncmVuZGVyZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE5nZURvY1JlbmRlcmVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKVxuICBwcml2YXRlIHJlYWRvbmx5IHJlbmRlcmVycyA9IGluamVjdChOR0VfRE9DX1JFTkRFUkVSUylcbiAgcHJpdmF0ZSByZWFkb25seSBkb2NTZXJ2aWNlID0gaW5qZWN0KE5nZURvY1NlcnZpY2UpXG4gIHByaXZhdGUgcmVhZG9ubHkgY29tcGlsZXJTZXJ2aWNlID0gaW5qZWN0KENvbXBpbGVyU2VydmljZSlcbiAgcHJpdmF0ZSByZWFkb25seSBjaGFuZ2VEZXRlY3RvclJlZiA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZilcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW11cbiAgcHJvdGVjdGVkIGxvYWRpbmcgPSBmYWxzZVxuICBwcm90ZWN0ZWQgbm9Gb3VuZCA9IGZhbHNlXG4gIHByb3RlY3RlZCBjb21wb25lbnRSZWZCeVR5cGVzID0gbmV3IE1hcDxUeXBlPGFueT4sIENvbXBvbmVudFJlZjxhbnk+PigpXG5cbiAgY29tcG9uZW50UmVmPzogQ29tcG9uZW50UmVmPGFueT5cblxuICBAVmlld0NoaWxkKCdjb250YWluZXInLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogdHJ1ZSB9KVxuICBjb250YWluZXIhOiBWaWV3Q29udGFpbmVyUmVmXG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2godGhpcy5kb2NTZXJ2aWNlLnN0YXRlQ2hhbmdlcy5zdWJzY3JpYmUodGhpcy5vbkNoYW5nZVN0YXRlLmJpbmQodGhpcykpKVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhclZpZXdDb250YWluZXIoKVxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKChzKSA9PiBzLnVuc3Vic2NyaWJlKCkpXG4gIH1cblxuICBwcml2YXRlIHNob3dMb2FkaW5nKCk6IHZvaWQge1xuICAgIHRoaXMubG9hZGluZyA9IHRydWVcblxuICAgIC8vIGlmIGxvYWRpbmcgaXMgc3RpbGwgdHJ1ZSBhZnRlciAxcyB0aGVuIHdlIGZvcmNlIGNoYW5nZSBkZXRlY3Rpb25cbiAgICAvLyBUaGlzIGlzIHVzZWZ1bCB0byBzaG93IHRoZSBsb2FkaW5nIGluZGljYXRvciBvbmx5IGlmIHRoZSBsb2FkaW5nIGlzIG5vdCB0b28gZmFzdFxuICAgIC8vIHNvIHRoYXQgdGhlIGxvYWRpbmcgaW5kaWNhdG9yIGRvZXMgbm90IGJsaW5rLlxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMubG9hZGluZykge1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpXG4gICAgICB9XG4gICAgfSwgMTAwMClcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJWaWV3Q29udGFpbmVyKCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbXBvbmVudFJlZnMgPSBBcnJheS5mcm9tKHRoaXMuY29tcG9uZW50UmVmQnlUeXBlcy52YWx1ZXMoKSlcbiAgICBpZiAodGhpcy5jb21wb25lbnRSZWYgJiYgY29tcG9uZW50UmVmcy5pbmNsdWRlcyh0aGlzLmNvbXBvbmVudFJlZikpIHtcbiAgICAgIHdoaWxlICh0aGlzLmNvbnRhaW5lci5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmRldGFjaCgpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29tcG9uZW50UmVmPy5kZXN0cm95KClcbiAgICAgIHRoaXMuY29tcG9uZW50UmVmID0gdW5kZWZpbmVkXG4gICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBvbkNoYW5nZVN0YXRlKHN0YXRlOiBOZ2VEb2NTdGF0ZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnNob3dMb2FkaW5nKClcbiAgICAgIHRoaXMuY2xlYXJWaWV3Q29udGFpbmVyKClcblxuICAgICAgaWYgKHN0YXRlLmN1cnJMaW5rKSB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVyID0gYXdhaXQgc3RhdGUuY3VyckxpbmsucmVuZGVyZXJcbiAgICAgICAgc3dpdGNoICh0eXBlb2YgcmVuZGVyZXIpIHtcbiAgICAgICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZW5kZXJNYXJrZG93bihyZW5kZXJlcilcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRSZWYgPSBhd2FpdCB0aGlzLmNvbXBpbGVyU2VydmljZS5yZW5kZXIoe1xuICAgICAgICAgICAgICB0eXBlOiBhd2FpdCByZW5kZXJlcigpLFxuICAgICAgICAgICAgICBpbnB1dHM6IHN0YXRlLmN1cnJMaW5rLmlucHV0cyxcbiAgICAgICAgICAgICAgY29udGFpbmVyOiB0aGlzLmNvbnRhaW5lcixcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlXG4gICAgICB0aGlzLm5vRm91bmQgPSAhdGhpcy5jb21wb25lbnRSZWZcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKClcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlbmRlck1hcmtkb3duKGRhdGE6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5yZW5kZXJlcnM/Lm1hcmtkb3duKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1tuZ2UtZG9jXTogbWlzc2luZyBtYXJrZG93biByZW5kZXJlci4nKVxuICAgIH1cblxuICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5yZW5kZXJlcnMubWFya2Rvd25cbiAgICBjb25zdCB0eXBlID0gYXdhaXQgcmVuZGVyZXIuY29tcG9uZW50KClcblxuICAgIGNvbnN0IGNyZWF0ZUlucHV0cyA9IGFzeW5jICgpOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+ID0+IHtcbiAgICAgIGxldCBpbnB1dHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7XG4gICAgICAgIGRhdGEsIC8vIHdlIGFzc3VtZSB0aGF0IGRhdGEgaXMgYSBtYXJrZG93biBjb250ZW50LlxuICAgICAgfVxuXG4gICAgICBpZiAoIWRhdGEuaW5jbHVkZXMoJ1xcbicpKSB7XG4gICAgICAgIC8vIGlmIGRhdGEgZG9lcyBub3QgaW5jbHVkZSBhdCBsZWFzdCB0d28gbGluZXMgdGhlbiBpdCdzIGFuIHVybFxuICAgICAgICBjb25zdCBodHRwID0gdGhpcy5pbmplY3Rvci5nZXQoSHR0cENsaWVudCwgbnVsbClcbiAgICAgICAgaWYgKCFodHRwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgJ1tuZ2UtZG9jXSBXaGVuIHVzaW5nIHRoZSBgZmlsZWAgcmVuZGVyZXIgeW91ICpoYXZlIHRvKiBwYXNzIHRoZSBgSHR0cENsaWVudGAgYXMgYSBwYXJhbWV0ZXIgb2YgdGhlIGBmb3JSb290YCBtZXRob2QuIFNlZSBSRUFETUUgZm9yIG1vcmUgaW5mb3JtYXRpb24nXG4gICAgICAgICAgKVxuICAgICAgICB9XG5cbiAgICAgICAgaW5wdXRzID0ge1xuICAgICAgICAgIGRhdGE6IGF3YWl0IGZpcnN0VmFsdWVGcm9tKGh0dHAuZ2V0KGRhdGEsIHsgcmVzcG9uc2VUeXBlOiAndGV4dCcgfSkpLFxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxldCBjdXN0b21JbnB1dHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fVxuICAgICAgaWYgKHR5cGVvZiByZW5kZXJlci5pbnB1dHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY3VzdG9tSW5wdXRzID0gYXdhaXQgcmVuZGVyZXIuaW5wdXRzKHRoaXMuaW5qZWN0b3IpXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiByZW5kZXJlci5pbnB1dHMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGN1c3RvbUlucHV0cyA9IHJlbmRlcmVyLmlucHV0c1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyAuLi5jdXN0b21JbnB1dHMsIC4uLmlucHV0cyB9XG4gICAgfVxuXG4gICAgY29uc3QgbWFya2Rvd25Db21wb25lbnQgPSB0aGlzLmNvbXBvbmVudFJlZkJ5VHlwZXMuZ2V0KHR5cGUpXG4gICAgaWYgKG1hcmtkb3duQ29tcG9uZW50KSB7XG4gICAgICB0aGlzLmF0dGFjaENvbXBvbmVudChtYXJrZG93bkNvbXBvbmVudCwgYXdhaXQgY3JlYXRlSW5wdXRzKCkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBjb21wb25lbnRSZWYgPSBhd2FpdCB0aGlzLmNvbXBpbGVyU2VydmljZS5yZW5kZXIoe1xuICAgICAgdHlwZSxcbiAgICAgIGlucHV0czogYXdhaXQgY3JlYXRlSW5wdXRzKCksXG4gICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLFxuICAgIH0pXG5cbiAgICB0aGlzLmNvbXBvbmVudFJlZiA9IGNvbXBvbmVudFJlZlxuICAgIHRoaXMuY29tcG9uZW50UmVmQnlUeXBlcy5zZXQodHlwZSwgY29tcG9uZW50UmVmKVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhdHRhY2hDb21wb25lbnQoY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8YW55PiwgaW5wdXRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5jb250YWluZXIuaW5zZXJ0KGNvbXBvbmVudFJlZi5ob3N0VmlldylcbiAgICB0aGlzLmNvbXBvbmVudFJlZiA9IGNvbXBvbmVudFJlZlxuXG4gICAgLy8gY29tcHV0ZSBjaGFuZ2VzXG4gICAgY29uc3QgY2hhbmdlczogU2ltcGxlQ2hhbmdlcyA9IHt9XG4gICAgY29uc3QgeyBpbnN0YW5jZSwgY2hhbmdlRGV0ZWN0b3JSZWYgfSA9IGNvbXBvbmVudFJlZlxuICAgIE9iamVjdC5rZXlzKGlucHV0cykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBjaGFuZ2VzW2tleV0gPSB7XG4gICAgICAgIGN1cnJlbnRWYWx1ZTogaW5wdXRzW2tleV0sXG4gICAgICAgIHByZXZpb3VzVmFsdWU6IGluc3RhbmNlW2tleV0sXG4gICAgICAgIGZpcnN0Q2hhbmdlOiBmYWxzZSxcbiAgICAgICAgaXNGaXJzdENoYW5nZTogKCkgPT4gZmFsc2UsXG4gICAgICB9XG4gICAgICBpbnN0YW5jZVtrZXldID0gaW5wdXRzW2tleV1cbiAgICB9KVxuXG4gICAgLy8gY2FsbCBuZ09uQ2hhbmdlc1xuICAgIGlmIChpbnN0YW5jZS5uZ09uQ2hhbmdlcykge1xuICAgICAgYXdhaXQgaW5zdGFuY2UubmdPbkNoYW5nZXMoY2hhbmdlcylcbiAgICB9XG5cbiAgICBjaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibG9hZGluZy1jb250YWluZXJcIiAqbmdJZj1cImxvYWRpbmdcIj5cbiAgPGRpdiBjbGFzcz1cImxvYWRpbmctc3Bpbm5lclwiPjwvZGl2PlxuICA8ZGl2IGNsYXNzPVwibG9hZGluZy10ZXh0XCI+TG9hZGluZy4uLjwvZGl2PlxuPC9kaXY+XG48ZGl2ICpuZ0lmPVwibm9Gb3VuZFwiPlxuICA8aDE+T29vcHMhPC9oMT5cbiAgPGhyIC8+XG4gIDxwPkl0IGxvb2tzIGxpa2UgdGhpcyBwYWdlIGRvZXNuJ3QgZXhpc3QuPC9wPlxuPC9kaXY+XG48ZGl2ICNjb250YWluZXI+PC9kaXY+XG4iXX0=