@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
199 lines • 32.7 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Component, ContentChildren, QueryList, Input } from '@angular/core';
import { Debounce } from '@microsoft/windows-admin-center-sdk/core/base/decorators/debounce.decorators';
import { EditableLayoutItemComponent } from './editable-layout-item.component';
import { LayoutComponent } from './layout.component';
import * as i0 from "@angular/core";
const _c0 = [[["sme-editable-layout-item"]]];
const _c1 = ["sme-editable-layout-item"];
export class EditableLayoutComponent extends LayoutComponent {
/**
* The source name to use for logging
*/
get logSourceName() {
return 'EditableLayoutComponent';
}
getInitialHostClasses() {
return super.getInitialHostClasses().concat([
'sme-layout-relative',
'sme-position-stretch',
'sme-arrange-overflow-auto'
]);
}
ngOnChanges() {
this.changeDraggable(this.isEditMode);
}
/**
* Method to change (start/stop) the draggable behavior of this layout.
* @param isDraggable flag to start/stop draggable behavior of all the layout inside this layout.
*/
changeDraggable(isDraggable) {
if (this.editableLayoutItems) {
const editableLayoutItems = this.editableLayoutItems.toArray();
for (let i = 0; i < editableLayoutItems.length; i++) {
editableLayoutItems[i].isLayoutItemDraggable = isDraggable;
}
}
}
ngAfterViewInit() {
this.snapToGrid();
this.editableLayoutItems.forEach((childComponent) => {
this.subscriptions.push(childComponent.dragEnd.subscribe((item) => {
this.dragEnd(item);
}));
});
}
get gridHeight() {
const editableLayoutItems = this.editableLayoutItems.toArray();
const itemsByMaxY = editableLayoutItems.map(item => item.yCoordInGrid + item.heightInGrid).sort((a, b) => a > b ? 1 : -1);
return Math.max(itemsByMaxY.last() + EditableLayoutComponent.gridPaddingSize, this.hostElement.nativeElement.clientHeight);
}
get gridWidth() {
const editableLayoutItems = this.editableLayoutItems.toArray();
const itemsByMaxX = editableLayoutItems.map(item => item.xCoordInGrid + item.widthInGrid).sort((a, b) => a > b ? 1 : -1);
return Math.max(itemsByMaxX.last() + EditableLayoutComponent.gridPaddingSize, this.hostElement.nativeElement.clientWidth);
}
/**
* This method will be called once child/item layout is dragged to change the their position or
* their corners are being dragged to resize them. This will be called on onMouseUp and onMouseLeave event.
* @param item layout that is just dragged.
*/
dragEnd(item) {
const editableLayoutItems = this.editableLayoutItems.toArray();
const draggedItemId = new Array();
draggedItemId.push(item.id);
const idOfLastElement = draggedItemId.pop();
for (let i = 0; i < editableLayoutItems.length; i++) {
const draggedItemY1 = item.yCoordInGrid;
const draggedItemX1 = item.xCoordInGrid;
const draggedItemY2 = draggedItemY1 + item.heightInGrid;
const draggedItemX2 = draggedItemX1 + item.widthInGrid;
if (idOfLastElement !== editableLayoutItems[i].id) {
const existingItemY1 = editableLayoutItems[i].yCoordInGrid;
const existingItemX1 = editableLayoutItems[i].xCoordInGrid;
const existingItemX2 = existingItemX1 + editableLayoutItems[i].widthInGrid;
const existingItemY2 = existingItemY1 + editableLayoutItems[i].heightInGrid;
const isXOverlapping = this.areElementsOverlapping(draggedItemX1, draggedItemX2, existingItemX1, existingItemX2);
const isYOverlapping = this.areElementsOverlapping(draggedItemY1, draggedItemY2, existingItemY1, existingItemY2);
if ((isXOverlapping && isYOverlapping)) {
if (existingItemY1 >= draggedItemY1) {
draggedItemId.push(editableLayoutItems[i].id);
editableLayoutItems[i].yCoordInGrid = draggedItemY2;
}
else {
item.yCoordInGrid = existingItemY2;
draggedItemId.push(item.id);
}
}
}
if (i === editableLayoutItems.length - 1 && draggedItemId.length > 0) {
this.dragEnd(editableLayoutItems[draggedItemId.pop()]);
}
}
this.snapToGrid();
}
/**
* This method will check overlapping when coordinates are out of conflicting area, like bigger div is dragged over smaller div.
* @param pointOneOfDraggedDiv Y/X starting point of Vertical/Horizontal point of dragged div
* @param pointTwoOfDraggedDiv Y/X ending point of Vertical/Horizontal point of dragged div
* @param pointOneOfExistingDiv Y/X starting point of Vertical/Horizontal div over which new div is dragged
* @param pointTwoOfExistingDiv Y/X ending point of Vertical/Horizontal div over which new div is dragged
*/
areElementsOverlapping(pointOneOfDraggedDiv, pointTwoOfDraggedDiv, pointOneOfExistingDiv, pointTwoOfExistingDiv) {
return (this.checkBetween(pointOneOfExistingDiv, pointTwoOfExistingDiv, pointOneOfDraggedDiv)
|| this.checkBetween(pointOneOfExistingDiv, pointTwoOfExistingDiv, pointTwoOfDraggedDiv))
|| (pointOneOfDraggedDiv <= pointOneOfExistingDiv && pointTwoOfDraggedDiv >= pointTwoOfExistingDiv);
}
/**
* Just to check if searched item is fall under certain range.
* @param start start of range
* @param end end of range
* @param search item being searched
*/
checkBetween(start, end, search) {
return (search > start) && (search < end) ? true : false;
}
/**
* This method is adjust all the div with to fall on the boundary of grid with 72 x 72.
*/
snapToGrid() {
this.editableLayoutItems.forEach((childComponent) => {
const remainderX = childComponent.xCoordInGrid % EditableLayoutComponent.gridSquareSize;
const remainderY = childComponent.yCoordInGrid % EditableLayoutComponent.gridSquareSize;
const remainderHeight = childComponent.heightInGrid % EditableLayoutComponent.gridSquareSize;
const remainderWidth = childComponent.widthInGrid % EditableLayoutComponent.gridSquareSize;
if (remainderX !== 0) {
childComponent.xCoordInGrid = Math.max(childComponent.xCoordInGrid - remainderX, 0);
}
if (remainderY !== 0) {
childComponent.yCoordInGrid = Math.max(childComponent.yCoordInGrid - remainderY, 0);
}
if (remainderHeight !== 0) {
childComponent.heightInGrid =
Math.max(childComponent.heightInGrid - remainderHeight, EditableLayoutComponent.gridSquareSize);
}
if (remainderWidth !== 0) {
childComponent.widthInGrid = Math.max(childComponent.widthInGrid - remainderWidth, EditableLayoutComponent.gridSquareSize);
}
// adjust for minimum area bounds
if (childComponent.area < childComponent.minArea) {
let widthModifier = 0;
let heightModifier = 0;
if (childComponent.widthInGrid >= childComponent.heightInGrid) {
widthModifier = EditableLayoutComponent.gridSquareSize;
}
if (childComponent.heightInGrid >= childComponent.widthInGrid) {
heightModifier = EditableLayoutComponent.gridSquareSize;
}
childComponent.widthInGrid += widthModifier;
childComponent.heightInGrid += heightModifier;
}
});
}
updateLayout() {
if (this.editableLayoutItems) {
const layoutWidth = this.hostElement.nativeElement.clientWidth || 0;
if (!layoutWidth) {
return;
}
// calculate coords and boxSize
const editableLayoutItems = this.editableLayoutItems.toArray();
for (let i = 0; i < editableLayoutItems.length; i++) {
editableLayoutItems[i].widthInGrid = editableLayoutItems[i].widthInGrid;
editableLayoutItems[i].heightInGrid = editableLayoutItems[i].heightInGrid;
}
}
}
}
EditableLayoutComponent.gridSquareSize = 72;
EditableLayoutComponent.gridPaddingSize = 8;
/** @nocollapse */ EditableLayoutComponent.ɵfac = /** @pureOrBreakMyCode */ function () { let ɵEditableLayoutComponent_BaseFactory; return function EditableLayoutComponent_Factory(t) { return (ɵEditableLayoutComponent_BaseFactory || (ɵEditableLayoutComponent_BaseFactory = i0.ɵɵgetInheritedFactory(EditableLayoutComponent)))(t || EditableLayoutComponent); }; }();
/** @nocollapse */ EditableLayoutComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: EditableLayoutComponent, selectors: [["sme-editable-layout"]], contentQueries: function EditableLayoutComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
i0.ɵɵcontentQuery(dirIndex, EditableLayoutItemComponent, 4);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.editableLayoutItems = _t);
} }, inputs: { isEditMode: "isEditMode" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c1, decls: 2, vars: 4, consts: [[1, "sme-editable-layout-grid"]], template: function EditableLayoutComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef(_c0);
i0.ɵɵelementStart(0, "div", 0);
i0.ɵɵprojection(1);
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵstyleProp("height", ctx.gridHeight, "px")("width", ctx.gridWidth, "px");
} }, encapsulation: 2 });
__decorate([
Debounce(0),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], EditableLayoutComponent.prototype, "updateLayout", null);
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EditableLayoutComponent, [{
type: Component,
args: [{ selector: 'sme-editable-layout', template: "<div class=\"sme-editable-layout-grid\" [style.height.px]=\"gridHeight\" [style.width.px]=\"gridWidth\">\r\n<ng-content select=\"sme-editable-layout-item\"></ng-content>\r\n</div>\r\n" }]
}], null, { editableLayoutItems: [{
type: ContentChildren,
args: [EditableLayoutItemComponent]
}], isEditMode: [{
type: Input
}], updateLayout: [] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtbGF5b3V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL2NvbnRyb2xzL2xheW91dC9lZGl0YWJsZS1sYXlvdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvbGF5b3V0L2VkaXRhYmxlLWxheW91dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFpQixTQUFTLEVBQUUsZUFBZSxFQUFhLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkcsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDhFQUE4RSxDQUFDO0FBQ3hHLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQy9FLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7OztBQU1yRCxNQUFNLE9BQU8sdUJBQXdCLFNBQVEsZUFBZTtJQUd4RDs7T0FFRztJQUNILElBQWMsYUFBYTtRQUN2QixPQUFPLHlCQUF5QixDQUFDO0lBQ3JDLENBQUM7SUFRUyxxQkFBcUI7UUFDM0IsT0FBTyxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxNQUFNLENBQUM7WUFDeEMscUJBQXFCO1lBQ3JCLHNCQUFzQjtZQUN0QiwyQkFBMkI7U0FDOUIsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVNLFdBQVc7UUFDZCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQ0Q7OztPQUdHO0lBQ0ksZUFBZSxDQUFDLFdBQW9CO1FBQ3ZDLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFO1lBQzFCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQy9ELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2pELG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixHQUFHLFdBQVcsQ0FBQzthQUM5RDtTQUNKO0lBQ0wsQ0FBQztJQUVNLGVBQWU7UUFDbEIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxjQUEyQyxFQUFFLEVBQUU7WUFDN0UsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDOUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN2QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ1IsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsSUFBVyxVQUFVO1FBQ2pCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQy9ELE1BQU0sV0FBVyxHQUFHLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxSCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxHQUFHLHVCQUF1QixDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMvSCxDQUFDO0lBRUQsSUFBVyxTQUFTO1FBQ2hCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQy9ELE1BQU0sV0FBVyxHQUFHLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6SCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxHQUFHLHVCQUF1QixDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM5SCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLE9BQU8sQ0FBQyxJQUFJO1FBQ2YsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0QsTUFBTSxhQUFhLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUNsQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM1QixNQUFNLGVBQWUsR0FBRyxhQUFhLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDNUMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNqRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1lBQ3hDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDeEMsTUFBTSxhQUFhLEdBQUcsYUFBYSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDeEQsTUFBTSxhQUFhLEdBQUcsYUFBYSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7WUFDdkQsSUFBSSxlQUFlLEtBQUssbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO2dCQUMvQyxNQUFNLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUM7Z0JBQzNELE1BQU0sY0FBYyxHQUFHLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQztnQkFDM0QsTUFBTSxjQUFjLEdBQUcsY0FBYyxHQUFHLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztnQkFDM0UsTUFBTSxjQUFjLEdBQUcsY0FBYyxHQUFHLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQztnQkFDNUUsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLGFBQWEsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxDQUFDO2dCQUNqSCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsYUFBYSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsY0FBYyxDQUFDLENBQUM7Z0JBQ2pILElBQUksQ0FBQyxjQUFjLElBQUksY0FBYyxDQUFDLEVBQUU7b0JBQ3BDLElBQUksY0FBYyxJQUFJLGFBQWEsRUFBRTt3QkFDakMsYUFBYSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQzt3QkFDOUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxHQUFHLGFBQWEsQ0FBQztxQkFDdkQ7eUJBQU07d0JBQ0gsSUFBSSxDQUFDLFlBQVksR0FBRyxjQUFjLENBQUM7d0JBQ25DLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO3FCQUMvQjtpQkFDSjthQUNKO1lBQ0QsSUFBSSxDQUFDLEtBQUssbUJBQW1CLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFDbEUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQzFEO1NBQ0o7UUFDRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLHNCQUFzQixDQUN6QixvQkFBNEIsRUFDNUIsb0JBQTRCLEVBQzVCLHFCQUE2QixFQUM3QixxQkFBNkI7UUFDN0IsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMscUJBQXFCLEVBQUUscUJBQXFCLEVBQUUsb0JBQW9CLENBQUM7ZUFDdEYsSUFBSSxDQUFDLFlBQVksQ0FBQyxxQkFBcUIsRUFBRSxxQkFBcUIsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO2VBQ3RGLENBQUMsb0JBQW9CLElBQUkscUJBQXFCLElBQUksb0JBQW9CLElBQUkscUJBQXFCLENBQUMsQ0FBQztJQUM1RyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxZQUFZLENBQUMsS0FBYSxFQUFFLEdBQVcsRUFBRSxNQUFjO1FBQzFELE9BQU8sQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQzdELENBQUM7SUFFRDs7T0FFRztJQUNJLFVBQVU7UUFDYixJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUMsY0FBMkMsRUFBRSxFQUFFO1lBQzdFLE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxZQUFZLEdBQUcsdUJBQXVCLENBQUMsY0FBYyxDQUFDO1lBQ3hGLE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxZQUFZLEdBQUcsdUJBQXVCLENBQUMsY0FBYyxDQUFDO1lBQ3hGLE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxZQUFZLEdBQUcsdUJBQXVCLENBQUMsY0FBYyxDQUFDO1lBQzdGLE1BQU0sY0FBYyxHQUFHLGNBQWMsQ0FBQyxXQUFXLEdBQUcsdUJBQXVCLENBQUMsY0FBYyxDQUFDO1lBQzNGLElBQUksVUFBVSxLQUFLLENBQUMsRUFBRTtnQkFDbEIsY0FBYyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxZQUFZLEdBQUcsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ3ZGO1lBQ0QsSUFBSSxVQUFVLEtBQUssQ0FBQyxFQUFFO2dCQUNsQixjQUFjLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFlBQVksR0FBRyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDdkY7WUFDRCxJQUFJLGVBQWUsS0FBSyxDQUFDLEVBQUU7Z0JBQ3ZCLGNBQWMsQ0FBQyxZQUFZO29CQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxZQUFZLEdBQUcsZUFBZSxFQUFFLHVCQUF1QixDQUFDLGNBQWMsQ0FBQyxDQUFDO2FBQ3ZHO1lBQ0QsSUFBSSxjQUFjLEtBQUssQ0FBQyxFQUFFO2dCQUN0QixjQUFjLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFdBQVcsR0FBRyxjQUFjLEVBQUUsdUJBQXVCLENBQUMsY0FBYyxDQUFDLENBQUM7YUFDOUg7WUFFRCxpQ0FBaUM7WUFDakMsSUFBSSxjQUFjLENBQUMsSUFBSSxHQUFHLGNBQWMsQ0FBQyxPQUFPLEVBQUU7Z0JBQzlDLElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQztnQkFDdEIsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDO2dCQUN2QixJQUFJLGNBQWMsQ0FBQyxXQUFXLElBQUksY0FBYyxDQUFDLFlBQVksRUFBRTtvQkFDM0QsYUFBYSxHQUFHLHVCQUF1QixDQUFDLGNBQWMsQ0FBQztpQkFDMUQ7Z0JBQ0QsSUFBSSxjQUFjLENBQUMsWUFBWSxJQUFJLGNBQWMsQ0FBQyxXQUFXLEVBQUU7b0JBQzNELGNBQWMsR0FBRyx1QkFBdUIsQ0FBQyxjQUFjLENBQUM7aUJBQzNEO2dCQUNELGNBQWMsQ0FBQyxXQUFXLElBQUksYUFBYSxDQUFDO2dCQUM1QyxjQUFjLENBQUMsWUFBWSxJQUFJLGNBQWMsQ0FBQzthQUNqRDtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUdTLFlBQVk7UUFDbEIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUU7WUFDMUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQztZQUNwRSxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNkLE9BQU87YUFDVjtZQUVELCtCQUErQjtZQUMvQixNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUUvRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUNqRCxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEdBQUcsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO2dCQUN4RSxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLEdBQUcsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO2FBQzdFO1NBQ0o7SUFDTCxDQUFDOztBQXJMYyxzQ0FBYyxHQUFHLEVBQUUsQ0FBQztBQUNwQix1Q0FBZSxHQUFHLENBQUMsQ0FBQzswU0FGMUIsdUJBQXVCLFNBQXZCLHVCQUF1Qjt5R0FBdkIsdUJBQXVCO29DQVVmLDJCQUEyQjs7Ozs7O1FDbkJoRCw4QkFBa0c7UUFDbEcsa0JBQTJEO1FBQzNELGlCQUFNOztRQUZnQyw4Q0FBOEIsOEJBQUE7O0FEK0toRTtJQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Ozs7MkRBZ0JYO3VGQXRMUSx1QkFBdUI7Y0FKbkMsU0FBUzsyQkFDSSxxQkFBcUI7Z0JBY3JCLG1CQUFtQjtrQkFENUIsZUFBZTttQkFBQywyQkFBMkI7WUFJckMsVUFBVTtrQkFEaEIsS0FBSztZQTBKSSxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBDb250ZW50Q2hpbGRyZW4sIE9uQ2hhbmdlcywgUXVlcnlMaXN0LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEZWJvdW5jZSB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvYmFzZS9kZWNvcmF0b3JzL2RlYm91bmNlLmRlY29yYXRvcnMnO1xyXG5pbXBvcnQgeyBFZGl0YWJsZUxheW91dEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2VkaXRhYmxlLWxheW91dC1pdGVtLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IExheW91dENvbXBvbmVudCB9IGZyb20gJy4vbGF5b3V0LmNvbXBvbmVudCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnc21lLWVkaXRhYmxlLWxheW91dCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZWRpdGFibGUtbGF5b3V0LmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRWRpdGFibGVMYXlvdXRDb21wb25lbnQgZXh0ZW5kcyBMYXlvdXRDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMge1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgZ3JpZFNxdWFyZVNpemUgPSA3MjtcclxuICAgIHByaXZhdGUgc3RhdGljIGdyaWRQYWRkaW5nU2l6ZSA9IDg7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzb3VyY2UgbmFtZSB0byB1c2UgZm9yIGxvZ2dpbmdcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGdldCBsb2dTb3VyY2VOYW1lKCkge1xyXG4gICAgICAgIHJldHVybiAnRWRpdGFibGVMYXlvdXRDb21wb25lbnQnO1xyXG4gICAgfVxyXG5cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oRWRpdGFibGVMYXlvdXRJdGVtQ29tcG9uZW50KVxyXG4gICAgcHJvdGVjdGVkIGVkaXRhYmxlTGF5b3V0SXRlbXM6IFF1ZXJ5TGlzdDxFZGl0YWJsZUxheW91dEl0ZW1Db21wb25lbnQ+O1xyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgaXNFZGl0TW9kZTogYm9vbGVhbjtcclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0SW5pdGlhbEhvc3RDbGFzc2VzKCkge1xyXG4gICAgICAgIHJldHVybiBzdXBlci5nZXRJbml0aWFsSG9zdENsYXNzZXMoKS5jb25jYXQoW1xyXG4gICAgICAgICAgICAnc21lLWxheW91dC1yZWxhdGl2ZScsXHJcbiAgICAgICAgICAgICdzbWUtcG9zaXRpb24tc3RyZXRjaCcsXHJcbiAgICAgICAgICAgICdzbWUtYXJyYW5nZS1vdmVyZmxvdy1hdXRvJ1xyXG4gICAgICAgIF0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uQ2hhbmdlcygpIHtcclxuICAgICAgICB0aGlzLmNoYW5nZURyYWdnYWJsZSh0aGlzLmlzRWRpdE1vZGUpO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRob2QgdG8gY2hhbmdlIChzdGFydC9zdG9wKSB0aGUgZHJhZ2dhYmxlIGJlaGF2aW9yIG9mIHRoaXMgbGF5b3V0LlxyXG4gICAgICogQHBhcmFtIGlzRHJhZ2dhYmxlIGZsYWcgdG8gc3RhcnQvc3RvcCBkcmFnZ2FibGUgYmVoYXZpb3Igb2YgYWxsIHRoZSBsYXlvdXQgaW5zaWRlIHRoaXMgbGF5b3V0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2hhbmdlRHJhZ2dhYmxlKGlzRHJhZ2dhYmxlOiBib29sZWFuKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZWRpdGFibGVMYXlvdXRJdGVtcykge1xyXG4gICAgICAgICAgICBjb25zdCBlZGl0YWJsZUxheW91dEl0ZW1zID0gdGhpcy5lZGl0YWJsZUxheW91dEl0ZW1zLnRvQXJyYXkoKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlZGl0YWJsZUxheW91dEl0ZW1zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBlZGl0YWJsZUxheW91dEl0ZW1zW2ldLmlzTGF5b3V0SXRlbURyYWdnYWJsZSA9IGlzRHJhZ2dhYmxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICAgICAgdGhpcy5zbmFwVG9HcmlkKCk7XHJcbiAgICAgICAgdGhpcy5lZGl0YWJsZUxheW91dEl0ZW1zLmZvckVhY2goKGNoaWxkQ29tcG9uZW50OiBFZGl0YWJsZUxheW91dEl0ZW1Db21wb25lbnQpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goY2hpbGRDb21wb25lbnQuZHJhZ0VuZC5zdWJzY3JpYmUoKGl0ZW0pID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0VuZChpdGVtKTtcclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgZ3JpZEhlaWdodCgpIHtcclxuICAgICAgICBjb25zdCBlZGl0YWJsZUxheW91dEl0ZW1zID0gdGhpcy5lZGl0YWJsZUxheW91dEl0ZW1zLnRvQXJyYXkoKTtcclxuICAgICAgICBjb25zdCBpdGVtc0J5TWF4WSA9IGVkaXRhYmxlTGF5b3V0SXRlbXMubWFwKGl0ZW0gPT4gaXRlbS55Q29vcmRJbkdyaWQgKyBpdGVtLmhlaWdodEluR3JpZCkuc29ydCgoYSwgYikgPT4gYSA+IGIgPyAxIDogLTEpO1xyXG4gICAgICAgIHJldHVybiBNYXRoLm1heChpdGVtc0J5TWF4WS5sYXN0KCkgKyBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkUGFkZGluZ1NpemUsIHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5jbGllbnRIZWlnaHQpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgZ3JpZFdpZHRoKCkge1xyXG4gICAgICAgIGNvbnN0IGVkaXRhYmxlTGF5b3V0SXRlbXMgPSB0aGlzLmVkaXRhYmxlTGF5b3V0SXRlbXMudG9BcnJheSgpO1xyXG4gICAgICAgIGNvbnN0IGl0ZW1zQnlNYXhYID0gZWRpdGFibGVMYXlvdXRJdGVtcy5tYXAoaXRlbSA9PiBpdGVtLnhDb29yZEluR3JpZCArIGl0ZW0ud2lkdGhJbkdyaWQpLnNvcnQoKGEsIGIpID0+IGEgPiBiID8gMSA6IC0xKTtcclxuICAgICAgICByZXR1cm4gTWF0aC5tYXgoaXRlbXNCeU1heFgubGFzdCgpICsgRWRpdGFibGVMYXlvdXRDb21wb25lbnQuZ3JpZFBhZGRpbmdTaXplLCB0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuY2xpZW50V2lkdGgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgb25jZSBjaGlsZC9pdGVtIGxheW91dCBpcyBkcmFnZ2VkIHRvIGNoYW5nZSB0aGUgdGhlaXIgcG9zaXRpb24gb3JcclxuICAgICAqIHRoZWlyIGNvcm5lcnMgYXJlIGJlaW5nIGRyYWdnZWQgdG8gcmVzaXplIHRoZW0uIFRoaXMgd2lsbCBiZSBjYWxsZWQgb24gb25Nb3VzZVVwIGFuZCBvbk1vdXNlTGVhdmUgZXZlbnQuXHJcbiAgICAgKiBAcGFyYW0gaXRlbSBsYXlvdXQgdGhhdCBpcyBqdXN0IGRyYWdnZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkcmFnRW5kKGl0ZW0pIHtcclxuICAgICAgICBjb25zdCBlZGl0YWJsZUxheW91dEl0ZW1zID0gdGhpcy5lZGl0YWJsZUxheW91dEl0ZW1zLnRvQXJyYXkoKTtcclxuICAgICAgICBjb25zdCBkcmFnZ2VkSXRlbUlkID0gbmV3IEFycmF5KCk7XHJcbiAgICAgICAgZHJhZ2dlZEl0ZW1JZC5wdXNoKGl0ZW0uaWQpO1xyXG4gICAgICAgIGNvbnN0IGlkT2ZMYXN0RWxlbWVudCA9IGRyYWdnZWRJdGVtSWQucG9wKCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlZGl0YWJsZUxheW91dEl0ZW1zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGRyYWdnZWRJdGVtWTEgPSBpdGVtLnlDb29yZEluR3JpZDtcclxuICAgICAgICAgICAgY29uc3QgZHJhZ2dlZEl0ZW1YMSA9IGl0ZW0ueENvb3JkSW5HcmlkO1xyXG4gICAgICAgICAgICBjb25zdCBkcmFnZ2VkSXRlbVkyID0gZHJhZ2dlZEl0ZW1ZMSArIGl0ZW0uaGVpZ2h0SW5HcmlkO1xyXG4gICAgICAgICAgICBjb25zdCBkcmFnZ2VkSXRlbVgyID0gZHJhZ2dlZEl0ZW1YMSArIGl0ZW0ud2lkdGhJbkdyaWQ7XHJcbiAgICAgICAgICAgIGlmIChpZE9mTGFzdEVsZW1lbnQgIT09IGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0uaWQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSXRlbVkxID0gZWRpdGFibGVMYXlvdXRJdGVtc1tpXS55Q29vcmRJbkdyaWQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ0l0ZW1YMSA9IGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0ueENvb3JkSW5HcmlkO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdJdGVtWDIgPSBleGlzdGluZ0l0ZW1YMSArIGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0ud2lkdGhJbkdyaWQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ0l0ZW1ZMiA9IGV4aXN0aW5nSXRlbVkxICsgZWRpdGFibGVMYXlvdXRJdGVtc1tpXS5oZWlnaHRJbkdyaWQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpc1hPdmVybGFwcGluZyA9IHRoaXMuYXJlRWxlbWVudHNPdmVybGFwcGluZyhkcmFnZ2VkSXRlbVgxLCBkcmFnZ2VkSXRlbVgyLCBleGlzdGluZ0l0ZW1YMSwgZXhpc3RpbmdJdGVtWDIpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaXNZT3ZlcmxhcHBpbmcgPSB0aGlzLmFyZUVsZW1lbnRzT3ZlcmxhcHBpbmcoZHJhZ2dlZEl0ZW1ZMSwgZHJhZ2dlZEl0ZW1ZMiwgZXhpc3RpbmdJdGVtWTEsIGV4aXN0aW5nSXRlbVkyKTtcclxuICAgICAgICAgICAgICAgIGlmICgoaXNYT3ZlcmxhcHBpbmcgJiYgaXNZT3ZlcmxhcHBpbmcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nSXRlbVkxID49IGRyYWdnZWRJdGVtWTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dlZEl0ZW1JZC5wdXNoKGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0uaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlZGl0YWJsZUxheW91dEl0ZW1zW2ldLnlDb29yZEluR3JpZCA9IGRyYWdnZWRJdGVtWTI7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS55Q29vcmRJbkdyaWQgPSBleGlzdGluZ0l0ZW1ZMjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dlZEl0ZW1JZC5wdXNoKGl0ZW0uaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaSA9PT0gZWRpdGFibGVMYXlvdXRJdGVtcy5sZW5ndGggLSAxICYmIGRyYWdnZWRJdGVtSWQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnRW5kKGVkaXRhYmxlTGF5b3V0SXRlbXNbZHJhZ2dlZEl0ZW1JZC5wb3AoKV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuc25hcFRvR3JpZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBtZXRob2Qgd2lsbCBjaGVjayBvdmVybGFwcGluZyB3aGVuIGNvb3JkaW5hdGVzIGFyZSBvdXQgb2YgY29uZmxpY3RpbmcgYXJlYSwgbGlrZSBiaWdnZXIgZGl2IGlzIGRyYWdnZWQgb3ZlciBzbWFsbGVyIGRpdi5cclxuICAgICAqIEBwYXJhbSBwb2ludE9uZU9mRHJhZ2dlZERpdiBZL1ggc3RhcnRpbmcgcG9pbnQgb2YgVmVydGljYWwvSG9yaXpvbnRhbCBwb2ludCBvZiBkcmFnZ2VkIGRpdlxyXG4gICAgICogQHBhcmFtIHBvaW50VHdvT2ZEcmFnZ2VkRGl2IFkvWCBlbmRpbmcgcG9pbnQgb2YgVmVydGljYWwvSG9yaXpvbnRhbCBwb2ludCBvZiBkcmFnZ2VkIGRpdlxyXG4gICAgICogQHBhcmFtIHBvaW50T25lT2ZFeGlzdGluZ0RpdiBZL1ggc3RhcnRpbmcgcG9pbnQgb2YgVmVydGljYWwvSG9yaXpvbnRhbCBkaXYgb3ZlciB3aGljaCBuZXcgZGl2IGlzIGRyYWdnZWRcclxuICAgICAqIEBwYXJhbSBwb2ludFR3b09mRXhpc3RpbmdEaXYgWS9YIGVuZGluZyBwb2ludCBvZiBWZXJ0aWNhbC9Ib3Jpem9udGFsIGRpdiBvdmVyIHdoaWNoIG5ldyBkaXYgaXMgZHJhZ2dlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXJlRWxlbWVudHNPdmVybGFwcGluZyhcclxuICAgICAgICBwb2ludE9uZU9mRHJhZ2dlZERpdjogbnVtYmVyLFxyXG4gICAgICAgIHBvaW50VHdvT2ZEcmFnZ2VkRGl2OiBudW1iZXIsXHJcbiAgICAgICAgcG9pbnRPbmVPZkV4aXN0aW5nRGl2OiBudW1iZXIsXHJcbiAgICAgICAgcG9pbnRUd29PZkV4aXN0aW5nRGl2OiBudW1iZXIpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMuY2hlY2tCZXR3ZWVuKHBvaW50T25lT2ZFeGlzdGluZ0RpdiwgcG9pbnRUd29PZkV4aXN0aW5nRGl2LCBwb2ludE9uZU9mRHJhZ2dlZERpdilcclxuICAgICAgICAgICAgfHwgdGhpcy5jaGVja0JldHdlZW4ocG9pbnRPbmVPZkV4aXN0aW5nRGl2LCBwb2ludFR3b09mRXhpc3RpbmdEaXYsIHBvaW50VHdvT2ZEcmFnZ2VkRGl2KSlcclxuICAgICAgICAgICAgfHwgKHBvaW50T25lT2ZEcmFnZ2VkRGl2IDw9IHBvaW50T25lT2ZFeGlzdGluZ0RpdiAmJiBwb2ludFR3b09mRHJhZ2dlZERpdiA+PSBwb2ludFR3b09mRXhpc3RpbmdEaXYpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSnVzdCB0byBjaGVjayBpZiBzZWFyY2hlZCBpdGVtIGlzIGZhbGwgdW5kZXIgY2VydGFpbiByYW5nZS5cclxuICAgICAqIEBwYXJhbSBzdGFydCBzdGFydCBvZiByYW5nZVxyXG4gICAgICogQHBhcmFtIGVuZCBlbmQgb2YgcmFuZ2VcclxuICAgICAqIEBwYXJhbSBzZWFyY2ggaXRlbSBiZWluZyBzZWFyY2hlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2hlY2tCZXR3ZWVuKHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyLCBzZWFyY2g6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAoc2VhcmNoID4gc3RhcnQpICYmIChzZWFyY2ggPCBlbmQpID8gdHJ1ZSA6IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBtZXRob2QgaXMgYWRqdXN0IGFsbCB0aGUgZGl2IHdpdGggdG8gZmFsbCBvbiB0aGUgYm91bmRhcnkgb2YgZ3JpZCB3aXRoIDcyIHggNzIuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzbmFwVG9HcmlkKCkge1xyXG4gICAgICAgIHRoaXMuZWRpdGFibGVMYXlvdXRJdGVtcy5mb3JFYWNoKChjaGlsZENvbXBvbmVudDogRWRpdGFibGVMYXlvdXRJdGVtQ29tcG9uZW50KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmRlclggPSBjaGlsZENvbXBvbmVudC54Q29vcmRJbkdyaWQgJSBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkU3F1YXJlU2l6ZTtcclxuICAgICAgICAgICAgY29uc3QgcmVtYWluZGVyWSA9IGNoaWxkQ29tcG9uZW50LnlDb29yZEluR3JpZCAlIEVkaXRhYmxlTGF5b3V0Q29tcG9uZW50LmdyaWRTcXVhcmVTaXplO1xyXG4gICAgICAgICAgICBjb25zdCByZW1haW5kZXJIZWlnaHQgPSBjaGlsZENvbXBvbmVudC5oZWlnaHRJbkdyaWQgJSBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkU3F1YXJlU2l6ZTtcclxuICAgICAgICAgICAgY29uc3QgcmVtYWluZGVyV2lkdGggPSBjaGlsZENvbXBvbmVudC53aWR0aEluR3JpZCAlIEVkaXRhYmxlTGF5b3V0Q29tcG9uZW50LmdyaWRTcXVhcmVTaXplO1xyXG4gICAgICAgICAgICBpZiAocmVtYWluZGVyWCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgY2hpbGRDb21wb25lbnQueENvb3JkSW5HcmlkID0gTWF0aC5tYXgoY2hpbGRDb21wb25lbnQueENvb3JkSW5HcmlkIC0gcmVtYWluZGVyWCwgMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlbWFpbmRlclkgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIGNoaWxkQ29tcG9uZW50LnlDb29yZEluR3JpZCA9IE1hdGgubWF4KGNoaWxkQ29tcG9uZW50LnlDb29yZEluR3JpZCAtIHJlbWFpbmRlclksIDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZW1haW5kZXJIZWlnaHQgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIGNoaWxkQ29tcG9uZW50LmhlaWdodEluR3JpZCA9XHJcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5tYXgoY2hpbGRDb21wb25lbnQuaGVpZ2h0SW5HcmlkIC0gcmVtYWluZGVySGVpZ2h0LCBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkU3F1YXJlU2l6ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlbWFpbmRlcldpZHRoICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBjaGlsZENvbXBvbmVudC53aWR0aEluR3JpZCA9IE1hdGgubWF4KGNoaWxkQ29tcG9uZW50LndpZHRoSW5HcmlkIC0gcmVtYWluZGVyV2lkdGgsIEVkaXRhYmxlTGF5b3V0Q29tcG9uZW50LmdyaWRTcXVhcmVTaXplKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gYWRqdXN0IGZvciBtaW5pbXVtIGFyZWEgYm91bmRzXHJcbiAgICAgICAgICAgIGlmIChjaGlsZENvbXBvbmVudC5hcmVhIDwgY2hpbGRDb21wb25lbnQubWluQXJlYSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHdpZHRoTW9kaWZpZXIgPSAwO1xyXG4gICAgICAgICAgICAgICAgbGV0IGhlaWdodE1vZGlmaWVyID0gMDtcclxuICAgICAgICAgICAgICAgIGlmIChjaGlsZENvbXBvbmVudC53aWR0aEluR3JpZCA+PSBjaGlsZENvbXBvbmVudC5oZWlnaHRJbkdyaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB3aWR0aE1vZGlmaWVyID0gRWRpdGFibGVMYXlvdXRDb21wb25lbnQuZ3JpZFNxdWFyZVNpemU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGRDb21wb25lbnQuaGVpZ2h0SW5HcmlkID49IGNoaWxkQ29tcG9uZW50LndpZHRoSW5HcmlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0TW9kaWZpZXIgPSBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkU3F1YXJlU2l6ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNoaWxkQ29tcG9uZW50LndpZHRoSW5HcmlkICs9IHdpZHRoTW9kaWZpZXI7XHJcbiAgICAgICAgICAgICAgICBjaGlsZENvbXBvbmVudC5oZWlnaHRJbkdyaWQgKz0gaGVpZ2h0TW9kaWZpZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBARGVib3VuY2UoMClcclxuICAgIHByb3RlY3RlZCB1cGRhdGVMYXlvdXQoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuZWRpdGFibGVMYXlvdXRJdGVtcykge1xyXG4gICAgICAgICAgICBjb25zdCBsYXlvdXRXaWR0aCA9IHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aCB8fCAwO1xyXG4gICAgICAgICAgICBpZiAoIWxheW91dFdpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBjb29yZHMgYW5kIGJveFNpemVcclxuICAgICAgICAgICAgY29uc3QgZWRpdGFibGVMYXlvdXRJdGVtcyA9IHRoaXMuZWRpdGFibGVMYXlvdXRJdGVtcy50b0FycmF5KCk7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVkaXRhYmxlTGF5b3V0SXRlbXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0ud2lkdGhJbkdyaWQgPSBlZGl0YWJsZUxheW91dEl0ZW1zW2ldLndpZHRoSW5HcmlkO1xyXG4gICAgICAgICAgICAgICAgZWRpdGFibGVMYXlvdXRJdGVtc1tpXS5oZWlnaHRJbkdyaWQgPSBlZGl0YWJsZUxheW91dEl0ZW1zW2ldLmhlaWdodEluR3JpZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwic21lLWVkaXRhYmxlLWxheW91dC1ncmlkXCIgW3N0eWxlLmhlaWdodC5weF09XCJncmlkSGVpZ2h0XCIgW3N0eWxlLndpZHRoLnB4XT1cImdyaWRXaWR0aFwiPlxyXG48bmctY29udGVudCBzZWxlY3Q9XCJzbWUtZWRpdGFibGUtbGF5b3V0LWl0ZW1cIj48L25nLWNvbnRlbnQ+XHJcbjwvZGl2PlxyXG4iXX0=