@spartacus/storefront
Version:
Spartacus Storefront is a package that you can include in your application, which allows you to add default storefront features.
168 lines • 20.7 kB
JavaScript
import { ComponentFactory, Directive, EventEmitter, Injector, Input, Output, TemplateRef, } from '@angular/core';
import { ReplaySubject, Subscription } from 'rxjs';
import { OutletContextData, OutletPosition, USE_STACKED_OUTLETS, } from './outlet.model';
import * as i0 from "@angular/core";
import * as i1 from "./outlet.service";
import * as i2 from "../../layout/loading/defer-loader.service";
import * as i3 from "./outlet-renderer.service";
export class OutletDirective {
constructor(vcr, templateRef, outletService, deferLoaderService, outletRendererService) {
this.vcr = vcr;
this.templateRef = templateRef;
this.outletService = outletService;
this.deferLoaderService = deferLoaderService;
this.outletRendererService = outletRendererService;
this.renderedTemplate = [];
this.renderedComponents = new Map();
/**
* Observable with current outlet context
*/
this.outletContext$ = new ReplaySubject(1);
this.loaded = new EventEmitter(true);
this.subscription = new Subscription();
}
/**
* Renders view for outlet or defers it, depending on the input `cxOutletDefer`
*/
render() {
this.vcr.clear();
this.renderedTemplate = [];
this.renderedComponents.clear();
this.subscription.unsubscribe();
this.subscription = new Subscription();
if (this.cxOutletDefer) {
this.deferLoading();
}
else {
this.build();
}
}
ngOnChanges(changes) {
if (changes.cxOutlet) {
this.render();
this.outletRendererService.register(this.cxOutlet, this);
}
if (changes.cxOutletContext) {
this.outletContext$.next(this.cxOutletContext);
}
}
deferLoading() {
this.loaded.emit(false);
const hostElement = this.getHostElement(this.vcr.element.nativeElement);
// Although the deferLoaderService might emit only once, as long as the hostElement
// isn't being loaded, there's no value being emitted. Therefore we need to clean up
// the subscription on destroy.
this.subscription.add(this.deferLoaderService
.load(hostElement, this.cxOutletDefer)
.subscribe(() => {
this.build();
this.loaded.emit(true);
}));
}
/**
* Renders view for outlet
*/
build() {
this.buildOutlet(OutletPosition.BEFORE);
this.buildOutlet(OutletPosition.REPLACE);
this.buildOutlet(OutletPosition.AFTER);
}
/**
* Renders view in a given position for outlet
*/
buildOutlet(position) {
let templates = (this.outletService.get(this.cxOutlet, position, USE_STACKED_OUTLETS));
templates = templates === null || templates === void 0 ? void 0 : templates.filter((el) => !this.renderedTemplate.includes(el));
if (!templates && position === OutletPosition.REPLACE) {
templates = [this.templateRef];
}
// Just in case someone extended the `OutletService` and
// returns a singular object.
if (!Array.isArray(templates)) {
templates = [templates];
}
const components = [];
templates.forEach((obj) => {
const component = this.create(obj, position);
components.push(component);
});
this.renderedComponents.set(position, components);
}
/**
* Renders view based on the given template or component factory
*/
create(tmplOrFactory, position) {
this.renderedTemplate.push(tmplOrFactory);
if (tmplOrFactory instanceof ComponentFactory) {
const component = this.vcr.createComponent(tmplOrFactory, undefined, this.getComponentInjector(position));
return component;
}
else if (tmplOrFactory instanceof TemplateRef) {
const view = this.vcr.createEmbeddedView(tmplOrFactory, {
$implicit: this.cxOutletContext,
});
// we do not know if content is created dynamically or not
// so we apply change detection anyway
view.markForCheck();
return view;
}
}
/**
* Returns injector with OutletContextData that can be injected to the component
* rendered in the outlet
*/
getComponentInjector(position) {
const contextData = {
reference: this.cxOutlet,
position,
context: this.cxOutletContext,
context$: this.outletContext$.asObservable(),
};
return Injector.create({
providers: [
{
provide: OutletContextData,
useValue: contextData,
},
],
parent: this.vcr.injector,
});
}
/**
* Returns the closest `HtmlElement`, by iterating over the
* parent nodes of the given element.
*
* We avoid traversing the parent _elements_, as this is blocking
* ie11 implementations. One of the spare exclusions we make to not
* supporting ie11.
*
* @param element
*/
getHostElement(element) {
if (element instanceof HTMLElement) {
return element;
}
return this.getHostElement(element.parentNode);
}
ngOnDestroy() {
this.subscription.unsubscribe();
this.outletContext$.complete();
}
}
OutletDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: OutletDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }, { token: i1.OutletService }, { token: i2.DeferLoaderService }, { token: i3.OutletRendererService }], target: i0.ɵɵFactoryTarget.Directive });
OutletDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.0.5", type: OutletDirective, selector: "[cxOutlet]", inputs: { cxOutlet: "cxOutlet", cxOutletContext: "cxOutletContext", cxOutletDefer: "cxOutletDefer" }, outputs: { loaded: "loaded" }, usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: OutletDirective, decorators: [{
type: Directive,
args: [{
selector: '[cxOutlet]',
}]
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.TemplateRef }, { type: i1.OutletService }, { type: i2.DeferLoaderService }, { type: i3.OutletRendererService }]; }, propDecorators: { cxOutlet: [{
type: Input
}], cxOutletContext: [{
type: Input
}], cxOutletDefer: [{
type: Input
}], loaded: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0bGV0LmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLXN0cnVjdHVyZS9vdXRsZXQvb3V0bGV0LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsZ0JBQWdCLEVBRWhCLFNBQVMsRUFFVCxZQUFZLEVBQ1osUUFBUSxFQUNSLEtBQUssRUFHTCxNQUFNLEVBRU4sV0FBVyxHQUVaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSW5ELE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsY0FBYyxFQUNkLG1CQUFtQixHQUNwQixNQUFNLGdCQUFnQixDQUFDOzs7OztBQU14QixNQUFNLE9BQU8sZUFBZTtJQTRCMUIsWUFDVSxHQUFxQixFQUNyQixXQUE2QixFQUM3QixhQUE0QixFQUM1QixrQkFBc0MsRUFDdEMscUJBQTRDO1FBSjVDLFFBQUcsR0FBSCxHQUFHLENBQWtCO1FBQ3JCLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtRQUM3QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1Qix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLDBCQUFxQixHQUFyQixxQkFBcUIsQ0FBdUI7UUFoQzlDLHFCQUFnQixHQUFHLEVBQUUsQ0FBQztRQUN2Qix1QkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFHaEMsQ0FBQztRQVNKOztXQUVHO1FBQ2MsbUJBQWMsR0FBRyxJQUFJLGFBQWEsQ0FBSSxDQUFDLENBQUMsQ0FBQztRQU9oRCxXQUFNLEdBQTBCLElBQUksWUFBWSxDQUFVLElBQUksQ0FBQyxDQUFDO1FBRTFFLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQVEvQixDQUFDO0lBRUo7O09BRUc7SUFDSSxNQUFNO1FBQ1gsSUFBSSxDQUFDLEdBQUcsQ0FB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QUFFO2dCQUNUO29CQUNFLE9BQU8sRUFBRSxpQkFBaUI7b0JBQzFCLFFBQVEsRUFBRSxXQUFXO2lCQUN0QjthQUNGO1lBQ0QsTUFBTSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUTtTQUMxQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ssY0FBYyxDQUFDLE9BQWE7UUFDbEMsSUFBSSxPQUFPLFlBQVksV0FBVyxFQUFFO1lBQ2xDLE9BQU8sT0FBTyxDQUFDO1NBQ2hCO1FBQ0QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNqQyxDQUFDOzs0R0EvTFUsZUFBZTtnR0FBZixlQUFlOzJGQUFmLGVBQWU7a0JBSDNCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLFlBQVk7aUJBQ3ZCO2tPQVFVLFFBQVE7c0JBQWhCLEtBQUs7Z0JBS0csZUFBZTtzQkFBdkIsS0FBSztnQkFVRyxhQUFhO3NCQUFyQixLQUFLO2dCQUVJLE1BQU07c0JBQWYsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudEZhY3RvcnksXG4gIENvbXBvbmVudFJlZixcbiAgRGlyZWN0aXZlLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NvbnRhaW5lclJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IERlZmVyTG9hZGVyU2VydmljZSB9IGZyb20gJy4uLy4uL2xheW91dC9sb2FkaW5nL2RlZmVyLWxvYWRlci5zZXJ2aWNlJztcbmltcG9ydCB7IEludGVyc2VjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi8uLi9sYXlvdXQvbG9hZGluZy9pbnRlcnNlY3Rpb24ubW9kZWwnO1xuaW1wb3J0IHsgT3V0bGV0UmVuZGVyZXJTZXJ2aWNlIH0gZnJvbSAnLi9vdXRsZXQtcmVuZGVyZXIuc2VydmljZSc7XG5pbXBvcnQge1xuICBPdXRsZXRDb250ZXh0RGF0YSxcbiAgT3V0bGV0UG9zaXRpb24sXG4gIFVTRV9TVEFDS0VEX09VVExFVFMsXG59IGZyb20gJy4vb3V0bGV0Lm1vZGVsJztcbmltcG9ydCB7IE91dGxldFNlcnZpY2UgfSBmcm9tICcuL291dGxldC5zZXJ2aWNlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2N4T3V0bGV0XScsXG59KVxuZXhwb3J0IGNsYXNzIE91dGxldERpcmVjdGl2ZTxUID0gYW55PiBpbXBsZW1lbnRzIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcbiAgcHJpdmF0ZSByZW5kZXJlZFRlbXBsYXRlID0gW107XG4gIHB1YmxpYyByZW5kZXJlZENvbXBvbmVudHMgPSBuZXcgTWFwPFxuICAgIE91dGxldFBvc2l0aW9uLFxuICAgIEFycmF5PENvbXBvbmVudFJlZjxhbnk+IHwgRW1iZWRkZWRWaWV3UmVmPGFueT4+XG4gID4oKTtcblxuICBASW5wdXQoKSBjeE91dGxldDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDb250ZXh0IGRhdGEgdG8gYmUgcHJvdmlkZWQgdG8gY2hpbGQgdmlldyBvZiB0aGUgb3V0bGV0XG4gICAqL1xuICBASW5wdXQoKSBjeE91dGxldENvbnRleHQ6IFQ7XG5cbiAgLyoqXG4gICAqIE9ic2VydmFibGUgd2l0aCBjdXJyZW50IG91dGxldCBjb250ZXh0XG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IG91dGxldENvbnRleHQkID0gbmV3IFJlcGxheVN1YmplY3Q8VD4oMSk7XG5cbiAgLyoqXG4gICAqIERlZmVycyBsb2FkaW5nIG9wdGlvbnMgZm9yIHRoZSB0aGUgdGVtcGxhdGVzIG9mIHRoaXMgb3V0bGV0LlxuICAgKi9cbiAgQElucHV0KCkgY3hPdXRsZXREZWZlcjogSW50ZXJzZWN0aW9uT3B0aW9ucztcblxuICBAT3V0cHV0KCkgbG9hZGVkOiBFdmVudEVtaXR0ZXI8Qm9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyPEJvb2xlYW4+KHRydWUpO1xuXG4gIHN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHZjcjogVmlld0NvbnRhaW5lclJlZixcbiAgICBwcml2YXRlIHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+LFxuICAgIHByaXZhdGUgb3V0bGV0U2VydmljZTogT3V0bGV0U2VydmljZSxcbiAgICBwcml2YXRlIGRlZmVyTG9hZGVyU2VydmljZTogRGVmZXJMb2FkZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgb3V0bGV0UmVuZGVyZXJTZXJ2aWNlOiBPdXRsZXRSZW5kZXJlclNlcnZpY2VcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBSZW5kZXJzIHZpZXcgZm9yIG91dGxldCBvciBkZWZlcnMgaXQsIGRlcGVuZGluZyBvbiB0aGUgaW5wdXQgYGN4T3V0bGV0RGVmZXJgXG4gICAqL1xuICBwdWJsaWMgcmVuZGVyKCk6IHZvaWQge1xuICAgIHRoaXMudmNyLmNsZWFyKCk7XG4gICAgdGhpcy5yZW5kZXJlZFRlbXBsYXRlID0gW107XG4gICAgdGhpcy5yZW5kZXJlZENvbXBvbmVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gICAgaWYgKHRoaXMuY3hPdXRsZXREZWZlcikge1xuICAgICAgdGhpcy5kZWZlckxvYWRpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5idWlsZCgpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlcy5jeE91dGxldCkge1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgIHRoaXMub3V0bGV0UmVuZGVyZXJTZXJ2aWNlLnJlZ2lzdGVyKHRoaXMuY3hPdXRsZXQsIHRoaXMpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5jeE91dGxldENvbnRleHQpIHtcbiAgICAgIHRoaXMub3V0bGV0Q29udGV4dCQubmV4dCh0aGlzLmN4T3V0bGV0Q29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZWZlckxvYWRpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkZWQuZW1pdChmYWxzZSk7XG4gICAgY29uc3QgaG9zdEVsZW1lbnQgPSB0aGlzLmdldEhvc3RFbGVtZW50KHRoaXMudmNyLmVsZW1lbnQubmF0aXZlRWxlbWVudCk7XG4gICAgLy8gQWx0aG91Z2ggdGhlIGRlZmVyTG9hZGVyU2VydmljZSBtaWdodCBlbWl0IG9ubHkgb25jZSwgYXMgbG9uZyBhcyB0aGUgaG9zdEVsZW1lbnRcbiAgICAvLyBpc24ndCBiZWluZyBsb2FkZWQsIHRoZXJlJ3Mgbm8gdmFsdWUgYmVpbmcgZW1pdHRlZC4gVGhlcmVmb3JlIHdlIG5lZWQgdG8gY2xlYW4gdXBcbiAgICAvLyB0aGUgc3Vic2NyaXB0aW9uIG9uIGRlc3Ryb3kuXG4gICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgdGhpcy5kZWZlckxvYWRlclNlcnZpY2VcbiAgICAgICAgLmxvYWQoaG9zdEVsZW1lbnQsIHRoaXMuY3hPdXRsZXREZWZlcilcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5idWlsZCgpO1xuICAgICAgICAgIHRoaXMubG9hZGVkLmVtaXQodHJ1ZSk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXJzIHZpZXcgZm9yIG91dGxldFxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZCgpIHtcbiAgICB0aGlzLmJ1aWxkT3V0bGV0KE91dGxldFBvc2l0aW9uLkJFRk9SRSk7XG4gICAgdGhpcy5idWlsZE91dGxldChPdXRsZXRQb3NpdGlvbi5SRVBMQUNFKTtcbiAgICB0aGlzLmJ1aWxkT3V0bGV0KE91dGxldFBvc2l0aW9uLkFGVEVSKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXJzIHZpZXcgaW4gYSBnaXZlbiBwb3NpdGlvbiBmb3Igb3V0bGV0XG4gICAqL1xuICBwcml2YXRlIGJ1aWxkT3V0bGV0KHBvc2l0aW9uOiBPdXRsZXRQb3NpdGlvbik6IHZvaWQge1xuICAgIGxldCB0ZW1wbGF0ZXM6IGFueVtdID0gPGFueVtdPihcbiAgICAgIHRoaXMub3V0bGV0U2VydmljZS5nZXQodGhpcy5jeE91dGxldCwgcG9zaXRpb24sIFVTRV9TVEFDS0VEX09VVExFVFMpXG4gICAgKTtcblxuICAgIHRlbXBsYXRlcyA9IHRlbXBsYXRlcz8uZmlsdGVyKChlbCkgPT4gIXRoaXMucmVuZGVyZWRUZW1wbGF0ZS5pbmNsdWRlcyhlbCkpO1xuXG4gICAgaWYgKCF0ZW1wbGF0ZXMgJiYgcG9zaXRpb24gPT09IE91dGxldFBvc2l0aW9uLlJFUExBQ0UpIHtcbiAgICAgIHRlbXBsYXRlcyA9IFt0aGlzLnRlbXBsYXRlUmVmXTtcbiAgICB9XG5cbiAgICAvLyBKdXN0IGluIGNhc2Ugc29tZW9uZSBleHRlbmRlZCB0aGUgYE91dGxldFNlcnZpY2VgIGFuZFxuICAgIC8vIHJldHVybnMgYSBzaW5ndWxhciBvYmplY3QuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRlbXBsYXRlcykpIHtcbiAgICAgIHRlbXBsYXRlcyA9IFt0ZW1wbGF0ZXNdO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbXBvbmVudHMgPSBbXTtcbiAgICB0ZW1wbGF0ZXMuZm9yRWFjaCgob2JqKSA9PiB7XG4gICAgICBjb25zdCBjb21wb25lbnQgPSB0aGlzLmNyZWF0ZShvYmosIHBvc2l0aW9uKTtcbiAgICAgIGNvbXBvbmVudHMucHVzaChjb21wb25lbnQpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5yZW5kZXJlZENvbXBvbmVudHMuc2V0KHBvc2l0aW9uLCBjb21wb25lbnRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXJzIHZpZXcgYmFzZWQgb24gdGhlIGdpdmVuIHRlbXBsYXRlIG9yIGNvbXBvbmVudCBmYWN0b3J5XG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZShcbiAgICB0bXBsT3JGYWN0b3J5OiBhbnksXG4gICAgcG9zaXRpb246IE91dGxldFBvc2l0aW9uXG4gICk6IENvbXBvbmVudFJlZjxhbnk+IHwgRW1iZWRkZWRWaWV3UmVmPGFueT4ge1xuICAgIHRoaXMucmVuZGVyZWRUZW1wbGF0ZS5wdXNoKHRtcGxPckZhY3RvcnkpO1xuXG4gICAgaWYgKHRtcGxPckZhY3RvcnkgaW5zdGFuY2VvZiBDb21wb25lbnRGYWN0b3J5KSB7XG4gICAgICBjb25zdCBjb21wb25lbnQgPSB0aGlzLnZjci5jcmVhdGVDb21wb25lbnQoXG4gICAgICAgIHRtcGxPckZhY3RvcnksXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgdGhpcy5nZXRDb21wb25lbnRJbmplY3Rvcihwb3NpdGlvbilcbiAgICAgICk7XG4gICAgICByZXR1cm4gY29tcG9uZW50O1xuICAgIH0gZWxzZSBpZiAodG1wbE9yRmFjdG9yeSBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmKSB7XG4gICAgICBjb25zdCB2aWV3ID0gdGhpcy52Y3IuY3JlYXRlRW1iZWRkZWRWaWV3KFxuICAgICAgICA8VGVtcGxhdGVSZWY8YW55Pj50bXBsT3JGYWN0b3J5LFxuICAgICAgICB7XG4gICAgICAgICAgJGltcGxpY2l0OiB0aGlzLmN4T3V0bGV0Q29udGV4dCxcbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgLy8gd2UgZG8gbm90IGtub3cgaWYgY29udGVudCBpcyBjcmVhdGVkIGR5bmFtaWNhbGx5IG9yIG5vdFxuICAgICAgLy8gc28gd2UgYXBwbHkgY2hhbmdlIGRldGVjdGlvbiBhbnl3YXlcbiAgICAgIHZpZXcubWFya0ZvckNoZWNrKCk7XG4gICAgICByZXR1cm4gdmlldztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBpbmplY3RvciB3aXRoIE91dGxldENvbnRleHREYXRhIHRoYXQgY2FuIGJlIGluamVjdGVkIHRvIHRoZSBjb21wb25lbnRcbiAgICogcmVuZGVyZWQgaW4gdGhlIG91dGxldFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRDb21wb25lbnRJbmplY3Rvcihwb3NpdGlvbjogT3V0bGV0UG9zaXRpb24pOiBJbmplY3RvciB7XG4gICAgY29uc3QgY29udGV4dERhdGE6IE91dGxldENvbnRleHREYXRhPFQ+ID0ge1xuICAgICAgcmVmZXJlbmNlOiB0aGlzLmN4T3V0bGV0LFxuICAgICAgcG9zaXRpb24sXG4gICAgICBjb250ZXh0OiB0aGlzLmN4T3V0bGV0Q29udGV4dCxcbiAgICAgIGNvbnRleHQkOiB0aGlzLm91dGxldENvbnRleHQkLmFzT2JzZXJ2YWJsZSgpLFxuICAgIH07XG5cbiAgICByZXR1cm4gSW5qZWN0b3IuY3JlYXRlKHtcbiAgICAgIHByb3ZpZGVyczogW1xuICAgICAgICB7XG4gICAgICAgICAgcHJvdmlkZTogT3V0bGV0Q29udGV4dERhdGEsXG4gICAgICAgICAgdXNlVmFsdWU6IGNvbnRleHREYXRhLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIHBhcmVudDogdGhpcy52Y3IuaW5qZWN0b3IsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBgSHRtbEVsZW1lbnRgLCBieSBpdGVyYXRpbmcgb3ZlciB0aGVcbiAgICogcGFyZW50IG5vZGVzIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgKlxuICAgKiBXZSBhdm9pZCB0cmF2ZXJzaW5nIHRoZSBwYXJlbnQgX2VsZW1lbnRzXywgYXMgdGhpcyBpcyBibG9ja2luZ1xuICAgKiBpZTExIGltcGxlbWVudGF0aW9ucy4gT25lIG9mIHRoZSBzcGFyZSBleGNsdXNpb25zIHdlIG1ha2UgdG8gbm90XG4gICAqIHN1cHBvcnRpbmcgaWUxMS5cbiAgICpcbiAgICogQHBhcmFtIGVsZW1lbnRcbiAgICovXG4gIHByaXZhdGUgZ2V0SG9zdEVsZW1lbnQoZWxlbWVudDogTm9kZSk6IEhUTUxFbGVtZW50IHtcbiAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0SG9zdEVsZW1lbnQoZWxlbWVudC5wYXJlbnROb2RlKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5vdXRsZXRDb250ZXh0JC5jb21wbGV0ZSgpO1xuICB9XG59XG4iXX0=