ngx-contextual-action-bar
Version:
ngx-contextual-action-bar is an Angular2+ implementation of the [Material Design Contextual Action Bar](https://material.io/components/app-bars-top#contextual-action-bar). The implementation makes it possible to change the action bar properties (i.e. titl
124 lines • 22.4 kB
JavaScript
import { Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import { combineLatest, fromEvent, of } from 'rxjs';
import { map, pairwise, scan, startWith, switchMap } from "rxjs/operators";
import { ActionBarLayerModes } from './model/action-bar-layer.model';
import { ContextualActionBarService } from './ngx-contextual-action-bar.service';
import { buttonAnimation } from './animations/button.animation';
import { navbarAnimation } from './animations/navbar.animation';
import { paddingAnimation } from './animations/padding.animations';
import { layerSwitchAnimation } from './animations/layer-switch.animation';
import { CdkPortalOutlet, ComponentPortal } from '@angular/cdk/portal';
export class ContextualActionBarComponent {
constructor(service) {
this.service = service;
this.scrollThreshold = 200;
this.group = 'root';
}
handleButtonClick(id) {
this.service.buttonEmitter.emit(id);
}
ngOnInit() {
this.layer$ = this.service.latest(this.group);
this.layer$.pipe(
// distinctUntilChanged((a,b) => a?.id === b?.id)
)
.subscribe(layer => {
var _a;
if ((_a = this.outlet) === null || _a === void 0 ? void 0 : _a.hasAttached()) {
this.outlet.ngOnDestroy();
this.outlet.detach();
}
if (layer === null || layer === void 0 ? void 0 : layer.middleElement) {
const ref = this.outlet.attachComponentPortal(new ComponentPortal(layer.middleElement));
this.service._customElement.next([layer.id, ref.instance]);
}
});
this.layerSwitchTrigger$ = this.layer$.pipe(map(layer => layer === null || layer === void 0 ? void 0 : layer.id));
this.scroll = fromEvent(this.content.nativeElement, 'scroll').pipe(map(event => event.target.scrollTop), startWith(0));
this.netScroll$ = this.scroll.pipe(startWith(0), pairwise(), scan((acc, cur) => {
const [a, b] = cur;
if (b > a) {
if (acc < 0)
return 0;
}
else {
if (acc > 0)
return 0;
}
return acc + (b - a);
}, 0));
this.button$ = this.layer$.pipe(map(layer => layer === null || layer === void 0 ? void 0 : layer.button), startWith(undefined), pairwise());
this.navbarState$ = combineLatest([this.scroll, this.netScroll$, this.layer$]).pipe(scan((prev, [scroll, netscroll, layer]) => {
// spaget 🍝
if ((layer === null || layer === void 0 ? void 0 : layer.background) === 'transparent')
return 'transparent';
if ((layer === null || layer === void 0 ? void 0 : layer.mode) === ActionBarLayerModes.follow) {
if (prev === 'noanim')
return 'fixed';
return scroll > 1 ? 'visible' : 'nonaim';
}
else if ((layer === null || layer === void 0 ? void 0 : layer.mode) === ActionBarLayerModes.fixed)
return 'fixed';
else {
if (prev === 'noanim')
return 'fixed';
else if (prev === 'fixed') {
if (scroll < ((layer === null || layer === void 0 ? void 0 : layer.prominent) ? 128 : 56))
return 'fixed';
}
else {
if (scroll < 1)
return 'noanim';
}
return netscroll < -this.scrollThreshold ? 'visible' : 'fixed';
}
}, 'fixed'));
this.shadow$ = this.layer$.pipe(switchMap(layer => {
if ((layer === null || layer === void 0 ? void 0 : layer.mode) === ActionBarLayerModes.follow) {
return this.scroll.pipe(map(v => v > 1));
}
else if ((layer === null || layer === void 0 ? void 0 : layer.background) === 'transparent') {
return of(false);
}
return this.navbarState$.pipe(map(v => v === 'visible'));
}));
this.contentState$ = this.layer$.pipe(map(layer => {
if (!layer)
return 'none';
if (layer.background !== 'transparent')
return 'none';
return layer.prominent ? 'prominent' : 'regular';
}));
}
ngOnDestroy() {
// this.outlet.ngOnDestroy();
// this.outlet?.dispose();
}
}
ContextualActionBarComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-contextual-action-bar',
template: "<ng-template #navbar let-layer=\"layer\">\r\n <div class=\"button\"\r\n *ngIf=\"(button$ | async); let button\"\r\n >\r\n <button mat-icon-button *ngIf=\"button[1]\" (click)=\"handleButtonClick(layer.id)\" [@buttonAnimation]=\"button\">\r\n <!-- <button mat-icon-button [@buttonAnimation]=\"button\" (click)=\"handleButtonClick(layer.id)\"> -->\r\n <div class=\"wrapper\">\r\n <mat-icon class=\"old\">{{button[0]}}</mat-icon>\r\n <mat-icon class=\"new\">{{button[1]}}</mat-icon>\r\n </div>\r\n </button>\r\n </div>\r\n <div class=\"title\">\r\n <div class=\"custom-element\">\r\n <div cdkPortalOutlet></div> \r\n </div>\r\n <h2 *ngIf=\"layer?.title\">{{layer.title}}</h2>\r\n </div>\r\n\r\n <div class=\"actions\" *ngIf=\"layer?.actions.length > 0\">\r\n <ngx-actions-overflow-menu [group]=\"group\"></ngx-actions-overflow-menu>\r\n </div>\r\n</ng-template>\r\n<div class=\"component\"\r\n [class]=\"(layer$ | async)?.mode\"\r\n [class.prominent]=\"(layer$ | async)?.prominent\"\r\n [@layerSwitch]=\"layerSwitchTrigger$ | async\"\r\n> \r\n <div class=\"content\" #c cdkScrollable\r\n [@padding]=\"contentState$ | async\"\r\n >\r\n \r\n \r\n <nav class=\"navbar\"\r\n [style.color]=\"(layer$ | async)?.color\"\r\n [style.background]=\"(layer$ | async)?.background\"\r\n [@navbar]=\"navbarState$ | async\"\r\n [class.shadow]=\"(shadow$ | async)\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"navbar; context: { layer: layer$ | async }\"></ng-container>\r\n </nav>\r\n <mat-divider></mat-divider>\r\n <ng-content></ng-content>\r\n </div>\r\n</div>",
host: {
'class': 'ngx-contextual-action-bar'
},
animations: [
navbarAnimation,
buttonAnimation,
paddingAnimation,
layerSwitchAnimation
],
encapsulation: ViewEncapsulation.Emulated,
styles: [":host{height:inherit;width:inherit}.component,:host{position:relative}.component{display:flex;flex-direction:column;height:100%;width:100%;z-index:16}.component .content{overflow-x:hidden;overflow-y:auto;position:relative;z-index:0}.navbar{box-sizing:border-box;flex-direction:row;height:56px;left:0;top:0;transition:box-shadow .28s cubic-bezier(.4,0,.2,1);transition-property:height,box-shadow,padding-bottom,color,background;width:100%;z-index:3}.navbar,.navbar .button{display:flex;position:relative}.navbar .button{flex-direction:column;height:100%;padding:8px}.navbar .button button,.navbar .button button .wrapper{align-items:center;display:flex;height:40px;justify-content:center;position:relative}.navbar .button button .wrapper{width:40px}.navbar .button button .mat-icon{position:absolute}.navbar .button button .mat-icon.old{display:none}.navbar .title{align-items:flex-end;display:flex;flex:2 1 auto;padding-bottom:10px;padding-left:16px;padding-right:64px;position:relative}.navbar .title h2{margin:0}.navbar .title .custom-element{bottom:0;height:56px;left:0;position:absolute;width:100%}.navbar .actions{display:flex;flex:0.5 1 50px;flex-direction:column;height:100%;min-width:0;overflow:hidden;position:relative}.navbar .actions .ngx-actions-overflow-menu{flex:0 0 56px}.navbar.shadow{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.component.prominent>.content>.navbar{height:128px;padding-bottom:8px}.component.transparent .navbar{position:absolute}"]
},] }
];
ContextualActionBarComponent.ctorParameters = () => [
{ type: ContextualActionBarService }
];
ContextualActionBarComponent.propDecorators = {
content: [{ type: ViewChild, args: ['c', { read: ElementRef, static: true },] }],
outlet: [{ type: ViewChild, args: [CdkPortalOutlet,] }],
scrollThreshold: [{ type: Input }],
group: [{ type: Input }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWNvbnRleHR1YWwtYWN0aW9uLWJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNvbnRleHR1YWwtYWN0aW9uLWJhci9zcmMvIiwic291cmNlcyI6WyJsaWIvbmd4LWNvbnRleHR1YWwtYWN0aW9uLWJhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBZ0IsVUFBVSxFQUFFLEtBQUssRUFBcUIsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVILE9BQU8sRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRSxPQUFPLEVBQWlELEdBQUcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxSCxPQUFPLEVBQXVCLG1CQUFtQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDMUYsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDakYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUMzRSxPQUFPLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBaUIsTUFBTSxxQkFBcUIsQ0FBQztBQWlCdEYsTUFBTSxPQUFPLDRCQUE0QjtJQW9CdkMsWUFDVSxPQUFtQztRQUFuQyxZQUFPLEdBQVAsT0FBTyxDQUE0QjtRQWJwQyxvQkFBZSxHQUFXLEdBQUcsQ0FBQztRQUc5QixVQUFLLEdBQVcsTUFBTSxDQUFDO0lBWWhDLENBQUM7SUFFRCxpQkFBaUIs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YUFBYSxFQUFFLGlCQUFpQixDQUFDLFFBQVE7O2FBQzFDOzs7WUFyQlEsMEJBQTBCOzs7c0JBeUJoQyxTQUFTLFNBQUMsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO3FCQUNqRCxTQUFTLFNBQUMsZUFBZTs4QkFJekIsS0FBSztvQkFHTCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBDb21wb25lbnRSZWYsIEVsZW1lbnRSZWYsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgVmlld0NoaWxkLCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBjb21iaW5lTGF0ZXN0LCBmcm9tRXZlbnQsIE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBkaXN0aW5jdFVudGlsS2V5Q2hhbmdlZCwgbWFwLCBwYWlyd2lzZSwgc2Nhbiwgc3RhcnRXaXRoLCBzd2l0Y2hNYXAgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcclxuaW1wb3J0IHsgQWN0aW9uQmFyTGF5ZXJNb2RlbCwgQWN0aW9uQmFyTGF5ZXJNb2RlcyB9IGZyb20gJy4vbW9kZWwvYWN0aW9uLWJhci1sYXllci5tb2RlbCc7XHJcbmltcG9ydCB7IENvbnRleHR1YWxBY3Rpb25CYXJTZXJ2aWNlIH0gZnJvbSAnLi9uZ3gtY29udGV4dHVhbC1hY3Rpb24tYmFyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBidXR0b25BbmltYXRpb24gfSBmcm9tICcuL2FuaW1hdGlvbnMvYnV0dG9uLmFuaW1hdGlvbic7XHJcbmltcG9ydCB7IG5hdmJhckFuaW1hdGlvbiB9IGZyb20gJy4vYW5pbWF0aW9ucy9uYXZiYXIuYW5pbWF0aW9uJztcclxuaW1wb3J0IHsgcGFkZGluZ0FuaW1hdGlvbiB9IGZyb20gJy4vYW5pbWF0aW9ucy9wYWRkaW5nLmFuaW1hdGlvbnMnO1xyXG5pbXBvcnQgeyBsYXllclN3aXRjaEFuaW1hdGlvbiB9IGZyb20gJy4vYW5pbWF0aW9ucy9sYXllci1zd2l0Y2guYW5pbWF0aW9uJztcclxuaW1wb3J0IHsgQ2RrUG9ydGFsT3V0bGV0LCBDb21wb25lbnRQb3J0YWwsIENvbXBvbmVudFR5cGUgfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmd4LWNvbnRleHR1YWwtYWN0aW9uLWJhcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL25neC1jb250ZXh0dWFsLWFjdGlvbi1iYXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL25neC1jb250ZXh0dWFsLWFjdGlvbi1iYXIuY29tcG9uZW50LnNjc3MnXSxcclxuICBob3N0OiB7XHJcbiAgICAnY2xhc3MnOiAnbmd4LWNvbnRleHR1YWwtYWN0aW9uLWJhcidcclxuICB9LFxyXG4gIGFuaW1hdGlvbnM6IFtcclxuICAgIG5hdmJhckFuaW1hdGlvbixcclxuICAgIGJ1dHRvbkFuaW1hdGlvbixcclxuICAgIHBhZGRpbmdBbmltYXRpb24sXHJcbiAgICBsYXllclN3aXRjaEFuaW1hdGlvblxyXG4gIF0sXHJcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uRW11bGF0ZWRcclxufSlcclxuZXhwb3J0IGNsYXNzIENvbnRleHR1YWxBY3Rpb25CYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XHJcblxyXG4gIFxyXG4gIEBWaWV3Q2hpbGQoJ2MnLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZSB9KSBjb250ZW50ITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XHJcbiAgQFZpZXdDaGlsZChDZGtQb3J0YWxPdXRsZXQpIG91dGxldCE6IENka1BvcnRhbE91dGxldDtcclxuICBcclxuICBwdWJsaWMgbmV0U2Nyb2xsJCE6IE9ic2VydmFibGU8bnVtYmVyPjtcclxuICBwdWJsaWMgc2Nyb2xsITogT2JzZXJ2YWJsZTxudW1iZXI+O1xyXG4gIEBJbnB1dCgpIHNjcm9sbFRocmVzaG9sZDogbnVtYmVyID0gMjAwO1xyXG4gIFxyXG4gIGxheWVyJCE6IE9ic2VydmFibGU8QWN0aW9uQmFyTGF5ZXJNb2RlbCB8IHVuZGVmaW5lZD47XHJcbiAgQElucHV0KCkgZ3JvdXA6IHN0cmluZyA9ICdyb290JztcclxuXHJcbiAgcHVibGljIG5hdmJhclN0YXRlJCE6IE9ic2VydmFibGU8c3RyaW5nPjtcclxuICBwdWJsaWMgYnV0dG9uJCE6IE9ic2VydmFibGU8W3N0cmluZyB8IHVuZGVmaW5lZCwgc3RyaW5nIHwgdW5kZWZpbmVkXT47XHJcbiAgcHVibGljIHNoYWRvdyQhOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xyXG4gIHB1YmxpYyBjb250ZW50U3RhdGUkITogT2JzZXJ2YWJsZTwnbm9uZScgfCAncmVndWxhcicgfCAncHJvbWluZW50Jz47XHJcbiAgcHVibGljIGxheWVyU3dpdGNoVHJpZ2dlciQhOiBPYnNlcnZhYmxlPHN0cmluZyB8IHVuZGVmaW5lZD47XHJcbiAgcHVibGljIGN1c3RvbUVsZW1lbnQkITogT2JzZXJ2YWJsZTxDb21wb25lbnRQb3J0YWw8YW55PiB8IHVuZGVmaW5lZD47XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBDb250ZXh0dWFsQWN0aW9uQmFyU2VydmljZVxyXG4gICkge1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlQnV0dG9uQ2xpY2soaWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5zZXJ2aWNlLmJ1dHRvbkVtaXR0ZXIuZW1pdChpZCk7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHsgICAgXHJcbiAgICB0aGlzLmxheWVyJCA9IHRoaXMuc2VydmljZS5sYXRlc3QodGhpcy5ncm91cCk7XHJcbiAgICB0aGlzLmxheWVyJC5waXBlKFxyXG4gICAgICAvLyBkaXN0aW5jdFVudGlsQ2hhbmdlZCgoYSxiKSA9PiBhPy5pZCA9PT0gYj8uaWQpXHJcbiAgICApXHJcbiAgICAuc3Vic2NyaWJlKGxheWVyID0+IHtcclxuICAgICAgaWYgKHRoaXMub3V0bGV0Py5oYXNBdHRhY2hlZCgpKSB7XHJcbiAgICAgICAgdGhpcy5vdXRsZXQubmdPbkRlc3Ryb3koKTtcclxuICAgICAgICB0aGlzLm91dGxldC5kZXRhY2goKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAobGF5ZXI/Lm1pZGRsZUVsZW1lbnQpIHsgICAgICBcclxuICAgICAgICBjb25zdCByZWYgPSB0aGlzLm91dGxldC5hdHRhY2hDb21wb25lbnRQb3J0YWwobmV3IENvbXBvbmVudFBvcnRhbChsYXllci5taWRkbGVFbGVtZW50KSlcclxuICAgICAgICB0aGlzLnNlcnZpY2UuX2N1c3RvbUVsZW1lbnQubmV4dChbbGF5ZXIuaWQsIHJlZi5pbnN0YW5jZV0pO1xyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gICAgdGhpcy5sYXllclN3aXRjaFRyaWdnZXIkID0gdGhpcy5sYXllciQucGlwZShcclxuICAgICAgbWFwKGxheWVyID0+IGxheWVyPy5pZClcclxuICAgIClcclxuICAgIHRoaXMuc2Nyb2xsID0gZnJvbUV2ZW50KHRoaXMuY29udGVudC5uYXRpdmVFbGVtZW50LCAnc2Nyb2xsJykucGlwZShcclxuICAgICAgbWFwKGV2ZW50ID0+IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLnNjcm9sbFRvcCksXHJcbiAgICAgIHN0YXJ0V2l0aCgwKVxyXG4gICAgKTtcclxuICAgIHRoaXMubmV0U2Nyb2xsJCA9IHRoaXMuc2Nyb2xsLnBpcGUoXHJcbiAgICAgIHN0YXJ0V2l0aCgwKSxcclxuICAgICAgcGFpcndpc2UoKSxcclxuICAgICAgc2NhbigoYWNjLCBjdXIpID0+IHtcclxuICAgICAgICBjb25zdCBbYSwgYl0gPSBjdXI7XHJcbiAgICAgICAgaWYgKGIgPiBhKXtcclxuICAgICAgICAgIGlmIChhY2MgPCAwKSByZXR1cm4gMDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgaWYgKGFjYyA+IDApIHJldHVybiAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYWNjICsgKGIgLSBhKTtcclxuICAgICAgfSwgMCksXHJcbiAgICApXHJcbiAgICB0aGlzLmJ1dHRvbiQgPSB0aGlzLmxheWVyJC5waXBlKFxyXG4gICAgICBtYXAobGF5ZXIgPT4gbGF5ZXI/LmJ1dHRvbiksXHJcbiAgICAgIHN0YXJ0V2l0aCh1bmRlZmluZWQpLFxyXG4gICAgICBwYWlyd2lzZSgpLFxyXG4gICAgKVxyXG5cclxuICAgIHRoaXMubmF2YmFyU3RhdGUkID0gY29tYmluZUxhdGVzdChbdGhpcy5zY3JvbGwsIHRoaXMubmV0U2Nyb2xsJCwgdGhpcy5sYXllciRdKS5waXBlKFxyXG4gICAgICBzY2FuKChwcmV2LCBbc2Nyb2xsLCBuZXRzY3JvbGwsIGxheWVyXSkgPT4ge1xyXG4gICAgICAgIC8vIHNwYWdldCDwn42dXHJcbiAgICAgICAgaWYgKGxheWVyPy5iYWNrZ3JvdW5kID09PSAndHJhbnNwYXJlbnQnKSByZXR1cm4gJ3RyYW5zcGFyZW50JztcclxuICAgICAgICBpZiAobGF5ZXI/Lm1vZGUgPT09IEFjdGlvbkJhckxheWVyTW9kZXMuZm9sbG93KXtcclxuICAgICAgICAgIGlmIChwcmV2ID09PSAnbm9hbmltJykgcmV0dXJuICdmaXhlZCc7XHJcbiAgICAgICAgICByZXR1cm4gc2Nyb2xsID4gMSA/ICd2aXNpYmxlJyA6ICdub25haW0nO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobGF5ZXI/Lm1vZGUgPT09IEFjdGlvbkJhckxheWVyTW9kZXMuZml4ZWQpIHJldHVybiAnZml4ZWQnO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgaWYgKHByZXYgPT09ICdub2FuaW0nKSByZXR1cm4gJ2ZpeGVkJztcclxuICAgICAgICAgIGVsc2UgaWYgKHByZXYgPT09ICdmaXhlZCcpe1xyXG4gICAgICAgICAgICBpZiAoc2Nyb2xsIDwgKGxheWVyPy5wcm9taW5lbnQgPyAxMjggOiA1NikpIHJldHVybiAnZml4ZWQnO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHNjcm9sbCA8IDEpIHJldHVybiAnbm9hbmltJztcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHJldHVybiBuZXRzY3JvbGwgPCAtdGhpcy5zY3JvbGxUaHJlc2hvbGQgPyAndmlzaWJsZScgOiAnZml4ZWQnXHJcbiAgICAgICAgfVxyXG4gICAgICB9LCAnZml4ZWQnKVxyXG4gICAgKVxyXG5cclxuICAgIHRoaXMuc2hhZG93JCA9IHRoaXMubGF5ZXIkLnBpcGUoXHJcbiAgICAgIHN3aXRjaE1hcChsYXllciA9PiB7XHJcbiAgICAgICAgaWYgKGxheWVyPy5tb2RlID09PSBBY3Rpb25CYXJMYXllck1vZGVzLmZvbGxvdykge1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuc2Nyb2xsLnBpcGUobWFwKHYgPT4gdiA+IDEpKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGxheWVyPy5iYWNrZ3JvdW5kID09PSAndHJhbnNwYXJlbnQnKSB7XHJcbiAgICAgICAgICByZXR1cm4gb2YoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5uYXZiYXJTdGF0ZSQucGlwZShtYXAodiA9PiB2ID09PSAndmlzaWJsZScpKTtcclxuICAgICAgfSlcclxuICAgIClcclxuXHJcbiAgICB0aGlzLmNvbnRlbnRTdGF0ZSQgPSB0aGlzLmxheWVyJC5waXBlKFxyXG4gICAgICBtYXAobGF5ZXIgPT4ge1xyXG4gICAgICAgIGlmICghbGF5ZXIpIHJldHVybiAnbm9uZSc7XHJcbiAgICAgICAgaWYgKGxheWVyLmJhY2tncm91bmQgIT09ICd0cmFuc3BhcmVudCcpIHJldHVybiAnbm9uZSc7XHJcbiAgICAgICAgcmV0dXJuIGxheWVyLnByb21pbmVudCA/ICdwcm9taW5lbnQnIDogJ3JlZ3VsYXInO1xyXG4gICAgICB9KVxyXG4gICAgKVxyXG5cclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCl7XHJcbiAgICAvLyB0aGlzLm91dGxldC5uZ09uRGVzdHJveSgpO1xyXG4gICAgLy8gdGhpcy5vdXRsZXQ/LmRpc3Bvc2UoKTtcclxuICB9XHJcblxyXG59XHJcbiJdfQ==