UNPKG

ng-devui

Version:

DevUI components based on Angular

242 lines 42.4 kB
import { Injectable } from '@angular/core'; import { DocumentRef, WindowRef } from 'ng-devui/window-ref'; import * as i0 from "@angular/core"; import * as i1 from "ng-devui/window-ref"; export class PositionService { constructor(documentRef, windowRef) { this.documentRef = documentRef; this.windowRef = windowRef; } position(element, round = true) { let elPosition; let parentOffset = { width: 0, height: 0, top: 0, bottom: 0, left: 0, right: 0 }; if (this.getStyle(element, 'position') === 'fixed') { elPosition = element.getBoundingClientRect(); } else { const offsetParentEl = this.offsetParent(element); elPosition = this.offset(element, false); if (offsetParentEl !== this.documentRef.documentElement) { parentOffset = this.offset(offsetParentEl, false); } parentOffset.top += offsetParentEl.clientTop - offsetParentEl.scrollTop; parentOffset.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft; } elPosition.top -= parentOffset.top; elPosition.bottom -= parentOffset.top; elPosition.left -= parentOffset.left; elPosition.right -= parentOffset.left; if (round) { elPosition.top = Math.round(elPosition.top); elPosition.bottom = Math.round(elPosition.bottom); elPosition.left = Math.round(elPosition.left); elPosition.right = Math.round(elPosition.right); } return elPosition; } offset(element, round = true) { const elBcr = element.getBoundingClientRect(); const viewportOffset = { top: this.windowRef.pageYOffset - this.documentRef.documentElement.clientTop, left: this.windowRef.pageXOffset - this.documentRef.documentElement.clientLeft, }; const elOffset = { height: elBcr.height || element.offsetHeight, width: elBcr.width || element.offsetWidth, top: elBcr.top + viewportOffset.top, bottom: elBcr.bottom + viewportOffset.top, left: elBcr.left + viewportOffset.left, right: elBcr.right + viewportOffset.left, }; if (round) { elOffset.height = Math.round(elOffset.height); elOffset.width = Math.round(elOffset.width); elOffset.top = Math.round(elOffset.top); elOffset.bottom = Math.round(elOffset.bottom); elOffset.left = Math.round(elOffset.left); elOffset.right = Math.round(elOffset.right); } return elOffset; } getScrollParent(element) { let style = getComputedStyle(element); const excludeStaticParent = style.position === 'absolute'; const overflowRegex = /(auto|scroll|overlay)/; if (style.position === 'fixed') { return this.documentRef.body; } for (let parent = element; (parent = parent.parentElement); parent.parentElement !== this.documentRef.body) { style = getComputedStyle(parent); if (excludeStaticParent && style.position === 'static') { continue; } if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) { return parent; } } return this.documentRef.body; } positionElements(hostElement, targetElement, placement, appendToBody) { const hostElPosition = appendToBody ? this.offset(hostElement, false) : this.position(hostElement, false); const shiftWidth = { left: hostElPosition.left, center: hostElPosition.left + hostElPosition.width / 2 - targetElement.offsetWidth / 2, right: hostElPosition.left + hostElPosition.width, }; const shiftHeight = { top: hostElPosition.top, center: hostElPosition.top + hostElPosition.height / 2 - targetElement.offsetHeight / 2, bottom: hostElPosition.top + hostElPosition.height, }; const targetElBCR = targetElement.getBoundingClientRect(); const targetElPosition = { height: targetElBCR.height || targetElement.offsetHeight, width: targetElBCR.width || targetElement.offsetWidth, top: 0, bottom: targetElBCR.height || targetElement.offsetHeight, left: 0, right: targetElBCR.width || targetElement.offsetWidth, }; let placementPrimary; let placementSecondary; if (Array.isArray(placement)) { const targetPlacement = this.getPlacement(hostElement, targetElement, placement); placementPrimary = targetPlacement[0]; placementSecondary = targetPlacement[1]; } else { placementPrimary = placement?.split('-')[0] || 'top'; placementSecondary = placement?.split('-')[1] || 'center'; } switch (placementPrimary) { case 'top': targetElPosition.top = hostElPosition.top - targetElement.offsetHeight; targetElPosition.bottom += hostElPosition.top - targetElement.offsetHeight; targetElPosition.left = placementSecondary === 'right' ? shiftWidth[placementSecondary] - targetElement.offsetWidth : shiftWidth[placementSecondary]; targetElPosition.right += shiftWidth[placementSecondary]; break; case 'bottom': targetElPosition.top = shiftHeight[placementPrimary]; targetElPosition.bottom += shiftHeight[placementPrimary]; targetElPosition.left = placementSecondary === 'right' ? shiftWidth[placementSecondary] - targetElement.offsetWidth : shiftWidth[placementSecondary]; targetElPosition.right += shiftWidth[placementSecondary]; break; case 'left': targetElPosition.top = placementSecondary === 'bottom' ? shiftHeight[placementSecondary] - targetElement.offsetHeight : shiftHeight[placementSecondary]; targetElPosition.bottom += shiftHeight[placementSecondary]; targetElPosition.left = hostElPosition.left - targetElement.offsetWidth; targetElPosition.right += hostElPosition.left - targetElement.offsetWidth; break; case 'right': targetElPosition.top = placementSecondary === 'bottom' ? shiftHeight[placementSecondary] - targetElement.offsetHeight : shiftHeight[placementSecondary]; targetElPosition.bottom += shiftHeight[placementSecondary]; targetElPosition.left = shiftWidth[placementPrimary]; targetElPosition.right += shiftWidth[placementPrimary]; break; default: } targetElPosition.top = Math.round(targetElPosition.top); targetElPosition.bottom = Math.round(targetElPosition.bottom); targetElPosition.left = Math.round(targetElPosition.left); targetElPosition.right = Math.round(targetElPosition.right); targetElPosition.placementPrimary = placementPrimary; targetElPosition.placementSecondary = placementSecondary; return targetElPosition; } // 根据传入数组选取第一个合适的位置 getPlacement(hostElement, targetElement, placement) { const hostElPosition = this.offset(hostElement, false); const shiftWidth = { left: hostElPosition.left, center: hostElPosition.left + hostElPosition.width / 2 - targetElement.offsetWidth / 2, right: hostElPosition.left + hostElPosition.width, }; const shiftHeight = { top: hostElPosition.top, center: hostElPosition.top + hostElPosition.height / 2 - targetElement.offsetHeight / 2, bottom: hostElPosition.top + hostElPosition.height, }; let placementPrimary = placement[0].split('-')[0] || 'top'; let placementSecondary = placement[0].split('-')[1] || 'center'; for (let i = 0; i < placement.length; i++) { const placementPrimaryTemp = placement[i].split('-')[0] || 'top'; const placementSecondaryTemp = placement[i].split('-')[1] || 'center'; let top; let left; switch (placementPrimaryTemp) { case 'top': top = hostElPosition.top - targetElement.offsetHeight; left = placementSecondaryTemp === 'right' ? shiftWidth[placementSecondaryTemp] - targetElement.offsetWidth : shiftWidth[placementSecondary]; break; case 'bottom': top = shiftHeight[placementPrimaryTemp]; left = placementSecondaryTemp === 'right' ? shiftWidth[placementSecondaryTemp] - targetElement.offsetWidth : shiftWidth[placementSecondary]; break; case 'left': top = placementSecondaryTemp === 'bottom' ? shiftHeight[placementSecondaryTemp] - targetElement.offsetHeight : shiftHeight[placementSecondary]; left = hostElPosition.left - targetElement.offsetWidth; break; case 'right': top = placementSecondaryTemp === 'bottom' ? shiftHeight[placementSecondaryTemp] - targetElement.offsetHeight : shiftHeight[placementSecondary]; left = shiftWidth[placementPrimaryTemp]; break; default: } if (this.isInViewPort(targetElement, { offsetLeft: left, offsetTop: top })) { placementPrimary = placement[i].split('-')[0] || 'top'; placementSecondary = placement[i].split('-')[1] || 'center'; return [placementPrimary, placementSecondary]; } } return [placementPrimary, placementSecondary]; } isInViewPort(ele, { offsetLeft, offsetTop }) { const targetElBCR = ele.getBoundingClientRect(); const viewPortHeight = this.windowRef.innerHeight || this.documentRef.documentElement.clientHeight || this.documentRef.body.clientHeight; const viewPortWidth = this.windowRef.innerWidth || this.documentRef.documentElement.clientWidth || this.documentRef.body.clientWidth; const height = targetElBCR.height || targetElBCR.offsetHeight; const width = targetElBCR.width || targetElBCR.offsetWidth; offsetTop = offsetTop || ele.offsetTop; const scrollTop = this.documentRef.documentElement.scrollTop || this.documentRef.body.scrollTop; const top = offsetTop - scrollTop; offsetLeft = offsetLeft || ele.offsetLeft; const scrollLeft = this.documentRef.documentElement.scrollLeft || this.documentRef.body.scrollLeft; const left = offsetLeft - scrollLeft; return top + height <= viewPortHeight && top > 0 && left + width <= viewPortWidth && left > 0; } getStyle(element, prop) { return this.windowRef.getComputedStyle(element)[prop]; } isStaticPositioned(element) { return (this.getStyle(element, 'position') || 'static') === 'static'; } offsetParent(element) { let offsetParentEl = element.offsetParent || this.documentRef.documentElement; while (offsetParentEl && offsetParentEl !== this.documentRef.documentElement && this.isStaticPositioned(offsetParentEl)) { offsetParentEl = offsetParentEl.offsetParent; } return offsetParentEl || this.documentRef.documentElement; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PositionService, deps: [{ token: i1.DocumentRef }, { token: i1.WindowRef }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PositionService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PositionService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.DocumentRef }, { type: i1.WindowRef }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zaXRpb25pbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2RldnVpL3Bvc2l0aW9uL3Bvc2l0aW9uaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7QUFHN0QsTUFBTSxPQUFPLGVBQWU7SUFDMUIsWUFBb0IsV0FBd0IsRUFBVSxTQUFvQjtRQUF0RCxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUFVLGNBQVMsR0FBVCxTQUFTLENBQVc7SUFBRyxDQUFDO0lBRTlFLFFBQVEsQ0FBQyxPQUFvQixFQUFFLEtBQUssR0FBRyxJQUFJO1FBQ3pDLElBQUksVUFBVSxDQUFDO1FBQ2YsSUFBSSxZQUFZLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBRWpGLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDbkQsVUFBVSxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQy9DLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVsRCxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsSUFBSSxjQUFjLEtBQUssSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDeEQsWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3BELENBQUM7WUFFRCxZQUFZLENBQUMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQztZQUN4RSxZQUFZLENBQUMsSUFBSSxJQUFJLGNBQWMsQ0FBQyxVQUFVLEdBQUcsY0FBYyxDQUFDLFVBQVUsQ0FBQztRQUM3RSxDQUFDO1FBRUQsVUFBVSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDO1FBQ25DLFVBQVUsQ0FBQyxNQUFNLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQztRQUN0QyxVQUFVLENBQUMsSUFBSSxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUM7UUFDckMsVUFBVSxDQUFDLEtBQUssSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDO1FBRXRDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixVQUFVLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzVDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbEQsVUFBVSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM5QyxVQUFVLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQsTUFBTSxDQUFDLE9BQW9CLEVBQUUsS0FBSyxHQUFHLElBQUk7UUFDdkMsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDOUMsTUFBTSxjQUFjLEdBQUc7WUFDckIsR0FBRyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLFNBQVM7WUFDNUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLFVBQVU7U0FDL0UsQ0FBQztRQUVGLE1BQU0sUUFBUSxHQUFHO1lBQ2YsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLFlBQVk7WUFDNUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLElBQUksT0FBTyxDQUFDLFdBQVc7WUFDekMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLEdBQUcsY0FBYyxDQUFDLEdBQUc7WUFDbkMsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEdBQUcsY0FBYyxDQUFDLEdBQUc7WUFDekMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEdBQUcsY0FBYyxDQUFDLElBQUk7WUFDdEMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLElBQUk7U0FDekMsQ0FBQztRQUVGLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUMsUUFBUSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN4QyxRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxDQUFD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LEdBQUcsVUFBVSxDQUFDO1FBRXJDLE9BQU8sR0FBRyxHQUFHLE1BQU0sSUFBSSxjQUFjLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxJQUFJLEdBQUcsS0FBSyxJQUFJLGFBQWEsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ2hHLENBQUM7SUFFTyxRQUFRLENBQUMsT0FBb0IsRUFBRSxJQUFZO1FBQ2pELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRU8sa0JBQWtCLENBQUMsT0FBb0I7UUFDN0MsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLFFBQVEsQ0FBQztJQUN2RSxDQUFDO0lBRU8sWUFBWSxDQUFDLE9BQW9CO1FBQ3ZDLElBQUksY0FBYyxHQUFnQixPQUFPLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDO1FBRTNGLE9BQU8sY0FBYyxJQUFJLGNBQWMsS0FBSyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztZQUN4SCxjQUFjLEdBQWdCLGNBQWMsQ0FBQyxZQUFZLENBQUM7UUFDNUQsQ0FBQztRQUVELE9BQU8sY0FBYyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDO0lBQzVELENBQUM7K0dBblFVLGVBQWU7bUhBQWYsZUFBZTs7NEZBQWYsZUFBZTtrQkFEM0IsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRG9jdW1lbnRSZWYsIFdpbmRvd1JlZiB9IGZyb20gJ25nLWRldnVpL3dpbmRvdy1yZWYnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgUG9zaXRpb25TZXJ2aWNlIHtcclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRvY3VtZW50UmVmOiBEb2N1bWVudFJlZiwgcHJpdmF0ZSB3aW5kb3dSZWY6IFdpbmRvd1JlZikge31cclxuXHJcbiAgcG9zaXRpb24oZWxlbWVudDogSFRNTEVsZW1lbnQsIHJvdW5kID0gdHJ1ZSkge1xyXG4gICAgbGV0IGVsUG9zaXRpb247XHJcbiAgICBsZXQgcGFyZW50T2Zmc2V0ID0geyB3aWR0aDogMCwgaGVpZ2h0OiAwLCB0b3A6IDAsIGJvdHRvbTogMCwgbGVmdDogMCwgcmlnaHQ6IDAgfTtcclxuXHJcbiAgICBpZiAodGhpcy5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSA9PT0gJ2ZpeGVkJykge1xyXG4gICAgICBlbFBvc2l0aW9uID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IG9mZnNldFBhcmVudEVsID0gdGhpcy5vZmZzZXRQYXJlbnQoZWxlbWVudCk7XHJcblxyXG4gICAgICBlbFBvc2l0aW9uID0gdGhpcy5vZmZzZXQoZWxlbWVudCwgZmFsc2UpO1xyXG5cclxuICAgICAgaWYgKG9mZnNldFBhcmVudEVsICE9PSB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudCkge1xyXG4gICAgICAgIHBhcmVudE9mZnNldCA9IHRoaXMub2Zmc2V0KG9mZnNldFBhcmVudEVsLCBmYWxzZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHBhcmVudE9mZnNldC50b3AgKz0gb2Zmc2V0UGFyZW50RWwuY2xpZW50VG9wIC0gb2Zmc2V0UGFyZW50RWwuc2Nyb2xsVG9wO1xyXG4gICAgICBwYXJlbnRPZmZzZXQubGVmdCArPSBvZmZzZXRQYXJlbnRFbC5jbGllbnRMZWZ0IC0gb2Zmc2V0UGFyZW50RWwuc2Nyb2xsTGVmdDtcclxuICAgIH1cclxuXHJcbiAgICBlbFBvc2l0aW9uLnRvcCAtPSBwYXJlbnRPZmZzZXQudG9wO1xyXG4gICAgZWxQb3NpdGlvbi5ib3R0b20gLT0gcGFyZW50T2Zmc2V0LnRvcDtcclxuICAgIGVsUG9zaXRpb24ubGVmdCAtPSBwYXJlbnRPZmZzZXQubGVmdDtcclxuICAgIGVsUG9zaXRpb24ucmlnaHQgLT0gcGFyZW50T2Zmc2V0LmxlZnQ7XHJcblxyXG4gICAgaWYgKHJvdW5kKSB7XHJcbiAgICAgIGVsUG9zaXRpb24udG9wID0gTWF0aC5yb3VuZChlbFBvc2l0aW9uLnRvcCk7XHJcbiAgICAgIGVsUG9zaXRpb24uYm90dG9tID0gTWF0aC5yb3VuZChlbFBvc2l0aW9uLmJvdHRvbSk7XHJcbiAgICAgIGVsUG9zaXRpb24ubGVmdCA9IE1hdGgucm91bmQoZWxQb3NpdGlvbi5sZWZ0KTtcclxuICAgICAgZWxQb3NpdGlvbi5yaWdodCA9IE1hdGgucm91bmQoZWxQb3NpdGlvbi5yaWdodCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVsUG9zaXRpb247XHJcbiAgfVxyXG5cclxuICBvZmZzZXQoZWxlbWVudDogSFRNTEVsZW1lbnQsIHJvdW5kID0gdHJ1ZSkge1xyXG4gICAgY29uc3QgZWxCY3IgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3Qgdmlld3BvcnRPZmZzZXQgPSB7XHJcbiAgICAgIHRvcDogdGhpcy53aW5kb3dSZWYucGFnZVlPZmZzZXQgLSB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudC5jbGllbnRUb3AsXHJcbiAgICAgIGxlZnQ6IHRoaXMud2luZG93UmVmLnBhZ2VYT2Zmc2V0IC0gdGhpcy5kb2N1bWVudFJlZi5kb2N1bWVudEVsZW1lbnQuY2xpZW50TGVmdCxcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgZWxPZmZzZXQgPSB7XHJcbiAgICAgIGhlaWdodDogZWxCY3IuaGVpZ2h0IHx8IGVsZW1lbnQub2Zmc2V0SGVpZ2h0LFxyXG4gICAgICB3aWR0aDogZWxCY3Iud2lkdGggfHwgZWxlbWVudC5vZmZzZXRXaWR0aCxcclxuICAgICAgdG9wOiBlbEJjci50b3AgKyB2aWV3cG9ydE9mZnNldC50b3AsXHJcbiAgICAgIGJvdHRvbTogZWxCY3IuYm90dG9tICsgdmlld3BvcnRPZmZzZXQudG9wLFxyXG4gICAgICBsZWZ0OiBlbEJjci5sZWZ0ICsgdmlld3BvcnRPZmZzZXQubGVmdCxcclxuICAgICAgcmlnaHQ6IGVsQmNyLnJpZ2h0ICsgdmlld3BvcnRPZmZzZXQubGVmdCxcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHJvdW5kKSB7XHJcbiAgICAgIGVsT2Zmc2V0LmhlaWdodCA9IE1hdGgucm91bmQoZWxPZmZzZXQuaGVpZ2h0KTtcclxuICAgICAgZWxPZmZzZXQud2lkdGggPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LndpZHRoKTtcclxuICAgICAgZWxPZmZzZXQudG9wID0gTWF0aC5yb3VuZChlbE9mZnNldC50b3ApO1xyXG4gICAgICBlbE9mZnNldC5ib3R0b20gPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LmJvdHRvbSk7XHJcbiAgICAgIGVsT2Zmc2V0LmxlZnQgPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LmxlZnQpO1xyXG4gICAgICBlbE9mZnNldC5yaWdodCA9IE1hdGgucm91bmQoZWxPZmZzZXQucmlnaHQpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBlbE9mZnNldDtcclxuICB9XHJcblxyXG4gIGdldFNjcm9sbFBhcmVudChlbGVtZW50KSB7XHJcbiAgICBsZXQgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xyXG4gICAgY29uc3QgZXhjbHVkZVN0YXRpY1BhcmVudCA9IHN0eWxlLnBvc2l0aW9uID09PSAnYWJzb2x1dGUnO1xyXG4gICAgY29uc3Qgb3ZlcmZsb3dSZWdleCA9IC8oYXV0b3xzY3JvbGx8b3ZlcmxheSkvO1xyXG5cclxuICAgIGlmIChzdHlsZS5wb3NpdGlvbiA9PT0gJ2ZpeGVkJykge1xyXG4gICAgICByZXR1cm4gdGhpcy5kb2N1bWVudFJlZi5ib2R5O1xyXG4gICAgfVxyXG4gICAgZm9yIChsZXQgcGFyZW50ID0gZWxlbWVudDsgKHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50KTsgcGFyZW50LnBhcmVudEVsZW1lbnQgIT09IHRoaXMuZG9jdW1lbnRSZWYuYm9keSkge1xyXG4gICAgICBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcclxuICAgICAgaWYgKGV4Y2x1ZGVTdGF0aWNQYXJlbnQgJiYgc3R5bGUucG9zaXRpb24gPT09ICdzdGF0aWMnKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKG92ZXJmbG93UmVnZXgudGVzdChzdHlsZS5vdmVyZmxvdyArIHN0eWxlLm92ZXJmbG93WSArIHN0eWxlLm92ZXJmbG93WCkpIHtcclxuICAgICAgICByZXR1cm4gcGFyZW50O1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuZG9jdW1lbnRSZWYuYm9keTtcclxuICB9XHJcblxyXG4gIHBvc2l0aW9uRWxlbWVudHMoaG9zdEVsZW1lbnQ6IEhUTUxFbGVtZW50LCB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCwgcGxhY2VtZW50OiBzdHJpbmcgfCBzdHJpbmdbXSwgYXBwZW5kVG9Cb2R5PzogYm9vbGVhbik6IGFueSB7XHJcbiAgICBjb25zdCBob3N0RWxQb3NpdGlvbiA9IGFwcGVuZFRvQm9keSA/IHRoaXMub2Zmc2V0KGhvc3RFbGVtZW50LCBmYWxzZSkgOiB0aGlzLnBvc2l0aW9uKGhvc3RFbGVtZW50LCBmYWxzZSk7XHJcbiAgICBjb25zdCBzaGlmdFdpZHRoOiBhbnkgPSB7XHJcbiAgICAgIGxlZnQ6IGhvc3RFbFBvc2l0aW9uLmxlZnQsXHJcbiAgICAgIGNlbnRlcjogaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoIC8gMiAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggLyAyLFxyXG4gICAgICByaWdodDogaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoLFxyXG4gICAgfTtcclxuICAgIGNvbnN0IHNoaWZ0SGVpZ2h0OiBhbnkgPSB7XHJcbiAgICAgIHRvcDogaG9zdEVsUG9zaXRpb24udG9wLFxyXG4gICAgICBjZW50ZXI6IGhvc3RFbFBvc2l0aW9uLnRvcCArIGhvc3RFbFBvc2l0aW9uLmhlaWdodCAvIDIgLSB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCAvIDIsXHJcbiAgICAgIGJvdHRvbTogaG9zdEVsUG9zaXRpb24udG9wICsgaG9zdEVsUG9zaXRpb24uaGVpZ2h0LFxyXG4gICAgfTtcclxuICAgIGNvbnN0IHRhcmdldEVsQkNSID0gdGFyZ2V0RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICBjb25zdCB0YXJnZXRFbFBvc2l0aW9uOiBhbnkgPSB7XHJcbiAgICAgIGhlaWdodDogdGFyZ2V0RWxCQ1IuaGVpZ2h0IHx8IHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0LFxyXG4gICAgICB3aWR0aDogdGFyZ2V0RWxCQ1Iud2lkdGggfHwgdGFyZ2V0RWxlbWVudC5vZmZzZXRXaWR0aCxcclxuICAgICAgdG9wOiAwLFxyXG4gICAgICBib3R0b206IHRhcmdldEVsQkNSLmhlaWdodCB8fCB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCxcclxuICAgICAgbGVmdDogMCxcclxuICAgICAgcmlnaHQ6IHRhcmdldEVsQkNSLndpZHRoIHx8IHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGgsXHJcbiAgICB9O1xyXG5cclxuICAgIGxldCBwbGFjZW1lbnRQcmltYXJ5OiBzdHJpbmc7XHJcbiAgICBsZXQgcGxhY2VtZW50U2Vjb25kYXJ5OiBzdHJpbmc7XHJcblxyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGxhY2VtZW50KSkge1xyXG4gICAgICBjb25zdCB0YXJnZXRQbGFjZW1lbnQgPSB0aGlzLmdldFBsYWNlbWVudChob3N0RWxlbWVudCwgdGFyZ2V0RWxlbWVudCwgcGxhY2VtZW50KTtcclxuICAgICAgcGxhY2VtZW50UHJpbWFyeSA9IHRhcmdldFBsYWNlbWVudFswXTtcclxuICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID0gdGFyZ2V0UGxhY2VtZW50WzFdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcGxhY2VtZW50UHJpbWFyeSA9IHBsYWNlbWVudD8uc3BsaXQoJy0nKVswXSB8fCAndG9wJztcclxuICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID0gcGxhY2VtZW50Py5zcGxpdCgnLScpWzFdIHx8ICdjZW50ZXInO1xyXG4gICAgfVxyXG5cclxuICAgIHN3aXRjaCAocGxhY2VtZW50UHJpbWFyeSkge1xyXG4gICAgY2FzZSAndG9wJzpcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi50b3AgPSBob3N0RWxQb3NpdGlvbi50b3AgLSB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodDtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20gKz0gaG9zdEVsUG9zaXRpb24udG9wIC0gdGFyZ2V0RWxlbWVudC5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ubGVmdCA9XHJcbiAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID09PSAncmlnaHQnID8gc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnldIC0gdGFyZ2V0RWxlbWVudC5vZmZzZXRXaWR0aCA6IHNoaWZ0V2lkdGhbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5yaWdodCArPSBzaGlmdFdpZHRoW3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAnYm90dG9tJzpcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi50b3AgPSBzaGlmdEhlaWdodFtwbGFjZW1lbnRQcmltYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20gKz0gc2hpZnRIZWlnaHRbcGxhY2VtZW50UHJpbWFyeV07XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ubGVmdCA9XHJcbiAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID09PSAncmlnaHQnID8gc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnldIC0gdGFyZ2V0RWxlbWVudC5vZmZzZXRXaWR0aCA6IHNoaWZ0V2lkdGhbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5yaWdodCArPSBzaGlmdFdpZHRoW3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAnbGVmdCc6XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24udG9wID1cclxuICAgICAgICBwbGFjZW1lbnRTZWNvbmRhcnkgPT09ICdib3R0b20nID8gc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XSAtIHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0IDogc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20gKz0gc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5sZWZ0ID0gaG9zdEVsUG9zaXRpb24ubGVmdCAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ucmlnaHQgKz0gaG9zdEVsUG9zaXRpb24ubGVmdCAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAncmlnaHQnOlxyXG4gICAgICB0YXJnZXRFbFBvc2l0aW9uLnRvcCA9XHJcbiAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID09PSAnYm90dG9tJyA/IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFNlY29uZGFyeV0gLSB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCA6IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24uYm90dG9tICs9IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ubGVmdCA9IHNoaWZ0V2lkdGhbcGxhY2VtZW50UHJpbWFyeV07XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ucmlnaHQgKz0gc2hpZnRXaWR0aFtwbGFjZW1lbnRQcmltYXJ5XTtcclxuICAgICAgYnJlYWs7XHJcbiAgICBkZWZhdWx0OlxyXG4gICAgfVxyXG5cclxuICAgIHRhcmdldEVsUG9zaXRpb24udG9wID0gTWF0aC5yb3VuZCh0YXJnZXRFbFBvc2l0aW9uLnRvcCk7XHJcbiAgICB0YXJnZXRFbFBvc2l0aW9uLmJvdHRvbSA9IE1hdGgucm91bmQodGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20pO1xyXG4gICAgdGFyZ2V0RWxQb3NpdGlvbi5sZWZ0ID0gTWF0aC5yb3VuZCh0YXJnZXRFbFBvc2l0aW9uLmxlZnQpO1xyXG4gICAgdGFyZ2V0RWxQb3NpdGlvbi5yaWdodCA9IE1hdGgucm91bmQodGFyZ2V0RWxQb3NpdGlvbi5yaWdodCk7XHJcbiAgICB0YXJnZXRFbFBvc2l0aW9uLnBsYWNlbWVudFByaW1hcnkgPSBwbGFjZW1lbnRQcmltYXJ5O1xyXG4gICAgdGFyZ2V0RWxQb3NpdGlvbi5wbGFjZW1lbnRTZWNvbmRhcnkgPSBwbGFjZW1lbnRTZWNvbmRhcnk7XHJcblxyXG4gICAgcmV0dXJuIHRhcmdldEVsUG9zaXRpb247XHJcbiAgfVxyXG5cclxuICAvLyDmoLnmja7kvKDlhaXmlbDnu4TpgInlj5bnrKzkuIDkuKrlkIjpgILnmoTkvY3nva5cclxuICBwcml2YXRlIGdldFBsYWNlbWVudChob3N0RWxlbWVudDogSFRNTEVsZW1lbnQsIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50LCBwbGFjZW1lbnQ6IHN0cmluZ1tdKSB7XHJcbiAgICBjb25zdCBob3N0RWxQb3NpdGlvbiA9IHRoaXMub2Zmc2V0KGhvc3RFbGVtZW50LCBmYWxzZSk7XHJcbiAgICBjb25zdCBzaGlmdFdpZHRoOiBhbnkgPSB7XHJcbiAgICAgIGxlZnQ6IGhvc3RFbFBvc2l0aW9uLmxlZnQsXHJcbiAgICAgIGNlbnRlcjogaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoIC8gMiAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggLyAyLFxyXG4gICAgICByaWdodDogaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoLFxyXG4gICAgfTtcclxuICAgIGNvbnN0IHNoaWZ0SGVpZ2h0OiBhbnkgPSB7XHJcbiAgICAgIHRvcDogaG9zdEVsUG9zaXRpb24udG9wLFxyXG4gICAgICBjZW50ZXI6IGhvc3RFbFBvc2l0aW9uLnRvcCArIGhvc3RFbFBvc2l0aW9uLmhlaWdodCAvIDIgLSB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCAvIDIsXHJcbiAgICAgIGJvdHRvbTogaG9zdEVsUG9zaXRpb24udG9wICsgaG9zdEVsUG9zaXRpb24uaGVpZ2h0LFxyXG4gICAgfTtcclxuXHJcbiAgICBsZXQgcGxhY2VtZW50UHJpbWFyeSA9IHBsYWNlbWVudFswXS5zcGxpdCgnLScpWzBdIHx8ICd0b3AnO1xyXG4gICAgbGV0IHBsYWNlbWVudFNlY29uZGFyeSA9IHBsYWNlbWVudFswXS5zcGxpdCgnLScpWzFdIHx8ICdjZW50ZXInO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGxhY2VtZW50Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IHBsYWNlbWVudFByaW1hcnlUZW1wID0gcGxhY2VtZW50W2ldLnNwbGl0KCctJylbMF0gfHwgJ3RvcCc7XHJcbiAgICAgIGNvbnN0IHBsYWNlbWVudFNlY29uZGFyeVRlbXAgPSBwbGFjZW1lbnRbaV0uc3BsaXQoJy0nKVsxXSB8fCAnY2VudGVyJztcclxuXHJcbiAgICAgIGxldCB0b3A7XHJcbiAgICAgIGxldCBsZWZ0O1xyXG4gICAgICBzd2l0Y2ggKHBsYWNlbWVudFByaW1hcnlUZW1wKSB7XHJcbiAgICAgIGNhc2UgJ3RvcCc6XHJcbiAgICAgICAgdG9wID0gaG9zdEVsUG9zaXRpb24udG9wIC0gdGFyZ2V0RWxlbWVudC5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgICAgbGVmdCA9XHJcbiAgICAgICAgICBwbGFjZW1lbnRTZWNvbmRhcnlUZW1wID09PSAncmlnaHQnXHJcbiAgICAgICAgICAgID8gc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnlUZW1wXSAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGhcclxuICAgICAgICAgICAgOiBzaGlmdFdpZHRoW3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2JvdHRvbSc6XHJcbiAgICAgICAgdG9wID0gc2hpZnRIZWlnaHRbcGxhY2VtZW50UHJpbWFyeVRlbXBdO1xyXG4gICAgICAgIGxlZnQgPVxyXG4gICAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5VGVtcCA9PT0gJ3JpZ2h0J1xyXG4gICAgICAgICAgICA/IHNoaWZ0V2lkdGhbcGxhY2VtZW50U2Vjb25kYXJ5VGVtcF0gLSB0YXJnZXRFbGVtZW50Lm9mZnNldFdpZHRoXHJcbiAgICAgICAgICAgIDogc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnldO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdsZWZ0JzpcclxuICAgICAgICB0b3AgPVxyXG4gICAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5VGVtcCA9PT0gJ2JvdHRvbSdcclxuICAgICAgICAgICAgPyBzaGlmdEhlaWdodFtwbGFjZW1lbnRTZWNvbmRhcnlUZW1wXSAtIHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0XHJcbiAgICAgICAgICAgIDogc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgICBsZWZ0ID0gaG9zdEVsUG9zaXRpb24ubGVmdCAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcclxuICAgICAgICB0b3AgPVxyXG4gICAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5VGVtcCA9PT0gJ2JvdHRvbSdcclxuICAgICAgICAgICAgPyBzaGlmdEhlaWdodFtwbGFjZW1lbnRTZWNvbmRhcnlUZW1wXSAtIHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0XHJcbiAgICAgICAgICAgIDogc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgICBsZWZ0ID0gc2hpZnRXaWR0aFtwbGFjZW1lbnRQcmltYXJ5VGVtcF07XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMuaXNJblZpZXdQb3J0KHRhcmdldEVsZW1lbnQsIHsgb2Zmc2V0TGVmdDogbGVmdCwgb2Zmc2V0VG9wOiB0b3AgfSkpIHtcclxuICAgICAgICBwbGFjZW1lbnRQcmltYXJ5ID0gcGxhY2VtZW50W2ldLnNwbGl0KCctJylbMF0gfHwgJ3RvcCc7XHJcbiAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID0gcGxhY2VtZW50W2ldLnNwbGl0KCctJylbMV0gfHwgJ2NlbnRlcic7XHJcbiAgICAgICAgcmV0dXJuIFtwbGFjZW1lbnRQcmltYXJ5LCBwbGFjZW1lbnRTZWNvbmRhcnldO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gW3BsYWNlbWVudFByaW1hcnksIHBsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGlzSW5WaWV3UG9ydChlbGUsIHsgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0pIHtcclxuICAgIGNvbnN0IHRhcmdldEVsQkNSID0gZWxlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3Qgdmlld1BvcnRIZWlnaHQgPVxyXG4gICAgICB0aGlzLndpbmRvd1JlZi5pbm5lckhlaWdodCB8fCB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQgfHwgdGhpcy5kb2N1bWVudFJlZi5ib2R5LmNsaWVudEhlaWdodDtcclxuICAgIGNvbnN0IHZpZXdQb3J0V2lkdGggPSB0aGlzLndpbmRvd1JlZi5pbm5lcldpZHRoIHx8IHRoaXMuZG9jdW1lbnRSZWYuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoIHx8IHRoaXMuZG9jdW1lbnRSZWYuYm9keS5jbGllbnRXaWR0aDtcclxuICAgIGNvbnN0IGhlaWdodCA9IHRhcmdldEVsQkNSLmhlaWdodCB8fCB0YXJnZXRFbEJDUi5vZmZzZXRIZWlnaHQ7XHJcbiAgICBjb25zdCB3aWR0aCA9IHRhcmdldEVsQkNSLndpZHRoIHx8IHRhcmdldEVsQkNSLm9mZnNldFdpZHRoO1xyXG4gICAgb2Zmc2V0VG9wID0gb2Zmc2V0VG9wIHx8IGVsZS5vZmZzZXRUb3A7XHJcbiAgICBjb25zdCBzY3JvbGxUb3AgPSB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgdGhpcy5kb2N1bWVudFJlZi5ib2R5LnNjcm9sbFRvcDtcclxuICAgIGNvbnN0IHRvcCA9IG9mZnNldFRvcCAtIHNjcm9sbFRvcDtcclxuICAgIG9mZnNldExlZnQgPSBvZmZzZXRMZWZ0IHx8IGVsZS5vZmZzZXRMZWZ0O1xyXG4gICAgY29uc3Qgc2Nyb2xsTGVmdCA9IHRoaXMuZG9jdW1lbnRSZWYuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgdGhpcy5kb2N1bWVudFJlZi5ib2R5LnNjcm9sbExlZnQ7XHJcbiAgICBjb25zdCBsZWZ0ID0gb2Zmc2V0TGVmdCAtIHNjcm9sbExlZnQ7XHJcblxyXG4gICAgcmV0dXJuIHRvcCArIGhlaWdodCA8PSB2aWV3UG9ydEhlaWdodCAmJiB0b3AgPiAwICYmIGxlZnQgKyB3aWR0aCA8PSB2aWV3UG9ydFdpZHRoICYmIGxlZnQgPiAwO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRTdHlsZShlbGVtZW50OiBIVE1MRWxlbWVudCwgcHJvcDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLndpbmRvd1JlZi5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpW3Byb3BdO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpc1N0YXRpY1Bvc2l0aW9uZWQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcclxuICAgIHJldHVybiAodGhpcy5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSB8fCAnc3RhdGljJykgPT09ICdzdGF0aWMnO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvZmZzZXRQYXJlbnQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBIVE1MRWxlbWVudCB7XHJcbiAgICBsZXQgb2Zmc2V0UGFyZW50RWwgPSA8SFRNTEVsZW1lbnQ+ZWxlbWVudC5vZmZzZXRQYXJlbnQgfHwgdGhpcy5kb2N1bWVudFJlZi5kb2N1bWVudEVsZW1lbnQ7XHJcblxyXG4gICAgd2hpbGUgKG9mZnNldFBhcmVudEVsICYmIG9mZnNldFBhcmVudEVsICE9PSB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudCAmJiB0aGlzLmlzU3RhdGljUG9zaXRpb25lZChvZmZzZXRQYXJlbnRFbCkpIHtcclxuICAgICAgb2Zmc2V0UGFyZW50RWwgPSA8SFRNTEVsZW1lbnQ+b2Zmc2V0UGFyZW50RWwub2Zmc2V0UGFyZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBvZmZzZXRQYXJlbnRFbCB8fCB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudDtcclxuICB9XHJcbn1cclxuIl19