UNPKG

webglimpse

Version:

Webglimpse is a data visualization library for the web.

226 lines 33.6 kB
/* * Copyright (c) 2014, Metron, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import { Notification } from '../util/notification'; import { log10, hasval } from '../util/util'; import { xFrac, yFrac, isLeftMouseDown } from '../core'; export class Axis1D { constructor(vMin, vMax, vMinLimit = -Infinity, vMaxLimit = Infinity) { this._limitsChanged = new Notification(); this._vMin = Math.max(vMin, vMinLimit); this._vMax = Math.min(vMax, vMaxLimit); this._vMinLimit = vMinLimit; this._vMaxLimit = vMaxLimit; } get vMin() { return this._vMin; } get vMax() { return this._vMax; } get vMinLimit() { return this._vMinLimit; } get vMaxLimit() { return this._vMaxLimit; } get limitsChanged() { return this._limitsChanged; } set vMin(vMin) { this._vMin = Math.max(vMin, this._vMinLimit); this._limitsChanged.fire(); } set vMax(vMax) { this._vMax = Math.min(vMax, this._vMaxLimit); this._limitsChanged.fire(); } set vMinLimit(vMinLimit) { this._vMinLimit = vMinLimit; this._vMin = Math.max(this._vMin, vMinLimit); this._vMax = Math.max(this._vMax, vMinLimit); this._limitsChanged.fire(); } set vMaxLimit(vMaxLimit) { this._vMaxLimit = vMaxLimit; this._vMin = Math.min(this._vMin, vMaxLimit); this._vMax = Math.min(this._vMax, vMaxLimit); this._limitsChanged.fire(); } setVRange(vMin, vMax) { this._vMin = Math.max(vMin, this._vMinLimit); this._vMax = Math.min(vMax, this._vMaxLimit); this._limitsChanged.fire(); } get vSize() { return (this._vMax - this._vMin); } vAtFrac(vFrac) { return (this._vMin + vFrac * (this._vMax - this._vMin)); } vFrac(v) { return (v - this._vMin) / (this._vMax - this._vMin); } pan(vAmount) { if (vAmount + this._vMin < this._vMinLimit) { this._vMax = this._vMinLimit + this.vSize; this._vMin = this._vMinLimit; } else if (vAmount + this._vMax > this._vMaxLimit) { this._vMin = this._vMaxLimit - this.vSize; this._vMax = this._vMaxLimit; } else { this._vMin += vAmount; this._vMax += vAmount; } this._limitsChanged.fire(); } zoom(factor, vAnchor) { const newVMin = vAnchor - factor * (vAnchor - this._vMin); const newVMax = vAnchor + factor * (this._vMax - vAnchor); this._vMin = Math.max(newVMin, this._vMinLimit); this._vMax = Math.min(newVMax, this._vMaxLimit); this._limitsChanged.fire(); } } export function getTickInterval(axis, approxNumTicks) { const vMin = Math.min(axis.vMin, axis.vMax); const vMax = Math.max(axis.vMin, axis.vMax); const approxTickInterval = (vMax - vMin) / approxNumTicks; const prelimTickInterval = Math.pow(10, Math.round(log10(approxTickInterval))); const prelimNumTicks = (vMax - vMin) / prelimTickInterval; if (prelimNumTicks >= 5 * approxNumTicks) { return (prelimTickInterval * 5); } if (prelimNumTicks >= 2 * approxNumTicks) { return (prelimTickInterval * 2); } if (5 * prelimNumTicks <= approxNumTicks) { return (prelimTickInterval / 5); } if (2 * prelimNumTicks <= approxNumTicks) { return (prelimTickInterval / 2); } return prelimTickInterval; } export function getTickCount(axis, tickInterval) { return Math.ceil(Math.abs(axis.vSize) / tickInterval) + 1; } export function getTickPositions(axis, tickInterval, tickCount, result) { const vMin = Math.min(axis.vMin, axis.vMax); const vMax = Math.max(axis.vMin, axis.vMax); const minTickNumber = Math.floor(vMin / tickInterval); for (let i = 0; i < tickCount; i++) { result[i] = (minTickNumber + i) * tickInterval; } if (axis.vMin > axis.vMax) { // XXX: Need floor() on tickCount/2? for (let i = 0; i < tickCount / 2; i++) { const temp = result[i]; result[i] = result[tickCount - 1 - i]; result[tickCount - 1 - i] = temp; } } } export class Axis2D { constructor(xAxis, yAxis) { this._xAxis = xAxis; this._yAxis = yAxis; } get xAxis() { return this._xAxis; } get xMin() { return this._xAxis.vMin; } get xMax() { return this._xAxis.vMax; } xAtFrac(xFrac) { return this._xAxis.vAtFrac(xFrac); } get yAxis() { return this._yAxis; } get yMin() { return this._yAxis.vMin; } get yMax() { return this._yAxis.vMax; } yAtFrac(yFrac) { return this._yAxis.vAtFrac(yFrac); } onLimitsChanged(listener) { this._xAxis.limitsChanged.on(listener); this._yAxis.limitsChanged.on(listener); } pan(xAmount, yAmount) { this._xAxis.pan(xAmount); this._yAxis.pan(yAmount); } zoom(factor, xAnchor, yAnchor) { this._xAxis.zoom(factor, xAnchor); this._yAxis.zoom(factor, yAnchor); } } export function newAxis2D(xMin, xMax, yMin, yMax) { return new Axis2D(new Axis1D(xMin, xMax), new Axis1D(yMin, yMax)); } // XXX: Would be nice if this could be a const export let axisZoomStep = 1.12; export function attachAxisMouseListeners1D(pane, axis, isVertical) { let vGrab = null; pane.mouseDown.on(function (ev) { if (isLeftMouseDown(ev.mouseEvent) && !hasval(vGrab)) { vGrab = axis.vAtFrac(isVertical ? yFrac(ev) : xFrac(ev)); } }); pane.mouseMove.on(function (ev) { if (isLeftMouseDown(ev.mouseEvent) && hasval(vGrab)) { axis.pan(vGrab - axis.vAtFrac(isVertical ? yFrac(ev) : xFrac(ev))); } }); pane.mouseUp.on(function (ev) { vGrab = null; }); pane.mouseWheel.on(function (ev) { const zoomFactor = Math.pow(axisZoomStep, ev.wheelSteps); axis.zoom(zoomFactor, axis.vAtFrac(isVertical ? yFrac(ev) : xFrac(ev))); }); } export function attachAxisMouseListeners2D(pane, axis) { let xGrab = null; let yGrab = null; pane.mouseDown.on(function (ev) { if (isLeftMouseDown(ev.mouseEvent) && !hasval(xGrab)) { xGrab = axis.xAtFrac(xFrac(ev)); yGrab = axis.yAtFrac(yFrac(ev)); } }); pane.mouseMove.on(function (ev) { if (isLeftMouseDown(ev.mouseEvent) && hasval(xGrab)) { axis.pan(xGrab - axis.xAtFrac(xFrac(ev)), yGrab - axis.yAtFrac(yFrac(ev))); } }); pane.mouseUp.on(function (ev) { xGrab = null; yGrab = null; }); pane.mouseWheel.on(function (ev) { const zoomFactor = Math.pow(axisZoomStep, ev.wheelSteps); axis.zoom(zoomFactor, axis.xAtFrac(xFrac(ev)), axis.yAtFrac(yFrac(ev))); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXhpcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy93ZWJnbGltcHNlL3Bsb3QvYXhpcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUNILE9BQU8sRUFBRSxZQUFZLEVBQVksTUFBTSxzQkFBc0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM3QyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBc0IsZUFBZSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRzVFLE1BQU0sT0FBTyxNQUFNO0lBT2YsWUFBWSxJQUFZLEVBQUUsSUFBWSxFQUFFLFNBQVMsR0FBRyxDQUFDLFFBQVEsRUFBRSxTQUFTLEdBQUcsUUFBUTtRQUYzRSxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFHeEMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO1FBQzVCLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksSUFBSTtRQUNKLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQzNCLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDVCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQztJQUVELElB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LEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDOUU7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsRUFBZ0I7UUFDdEMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNiLEtBQUssR0FBRyxJQUFJLENBQUM7SUFDakIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQWdCO1FBQ3pDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1RSxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQsIE1ldHJvbiwgSW5jLlxyXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gKlxyXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLFxyXG4gKiBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XHJcbiAqXHJcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xyXG4gKiAgICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cclxuICpcclxuICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxyXG4gKiAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXHJcbiAqICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxyXG4gKlxyXG4gKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBjb3B5cmlnaHQgaG9sZGVyIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xyXG4gKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dFxyXG4gKiAgICBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXHJcbiAqXHJcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORFxyXG4gKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxyXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXHJcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SXHJcbiAqIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xyXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XHJcbiAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTlxyXG4gKiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxyXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJU1xyXG4gKiBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cclxuICovXHJcbmltcG9ydCB7IE5vdGlmaWNhdGlvbiwgTGlzdGVuZXIgfSBmcm9tICcuLi91dGlsL25vdGlmaWNhdGlvbic7XHJcbmltcG9ydCB7IGxvZzEwLCBoYXN2YWwgfSBmcm9tICcuLi91dGlsL3V0aWwnO1xyXG5pbXBvcnQgeyB4RnJhYywgeUZyYWMsIFBhbmUsIFBvaW50ZXJFdmVudCwgaXNMZWZ0TW91c2VEb3duIH0gZnJvbSAnLi4vY29yZSc7XHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIEF4aXMxRCB7XHJcbiAgICBwcml2YXRlIF92TWluOiBudW1iZXI7XHJcbiAgICBwcml2YXRlIF92TWF4OiBudW1iZXI7XHJcbiAgICBwcml2YXRlIF92TWluTGltaXQ6IG51bWJlcjtcclxuICAgIHByaXZhdGUgX3ZNYXhMaW1pdDogbnVtYmVyO1xyXG4gICAgcHJpdmF0ZSBfbGltaXRzQ2hhbmdlZCA9IG5ldyBOb3RpZmljYXRpb24oKTtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih2TWluOiBudW1iZXIsIHZNYXg6IG51bWJlciwgdk1pbkxpbWl0ID0gLUluZmluaXR5LCB2TWF4TGltaXQgPSBJbmZpbml0eSkge1xyXG4gICAgICAgIHRoaXMuX3ZNaW4gPSBNYXRoLm1heCh2TWluLCB2TWluTGltaXQpO1xyXG4gICAgICAgIHRoaXMuX3ZNYXggPSBNYXRoLm1pbih2TWF4LCB2TWF4TGltaXQpO1xyXG4gICAgICAgIHRoaXMuX3ZNaW5MaW1pdCA9IHZNaW5MaW1pdDtcclxuICAgICAgICB0aGlzLl92TWF4TGltaXQgPSB2TWF4TGltaXQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHZNaW4oKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdk1pbjtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdk1heCgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92TWF4O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB2TWluTGltaXQoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdk1pbkxpbWl0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB2TWF4TGltaXQoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdk1heExpbWl0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBsaW1pdHNDaGFuZ2VkKCk6IE5vdGlmaWNhdGlvbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xpbWl0c0NoYW5nZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHZNaW4odk1pbjogbnVtYmVyKSB7XHJcbiAgICAgICAgdGhpcy5fdk1pbiA9IE1hdGgubWF4KHZNaW4sIHRoaXMuX3ZNaW5MaW1pdCk7XHJcbiAgICAgICAgdGhpcy5fbGltaXRzQ2hhbmdlZC5maXJlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHZNYXgodk1heDogbnVtYmVyKSB7XHJcbiAgICAgICAgdGhpcy5fdk1heCA9IE1hdGgubWluKHZNYXgsIHRoaXMuX3ZNYXhMaW1pdCk7XHJcbiAgICAgICAgdGhpcy5fbGltaXRzQ2hhbmdlZC5maXJlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHZNaW5MaW1pdCh2TWluTGltaXQ6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuX3ZNaW5MaW1pdCA9IHZNaW5MaW1pdDtcclxuICAgICAgICB0aGlzLl92TWluID0gTWF0aC5tYXgodGhpcy5fdk1pbiwgdk1pbkxpbWl0KTtcclxuICAgICAgICB0aGlzLl92TWF4ID0gTWF0aC5tYXgodGhpcy5fdk1heCwgdk1pbkxpbWl0KTtcclxuICAgICAgICB0aGlzLl9saW1pdHNDaGFuZ2VkLmZpcmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgdk1heExpbWl0KHZNYXhMaW1pdDogbnVtYmVyKSB7XHJcbiAgICAgICAgdGhpcy5fdk1heExpbWl0ID0gdk1heExpbWl0O1xyXG4gICAgICAgIHRoaXMuX3ZNaW4gPSBNYXRoLm1pbih0aGlzLl92TWluLCB2TWF4TGltaXQpO1xyXG4gICAgICAgIHRoaXMuX3ZNYXggPSBNYXRoLm1pbih0aGlzLl92TWF4LCB2TWF4TGltaXQpO1xyXG4gICAgICAgIHRoaXMuX2xpbWl0c0NoYW5nZWQuZmlyZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldFZSYW5nZSh2TWluOiBudW1iZXIsIHZNYXg6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuX3ZNaW4gPSBNYXRoLm1heCh2TWluLCB0aGlzLl92TWluTGltaXQpO1xyXG4gICAgICAgIHRoaXMuX3ZNYXggPSBNYXRoLm1pbih2TWF4LCB0aGlzLl92TWF4TGltaXQpO1xyXG4gICAgICAgIHRoaXMuX2xpbWl0c0NoYW5nZWQuZmlyZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB2U2l6ZSgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiAodGhpcy5fdk1heCAtIHRoaXMuX3ZNaW4pO1xyXG4gICAgfVxyXG5cclxuICAgIHZBdEZyYWModkZyYWM6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLl92TWluICsgdkZyYWMgKiAodGhpcy5fdk1heCAtIHRoaXMuX3ZNaW4pKTtcclxuICAgIH1cclxuXHJcbiAgICB2RnJhYyh2OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiAodiAtIHRoaXMuX3ZNaW4pIC8gKHRoaXMuX3ZNYXggLSB0aGlzLl92TWluKTtcclxuICAgIH1cclxuXHJcbiAgICBwYW4odkFtb3VudDogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHZBbW91bnQgKyB0aGlzLl92TWluIDwgdGhpcy5fdk1pbkxpbWl0KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZNYXggPSB0aGlzLl92TWluTGltaXQgKyB0aGlzLnZTaXplO1xyXG4gICAgICAgICAgICB0aGlzLl92TWluID0gdGhpcy5fdk1pbkxpbWl0O1xyXG4gICAgICAgIH0gZWxzZSBpZiAodkFtb3VudCArIHRoaXMuX3ZNYXggPiB0aGlzLl92TWF4TGltaXQpIHtcclxuICAgICAgICAgICAgdGhpcy5fdk1pbiA9IHRoaXMuX3ZNYXhMaW1pdCAtIHRoaXMudlNpemU7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZNYXggPSB0aGlzLl92TWF4TGltaXQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fdk1pbiArPSB2QW1vdW50O1xyXG4gICAgICAgICAgICB0aGlzLl92TWF4ICs9IHZBbW91bnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2xpbWl0c0NoYW5nZWQuZmlyZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHpvb20oZmFjdG9yOiBudW1iZXIsIHZBbmNob3I6IG51bWJlcikge1xyXG4gICAgICAgIGNvbnN0IG5ld1ZNaW4gPSB2QW5jaG9yIC0gZmFjdG9yICogKHZBbmNob3IgLSB0aGlzLl92TWluKTtcclxuICAgICAgICBjb25zdCBuZXdWTWF4ID0gdkFuY2hvciArIGZhY3RvciAqICh0aGlzLl92TWF4IC0gdkFuY2hvcik7XHJcbiAgICAgICAgdGhpcy5fdk1pbiA9IE1hdGgubWF4KG5ld1ZNaW4sIHRoaXMuX3ZNaW5MaW1pdCk7XHJcbiAgICAgICAgdGhpcy5fdk1heCA9IE1hdGgubWluKG5ld1ZNYXgsIHRoaXMuX3ZNYXhMaW1pdCk7XHJcbiAgICAgICAgdGhpcy5fbGltaXRzQ2hhbmdlZC5maXJlKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGlja0ludGVydmFsKGF4aXM6IEF4aXMxRCwgYXBwcm94TnVtVGlja3M6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICBjb25zdCB2TWluID0gTWF0aC5taW4oYXhpcy52TWluLCBheGlzLnZNYXgpO1xyXG4gICAgY29uc3Qgdk1heCA9IE1hdGgubWF4KGF4aXMudk1pbiwgYXhpcy52TWF4KTtcclxuICAgIGNvbnN0IGFwcHJveFRpY2tJbnRlcnZhbCA9ICh2TWF4IC0gdk1pbikgLyBhcHByb3hOdW1UaWNrcztcclxuICAgIGNvbnN0IHByZWxpbVRpY2tJbnRlcnZhbCA9IE1hdGgucG93KDEwLCBNYXRoLnJvdW5kKGxvZzEwKGFwcHJveFRpY2tJbnRlcnZhbCkpKTtcclxuICAgIGNvbnN0IHByZWxpbU51bVRpY2tzID0gKHZNYXggLSB2TWluKSAvIHByZWxpbVRpY2tJbnRlcnZhbDtcclxuXHJcbiAgICBpZiAocHJlbGltTnVtVGlja3MgPj0gNSAqIGFwcHJveE51bVRpY2tzKSB7XHJcbiAgICAgICAgcmV0dXJuIChwcmVsaW1UaWNrSW50ZXJ2YWwgKiA1KTtcclxuICAgIH1cclxuICAgIGlmIChwcmVsaW1OdW1UaWNrcyA+PSAyICogYXBwcm94TnVtVGlja3MpIHtcclxuICAgICAgICByZXR1cm4gKHByZWxpbVRpY2tJbnRlcnZhbCAqIDIpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICg1ICogcHJlbGltTnVtVGlja3MgPD0gYXBwcm94TnVtVGlja3MpIHtcclxuICAgICAgICByZXR1cm4gKHByZWxpbVRpY2tJbnRlcnZhbCAvIDUpO1xyXG4gICAgfVxyXG4gICAgaWYgKDIgKiBwcmVsaW1OdW1UaWNrcyA8PSBhcHByb3hOdW1UaWNrcykge1xyXG4gICAgICAgIHJldHVybiAocHJlbGltVGlja0ludGVydmFsIC8gMik7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHByZWxpbVRpY2tJbnRlcnZhbDtcclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRUaWNrQ291bnQoYXhpczogQXhpczFELCB0aWNrSW50ZXJ2YWw6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gTWF0aC5jZWlsKE1hdGguYWJzKGF4aXMudlNpemUpIC8gdGlja0ludGVydmFsKSArIDE7XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGlja1Bvc2l0aW9ucyhheGlzOiBBeGlzMUQsIHRpY2tJbnRlcnZhbDogbnVtYmVyLCB0aWNrQ291bnQ6IG51bWJlciwgcmVzdWx0OiBGbG9hdDMyQXJyYXkpIHtcclxuICAgIGNvbnN0IHZNaW4gPSBNYXRoLm1pbihheGlzLnZNaW4sIGF4aXMudk1heCk7XHJcbiAgICBjb25zdCB2TWF4ID0gTWF0aC5tYXgoYXhpcy52TWluLCBheGlzLnZNYXgpO1xyXG5cclxuICAgIGNvbnN0IG1pblRpY2tOdW1iZXIgPSBNYXRoLmZsb29yKHZNaW4gLyB0aWNrSW50ZXJ2YWwpO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGlja0NvdW50OyBpKyspIHtcclxuICAgICAgICByZXN1bHRbaV0gPSAobWluVGlja051bWJlciArIGkpICogdGlja0ludGVydmFsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChheGlzLnZNaW4gPiBheGlzLnZNYXgpIHtcclxuICAgICAgICAvLyBYWFg6IE5lZWQgZmxvb3IoKSBvbiB0aWNrQ291bnQvMj9cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRpY2tDb3VudCAvIDI7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCB0ZW1wID0gcmVzdWx0W2ldO1xyXG4gICAgICAgICAgICByZXN1bHRbaV0gPSByZXN1bHRbdGlja0NvdW50IC0gMSAtIGldO1xyXG4gICAgICAgICAgICByZXN1bHRbdGlja0NvdW50IC0gMSAtIGldID0gdGVtcDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG5leHBvcnQgY2xhc3MgQXhpczJEIHtcclxuICAgIHByaXZhdGUgX3hBeGlzOiBBeGlzMUQ7XHJcbiAgICBwcml2YXRlIF95QXhpczogQXhpczFEO1xyXG5cclxuICAgIGdldCB4QXhpcygpOiBBeGlzMUQgeyByZXR1cm4gdGhpcy5feEF4aXM7IH1cclxuICAgIGdldCB4TWluKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl94QXhpcy52TWluOyB9XHJcbiAgICBnZXQgeE1heCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5feEF4aXMudk1heDsgfVxyXG4gICAgeEF0RnJhYyh4RnJhYzogbnVtYmVyKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3hBeGlzLnZBdEZyYWMoeEZyYWMpOyB9XHJcblxyXG4gICAgZ2V0IHlBeGlzKCk6IEF4aXMxRCB7IHJldHVybiB0aGlzLl95QXhpczsgfVxyXG4gICAgZ2V0IHlNaW4oKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3lBeGlzLnZNaW47IH1cclxuICAgIGdldCB5TWF4KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl95QXhpcy52TWF4OyB9XHJcbiAgICB5QXRGcmFjKHlGcmFjOiBudW1iZXIpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5feUF4aXMudkF0RnJhYyh5RnJhYyk7IH1cclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih4QXhpczogQXhpczFELCB5QXhpczogQXhpczFEKSB7XHJcbiAgICAgICAgdGhpcy5feEF4aXMgPSB4QXhpcztcclxuICAgICAgICB0aGlzLl95QXhpcyA9IHlBeGlzO1xyXG4gICAgfVxyXG5cclxuICAgIG9uTGltaXRzQ2hhbmdlZChsaXN0ZW5lcjogTGlzdGVuZXIpIHtcclxuICAgICAgICB0aGlzLl94QXhpcy5saW1pdHNDaGFuZ2VkLm9uKGxpc3RlbmVyKTtcclxuICAgICAgICB0aGlzLl95QXhpcy5saW1pdHNDaGFuZ2VkLm9uKGxpc3RlbmVyKTtcclxuICAgIH1cclxuXHJcbiAgICBwYW4oeEFtb3VudDogbnVtYmVyLCB5QW1vdW50OiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLl94QXhpcy5wYW4oeEFtb3VudCk7XHJcbiAgICAgICAgdGhpcy5feUF4aXMucGFuKHlBbW91bnQpO1xyXG4gICAgfVxyXG5cclxuICAgIHpvb20oZmFjdG9yOiBudW1iZXIsIHhBbmNob3I6IG51bWJlciwgeUFuY2hvcjogbnVtYmVyKSB7XHJcbiAgICAgICAgdGhpcy5feEF4aXMuem9vbShmYWN0b3IsIHhBbmNob3IpO1xyXG4gICAgICAgIHRoaXMuX3lBeGlzLnpvb20oZmFjdG9yLCB5QW5jaG9yKTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBuZXdBeGlzMkQoeE1pbjogbnVtYmVyLCB4TWF4OiBudW1iZXIsIHlNaW46IG51bWJlciwgeU1heDogbnVtYmVyKTogQXhpczJEIHtcclxuICAgIHJldHVybiBuZXcgQXhpczJEKG5ldyBBeGlzMUQoeE1pbiwgeE1heCksIG5ldyBBeGlzMUQoeU1pbiwgeU1heCkpO1xyXG59XHJcblxyXG5cclxuLy8gWFhYOiBXb3VsZCBiZSBuaWNlIGlmIHRoaXMgY291bGQgYmUgYSBjb25zdFxyXG5leHBvcnQgbGV0IGF4aXNab29tU3RlcCA9IDEuMTI7XHJcblxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaEF4aXNNb3VzZUxpc3RlbmVyczFEKHBhbmU6IFBhbmUsIGF4aXM6IEF4aXMxRCwgaXNWZXJ0aWNhbDogYm9vbGVhbikge1xyXG4gICAgbGV0IHZHcmFiOiBudW1iZXIgPSBudWxsO1xyXG5cclxuICAgIHBhbmUubW91c2VEb3duLm9uKGZ1bmN0aW9uIChldjogUG9pbnRlckV2ZW50KSB7XHJcbiAgICAgICAgaWYgKGlzTGVmdE1vdXNlRG93bihldi5tb3VzZUV2ZW50KSAmJiAhaGFzdmFsKHZHcmFiKSkge1xyXG4gICAgICAgICAgICB2R3JhYiA9IGF4aXMudkF0RnJhYyhpc1ZlcnRpY2FsID8geUZyYWMoZXYpIDogeEZyYWMoZXYpKTtcclxuICAgICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBwYW5lLm1vdXNlTW92ZS5vbihmdW5jdGlvbiAoZXY6IFBvaW50ZXJFdmVudCkge1xyXG4gICAgICAgIGlmIChpc0xlZnRNb3VzZURvd24oZXYubW91c2VFdmVudCkgJiYgaGFzdmFsKHZHcmFiKSkge1xyXG4gICAgICAgICAgICBheGlzLnBhbih2R3JhYiAtIGF4aXMudkF0RnJhYyhpc1ZlcnRpY2FsID8geUZyYWMoZXYpIDogeEZyYWMoZXYpKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcGFuZS5tb3VzZVVwLm9uKGZ1bmN0aW9uIChldjogUG9pbnRlckV2ZW50KSB7XHJcbiAgICAgICAgdkdyYWIgPSBudWxsO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcGFuZS5tb3VzZVdoZWVsLm9uKGZ1bmN0aW9uIChldjogUG9pbnRlckV2ZW50KSB7XHJcbiAgICAgICAgY29uc3Qgem9vbUZhY3RvciA9IE1hdGgucG93KGF4aXNab29tU3RlcCwgZXYud2hlZWxTdGVwcyk7XHJcbiAgICAgICAgYXhpcy56b29tKHpvb21GYWN0b3IsIGF4aXMudkF0RnJhYyhpc1ZlcnRpY2FsID8geUZyYWMoZXYpIDogeEZyYWMoZXYpKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBhdHRhY2hBeGlzTW91c2VMaXN0ZW5lcnMyRChwYW5lOiBQYW5lLCBheGlzOiBBeGlzMkQpIHtcclxuICAgIGxldCB4R3JhYjogbnVtYmVyID0gbnVsbDtcclxuICAgIGxldCB5R3JhYjogbnVtYmVyID0gbnVsbDtcclxuXHJcbiAgICBwYW5lLm1vdXNlRG93bi5vbihmdW5jdGlvbiAoZXY6IFBvaW50ZXJFdmVudCkge1xyXG4gICAgICAgIGlmIChpc0xlZnRNb3VzZURvd24oZXYubW91c2VFdmVudCkgJiYgIWhhc3ZhbCh4R3JhYikpIHtcclxuICAgICAgICAgICAgeEdyYWIgPSBheGlzLnhBdEZyYWMoeEZyYWMoZXYpKTtcclxuICAgICAgICAgICAgeUdyYWIgPSBheGlzLnlBdEZyYWMoeUZyYWMoZXYpKTtcclxuICAgICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBwYW5lLm1vdXNlTW92ZS5vbihmdW5jdGlvbiAoZXY6IFBvaW50ZXJFdmVudCkge1xyXG4gICAgICAgIGlmIChpc0xlZnRNb3VzZURvd24oZXYubW91c2VFdmVudCkgJiYgaGFzdmFsKHhHcmFiKSkge1xyXG4gICAgICAgICAgICBheGlzLnBhbih4R3JhYiAtIGF4aXMueEF0RnJhYyh4RnJhYyhldikpLCB5R3JhYiAtIGF4aXMueUF0RnJhYyh5RnJhYyhldikpKTtcclxuICAgICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBwYW5lLm1vdXNlVXAub24oZnVuY3Rpb24gKGV2OiBQb2ludGVyRXZlbnQpIHtcclxuICAgICAgICB4R3JhYiA9IG51bGw7XHJcbiAgICAgICAgeUdyYWIgPSBudWxsO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcGFuZS5tb3VzZVdoZWVsLm9uKGZ1bmN0aW9uIChldjogUG9pbnRlckV2ZW50KSB7XHJcbiAgICAgICAgY29uc3Qgem9vbUZhY3RvciA9IE1hdGgucG93KGF4aXNab29tU3RlcCwgZXYud2hlZWxTdGVwcyk7XHJcbiAgICAgICAgYXhpcy56b29tKHpvb21GYWN0b3IsIGF4aXMueEF0RnJhYyh4RnJhYyhldikpLCBheGlzLnlBdEZyYWMoeUZyYWMoZXYpKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuIl19