@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
292 lines • 38.7 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Component, ElementRef, EventEmitter, Inject, Injector, Input, Optional, Output, ViewChild } from '@angular/core';
import { Debounce } from '@microsoft/windows-admin-center-sdk/core/base/decorators/debounce.decorators';
import { Yield } from '@microsoft/windows-admin-center-sdk/core/base/decorators/yield.decorator';
import { CoreBaseComponent } from '../common/base.component';
import { SME_LAYOUT_PROVIDER } from '../common/layout';
import { DetailsResponsiveWindowManager } from './details-responsive-window-manager';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
const _c0 = ["expander"];
const _c1 = function (a0, a1) { return { "sme-icon-chevronUpMed": a0, "sme-icon-chevronDownMed": a1 }; };
function DetailsComponent_span_5_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "span", 8);
} if (rf & 2) {
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵstyleProp("order", ctx_r1.chevronPosition);
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c1, !ctx_r1.isExpanded, ctx_r1.isExpanded));
} }
function DetailsComponent_span_6_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "span", 8);
} if (rf & 2) {
const ctx_r2 = i0.ɵɵnextContext();
i0.ɵɵstyleProp("order", ctx_r2.chevronPosition);
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c1, ctx_r2.isExpanded, !ctx_r2.isExpanded));
} }
function DetailsComponent_hr_12_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "hr");
} }
const _c2 = function (a0, a1) { return { "sme-layout-absolute-phone-up sme-position-inset-none sme-padding-bottom-sm sme-arrange-overflow-auto": a0, "sme-layout-relative sme-position-stretch-v": a1 }; };
const _c3 = ["*"];
/**
*
* @smeDoc {@label Details @id sme-details}
*
* @overview
* @file {@filepath ./examples/details-overview.md}
*
* @example {@label Basic Usage @id basic-usage}
* @file {@filename component.ts @filepath ./examples/details-example.component.ts}
* @file {@filename component.html @filepath ./examples/details-example.component.html}
*
*/
export var ChevronPosition;
(function (ChevronPosition) {
ChevronPosition["Left"] = "-1";
ChevronPosition["Right"] = "0";
})(ChevronPosition || (ChevronPosition = {}));
export class DetailsComponent extends CoreBaseComponent {
constructor(injector, layout) {
super(injector);
this.resourceStrings = MsftSme.getStrings().MsftSmeShell.Angular.Details;
/**
* The detail component's height will be determined on the whole children's height.
*/
this.autoHeight = false;
this.isExpandedChange = new EventEmitter();
this.layoutChanged = new EventEmitter();
this.initialHeightPercentage = 30;
if (layout) {
this.detailsResponsiveWindowManager = new DetailsResponsiveWindowManager(layout);
// on parent layout changes, re-emit the layout change to our event
this.subscriptions.push(layout.layoutChanged.subscribe((() => this.onLayoutChanged())));
// on window break point changes, emit the event about critical classes and styling updates signal.
this.subscriptions.push(layout.windowBreakpointChanged.subscribe(() => this.onWindowBreakpointChanged()));
this.deferredOnLayoutChanged();
}
}
get minExpanderHeight() {
return this.detailsResponsiveWindowManager.minExpanderHeight;
}
get shouldContentSlim() {
return this.detailsResponsiveWindowManager.shouldContentSlim;
}
/**
* The source name to use for logging
*/
get logSourceName() {
return 'DetailsComponent';
}
/**
* @deprecated since 02/25/2019. Please use 'header' instead
*/
set title(value) {
this.header = value;
}
get title() {
return this.header;
}
ngOnChanges(changes) {
super.ngOnChanges(changes);
if (changes.isExpanded) {
this.onLayoutChanged();
}
}
toggleExpansion() {
this.isExpanded = !this.isExpanded;
this.isExpandedChange.emit(this.isExpanded);
this.onLayoutChanged();
}
refresh() {
this.onLayoutChanged();
}
/**
* The on window breakpoint changed handler.
* Adding yield for component to get ElementRef after initialization.
*/
onWindowBreakpointChanged() {
this.detailsResponsiveWindowManager.onWindowSizeChanged(this.hostElement?.nativeElement);
}
/**
* The deferred layout changed handler.
*/
deferredOnLayoutChanged() {
this.onLayoutChanged();
}
/**
* The layout changed event handler.
*/
onLayoutChanged() {
if (!this.hostElement || !this.hostElement.nativeElement) {
return;
}
const expanderOffsetHeight = MsftSme.getValue(this.expander, 'nativeElement.offsetHeight') || 0;
const expanderHeight = expanderOffsetHeight > 0 ? `{0}px`.format(expanderOffsetHeight) : this.minExpanderHeight;
if (!this.isExpanded) {
this.hostElement.nativeElement.style.height = expanderHeight;
this.hostElement.nativeElement.style.minHeight = '';
return;
}
let potentialHeight = this.hostElement.nativeElement.offsetParent.offsetHeight || 0;
const parentOffsetTop = this.hostElement.nativeElement.offsetParent.offsetTop || 0;
const totalHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
const detailContentHeight = this.detailsResponsiveWindowManager.detailContentHeight;
// Enforces a max height when setting the default height.
const maxHeight = detailContentHeight.max;
const minHeight = detailContentHeight.min;
const phoneDown = detailContentHeight.phoneDown;
// On small window height, the detail pane height would be the smaller value [window height * 0.6, maxHeight]
if (phoneDown) {
potentialHeight = Math.min(totalHeight - parentOffsetTop, potentialHeight);
// Prevents the initial size exceed max height
potentialHeight = Math.min(potentialHeight, maxHeight);
potentialHeight = Math.max(potentialHeight, minHeight);
const portHeight = window.innerHeight;
if (portHeight < minHeight) {
potentialHeight = minHeight;
}
else if (portHeight > minHeight && portHeight < maxHeight) {
// Math.ceil can make calculation without rounding issues.
potentialHeight = Math.ceil(portHeight * 0.6);
}
else if (portHeight > maxHeight && portHeight * 0.4 > maxHeight) {
potentialHeight = Math.ceil(maxHeight);
}
else if (portHeight > maxHeight && portHeight * 0.4 > minHeight) {
potentialHeight = Math.ceil(portHeight * 0.4);
}
this.hostElement.nativeElement.style.height = '';
}
else {
// Shrink only if exceeds parents offset height;
if (potentialHeight > this.hostElement.nativeElement.offsetParent.offsetHeight) {
// Set initial expanded height to 30vh.
// Poor design that needs to re-visit.
const oneVh = totalHeight / 100;
potentialHeight = oneVh * this.initialHeightPercentage;
}
else {
// sme-border-top-sm on the details resizer border.
// minus the border height to get rid of the extra scroll bar.
potentialHeight -= 1;
}
potentialHeight = Math.min(potentialHeight, maxHeight);
potentialHeight = Math.max(potentialHeight, minHeight);
this.hostElement.nativeElement.style.minHeight = '';
if (!this.autoHeight) {
this.hostElement.nativeElement.style.height = `{0}px`.format(potentialHeight);
}
else {
this.hostElement.nativeElement.style.height = '';
}
}
setTimeout(() => {
// the height would be changed on window height or width change
// re-calculate the potential height should be notifying parents.
this.layoutChanged.emit();
});
}
getInitialHostClasses() {
return super.getInitialHostClasses().concat([
'sme-arrange-stack-v'
]);
}
createIdBag() {
return {
detailsSpan: ''
};
}
}
/** @nocollapse */ DetailsComponent.ɵfac = function DetailsComponent_Factory(t) { return new (t || DetailsComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(SME_LAYOUT_PROVIDER, 8)); };
/** @nocollapse */ DetailsComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: DetailsComponent, selectors: [["sme-details"]], viewQuery: function DetailsComponent_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(_c0, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.expander = _t.first);
} }, inputs: { initialHeightPercentage: "initialHeightPercentage", header: "header", chevronInverted: "chevronInverted", chevronPosition: "chevronPosition", addBottomBorder: "addBottomBorder", autoHeight: "autoHeight", title: "title", isExpanded: "isExpanded" }, outputs: { isExpandedChange: "isExpandedChange" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c3, decls: 13, vars: 20, consts: [["role", "button", "tabindex", "0", 1, "sme-button", "sme-button-trigger", "sme-button-auto-width", "sme-position-flex-none", "sme-padding-squish-v-md", "sme-padding-horizontal-lg", "sme-position-stretch-h", "sme-position-left-inline", "sme-arrange-stack-h", "sme-focus-zone", 3, "click"], ["expander", ""], [1, "sme-font-h3", "sme-position-flex-auto", "sme-arrange-ellipsis"], ["class", "sme-icon sme-position-flex-none sme-margin-horizontal-xs", "aria-hidden", "true", 3, "order", "ngClass", 4, "ngIf"], [1, "sme-screen-reader", 3, "id"], [1, "sme-position-flex-auto", "sme-layout-relative"], [3, "ngClass"], [4, "ngIf"], ["aria-hidden", "true", 1, "sme-icon", "sme-position-flex-none", "sme-margin-horizontal-xs", 3, "ngClass"]], template: function DetailsComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef();
i0.ɵɵelementStart(0, "h3")(1, "div", 0, 1);
i0.ɵɵlistener("click", function DetailsComponent_Template_div_click_1_listener() { return ctx.toggleExpansion(); });
i0.ɵɵelementStart(3, "span", 2);
i0.ɵɵtext(4);
i0.ɵɵelementEnd();
i0.ɵɵtemplate(5, DetailsComponent_span_5_Template, 1, 6, "span", 3);
i0.ɵɵtemplate(6, DetailsComponent_span_6_Template, 1, 6, "span", 3);
i0.ɵɵelementStart(7, "div", 4);
i0.ɵɵtext(8);
i0.ɵɵelementEnd()()();
i0.ɵɵelementStart(9, "div", 5)(10, "div", 6);
i0.ɵɵprojection(11);
i0.ɵɵelementEnd()();
i0.ɵɵtemplate(12, DetailsComponent_hr_12_Template, 1, 0, "hr", 7);
} if (rf & 2) {
i0.ɵɵadvance(1);
i0.ɵɵstyleProp("min-height", ctx.minExpanderHeight);
i0.ɵɵattribute("aria-expanded", !!ctx.isExpanded)("aria-describedBy", ctx.idBag.detailsSpan);
i0.ɵɵadvance(3);
i0.ɵɵtextInterpolate(ctx.header);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", !ctx.chevronInverted);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.chevronInverted);
i0.ɵɵadvance(1);
i0.ɵɵproperty("id", ctx.idBag.detailsSpan);
i0.ɵɵadvance(1);
i0.ɵɵtextInterpolate1(" ", ctx.resourceStrings.AriaDescription, "");
i0.ɵɵadvance(1);
i0.ɵɵclassProp("sme-margin-horizontal-lg", ctx.shouldContentSlim)("sme-position-stretch-v", ctx.autoHeight);
i0.ɵɵadvance(1);
i0.ɵɵclassProp("sme-layout-none", !ctx.isExpanded);
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(17, _c2, !ctx.autoHeight, ctx.autoHeight));
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", ctx.addBottomBorder);
} }, dependencies: [i1.NgClass, i1.NgIf], encapsulation: 2 });
__decorate([
Yield(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], DetailsComponent.prototype, "onWindowBreakpointChanged", null);
__decorate([
Debounce(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], DetailsComponent.prototype, "deferredOnLayoutChanged", null);
__decorate([
Yield(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], DetailsComponent.prototype, "onLayoutChanged", null);
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DetailsComponent, [{
type: Component,
args: [{ selector: 'sme-details', template: "<h3>\r\n <div #expander\r\n class=\"sme-button sme-button-trigger sme-button-auto-width sme-position-flex-none sme-padding-squish-v-md sme-padding-horizontal-lg sme-position-stretch-h sme-position-left-inline sme-arrange-stack-h sme-focus-zone\"\r\n role=\"button\" tabindex=\"0\" (click)=\"toggleExpansion()\" [style.min-height]=\"minExpanderHeight\"\r\n [attr.aria-expanded]=\"!!isExpanded\" [attr.aria-describedBy]=\"idBag.detailsSpan\">\r\n <span class=\"sme-font-h3 sme-position-flex-auto sme-arrange-ellipsis\">{{ header }}</span>\r\n <span [style.order]=\"chevronPosition\" *ngIf=\"!chevronInverted\" class=\"sme-icon sme-position-flex-none sme-margin-horizontal-xs\"\r\n [ngClass]=\"{'sme-icon-chevronUpMed': !isExpanded, 'sme-icon-chevronDownMed': isExpanded}\"\r\n aria-hidden=\"true\"></span>\r\n <span [style.order]=\"chevronPosition\" *ngIf=\"chevronInverted\" class=\"sme-icon sme-position-flex-none sme-margin-horizontal-xs\"\r\n [ngClass]=\"{'sme-icon-chevronUpMed': isExpanded, 'sme-icon-chevronDownMed': !isExpanded}\"\r\n aria-hidden=\"true\"></span>\r\n <div class=\"sme-screen-reader\" [id]=\"idBag.detailsSpan\"> {{ resourceStrings.AriaDescription }}</div>\r\n </div>\r\n</h3>\r\n\r\n<div class=\"sme-position-flex-auto sme-layout-relative\" [class.sme-margin-horizontal-lg]=\"shouldContentSlim\" [class.sme-position-stretch-v]=\"autoHeight\">\r\n <div [ngClass]=\"{'sme-layout-absolute-phone-up sme-position-inset-none sme-padding-bottom-sm sme-arrange-overflow-auto': !autoHeight, 'sme-layout-relative sme-position-stretch-v': autoHeight}\"\r\n [class.sme-layout-none]=\"!isExpanded\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n\r\n<hr *ngIf=\"addBottomBorder\">\r\n" }]
}], function () { return [{ type: i0.Injector }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [SME_LAYOUT_PROVIDER]
}] }]; }, { expander: [{
type: ViewChild,
args: ['expander']
}], initialHeightPercentage: [{
type: Input
}], header: [{
type: Input
}], chevronInverted: [{
type: Input
}], chevronPosition: [{
type: Input
}], addBottomBorder: [{
type: Input
}], autoHeight: [{
type: Input
}], title: [{
type: Input
}], isExpanded: [{
type: Input
}], isExpandedChange: [{
type: Output
}], onWindowBreakpointChanged: [], deferredOnLayoutChanged: [], onLayoutChanged: [] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV0YWlscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9hbmd1bGFyL3NyYy9jb250cm9scy9kZXRhaWxzL2RldGFpbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvZGV0YWlscy9kZXRhaWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0gsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLFFBQVEsRUFDUixLQUFLLEVBRUwsUUFBUSxFQUNSLE1BQU0sRUFFTixTQUFTLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDhFQUE4RSxDQUFDO0FBQ3hHLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSwwRUFBMEUsQ0FBQztBQUVqRyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RCxPQUFPLEVBQVUsbUJBQW1CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7Ozs7O0lDWmpGLDBCQUU0Qjs7O0lBRnRCLCtDQUErQjtJQUNuQywyRkFBeUY7OztJQUUzRiwwQkFFNEI7OztJQUZ0QiwrQ0FBK0I7SUFDbkMsMkZBQXlGOzs7SUFhL0YscUJBQTRCOzs7O0FESDVCOzs7Ozs7Ozs7OztHQVdHO0FBRUgsTUFBTSxDQUFOLElBQVksZUFHWDtBQUhELFdBQVksZUFBZTtJQUN2Qiw4QkFBVyxDQUFBO0lBQ1gsOEJBQVcsQ0FBQTtBQUNmLENBQUMsRUFIVyxlQUFlLEtBQWYsZUFBZSxRQUcxQjtBQUtELE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxpQkFBaUI7SUFnRW5ELFlBQVksUUFBa0IsRUFBMkMsTUFBYztRQUNuRixLQUFL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LEVBQUE7UUFHUixpRUFBNEI7O1FBcEIrQixlQUFzQztRQUF0QyxtREFBc0M7UUFDN0YsaURBQW1DLDJDQUFBO1FBQ21DLGVBQVk7UUFBWixnQ0FBWTtRQUMzQyxlQUFzQjtRQUF0QiwyQ0FBc0I7UUFHdEIsZUFBcUI7UUFBckIsMENBQXFCO1FBRzdCLGVBQXdCO1FBQXhCLDBDQUF3QjtRQUFFLGVBQXFDO1FBQXJDLG1FQUFxQztRQUkxQyxlQUFvRDtRQUFwRCxpRUFBb0QsMENBQUE7UUFFeEcsZUFBcUM7UUFBckMsa0RBQXFDO1FBRGxDLHNGQUEyTDtRQU03TCxlQUFxQjtRQUFyQiwwQ0FBcUI7O0FEcUh0QjtJQUFDLEtBQUssRUFBRTs7OztpRUFHUDtBQUtEO0lBQUMsUUFBUSxFQUFFOzs7OytEQUdWO0FBS0Q7SUFBQyxLQUFLLEVBQUU7Ozs7dURBMkVQO3VGQTlMUSxnQkFBZ0I7Y0FKNUIsU0FBUzsyQkFDSSxhQUFhOztzQkFtRVUsUUFBUTs7c0JBQUksTUFBTTt1QkFBQyxtQkFBbUI7d0JBN0NoRSxRQUFRO2tCQURkLFNBQVM7bUJBQUMsVUFBVTtZQUlkLHVCQUF1QjtrQkFEN0IsS0FBSztZQUlDLE1BQU07a0JBRFosS0FBSztZQUlDLGVBQWU7a0JBRHJCLEtBQUs7WUFJQyxlQUFlO2tCQURyQixLQUFLO1lBSUMsZUFBZTtrQkFEckIsS0FBSztZQU9DLFVBQVU7a0JBRGhCLEtBQUs7WUFPSyxLQUFLO2tCQURmLEtBQUs7WUFVQyxVQUFVO2tCQURoQixLQUFLO1lBSUMsZ0JBQWdCO2tCQUR0QixNQUFNO1lBMkNBLHlCQUF5QixNQVF4Qix1QkFBdUIsTUFRdkIsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgICBDb21wb25lbnQsXHJcbiAgICBFbGVtZW50UmVmLFxyXG4gICAgRXZlbnRFbWl0dGVyLFxyXG4gICAgSW5qZWN0LFxyXG4gICAgSW5qZWN0b3IsXHJcbiAgICBJbnB1dCxcclxuICAgIE9uQ2hhbmdlcyxcclxuICAgIE9wdGlvbmFsLFxyXG4gICAgT3V0cHV0LFxyXG4gICAgU2ltcGxlQ2hhbmdlcyxcclxuICAgIFZpZXdDaGlsZFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEZWJvdW5jZSB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvYmFzZS9kZWNvcmF0b3JzL2RlYm91bmNlLmRlY29yYXRvcnMnO1xyXG5pbXBvcnQgeyBZaWVsZCB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvYmFzZS9kZWNvcmF0b3JzL3lpZWxkLmRlY29yYXRvcic7XHJcbmltcG9ydCB7IFN0cmluZ3MgfSBmcm9tICcuLi8uLi9nZW5lcmF0ZWQvc3RyaW5ncyc7XHJcbmltcG9ydCB7IENvcmVCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tbW9uL2Jhc2UuY29tcG9uZW50JztcclxuaW1wb3J0IHsgTGF5b3V0LCBTTUVfTEFZT1VUX1BST1ZJREVSIH0gZnJvbSAnLi4vY29tbW9uL2xheW91dCc7XHJcbmltcG9ydCB7IERldGFpbHNSZXNwb25zaXZlV2luZG93TWFuYWdlciB9IGZyb20gJy4vZGV0YWlscy1yZXNwb25zaXZlLXdpbmRvdy1tYW5hZ2VyJztcclxuXHJcbi8qKlxyXG4gKlxyXG4gKiBAc21lRG9jIHtAbGFiZWwgRGV0YWlscyBAaWQgc21lLWRldGFpbHN9XHJcbiAqXHJcbiAqIEBvdmVydmlld1xyXG4gKiBAZmlsZSB7QGZpbGVwYXRoIC4vZXhhbXBsZXMvZGV0YWlscy1vdmVydmlldy5tZH1cclxuICpcclxuICogQGV4YW1wbGUge0BsYWJlbCBCYXNpYyBVc2FnZSBAaWQgYmFzaWMtdXNhZ2V9XHJcbiAqIEBmaWxlIHtAZmlsZW5hbWUgY29tcG9uZW50LnRzIEBmaWxlcGF0aCAuL2V4YW1wbGVzL2RldGFpbHMtZXhhbXBsZS5jb21wb25lbnQudHN9XHJcbiAqIEBmaWxlIHtAZmlsZW5hbWUgY29tcG9uZW50Lmh0bWwgQGZpbGVwYXRoIC4vZXhhbXBsZXMvZGV0YWlscy1leGFtcGxlLmNvbXBvbmVudC5odG1sfVxyXG4gKlxyXG4gKi9cclxuXHJcbmV4cG9ydCBlbnVtIENoZXZyb25Qb3NpdGlvbiB7XHJcbiAgICBMZWZ0ID0gJy0xJyxcclxuICAgIFJpZ2h0ID0gJzAnXHJcbn1cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NtZS1kZXRhaWxzJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9kZXRhaWxzLmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRGV0YWlsc0NvbXBvbmVudCBleHRlbmRzIENvcmVCYXNlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcclxuXHJcbiAgICBwdWJsaWMgZ2V0IG1pbkV4cGFuZGVySGVpZ2h0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRldGFpbHNSZXNwb25zaXZlV2luZG93TWFuYWdlci5taW5FeHBhbmRlckhlaWdodDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IHNob3VsZENvbnRlbnRTbGltKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRldGFpbHNSZXNwb25zaXZlV2luZG93TWFuYWdlci5zaG91bGRDb250ZW50U2xpbTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzb3VyY2UgbmFtZSB0byB1c2UgZm9yIGxvZ2dpbmdcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGdldCBsb2dTb3VyY2VOYW1lKCkge1xyXG4gICAgICAgIHJldHVybiAnRGV0YWlsc0NvbXBvbmVudCc7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgcmVzb3VyY2VTdHJpbmdzID0gTXNmdFNtZS5nZXRTdHJpbmdzPFN0cmluZ3M+KCkuTXNmdFNtZVNoZWxsLkFuZ3VsYXIuRGV0YWlscztcclxuXHJcbiAgICBAVmlld0NoaWxkKCdleHBhbmRlcicpXHJcbiAgICBwdWJsaWMgZXhwYW5kZXI6IEVsZW1lbnRSZWY7XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBpbml0aWFsSGVpZ2h0UGVyY2VudGFnZTogbnVtYmVyO1xyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgaGVhZGVyOiBzdHJpbmc7XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjaGV2cm9uSW52ZXJ0ZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjaGV2cm9uUG9zaXRpb246IHN0cmluZztcclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGFkZEJvdHRvbUJvcmRlcjogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBkZXRhaWwgY29tcG9uZW50J3MgaGVpZ2h0IHdpbGwgYmUgZGV0ZXJtaW5lZCBvbiB0aGUgd2hvbGUgY2hpbGRyZW4ncyBoZWlnaHQuXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgYXV0b0hlaWdodCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlcHJlY2F0ZWQgc2luY2UgMDIvMjUvMjAxOS4gUGxlYXNlIHVzZSAnaGVhZGVyJyBpbnN0ZWFkXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2V0IHRpdGxlKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLmhlYWRlciA9IHZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgdGl0bGUoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oZWFkZXI7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBpc0V4cGFuZGVkOiBib29sZWFuO1xyXG5cclxuICAgIEBPdXRwdXQoKVxyXG4gICAgcHVibGljIGlzRXhwYW5kZWRDaGFuZ2U6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcclxuXHJcbiAgICBwdWJsaWMgbGF5b3V0Q2hhbmdlZDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAgIHByaXZhdGUgZGV0YWlsc1Jlc3BvbnNpdmVXaW5kb3dNYW5hZ2VyOiBEZXRhaWxzUmVzcG9uc2l2ZVdpbmRvd01hbmFnZXI7XHJcblxyXG4gICAgY29uc3RydWN0b3IoaW5qZWN0b3I6IEluamVjdG9yLCBAT3B0aW9uYWwoKSBASW5qZWN0KFNNRV9MQVlPVVRfUFJPVklERVIpIGxheW91dDogTGF5b3V0KSB7XHJcbiAgICAgICAgc3VwZXIoaW5qZWN0b3IpO1xyXG4gICAgICAgIHRoaXMuaW5pdGlhbEhlaWdodFBlcmNlbnRhZ2UgPSAzMDtcclxuICAgICAgICBpZiAobGF5b3V0KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGV0YWlsc1Jlc3BvbnNpdmVXaW5kb3dNYW5hZ2VyID0gbmV3IERldGFpbHNSZXNwb25zaXZlV2luZG93TWFuYWdlcihsYXlvdXQpO1xyXG4gICAgICAgICAgICAvLyBvbiBwYXJlbnQgbGF5b3V0IGNoYW5nZXMsIHJlLWVtaXQgdGhlIGxheW91dCBjaGFuZ2UgdG8gb3VyIGV2ZW50XHJcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKGxheW91dC5sYXlvdXRDaGFuZ2VkLnN1YnNjcmliZSgoKCkgPT4gdGhpcy5vbkxheW91dENoYW5nZWQoKSkpKTtcclxuICAgICAgICAgICAgLy8gb24gd2luZG93IGJyZWFrIHBvaW50IGNoYW5nZXMsIGVtaXQgdGhlIGV2ZW50IGFib3V0IGNyaXRpY2FsIGNsYXNzZXMgYW5kIHN0eWxpbmcgdXBkYXRlcyBzaWduYWwuXHJcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKGxheW91dC53aW5kb3dCcmVha3BvaW50Q2hhbmdlZC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5vbldpbmRvd0JyZWFrcG9pbnRDaGFuZ2VkKCkpKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZGVmZXJyZWRPbkxheW91dENoYW5nZWQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgICAgICBzdXBlci5uZ09uQ2hhbmdlcyhjaGFuZ2VzKTtcclxuICAgICAgICBpZiAoY2hhbmdlcy5pc0V4cGFuZGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25MYXlvdXRDaGFuZ2VkKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB0b2dnbGVFeHBhbnNpb24oKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5pc0V4cGFuZGVkID0gIXRoaXMuaXNFeHBhbmRlZDtcclxuICAgICAgICB0aGlzLmlzRXhwYW5kZWRDaGFuZ2UuZW1pdCh0aGlzLmlzRXhwYW5kZWQpO1xyXG4gICAgICAgIHRoaXMub25MYXlvdXRDaGFuZ2VkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlZnJlc2goKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5vbkxheW91dENoYW5nZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBvbiB3aW5kb3cgYnJlYWtwb2ludCBjaGFuZ2VkIGhhbmRsZXIuXHJcbiAgICAgKiBBZGRpbmcgeWllbGQgZm9yIGNvbXBvbmVudCB0byBnZXQgRWxlbWVudFJlZiBhZnRlciBpbml0aWFsaXphdGlvbi5cclxuICAgICAqL1xyXG4gICAgQFlpZWxkKClcclxuICAgIHB1YmxpYyBvbldpbmRvd0JyZWFrcG9pbnRDaGFuZ2VkKCkge1xyXG4gICAgICAgIHRoaXMuZGV0YWlsc1Jlc3BvbnNpdmVXaW5kb3dNYW5hZ2VyLm9uV2luZG93U2l6ZUNoYW5nZWQodGhpcy5ob3N0RWxlbWVudD8ubmF0aXZlRWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZGVmZXJyZWQgbGF5b3V0IGNoYW5nZWQgaGFuZGxlci5cclxuICAgICAqL1xyXG4gICAgQERlYm91bmNlKClcclxuICAgIHByaXZhdGUgZGVmZXJyZWRPbkxheW91dENoYW5nZWQoKSB7XHJcbiAgICAgICAgdGhpcy5vbkxheW91dENoYW5nZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBsYXlvdXQgY2hhbmdlZCBldmVudCBoYW5kbGVyLlxyXG4gICAgICovXHJcbiAgICBAWWllbGQoKVxyXG4gICAgcHJpdmF0ZSBvbkxheW91dENoYW5nZWQoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmhvc3RFbGVtZW50IHx8ICF0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZXhwYW5kZXJPZmZzZXRIZWlnaHQgPSBNc2Z0U21lLmdldFZhbHVlPG51bWJlcj4odGhpcy5leHBhbmRlciwgJ25hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0JykgfHwgMDtcclxuICAgICAgICBjb25zdCBleHBhbmRlckhlaWdodCA9IGV4cGFuZGVyT2Zmc2V0SGVpZ2h0ID4gMCA/IGB7MH1weGAuZm9ybWF0KGV4cGFuZGVyT2Zmc2V0SGVpZ2h0KSA6IHRoaXMubWluRXhwYW5kZXJIZWlnaHQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLmlzRXhwYW5kZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5ob3N0RWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IGV4cGFuZGVySGVpZ2h0O1xyXG4gICAgICAgICAgICB0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuc3R5bGUubWluSGVpZ2h0ID0gJyc7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBwb3RlbnRpYWxIZWlnaHQgPSB0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0UGFyZW50Lm9mZnNldEhlaWdodCB8fCAwO1xyXG4gICAgICAgIGNvbnN0IHBhcmVudE9mZnNldFRvcCA9IHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5vZmZzZXRQYXJlbnQub2Zmc2V0VG9wIHx8IDA7XHJcbiAgICAgICAgY29uc3QgdG90YWxIZWlnaHQgPSBNYXRoLm1heChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0LCB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgMCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGRldGFpbENvbnRlbnRIZWlnaHQgPSB0aGlzLmRldGFpbHNSZXNwb25zaXZlV2luZG93TWFuYWdlci5kZXRhaWxDb250ZW50SGVpZ2h0O1xyXG5cclxuICAgICAgICAvLyBFbmZvcmNlcyBhIG1heCBoZWlnaHQgd2hlbiBzZXR0aW5nIHRoZSBkZWZhdWx0IGhlaWdodC5cclxuICAgICAgICBjb25zdCBtYXhIZWlnaHQgPSBkZXRhaWxDb250ZW50SGVpZ2h0Lm1heDtcclxuICAgICAgICBjb25zdCBtaW5IZWlnaHQgPSBkZXRhaWxDb250ZW50SGVpZ2h0Lm1pbjtcclxuICAgICAgICBjb25zdCBwaG9uZURvd24gPSBkZXRhaWxDb250ZW50SGVpZ2h0LnBob25lRG93bjtcclxuXHJcbiAgICAgICAgLy8gT24gc21hbGwgd2luZG93IGhlaWdodCwgdGhlIGRldGFpbCBwYW5lIGhlaWdodCB3b3VsZCBiZSB0aGUgc21hbGxlciB2YWx1ZSBbd2luZG93IGhlaWdodCAqIDAuNiwgbWF4SGVpZ2h0XVxyXG4gICAgICAgIGlmIChwaG9uZURvd24pIHtcclxuICAgICAgICAgICAgcG90ZW50aWFsSGVpZ2h0ID0gTWF0aC5taW4odG90YWxIZWlnaHQgLSBwYXJlbnRPZmZzZXRUb3AsIHBvdGVudGlhbEhlaWdodCk7XHJcbiAgICAgICAgICAgIC8vIFByZXZlbnRzIHRoZSBpbml0aWFsIHNpemUgZXhjZWVkIG1heCBoZWlnaHRcclxuICAgICAgICAgICAgcG90ZW50aWFsSGVpZ2h0ID0gTWF0aC5taW4ocG90ZW50aWFsSGVpZ2h0LCBtYXhIZWlnaHQpO1xyXG4gICAgICAgICAgICBwb3RlbnRpYWxIZWlnaHQgPSBNYXRoLm1heChwb3RlbnRpYWxIZWlnaHQsIG1pbkhlaWdodCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBwb3J0SGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xyXG4gICAgICAgICAgICBpZiAocG9ydEhlaWdodCA8IG1pbkhlaWdodCkge1xyXG4gICAgICAgICAgICAgICAgcG90ZW50aWFsSGVpZ2h0ID0gbWluSGVpZ2h0O1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBvcnRIZWlnaHQgPiBtaW5IZWlnaHQgJiYgcG9ydEhlaWdodCA8IG1heEhlaWdodCkge1xyXG4gICAgICAgICAgICAgICAgLy8gTWF0aC5jZWlsIGNhbiBtYWtlIGNhbGN1bGF0aW9uIHdpdGhvdXQgcm91bmRpbmcgaXNzdWVzLlxyXG4gICAgICAgICAgICAgICAgcG90ZW50aWFsSGVpZ2h0ID0gTWF0aC5jZWlsKHBvcnRIZWlnaHQgKiAwLjYpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBvcnRIZWlnaHQgPiBtYXhIZWlnaHQgJiYgcG9ydEhlaWdodCAqIDAuNCA+IG1heEhlaWdodCkge1xyXG4gICAgICAgICAgICAgICAgcG90ZW50aWFsSGVpZ2h0ID0gTWF0aC5jZWlsKG1heEhlaWdodCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocG9ydEhlaWdodCA+IG1heEhlaWdodCAmJiBwb3J0SGVpZ2h0ICogMC40ID4gbWluSGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICBwb3RlbnRpYWxIZWlnaHQgPSBNYXRoLmNlaWwocG9ydEhlaWdodCAqIDAuNCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSAnJztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBTaHJpbmsgb25seSBpZiBleGNlZWRzIHBhcmVudHMgb2Zmc2V0IGhlaWdodDtcclxuICAgICAgICAgICAgaWYgKHBvdGVudGlhbEhlaWdodCA+IHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5vZmZzZXRQYXJlbnQub2Zmc2V0SGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCBleHBhbmRlZCBoZWlnaHQgdG8gMzB2aC5cclxuICAgICAgICAgICAgICAgIC8vIFBvb3IgZGVzaWduIHRoYXQgbmVlZHMgdG8gcmUtdmlzaXQuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBvbmVWaCA9IHRvdGFsSGVpZ2h0IC8gMTAwO1xyXG4gICAgICAgICAgICAgICAgcG90ZW50aWFsSGVpZ2h0ID0gb25lVmggKiB0aGlzLmluaXRpYWxIZWlnaHRQZXJjZW50YWdlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gc21lLWJvcmRlci10b3Atc20gb24gdGhlIGRldGFpbHMgcmVzaXplciBib3JkZXIuXHJcbiAgICAgICAgICAgICAgICAvLyBtaW51cyB0aGUgYm9yZGVyIGhlaWdodCB0byBnZXQgcmlkIG9mIHRoZSBleHRyYSBzY3JvbGwgYmFyLlxyXG4gICAgICAgICAgICAgICAgcG90ZW50aWFsSGVpZ2h0IC09IDE7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHBvdGVudGlhbEhlaWdodCA9IE1hdGgubWluKHBvdGVudGlhbEhlaWdodCwgbWF4SGVpZ2h0KTtcclxuICAgICAgICAgICAgcG90ZW50aWFsSGVpZ2h0ID0gTWF0aC5tYXgocG90ZW50aWFsSGVpZ2h0LCBtaW5IZWlnaHQpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5ob3N0RWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLm1pbkhlaWdodCA9ICcnO1xyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLmF1dG9IZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgezB9cHhgLmZvcm1hdChwb3RlbnRpYWxIZWlnaHQpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ob3N0RWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9ICcnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgLy8gdGhlIGhlaWdodCB3b3VsZCBiZSBjaGFuZ2VkIG9uIHdpbmRvdyBoZWlnaHQgb3Igd2lkdGggY2hhbmdlXHJcbiAgICAgICAgICAgIC8vIHJlLWNhbGN1bGF0ZSB0aGUgcG90ZW50aWFsIGhlaWdodCBzaG91bGQgYmUgbm90aWZ5aW5nIHBhcmVudHMuXHJcbiAgICAgICAgICAgIHRoaXMubGF5b3V0Q2hhbmdlZC5lbWl0KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGdldEluaXRpYWxIb3N0Q2xhc3NlcygpIHtcclxuICAgICAgICByZXR1cm4gc3VwZXIuZ2V0SW5pdGlhbEhvc3RDbGFzc2VzKCkuY29uY2F0KFtcclxuICAgICAgICAgICAgJ3NtZS1hcnJhbmdlLXN0YWNrLXYnXHJcbiAgICAgICAgXSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGNyZWF0ZUlkQmFnKCk6IE1zZnRTbWUuU3RyaW5nTWFwPHN0cmluZz4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGRldGFpbHNTcGFuOiAnJ1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuIiwiPGgzPlxyXG4gIDxkaXYgI2V4cGFuZGVyXHJcbiAgICBjbGFzcz1cInNtZS1idXR0b24gc21lLWJ1dHRvbi10cmlnZ2VyIHNtZS1idXR0b24tYXV0by13aWR0aCBzbWUtcG9zaXRpb24tZmxleC1ub25lIHNtZS1wYWRkaW5nLXNxdWlzaC12LW1kIHNtZS1wYWRkaW5nLWhvcml6b250YWwtbGcgc21lLXBvc2l0aW9uLXN0cmV0Y2gtaCBzbWUtcG9zaXRpb24tbGVmdC1pbmxpbmUgc21lLWFycmFuZ2Utc3RhY2staCBzbWUtZm9jdXMtem9uZVwiXHJcbiAgICByb2xlPVwiYnV0dG9uXCIgdGFiaW5kZXg9XCIwXCIgKGNsaWNrKT1cInRvZ2dsZUV4cGFuc2lvbigpXCIgW3N0eWxlLm1pbi1oZWlnaHRdPVwibWluRXhwYW5kZXJIZWlnaHRcIlxyXG4gICAgW2F0dHIuYXJpYS1leHBhbmRlZF09XCIhIWlzRXhwYW5kZWRcIiBbYXR0ci5hcmlhLWRlc2NyaWJlZEJ5XT1cImlkQmFnLmRldGFpbHNTcGFuXCI+XHJcbiAgICA8c3BhbiBjbGFzcz1cInNtZS1mb250LWgzIHNtZS1wb3NpdGlvbi1mbGV4LWF1dG8gc21lLWFycmFuZ2UtZWxsaXBzaXNcIj57eyBoZWFkZXIgfX08L3NwYW4+XHJcbiAgICA8c3BhbiBbc3R5bGUub3JkZXJdPVwiY2hldnJvblBvc2l0aW9uXCIgKm5nSWY9XCIhY2hldnJvbkludmVydGVkXCIgY2xhc3M9XCJzbWUtaWNvbiBzbWUtcG9zaXRpb24tZmxleC1ub25lIHNtZS1tYXJnaW4taG9yaXpvbnRhbC14c1wiXHJcbiAgICAgIFtuZ0NsYXNzXT1cInsnc21lLWljb24tY2hldnJvblVwTWVkJzogIWlzRXhwYW5kZWQsICdzbWUtaWNvbi1jaGV2cm9uRG93bk1lZCc6IGlzRXhwYW5kZWR9XCJcclxuICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxyXG4gICAgPHNwYW4gW3N0eWxlLm9yZGVyXT1cImNoZXZyb25Qb3NpdGlvblwiICpuZ0lmPVwiY2hldnJvbkludmVydGVkXCIgY2xhc3M9XCJzbWUtaWNvbiBzbWUtcG9zaXRpb24tZmxleC1ub25lIHNtZS1tYXJnaW4taG9yaXpvbnRhbC14c1wiXHJcbiAgICAgIFtuZ0NsYXNzXT1cInsnc21lLWljb24tY2hldnJvblVwTWVkJzogaXNFeHBhbmRlZCwgJ3NtZS1pY29uLWNoZXZyb25Eb3duTWVkJzogIWlzRXhwYW5kZWR9XCJcclxuICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxyXG4gICAgPGRpdiBjbGFzcz1cInNtZS1zY3JlZW4tcmVhZGVyXCIgW2lkXT1cImlkQmFnLmRldGFpbHNTcGFuXCI+IHt7IHJlc291cmNlU3RyaW5ncy5BcmlhRGVzY3JpcHRpb24gfX08L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9oMz5cclxuXHJcbjxkaXYgY2xhc3M9XCJzbWUtcG9zaXRpb24tZmxleC1hdXRvIHNtZS1sYXlvdXQtcmVsYXRpdmVcIiBbY2xhc3Muc21lLW1hcmdpbi1ob3Jpem9udGFsLWxnXT1cInNob3VsZENvbnRlbnRTbGltXCIgW2NsYXNzLnNtZS1wb3NpdGlvbi1zdHJldGNoLXZdPVwiYXV0b0hlaWdodFwiPlxyXG4gIDxkaXYgW25nQ2xhc3NdPVwieydzbWUtbGF5b3V0LWFic29sdXRlLXBob25lLXVwIHNtZS1wb3NpdGlvbi1pbnNldC1ub25lIHNtZS1wYWRkaW5nLWJvdHRvbS1zbSBzbWUtYXJyYW5nZS1vdmVyZmxvdy1hdXRvJzogIWF1dG9IZWlnaHQsICdzbWUtbGF5b3V0LXJlbGF0aXZlIHNtZS1wb3NpdGlvbi1zdHJldGNoLXYnOiBhdXRvSGVpZ2h0fVwiXHJcbiAgICBbY2xhc3Muc21lLWxheW91dC1ub25lXT1cIiFpc0V4cGFuZGVkXCI+XHJcbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGhyICpuZ0lmPVwiYWRkQm90dG9tQm9yZGVyXCI+XHJcbiJdfQ==