ontimize-web-ngx
Version:
Ontimize Web framework using Angular 15
246 lines • 35.4 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { ChangeDetectionStrategy, Component, ElementRef, forwardRef, HostListener, Inject, NgZone, Renderer2, ViewEncapsulation } from '@angular/core';
import { BooleanInputConverter } from '../../../../../decorators/input-converter';
import { Util } from '../../../../../util/util';
import { OTableBase } from '../../../o-table-base.class';
import * as i0 from "@angular/core";
import * as i1 from "../../../o-table-base.class";
export const DEFAULT_INPUTS_O_TABLE_COLUMN_RESIZER = [
'column'
];
export const DEFAULT_OUTPUTS_O_TABLE_COLUMN_RESIZER = [];
export class OTableColumnResizerComponent {
constructor(table, elRef, ngZone, renderer) {
this.table = table;
this.elRef = elRef;
this.ngZone = ngZone;
this.renderer = renderer;
this.disabled = false;
this.dragListeners = [];
this.isResizing = false;
this.blockedMinCols = [];
this.blockedMaxCols = [];
this.columnsStartWidth = {};
}
ngOnInit() {
if (!this.isDisabled) {
this.headerEl = this.getHeaderEL();
if (this.headerEl) {
this.nextOColumns = this.getFollowingOColumns();
}
}
}
ngOnDestroy() {
this.stopDragging();
}
onClick(event) {
event.stopPropagation();
event.preventDefault();
}
get isDisabled() {
return this.column && !this.column.resizable;
}
onMousedown(e) {
if (!this.isDisabled) {
this.startResize(e);
}
}
onMouseup() {
this.isResizing = false;
this.stopDragging();
}
stopDragging() {
this.isResizing = false;
this.columnsStartWidth = {};
while (this.dragListeners.length > 0) {
const fct = this.dragListeners.pop();
if (fct) {
fct();
}
}
}
startResize(startEvent) {
startEvent.preventDefault();
startEvent.stopPropagation();
if (!Util.isDefined(this.headerEl)) {
return;
}
const DOMWidth = this.table.getClientWidthColumn(this.column);
this.startX = (startEvent instanceof MouseEvent) ? startEvent.screenX : startEvent.touches[0].screenX;
this.startWidth = DOMWidth;
this.minWidth = this.column.getMinWidthValue();
this.initializeWidthData();
this.ngZone.runOutsideAngular(() => {
this.dragListeners.push(this.renderer.listen('document', 'mouseup', () => this.stopDragging()));
this.dragListeners.push(this.renderer.listen('document', 'touchend', () => this.stopDragging()));
});
const moveEvent = (startEvent instanceof MouseEvent) ? 'mousemove' : 'touchmove';
this.ngZone.runOutsideAngular(() => {
this.dragListeners.push(this.renderer.listen('document', moveEvent, (e) => this.resizeEvent(e)));
});
this.isResizing = true;
}
resizeEvent(event) {
if (!this.isResizing) {
return;
}
const movementX = (event instanceof MouseEvent) ? (event.screenX - this.startX) : (event.touches[0].screenX - this.startX);
if (movementX === 0) {
return;
}
const newColumnWidth = this.startWidth + movementX;
const lessThanMin = newColumnWidth < this.minWidth;
const moreThanMax = newColumnWidth > this.maxWidth;
if (lessThanMin || moreThanMax) {
return;
}
if (!this.table.horizontalScroll) {
this.calculateNewColumnsWidth(movementX, newColumnWidth);
this.updateBlockedCols();
}
else {
this.column.setWidth(newColumnWidth);
}
this.table.cd.detectChanges();
}
getHeaderEL() {
let element;
let currentEl = this.elRef.nativeElement.parentElement;
while (!element && currentEl) {
if (currentEl.nodeName === 'TH') {
element = currentEl;
}
else {
currentEl = currentEl.parentElement;
}
}
return currentEl;
}
getFollowingOColumns() {
const result = [];
let nextTh = this.headerEl.nextSibling;
const self = this;
while (nextTh) {
const oCol = self.table.getOColumnFromTh(nextTh);
if (Util.isDefined(oCol)) {
result.push(oCol);
}
nextTh = nextTh.nextSibling;
}
return result;
}
updateBlockedCols() {
const self = this;
this.blockedMinCols = [];
this.blockedMaxCols = [];
const columns = [this.column, ...this.nextOColumns];
columns.forEach(oCol => {
const DOMWidth = this.table.getClientWidthColumn(oCol);
if (DOMWidth <= oCol.getMinWidthValue()) {
self.blockedMinCols.push(oCol.attr);
}
const maxW = oCol.getMaxWidthValue();
if (Util.isDefined(maxW) && DOMWidth >= maxW) {
self.blockedMaxCols.push(oCol.attr);
}
});
}
calculateNewColumnsWidth(movementX, newColumnWidth) {
const positive = (movementX > 0);
if (positive) {
this.calculateUsingNextColumnsRestrictions(movementX, newColumnWidth);
}
else {
this.calculateUsingOwnColumnRestriction(movementX, newColumnWidth);
}
}
calculateUsingNextColumnsRestrictions(movementX, newColumnWidth) {
const availableCols = this.nextOColumns.length - this.blockedMinCols.length;
if (availableCols <= 0) {
return;
}
const widthRatio = movementX / availableCols;
const cols = this.nextOColumns.filter((oCol) => this.blockedMinCols.indexOf(oCol.attr) === -1);
cols.forEach(oCol => {
let newWidth = (this.columnsStartWidth[oCol.attr] - widthRatio);
const minWidth = oCol.getMinWidthValue();
if (newWidth <= minWidth) {
newWidth = minWidth;
this.blockedMinCols.push(oCol.attr);
}
oCol.setWidth(newWidth);
});
this.column.setWidth(newColumnWidth);
}
calculateUsingOwnColumnRestriction(movementX, newColumnWidth) {
let widthRatio = Math.abs(movementX) / this.nextOColumns.length;
let widthDifference = 0;
if (widthRatio > 0 && this.blockedMaxCols.length < this.nextOColumns.length) {
const cols = this.nextOColumns.filter((oCol) => this.blockedMaxCols.indexOf(oCol.attr) === -1);
cols.forEach(oCol => {
let newWidthValue = (this.columnsStartWidth[oCol.attr] + widthRatio);
const maxWidth = oCol.getMaxWidthValue();
if (maxWidth && newWidthValue > maxWidth) {
const diff = newWidthValue - maxWidth;
newWidthValue = maxWidth;
this.blockedMaxCols.push(oCol.attr);
const notBlocked = this.nextOColumns.length - this.blockedMaxCols.length;
widthRatio += notBlocked > 0 ? Math.floor(diff / notBlocked) : 0;
}
const DOMWidth = this.table.getClientWidthColumn(oCol);
widthDifference += newWidthValue - DOMWidth;
oCol.setWidth(newWidthValue);
});
}
const newWidth = Math.min(this.startWidth - widthDifference, newColumnWidth);
this.column.setWidth(newWidth);
}
initializeWidthData() {
let maxWidth = this.column.getMaxWidthValue();
let nextColMinWidthAcum = 0;
let nextColWidthAcum = 0;
this.nextOColumns.forEach((col) => {
nextColMinWidthAcum += col.getMinWidthValue();
const DOMWidth = this.table.getClientWidthColumn(col);
nextColWidthAcum += DOMWidth;
this.columnsStartWidth[col.attr] = DOMWidth;
});
const calcMaxWidth = this.headerEl.clientWidth + (nextColWidthAcum - nextColMinWidthAcum);
if (Util.isDefined(maxWidth)) {
maxWidth = Math.min(maxWidth, calcMaxWidth);
}
else {
maxWidth = calcMaxWidth;
}
this.maxWidth = maxWidth;
}
}
OTableColumnResizerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OTableColumnResizerComponent, deps: [{ token: forwardRef(() => OTableBase) }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
OTableColumnResizerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OTableColumnResizerComponent, selector: "o-table-column-resizer", inputs: { column: "column" }, host: { listeners: { "mousedown": "onMousedown($event)", "touchstart": "onMousedown($event)", "document:mouseup": "onMouseup()", "document:touchend": "onMouseup()" }, properties: { "class.o-table-column-resizer": "true", "class.disabled": "isDisabled" } }, ngImport: i0, template: "<span class=\"resizer\" (click)=\"onClick($event)\"></span>", styles: [".o-table-column-resizer{display:inline-block;width:13px}.o-table-column-resizer:not(.disabled){cursor:col-resize}.o-table-column-resizer span{height:100%;width:1px;display:block;margin-left:auto;margin-right:auto}.o-table-column-resizer.disabled{cursor:default}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OTableColumnResizerComponent.prototype, "disabled", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OTableColumnResizerComponent, decorators: [{
type: Component,
args: [{ selector: 'o-table-column-resizer', inputs: DEFAULT_INPUTS_O_TABLE_COLUMN_RESIZER, outputs: DEFAULT_OUTPUTS_O_TABLE_COLUMN_RESIZER, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
'[class.o-table-column-resizer]': 'true',
'[class.disabled]': 'isDisabled',
}, template: "<span class=\"resizer\" (click)=\"onClick($event)\"></span>", styles: [".o-table-column-resizer{display:inline-block;width:13px}.o-table-column-resizer:not(.disabled){cursor:col-resize}.o-table-column-resizer span{height:100%;width:1px;display:block;margin-left:auto;margin-right:auto}.o-table-column-resizer.disabled{cursor:default}\n"] }]
}], ctorParameters: function () { return [{ type: i1.OTableBase, decorators: [{
type: Inject,
args: [forwardRef(() => OTableBase)]
}] }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }]; }, propDecorators: { disabled: [], onMousedown: [{
type: HostListener,
args: ['mousedown', ['$event']]
}, {
type: HostListener,
args: ['touchstart', ['$event']]
}], onMouseup: [{
type: HostListener,
args: ['document:mouseup']
}, {
type: HostListener,
args: ['document:touchend']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby10YWJsZS1jb2x1bW4tcmVzaXplci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbnRpbWl6ZS13ZWItbmd4L3NyYy9saWIvY29tcG9uZW50cy90YWJsZS9leHRlbnNpb25zL2hlYWRlci90YWJsZS1jb2x1bW4tcmVzaXplci9vLXRhYmxlLWNvbHVtbi1yZXNpemVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL3RhYmxlL2V4dGVuc2lvbnMvaGVhZGVyL3RhYmxlLWNvbHVtbi1yZXNpemVyL28tdGFibGUtY29sdW1uLXJlc2l6ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFVBQVUsRUFDVixVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixNQUFNLEVBR04sU0FBUyxFQUNULGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNsRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDZCQUE2QixDQUFDOzs7QUFFekQsTUFBTSxDQUFDLE1BQU0scUNBQXFDLEdBQUc7SUFDbkQsUUFBUTtDQUNULENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxzQ0FBc0MsR0FBRyxFQUdyRCxDQUFDO0FBZUYsTUFBTSxPQUFPLDRCQUE0QjtJQXlCdkMsWUFDK0MsS0FBaUIsRUFDcEQsS0FBaUIsRUFDakIsTUFBYyxFQUNkLFFBQW1CO1FBSGdCLFVBQUssR0FBTCxLQUFLLENBQVk7UUFDcEQsVUFBSyxHQUFMLEtBQUssQ0FBWTtR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QVMsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUM1QixRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLENBQUM7U0FDN0M7YUFBTTtZQUNMLFFBQVEsR0FBRyxZQUFZLENBQUM7U0FDekI7UUFDRCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixDQUFDOzswSEFqUFUsNEJBQTRCLGtCQTBCN0IsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQzs4R0ExQjNCLDRCQUE0Qiw2VkN6Q3pDLDZEQUF1RDtBRDRDckQ7SUFBQyxxQkFBcUIsRUFBRTs7OERBQ0U7NEZBSmYsNEJBQTRCO2tCQWJ4QyxTQUFTOytCQUNFLHdCQUF3QixVQUMxQixxQ0FBcUMsV0FDcEMsc0NBQXNDLG1CQUc5Qix1QkFBdUIsQ0FBQyxNQUFNLGlCQUNoQyxpQkFBaUIsQ0FBQyxJQUFJLFFBQy9CO3dCQUNKLGdDQUFnQyxFQUFFLE1BQU07d0JBQ3hDLGtCQUFrQixFQUFFLFlBQVk7cUJBQ2pDOzswQkE0QkUsTUFBTTsyQkFBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDO2tIQXRCdEMsUUFBUSxNQW9EUixXQUFXO3NCQUZWLFlBQVk7dUJBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDOztzQkFDcEMsWUFBWTt1QkFBQyxZQUFZLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBU3RDLFNBQVM7c0JBRlIsWUFBWTt1QkFBQyxrQkFBa0I7O3NCQUMvQixZQUFZO3VCQUFDLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIGZvcndhcmRSZWYsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5qZWN0LFxuICBOZ1pvbmUsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBSZW5kZXJlcjIsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBCb29sZWFuSW5wdXRDb252ZXJ0ZXIgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9kZWNvcmF0b3JzL2lucHV0LWNvbnZlcnRlcic7XG5pbXBvcnQgeyBVdGlsIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vdXRpbC91dGlsJztcbmltcG9ydCB0eXBlIHsgT0NvbHVtbiB9IGZyb20gJy4uLy4uLy4uL2NvbHVtbi9vLWNvbHVtbi5jbGFzcyc7XG5pbXBvcnQgeyBPVGFibGVCYXNlIH0gZnJvbSAnLi4vLi4vLi4vby10YWJsZS1iYXNlLmNsYXNzJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfSU5QVVRTX09fVEFCTEVfQ09MVU1OX1JFU0laRVIgPSBbXG4gICdjb2x1bW4nXG5dO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9PVVRQVVRTX09fVEFCTEVfQ09MVU1OX1JFU0laRVIgPSBbXG4gIC8vICdyZXNpemluZycsXG4gIC8vICdyZXNpemVkJ1xuXTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnby10YWJsZS1jb2x1bW4tcmVzaXplcicsXG4gIGlucHV0czogREVGQVVMVF9JTlBVVFNfT19UQUJMRV9DT0xVTU5fUkVTSVpFUixcbiAgb3V0cHV0czogREVGQVVMVF9PVVRQVVRTX09fVEFCTEVfQ09MVU1OX1JFU0laRVIsXG4gIHRlbXBsYXRlVXJsOiAnLi9vLXRhYmxlLWNvbHVtbi1yZXNpemVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vby10YWJsZS1jb2x1bW4tcmVzaXplci5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgaG9zdDoge1xuICAgICdbY2xhc3Muby10YWJsZS1jb2x1bW4tcmVzaXplcl0nOiAndHJ1ZScsXG4gICAgJ1tjbGFzcy5kaXNhYmxlZF0nOiAnaXNEaXNhYmxlZCcsXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgT1RhYmxlQ29sdW1uUmVzaXplckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICBjb2x1bW46IE9Db2x1bW47XG4gIEBCb29sZWFuSW5wdXRDb252ZXJ0ZXIoKVxuICBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIHJlc2l6aW5nID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuICAvLyByZXNpemVkID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gIHByb3RlY3RlZCBzdGFydFdpZHRoOiBhbnk7XG4gIHByb3RlY3RlZCBtaW5XaWR0aDogYW55O1xuICBwcm90ZWN0ZWQgbWF4V2lkdGg6IGFueTtcblxuICBwcm90ZWN0ZWQgc3RhcnRYOiBhbnk7XG5cbiAgcHJvdGVjdGVkIGhlYWRlckVsOiBhbnk7XG5cbiAgcHJvdGVjdGVkIG5leHRPQ29sdW1uczogT0NvbHVtbltdO1xuXG4gIHByb3RlY3RlZCBkcmFnTGlzdGVuZXJzOiBBcnJheTwoKSA9PiB2b2lkPiA9IFtdO1xuICBwcm90ZWN0ZWQgaXNSZXNpemluZzogYm9vbGVhbiA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgYmxvY2tlZE1pbkNvbHMgPSBbXTtcbiAgcHJvdGVjdGVkIGJsb2NrZWRNYXhDb2xzID0gW107XG5cbiAgcHJvdGVjdGVkIGNvbHVtbnNTdGFydFdpZHRoID0ge307XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChmb3J3YXJkUmVmKCgpID0+IE9UYWJsZUJhc2UpKSBwdWJsaWMgdGFibGU6IE9UYWJsZUJhc2UsXG4gICAgcHJvdGVjdGVkIGVsUmVmOiBFbGVtZW50UmVmLFxuICAgIHByb3RlY3RlZCBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcm90ZWN0ZWQgcmVuZGVyZXI6IFJlbmRlcmVyMlxuICApIHsgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0Rpc2FibGVkKSB7XG4gICAgICB0aGlzLmhlYWRlckVsID0gdGhpcy5nZXRIZWFkZXJFTCgpO1xuICAgICAgaWYgKHRoaXMuaGVhZGVyRWwpIHtcbiAgICAgICAgdGhpcy5uZXh0T0NvbHVtbnMgPSB0aGlzLmdldEZvbGxvd2luZ09Db2x1bW5zKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wRHJhZ2dpbmcoKTtcbiAgfVxuXG4gIG9uQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgZ2V0IGlzRGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29sdW1uICYmICF0aGlzLmNvbHVtbi5yZXNpemFibGU7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdtb3VzZWRvd24nLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgWyckZXZlbnQnXSlcbiAgb25Nb3VzZWRvd24oZTogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuaXNEaXNhYmxlZCkge1xuICAgICAgdGhpcy5zdGFydFJlc2l6ZShlKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZXVwJylcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6dG91Y2hlbmQnKVxuICBvbk1vdXNldXAoKSB7XG4gICAgdGhpcy5pc1Jlc2l6aW5nID0gZmFsc2U7XG4gICAgdGhpcy5zdG9wRHJhZ2dpbmcoKTtcbiAgICAvLyB0aGlzLnJlc2l6ZS5lbWl0KHRoaXMuZWxlbWVudC5jbGllbnRXaWR0aCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc3RvcERyYWdnaW5nKCkge1xuICAgIHRoaXMuaXNSZXNpemluZyA9IGZhbHNlO1xuICAgIHRoaXMuY29sdW1uc1N0YXJ0V2lkdGggPSB7fTtcbiAgICB3aGlsZSAodGhpcy5kcmFnTGlzdGVuZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGZjdCA9IHRoaXMuZHJhZ0xpc3RlbmVycy5wb3AoKTtcbiAgICAgIGlmIChmY3QpIHtcbiAgICAgICAgZmN0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhcnRSZXNpemUoc3RhcnRFdmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpOiB2b2lkIHtcbiAgICBzdGFydEV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgc3RhcnRFdmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIVV0aWwuaXNEZWZpbmVkKHRoaXMuaGVhZGVyRWwpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IERPTVdpZHRoID0gdGhpcy50YWJsZS5nZXRDbGllbnRXaWR0aENvbHVtbih0aGlzLmNvbHVtbik7XG4gICAgdGhpcy5zdGFydFggPSAoc3RhcnRFdmVudCBpbnN0YW5jZW9mIE1vdXNlRXZlbnQpID8gc3RhcnRFdmVudC5zY3JlZW5YIDogc3RhcnRFdmVudC50b3VjaGVzWzBdLnNjcmVlblg7XG4gICAgdGhpcy5zdGFydFdpZHRoID0gRE9NV2lkdGg7XG4gICAgdGhpcy5taW5XaWR0aCA9IHRoaXMuY29sdW1uLmdldE1pbldpZHRoVmFsdWUoKTtcbiAgICB0aGlzLmluaXRpYWxpemVXaWR0aERhdGEoKTtcbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICB0aGlzLmRyYWdMaXN0ZW5lcnMucHVzaCh0aGlzLnJlbmRlcmVyLmxpc3RlbignZG9jdW1lbnQnLCAnbW91c2V1cCcsICgpID0+IHRoaXMuc3RvcERyYWdnaW5nKCkpKTtcbiAgICAgIHRoaXMuZHJhZ0xpc3RlbmVycy5wdXNoKHRoaXMucmVuZGVyZXIubGlzdGVuKCdkb2N1bWVudCcsICd0b3VjaGVuZCcsICgpID0+IHRoaXMuc3RvcERyYWdnaW5nKCkpKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG1vdmVFdmVudCA9IChzdGFydEV2ZW50IGluc3RhbmNlb2YgTW91c2VFdmVudCkgPyAnbW91c2Vtb3ZlJyA6ICd0b3VjaG1vdmUnO1xuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHRoaXMuZHJhZ0xpc3RlbmVycy5wdXNoKHRoaXMucmVuZGVyZXIubGlzdGVuKCdkb2N1bWVudCcsIG1vdmVFdmVudCwgKGU6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB0aGlzLnJlc2l6ZUV2ZW50KGUpKSk7XG4gICAgfSk7XG4gICAgdGhpcy5pc1Jlc2l6aW5nID0gdHJ1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZXNpemVFdmVudChldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNSZXNpemluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtb3ZlbWVudFggPSAoZXZlbnQgaW5zdGFuY2VvZiBNb3VzZUV2ZW50KSA/IChldmVudC5zY3JlZW5YIC0gdGhpcy5zdGFydFgpIDogKGV2ZW50LnRvdWNoZXNbMF0uc2NyZWVuWCAtIHRoaXMuc3RhcnRYKTtcbiAgICBpZiAobW92ZW1lbnRYID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5ld0NvbHVtbldpZHRoID0gdGhpcy5zdGFydFdpZHRoICsgbW92ZW1lbnRYO1xuXG4gICAgY29uc3QgbGVzc1RoYW5NaW4gPSBuZXdDb2x1bW5XaWR0aCA8IHRoaXMubWluV2lkdGg7XG4gICAgY29uc3QgbW9yZVRoYW5NYXggPSBuZXdDb2x1bW5XaWR0aCA+IHRoaXMubWF4V2lkdGg7XG4gICAgaWYgKGxlc3NUaGFuTWluIHx8IG1vcmVUaGFuTWF4KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy50YWJsZS5ob3Jpem9udGFsU2Nyb2xsKSB7XG4gICAgICB0aGlzLmNhbGN1bGF0ZU5ld0NvbHVtbnNXaWR0aChtb3ZlbWVudFgsIG5ld0NvbHVtbldpZHRoKTtcbiAgICAgIHRoaXMudXBkYXRlQmxvY2tlZENvbHMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb2x1bW4uc2V0V2lkdGgobmV3Q29sdW1uV2lkdGgpO1xuICAgIH1cbiAgICB0aGlzLnRhYmxlLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRIZWFkZXJFTCgpOiBOb2RlIHtcbiAgICBsZXQgZWxlbWVudDtcbiAgICBsZXQgY3VycmVudEVsOiBOb2RlID0gdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LnBhcmVudEVsZW1lbnQ7XG4gICAgd2hpbGUgKCFlbGVtZW50ICYmIGN1cnJlbnRFbCkge1xuICAgICAgaWYgKGN1cnJlbnRFbC5ub2RlTmFtZSA9PT0gJ1RIJykge1xuICAgICAgICBlbGVtZW50ID0gY3VycmVudEVsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudEVsID0gY3VycmVudEVsLnBhcmVudEVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjdXJyZW50RWw7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0Rm9sbG93aW5nT0NvbHVtbnMoKTogT0NvbHVtbltdIHtcbiAgICBjb25zdCByZXN1bHQ6IE9Db2x1bW5bXSA9IFtdO1xuICAgIGxldCBuZXh0VGg6IGFueSA9IHRoaXMuaGVhZGVyRWwubmV4dFNpYmxpbmc7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgd2hpbGUgKG5leHRUaCkge1xuICAgICAgY29uc3Qgb0NvbDogT0NvbHVtbiA9IHNlbGYudGFibGUuZ2V0T0NvbHVtbkZyb21UaChuZXh0VGgpO1xuICAgICAgaWYgKFV0aWwuaXNEZWZpbmVkKG9Db2wpKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKG9Db2wpO1xuICAgICAgfVxuICAgICAgbmV4dFRoID0gbmV4dFRoLm5leHRTaWJsaW5nO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIHVwZGF0ZUJsb2NrZWRDb2xzKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuYmxvY2tlZE1pbkNvbHMgPSBbXTtcbiAgICB0aGlzLmJsb2NrZWRNYXhDb2xzID0gW107XG4gICAgY29uc3QgY29sdW1ucyA9IFt0aGlzLmNvbHVtbiwgLi4udGhpcy5uZXh0T0NvbHVtbnNdO1xuICAgIGNvbHVtbnMuZm9yRWFjaChvQ29sID0+IHtcbiAgICAgIGNvbnN0IERPTVdpZHRoID0gdGhpcy50YWJsZS5nZXRDbGllbnRXaWR0aENvbHVtbihvQ29sKTtcbiAgICAgIGlmIChET01XaWR0aCA8PSBvQ29sLmdldE1pbldpZHRoVmFsdWUoKSkge1xuICAgICAgICBzZWxmLmJsb2NrZWRNaW5Db2xzLnB1c2gob0NvbC5hdHRyKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1heFcgPSBvQ29sLmdldE1heFdpZHRoVmFsdWUoKTtcbiAgICAgIGlmIChVdGlsLmlzRGVmaW5lZChtYXhXKSAmJiBET01XaWR0aCA+PSBtYXhXKSB7XG4gICAgICAgIHNlbGYuYmxvY2tlZE1heENvbHMucHVzaChvQ29sLmF0dHIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNhbGN1bGF0ZU5ld0NvbHVtbnNXaWR0aChtb3ZlbWVudFg6IG51bWJlciwgbmV3Q29sdW1uV2lkdGg6IG51bWJlcikge1xuICAgIGNvbnN0IHBvc2l0aXZlID0gKG1vdmVtZW50WCA+IDApO1xuICAgIGlmIChwb3NpdGl2ZSkge1xuICAgICAgdGhpcy5jYWxjdWxhdGVVc2luZ05leHRDb2x1bW5zUmVzdHJpY3Rpb25zKG1vdmVtZW50WCwgbmV3Q29sdW1uV2lkdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNhbGN1bGF0ZVVzaW5nT3duQ29sdW1uUmVzdHJpY3Rpb24obW92ZW1lbnRYLCBuZXdDb2x1bW5XaWR0aCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGNhbGN1bGF0ZVVzaW5nTmV4dENvbHVtbnNSZXN0cmljdGlvbnMobW92ZW1lbnRYOiBudW1iZXIsIG5ld0NvbHVtbldpZHRoOiBudW1iZXIpIHtcbiAgICBjb25zdCBhdmFpbGFibGVDb2xzID0gdGhpcy5uZXh0T0NvbHVtbnMubGVuZ3RoIC0gdGhpcy5ibG9ja2VkTWluQ29scy5sZW5ndGg7XG4gICAgaWYgKGF2YWlsYWJsZUNvbHMgPD0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB3aWR0aFJhdGlvID0gbW92ZW1lbnRYIC8gYXZhaWxhYmxlQ29scztcbiAgICBjb25zdCBjb2xzID0gdGhpcy5uZXh0T0NvbHVtbnMuZmlsdGVyKChvQ29sOiBPQ29sdW1uKSA9PiB0aGlzLmJsb2NrZWRNaW5Db2xzLmluZGV4T2Yob0NvbC5hdHRyKSA9PT0gLTEpO1xuICAgIGNvbHMuZm9yRWFjaChvQ29sID0+IHtcbiAgICAgIGxldCBuZXdXaWR0aCA9ICh0aGlzLmNvbHVtbnNTdGFydFdpZHRoW29Db2wuYXR0cl0gLSB3aWR0aFJhdGlvKTtcbiAgICAgIGNvbnN0IG1pbldpZHRoID0gb0NvbC5nZXRNaW5XaWR0aFZhbHVlKCk7XG4gICAgICBpZiAobmV3V2lkdGggPD0gbWluV2lkdGgpIHtcbiAgICAgICAgbmV3V2lkdGggPSBtaW5XaWR0aDtcbiAgICAgICAgdGhpcy5ibG9ja2VkTWluQ29scy5wdXNoKG9Db2wuYXR0cik7XG4gICAgICB9XG4gICAgICBvQ29sLnNldFdpZHRoKG5ld1dpZHRoKTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbHVtbi5zZXRXaWR0aChuZXdDb2x1bW5XaWR0aCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2FsY3VsYXRlVXNpbmdPd25Db2x1bW5SZXN0cmljdGlvbihtb3ZlbWVudFg6IG51bWJlciwgbmV3Q29sdW1uV2lkdGg6IG51bWJlcikge1xuICAgIGxldCB3aWR0aFJhdGlvID0gTWF0aC5hYnMobW92ZW1lbnRYKSAvIHRoaXMubmV4dE9Db2x1bW5zLmxlbmd0aDtcbiAgICBsZXQgd2lkdGhEaWZmZXJlbmNlID0gMDtcbiAgICBpZiAod2lkdGhSYXRpbyA+IDAgJiYgdGhpcy5ibG9ja2VkTWF4Q29scy5sZW5ndGggPCB0aGlzLm5leHRPQ29sdW1ucy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IGNvbHMgPSB0aGlzLm5leHRPQ29sdW1ucy5maWx0ZXIoKG9Db2w6IE9Db2x1bW4pID0+IHRoaXMuYmxvY2tlZE1heENvbHMuaW5kZXhPZihvQ29sLmF0dHIpID09PSAtMSk7XG4gICAgICBjb2xzLmZvckVhY2gob0NvbCA9PiB7XG4gICAgICAgIGxldCBuZXdXaWR0aFZhbHVlID0gKHRoaXMuY29sdW1uc1N0YXJ0V2lkdGhbb0NvbC5hdHRyXSArIHdpZHRoUmF0aW8pO1xuICAgICAgICBjb25zdCBtYXhXaWR0aCA9IG9Db2wuZ2V0TWF4V2lkdGhWYWx1ZSgpO1xuICAgICAgICBpZiAobWF4V2lkdGggJiYgbmV3V2lkdGhWYWx1ZSA+IG1heFdpZHRoKSB7XG4gICAgICAgICAgY29uc3QgZGlmZiA9IG5ld1dpZHRoVmFsdWUgLSBtYXhXaWR0aDtcbiAgICAgICAgICBuZXdXaWR0aFZhbHVlID0gbWF4V2lkdGg7XG4gICAgICAgICAgdGhpcy5ibG9ja2VkTWF4Q29scy5wdXNoKG9Db2wuYXR0cik7XG4gICAgICAgICAgY29uc3Qgbm90QmxvY2tlZCA9IHRoaXMubmV4dE9Db2x1bW5zLmxlbmd0aCAtIHRoaXMuYmxvY2tlZE1heENvbHMubGVuZ3RoO1xuICAgICAgICAgIHdpZHRoUmF0aW8gKz0gbm90QmxvY2tlZCA+IDAgPyBNYXRoLmZsb29yKGRpZmYgLyBub3RCbG9ja2VkKSA6IDA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgRE9NV2lkdGggPSB0aGlzLnRhYmxlLmdldENsaWVudFdpZHRoQ29sdW1uKG9Db2wpO1xuICAgICAgICB3aWR0aERpZmZlcmVuY2UgKz0gbmV3V2lkdGhWYWx1ZSAtIERPTVdpZHRoO1xuICAgICAgICBvQ29sLnNldFdpZHRoKG5ld1dpZHRoVmFsdWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IG5ld1dpZHRoID0gTWF0aC5taW4odGhpcy5zdGFydFdpZHRoIC0gd2lkdGhEaWZmZXJlbmNlLCBuZXdDb2x1bW5XaWR0aCk7XG4gICAgdGhpcy5jb2x1bW4uc2V0V2lkdGgobmV3V2lkdGgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGluaXRpYWxpemVXaWR0aERhdGEoKSB7XG4gICAgbGV0IG1heFdpZHRoID0gdGhpcy5jb2x1bW4uZ2V0TWF4V2lkdGhWYWx1ZSgpO1xuICAgIGxldCBuZXh0Q29sTWluV2lkdGhBY3VtID0gMDtcbiAgICBsZXQgbmV4dENvbFdpZHRoQWN1bSA9IDA7XG4gICAgdGhpcy5uZXh0T0NvbHVtbnMuZm9yRWFjaCgoY29sOiBPQ29sdW1uKSA9PiB7XG4gICAgICBuZXh0Q29sTWluV2lkdGhBY3VtICs9IGNvbC5nZXRNaW5XaWR0aFZhbHVlKCk7XG4gICAgICBjb25zdCBET01XaWR0aCA9IHRoaXMudGFibGUuZ2V0Q2xpZW50V2lkdGhDb2x1bW4oY29sKTtcbiAgICAgIG5leHRDb2xXaWR0aEFjdW0gKz0gRE9NV2lkdGg7XG4gICAgICB0aGlzLmNvbHVtbnNTdGFydFdpZHRoW2NvbC5hdHRyXSA9IERPTVdpZHRoO1xuICAgIH0pO1xuICAgIGNvbnN0IGNhbGNNYXhXaWR0aCA9IHRoaXMuaGVhZGVyRWwuY2xpZW50V2lkdGggKyAobmV4dENvbFdpZHRoQWN1bSAtIG5leHRDb2xNaW5XaWR0aEFjdW0pO1xuICAgIGlmIChVdGlsLmlzRGVmaW5lZChtYXhXaWR0aCkpIHtcbiAgICAgIG1heFdpZHRoID0gTWF0aC5taW4obWF4V2lkdGgsIGNhbGNNYXhXaWR0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1heFdpZHRoID0gY2FsY01heFdpZHRoO1xuICAgIH1cbiAgICB0aGlzLm1heFdpZHRoID0gbWF4V2lkdGg7XG4gIH1cblxufVxuIiwiPHNwYW4gY2xhc3M9XCJyZXNpemVyXCIgKGNsaWNrKT1cIm9uQ2xpY2soJGV2ZW50KVwiPjwvc3Bhbj4iXX0=