UNPKG

stimulsoft-forms

Version:
192 lines 32.8 kB
import { Injectable } from "@angular/core"; import { StiFormPageElement } from "../elements/StiFormPageElement"; import StiRectangleGeometry from "../properties/StiRectangleGeometry"; import * as i0 from "@angular/core"; import * as i1 from "../services/model.service"; import * as i2 from "../services/sti-name.service"; export default class StiRectangleGeometryLayout { constructor(model, nameService) { this.model = model; this.nameService = nameService; } insertElement(newElement, contentAreaWidth = 0) { // let fixedGeometry = this.fixForInsert(newElement.geometry); let parentElement = this.model.getElementPage(newElement) ?? this.model.getElementPanel(newElement); let otherElements = Array.from(parentElement.elements); otherElements.splice(otherElements.indexOf(newElement), 1); if (newElement) { let fixedGeometry = newElement.geometry; this.insertFixed(fixedGeometry, newElement, otherElements, contentAreaWidth); } } isHigherThan(left, right) { return left.bottom <= right.y; } isHigherThan2(left, right) { return left.bottom - left.height / 2 <= right.y; } removeElement(elementToRemove, otherElements) { let elementsAbove = []; let elementsBelow = []; for (let element of otherElements) { if (this.isHigherThan(element.geometry, elementToRemove.geometry)) { elementsAbove.push(element); } else { elementsBelow.push(element); } } this.snapBelowsToAboves(elementsBelow, elementsAbove); } changeElementGeometry(elementToChange, otherElements, contentAreaWidth = 0) { let fixedGeometry = elementToChange.geometry; this.insertFixed(fixedGeometry, elementToChange, otherElements, contentAreaWidth); } fitWidth(fixedGeometry, otherElements, contentAreaWidth) { if (contentAreaWidth > 0) { let right = contentAreaWidth; let rect = new StiRectangleGeometry(fixedGeometry.width - fixedGeometry.minWidth, fixedGeometry.height / 2); rect.x = fixedGeometry.x + fixedGeometry.minWidth; rect.y = fixedGeometry.y; otherElements.forEach((element) => { if (element.geometry.intersectWith(rect)) { right = Math.min(right, element.geometry.x); } }); let newWidth = fixedGeometry.width - (fixedGeometry.right - right); if (newWidth + StiRectangleGeometry.DELTA > fixedGeometry.minWidth && newWidth <= fixedGeometry.width + StiRectangleGeometry.DELTA) { fixedGeometry.width = newWidth; } } } insertFixed(fixedGeometry, elementToInsert, otherElements, contentAreaWidth) { let elementsAbove = []; let elementsBelow = []; for (let element of otherElements) { if (this.isHigherThan2(element.geometry, fixedGeometry)) { elementsAbove.push(element); } else { elementsBelow.push(element); } } this.fitWidth(fixedGeometry, otherElements, contentAreaWidth); let snappedNewGeometry = this.snapOneToAboves(fixedGeometry, elementsAbove, true); elementToInsert.geometry = snappedNewGeometry; elementsAbove.push(elementToInsert); this.moveDown(elementsBelow, 2 * snappedNewGeometry.height); this.snapBelowsToAboves(elementsBelow, elementsAbove); this.fitWidth(snappedNewGeometry, otherElements, contentAreaWidth); } snapOneToAboves(geometry, elementsAboveToSnap, canShrink = false) { let elementsExcatlyAbove = elementsAboveToSnap.filter((element) => element.geometry.xProjectionIntersectsWith(geometry)); if (elementsExcatlyAbove.length > 0) { let max = elementsExcatlyAbove.reduce((acc, curr) => (acc.geometry.bottom > curr.geometry.bottom ? acc : curr)); return geometry.withY(max.geometry.bottom); } else return geometry.withY(0); } moveDown(elementsToMoveDown, distance) { for (let element of elementsToMoveDown) { element.geometry = element.geometry.withY(element.geometry.y + distance); } } snapBelowsToAboves(belows, aboves) { belows.sort(function (left, right) { let difference = left.geometry.y - right.geometry.y; if (difference < StiRectangleGeometry.DELTA) { return -1; } else if (difference > StiRectangleGeometry.DELTA) { return 1; } else { return 0; } }); for (let element of belows) { let snappedFromBelow = this.snapOneToAboves(element.geometry, aboves); element.geometry = snappedFromBelow; aboves.push(element); } } getFreeToBottomResizeArea(currentResizeElement, otherElements) { let currentContainer = this.model.getElementPage(currentResizeElement) ?? this.model.getElementPanel(currentResizeElement); let geometry = currentResizeElement.geometry; let bottomElements = otherElements?.filter((element) => element.y >= geometry.bottom); let elementsExcatlyBelow = bottomElements?.filter((element) => element.geometry.xProjectionIntersectsWith(geometry)); let bottomPoints = elementsExcatlyBelow?.map((element) => { return element.geometry.bottom; }); let topPoints = elementsExcatlyBelow?.map((element) => { return element.geometry.y; }); let maxBottomPoint = Math.max(...bottomPoints); let minTopPoint = Math.min(...topPoints); let bottomElementsHeight = maxBottomPoint - minTopPoint; return (currentContainer.contentAreaHeight - geometry.bottom - (elementsExcatlyBelow.length > 0 ? bottomElementsHeight : 0)); } checkOutputs(usedPage) { let outputElements = []; let summaryHeight = 0; usedPage?.elements.forEach((element) => { if (element.geometry.bottom > usedPage.contentAreaHeight) { outputElements.push(element); } }); if (outputElements.length > 0) { outputElements.forEach((element) => { summaryHeight += element.height; usedPage.elements.splice(usedPage.elements.indexOf(element), 1); this.removeElement(element, usedPage.elements); }); if (this.model.form.pages[this.model.form.pages.indexOf(usedPage) + 1]) { let nextPage = this.model.form.pages[this.model.form.pages.indexOf(usedPage) + 1]; if (nextPage.contentAreaHeight - Math.max(...nextPage.elements.map((element) => element.geometry.bottom)) > summaryHeight) { let currentBottomPoint = 0; outputElements.forEach((element, index) => { nextPage.elements.splice(index, 0, element); element.y = currentBottomPoint; this.insertElement(element); currentBottomPoint += element.height; }); } else { let page1 = new StiFormPageElement(this.model.form); page1.name = this.nameService.getElementName(page1); this.model.form.pages.splice(this.model.form.pages.indexOf(nextPage), 0, page1); let currentBottomPoint = 0; outputElements.forEach((element, index) => { page1.elements.splice(index, 0, element); element.y = currentBottomPoint; this.insertElement(element); currentBottomPoint += element.height; }); } } else { let page1 = new StiFormPageElement(this.model.form); page1.name = this.nameService.getElementName(page1); this.model.form.pages.push(page1); let currentBottomPoint = 0; outputElements.forEach((element, index) => { page1.elements.splice(index, 0, element); element.y = currentBottomPoint; this.insertElement(element); currentBottomPoint += element.geometry.bottom; }); } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiRectangleGeometryLayout, deps: [{ token: i1.StiModelService }, { token: i2.StiNameService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiRectangleGeometryLayout }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiRectangleGeometryLayout, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.StiModelService }, { type: i2.StiNameService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RpUmVjdGFuZ2xlR2VvbWV0cnlMYXlvdXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zdGltdWxzb2Z0LWZvcm1zL3NyYy9saWIvY29tcHV0ZWQvU3RpUmVjdGFuZ2xlR2VvbWV0cnlMYXlvdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLG9CQUFvQixNQUFNLG9DQUFvQyxDQUFDOzs7O0FBS3RFLE1BQU0sQ0FBQyxPQUFPLE9BQU8sMEJBQTBCO0lBRzdDLFlBQW1CLEtBQXNCLEVBQVMsV0FBMkI7UUFBMUQsVUFBSyxHQUFMLEtBQUssQ0FBaUI7UUFBUyxnQkFBVyxHQUFYLFdBQVcsQ0FBZ0I7SUFBSSxDQUFDO0lBQzNFLGFBQWEsQ0FBQyxVQUEwQixFQUFFLG1CQUEyQixDQUFDO1FBQzNFLDhEQUE4RDtRQUM5RCxJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwRyxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2RCxhQUFhLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0QsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLElBQUksYUFBYSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDeEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQy9FLENBQUM7SUFD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QixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUM1QixrQkFBa0IsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztnQkFDaEQsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7K0dBN01rQiwwQkFBMEI7bUhBQTFCLDBCQUEwQjs7NEZBQTFCLDBCQUEwQjtrQkFEOUMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBTdGlGb3JtRWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50cy9iYXNlL1N0aUZvcm1FbGVtZW50XCI7XHJcbmltcG9ydCB7IFN0aUZvcm1QYWdlRWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50cy9TdGlGb3JtUGFnZUVsZW1lbnRcIjtcclxuaW1wb3J0IFN0aVJlY3RhbmdsZUdlb21ldHJ5IGZyb20gXCIuLi9wcm9wZXJ0aWVzL1N0aVJlY3RhbmdsZUdlb21ldHJ5XCI7XHJcbmltcG9ydCB7IFN0aU1vZGVsU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlcy9tb2RlbC5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFN0aU5hbWVTZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL3N0aS1uYW1lLnNlcnZpY2VcIjtcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3RpUmVjdGFuZ2xlR2VvbWV0cnlMYXlvdXQge1xyXG4gIHB1YmxpYyB3aWR0aDogbnVtYmVyO1xyXG4gIHB1YmxpYyBoZWlnaHQ6IG51bWJlcjtcclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbW9kZWw6IFN0aU1vZGVsU2VydmljZSwgcHVibGljIG5hbWVTZXJ2aWNlOiBTdGlOYW1lU2VydmljZSkgeyB9XHJcbiAgcHVibGljIGluc2VydEVsZW1lbnQobmV3RWxlbWVudDogU3RpRm9ybUVsZW1lbnQsIGNvbnRlbnRBcmVhV2lkdGg6IG51bWJlciA9IDApIHtcclxuICAgIC8vIGxldCBmaXhlZEdlb21ldHJ5ID0gdGhpcy5maXhGb3JJbnNlcnQobmV3RWxlbWVudC5nZW9tZXRyeSk7XHJcbiAgICBsZXQgcGFyZW50RWxlbWVudCA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudFBhZ2UobmV3RWxlbWVudCkgPz8gdGhpcy5tb2RlbC5nZXRFbGVtZW50UGFuZWwobmV3RWxlbWVudCk7XHJcbiAgICBsZXQgb3RoZXJFbGVtZW50cyA9IEFycmF5LmZyb20ocGFyZW50RWxlbWVudC5lbGVtZW50cyk7XHJcbiAgICBvdGhlckVsZW1lbnRzLnNwbGljZShvdGhlckVsZW1lbnRzLmluZGV4T2YobmV3RWxlbWVudCksIDEpO1xyXG4gICAgaWYgKG5ld0VsZW1lbnQpIHtcclxuICAgICAgbGV0IGZpeGVkR2VvbWV0cnkgPSBuZXdFbGVtZW50Lmdlb21ldHJ5O1xyXG4gICAgICB0aGlzLmluc2VydEZpeGVkKGZpeGVkR2VvbWV0cnksIG5ld0VsZW1lbnQsIG90aGVyRWxlbWVudHMsIGNvbnRlbnRBcmVhV2lkdGgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGlzSGlnaGVyVGhhbihsZWZ0OiBTdGlSZWN0YW5nbGVHZW9tZXRyeSwgcmlnaHQ6IFN0aVJlY3RhbmdsZUdlb21ldHJ5KTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gbGVmdC5ib3R0b20gPD0gcmlnaHQueTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBpc0hpZ2hlclRoYW4yKGxlZnQ6IFN0aVJlY3RhbmdsZUdlb21ldHJ5LCByaWdodDogU3RpUmVjdGFuZ2xlR2VvbWV0cnkpOiBib29sZWFuIHtcclxuICAgIHJldHVybiBsZWZ0LmJvdHRvbSAtIGxlZnQuaGVpZ2h0IC8gMiA8PSByaWdodC55O1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHJlbW92ZUVsZW1lbnQoZWxlbWVudFRvUmVtb3ZlOiBTdGlGb3JtRWxlbWVudCwgb3RoZXJFbGVtZW50czogU3RpRm9ybUVsZW1lbnRbXSkge1xyXG4gICAgbGV0IGVsZW1lbnRzQWJvdmU6IFN0aUZvcm1FbGVtZW50W10gPSBbXTtcclxuICAgIGxldCBlbGVtZW50c0JlbG93OiBTdGlGb3JtRWxlbWVudFtdID0gW107XHJcbiAgICBmb3IgKGxldCBlbGVtZW50IG9mIG90aGVyRWxlbWVudHMpIHtcclxuICAgICAgaWYgKHRoaXMuaXNIaWdoZXJUaGFuKGVsZW1lbnQuZ2VvbWV0cnksIGVsZW1lbnRUb1JlbW92ZS5nZW9tZXRyeSkpIHtcclxuICAgICAgICBlbGVtZW50c0Fib3ZlLnB1c2goZWxlbWVudCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZWxlbWVudHNCZWxvdy5wdXNoKGVsZW1lbnQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLnNuYXBCZWxvd3NUb0Fib3ZlcyhlbGVtZW50c0JlbG93LCBlbGVtZW50c0Fib3ZlKTtcclxuICB9XHJcbiAgcHVibGljIGNoYW5nZUVsZW1lbnRHZW9tZXRyeShcclxuICAgIGVsZW1lbnRUb0NoYW5nZTogU3RpRm9ybUVsZW1lbnQsXHJcbiAgICBvdGhlckVsZW1lbnRzOiBTdGlGb3JtRWxlbWVudFtdLFxyXG4gICAgY29udGVudEFyZWFXaWR0aDogbnVtYmVyID0gMFxyXG4gICkge1xyXG4gICAgbGV0IGZpeGVkR2VvbWV0cnkgPSBlbGVtZW50VG9DaGFuZ2UuZ2VvbWV0cnk7XHJcbiAgICB0aGlzLmluc2VydEZpeGVkKGZpeGVkR2VvbWV0cnksIGVsZW1lbnRUb0NoYW5nZSwgb3RoZXJFbGVtZW50cywgY29udGVudEFyZWFXaWR0aCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZpdFdpZHRoKGZpeGVkR2VvbWV0cnk6IFN0aVJlY3RhbmdsZUdlb21ldHJ5LCBvdGhlckVsZW1lbnRzOiBTdGlGb3JtRWxlbWVudFtdLCBjb250ZW50QXJlYVdpZHRoOiBudW1iZXIpIHtcclxuICAgIGlmIChjb250ZW50QXJlYVdpZHRoID4gMCkge1xyXG4gICAgICBsZXQgcmlnaHQgPSBjb250ZW50QXJlYVdpZHRoO1xyXG4gICAgICBsZXQgcmVjdCA9IG5ldyBTdGlSZWN0YW5nbGVHZW9tZXRyeShmaXhlZEdlb21ldHJ5LndpZHRoIC0gZml4ZWRHZW9tZXRyeS5taW5XaWR0aCwgZml4ZWRHZW9tZXRyeS5oZWlnaHQgLyAyKTtcclxuICAgICAgcmVjdC54ID0gZml4ZWRHZW9tZXRyeS54ICsgZml4ZWRHZW9tZXRyeS5taW5XaWR0aDtcclxuICAgICAgcmVjdC55ID0gZml4ZWRHZW9tZXRyeS55O1xyXG5cclxuICAgICAgb3RoZXJFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKGVsZW1lbnQuZ2VvbWV0cnkuaW50ZXJzZWN0V2l0aChyZWN0KSkge1xyXG4gICAgICAgICAgcmlnaHQgPSBNYXRoLm1pbihyaWdodCwgZWxlbWVudC5nZW9tZXRyeS54KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbGV0IG5ld1dpZHRoID0gZml4ZWRHZW9tZXRyeS53aWR0aCAtIChmaXhlZEdlb21ldHJ5LnJpZ2h0IC0gcmlnaHQpO1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgbmV3V2lkdGggKyBTdGlSZWN0YW5nbGVHZW9tZXRyeS5ERUxUQSA+IGZpeGVkR2VvbWV0cnkubWluV2lkdGggJiZcclxuICAgICAgICBuZXdXaWR0aCA8PSBmaXhlZEdlb21ldHJ5LndpZHRoICsgU3RpUmVjdGFuZ2xlR2VvbWV0cnkuREVMVEFcclxuICAgICAgKSB7XHJcbiAgICAgICAgZml4ZWRHZW9tZXRyeS53aWR0aCA9IG5ld1dpZHRoO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluc2VydEZpeGVkKFxyXG4gICAgZml4ZWRHZW9tZXRyeTogU3RpUmVjdGFuZ2xlR2VvbWV0cnksXHJcbiAgICBlbGVtZW50VG9JbnNlcnQ6IFN0aUZvcm1FbGVtZW50LFxyXG4gICAgb3RoZXJFbGVtZW50czogU3RpRm9ybUVsZW1lbnRbXSxcclxuICAgIGNvbnRlbnRBcmVhV2lkdGg6IG51bWJlclxyXG4gICkge1xyXG4gICAgbGV0IGVsZW1lbnRzQWJvdmU6IFN0aUZvcm1FbGVtZW50W10gPSBbXTtcclxuICAgIGxldCBlbGVtZW50c0JlbG93OiBTdGlGb3JtRWxlbWVudFtdID0gW107XHJcbiAgICBmb3IgKGxldCBlbGVtZW50IG9mIG90aGVyRWxlbWVudHMpIHtcclxuICAgICAgaWYgKHRoaXMuaXNIaWdoZXJUaGFuMihlbGVtZW50Lmdlb21ldHJ5LCBmaXhlZEdlb21ldHJ5KSkge1xyXG4gICAgICAgIGVsZW1lbnRzQWJvdmUucHVzaChlbGVtZW50KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBlbGVtZW50c0JlbG93LnB1c2goZWxlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmZpdFdpZHRoKGZpeGVkR2VvbWV0cnksIG90aGVyRWxlbWVudHMsIGNvbnRlbnRBcmVhV2lkdGgpO1xyXG5cclxuICAgIGxldCBzbmFwcGVkTmV3R2VvbWV0cnkgPSB0aGlzLnNuYXBPbmVUb0Fib3ZlcyhmaXhlZEdlb21ldHJ5LCBlbGVtZW50c0Fib3ZlLCB0cnVlKTtcclxuICAgIGVsZW1lbnRUb0luc2VydC5nZW9tZXRyeSA9IHNuYXBwZWROZXdHZW9tZXRyeTtcclxuICAgIGVsZW1lbnRzQWJvdmUucHVzaChlbGVtZW50VG9JbnNlcnQpO1xyXG4gICAgdGhpcy5tb3ZlRG93bihlbGVtZW50c0JlbG93LCAyICogc25hcHBlZE5ld0dlb21ldHJ5LmhlaWdodCk7XHJcbiAgICB0aGlzLnNuYXBCZWxvd3NUb0Fib3ZlcyhlbGVtZW50c0JlbG93LCBlbGVtZW50c0Fib3ZlKTtcclxuXHJcbiAgICB0aGlzLmZpdFdpZHRoKHNuYXBwZWROZXdHZW9tZXRyeSwgb3RoZXJFbGVtZW50cywgY29udGVudEFyZWFXaWR0aCk7XHJcbiAgfVxyXG4gIHByaXZhdGUgc25hcE9uZVRvQWJvdmVzKFxyXG4gICAgZ2VvbWV0cnk6IFN0aVJlY3RhbmdsZUdlb21ldHJ5LFxyXG4gICAgZWxlbWVudHNBYm92ZVRvU25hcDogU3RpRm9ybUVsZW1lbnRbXSxcclxuICAgIGNhblNocmluayA9IGZhbHNlXHJcbiAgKTogU3RpUmVjdGFuZ2xlR2VvbWV0cnkge1xyXG4gICAgbGV0IGVsZW1lbnRzRXhjYXRseUFib3ZlID0gZWxlbWVudHNBYm92ZVRvU25hcC5maWx0ZXIoKGVsZW1lbnQpID0+XHJcbiAgICAgIGVsZW1lbnQuZ2VvbWV0cnkueFByb2plY3Rpb25JbnRlcnNlY3RzV2l0aChnZW9tZXRyeSlcclxuICAgICk7XHJcbiAgICBpZiAoZWxlbWVudHNFeGNhdGx5QWJvdmUubGVuZ3RoID4gMCkge1xyXG4gICAgICBsZXQgbWF4ID0gZWxlbWVudHNFeGNhdGx5QWJvdmUucmVkdWNlKChhY2MsIGN1cnIpID0+IChhY2MuZ2VvbWV0cnkuYm90dG9tID4gY3Vyci5nZW9tZXRyeS5ib3R0b20gPyBhY2MgOiBjdXJyKSk7XHJcbiAgICAgIHJldHVybiBnZW9tZXRyeS53aXRoWShtYXguZ2VvbWV0cnkuYm90dG9tKTtcclxuICAgIH0gZWxzZSByZXR1cm4gZ2VvbWV0cnkud2l0aFkoMCk7XHJcbiAgfVxyXG4gIHByaXZhdGUgbW92ZURvd24oZWxlbWVudHNUb01vdmVEb3duOiBTdGlGb3JtRWxlbWVudFtdLCBkaXN0YW5jZTogbnVtYmVyKSB7XHJcbiAgICBmb3IgKGxldCBlbGVtZW50IG9mIGVsZW1lbnRzVG9Nb3ZlRG93bikge1xyXG4gICAgICBlbGVtZW50Lmdlb21ldHJ5ID0gZWxlbWVudC5nZW9tZXRyeS53aXRoWShlbGVtZW50Lmdlb21ldHJ5LnkgKyBkaXN0YW5jZSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHByaXZhdGUgc25hcEJlbG93c1RvQWJvdmVzKGJlbG93czogU3RpRm9ybUVsZW1lbnRbXSwgYWJvdmVzOiBTdGlGb3JtRWxlbWVudFtdKSB7XHJcbiAgICBiZWxvd3Muc29ydChmdW5jdGlvbiAobGVmdCwgcmlnaHQpIHtcclxuICAgICAgbGV0IGRpZmZlcmVuY2UgPSBsZWZ0Lmdlb21ldHJ5LnkgLSByaWdodC5nZW9tZXRyeS55O1xyXG4gICAgICBpZiAoZGlmZmVyZW5jZSA8IFN0aVJlY3RhbmdsZUdlb21ldHJ5LkRFTFRBKSB7XHJcbiAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICB9IGVsc2UgaWYgKGRpZmZlcmVuY2UgPiBTdGlSZWN0YW5nbGVHZW9tZXRyeS5ERUxUQSkge1xyXG4gICAgICAgIHJldHVybiAxO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIGZvciAobGV0IGVsZW1lbnQgb2YgYmVsb3dzKSB7XHJcbiAgICAgIGxldCBzbmFwcGVkRnJvbUJlbG93ID0gdGhpcy5zbmFwT25lVG9BYm92ZXMoZWxlbWVudC5nZW9tZXRyeSwgYWJvdmVzKTtcclxuICAgICAgZWxlbWVudC5nZW9tZXRyeSA9IHNuYXBwZWRGcm9tQmVsb3c7XHJcbiAgICAgIGFib3Zlcy5wdXNoKGVsZW1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuICBwdWJsaWMgZ2V0RnJlZVRvQm90dG9tUmVzaXplQXJlYShjdXJyZW50UmVzaXplRWxlbWVudDogU3RpRm9ybUVsZW1lbnQsIG90aGVyRWxlbWVudHM6IFN0aUZvcm1FbGVtZW50W10pOiBudW1iZXIge1xyXG4gICAgbGV0IGN1cnJlbnRDb250YWluZXIgPVxyXG4gICAgICB0aGlzLm1vZGVsLmdldEVsZW1lbnRQYWdlKGN1cnJlbnRSZXNpemVFbGVtZW50KSA/PyB0aGlzLm1vZGVsLmdldEVsZW1lbnRQYW5lbChjdXJyZW50UmVzaXplRWxlbWVudCk7XHJcbiAgICBsZXQgZ2VvbWV0cnkgPSBjdXJyZW50UmVzaXplRWxlbWVudC5nZW9tZXRyeTtcclxuICAgIGxldCBib3R0b21FbGVtZW50cyA9IG90aGVyRWxlbWVudHM/LmZpbHRlcigoZWxlbWVudCkgPT4gZWxlbWVudC55ID49IGdlb21ldHJ5LmJvdHRvbSk7XHJcbiAgICBsZXQgZWxlbWVudHNFeGNhdGx5QmVsb3cgPSBib3R0b21FbGVtZW50cz8uZmlsdGVyKChlbGVtZW50KSA9PlxyXG4gICAgICBlbGVtZW50Lmdlb21ldHJ5LnhQcm9qZWN0aW9uSW50ZXJzZWN0c1dpdGgoZ2VvbWV0cnkpXHJcbiAgICApO1xyXG4gICAgbGV0IGJvdHRvbVBvaW50cyA9IGVsZW1lbnRzRXhjYXRseUJlbG93Py5tYXAoKGVsZW1lbnQpID0+IHtcclxuICAgICAgcmV0dXJuIGVsZW1lbnQuZ2VvbWV0cnkuYm90dG9tO1xyXG4gICAgfSk7XHJcbiAgICBsZXQgdG9wUG9pbnRzID0gZWxlbWVudHNFeGNhdGx5QmVsb3c/Lm1hcCgoZWxlbWVudCkgPT4ge1xyXG4gICAgICByZXR1cm4gZWxlbWVudC5nZW9tZXRyeS55O1xyXG4gICAgfSk7XHJcbiAgICBsZXQgbWF4Qm90dG9tUG9pbnQgPSBNYXRoLm1heCguLi5ib3R0b21Qb2ludHMpO1xyXG4gICAgbGV0IG1pblRvcFBvaW50ID0gTWF0aC5taW4oLi4udG9wUG9pbnRzKTtcclxuICAgIGxldCBib3R0b21FbGVtZW50c0hlaWdodCA9IG1heEJvdHRvbVBvaW50IC0gbWluVG9wUG9pbnQ7XHJcblxyXG4gICAgcmV0dXJuIChcclxuICAgICAgY3VycmVudENvbnRhaW5lci5jb250ZW50QXJlYUhlaWdodCAtXHJcbiAgICAgIGdlb21ldHJ5LmJvdHRvbSAtXHJcbiAgICAgIChlbGVtZW50c0V4Y2F0bHlCZWxvdy5sZW5ndGggPiAwID8gYm90dG9tRWxlbWVudHNIZWlnaHQgOiAwKVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjaGVja091dHB1dHModXNlZFBhZ2U6IFN0aUZvcm1QYWdlRWxlbWVudCkge1xyXG4gICAgbGV0IG91dHB1dEVsZW1lbnRzID0gW107XHJcbiAgICBsZXQgc3VtbWFyeUhlaWdodDogbnVtYmVyID0gMDtcclxuICAgIHVzZWRQYWdlPy5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgIGlmIChlbGVtZW50Lmdlb21ldHJ5LmJvdHRvbSA+IHVzZWRQYWdlLmNvbnRlbnRBcmVhSGVpZ2h0KSB7XHJcbiAgICAgICAgb3V0cHV0RWxlbWVudHMucHVzaChlbGVtZW50KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICBpZiAob3V0cHV0RWxlbWVudHMubGVuZ3RoID4gMCkge1xyXG4gICAgICBvdXRwdXRFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgICAgc3VtbWFyeUhlaWdodCArPSBlbGVtZW50LmhlaWdodDtcclxuICAgICAgICB1c2VkUGFnZS5lbGVtZW50cy5zcGxpY2UodXNlZFBhZ2UuZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSwgMSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVFbGVtZW50KGVsZW1lbnQsIHVzZWRQYWdlLmVsZW1lbnRzKTtcclxuICAgICAgfSk7XHJcbiAgICAgIGlmICh0aGlzLm1vZGVsLmZvcm0ucGFnZXNbdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLmluZGV4T2YodXNlZFBhZ2UpICsgMV0pIHtcclxuICAgICAgICBsZXQgbmV4dFBhZ2UgPSB0aGlzLm1vZGVsLmZvcm0ucGFnZXNbdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLmluZGV4T2YodXNlZFBhZ2UpICsgMV07XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgbmV4dFBhZ2UuY29udGVudEFyZWFIZWlnaHQgLSBNYXRoLm1heCguLi5uZXh0UGFnZS5lbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IGVsZW1lbnQuZ2VvbWV0cnkuYm90dG9tKSkgPlxyXG4gICAgICAgICAgc3VtbWFyeUhlaWdodFxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgbGV0IGN1cnJlbnRCb3R0b21Qb2ludDogbnVtYmVyID0gMDtcclxuICAgICAgICAgIG91dHB1dEVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgIG5leHRQYWdlLmVsZW1lbnRzLnNwbGljZShpbmRleCwgMCwgZWxlbWVudCk7XHJcbiAgICAgICAgICAgIGVsZW1lbnQueSA9IGN1cnJlbnRCb3R0b21Qb2ludDtcclxuICAgICAgICAgICAgdGhpcy5pbnNlcnRFbGVtZW50KGVsZW1lbnQpO1xyXG4gICAgICAgICAgICBjdXJyZW50Qm90dG9tUG9pbnQgKz0gZWxlbWVudC5oZWlnaHQ7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgbGV0IHBhZ2UxID0gbmV3IFN0aUZvcm1QYWdlRWxlbWVudCh0aGlzLm1vZGVsLmZvcm0pO1xyXG4gICAgICAgICAgcGFnZTEubmFtZSA9IHRoaXMubmFtZVNlcnZpY2UuZ2V0RWxlbWVudE5hbWUocGFnZTEpO1xyXG4gICAgICAgICAgdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLnNwbGljZSh0aGlzLm1vZGVsLmZvcm0ucGFnZXMuaW5kZXhPZihuZXh0UGFnZSksIDAsIHBhZ2UxKTtcclxuICAgICAgICAgIGxldCBjdXJyZW50Qm90dG9tUG9pbnQ6IG51bWJlciA9IDA7XHJcbiAgICAgICAgICBvdXRwdXRFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50LCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBwYWdlMS5lbGVtZW50cy5zcGxpY2UoaW5kZXgsIDAsIGVsZW1lbnQpO1xyXG4gICAgICAgICAgICBlbGVtZW50LnkgPSBjdXJyZW50Qm90dG9tUG9pbnQ7XHJcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0RWxlbWVudChlbGVtZW50KTtcclxuICAgICAgICAgICAgY3VycmVudEJvdHRvbVBvaW50ICs9IGVsZW1lbnQuaGVpZ2h0O1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxldCBwYWdlMSA9IG5ldyBTdGlGb3JtUGFnZUVsZW1lbnQodGhpcy5tb2RlbC5mb3JtKTtcclxuICAgICAgICBwYWdlMS5uYW1lID0gdGhpcy5uYW1lU2VydmljZS5nZXRFbGVtZW50TmFtZShwYWdlMSk7XHJcbiAgICAgICAgdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLnB1c2gocGFnZTEpO1xyXG4gICAgICAgIGxldCBjdXJyZW50Qm90dG9tUG9pbnQ6IG51bWJlciA9IDA7XHJcbiAgICAgICAgb3V0cHV0RWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCwgaW5kZXgpID0+IHtcclxuICAgICAgICAgIHBhZ2UxLmVsZW1lbnRzLnNwbGljZShpbmRleCwgMCwgZWxlbWVudCk7XHJcbiAgICAgICAgICBlbGVtZW50LnkgPSBjdXJyZW50Qm90dG9tUG9pbnQ7XHJcbiAgICAgICAgICB0aGlzLmluc2VydEVsZW1lbnQoZWxlbWVudCk7XHJcbiAgICAgICAgICBjdXJyZW50Qm90dG9tUG9pbnQgKz0gZWxlbWVudC5nZW9tZXRyeS5ib3R0b207XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19