UNPKG

@nova-ui/bits

Version:

SolarWinds Nova Framework

182 lines 38.5 kB
// © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, HostBinding, Input, NgZone, Output, QueryList, ViewChild, } from "@angular/core"; import { TabHeadingComponent } from "../tab-heading/tab-heading.component"; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "../../icon/icon.component"; // <example-url>./../examples/index.html#/tabgroup</example-url> export class TabHeadingGroupComponent { get isVertical() { return this.vertical; } constructor(el, changeDetectorRef, ngZone) { this.el = el; this.changeDetectorRef = changeDetectorRef; this.ngZone = ngZone; /** * Emits id of selected tab */ this.selected = new EventEmitter(); this.leftTraverseEnabled = true; this.rightTraverseEnabled = false; this.hasTraverse = false; this._traverseButtonsWidth = 60; this._traverseStepSize = 50; this._tabSelectedSubscriptions = []; } ngAfterViewInit() { // Observing the size of the component to check traverse this._ro = new ResizeObserver((entries) => entries.forEach(() => this.checkTraverse())); this.ngZone.runOutsideAngular(() => { this._ro.observe(this.resizableArea.nativeElement); this._ro.observe(this.el.nativeElement); }); // Making the first tab in group active by default this.setActiveTab(); this.subscribeToSelection(); this._changesSubscription = this._tabs.changes.subscribe((changedTabs) => { this.setActiveTab(); this._tabSelectedSubscriptions.forEach((sub) => sub.unsubscribe()); this._tabSelectedSubscriptions = []; this.subscribeToSelection(); }); } setActiveTab() { if (this._tabs.length && !this.getActiveTab()) { this._tabs.first.active = true; this.selected.emit(this._tabs.first.tabId); } } getActiveTab() { return this._tabs.filter((tab) => tab.active)[0]; } checkTraverse() { this.hasTraverse = this.allowTraverse(); this.changeDetectorRef.detectChanges(); if (!this.hasTraverse) { this.setNewShift("0px"); } } allowTraverse() { const holderSize = this.getElementSize("nui-tab-headings__holder"); const contentSize = this.getElementSize("nui-tab-headings__container"); if (this.vertical) { return false; } return holderSize + this._traverseButtonsWidth <= contentSize; } traverseRight() { const margin = this.getCurrentShift(); if (this.isTraverseRightAllowed(margin)) { const traverseStep = Math.abs(this.getNumberFromPixels(margin)) < this._traverseStepSize ? Math.abs(this.getNumberFromPixels(margin)) : this._traverseStepSize; this.setNewShift(this.addPixels(margin, traverseStep)); this.rightTraverseEnabled = this.isTraverseRightAllowed(this.addPixels(margin, traverseStep)); this.leftTraverseEnabled = this.isTraverseLeftAllowed(this.addPixels(margin, traverseStep)); } } traverseLeft() { const margin = this.getCurrentShift(); if (this.isTraverseLeftAllowed(margin)) { const tabsSize = this.getElementSize("nui-tab-headings__container"); const tabHolderSize = this.getElementSize("nui-tab-headings__holder"); const maxAllowedMargin = Math.abs(tabsSize - tabHolderSize + this._traverseButtonsWidth); const leftMarginValue = Math.abs(this.getNumberFromPixels(margin)); const traverseStep = Math.min(maxAllowedMargin - leftMarginValue, this._traverseStepSize); this.setNewShift(this.addPixels(margin, -traverseStep)); this.rightTraverseEnabled = this.isTraverseRightAllowed(this.addPixels(margin, -traverseStep)); this.leftTraverseEnabled = this.isTraverseLeftAllowed(this.addPixels(margin, -traverseStep)); } } // Subscribing to all tabs and their 'selected' event. Once the event has been fired the origin tab becomes active. subscribeToSelection() { this._tabs.forEach((tab) => { this._tabSelectedSubscriptions.push(tab.selected.subscribe((currentTab) => { if (!currentTab.active && !currentTab.disabled) { // Making all elements in array inactive to make than current one active this._tabs.forEach((tabHeading) => { tabHeading.active = false; }); currentTab.active = true; this.changeDetectorRef.markForCheck(); this.changeDetectorRef.detectChanges(); this.selected.emit(currentTab.tabId); } })); }); } isTraverseLeftAllowed(leftMargin) { const tabsSize = this.getElementSize("nui-tab-headings__container"); const tabHolderSize = this.getElementSize("nui-tab-headings__holder"); const maxAllowedMargin = Math.abs(tabsSize - tabHolderSize + this._traverseButtonsWidth); const margin = Math.abs(this.getNumberFromPixels(leftMargin)); return margin < maxAllowedMargin; } isTraverseRightAllowed(margin) { return this.getNumberFromPixels(margin) < 0; } getElementSize(selector) { return this.el.nativeElement.querySelector("." + selector).offsetWidth; } getNumberFromPixels(pixels) { return pixels.indexOf("px") ? Number(pixels.substring(0, pixels.indexOf("px"))) : 0; } getCurrentShift() { return this.el.nativeElement.querySelector(".nui-tab-headings__container").style.marginLeft; } setNewShift(newShift) { this.el.nativeElement.querySelector(".nui-tab-headings__container").style.marginTop = "0px"; this.el.nativeElement.querySelector(".nui-tab-headings__container").style.marginLeft = newShift; } addPixels(currentValue, increment) { const value = this.getNumberFromPixels(currentValue); return value + increment + "px"; } ngOnDestroy() { this._changesSubscription.unsubscribe(); this._tabSelectedSubscriptions.forEach((sub) => sub.unsubscribe()); this._ro.disconnect(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TabHeadingGroupComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TabHeadingGroupComponent, selector: "nui-tab-heading-group", inputs: { vertical: "vertical" }, outputs: { selected: "selected" }, host: { attributes: { "role": "tablist" }, properties: { "class.vertical": "this.isVertical" } }, queries: [{ propertyName: "_tabs", predicate: TabHeadingComponent }], viewQueries: [{ propertyName: "resizableArea", first: true, predicate: ["resizableArea"], descendants: true }], ngImport: i0, template: "<div class=\"nui-tab-headings__holder\" (click)=\"$event.preventDefault()\">\n <div\n class=\"btn-caret-left\"\n [class.disabled]=\"!rightTraverseEnabled\"\n *ngIf=\"hasTraverse\"\n (click)=\"traverseRight()\"\n >\n <nui-icon\n iconSize=\"default\"\n icon=\"caret-left\"\n [iconColor]=\"!rightTraverseEnabled ? 'disabled-gray' : 'gray'\"\n ></nui-icon>\n </div>\n <div class=\"nui-tab-headings\">\n <div\n class=\"nui-tab-headings__container\"\n #resizableArea\n [class.flex-column]=\"vertical\"\n >\n <ng-content></ng-content>\n </div>\n </div>\n <div\n class=\"btn-caret-right\"\n [class.disabled]=\"!leftTraverseEnabled\"\n *ngIf=\"hasTraverse\"\n (click)=\"traverseLeft()\"\n >\n <nui-icon\n iconSize=\"default\"\n icon=\"caret-right\"\n [iconColor]=\"!leftTraverseEnabled ? 'disabled-gray' : 'gray'\"\n ></nui-icon>\n </div>\n</div>\n", styles: [":host{display:flex;height:100%}:host .nui-tab-headings{display:flex;justify-content:flex-start;margin-bottom:0;overflow:hidden}:host .nui-tab-headings__holder{display:flex;border-bottom:1px solid #d9d9d9;border-bottom:1px solid var(--nui-color-line-default, #d9d9d9);width:100%}:host .nui-tab-headings__holder .btn-caret-right{align-items:center;justify-content:center;display:flex;flex:1;background:var(--nui-color-bg-content,#fff);min-width:40px;max-width:40px;min-height:40px;z-index:0;border-bottom:none;cursor:pointer;border-left:1px solid;border-left-color:var(--nui-color-line-default,#d9d9d9);box-shadow:-6px 0 5px -5px var(--nui-shadow-color, rgba(17, 17, 17, .3))}:host .nui-tab-headings__holder .btn-caret-right.disabled{cursor:auto}:host .nui-tab-headings__holder .btn-caret-left{border-right:1px solid;border-right-color:var(--nui-color-line-default,#d9d9d9);box-shadow:6px 0 5px -5px var(--nui-shadow-color, rgba(17, 17, 17, .3));align-items:center;justify-content:center;display:flex;flex:1;background:var(--nui-color-bg-content,#fff);min-width:40px;max-width:40px;min-height:40px;z-index:0;border-bottom:none;cursor:pointer}:host .nui-tab-headings__holder .btn-caret-left.disabled{cursor:auto}:host .nui-tab-headings__container{display:flex}.caret-button{align-items:center;justify-content:center;display:flex;flex:1;background:var(--nui-color-bg-content,#fff);min-width:40px;max-width:40px;min-height:40px;z-index:0;border-bottom:none;cursor:pointer}.caret-button.disabled{cursor:auto}:host-context(nui-tab-heading-group.vertical) .nui-tab-headings__holder{flex-direction:column;border-right:1px solid;border-right-color:var(--nui-color-line-default,#d9d9d9);border-bottom:0;background:var(--nui-color-bg-secondary,#fafafa)}:host-context(nui-tab-heading-group.vertical) .nui-tab-headings__container{width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.IconComponent, selector: "nui-icon", inputs: ["iconColor", "brushType", "iconHoverColor", "iconSize", "cssClass", "fillContainer", "status", "childStatus", "icon", "counter"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TabHeadingGroupComponent, decorators: [{ type: Component, args: [{ selector: "nui-tab-heading-group", changeDetection: ChangeDetectionStrategy.OnPush, host: { role: "tablist" }, template: "<div class=\"nui-tab-headings__holder\" (click)=\"$event.preventDefault()\">\n <div\n class=\"btn-caret-left\"\n [class.disabled]=\"!rightTraverseEnabled\"\n *ngIf=\"hasTraverse\"\n (click)=\"traverseRight()\"\n >\n <nui-icon\n iconSize=\"default\"\n icon=\"caret-left\"\n [iconColor]=\"!rightTraverseEnabled ? 'disabled-gray' : 'gray'\"\n ></nui-icon>\n </div>\n <div class=\"nui-tab-headings\">\n <div\n class=\"nui-tab-headings__container\"\n #resizableArea\n [class.flex-column]=\"vertical\"\n >\n <ng-content></ng-content>\n </div>\n </div>\n <div\n class=\"btn-caret-right\"\n [class.disabled]=\"!leftTraverseEnabled\"\n *ngIf=\"hasTraverse\"\n (click)=\"traverseLeft()\"\n >\n <nui-icon\n iconSize=\"default\"\n icon=\"caret-right\"\n [iconColor]=\"!leftTraverseEnabled ? 'disabled-gray' : 'gray'\"\n ></nui-icon>\n </div>\n</div>\n", styles: [":host{display:flex;height:100%}:host .nui-tab-headings{display:flex;justify-content:flex-start;margin-bottom:0;overflow:hidden}:host .nui-tab-headings__holder{display:flex;border-bottom:1px solid #d9d9d9;border-bottom:1px solid var(--nui-color-line-default, #d9d9d9);width:100%}:host .nui-tab-headings__holder .btn-caret-right{align-items:center;justify-content:center;display:flex;flex:1;background:var(--nui-color-bg-content,#fff);min-width:40px;max-width:40px;min-height:40px;z-index:0;border-bottom:none;cursor:pointer;border-left:1px solid;border-left-color:var(--nui-color-line-default,#d9d9d9);box-shadow:-6px 0 5px -5px var(--nui-shadow-color, rgba(17, 17, 17, .3))}:host .nui-tab-headings__holder .btn-caret-right.disabled{cursor:auto}:host .nui-tab-headings__holder .btn-caret-left{border-right:1px solid;border-right-color:var(--nui-color-line-default,#d9d9d9);box-shadow:6px 0 5px -5px var(--nui-shadow-color, rgba(17, 17, 17, .3));align-items:center;justify-content:center;display:flex;flex:1;background:var(--nui-color-bg-content,#fff);min-width:40px;max-width:40px;min-height:40px;z-index:0;border-bottom:none;cursor:pointer}:host .nui-tab-headings__holder .btn-caret-left.disabled{cursor:auto}:host .nui-tab-headings__container{display:flex}.caret-button{align-items:center;justify-content:center;display:flex;flex:1;background:var(--nui-color-bg-content,#fff);min-width:40px;max-width:40px;min-height:40px;z-index:0;border-bottom:none;cursor:pointer}.caret-button.disabled{cursor:auto}:host-context(nui-tab-heading-group.vertical) .nui-tab-headings__holder{flex-direction:column;border-right:1px solid;border-right-color:var(--nui-color-line-default,#d9d9d9);border-bottom:0;background:var(--nui-color-bg-secondary,#fafafa)}:host-context(nui-tab-heading-group.vertical) .nui-tab-headings__container{width:100%}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }], propDecorators: { _tabs: [{ type: ContentChildren, args: [TabHeadingComponent] }], resizableArea: [{ type: ViewChild, args: ["resizableArea"] }], vertical: [{ type: Input }], selected: [{ type: Output }], isVertical: [{ type: HostBinding, args: ["class.vertical"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWhlYWRpbmctZ3JvdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi90YWJncm91cC90YWItaGVhZGluZy1ncm91cC90YWItaGVhZGluZy1ncm91cC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RhYmdyb3VwL3RhYi1oZWFkaW5nLWdyb3VwL3RhYi1oZWFkaW5nLWdyb3VwLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQUVqQixPQUFPLEVBRUgsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osV0FBVyxFQUNYLEtBQUssRUFDTCxNQUFNLEVBRU4sTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7Ozs7QUFFM0UsZ0VBQWdFO0FBUWhFLE1BQU0sT0FBTyx3QkFBd0I7SUFhakMsSUFBbUMsVUFBVTtRQUN6QyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDekIsQ0FBQztJQVlELFlBQ1ksRUFBYyxFQUNkLGlCQUFvQyxFQUNwQyxNQUFjO1FBRmQsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNkLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FB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QUN6QyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7b0lBR2EsS0FBSztzQkFBMUMsZUFBZTt1QkFBQyxtQkFBbUI7Z0JBRVIsYUFBYTtzQkFBeEMsU0FBUzt1QkFBQyxlQUFlO2dCQUdWLFFBQVE7c0JBQXZCLEtBQUs7Z0JBS0ksUUFBUTtzQkFBakIsTUFBTTtnQkFFNEIsVUFBVTtzQkFBNUMsV0FBVzt1QkFBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyIvLyDCqSAyMDIyIFNvbGFyV2luZHMgV29ybGR3aWRlLCBMTEMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4vLyAgZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vICByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSW5wdXQsXG4gICAgTmdab25lLFxuICAgIE9uRGVzdHJveSxcbiAgICBPdXRwdXQsXG4gICAgUXVlcnlMaXN0LFxuICAgIFZpZXdDaGlsZCxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XG5cbmltcG9ydCB7IFRhYkhlYWRpbmdDb21wb25lbnQgfSBmcm9tIFwiLi4vdGFiLWhlYWRpbmcvdGFiLWhlYWRpbmcuY29tcG9uZW50XCI7XG5cbi8vIDxleGFtcGxlLXVybD4uLy4uL2V4YW1wbGVzL2luZGV4Lmh0bWwjL3RhYmdyb3VwPC9leGFtcGxlLXVybD5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiBcIm51aS10YWItaGVhZGluZy1ncm91cFwiLFxuICAgIHRlbXBsYXRlVXJsOiBcIi4vdGFiLWhlYWRpbmctZ3JvdXAuY29tcG9uZW50Lmh0bWxcIixcbiAgICBzdHlsZVVybHM6IFtcIi4vdGFiLWhlYWRpbmctZ3JvdXAuY29tcG9uZW50Lmxlc3NcIl0sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgaG9zdDogeyByb2xlOiBcInRhYmxpc3RcIiB9LFxufSlcbmV4cG9ydCBjbGFzcyBUYWJIZWFkaW5nR3JvdXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuICAgIEBDb250ZW50Q2hpbGRyZW4oVGFiSGVhZGluZ0NvbXBvbmVudCkgX3RhYnM6IFF1ZXJ5TGlzdDxUYWJIZWFkaW5nQ29tcG9uZW50PjtcblxuICAgIEBWaWV3Q2hpbGQoXCJyZXNpemFibGVBcmVhXCIpIHJlc2l6YWJsZUFyZWE6IEVsZW1lbnRSZWY7XG5cbiAgICAvKiogSWYgdHJ1ZSB0YWJzIHdpbGwgYmUgcGxhY2VkIHZlcnRpY2FsbHkgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdmVydGljYWw6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBpZCBvZiBzZWxlY3RlZCB0YWJcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgc2VsZWN0ZWQ6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgQEhvc3RCaW5kaW5nKFwiY2xhc3MudmVydGljYWxcIikgZ2V0IGlzVmVydGljYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnZlcnRpY2FsO1xuICAgIH1cblxuICAgIHB1YmxpYyBsZWZ0VHJhdmVyc2VFbmFibGVkID0gdHJ1ZTtcbiAgICBwdWJsaWMgcmlnaHRUcmF2ZXJzZUVuYWJsZWQgPSBmYWxzZTtcbiAgICBwdWJsaWMgaGFzVHJhdmVyc2UgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgX3RyYXZlcnNlQnV0dG9uc1dpZHRoID0gNjA7XG4gICAgcHJpdmF0ZSBfdHJhdmVyc2VTdGVwU2l6ZSA9IDUwO1xuICAgIHByaXZhdGUgX3JvOiBSZXNpemVPYnNlcnZlcjtcbiAgICBwcml2YXRlIF90YWJTZWxlY3RlZFN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG4gICAgcHJpdmF0ZSBfY2hhbmdlc1N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXG4gICAgICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICBwcml2YXRlIG5nWm9uZTogTmdab25lXG4gICAgKSB7fVxuXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgLy8gT2JzZXJ2aW5nIHRoZSBzaXplIG9mIHRoZSBjb21wb25lbnQgdG8gY2hlY2sgdHJhdmVyc2VcbiAgICAgICAgdGhpcy5fcm8gPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKGVudHJpZXMpID0+XG4gICAgICAgICAgICBlbnRyaWVzLmZvckVhY2goKCkgPT4gdGhpcy5jaGVja1RyYXZlcnNlKCkpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3JvLm9ic2VydmUodGhpcy5yZXNpemFibGVBcmVhLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICAgICAgdGhpcy5fcm8ub2JzZXJ2ZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNYWtpbmcgdGhlIGZpcnN0IHRhYiBpbiBncm91cCBhY3RpdmUgYnkgZGVmYXVsdFxuICAgICAgICB0aGlzLnNldEFjdGl2ZVRhYigpO1xuICAgICAgICB0aGlzLnN1YnNjcmliZVRvU2VsZWN0aW9uKCk7XG5cbiAgICAgICAgdGhpcy5fY2hhbmdlc1N1YnNjcmlwdGlvbiA9IHRoaXMuX3RhYnMuY2hhbmdlcy5zdWJzY3JpYmUoXG4gICAgICAgICAgICAoY2hhbmdlZFRhYnM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0QWN0aXZlVGFiKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGFiU2VsZWN0ZWRTdWJzY3JpcHRpb25zLmZvckVhY2goKHN1YikgPT5cbiAgICAgICAgICAgICAgICAgICAgc3ViLnVuc3Vic2NyaWJlKClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuX3RhYlNlbGVjdGVkU3Vic2NyaXB0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Vic2NyaWJlVG9TZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0QWN0aXZlVGFiKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5fdGFicy5sZW5ndGggJiYgIXRoaXMuZ2V0QWN0aXZlVGFiKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3RhYnMuZmlyc3QuYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWQuZW1pdCh0aGlzLl90YWJzLmZpcnN0LnRhYklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRBY3RpdmVUYWIoKTogVGFiSGVhZGluZ0NvbXBvbmVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLl90YWJzLmZpbHRlcigodGFiOiBUYWJIZWFkaW5nQ29tcG9uZW50KSA9PiB0YWIuYWN0aXZlKVswXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY2hlY2tUcmF2ZXJzZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5oYXNUcmF2ZXJzZSA9IHRoaXMuYWxsb3dUcmF2ZXJzZSgpO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgaWYgKCF0aGlzLmhhc1RyYXZlcnNlKSB7XG4gICAgICAgICAgICB0aGlzLnNldE5ld1NoaWZ0KFwiMHB4XCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGFsbG93VHJhdmVyc2UoKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGhvbGRlclNpemUgPSB0aGlzLmdldEVsZW1lbnRTaXplKFwibnVpLXRhYi1oZWFkaW5nc19faG9sZGVyXCIpO1xuICAgICAgICBjb25zdCBjb250ZW50U2l6ZSA9IHRoaXMuZ2V0RWxlbWVudFNpemUoXCJudWktdGFiLWhlYWRpbmdzX19jb250YWluZXJcIik7XG4gICAgICAgIGlmICh0aGlzLnZlcnRpY2FsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhvbGRlclNpemUgKyB0aGlzLl90cmF2ZXJzZUJ1dHRvbnNXaWR0aCA8PSBjb250ZW50U2l6ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdHJhdmVyc2VSaWdodCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbWFyZ2luID0gdGhpcy5nZXRDdXJyZW50U2hpZnQoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNUcmF2ZXJzZVJpZ2h0QWxsb3dlZChtYXJnaW4pKSB7XG4gICAgICAgICAgICBjb25zdCB0cmF2ZXJzZVN0ZXAgPVxuICAgICAgICAgICAgICAgIE1hdGguYWJzKHRoaXMuZ2V0TnVtYmVyRnJvbVBpeGVscyhtYXJnaW4pKSA8XG4gICAgICAgICAgICAgICAgdGhpcy5fdHJhdmVyc2VTdGVwU2l6ZVxuICAgICAgICAgICAgICAgICAgICA/IE1hdGguYWJzKHRoaXMuZ2V0TnVtYmVyRnJvbVBpeGVscyhtYXJnaW4pKVxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX3RyYXZlcnNlU3RlcFNpemU7XG4gICAgICAgICAgICB0aGlzLnNldE5ld1NoaWZ0KHRoaXMuYWRkUGl4ZWxzKG1hcmdpbiwgdHJhdmVyc2VTdGVwKSk7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0VHJhdmVyc2VFbmFibGVkID0gdGhpcy5pc1RyYXZlcnNlUmlnaHRBbGxvd2VkKFxuICAgICAgICAgICAgICAgIHRoaXMuYWRkUGl4ZWxzKG1hcmdpbiwgdHJhdmVyc2VTdGVwKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubGVmdFRyYXZlcnNlRW5hYmxlZCA9IHRoaXMuaXNUcmF2ZXJzZUxlZnRBbGxvd2VkKFxuICAgICAgICAgICAgICAgIHRoaXMuYWRkUGl4ZWxzKG1hcmdpbiwgdHJhdmVyc2VTdGVwKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyB0cmF2ZXJzZUxlZnQoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hcmdpbiA9IHRoaXMuZ2V0Q3VycmVudFNoaWZ0KCk7XG4gICAgICAgIGlmICh0aGlzLmlzVHJhdmVyc2VMZWZ0QWxsb3dlZChtYXJnaW4pKSB7XG4gICAgICAgICAgICBjb25zdCB0YWJzU2l6ZSA9IHRoaXMuZ2V0RWxlbWVudFNpemUoXCJudWktdGFiLWhlYWRpbmdzX19jb250YWluZXJcIik7XG4gICAgICAgICAgICBjb25zdCB0YWJIb2xkZXJTaXplID0gdGhpcy5nZXRFbGVtZW50U2l6ZShcbiAgICAgICAgICAgICAgICBcIm51aS10YWItaGVhZGluZ3NfX2hvbGRlclwiXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgbWF4QWxsb3dlZE1hcmdpbiA9IE1hdGguYWJzKFxuICAgICAgICAgICAgICAgIHRhYnNTaXplIC0gdGFiSG9sZGVyU2l6ZSArIHRoaXMuX3RyYXZlcnNlQnV0dG9uc1dpZHRoXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgbGVmdE1hcmdpblZhbHVlID0gTWF0aC5hYnModGhpcy5nZXROdW1iZXJGcm9tUGl4ZWxzKG1hcmdpbikpO1xuICAgICAgICAgICAgY29uc3QgdHJhdmVyc2VTdGVwID0gTWF0aC5taW4oXG4gICAgICAgICAgICAgICAgbWF4QWxsb3dlZE1hcmdpbiAtIGxlZnRNYXJnaW5WYWx1ZSxcbiAgICAgICAgICAgICAgICB0aGlzLl90cmF2ZXJzZVN0ZXBTaXplXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5zZXROZXdTaGlmdCh0aGlzLmFkZFBpeGVscyhtYXJnaW4sIC10cmF2ZXJzZVN0ZXApKTtcbiAgICAgICAgICAgIHRoaXMucmlnaHRUcmF2ZXJzZUVuYWJsZWQgPSB0aGlzLmlzVHJhdmVyc2VSaWdodEFsbG93ZWQoXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQaXhlbHMobWFyZ2luLCAtdHJhdmVyc2VTdGVwKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubGVmdFRyYXZlcnNlRW5hYmxlZCA9IHRoaXMuaXNUcmF2ZXJzZUxlZnRBbGxvd2VkKFxuICAgICAgICAgICAgICAgIHRoaXMuYWRkUGl4ZWxzKG1hcmdpbiwgLXRyYXZlcnNlU3RlcClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTdWJzY3JpYmluZyB0byBhbGwgdGFicyBhbmQgdGhlaXIgJ3NlbGVjdGVkJyBldmVudC4gT25jZSB0aGUgZXZlbnQgaGFzIGJlZW4gZmlyZWQgdGhlIG9yaWdpbiB0YWIgYmVjb21lcyBhY3RpdmUuXG4gICAgcHJpdmF0ZSBzdWJzY3JpYmVUb1NlbGVjdGlvbigpIHtcbiAgICAgICAgdGhpcy5fdGFicy5mb3JFYWNoKCh0YWI6IFRhYkhlYWRpbmdDb21wb25lbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3RhYlNlbGVjdGVkU3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICAgICAgICAgIHRhYi5zZWxlY3RlZC5zdWJzY3JpYmUoKGN1cnJlbnRUYWI6IFRhYkhlYWRpbmdDb21wb25lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJyZW50VGFiLmFjdGl2ZSAmJiAhY3VycmVudFRhYi5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFraW5nIGFsbCBlbGVtZW50cyBpbiBhcnJheSBpbmFjdGl2ZSB0byBtYWtlIHRoYW4gY3VycmVudCBvbmUgYWN0aXZlXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90YWJzLmZvckVhY2goXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRhYkhlYWRpbmc6IFRhYkhlYWRpbmdDb21wb25lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFiSGVhZGluZy5hY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFRhYi5hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZC5lbWl0KGN1cnJlbnRUYWIudGFiSWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNUcmF2ZXJzZUxlZnRBbGxvd2VkKGxlZnRNYXJnaW46IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB0YWJzU2l6ZSA9IHRoaXMuZ2V0RWxlbWVudFNpemUoXCJudWktdGFiLWhlYWRpbmdzX19jb250YWluZXJcIik7XG4gICAgICAgIGNvbnN0IHRhYkhvbGRlclNpemUgPSB0aGlzLmdldEVsZW1lbnRTaXplKFwibnVpLXRhYi1oZWFkaW5nc19faG9sZGVyXCIpO1xuICAgICAgICBjb25zdCBtYXhBbGxvd2VkTWFyZ2luID0gTWF0aC5hYnMoXG4gICAgICAgICAgICB0YWJzU2l6ZSAtIHRhYkhvbGRlclNpemUgKyB0aGlzLl90cmF2ZXJzZUJ1dHRvbnNXaWR0aFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IG1hcmdpbiA9IE1hdGguYWJzKHRoaXMuZ2V0TnVtYmVyRnJvbVBpeGVscyhsZWZ0TWFyZ2luKSk7XG4gICAgICAgIHJldHVybiBtYXJnaW4gPCBtYXhBbGxvd2VkTWFyZ2luO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNUcmF2ZXJzZVJpZ2h0QWxsb3dlZChtYXJnaW46IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXJGcm9tUGl4ZWxzKG1hcmdpbikgPCAwO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RWxlbWVudFNpemUoc2VsZWN0b3I6IHN0cmluZyk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcIi5cIiArIHNlbGVjdG9yKS5vZmZzZXRXaWR0aDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldE51bWJlckZyb21QaXhlbHMocGl4ZWxzOiBzdHJpbmcpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gcGl4ZWxzLmluZGV4T2YoXCJweFwiKVxuICAgICAgICAgICAgPyBOdW1iZXIocGl4ZWxzLnN1YnN0cmluZygwLCBwaXhlbHMuaW5kZXhPZihcInB4XCIpKSlcbiAgICAgICAgICAgIDogMDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEN1cnJlbnRTaGlmdCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICBcIi5udWktdGFiLWhlYWRpbmdzX19jb250YWluZXJcIlxuICAgICAgICApLnN0eWxlLm1hcmdpbkxlZnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXROZXdTaGlmdChuZXdTaGlmdDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICAgXCIubnVpLXRhYi1oZWFkaW5nc19fY29udGFpbmVyXCJcbiAgICAgICAgKS5zdHlsZS5tYXJnaW5Ub3AgPSBcIjBweFwiO1xuICAgICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAgIFwiLm51aS10YWItaGVhZGluZ3NfX2NvbnRhaW5lclwiXG4gICAgICAgICkuc3R5bGUubWFyZ2luTGVmdCA9IG5ld1NoaWZ0O1xuICAgIH1cblxuICAgIHByaXZhdGUgYWRkUGl4ZWxzKGN1cnJlbnRWYWx1ZTogc3RyaW5nLCBpbmNyZW1lbnQ6IG51bWJlcik6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXROdW1iZXJGcm9tUGl4ZWxzKGN1cnJlbnRWYWx1ZSk7XG4gICAgICAgIHJldHVybiB2YWx1ZSArIGluY3JlbWVudCArIFwicHhcIjtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2NoYW5nZXNTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5fdGFiU2VsZWN0ZWRTdWJzY3JpcHRpb25zLmZvckVhY2goKHN1YikgPT4gc3ViLnVuc3Vic2NyaWJlKCkpO1xuICAgICAgICB0aGlzLl9yby5kaXNjb25uZWN0KCk7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm51aS10YWItaGVhZGluZ3NfX2hvbGRlclwiIChjbGljayk9XCIkZXZlbnQucHJldmVudERlZmF1bHQoKVwiPlxuICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJidG4tY2FyZXQtbGVmdFwiXG4gICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCIhcmlnaHRUcmF2ZXJzZUVuYWJsZWRcIlxuICAgICAgICAqbmdJZj1cImhhc1RyYXZlcnNlXCJcbiAgICAgICAgKGNsaWNrKT1cInRyYXZlcnNlUmlnaHQoKVwiXG4gICAgPlxuICAgICAgICA8bnVpLWljb25cbiAgICAgICAgICAgIGljb25TaXplPVwiZGVmYXVsdFwiXG4gICAgICAgICAgICBpY29uPVwiY2FyZXQtbGVmdFwiXG4gICAgICAgICAgICBbaWNvbkNvbG9yXT1cIiFyaWdodFRyYXZlcnNlRW5hYmxlZCA/ICdkaXNhYmxlZC1ncmF5JyA6ICdncmF5J1wiXG4gICAgICAgID48L251aS1pY29uPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJudWktdGFiLWhlYWRpbmdzXCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwibnVpLXRhYi1oZWFkaW5nc19fY29udGFpbmVyXCJcbiAgICAgICAgICAgICNyZXNpemFibGVBcmVhXG4gICAgICAgICAgICBbY2xhc3MuZmxleC1jb2x1bW5dPVwidmVydGljYWxcIlxuICAgICAgICA+XG4gICAgICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJidG4tY2FyZXQtcmlnaHRcIlxuICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwiIWxlZnRUcmF2ZXJzZUVuYWJsZWRcIlxuICAgICAgICAqbmdJZj1cImhhc1RyYXZlcnNlXCJcbiAgICAgICAgKGNsaWNrKT1cInRyYXZlcnNlTGVmdCgpXCJcbiAgICA+XG4gICAgICAgIDxudWktaWNvblxuICAgICAgICAgICAgaWNvblNpemU9XCJkZWZhdWx0XCJcbiAgICAgICAgICAgIGljb249XCJjYXJldC1yaWdodFwiXG4gICAgICAgICAgICBbaWNvbkNvbG9yXT1cIiFsZWZ0VHJhdmVyc2VFbmFibGVkID8gJ2Rpc2FibGVkLWdyYXknIDogJ2dyYXknXCJcbiAgICAgICAgPjwvbnVpLWljb24+XG4gICAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==