@spartacus/storefront
Version:
Spartacus Storefront is a package that you can include in your application, which allows you to add default storefront features.
159 lines • 22.4 kB
JavaScript
import { ChangeDetectionStrategy, Component, HostBinding, Input, } from '@angular/core';
import { BehaviorSubject, Subscription } from 'rxjs';
import { distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@spartacus/core";
import * as i2 from "./page-slot.service";
import * as i3 from "../../outlet/outlet.directive";
import * as i4 from "@angular/common";
import * as i5 from "../component/component-wrapper.directive";
/**
* The `PageSlotComponent` is used to render the CMS page slot and it's components.
*
* The Page slot host element will be supplemented with css classes so that the layout
* can be fully controlled by customers:
* - The page slot _position_ is added as a css class by default.
* - The `cx-pending` is added for as long as the slot hasn't start loading.
* - The `page-fold` style class is added for the page slot which is configured as the page fold.
*/
export class PageSlotComponent {
constructor(cmsService, dynamicAttributeService, renderer, elementRef, cd, pageSlotService) {
this.cmsService = cmsService;
this.dynamicAttributeService = dynamicAttributeService;
this.renderer = renderer;
this.elementRef = elementRef;
this.cd = cd;
this.pageSlotService = pageSlotService;
/**
* Indicates that the page slot is the last page slot above the fold.
*/
this.isPageFold = false;
/**
* Indicates that the components of the page slot haven't been loaded as long
* as the isPending state is true.
*/
this.isPending = true;
/**
* Indicates that the page slot doesn't contain any components. This is no
* longer used in spartacus, but kept for backwards compatibility.
*/
this.hasComponents = false;
this.position$ = new BehaviorSubject(undefined);
this.slot$ = this.position$.pipe(switchMap((position) => this.cmsService.getContentSlot(position)), distinctUntilChanged(this.isDistinct));
/** Observes the components for the given page slot. */
this.components$ = this.slot$.pipe(map((slot) => { var _a; return (_a = slot === null || slot === void 0 ? void 0 : slot.components) !== null && _a !== void 0 ? _a : []; }));
this.subscription = new Subscription();
/** Keeps track of the pending components that must be loaded for the page slot */
this.pendingComponentCount = 0;
}
/**
* The position represents the unique key for a page slot on a single page, but can
* be reused cross pages.
*
* The position is used to find the CMS components for the page slot. It is also
* added as an additional CSS class so that layout can be applied.
*/
set position(value) {
this.position$.next(value);
}
get position() {
return this.position$.value;
}
ngOnInit() {
this.subscription.add(this.slot$.pipe(tap((slot) => this.decorate(slot))).subscribe((value) => {
this.components = (value === null || value === void 0 ? void 0 : value.components) || [];
this.cd.markForCheck();
}));
}
decorate(slot) {
var _a, _b;
let cls = this.class || '';
if (this.lastPosition && cls.indexOf(this.lastPosition) > -1) {
cls = cls.replace(this.lastPosition, '');
}
if (this.position$.value) {
cls += ` ${this.position$.value}`;
this.lastPosition = this.position$.value;
}
// host bindings
this.pending = ((_a = slot === null || slot === void 0 ? void 0 : slot.components) === null || _a === void 0 ? void 0 : _a.length) || 0;
this.hasComponents = ((_b = slot === null || slot === void 0 ? void 0 : slot.components) === null || _b === void 0 ? void 0 : _b.length) > 0;
if (cls && cls !== this.class) {
this.class = cls;
}
if (slot) {
this.dynamicAttributeService.addAttributesToSlot(this.elementRef.nativeElement, this.renderer, slot);
}
}
/**
* Sets the pending count for the page slot components. Once all pending components are
* loaded, the `isPending` flag is updated, so that the associated class can be updated
*/
set pending(count) {
this.pendingComponentCount = count;
this.isPending = this.pendingComponentCount > 0;
}
get pending() {
return this.pendingComponentCount;
}
/*
* Is triggered when a component is added to the view. This is used to
* update the pending count
*/
isLoaded(loadState) {
if (loadState) {
this.pending--;
this.cd.markForCheck();
}
}
/**
* The `DeferLoadingStrategy` indicates whether the component should be
* rendered instantly or whether it should be deferred.
*/
getComponentDeferOptions(componentType) {
return this.pageSlotService.getComponentDeferOptions(this.position, componentType);
}
isDistinct(old, current) {
var _a;
return (current.components &&
((_a = old.components) === null || _a === void 0 ? void 0 : _a.length) === current.components.length &&
!old.components.find((el, index) => el.uid !== current.components[index].uid));
}
ngOnDestroy() {
var _a;
(_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
}
}
PageSlotComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: PageSlotComponent, deps: [{ token: i1.CmsService }, { token: i1.DynamicAttributeService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i2.PageSlotService }], target: i0.ɵɵFactoryTarget.Component });
PageSlotComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: PageSlotComponent, selector: "cx-page-slot,[cx-page-slot]", inputs: { position: "position", class: "class", isPageFold: "isPageFold", hasComponents: "hasComponents" }, host: { properties: { "attr.position": "this.position", "class": "this.class", "class.page-fold": "this.isPageFold", "class.cx-pending": "this.isPending", "class.has-components": "this.hasComponents" } }, ngImport: i0, template: "<ng-template\n [cxOutlet]=\"position\"\n [cxOutletContext]=\"{ components$: components$ }\"\n>\n <ng-template\n *ngFor=\"let component of components\"\n [cxOutlet]=\"component.flexType\"\n [cxOutletContext]=\"{ component: component }\"\n [cxOutletDefer]=\"getComponentDeferOptions(component.flexType)\"\n (loaded)=\"isLoaded($event)\"\n >\n <ng-container [cxComponentWrapper]=\"component\"></ng-container>\n </ng-template>\n</ng-template>\n", directives: [{ type: i3.OutletDirective, selector: "[cxOutlet]", inputs: ["cxOutlet", "cxOutletContext", "cxOutletDefer"], outputs: ["loaded"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.ComponentWrapperDirective, selector: "[cxComponentWrapper]", inputs: ["cxComponentWrapper"], outputs: ["cxComponentRef"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: PageSlotComponent, decorators: [{
type: Component,
args: [{
selector: 'cx-page-slot,[cx-page-slot]',
templateUrl: './page-slot.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}], ctorParameters: function () { return [{ type: i1.CmsService }, { type: i1.DynamicAttributeService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i2.PageSlotService }]; }, propDecorators: { position: [{
type: HostBinding,
args: ['attr.position']
}, {
type: Input
}], class: [{
type: Input
}, {
type: HostBinding
}], isPageFold: [{
type: HostBinding,
args: ['class.page-fold']
}, {
type: Input
}], isPending: [{
type: HostBinding,
args: ['class.cx-pending']
}], hasComponents: [{
type: HostBinding,
args: ['class.has-components']
}, {
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZS1zbG90LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLXN0cnVjdHVyZS9wYWdlL3Nsb3QvcGFnZS1zbG90LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLXN0cnVjdHVyZS9wYWdlL3Nsb3QvcGFnZS1zbG90LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFdBQVcsRUFDWCxLQUFLLEdBSU4sTUFBTSxlQUFlLENBQUM7QUFPdkIsT0FBTyxFQUFFLGVBQWUsRUFBYyxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7QUFJM0U7Ozs7Ozs7O0dBUUc7QUFNSCxNQUFNLE9BQU8saUJBQWlCO0lBNEQ1QixZQUNZLFVBQXNCLEVBQ3RCLHVCQUFnRCxFQUNoRCxRQUFtQixFQUNuQixVQUFzQixFQUN0QixFQUFxQixFQUNyQixlQUFnQztRQUxoQyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7UUFDaEQsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBQ3JCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQTVDNUM7O1dBRUc7UUFDc0MsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUU1RDs7O1dBR0c7UUFDOEIsY0FBUyxHQUFHLElBQUksQ0FBQztRQUVsRDs7O1dBR0c7UUFDMkMsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFFMUQsY0FBUyxHQUE0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QzlCLGlkQWNBOzJGRHNCYSxpQkFBaUI7a0JBTDdCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLDZCQUE2QjtvQkFDdkMsV0FBVyxFQUFFLDRCQUE0QjtvQkFDekMsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07aUJBQ2hEO3NQQVdLLFFBQVE7c0JBRlgsV0FBVzt1QkFBQyxlQUFlOztzQkFDM0IsS0FBSztnQkFXa0IsS0FBSztzQkFBNUIsS0FBSzs7c0JBQUksV0FBVztnQkFLb0IsVUFBVTtzQkFBbEQsV0FBVzt1QkFBQyxpQkFBaUI7O3NCQUFHLEtBQUs7Z0JBTUwsU0FBUztzQkFBekMsV0FBVzt1QkFBQyxrQkFBa0I7Z0JBTWUsYUFBYTtzQkFBMUQsV0FBVzt1QkFBQyxzQkFBc0I7O3NCQUFHLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgUmVuZGVyZXIyLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIENtc1NlcnZpY2UsXG4gIENvbnRlbnRTbG90Q29tcG9uZW50RGF0YSxcbiAgQ29udGVudFNsb3REYXRhLFxuICBEeW5hbWljQXR0cmlidXRlU2VydmljZSxcbn0gZnJvbSAnQHNwYXJ0YWN1cy9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEludGVyc2VjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi8uLi8uLi9sYXlvdXQvbG9hZGluZy9pbnRlcnNlY3Rpb24ubW9kZWwnO1xuaW1wb3J0IHsgUGFnZVNsb3RTZXJ2aWNlIH0gZnJvbSAnLi9wYWdlLXNsb3Quc2VydmljZSc7XG5cbi8qKlxuICogVGhlIGBQYWdlU2xvdENvbXBvbmVudGAgaXMgdXNlZCB0byByZW5kZXIgdGhlIENNUyBwYWdlIHNsb3QgYW5kIGl0J3MgY29tcG9uZW50cy5cbiAqXG4gKiBUaGUgUGFnZSBzbG90IGhvc3QgZWxlbWVudCB3aWxsIGJlIHN1cHBsZW1lbnRlZCB3aXRoIGNzcyBjbGFzc2VzIHNvIHRoYXQgdGhlIGxheW91dFxuICogY2FuIGJlIGZ1bGx5IGNvbnRyb2xsZWQgYnkgY3VzdG9tZXJzOlxuICogLSBUaGUgcGFnZSBzbG90IF9wb3NpdGlvbl8gaXMgYWRkZWQgYXMgYSBjc3MgY2xhc3MgYnkgZGVmYXVsdC5cbiAqIC0gVGhlIGBjeC1wZW5kaW5nYCBpcyBhZGRlZCBmb3IgYXMgbG9uZyBhcyB0aGUgc2xvdCBoYXNuJ3Qgc3RhcnQgbG9hZGluZy5cbiAqIC0gVGhlIGBwYWdlLWZvbGRgIHN0eWxlIGNsYXNzIGlzIGFkZGVkIGZvciB0aGUgcGFnZSBzbG90IHdoaWNoIGlzIGNvbmZpZ3VyZWQgYXMgdGhlIHBhZ2UgZm9sZC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3gtcGFnZS1zbG90LFtjeC1wYWdlLXNsb3RdJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3BhZ2Utc2xvdC5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBQYWdlU2xvdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgLyoqXG4gICAqIFRoZSBwb3NpdGlvbiByZXByZXNlbnRzIHRoZSB1bmlxdWUga2V5IGZvciBhIHBhZ2Ugc2xvdCBvbiBhIHNpbmdsZSBwYWdlLCBidXQgY2FuXG4gICAqIGJlIHJldXNlZCBjcm9zcyBwYWdlcy5cbiAgICpcbiAgICogVGhlIHBvc2l0aW9uIGlzIHVzZWQgdG8gZmluZCB0aGUgQ01TIGNvbXBvbmVudHMgZm9yIHRoZSBwYWdlIHNsb3QuIEl0IGlzIGFsc29cbiAgICogYWRkZWQgYXMgYW4gYWRkaXRpb25hbCBDU1MgY2xhc3Mgc28gdGhhdCBsYXlvdXQgY2FuIGJlIGFwcGxpZWQuXG4gICAqL1xuICBASG9zdEJpbmRpbmcoJ2F0dHIucG9zaXRpb24nKVxuICBASW5wdXQoKVxuICBzZXQgcG9zaXRpb24odmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMucG9zaXRpb24kLm5leHQodmFsdWUpO1xuICB9XG4gIGdldCBwb3NpdGlvbigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9uJC52YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWludGFpbnMgY3NzIGNsYXNzZXMgaW50cm9kdWNlZCBieSB0aGUgaG9zdCBhbmQgYWRkcyBhZGRpdGlvbmFsIGNsYXNzZXMuXG4gICAqL1xuICBASW5wdXQoKSBASG9zdEJpbmRpbmcoKSBjbGFzczogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgcGFnZSBzbG90IGlzIHRoZSBsYXN0IHBhZ2Ugc2xvdCBhYm92ZSB0aGUgZm9sZC5cbiAgICovXG4gIEBIb3N0QmluZGluZygnY2xhc3MucGFnZS1mb2xkJykgQElucHV0KCkgaXNQYWdlRm9sZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgY29tcG9uZW50cyBvZiB0aGUgcGFnZSBzbG90IGhhdmVuJ3QgYmVlbiBsb2FkZWQgYXMgbG9uZ1xuICAgKiBhcyB0aGUgaXNQZW5kaW5nIHN0YXRlIGlzIHRydWUuXG4gICAqL1xuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmN4LXBlbmRpbmcnKSBpc1BlbmRpbmcgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgcGFnZSBzbG90IGRvZXNuJ3QgY29udGFpbiBhbnkgY29tcG9uZW50cy4gVGhpcyBpcyBub1xuICAgKiBsb25nZXIgdXNlZCBpbiBzcGFydGFjdXMsIGJ1dCBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgICovXG4gIEBIb3N0QmluZGluZygnY2xhc3MuaGFzLWNvbXBvbmVudHMnKSBASW5wdXQoKSBoYXNDb21wb25lbnRzID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIHBvc2l0aW9uJDogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHVuZGVmaW5lZCk7XG5cbiAgY29tcG9uZW50czogQ29udGVudFNsb3RDb21wb25lbnREYXRhW107XG5cbiAgcHJvdGVjdGVkIHNsb3QkOiBPYnNlcnZhYmxlPENvbnRlbnRTbG90RGF0YT4gPSB0aGlzLnBvc2l0aW9uJC5waXBlKFxuICAgIHN3aXRjaE1hcCgocG9zaXRpb24pID0+IHRoaXMuY21zU2VydmljZS5nZXRDb250ZW50U2xvdChwb3NpdGlvbikpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKHRoaXMuaXNEaXN0aW5jdClcbiAgKTtcblxuICAvKiogT2JzZXJ2ZXMgdGhlIGNvbXBvbmVudHMgZm9yIHRoZSBnaXZlbiBwYWdlIHNsb3QuICovXG4gIGNvbXBvbmVudHMkOiBPYnNlcnZhYmxlPENvbnRlbnRTbG90Q29tcG9uZW50RGF0YVtdPiA9IHRoaXMuc2xvdCQucGlwZShcbiAgICBtYXAoKHNsb3QpID0+IHNsb3Q/LmNvbXBvbmVudHMgPz8gW10pXG4gICk7XG5cbiAgcHJvdGVjdGVkIHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIC8qKiBLZWVwcyB0cmFjayBvZiB0aGUgcGVuZGluZyBjb21wb25lbnRzIHRoYXQgbXVzdCBiZSBsb2FkZWQgZm9yIHRoZSBwYWdlIHNsb3QgKi9cbiAgcHJpdmF0ZSBwZW5kaW5nQ29tcG9uZW50Q291bnQgPSAwO1xuXG4gIC8qKiBUcmFja3MgdGhlIGxhc3QgdXNlZCBwb3NpdGlvbiwgaW4gY2FzZSB0aGUgcGFnZSBzbG90IGlzIHVzZWQgZHluYW1pY2FsbHkgKi9cbiAgcHJpdmF0ZSBsYXN0UG9zaXRpb246IHN0cmluZztcbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGNtc1NlcnZpY2U6IENtc1NlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGR5bmFtaWNBdHRyaWJ1dGVTZXJ2aWNlOiBEeW5hbWljQXR0cmlidXRlU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcm90ZWN0ZWQgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByb3RlY3RlZCBwYWdlU2xvdFNlcnZpY2U6IFBhZ2VTbG90U2VydmljZVxuICApIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgdGhpcy5zbG90JC5waXBlKHRhcCgoc2xvdCkgPT4gdGhpcy5kZWNvcmF0ZShzbG90KSkpLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgdGhpcy5jb21wb25lbnRzID0gdmFsdWU/LmNvbXBvbmVudHMgfHwgW107XG4gICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZGVjb3JhdGUoc2xvdDogQ29udGVudFNsb3REYXRhKTogdm9pZCB7XG4gICAgbGV0IGNscyA9IHRoaXMuY2xhc3MgfHwgJyc7XG5cbiAgICBpZiAodGhpcy5sYXN0UG9zaXRpb24gJiYgY2xzLmluZGV4T2YodGhpcy5sYXN0UG9zaXRpb24pID4gLTEpIHtcbiAgICAgIGNscyA9IGNscy5yZXBsYWNlKHRoaXMubGFzdFBvc2l0aW9uLCAnJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnBvc2l0aW9uJC52YWx1ZSkge1xuICAgICAgY2xzICs9IGAgJHt0aGlzLnBvc2l0aW9uJC52YWx1ZX1gO1xuICAgICAgdGhpcy5sYXN0UG9zaXRpb24gPSB0aGlzLnBvc2l0aW9uJC52YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBob3N0IGJpbmRpbmdzXG4gICAgdGhpcy5wZW5kaW5nID0gc2xvdD8uY29tcG9uZW50cz8ubGVuZ3RoIHx8IDA7XG4gICAgdGhpcy5oYXNDb21wb25lbnRzID0gc2xvdD8uY29tcG9uZW50cz8ubGVuZ3RoID4gMDtcbiAgICBpZiAoY2xzICYmIGNscyAhPT0gdGhpcy5jbGFzcykge1xuICAgICAgdGhpcy5jbGFzcyA9IGNscztcbiAgICB9XG5cbiAgICBpZiAoc2xvdCkge1xuICAgICAgdGhpcy5keW5hbWljQXR0cmlidXRlU2VydmljZS5hZGRBdHRyaWJ1dGVzVG9TbG90KFxuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcbiAgICAgICAgdGhpcy5yZW5kZXJlcixcbiAgICAgICAgc2xvdFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgcGVuZGluZyBjb3VudCBmb3IgdGhlIHBhZ2Ugc2xvdCBjb21wb25lbnRzLiBPbmNlIGFsbCBwZW5kaW5nIGNvbXBvbmVudHMgYXJlXG4gICAqIGxvYWRlZCwgdGhlIGBpc1BlbmRpbmdgIGZsYWcgaXMgdXBkYXRlZCwgc28gdGhhdCB0aGUgYXNzb2NpYXRlZCBjbGFzcyBjYW4gYmUgdXBkYXRlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHNldCBwZW5kaW5nKGNvdW50OiBudW1iZXIpIHtcbiAgICB0aGlzLnBlbmRpbmdDb21wb25lbnRDb3VudCA9IGNvdW50O1xuICAgIHRoaXMuaXNQZW5kaW5nID0gdGhpcy5wZW5kaW5nQ29tcG9uZW50Q291bnQgPiAwO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBwZW5kaW5nKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGVuZGluZ0NvbXBvbmVudENvdW50O1xuICB9XG5cbiAgLypcbiAgICogSXMgdHJpZ2dlcmVkIHdoZW4gYSBjb21wb25lbnQgaXMgYWRkZWQgdG8gdGhlIHZpZXcuIFRoaXMgaXMgdXNlZCB0b1xuICAgKiB1cGRhdGUgdGhlIHBlbmRpbmcgY291bnRcbiAgICovXG4gIGlzTG9hZGVkKGxvYWRTdGF0ZTogYm9vbGVhbikge1xuICAgIGlmIChsb2FkU3RhdGUpIHtcbiAgICAgIHRoaXMucGVuZGluZy0tO1xuICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIGBEZWZlckxvYWRpbmdTdHJhdGVneWAgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIGNvbXBvbmVudCBzaG91bGQgYmVcbiAgICogcmVuZGVyZWQgaW5zdGFudGx5IG9yIHdoZXRoZXIgaXQgc2hvdWxkIGJlIGRlZmVycmVkLlxuICAgKi9cbiAgZ2V0Q29tcG9uZW50RGVmZXJPcHRpb25zKGNvbXBvbmVudFR5cGU6IHN0cmluZyk6IEludGVyc2VjdGlvbk9wdGlvbnMge1xuICAgIHJldHVybiB0aGlzLnBhZ2VTbG90U2VydmljZS5nZXRDb21wb25lbnREZWZlck9wdGlvbnMoXG4gICAgICB0aGlzLnBvc2l0aW9uLFxuICAgICAgY29tcG9uZW50VHlwZVxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNEaXN0aW5jdChvbGQ6IENvbnRlbnRTbG90RGF0YSwgY3VycmVudDogQ29udGVudFNsb3REYXRhKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGN1cnJlbnQuY29tcG9uZW50cyAmJlxuICAgICAgb2xkLmNvbXBvbmVudHM/Lmxlbmd0aCA9PT0gY3VycmVudC5jb21wb25lbnRzLmxlbmd0aCAmJlxuICAgICAgIW9sZC5jb21wb25lbnRzLmZpbmQoXG4gICAgICAgIChlbCwgaW5kZXgpID0+IGVsLnVpZCAhPT0gY3VycmVudC5jb21wb25lbnRzW2luZGV4XS51aWRcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gIH1cbn1cbiIsIjxuZy10ZW1wbGF0ZVxuICBbY3hPdXRsZXRdPVwicG9zaXRpb25cIlxuICBbY3hPdXRsZXRDb250ZXh0XT1cInsgY29tcG9uZW50cyQ6IGNvbXBvbmVudHMkIH1cIlxuPlxuICA8bmctdGVtcGxhdGVcbiAgICAqbmdGb3I9XCJsZXQgY29tcG9uZW50IG9mIGNvbXBvbmVudHNcIlxuICAgIFtjeE91dGxldF09XCJjb21wb25lbnQuZmxleFR5cGVcIlxuICAgIFtjeE91dGxldENvbnRleHRdPVwieyBjb21wb25lbnQ6IGNvbXBvbmVudCB9XCJcbiAgICBbY3hPdXRsZXREZWZlcl09XCJnZXRDb21wb25lbnREZWZlck9wdGlvbnMoY29tcG9uZW50LmZsZXhUeXBlKVwiXG4gICAgKGxvYWRlZCk9XCJpc0xvYWRlZCgkZXZlbnQpXCJcbiAgPlxuICAgIDxuZy1jb250YWluZXIgW2N4Q29tcG9uZW50V3JhcHBlcl09XCJjb21wb25lbnRcIj48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvbmctdGVtcGxhdGU+XG4iXX0=