UNPKG

@nova-ui/bits

Version:

SolarWinds Nova Framework

147 lines 36.8 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 { ChangeDetectorRef, Component, ElementRef, Input, ViewEncapsulation, } from "@angular/core"; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "../../icon/icon.component"; import * as i3 from "../tab/tab-heading-custom-template-ref.directive"; // <example-url>./../examples/index.html#/tabgroup</example-url> /** @ignore */ export class TabGroupComponent { /** If true tabs will be placed vertically */ get vertical() { return Boolean(this._vertical); } set vertical(value) { this._vertical = value; } constructor(el, changeDetectorRef) { this.el = el; this.changeDetectorRef = changeDetectorRef; this.tabs = []; this.leftTraverseEnabled = true; this.rightTraverseEnabled = false; this.hasTraverse = false; this.traverseButtonsWidth = 60; this.traverseStepSize = 50; } ngAfterViewInit() { this.checkTraverse(); } checkTraverse() { this.hasTraverse = this.allowTraverse(); this.changeDetectorRef.detectChanges(); if (!this.hasTraverse) { this.setNewShift("0px"); } } addTab(tab) { this.tabs.push(tab); tab.active = this.tabs.length === 1 && typeof tab.active === "undefined"; } selectTab(selectedTab) { if (!selectedTab.disabled) { selectedTab.active = true; this.tabs.forEach((tab) => { if (tab !== selectedTab) { tab.active = false; } }); } } allowTraverse() { const holderSize = this.getElementSize("nui-tabs__holder"); const contentSize = this.getElementSize("nui-tabs__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-tabs__container"); const tabHolderSize = this.getElementSize("nui-tabs__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)); } } isTraverseLeftAllowed(leftMargin) { const tabsSize = this.getElementSize("nui-tabs__container"); const tabHolderSize = this.getElementSize("nui-tabs__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-tabs__container").style .marginLeft; } setNewShift(newShift) { this.el.nativeElement.querySelector(".nui-tabs__container").style.marginTop = "0px"; this.el.nativeElement.querySelector(".nui-tabs__container").style.marginLeft = newShift; } addPixels(currentValue, increment) { const value = this.getNumberFromPixels(currentValue); return value + increment + "px"; } ngOnDestroy() { this.isDestroyed = true; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TabGroupComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TabGroupComponent, selector: "nui-tab-group", inputs: { vertical: "vertical" }, host: { listeners: { "window:resize": "checkTraverse()" } }, ngImport: i0, template: "<div class=\"nui-tabgroup\" [class.flex-column]=\"!vertical\">\n <div\n class=\"nui-tabs__holder\"\n [class.vertical]=\"vertical\"\n (click)=\"$event.preventDefault()\"\n >\n <div\n class=\"btn-caret-left\"\n [class.disabled]=\"!rightTraverseEnabled\"\n *ngIf=\"hasTraverse\"\n (click)=\"traverseRight()\"\n >\n <nui-icon\n [icon]=\"'caret-left'\"\n [iconColor]=\"!rightTraverseEnabled ? 'gray' : 'default'\"\n ></nui-icon>\n </div>\n <div class=\"nui-tabs\">\n <div class=\"nui-tabs__container\" [class.flex-column]=\"vertical\">\n <ng-container *ngFor=\"let tab of tabs\">\n <div\n class=\"nui-tab\"\n [class.active]=\"tab.active && !vertical\"\n [class.horizontal]=\"tab.active && !vertical\"\n [class.disabled]=\"tab.disabled\"\n [class.active__vertical]=\"tab.active && vertical\"\n >\n <span class=\"tab-link\" (click)=\"selectTab(tab)\">\n <span\n [nuiTabHeadingCustomTemplateRef]=\"\n tab.headingRef\n \"\n >{{ tab.heading }}</span\n >\n </span>\n </div>\n </ng-container>\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 [icon]=\"'caret-right'\"\n [iconColor]=\"!leftTraverseEnabled ? 'gray' : 'default'\"\n ></nui-icon>\n </div>\n </div>\n <div class=\"nui-tabgroup__content\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".nui-tabgroup{display:flex;height:100%}.nui-tabgroup .nui-tabs{display:flex;justify-content:flex-start;margin-bottom:0;overflow:hidden}.nui-tabgroup .nui-tabs__holder{display:flex;border-bottom:1px solid #d9d9d9;border-bottom:1px solid var(--nui-color-line-default, #d9d9d9);flex-direction:row;background-color:var(--nui-color-bg-content,#fff)}.nui-tabgroup .nui-tabs__holder.vertical{border-right:1px solid #d9d9d9;border-right:1px solid var(--nui-color-line-default, #d9d9d9);border-bottom:0!important;margin-right:5px;margin-bottom:5px}.nui-tabgroup .nui-tabs__holder .btn-caret-right{align-items:center;justify-content:center;display:flex;flex:1;background:#fff;min-width:30px;max-width:30px;min-height:20px;z-index:2;border-bottom:none;cursor:pointer;border-left:1px solid #d9d9d9;border-left:1px solid var(--nui-color-line-default, #d9d9d9);box-shadow:-2px 0 2px #d9d9d9;box-shadow:-2px 0 2px var(--nui-color-line-default, #d9d9d9)}.nui-tabgroup .nui-tabs__holder .btn-caret-right.disabled{cursor:auto}.nui-tabgroup .nui-tabs__holder .btn-caret-left{align-items:center;justify-content:center;display:flex;flex:1;background:#fff;min-width:30px;max-width:30px;min-height:20px;z-index:2;border-bottom:none;cursor:pointer;border-right:1px solid #d9d9d9;border-right:1px solid var(--nui-color-line-default, #d9d9d9);box-shadow:2px 0 2px #d9d9d9;box-shadow:2px 0 2px var(--nui-color-line-default, #d9d9d9)}.nui-tabgroup .nui-tabs__holder .btn-caret-left.disabled{cursor:auto}.nui-tabgroup .nui-tabs__container{display:flex}.nui-tabgroup .nui-tabs__container .nui-tab{margin-bottom:-1px;white-space:nowrap}.nui-tabgroup .nui-tabs__container .nui-tab.horizontal{border-left:none}.nui-tabgroup .nui-tabs__container .nui-tab.active{border-bottom:3px solid #00c4d2;border-bottom:3px solid var(--nui-color-selected-contrast, #00c4d2)}.nui-tabgroup .nui-tabs__container .nui-tab.active>.tab-link{color:var(--nui-color-text-default,#111);background-color:var(--nui-color-bg-transparent,transparent)}.nui-tabgroup .nui-tabs__container .nui-tab.active__vertical{border-left:3px solid #00c4d2;border-left:3px solid var(--nui-color-selected-contrast, #00c4d2)}.nui-tabgroup .nui-tabs__container .nui-tab.disabled>.tab-link{cursor:not-allowed;color:var(--nui-color-text-disabled,rgba(17, 17, 17, .3))}.nui-tabgroup .nui-tabs__container .nui-tab.disabled>.tab-link:hover{background:transparent}.nui-tabgroup .nui-tabs__container .nui-tab:hover{background:var(--nui-color-bg-light-hover,#f2f2f2)}.nui-tabgroup .nui-tabs__container .nui-tab .tab-link{display:block;padding:5px 10px;cursor:pointer;text-transform:uppercase;font-size:13px;font-weight:600;line-height:18px;color:var(--nui-color-text-secondary,rgba(17, 17, 17, .6))}.nui-tabgroup .nui-tabs__container .nui-tab .tab-link:hover{background:var(--nui-color-bg-light-hover,#f2f2f2)}.nui-tabgroup__content,.full-width{width:100%}.flex-column{flex-direction:column}.caret-button{align-items:center;justify-content:center;display:flex;flex:1;background:#fff;min-width:30px;max-width:30px;min-height:20px;z-index:2;border-bottom:none;cursor:pointer}.caret-button.disabled{cursor:auto}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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"] }, { kind: "directive", type: i3.TabHeadingCustomTemplateRefDirective, selector: "[nuiTabHeadingCustomTemplateRef]", inputs: ["nuiTabHeadingCustomTemplateRef"] }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TabGroupComponent, decorators: [{ type: Component, args: [{ selector: "nui-tab-group", host: { "(window:resize)": "checkTraverse()", }, encapsulation: ViewEncapsulation.None, template: "<div class=\"nui-tabgroup\" [class.flex-column]=\"!vertical\">\n <div\n class=\"nui-tabs__holder\"\n [class.vertical]=\"vertical\"\n (click)=\"$event.preventDefault()\"\n >\n <div\n class=\"btn-caret-left\"\n [class.disabled]=\"!rightTraverseEnabled\"\n *ngIf=\"hasTraverse\"\n (click)=\"traverseRight()\"\n >\n <nui-icon\n [icon]=\"'caret-left'\"\n [iconColor]=\"!rightTraverseEnabled ? 'gray' : 'default'\"\n ></nui-icon>\n </div>\n <div class=\"nui-tabs\">\n <div class=\"nui-tabs__container\" [class.flex-column]=\"vertical\">\n <ng-container *ngFor=\"let tab of tabs\">\n <div\n class=\"nui-tab\"\n [class.active]=\"tab.active && !vertical\"\n [class.horizontal]=\"tab.active && !vertical\"\n [class.disabled]=\"tab.disabled\"\n [class.active__vertical]=\"tab.active && vertical\"\n >\n <span class=\"tab-link\" (click)=\"selectTab(tab)\">\n <span\n [nuiTabHeadingCustomTemplateRef]=\"\n tab.headingRef\n \"\n >{{ tab.heading }}</span\n >\n </span>\n </div>\n </ng-container>\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 [icon]=\"'caret-right'\"\n [iconColor]=\"!leftTraverseEnabled ? 'gray' : 'default'\"\n ></nui-icon>\n </div>\n </div>\n <div class=\"nui-tabgroup__content\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".nui-tabgroup{display:flex;height:100%}.nui-tabgroup .nui-tabs{display:flex;justify-content:flex-start;margin-bottom:0;overflow:hidden}.nui-tabgroup .nui-tabs__holder{display:flex;border-bottom:1px solid #d9d9d9;border-bottom:1px solid var(--nui-color-line-default, #d9d9d9);flex-direction:row;background-color:var(--nui-color-bg-content,#fff)}.nui-tabgroup .nui-tabs__holder.vertical{border-right:1px solid #d9d9d9;border-right:1px solid var(--nui-color-line-default, #d9d9d9);border-bottom:0!important;margin-right:5px;margin-bottom:5px}.nui-tabgroup .nui-tabs__holder .btn-caret-right{align-items:center;justify-content:center;display:flex;flex:1;background:#fff;min-width:30px;max-width:30px;min-height:20px;z-index:2;border-bottom:none;cursor:pointer;border-left:1px solid #d9d9d9;border-left:1px solid var(--nui-color-line-default, #d9d9d9);box-shadow:-2px 0 2px #d9d9d9;box-shadow:-2px 0 2px var(--nui-color-line-default, #d9d9d9)}.nui-tabgroup .nui-tabs__holder .btn-caret-right.disabled{cursor:auto}.nui-tabgroup .nui-tabs__holder .btn-caret-left{align-items:center;justify-content:center;display:flex;flex:1;background:#fff;min-width:30px;max-width:30px;min-height:20px;z-index:2;border-bottom:none;cursor:pointer;border-right:1px solid #d9d9d9;border-right:1px solid var(--nui-color-line-default, #d9d9d9);box-shadow:2px 0 2px #d9d9d9;box-shadow:2px 0 2px var(--nui-color-line-default, #d9d9d9)}.nui-tabgroup .nui-tabs__holder .btn-caret-left.disabled{cursor:auto}.nui-tabgroup .nui-tabs__container{display:flex}.nui-tabgroup .nui-tabs__container .nui-tab{margin-bottom:-1px;white-space:nowrap}.nui-tabgroup .nui-tabs__container .nui-tab.horizontal{border-left:none}.nui-tabgroup .nui-tabs__container .nui-tab.active{border-bottom:3px solid #00c4d2;border-bottom:3px solid var(--nui-color-selected-contrast, #00c4d2)}.nui-tabgroup .nui-tabs__container .nui-tab.active>.tab-link{color:var(--nui-color-text-default,#111);background-color:var(--nui-color-bg-transparent,transparent)}.nui-tabgroup .nui-tabs__container .nui-tab.active__vertical{border-left:3px solid #00c4d2;border-left:3px solid var(--nui-color-selected-contrast, #00c4d2)}.nui-tabgroup .nui-tabs__container .nui-tab.disabled>.tab-link{cursor:not-allowed;color:var(--nui-color-text-disabled,rgba(17, 17, 17, .3))}.nui-tabgroup .nui-tabs__container .nui-tab.disabled>.tab-link:hover{background:transparent}.nui-tabgroup .nui-tabs__container .nui-tab:hover{background:var(--nui-color-bg-light-hover,#f2f2f2)}.nui-tabgroup .nui-tabs__container .nui-tab .tab-link{display:block;padding:5px 10px;cursor:pointer;text-transform:uppercase;font-size:13px;font-weight:600;line-height:18px;color:var(--nui-color-text-secondary,rgba(17, 17, 17, .6))}.nui-tabgroup .nui-tabs__container .nui-tab .tab-link:hover{background:var(--nui-color-bg-light-hover,#f2f2f2)}.nui-tabgroup__content,.full-width{width:100%}.flex-column{flex-direction:column}.caret-button{align-items:center;justify-content:center;display:flex;flex:1;background:#fff;min-width:30px;max-width:30px;min-height:20px;z-index:2;border-bottom:none;cursor:pointer}.caret-button.disabled{cursor:auto}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { vertical: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWdyb3VwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdGFiZ3JvdXAvdGFiLWdyb3VwL3RhYi1ncm91cC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RhYmdyb3VwL3RhYi1ncm91cC90YWItZ3JvdXAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFFSCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixLQUFLLEVBRUwsaUJBQWlCLEdBQ3BCLE1BQU0sZUFBZSxDQUFDOzs7OztBQUl2QixnRUFBZ0U7QUFDaEUsY0FBYztBQVVkLE1BQU0sT0FBTyxpQkFBaUI7SUFDMUIsNkNBQTZDO0lBQzdDLElBQ0ksUUFBUTtRQUNSLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsSUFBSSxRQUFRLENBQUMsS0FBYztRQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUMzQixDQUFDO0lBYUQsWUFDWSxFQUFjLEVBQ2QsaUJBQW9DO1FBRHBDLE9BQUUsR0FBRixFQUFFLENBQVk7UUFDZCxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBYnpDLFNBQUksR0FBbUIsRUFBRSxDQUFDO1FBQzFCLHdCQUFtQixHQUFHLElBQUksQ0FB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RCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDckQsT0FBTyxLQUFLLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQztJQUNwQyxDQUFDO0lBRU0sV0FBVztRQUNkLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQzVCLENBQUM7K0dBeEpRLGlCQUFpQjttR0FBakIsaUJBQWlCLG9KQzNDOUIsa2pFQXVEQTs7NEZEWmEsaUJBQWlCO2tCQVQ3QixTQUFTOytCQUNJLGVBQWUsUUFFbkI7d0JBQ0YsaUJBQWlCLEVBQUUsaUJBQWlCO3FCQUN2QyxpQkFFYyxpQkFBaUIsQ0FBQyxJQUFJOytHQUtqQyxRQUFRO3NCQURYLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvLyDCqSAyMDIyIFNvbGFyV2luZHMgV29ybGR3aWRlLCBMTEMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4vLyAgZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vICByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcblxuaW1wb3J0IHsgVGFiQ29tcG9uZW50IH0gZnJvbSBcIi4uL3RhYi90YWIuY29tcG9uZW50XCI7XG5cbi8vIDxleGFtcGxlLXVybD4uLy4uL2V4YW1wbGVzL2luZGV4Lmh0bWwjL3RhYmdyb3VwPC9leGFtcGxlLXVybD5cbi8qKiBAaWdub3JlICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogXCJudWktdGFiLWdyb3VwXCIsXG4gICAgdGVtcGxhdGVVcmw6IFwiLi90YWItZ3JvdXAuY29tcG9uZW50Lmh0bWxcIixcbiAgICBob3N0OiB7XG4gICAgICAgIFwiKHdpbmRvdzpyZXNpemUpXCI6IFwiY2hlY2tUcmF2ZXJzZSgpXCIsXG4gICAgfSxcbiAgICBzdHlsZVVybHM6IFtcIi4vdGFiLWdyb3VwLmNvbXBvbmVudC5sZXNzXCJdLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuZXhwb3J0IGNsYXNzIFRhYkdyb3VwQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcbiAgICAvKiogSWYgdHJ1ZSB0YWJzIHdpbGwgYmUgcGxhY2VkIHZlcnRpY2FsbHkgKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCB2ZXJ0aWNhbCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4odGhpcy5fdmVydGljYWwpO1xuICAgIH1cblxuICAgIHNldCB2ZXJ0aWNhbCh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl92ZXJ0aWNhbCA9IHZhbHVlO1xuICAgIH1cblxuICAgIHB1YmxpYyB0YWJzOiBUYWJDb21wb25lbnRbXSA9IFtdO1xuICAgIHB1YmxpYyBsZWZ0VHJhdmVyc2VFbmFibGVkID0gdHJ1ZTtcbiAgICBwdWJsaWMgcmlnaHRUcmF2ZXJzZUVuYWJsZWQgPSBmYWxzZTtcbiAgICBwdWJsaWMgaGFzVHJhdmVyc2UgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgdHJhdmVyc2VCdXR0b25zV2lkdGggPSA2MDtcbiAgICBwcml2YXRlIHRyYXZlcnNlU3RlcFNpemUgPSA1MDtcblxuICAgIHByb3RlY3RlZCBpc0Rlc3Ryb3llZDogYm9vbGVhbjtcbiAgICBwcm90ZWN0ZWQgX3ZlcnRpY2FsOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXG4gICAgICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmXG4gICAgKSB7fVxuXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jaGVja1RyYXZlcnNlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNoZWNrVHJhdmVyc2UoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaGFzVHJhdmVyc2UgPSB0aGlzLmFsbG93VHJhdmVyc2UoKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIGlmICghdGhpcy5oYXNUcmF2ZXJzZSkge1xuICAgICAgICAgICAgdGhpcy5zZXROZXdTaGlmdChcIjBweFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhZGRUYWIodGFiOiBUYWJDb21wb25lbnQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50YWJzLnB1c2godGFiKTtcbiAgICAgICAgdGFiLmFjdGl2ZSA9XG4gICAgICAgICAgICB0aGlzLnRhYnMubGVuZ3RoID09PSAxICYmIHR5cGVvZiB0YWIuYWN0aXZlID09PSBcInVuZGVmaW5lZFwiO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZWxlY3RUYWIoc2VsZWN0ZWRUYWI6IFRhYkNvbXBvbmVudCk6IHZvaWQge1xuICAgICAgICBpZiAoIXNlbGVjdGVkVGFiLmRpc2FibGVkKSB7XG4gICAgICAgICAgICBzZWxlY3RlZFRhYi5hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy50YWJzLmZvckVhY2goKHRhYjogVGFiQ29tcG9uZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRhYiAhPT0gc2VsZWN0ZWRUYWIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFiLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGFsbG93VHJhdmVyc2UoKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGhvbGRlclNpemUgPSB0aGlzLmdldEVsZW1lbnRTaXplKFwibnVpLXRhYnNfX2hvbGRlclwiKTtcbiAgICAgICAgY29uc3QgY29udGVudFNpemUgPSB0aGlzLmdldEVsZW1lbnRTaXplKFwibnVpLXRhYnNfX2NvbnRhaW5lclwiKTtcbiAgICAgICAgaWYgKHRoaXMudmVydGljYWwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaG9sZGVyU2l6ZSArIHRoaXMudHJhdmVyc2VCdXR0b25zV2lkdGggPD0gY29udGVudFNpemU7XG4gICAgfVxuXG4gICAgcHVibGljIHRyYXZlcnNlUmlnaHQoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1hcmdpbiA9IHRoaXMuZ2V0Q3VycmVudFNoaWZ0KCk7XG4gICAgICAgIGlmICh0aGlzLmlzVHJhdmVyc2VSaWdodEFsbG93ZWQobWFyZ2luKSkge1xuICAgICAgICAgICAgY29uc3QgdHJhdmVyc2VTdGVwID1cbiAgICAgICAgICAgICAgICBNYXRoLmFicyh0aGlzLmdldE51bWJlckZyb21QaXhlbHMobWFyZ2luKSkgPFxuICAgICAgICAgICAgICAgIHRoaXMudHJhdmVyc2VTdGVwU2l6ZVxuICAgICAgICAgICAgICAgICAgICA/IE1hdGguYWJzKHRoaXMuZ2V0TnVtYmVyRnJvbVBpeGVscyhtYXJnaW4pKVxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMudHJhdmVyc2VTdGVwU2l6ZTtcbiAgICAgICAgICAgIHRoaXMuc2V0TmV3U2hpZnQodGhpcy5hZGRQaXhlbHMobWFyZ2luLCB0cmF2ZXJzZVN0ZXApKTtcbiAgICAgICAgICAgIHRoaXMucmlnaHRUcmF2ZXJzZUVuYWJsZWQgPSB0aGlzLmlzVHJhdmVyc2VSaWdodEFsbG93ZWQoXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQaXhlbHMobWFyZ2luLCB0cmF2ZXJzZVN0ZXApXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5sZWZ0VHJhdmVyc2VFbmFibGVkID0gdGhpcy5pc1RyYXZlcnNlTGVmdEFsbG93ZWQoXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQaXhlbHMobWFyZ2luLCB0cmF2ZXJzZVN0ZXApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHRyYXZlcnNlTGVmdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbWFyZ2luID0gdGhpcy5nZXRDdXJyZW50U2hpZnQoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNUcmF2ZXJzZUxlZnRBbGxvd2VkKG1hcmdpbikpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhYnNTaXplID0gdGhpcy5nZXRFbGVtZW50U2l6ZShcIm51aS10YWJzX19jb250YWluZXJcIik7XG4gICAgICAgICAgICBjb25zdCB0YWJIb2xkZXJTaXplID0gdGhpcy5nZXRFbGVtZW50U2l6ZShcIm51aS10YWJzX19ob2xkZXJcIik7XG4gICAgICAgICAgICBjb25zdCBtYXhBbGxvd2VkTWFyZ2luID0gTWF0aC5hYnMoXG4gICAgICAgICAgICAgICAgdGFic1NpemUgLSB0YWJIb2xkZXJTaXplICsgdGhpcy50cmF2ZXJzZUJ1dHRvbnNXaWR0aFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGxlZnRNYXJnaW5WYWx1ZSA9IE1hdGguYWJzKHRoaXMuZ2V0TnVtYmVyRnJvbVBpeGVscyhtYXJnaW4pKTtcbiAgICAgICAgICAgIGNvbnN0IHRyYXZlcnNlU3RlcCA9IE1hdGgubWluKFxuICAgICAgICAgICAgICAgIG1heEFsbG93ZWRNYXJnaW4gLSBsZWZ0TWFyZ2luVmFsdWUsXG4gICAgICAgICAgICAgICAgdGhpcy50cmF2ZXJzZVN0ZXBTaXplXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5zZXROZXdTaGlmdCh0aGlzLmFkZFBpeGVscyhtYXJnaW4sIC10cmF2ZXJzZVN0ZXApKTtcbiAgICAgICAgICAgIHRoaXMucmlnaHRUcmF2ZXJzZUVuYWJsZWQgPSB0aGlzLmlzVHJhdmVyc2VSaWdodEFsbG93ZWQoXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQaXhlbHMobWFyZ2luLCAtdHJhdmVyc2VTdGVwKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubGVmdFRyYXZlcnNlRW5hYmxlZCA9IHRoaXMuaXNUcmF2ZXJzZUxlZnRBbGxvd2VkKFxuICAgICAgICAgICAgICAgIHRoaXMuYWRkUGl4ZWxzKG1hcmdpbiwgLXRyYXZlcnNlU3RlcClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzVHJhdmVyc2VMZWZ0QWxsb3dlZChsZWZ0TWFyZ2luOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdGFic1NpemUgPSB0aGlzLmdldEVsZW1lbnRTaXplKFwibnVpLXRhYnNfX2NvbnRhaW5lclwiKTtcbiAgICAgICAgY29uc3QgdGFiSG9sZGVyU2l6ZSA9IHRoaXMuZ2V0RWxlbWVudFNpemUoXCJudWktdGFic19faG9sZGVyXCIpO1xuICAgICAgICBjb25zdCBtYXhBbGxvd2VkTWFyZ2luID0gTWF0aC5hYnMoXG4gICAgICAgICAgICB0YWJzU2l6ZSAtIHRhYkhvbGRlclNpemUgKyB0aGlzLnRyYXZlcnNlQnV0dG9uc1dpZHRoXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgbWFyZ2luID0gTWF0aC5hYnModGhpcy5nZXROdW1iZXJGcm9tUGl4ZWxzKGxlZnRNYXJnaW4pKTtcbiAgICAgICAgcmV0dXJuIG1hcmdpbiA8IG1heEFsbG93ZWRNYXJnaW47XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1RyYXZlcnNlUmlnaHRBbGxvd2VkKG1hcmdpbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE51bWJlckZyb21QaXhlbHMobWFyZ2luKSA8IDA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRFbGVtZW50U2l6ZShzZWxlY3Rvcjogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiLlwiICsgc2VsZWN0b3IpLm9mZnNldFdpZHRoO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0TnVtYmVyRnJvbVBpeGVscyhwaXhlbHM6IHN0cmluZyk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBwaXhlbHMuaW5kZXhPZihcInB4XCIpXG4gICAgICAgICAgICA/IE51bWJlcihwaXhlbHMuc3Vic3RyaW5nKDAsIHBpeGVscy5pbmRleE9mKFwicHhcIikpKVxuICAgICAgICAgICAgOiAwO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q3VycmVudFNoaWZ0KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcIi5udWktdGFic19fY29udGFpbmVyXCIpLnN0eWxlXG4gICAgICAgICAgICAubWFyZ2luTGVmdDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldE5ld1NoaWZ0KG5ld1NoaWZ0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICBcIi5udWktdGFic19fY29udGFpbmVyXCJcbiAgICAgICAgKS5zdHlsZS5tYXJnaW5Ub3AgPSBcIjBweFwiO1xuICAgICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAgIFwiLm51aS10YWJzX19jb250YWluZXJcIlxuICAgICAgICApLnN0eWxlLm1hcmdpbkxlZnQgPSBuZXdTaGlmdDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFkZFBpeGVscyhjdXJyZW50VmFsdWU6IHN0cmluZywgaW5jcmVtZW50OiBudW1iZXIpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0TnVtYmVyRnJvbVBpeGVscyhjdXJyZW50VmFsdWUpO1xuICAgICAgICByZXR1cm4gdmFsdWUgKyBpbmNyZW1lbnQgKyBcInB4XCI7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmlzRGVzdHJveWVkID0gdHJ1ZTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibnVpLXRhYmdyb3VwXCIgW2NsYXNzLmZsZXgtY29sdW1uXT1cIiF2ZXJ0aWNhbFwiPlxuICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJudWktdGFic19faG9sZGVyXCJcbiAgICAgICAgW2NsYXNzLnZlcnRpY2FsXT1cInZlcnRpY2FsXCJcbiAgICAgICAgKGNsaWNrKT1cIiRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCJcbiAgICA+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwiYnRuLWNhcmV0LWxlZnRcIlxuICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cIiFyaWdodFRyYXZlcnNlRW5hYmxlZFwiXG4gICAgICAgICAgICAqbmdJZj1cImhhc1RyYXZlcnNlXCJcbiAgICAgICAgICAgIChjbGljayk9XCJ0cmF2ZXJzZVJpZ2h0KClcIlxuICAgICAgICA+XG4gICAgICAgICAgICA8bnVpLWljb25cbiAgICAgICAgICAgICAgICBbaWNvbl09XCInY2FyZXQtbGVmdCdcIlxuICAgICAgICAgICAgICAgIFtpY29uQ29sb3JdPVwiIXJpZ2h0VHJhdmVyc2VFbmFibGVkID8gJ2dyYXknIDogJ2RlZmF1bHQnXCJcbiAgICAgICAgICAgID48L251aS1pY29uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm51aS10YWJzXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibnVpLXRhYnNfX2NvbnRhaW5lclwiIFtjbGFzcy5mbGV4LWNvbHVtbl09XCJ2ZXJ0aWNhbFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHRhYiBvZiB0YWJzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibnVpLXRhYlwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cInRhYi5hY3RpdmUgJiYgIXZlcnRpY2FsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5ob3Jpem9udGFsXT1cInRhYi5hY3RpdmUgJiYgIXZlcnRpY2FsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCJ0YWIuZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV9fdmVydGljYWxdPVwidGFiLmFjdGl2ZSAmJiB2ZXJ0aWNhbFwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGFiLWxpbmtcIiAoY2xpY2spPVwic2VsZWN0VGFiKHRhYilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbnVpVGFiSGVhZGluZ0N1c3RvbVRlbXBsYXRlUmVmXT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFiLmhlYWRpbmdSZWZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPnt7IHRhYi5oZWFkaW5nIH19PC9zcGFuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJidG4tY2FyZXQtcmlnaHRcIlxuICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cIiFsZWZ0VHJhdmVyc2VFbmFibGVkXCJcbiAgICAgICAgICAgICpuZ0lmPVwiaGFzVHJhdmVyc2VcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInRyYXZlcnNlTGVmdCgpXCJcbiAgICAgICAgPlxuICAgICAgICAgICAgPG51aS1pY29uXG4gICAgICAgICAgICAgICAgW2ljb25dPVwiJ2NhcmV0LXJpZ2h0J1wiXG4gICAgICAgICAgICAgICAgW2ljb25Db2xvcl09XCIhbGVmdFRyYXZlcnNlRW5hYmxlZCA/ICdncmF5JyA6ICdkZWZhdWx0J1wiXG4gICAgICAgICAgICA+PC9udWktaWNvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm51aS10YWJncm91cF9fY29udGVudFwiPlxuICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==