UNPKG

@covalent/core

Version:

Core Teradata UI Platform for layouts, icons, custom components and themes. This should be added as a dependency for any project that wants to use layouts, icons and themes for Angular Material.

222 lines 34.3 kB
import { merge, fromEvent } from 'rxjs'; var corners; (function (corners) { corners["topRight"] = "topRight"; corners["bottomRight"] = "bottomRight"; corners["bottomLeft"] = "bottomLeft"; corners["topLeft"] = "topLeft"; })(corners || (corners = {})); var cursors; (function (cursors) { cursors["nesw"] = "nesw-resize"; cursors["nwse"] = "nwse-resize"; })(cursors || (cursors = {})); var verticalAlignment; (function (verticalAlignment) { verticalAlignment["top"] = "top"; verticalAlignment["bottom"] = "bottom"; })(verticalAlignment || (verticalAlignment = {})); var horizontalAlignment; (function (horizontalAlignment) { horizontalAlignment["right"] = "right"; horizontalAlignment["left"] = "left"; })(horizontalAlignment || (horizontalAlignment = {})); const cornerWidth = '16px'; const offset = '0px'; const minWidth = 200; const minHeight = 200; function getPixels(sizeString) { return parseFloat((sizeString || '').replace('px', '')); } function clamp(min, num, max) { return Math.min(Math.max(num, min), max); } export class ResizableDraggableDialog { _document; _renderer2; _dialogRef; _dragRef; cornerElements = []; pointerDownSubs = []; constructor(_document, _renderer2, _dialogRef, _dragRef) { this._document = _document; this._renderer2 = _renderer2; this._dialogRef = _dialogRef; this._dragRef = _dragRef; this._initialPositionReset(); this._attachCorners(); } attach() { this.detach(); this._attachCorners(); } detach() { this.pointerDownSubs.forEach((sub) => sub.unsubscribe()); this.pointerDownSubs = []; this.cornerElements.forEach((elem) => this._renderer2.removeChild(this._getDialogWrapper(), elem)); this.cornerElements = []; } _getDialogWrapper() { return (this._document.getElementById(this._dialogRef.id) || {}).parentElement; } _getViewportDimensions() { return this._getDialogWrapper()?.parentElement?.getBoundingClientRect(); } _getDialogWrapperDimensions() { const wrapper = this._getDialogWrapper(); if (!wrapper) { return { width: 0, height: 0 }; } const dimensions = getComputedStyle(wrapper); return { width: getPixels(dimensions.width), height: getPixels(dimensions.height), }; } _initialPositionReset() { const viewportWidth = this._getViewportDimensions()?.right ?? 0; const viewportHeight = this._getViewportDimensions()?.bottom ?? 0; const { width, height } = this._getDialogWrapperDimensions(); const wrapperStyle = this._getDialogWrapper()?.style; const originalDialogRight = wrapperStyle?.marginRight; const originalDialogLeft = wrapperStyle?.marginLeft; const originalDialogBottom = wrapperStyle?.marginBottom; const originalDialogTop = wrapperStyle?.marginTop; let x; if (originalDialogLeft) { x = getPixels(originalDialogLeft); } else if (originalDialogRight) { x = viewportWidth - getPixels(originalDialogRight) - width; } else { x = (viewportWidth - width) / 2; } let y; if (originalDialogTop) { y = getPixels(originalDialogTop); } else if (originalDialogBottom) { y = viewportHeight - getPixels(originalDialogBottom) - height; } else { y = (viewportHeight - height) / 2; } // use drag ref's mechanisms for positioning instead of the dialog's this._dialogRef.updatePosition({ top: '0px', right: '0px', bottom: '0px', left: '0px', }); this._dragRef.setFreeDragPosition({ x, y }); } _attachCorners() { Object.values(corners).forEach((corner) => { const element = this._renderer2.createElement('div'); this.cornerElements = [...this.cornerElements, element]; this._renderer2.setStyle(element, 'position', 'absolute'); this._renderer2.setStyle(element, 'width', cornerWidth); this._renderer2.setStyle(element, 'height', cornerWidth); this._renderer2.setStyle(element, 'z-index', 1); this._renderer2.appendChild(this._getDialogWrapper(), element); let cursor; let topBottom; let rightLeft; if (corner === corners.topRight) { cursor = cursors.nesw; topBottom = verticalAlignment.top; rightLeft = horizontalAlignment.right; } else if (corner === corners.bottomRight) { cursor = cursors.nwse; topBottom = verticalAlignment.bottom; rightLeft = horizontalAlignment.right; const icon = this._renderer2.createElement('i'); this._renderer2.addClass(icon, 'material-symbols-outlined'); this._renderer2.appendChild(icon, this._renderer2.createText('filter_list')); this._renderer2.appendChild(element, icon); this._renderer2.setStyle(icon, 'transform', `rotate(${315}deg) translate(0px, ${offset})`); this._renderer2.setStyle(icon, 'font-size', cornerWidth); this._renderer2.setStyle(icon, 'z-index', 1); } else if (corner === corners.bottomLeft) { cursor = cursors.nesw; topBottom = verticalAlignment.bottom; rightLeft = horizontalAlignment.left; } else { cursor = cursors.nwse; topBottom = verticalAlignment.top; rightLeft = horizontalAlignment.left; } this._renderer2.setStyle(element, topBottom, offset); this._renderer2.setStyle(element, rightLeft, offset); this._renderer2.setStyle(element, 'cursor', cursor); const pointerDownSub = fromEvent(element, 'pointerdown').subscribe((event) => { this._handleMouseDown(event, corner); }); this.pointerDownSubs = [...this.pointerDownSubs, pointerDownSub]; }); } _handleMouseDown(event, corner) { this._renderer2.setStyle(this._document.body, 'user-select', 'none'); const { width: originalWidth, height: originalHeight } = this._getDialogWrapperDimensions(); const originalMouseX = event.pageX; const originalMouseY = event.pageY; const { x: currentTransformX, y: currentTransformY } = this._dragRef.getFreeDragPosition(); const wrapper = this._getDialogWrapper()?.getBoundingClientRect(); const distanceFromBottom = wrapper?.bottom ?? 0; const distanceFromRight = wrapper?.right ?? 0; const viewportWidth = this._getViewportDimensions()?.right ?? 0; const viewportHeight = this._getViewportDimensions()?.bottom ?? 0; const mouseMoveSub = fromEvent(window, 'pointermove').subscribe((e) => { e.preventDefault(); // prevent highlighting of text when dragging const yDelta = clamp(0, e.pageY, viewportHeight) - originalMouseY; const xDelta = clamp(0, e.pageX, viewportWidth) - originalMouseX; let newHeight; let newWidth; let newTransformY = 0; let newTransformX = 0; // top right if (corner === corners.topRight) { newHeight = clamp(minHeight, originalHeight - yDelta, viewportHeight); newWidth = clamp(minWidth, originalWidth + xDelta, viewportWidth); newTransformY = clamp(0, currentTransformY + yDelta, distanceFromBottom - newHeight); newTransformX = currentTransformX; } // bottom right else if (corner === corners.bottomRight) { newHeight = clamp(minHeight, originalHeight + yDelta, viewportHeight); newWidth = clamp(minWidth, originalWidth + xDelta, viewportWidth); newTransformY = currentTransformY; newTransformX = currentTransformX; } // bottom left else if (corner === corners.bottomLeft) { newHeight = clamp(minHeight, originalHeight + yDelta, viewportHeight); newWidth = clamp(minWidth, originalWidth - xDelta, viewportWidth); newTransformY = currentTransformY; newTransformX = clamp(0, currentTransformX + xDelta, distanceFromRight - newWidth); } // top left else { newHeight = clamp(minHeight, originalHeight - yDelta, viewportHeight); newWidth = clamp(minWidth, originalWidth - xDelta, viewportWidth); newTransformX = clamp(0, currentTransformX + xDelta, distanceFromRight - newWidth); newTransformY = clamp(0, currentTransformY + yDelta, distanceFromBottom - newHeight); } this._dialogRef.updateSize(`${newWidth}px`, `${newHeight}px`); this._dragRef.setFreeDragPosition({ x: newTransformX, y: newTransformY, }); }); const mouseUpSub = merge(fromEvent(window, 'pointerup'), fromEvent(window, 'pointercancel')).subscribe(() => { this._renderer2.removeStyle(this._document.body, 'user-select'); mouseMoveSub.unsubscribe(); mouseUpSub.unsubscribe(); }); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzaXphYmxlLWRyYWdnYWJsZS1kaWFsb2cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXIvZGlhbG9ncy9zcmMvcmVzaXphYmxlLWRyYWdnYWJsZS1kaWFsb2cvcmVzaXphYmxlLWRyYWdnYWJsZS1kaWFsb2cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLEtBQUssRUFBZ0IsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3RELElBQUssT0FLSjtBQUxELFdBQUssT0FBTztJQUNWLGdDQUFxQixDQUFBO0lBQ3JCLHNDQUEyQixDQUFBO0lBQzNCLG9DQUF5QixDQUFBO0lBQ3pCLDhCQUFtQixDQUFBO0FBQ3JCLENBQUMsRUFMSSxPQUFPLEtBQVAsT0FBTyxRQUtYO0FBQ0QsSUFBSyxPQUdKO0FBSEQsV0FBSyxPQUFPO0lBQ1YsK0JBQW9CLENBQUE7SUFDcEIsK0JBQW9CLENBQUE7QUFDdEIsQ0FBQyxFQUhJLE9BQU8sS0FBUCxPQUFPLFFBR1g7QUFDRCxJQUFLLGlCQUdKO0FBSEQsV0FBSyxpQkFBaUI7SUFDcEIsZ0NBQVcsQ0FBQTtJQUNYLHNDQUFpQixDQUFBO0FBQ25CLENBQUMsRUFISSxpQkFBaUIsS0FBakIsaUJBQWlCLFFBR3JCO0FBQ0QsSUFBSyxtQkFHSjtBQUhELFdBQUssbUJBQW1CO0lBQ3RCLHNDQUFlLENBQUE7SUFDZixvQ0FBYSxDQUFBO0FBQ2YsQ0FBQyxFQUhJLG1CQUFtQixLQUFuQixtQkFBbUIsUUFHdkI7QUFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUM7QUFDM0IsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDO0FBQ3JCLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQztBQUNyQixNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUM7QUFFdEIsU0FBUyxTQUFTLENBQUMsVUFBa0I7SUFDbkMsT0FBTyxVQUFVLENBQUMsQ0FBQyxVQUFVLElBQUksRUFB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LEdBQUcsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDO2dCQUVsRSxhQUFhLEdBQUcsS0FBSyxDQUNuQixDQUFDLEVBQ0QsaUJBQWlCLEdBQUcsTUFBTSxFQUMxQixpQkFBaUIsR0FBRyxRQUFRLENBQzdCLENBQUM7Z0JBQ0YsYUFBYSxHQUFHLEtBQUssQ0FDbkIsQ0FBQyxFQUNELGlCQUFpQixHQUFHLE1BQU0sRUFDMUIsa0JBQWtCLEdBQUcsU0FBUyxDQUMvQixDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEdBQUcsUUFBUSxJQUFJLEVBQUUsR0FBRyxTQUFTLElBQUksQ0FBQyxDQUFDO1lBQzlELElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUM7Z0JBQ2hDLENBQUMsRUFBRSxhQUFhO2dCQUNoQixDQUFDLEVBQUUsYUFBYTthQUNqQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sVUFBVSxHQUFpQixLQUFLLENBQ3BDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLEVBQzlCLFNBQVMsQ0FBQyxNQUFNLEVBQUUsZUFBZSxDQUFDLENBQ25DLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNmLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUNaLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUNoQyxhQUFhLENBQ2QsQ0FBQztZQUNGLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQixVQUFVLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZW5kZXJlcjIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBEcmFnUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5pbXBvcnQgeyBtZXJnZSwgU3Vic2NyaXB0aW9uLCBmcm9tRXZlbnQgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFBvaW50IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5cbmVudW0gY29ybmVycyB7XG4gIHRvcFJpZ2h0ID0gJ3RvcFJpZ2h0JyxcbiAgYm90dG9tUmlnaHQgPSAnYm90dG9tUmlnaHQnLFxuICBib3R0b21MZWZ0ID0gJ2JvdHRvbUxlZnQnLFxuICB0b3BMZWZ0ID0gJ3RvcExlZnQnLFxufVxuZW51bSBjdXJzb3JzIHtcbiAgbmVzdyA9ICduZXN3LXJlc2l6ZScsXG4gIG53c2UgPSAnbndzZS1yZXNpemUnLFxufVxuZW51bSB2ZXJ0aWNhbEFsaWdubWVudCB7XG4gIHRvcCA9ICd0b3AnLFxuICBib3R0b20gPSAnYm90dG9tJyxcbn1cbmVudW0gaG9yaXpvbnRhbEFsaWdubWVudCB7XG4gIHJpZ2h0ID0gJ3JpZ2h0JyxcbiAgbGVmdCA9ICdsZWZ0Jyxcbn1cblxuY29uc3QgY29ybmVyV2lkdGggPSAnMTZweCc7XG5jb25zdCBvZmZzZXQgPSAnMHB4JztcbmNvbnN0IG1pbldpZHRoID0gMjAwO1xuY29uc3QgbWluSGVpZ2h0ID0gMjAwO1xuXG5mdW5jdGlvbiBnZXRQaXhlbHMoc2l6ZVN0cmluZzogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIHBhcnNlRmxvYXQoKHNpemVTdHJpbmcgfHwgJycpLnJlcGxhY2UoJ3B4JywgJycpKTtcbn1cblxuZnVuY3Rpb24gY2xhbXAobWluOiBudW1iZXIsIG51bTogbnVtYmVyLCBtYXg6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLm1pbihNYXRoLm1heChudW0sIG1pbiksIG1heCk7XG59XG5cbmV4cG9ydCBjbGFzcyBSZXNpemFibGVEcmFnZ2FibGVEaWFsb2cge1xuICBjb3JuZXJFbGVtZW50czogSFRNTEVsZW1lbnRbXSA9IFtdO1xuICBwb2ludGVyRG93blN1YnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfZG9jdW1lbnQ6IGFueSxcbiAgICBwcml2YXRlIF9yZW5kZXJlcjI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIF9kaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxhbnk+LFxuICAgIHByaXZhdGUgX2RyYWdSZWY6IERyYWdSZWZcbiAgKSB7XG4gICAgdGhpcy5faW5pdGlhbFBvc2l0aW9uUmVzZXQoKTtcbiAgICB0aGlzLl9hdHRhY2hDb3JuZXJzKCk7XG4gIH1cblxuICBwdWJsaWMgYXR0YWNoKCk6IHZvaWQge1xuICAgIHRoaXMuZGV0YWNoKCk7XG4gICAgdGhpcy5fYXR0YWNoQ29ybmVycygpO1xuICB9XG5cbiAgcHVibGljIGRldGFjaCgpOiB2b2lkIHtcbiAgICB0aGlzLnBvaW50ZXJEb3duU3Vicy5mb3JFYWNoKChzdWI6IFN1YnNjcmlwdGlvbikgPT4gc3ViLnVuc3Vic2NyaWJlKCkpO1xuICAgIHRoaXMucG9pbnRlckRvd25TdWJzID0gW107XG4gICAgdGhpcy5jb3JuZXJFbGVtZW50cy5mb3JFYWNoKChlbGVtOiBIVE1MRWxlbWVudCkgPT5cbiAgICAgIHRoaXMuX3JlbmRlcmVyMi5yZW1vdmVDaGlsZCh0aGlzLl9nZXREaWFsb2dXcmFwcGVyKCksIGVsZW0pXG4gICAgKTtcbiAgICB0aGlzLmNvcm5lckVsZW1lbnRzID0gW107XG4gIH1cblxuICBwcml2YXRlIF9nZXREaWFsb2dXcmFwcGVyKCk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxIVE1MRWxlbWVudD50aGlzLl9kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLl9kaWFsb2dSZWYuaWQpIHx8IHt9XG4gICAgKS5wYXJlbnRFbGVtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0Vmlld3BvcnREaW1lbnNpb25zKCk6IENsaWVudFJlY3QgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9nZXREaWFsb2dXcmFwcGVyKCk/LnBhcmVudEVsZW1lbnQ/LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0RGlhbG9nV3JhcHBlckRpbWVuc2lvbnMoKTogeyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9IHtcbiAgICBjb25zdCB3cmFwcGVyID0gdGhpcy5fZ2V0RGlhbG9nV3JhcHBlcigpO1xuICAgIGlmICghd3JhcHBlcikge1xuICAgICAgcmV0dXJuIHsgd2lkdGg6IDAsIGhlaWdodDogMCB9O1xuICAgIH1cbiAgICBjb25zdCBkaW1lbnNpb25zOiBDU1NTdHlsZURlY2xhcmF0aW9uID0gZ2V0Q29tcHV0ZWRTdHlsZSh3cmFwcGVyKTtcbiAgICByZXR1cm4ge1xuICAgICAgd2lkdGg6IGdldFBpeGVscyhkaW1lbnNpb25zLndpZHRoKSxcbiAgICAgIGhlaWdodDogZ2V0UGl4ZWxzKGRpbWVuc2lvbnMuaGVpZ2h0KSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdGlhbFBvc2l0aW9uUmVzZXQoKTogdm9pZCB7XG4gICAgY29uc3Qgdmlld3BvcnRXaWR0aCA9IHRoaXMuX2dldFZpZXdwb3J0RGltZW5zaW9ucygpPy5yaWdodCA/PyAwO1xuICAgIGNvbnN0IHZpZXdwb3J0SGVpZ2h0ID0gdGhpcy5fZ2V0Vmlld3BvcnREaW1lbnNpb25zKCk/LmJvdHRvbSA/PyAwO1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gdGhpcy5fZ2V0RGlhbG9nV3JhcHBlckRpbWVuc2lvbnMoKTtcbiAgICBjb25zdCB3cmFwcGVyU3R5bGUgPSB0aGlzLl9nZXREaWFsb2dXcmFwcGVyKCk/LnN0eWxlO1xuICAgIGNvbnN0IG9yaWdpbmFsRGlhbG9nUmlnaHQgPSB3cmFwcGVyU3R5bGU/Lm1hcmdpblJpZ2h0O1xuICAgIGNvbnN0IG9yaWdpbmFsRGlhbG9nTGVmdCA9IHdyYXBwZXJTdHlsZT8ubWFyZ2luTGVmdDtcbiAgICBjb25zdCBvcmlnaW5hbERpYWxvZ0JvdHRvbSA9IHdyYXBwZXJTdHlsZT8ubWFyZ2luQm90dG9tO1xuICAgIGNvbnN0IG9yaWdpbmFsRGlhbG9nVG9wID0gd3JhcHBlclN0eWxlPy5tYXJnaW5Ub3A7XG4gICAgbGV0IHg6IG51bWJlcjtcbiAgICBpZiAob3JpZ2luYWxEaWFsb2dMZWZ0KSB7XG4gICAgICB4ID0gZ2V0UGl4ZWxzKG9yaWdpbmFsRGlhbG9nTGVmdCk7XG4gICAgfSBlbHNlIGlmIChvcmlnaW5hbERpYWxvZ1JpZ2h0KSB7XG4gICAgICB4ID0gdmlld3BvcnRXaWR0aCAtIGdldFBpeGVscyhvcmlnaW5hbERpYWxvZ1JpZ2h0KSAtIHdpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB4ID0gKHZpZXdwb3J0V2lkdGggLSB3aWR0aCkgLyAyO1xuICAgIH1cbiAgICBsZXQgeTogbnVtYmVyO1xuICAgIGlmIChvcmlnaW5hbERpYWxvZ1RvcCkge1xuICAgICAgeSA9IGdldFBpeGVscyhvcmlnaW5hbERpYWxvZ1RvcCk7XG4gICAgfSBlbHNlIGlmIChvcmlnaW5hbERpYWxvZ0JvdHRvbSkge1xuICAgICAgeSA9IHZpZXdwb3J0SGVpZ2h0IC0gZ2V0UGl4ZWxzKG9yaWdpbmFsRGlhbG9nQm90dG9tKSAtIGhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgeSA9ICh2aWV3cG9ydEhlaWdodCAtIGhlaWdodCkgLyAyO1xuICAgIH1cbiAgICAvLyB1c2UgZHJhZyByZWYncyBtZWNoYW5pc21zIGZvciBwb3NpdGlvbmluZyBpbnN0ZWFkIG9mIHRoZSBkaWFsb2cnc1xuICAgIHRoaXMuX2RpYWxvZ1JlZi51cGRhdGVQb3NpdGlvbih7XG4gICAgICB0b3A6ICcwcHgnLFxuICAgICAgcmlnaHQ6ICcwcHgnLFxuICAgICAgYm90dG9tOiAnMHB4JyxcbiAgICAgIGxlZnQ6ICcwcHgnLFxuICAgIH0pO1xuICAgIHRoaXMuX2RyYWdSZWYuc2V0RnJlZURyYWdQb3NpdGlvbih7IHgsIHkgfSk7XG4gIH1cblxuICBwcml2YXRlIF9hdHRhY2hDb3JuZXJzKCk6IHZvaWQge1xuICAgIE9iamVjdC52YWx1ZXMoY29ybmVycykuZm9yRWFjaCgoY29ybmVyOiBjb3JuZXJzKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50OiBIVE1MRWxlbWVudCA9IHRoaXMuX3JlbmRlcmVyMi5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHRoaXMuY29ybmVyRWxlbWVudHMgPSBbLi4udGhpcy5jb3JuZXJFbGVtZW50cywgZWxlbWVudF07XG4gICAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJywgJ2Fic29sdXRlJyk7XG4gICAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoZWxlbWVudCwgJ3dpZHRoJywgY29ybmVyV2lkdGgpO1xuICAgICAgdGhpcy5fcmVuZGVyZXIyLnNldFN0eWxlKGVsZW1lbnQsICdoZWlnaHQnLCBjb3JuZXJXaWR0aCk7XG4gICAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoZWxlbWVudCwgJ3otaW5kZXgnLCAxKTtcbiAgICAgIHRoaXMuX3JlbmRlcmVyMi5hcHBlbmRDaGlsZCh0aGlzLl9nZXREaWFsb2dXcmFwcGVyKCksIGVsZW1lbnQpO1xuXG4gICAgICBsZXQgY3Vyc29yOiBjdXJzb3JzO1xuICAgICAgbGV0IHRvcEJvdHRvbTogdmVydGljYWxBbGlnbm1lbnQ7XG4gICAgICBsZXQgcmlnaHRMZWZ0OiBob3Jpem9udGFsQWxpZ25tZW50O1xuXG4gICAgICBpZiAoY29ybmVyID09PSBjb3JuZXJzLnRvcFJpZ2h0KSB7XG4gICAgICAgIGN1cnNvciA9IGN1cnNvcnMubmVzdztcbiAgICAgICAgdG9wQm90dG9tID0gdmVydGljYWxBbGlnbm1lbnQudG9wO1xuICAgICAgICByaWdodExlZnQgPSBob3Jpem9udGFsQWxpZ25tZW50LnJpZ2h0O1xuICAgICAgfSBlbHNlIGlmIChjb3JuZXIgPT09IGNvcm5lcnMuYm90dG9tUmlnaHQpIHtcbiAgICAgICAgY3Vyc29yID0gY3Vyc29ycy5ud3NlO1xuICAgICAgICB0b3BCb3R0b20gPSB2ZXJ0aWNhbEFsaWdubWVudC5ib3R0b207XG4gICAgICAgIHJpZ2h0TGVmdCA9IGhvcml6b250YWxBbGlnbm1lbnQucmlnaHQ7XG5cbiAgICAgICAgY29uc3QgaWNvbjogSFRNTEVsZW1lbnQgPSB0aGlzLl9yZW5kZXJlcjIuY3JlYXRlRWxlbWVudCgnaScpO1xuICAgICAgICB0aGlzLl9yZW5kZXJlcjIuYWRkQ2xhc3MoaWNvbiwgJ21hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQnKTtcbiAgICAgICAgdGhpcy5fcmVuZGVyZXIyLmFwcGVuZENoaWxkKFxuICAgICAgICAgIGljb24sXG4gICAgICAgICAgdGhpcy5fcmVuZGVyZXIyLmNyZWF0ZVRleHQoJ2ZpbHRlcl9saXN0JylcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5fcmVuZGVyZXIyLmFwcGVuZENoaWxkKGVsZW1lbnQsIGljb24pO1xuICAgICAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoXG4gICAgICAgICAgaWNvbixcbiAgICAgICAgICAndHJhbnNmb3JtJyxcbiAgICAgICAgICBgcm90YXRlKCR7MzE1fWRlZykgdHJhbnNsYXRlKDBweCwgJHtvZmZzZXR9KWBcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5fcmVuZGVyZXIyLnNldFN0eWxlKGljb24sICdmb250LXNpemUnLCBjb3JuZXJXaWR0aCk7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVyMi5zZXRTdHlsZShpY29uLCAnei1pbmRleCcsIDEpO1xuICAgICAgfSBlbHNlIGlmIChjb3JuZXIgPT09IGNvcm5lcnMuYm90dG9tTGVmdCkge1xuICAgICAgICBjdXJzb3IgPSBjdXJzb3JzLm5lc3c7XG4gICAgICAgIHRvcEJvdHRvbSA9IHZlcnRpY2FsQWxpZ25tZW50LmJvdHRvbTtcbiAgICAgICAgcmlnaHRMZWZ0ID0gaG9yaXpvbnRhbEFsaWdubWVudC5sZWZ0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3Vyc29yID0gY3Vyc29ycy5ud3NlO1xuICAgICAgICB0b3BCb3R0b20gPSB2ZXJ0aWNhbEFsaWdubWVudC50b3A7XG4gICAgICAgIHJpZ2h0TGVmdCA9IGhvcml6b250YWxBbGlnbm1lbnQubGVmdDtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3JlbmRlcmVyMi5zZXRTdHlsZShlbGVtZW50LCB0b3BCb3R0b20sIG9mZnNldCk7XG4gICAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoZWxlbWVudCwgcmlnaHRMZWZ0LCBvZmZzZXQpO1xuICAgICAgdGhpcy5fcmVuZGVyZXIyLnNldFN0eWxlKGVsZW1lbnQsICdjdXJzb3InLCBjdXJzb3IpO1xuXG4gICAgICBjb25zdCBwb2ludGVyRG93blN1YjogU3Vic2NyaXB0aW9uID0gZnJvbUV2ZW50PFBvaW50ZXJFdmVudD4oXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgICdwb2ludGVyZG93bidcbiAgICAgICkuc3Vic2NyaWJlKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuX2hhbmRsZU1vdXNlRG93bihldmVudCwgY29ybmVyKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wb2ludGVyRG93blN1YnMgPSBbLi4udGhpcy5wb2ludGVyRG93blN1YnMsIHBvaW50ZXJEb3duU3ViXTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2hhbmRsZU1vdXNlRG93bihldmVudDogUG9pbnRlckV2ZW50LCBjb3JuZXI6IGNvcm5lcnMpOiB2b2lkIHtcbiAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoXG4gICAgICA8SFRNTEVsZW1lbnQ+dGhpcy5fZG9jdW1lbnQuYm9keSxcbiAgICAgICd1c2VyLXNlbGVjdCcsXG4gICAgICAnbm9uZSdcbiAgICApO1xuICAgIGNvbnN0IHsgd2lkdGg6IG9yaWdpbmFsV2lkdGgsIGhlaWdodDogb3JpZ2luYWxIZWlnaHQgfSA9XG4gICAgICB0aGlzLl9nZXREaWFsb2dXcmFwcGVyRGltZW5zaW9ucygpO1xuICAgIGNvbnN0IG9yaWdpbmFsTW91c2VYOiBudW1iZXIgPSBldmVudC5wYWdlWDtcbiAgICBjb25zdCBvcmlnaW5hbE1vdXNlWTogbnVtYmVyID0gZXZlbnQucGFnZVk7XG4gICAgY29uc3QgeyB4OiBjdXJyZW50VHJhbnNmb3JtWCwgeTogY3VycmVudFRyYW5zZm9ybVkgfTogUG9pbnQgPVxuICAgICAgdGhpcy5fZHJhZ1JlZi5nZXRGcmVlRHJhZ1Bvc2l0aW9uKCk7XG4gICAgY29uc3Qgd3JhcHBlciA9IHRoaXMuX2dldERpYWxvZ1dyYXBwZXIoKT8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgZGlzdGFuY2VGcm9tQm90dG9tID0gd3JhcHBlcj8uYm90dG9tID8/IDA7XG4gICAgY29uc3QgZGlzdGFuY2VGcm9tUmlnaHQgPSB3cmFwcGVyPy5yaWdodCA/PyAwO1xuICAgIGNvbnN0IHZpZXdwb3J0V2lkdGggPSB0aGlzLl9nZXRWaWV3cG9ydERpbWVuc2lvbnMoKT8ucmlnaHQgPz8gMDtcbiAgICBjb25zdCB2aWV3cG9ydEhlaWdodCA9IHRoaXMuX2dldFZpZXdwb3J0RGltZW5zaW9ucygpPy5ib3R0b20gPz8gMDtcblxuICAgIGNvbnN0IG1vdXNlTW92ZVN1YjogU3Vic2NyaXB0aW9uID0gZnJvbUV2ZW50PFBvaW50ZXJFdmVudD4oXG4gICAgICB3aW5kb3csXG4gICAgICAncG9pbnRlcm1vdmUnXG4gICAgKS5zdWJzY3JpYmUoKGU6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOyAvLyBwcmV2ZW50IGhpZ2hsaWdodGluZyBvZiB0ZXh0IHdoZW4gZHJhZ2dpbmdcblxuICAgICAgY29uc3QgeURlbHRhOiBudW1iZXIgPSBjbGFtcCgwLCBlLnBhZ2VZLCB2aWV3cG9ydEhlaWdodCkgLSBvcmlnaW5hbE1vdXNlWTtcbiAgICAgIGNvbnN0IHhEZWx0YTogbnVtYmVyID0gY2xhbXAoMCwgZS5wYWdlWCwgdmlld3BvcnRXaWR0aCkgLSBvcmlnaW5hbE1vdXNlWDtcbiAgICAgIGxldCBuZXdIZWlnaHQ6IG51bWJlcjtcbiAgICAgIGxldCBuZXdXaWR0aDogbnVtYmVyO1xuICAgICAgbGV0IG5ld1RyYW5zZm9ybVkgPSAwO1xuICAgICAgbGV0IG5ld1RyYW5zZm9ybVggPSAwO1xuXG4gICAgICAvLyB0b3AgcmlnaHRcbiAgICAgIGlmIChjb3JuZXIgPT09IGNvcm5lcnMudG9wUmlnaHQpIHtcbiAgICAgICAgbmV3SGVpZ2h0ID0gY2xhbXAobWluSGVpZ2h0LCBvcmlnaW5hbEhlaWdodCAtIHlEZWx0YSwgdmlld3BvcnRIZWlnaHQpO1xuICAgICAgICBuZXdXaWR0aCA9IGNsYW1wKG1pbldpZHRoLCBvcmlnaW5hbFdpZHRoICsgeERlbHRhLCB2aWV3cG9ydFdpZHRoKTtcbiAgICAgICAgbmV3VHJhbnNmb3JtWSA9IGNsYW1wKFxuICAgICAgICAgIDAsXG4gICAgICAgICAgY3VycmVudFRyYW5zZm9ybVkgKyB5RGVsdGEsXG4gICAgICAgICAgZGlzdGFuY2VGcm9tQm90dG9tIC0gbmV3SGVpZ2h0XG4gICAgICAgICk7XG4gICAgICAgIG5ld1RyYW5zZm9ybVggPSBjdXJyZW50VHJhbnNmb3JtWDtcbiAgICAgIH1cbiAgICAgIC8vIGJvdHRvbSByaWdodFxuICAgICAgZWxzZSBpZiAoY29ybmVyID09PSBjb3JuZXJzLmJvdHRvbVJpZ2h0KSB7XG4gICAgICAgIG5ld0hlaWdodCA9IGNsYW1wKG1pbkhlaWdodCwgb3JpZ2luYWxIZWlnaHQgKyB5RGVsdGEsIHZpZXdwb3J0SGVpZ2h0KTtcbiAgICAgICAgbmV3V2lkdGggPSBjbGFtcChtaW5XaWR0aCwgb3JpZ2luYWxXaWR0aCArIHhEZWx0YSwgdmlld3BvcnRXaWR0aCk7XG4gICAgICAgIG5ld1RyYW5zZm9ybVkgPSBjdXJyZW50VHJhbnNmb3JtWTtcbiAgICAgICAgbmV3VHJhbnNmb3JtWCA9IGN1cnJlbnRUcmFuc2Zvcm1YO1xuICAgICAgfVxuICAgICAgLy8gYm90dG9tIGxlZnRcbiAgICAgIGVsc2UgaWYgKGNvcm5lciA9PT0gY29ybmVycy5ib3R0b21MZWZ0KSB7XG4gICAgICAgIG5ld0hlaWdodCA9IGNsYW1wKG1pbkhlaWdodCwgb3JpZ2luYWxIZWlnaHQgKyB5RGVsdGEsIHZpZXdwb3J0SGVpZ2h0KTtcbiAgICAgICAgbmV3V2lkdGggPSBjbGFtcChtaW5XaWR0aCwgb3JpZ2luYWxXaWR0aCAtIHhEZWx0YSwgdmlld3BvcnRXaWR0aCk7XG4gICAgICAgIG5ld1RyYW5zZm9ybVkgPSBjdXJyZW50VHJhbnNmb3JtWTtcbiAgICAgICAgbmV3VHJhbnNmb3JtWCA9IGNsYW1wKFxuICAgICAgICAgIDAsXG4gICAgICAgICAgY3VycmVudFRyYW5zZm9ybVggKyB4RGVsdGEsXG4gICAgICAgICAgZGlzdGFuY2VGcm9tUmlnaHQgLSBuZXdXaWR0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gdG9wIGxlZnRcbiAgICAgIGVsc2Uge1xuICAgICAgICBuZXdIZWlnaHQgPSBjbGFtcChtaW5IZWlnaHQsIG9yaWdpbmFsSGVpZ2h0IC0geURlbHRhLCB2aWV3cG9ydEhlaWdodCk7XG4gICAgICAgIG5ld1dpZHRoID0gY2xhbXAobWluV2lkdGgsIG9yaWdpbmFsV2lkdGggLSB4RGVsdGEsIHZpZXdwb3J0V2lkdGgpO1xuXG4gICAgICAgIG5ld1RyYW5zZm9ybVggPSBjbGFtcChcbiAgICAgICAgICAwLFxuICAgICAgICAgIGN1cnJlbnRUcmFuc2Zvcm1YICsgeERlbHRhLFxuICAgICAgICAgIGRpc3RhbmNlRnJvbVJpZ2h0IC0gbmV3V2lkdGhcbiAgICAgICAgKTtcbiAgICAgICAgbmV3VHJhbnNmb3JtWSA9IGNsYW1wKFxuICAgICAgICAgIDAsXG4gICAgICAgICAgY3VycmVudFRyYW5zZm9ybVkgKyB5RGVsdGEsXG4gICAgICAgICAgZGlzdGFuY2VGcm9tQm90dG9tIC0gbmV3SGVpZ2h0XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLl9kaWFsb2dSZWYudXBkYXRlU2l6ZShgJHtuZXdXaWR0aH1weGAsIGAke25ld0hlaWdodH1weGApO1xuICAgICAgdGhpcy5fZHJhZ1JlZi5zZXRGcmVlRHJhZ1Bvc2l0aW9uKHtcbiAgICAgICAgeDogbmV3VHJhbnNmb3JtWCxcbiAgICAgICAgeTogbmV3VHJhbnNmb3JtWSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgbW91c2VVcFN1YjogU3Vic2NyaXB0aW9uID0gbWVyZ2UoXG4gICAgICBmcm9tRXZlbnQod2luZG93LCAncG9pbnRlcnVwJyksXG4gICAgICBmcm9tRXZlbnQod2luZG93LCAncG9pbnRlcmNhbmNlbCcpXG4gICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5fcmVuZGVyZXIyLnJlbW92ZVN0eWxlKFxuICAgICAgICA8SFRNTEVsZW1lbnQ+dGhpcy5fZG9jdW1lbnQuYm9keSxcbiAgICAgICAgJ3VzZXItc2VsZWN0J1xuICAgICAgKTtcbiAgICAgIG1vdXNlTW92ZVN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgbW91c2VVcFN1Yi51bnN1YnNjcmliZSgpO1xuICAgIH0pO1xuICB9XG59XG4iXX0=