UNPKG

@future-grid/fgp-graph

Version:

fgp-graph is a chart lib based on Dygraphs

284 lines (205 loc) 35.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _DygraphInteraction = _interopRequireDefault(require("./DygraphInteraction")); var _utils = _interopRequireDefault(require("./utils")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var RangeHandles = function RangeHandles() { var _this = this; _classCallCheck(this, RangeHandles); _defineProperty(this, "g", void 0); _defineProperty(this, "isMobileDevice", /mobile|android/gi.test(navigator.appVersion)); _defineProperty(this, "graphDiv", void 0); _defineProperty(this, "singleZoomHandle", void 0); _defineProperty(this, "rangebarCanvasRect", void 0); _defineProperty(this, "rangeSize", 0); _defineProperty(this, "toString", function () { return "Fgp Range-bar-Handles Plugin"; }); _defineProperty(this, "activate", function (dygraph) { var _this$g; _this.g = dygraph; _this.graphDiv = _this.g.graphDiv; if ((_this$g = _this.g) === null || _this$g === void 0 ? void 0 : _this$g.getOption('showRangeSelector')) { _this.createSingleZoomHandle(); _this.initPanInteraction(); } return { didDrawChart: _this.placeHandle }; }); _defineProperty(this, "destory", function () {}); _defineProperty(this, "initPanInteraction", function () { var isPanning = false; var clientXLast = 0; var topElem = document; var dynamic = !_this.isMobileDevice; var initGap = -1; _this.g.attrs_['interactionModel'] = _DygraphInteraction["default"].dragIsPanInteractionModel; _this.g.attrs_['panEdgeFraction'] = 0.0001; var toXDataWindow = function toXDataWindow(zoomHandleStatus) { var _this$g2; var xDataLimits = (_this$g2 = _this.g) === null || _this$g2 === void 0 ? void 0 : _this$g2.xAxisExtremes(); var xDataMin = 0; var xDataMax = 0; if (xDataLimits && _this.rangebarCanvasRect) { var fact = (xDataLimits[1] - xDataLimits[0]) / _this.rangebarCanvasRect.w; xDataMin = xDataLimits[0] + (zoomHandleStatus.leftHandlePos - _this.rangebarCanvasRect.x) * fact; xDataMax = xDataLimits[0] + (zoomHandleStatus.rightHandlePos - _this.rangebarCanvasRect.x) * fact; } console.log("new positiong: ", [xDataMin, xDataMax]); return [xDataMin, xDataMax]; }; var onPanEnd = function onPanEnd(e) { if (!isPanning) { return false; } isPanning = false; _utils["default"].removeEvent(topElem, 'mousemove', onPan); _utils["default"].removeEvent(topElem, 'mouseup', onPanEnd); // If on a slower device, do pan now. if (!dynamic) { doPan(); } return true; }; var onPanStart = function onPanStart(e) { if (!isPanning) { _utils["default"].cancelEvent(e); isPanning = true; clientXLast = e.clientX; if (e.type === 'mousedown') { // These events are removed manually. _utils["default"].addEvent(topElem, 'mousemove', onPan); _utils["default"].addEvent(topElem, 'mouseup', onPanEnd); } return true; } return false; }; var doPan = function doPan() { //get left and right handles position var halfHandleWidth = _this.singleZoomHandle.width / 2; if (initGap > 0) { var leftHandlePos = parseFloat(_this.singleZoomHandle.style.left) + halfHandleWidth; var dataWindow = toXDataWindow({ leftHandlePos: leftHandlePos, rightHandlePos: leftHandlePos + initGap }); _this.g.dateWindow_ = dataWindow; _this.g.drawGraph_(false); } }; var onPan = function onPan(e) { var _this$graphDiv; if (!isPanning) { return false; } _utils["default"].cancelEvent(e); var handles = (_this$graphDiv = _this.graphDiv) === null || _this$graphDiv === void 0 ? void 0 : _this$graphDiv.getElementsByClassName('dygraph-rangesel-zoomhandle'); var halfHandleWidth = _this.singleZoomHandle.width / 2; if (handles) { var leftHandlePos = parseFloat(handles[0].style.left) + halfHandleWidth; var rightHandlePos = parseFloat(handles[1].style.left) + halfHandleWidth; initGap = rightHandlePos - leftHandlePos; } var delX = e.clientX - clientXLast; if (Math.abs(delX) < 4) { return true; } clientXLast = e.clientX; // get handle position var handlePos = parseFloat(_this.singleZoomHandle.style.left) + halfHandleWidth; // move handle if (_this.rangebarCanvasRect && handlePos + delX <= _this.rangebarCanvasRect.x) { // move outside left handlePos = _this.rangebarCanvasRect.x; } else if (_this.rangebarCanvasRect && handlePos + delX >= _this.rangebarCanvasRect.x + _this.rangebarCanvasRect.w) { // move outside right handlePos = _this.rangebarCanvasRect.x + _this.rangebarCanvasRect.w; } else { handlePos += delX; } // update position _this.singleZoomHandle.style.left = handlePos - halfHandleWidth + 'px'; if (dynamic) { doPan(); } return true; }; var onCanvasHover = function onCanvasHover(e) { console.log("panning......."); }; _this.g.addAndTrackEvent(_this.singleZoomHandle, 'mousedown', onPanStart); }); _defineProperty(this, "createSingleZoomHandle", function () { var _this$graphDiv2; var img = new Image(); img.className = 'dygraph-rangesel-zoomhandle-single'; img.style.position = 'absolute'; img.style.zIndex = "12"; img.style.visibility = 'hidden'; // Initially hidden so they don't show up in the wrong place. img.style.cursor = 'move'; img.width = 9; img.height = 16; img.src = 'data:image/png;base64,' + 'iVBORw0KGgoAAAANSUhEUgAAAAkAAAAQCAYAAADESFVDAAAAAXNSR0IArs4c6QAAAAZiS0dEANAA' + 'zwDP4Z7KegAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9sHGw0cMqdt1UwAAAAZdEVYdENv' + 'bW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAaElEQVQoz+3SsRFAQBCF4Z9WJM8KCDVwownl' + '6YXsTmCUsyKGkZzcl7zkz3YLkypgAnreFmDEpHkIwVOMfpdi9CEEN2nGpFdwD03yEqDtOgCaun7s' + 'qSTDH32I1pQA2Pb9sZecAxc5r3IAb21d6878xsAAAAAASUVORK5CYII='; // add to bar if (_this.isMobileDevice) { img.width *= 2; img.height *= 2; } _this.singleZoomHandle = img; (_this$graphDiv2 = _this.graphDiv) === null || _this$graphDiv2 === void 0 ? void 0 : _this$graphDiv2.appendChild(_this.singleZoomHandle); }); _defineProperty(this, "placeHandle", function () { var _this$g3; // when rangebar enabled if ((_this$g3 = _this.g) === null || _this$g3 === void 0 ? void 0 : _this$g3.getOption('showRangeSelector')) { var _this$g4, _this$graphDiv3; var plotArea = _this.g.layout_.getPlotArea(); var xAxisLabelHeight = 0; if ((_this$g4 = _this.g) === null || _this$g4 === void 0 ? void 0 : _this$g4.getOptionForAxis('drawAxis', 'x')) { var _this$g5, _this$g6, _this$g7; xAxisLabelHeight = ((_this$g5 = _this.g) === null || _this$g5 === void 0 ? void 0 : _this$g5.getOption('xAxisHeight')) || ((_this$g6 = _this.g) === null || _this$g6 === void 0 ? void 0 : _this$g6.getOption('axisLabelFontSize')) + 2 * ((_this$g7 = _this.g) === null || _this$g7 === void 0 ? void 0 : _this$g7.getOption('axisTickSize')); } if (plotArea) { var _this$g8; _this.rangebarCanvasRect = { x: plotArea.x, y: plotArea.y + plotArea.h + xAxisLabelHeight + 4, w: plotArea.w, h: (_this$g8 = _this.g) === null || _this$g8 === void 0 ? void 0 : _this$g8.getOption('rangeSelectorHeight') }; } // get handles var handles = (_this$graphDiv3 = _this.graphDiv) === null || _this$graphDiv3 === void 0 ? void 0 : _this$graphDiv3.getElementsByClassName('dygraph-rangesel-zoomhandle'); if (handles && handles.length > 0 && _this.rangebarCanvasRect && _this.singleZoomHandle) { // var leftHandle = handles[0]; var rightHandle = handles[1]; if (leftHandle.style.left != "" && rightHandle.style.left != "") { var leftHandlePos = parseFloat(leftHandle.style.left); var rightHandlePos = parseFloat(rightHandle.style.left); if (rightHandlePos - leftHandlePos < 2) { var _this$g9, _this$g10; var halfHandleWidth = _this.singleZoomHandle.width / 2; _this.rangeSize = parseFloat(rightHandle.style.left) + halfHandleWidth - (parseFloat(leftHandle.style.left) + halfHandleWidth); // put the handle to correct spot. var xExtremes = (_this$g9 = _this.g) === null || _this$g9 === void 0 ? void 0 : _this$g9.xAxisExtremes(); var xWindowLimits = (_this$g10 = _this.g) === null || _this$g10 === void 0 ? void 0 : _this$g10.xAxisRange(); var xRange = xExtremes[1] - xExtremes[0]; var leftPercent = Math.max(0, (xWindowLimits[0] - xExtremes[0]) / xRange); var leftCoord = _this.rangebarCanvasRect.x + _this.rangebarCanvasRect.w * leftPercent; var handleTop = Math.max(_this.rangebarCanvasRect.y, _this.rangebarCanvasRect.y + (_this.rangebarCanvasRect.h - _this.singleZoomHandle.height) / 2); _this.singleZoomHandle.style.left = leftCoord - halfHandleWidth + 'px'; _this.singleZoomHandle.style.top = handleTop + 'px'; _this.singleZoomHandle.style.visibility = 'visible'; } else { _this.singleZoomHandle.style.visibility = 'hidden'; } } } else if (_this.singleZoomHandle) { _this.singleZoomHandle.style.visibility = 'hidden'; } } }); }; exports["default"] = RangeHandles; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9leHRyYXMvUmFuZ2VIYW5kbGVzLnRzIl0sIm5hbWVzIjpbIlJhbmdlSGFuZGxlcyIsInRlc3QiLCJuYXZpZ2F0b3IiLCJhcHBWZXJzaW9uIiwiZHlncmFwaCIsImciLCJncmFwaERpdiIsImdldE9wdGlvbiIsImNyZWF0ZVNpbmdsZVpvb21IYW5kbGUiLCJpbml0UGFuSW50ZXJhY3Rpb24iLCJkaWREcmF3Q2hhcnQiLCJwbGFjZUhhbmRsZSIsImlzUGFubmluZyIsImNsaWVudFhMYXN0IiwidG9wRWxlbSIsImRvY3VtZW50IiwiZHluYW1pYyIsImlzTW9iaWxlRGV2aWNlIiwiaW5pdEdhcCIsImF0dHJzXyIsIkR5Z3JhcGhJbnRlcmFjdGlvbiIsImRyYWdJc1BhbkludGVyYWN0aW9uTW9kZWwiLCJ0b1hEYXRhV2luZG93Iiwiem9vbUhhbmRsZVN0YXR1cyIsInhEYXRhTGltaXRzIiwieEF4aXNFeHRyZW1lcyIsInhEYXRhTWluIiwieERhdGFNYXgiLCJyYW5nZWJhckNhbnZhc1JlY3QiLCJmYWN0IiwidyIsImxlZnRIYW5kbGVQb3MiLCJ4IiwicmlnaHRIYW5kbGVQb3MiLCJjb25zb2xlIiwibG9nIiwib25QYW5FbmQiLCJlIiwidXRpbHMiLCJyZW1vdmVFdmVudCIsIm9uUGFuIiwiZG9QYW4iLCJvblBhblN0YXJ0IiwiY2FuY2VsRXZlbnQiLCJjbGllbnRYIiwidHlwZSIsImFkZEV2ZW50IiwiaGFsZkhhbmRsZVdpZHRoIiwic2luZ2xlWm9vbUhhbmRsZSIsIndpZHRoIiwicGFyc2VGbG9hdCIsInN0eWxlIiwibGVmdCIsImRhdGFXaW5kb3ciLCJkYXRlV2luZG93XyIsImRyYXdHcmFwaF8iLCJoYW5kbGVzIiwiZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSIsImRlbFgiLCJNYXRoIiwiYWJzIiwiaGFuZGxlUG9zIiwib25DYW52YXNIb3ZlciIsImFkZEFuZFRyYWNrRXZlbnQiLCJpbWciLCJJbWFnZSIsImNsYXNzTmFtZSIsInBvc2l0aW9uIiwiekluZGV4IiwidmlzaWJpbGl0eSIsImN1cnNvciIsImhlaWdodCIsInNyYyIsImFwcGVuZENoaWxkIiwicGxvdEFyZWEiLCJsYXlvdXRfIiwiZ2V0UGxvdEFyZWEiLCJ4QXhpc0xhYmVsSGVpZ2h0IiwiZ2V0T3B0aW9uRm9yQXhpcyIsInkiLCJoIiwibGVuZ3RoIiwibGVmdEhhbmRsZSIsInJpZ2h0SGFuZGxlIiwicmFuZ2VTaXplIiwieEV4dHJlbWVzIiwieFdpbmRvd0xpbWl0cyIsInhBeGlzUmFuZ2UiLCJ4UmFuZ2UiLCJsZWZ0UGVyY2VudCIsIm1heCIsImxlZnRDb29yZCIsImhhbmRsZVRvcCIsInRvcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOzs7Ozs7OztJQUdxQkEsWSxHQStCakIsd0JBQWM7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQSwwQ0EzQlcsbUJBQW1CQyxJQUFuQixDQUF3QkMsU0FBUyxDQUFDQyxVQUFsQyxDQTJCWDs7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQSxxQ0FuQmMsQ0FtQmQ7O0FBQUEsb0NBakJILFlBQU07QUFDYixXQUFPLDhCQUFQO0FBQ0gsR0FlYTs7QUFBQSxvQ0FiSCxVQUFDQyxPQUFELEVBQXNCO0FBQUE7O0FBQzdCLElBQUEsS0FBSSxDQUFDQyxDQUFMLEdBQVNELE9BQVQ7QUFDQSxJQUFBLEtBQUksQ0FBQ0UsUUFBTCxHQUFzQixLQUFJLENBQUNELENBQVgsQ0FBY0MsUUFBOUI7O0FBQ0EsbUJBQUksS0FBSSxDQUFDRCxDQUFULDRDQUFJLFFBQVFFLFNBQVIsQ0FBa0IsbUJBQWxCLENBQUosRUFBNEM7QUFDeEMsTUFBQSxLQUFJLENBQUNDLHNCQUFMOztBQUNBLE1BQUEsS0FBSSxDQUFDQyxrQkFBTDtBQUNIOztBQUVELFdBQU87QUFDSEMsTUFBQUEsWUFBWSxFQUFFLEtBQUksQ0FBQ0M7QUFEaEIsS0FBUDtBQUdILEdBRWE7O0FBQUEsbUNBSUosWUFBTSxDQUVmLENBTmE7O0FBQUEsOENBV2UsWUFBTTtBQUMvQixRQUFJQyxTQUFTLEdBQUcs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LFVBQTVCLEdBQXlDLFFBQXpDO0FBQ0g7QUFFSjtBQUNKLE9BM0JELE1BMkJPLElBQUksS0FBSSxDQUFDckIsZ0JBQVQsRUFBMkI7QUFDOUIsUUFBQSxLQUFJLENBQUNBLGdCQUFMLENBQXNCRyxLQUF0QixDQUE0QmtCLFVBQTVCLEdBQXlDLFFBQXpDO0FBQ0g7QUFFSjtBQUdKLEdBbk9hO0FBRWIsQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBEeWdyYXBoIGZyb20gJ2R5Z3JhcGhzJztcbmltcG9ydCBEeWdyYXBoSW50ZXJhY3Rpb24gZnJvbSBcIi4vRHlncmFwaEludGVyYWN0aW9uXCI7XG5pbXBvcnQgdXRpbHMgZnJvbSBcIi4vdXRpbHNcIjtcblxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYW5nZUhhbmRsZXMge1xuXG4gICAgcHJpdmF0ZSBnPzogRHlncmFwaDtcblxuICAgIHByaXZhdGUgaXNNb2JpbGVEZXZpY2UgPSAvbW9iaWxlfGFuZHJvaWQvZ2kudGVzdChuYXZpZ2F0b3IuYXBwVmVyc2lvbik7XG5cbiAgICBwcml2YXRlIGdyYXBoRGl2PzogSFRNTERpdkVsZW1lbnQ7XG5cbiAgICBwcml2YXRlIHNpbmdsZVpvb21IYW5kbGU/OiBhbnk7XG5cbiAgICBwcml2YXRlIHJhbmdlYmFyQ2FudmFzUmVjdD86IHsgeDogbnVtYmVyLCB5OiBudW1iZXIsIHc6IG51bWJlciwgaDogbnVtYmVyIH07XG5cbiAgICBwcml2YXRlIHJhbmdlU2l6ZTogbnVtYmVyID0gMDtcblxuICAgIHRvU3RyaW5nID0gKCkgPT4ge1xuICAgICAgICByZXR1cm4gXCJGZ3AgUmFuZ2UtYmFyLUhhbmRsZXMgUGx1Z2luXCI7XG4gICAgfTtcblxuICAgIGFjdGl2YXRlID0gKGR5Z3JhcGg6IER5Z3JhcGgpID0+IHtcbiAgICAgICAgdGhpcy5nID0gZHlncmFwaDtcbiAgICAgICAgdGhpcy5ncmFwaERpdiA9ICg8YW55PnRoaXMuZykuZ3JhcGhEaXY7XG4gICAgICAgIGlmICh0aGlzLmc/LmdldE9wdGlvbignc2hvd1JhbmdlU2VsZWN0b3InKSkge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVTaW5nbGVab29tSGFuZGxlKCk7XG4gICAgICAgICAgICB0aGlzLmluaXRQYW5JbnRlcmFjdGlvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRpZERyYXdDaGFydDogdGhpcy5wbGFjZUhhbmRsZVxuICAgICAgICB9O1xuICAgIH07XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIH1cblxuICAgIGRlc3RvcnkgPSAoKSA9PiB7XG5cbiAgICB9O1xuXG5cbiAgICAvLy0tLS0tLS1wcml2YXRlIG1ldGhvZHMtLS0tLS0tLS8vXG5cbiAgICBwcml2YXRlIGluaXRQYW5JbnRlcmFjdGlvbiA9ICgpID0+IHtcbiAgICAgICAgbGV0IGlzUGFubmluZyA9IGZhbHNlO1xuICAgICAgICBsZXQgY2xpZW50WExhc3QgPSAwO1xuICAgICAgICBsZXQgdG9wRWxlbSA9IGRvY3VtZW50O1xuICAgICAgICBsZXQgZHluYW1pYyA9ICF0aGlzLmlzTW9iaWxlRGV2aWNlO1xuICAgICAgICBsZXQgaW5pdEdhcCA9IC0xO1xuXG5cbiAgICAgICAgKDxhbnk+dGhpcy5nKS5hdHRyc19bJ2ludGVyYWN0aW9uTW9kZWwnXSA9IER5Z3JhcGhJbnRlcmFjdGlvbi5kcmFnSXNQYW5JbnRlcmFjdGlvbk1vZGVsO1xuICAgICAgICAoPGFueT50aGlzLmcpLmF0dHJzX1sncGFuRWRnZUZyYWN0aW9uJ10gPSAwLjAwMDE7XG5cblxuICAgICAgICBsZXQgdG9YRGF0YVdpbmRvdyA9ICh6b29tSGFuZGxlU3RhdHVzOiB7IGxlZnRIYW5kbGVQb3M6IG51bWJlciwgcmlnaHRIYW5kbGVQb3M6IG51bWJlciB9KSA9PiB7XG4gICAgICAgICAgICBsZXQgeERhdGFMaW1pdHMgPSB0aGlzLmc/LnhBeGlzRXh0cmVtZXMoKTtcbiAgICAgICAgICAgIGxldCB4RGF0YU1pbiA9IDA7XG4gICAgICAgICAgICBsZXQgeERhdGFNYXggPSAwO1xuXG4gICAgICAgICAgICBpZiAoeERhdGFMaW1pdHMgJiYgdGhpcy5yYW5nZWJhckNhbnZhc1JlY3QpIHtcbiAgICAgICAgICAgICAgICBsZXQgZmFjdCA9ICh4RGF0YUxpbWl0c1sxXSAtIHhEYXRhTGltaXRzWzBdKSAvIHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0Lnc7XG4gICAgICAgICAgICAgICAgeERhdGFNaW4gPSB4RGF0YUxpbWl0c1swXSArICh6b29tSGFuZGxlU3RhdHVzLmxlZnRIYW5kbGVQb3MgLSB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC54KSAqIGZhY3Q7XG4gICAgICAgICAgICAgICAgeERhdGFNYXggPSB4RGF0YUxpbWl0c1swXSArICh6b29tSGFuZGxlU3RhdHVzLnJpZ2h0SGFuZGxlUG9zIC0gdGhpcy5yYW5nZWJhckNhbnZhc1JlY3QueCkgKiBmYWN0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5sb2coXCJuZXcgcG9zaXRpb25nOiBcIiwgW3hEYXRhTWluLCB4RGF0YU1heF0pO1xuICAgICAgICAgICAgcmV0dXJuIFt4RGF0YU1pbiwgeERhdGFNYXhdO1xuICAgICAgICB9O1xuXG4gICAgICAgIGxldCBvblBhbkVuZCA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWlzUGFubmluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzUGFubmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdXRpbHMucmVtb3ZlRXZlbnQodG9wRWxlbSwgJ21vdXNlbW92ZScsIG9uUGFuKTtcbiAgICAgICAgICAgIHV0aWxzLnJlbW92ZUV2ZW50KHRvcEVsZW0sICdtb3VzZXVwJywgb25QYW5FbmQpO1xuICAgICAgICAgICAgLy8gSWYgb24gYSBzbG93ZXIgZGV2aWNlLCBkbyBwYW4gbm93LlxuICAgICAgICAgICAgaWYgKCFkeW5hbWljKSB7XG4gICAgICAgICAgICAgICAgZG9QYW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuXG5cbiAgICAgICAgbGV0IG9uUGFuU3RhcnQgPSAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFpc1Bhbm5pbmcpIHtcbiAgICAgICAgICAgICAgICB1dGlscy5jYW5jZWxFdmVudChlKTtcbiAgICAgICAgICAgICAgICBpc1Bhbm5pbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNsaWVudFhMYXN0ID0gZS5jbGllbnRYO1xuICAgICAgICAgICAgICAgIGlmIChlLnR5cGUgPT09ICdtb3VzZWRvd24nKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZXNlIGV2ZW50cyBhcmUgcmVtb3ZlZCBtYW51YWxseS5cbiAgICAgICAgICAgICAgICAgICAgdXRpbHMuYWRkRXZlbnQodG9wRWxlbSwgJ21vdXNlbW92ZScsIG9uUGFuKTtcbiAgICAgICAgICAgICAgICAgICAgdXRpbHMuYWRkRXZlbnQodG9wRWxlbSwgJ21vdXNldXAnLCBvblBhbkVuZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuXG5cbiAgICAgICAgbGV0IGRvUGFuID0gKCkgPT4ge1xuXG4gICAgICAgICAgICAvL2dldCBsZWZ0IGFuZCByaWdodCBoYW5kbGVzIHBvc2l0aW9uXG4gICAgICAgICAgICBsZXQgaGFsZkhhbmRsZVdpZHRoID0gdGhpcy5zaW5nbGVab29tSGFuZGxlLndpZHRoIC8gMjtcbiAgICAgICAgICAgIGlmIChpbml0R2FwID4gMCkge1xuICAgICAgICAgICAgICAgIGxldCBsZWZ0SGFuZGxlUG9zID0gcGFyc2VGbG9hdCh0aGlzLnNpbmdsZVpvb21IYW5kbGUuc3R5bGUubGVmdCkgKyBoYWxmSGFuZGxlV2lkdGg7XG5cbiAgICAgICAgICAgICAgICBsZXQgZGF0YVdpbmRvdyA9IHRvWERhdGFXaW5kb3coe1xuICAgICAgICAgICAgICAgICAgICBsZWZ0SGFuZGxlUG9zOiBsZWZ0SGFuZGxlUG9zLFxuICAgICAgICAgICAgICAgICAgICByaWdodEhhbmRsZVBvczogbGVmdEhhbmRsZVBvcyArIGluaXRHYXBcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAoPGFueT50aGlzLmcpLmRhdGVXaW5kb3dfID0gZGF0YVdpbmRvdztcbiAgICAgICAgICAgICAgICAoPGFueT50aGlzLmcpLmRyYXdHcmFwaF8oZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGxldCBvblBhbiA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWlzUGFubmluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdXRpbHMuY2FuY2VsRXZlbnQoZSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXMgPSB0aGlzLmdyYXBoRGl2Py5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdkeWdyYXBoLXJhbmdlc2VsLXpvb21oYW5kbGUnKTtcbiAgICAgICAgICAgIGxldCBoYWxmSGFuZGxlV2lkdGggPSB0aGlzLnNpbmdsZVpvb21IYW5kbGUud2lkdGggLyAyO1xuXG4gICAgICAgICAgICBpZiAoaGFuZGxlcykge1xuICAgICAgICAgICAgICAgIGxldCBsZWZ0SGFuZGxlUG9zID0gcGFyc2VGbG9hdCgoPEhUTUxJbWFnZUVsZW1lbnQ+aGFuZGxlc1swXSkuc3R5bGUubGVmdCkgKyBoYWxmSGFuZGxlV2lkdGg7XG4gICAgICAgICAgICAgICAgbGV0IHJpZ2h0SGFuZGxlUG9zID0gcGFyc2VGbG9hdCgoPEhUTUxJbWFnZUVsZW1lbnQ+aGFuZGxlc1sxXSkuc3R5bGUubGVmdCkgKyBoYWxmSGFuZGxlV2lkdGg7XG4gICAgICAgICAgICAgICAgaW5pdEdhcCA9IHJpZ2h0SGFuZGxlUG9zIC0gbGVmdEhhbmRsZVBvcztcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICBsZXQgZGVsWCA9IGUuY2xpZW50WCAtIGNsaWVudFhMYXN0O1xuXG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoZGVsWCkgPCA0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNsaWVudFhMYXN0ID0gZS5jbGllbnRYO1xuXG4gICAgICAgICAgICAvLyBnZXQgaGFuZGxlIHBvc2l0aW9uXG5cbiAgICAgICAgICAgIGxldCBoYW5kbGVQb3MgPSBwYXJzZUZsb2F0KHRoaXMuc2luZ2xlWm9vbUhhbmRsZS5zdHlsZS5sZWZ0KSArIGhhbGZIYW5kbGVXaWR0aDtcblxuICAgICAgICAgICAgLy8gbW92ZSBoYW5kbGVcbiAgICAgICAgICAgIGlmICh0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdCAmJiBoYW5kbGVQb3MgKyBkZWxYIDw9IHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0LngpIHtcbiAgICAgICAgICAgICAgICAvLyBtb3ZlIG91dHNpZGUgbGVmdFxuICAgICAgICAgICAgICAgIGhhbmRsZVBvcyA9IHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0Lng7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0ICYmIGhhbmRsZVBvcyArIGRlbFggPj0gKHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0LnggKyB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC53KSkge1xuICAgICAgICAgICAgICAgIC8vIG1vdmUgb3V0c2lkZSByaWdodFxuICAgICAgICAgICAgICAgIGhhbmRsZVBvcyA9IHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0LnggKyB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC53O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVQb3MgKz0gZGVsWDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdXBkYXRlIHBvc2l0aW9uXG4gICAgICAgICAgICB0aGlzLnNpbmdsZVpvb21IYW5kbGUuc3R5bGUubGVmdCA9IGhhbmRsZVBvcyAtIGhhbGZIYW5kbGVXaWR0aCArICdweCc7XG5cbiAgICAgICAgICAgIGlmIChkeW5hbWljKSB7XG4gICAgICAgICAgICAgICAgZG9QYW4oKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cblxuICAgICAgICBsZXQgb25DYW52YXNIb3ZlciA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcInBhbm5pbmcuLi4uLi4uXCIpO1xuXG4gICAgICAgIH07XG5cblxuICAgICAgICAoPGFueT50aGlzLmcpLmFkZEFuZFRyYWNrRXZlbnQodGhpcy5zaW5nbGVab29tSGFuZGxlLCAnbW91c2Vkb3duJywgb25QYW5TdGFydCk7XG4gICAgfTtcblxuXG4gICAgcHJpdmF0ZSBjcmVhdGVTaW5nbGVab29tSGFuZGxlID0gKCkgPT4ge1xuICAgICAgICBsZXQgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgICAgIGltZy5jbGFzc05hbWUgPSAnZHlncmFwaC1yYW5nZXNlbC16b29taGFuZGxlLXNpbmdsZSc7XG4gICAgICAgIGltZy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgIGltZy5zdHlsZS56SW5kZXggPSBcIjEyXCI7XG4gICAgICAgIGltZy5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7IC8vIEluaXRpYWxseSBoaWRkZW4gc28gdGhleSBkb24ndCBzaG93IHVwIGluIHRoZSB3cm9uZyBwbGFjZS5cbiAgICAgICAgaW1nLnN0eWxlLmN1cnNvciA9ICdtb3ZlJztcbiAgICAgICAgaW1nLndpZHRoID0gOTtcbiAgICAgICAgaW1nLmhlaWdodCA9IDE2O1xuICAgICAgICBpbWcuc3JjID0gJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwnICtcbiAgICAgICAgICAgICdpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQWtBQUFBUUNBWUFBQURFU0ZWREFBQUFBWE5TUjBJQXJzNGM2UUFBQUFaaVMwZEVBTkFBJyArXG4gICAgICAgICAgICAnendEUDRaN0tlZ0FBQUFsd1NGbHpBQUFPeEFBQURzUUJsU3NPR3dBQUFBZDBTVTFGQjlzSEd3MGNNcWR0MVV3QUFBQVpkRVZZZEVOdicgK1xuICAgICAgICAgICAgJ2JXMWxiblFBUTNKbFlYUmxaQ0IzYVhSb0lFZEpUVkJYZ1E0WEFBQUFhRWxFUVZRb3orM1NzUkZBUUJDRjRaOVdKTThLQ0RWd293bmwnICtcbiAgICAgICAgICAgICc2WVhzVG1DVXN5S0drWnpjbDd6a3ozWUxreXBnQW5yZUZtREVwSGtJd1ZPTWZwZGk5Q0VFTjJuR3BGZHdEMDN5RXFEdE9nQ2F1bjdzJyArXG4gICAgICAgICAgICAncVNUREgzMkkxcFFBMlBiOXNaZWNBeGM1cjNJQWIyMWQ2ODc4eHNBQUFBQUFTVVZPUks1Q1lJST0nO1xuICAgICAgICAvLyBhZGQgdG8gYmFyXG4gICAgICAgIGlmICh0aGlzLmlzTW9iaWxlRGV2aWNlKSB7XG4gICAgICAgICAgICBpbWcud2lkdGggKj0gMjtcbiAgICAgICAgICAgIGltZy5oZWlnaHQgKj0gMjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNpbmdsZVpvb21IYW5kbGUgPSBpbWc7XG4gICAgICAgIHRoaXMuZ3JhcGhEaXY/LmFwcGVuZENoaWxkKHRoaXMuc2luZ2xlWm9vbUhhbmRsZSk7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogbW92ZSBoYW5kbGUgdG8gY29ycmVjdCBzcG90XG4gICAgICovXG4gICAgcHJpdmF0ZSBwbGFjZUhhbmRsZSA9ICgpID0+IHtcblxuICAgICAgICAvLyB3aGVuIHJhbmdlYmFyIGVuYWJsZWRcbiAgICAgICAgaWYgKHRoaXMuZz8uZ2V0T3B0aW9uKCdzaG93UmFuZ2VTZWxlY3RvcicpKSB7XG4gICAgICAgICAgICBsZXQgcGxvdEFyZWEgPSAoPGFueT50aGlzLmcpLmxheW91dF8uZ2V0UGxvdEFyZWEoKTtcbiAgICAgICAgICAgIGxldCB4QXhpc0xhYmVsSGVpZ2h0ID0gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmc/LmdldE9wdGlvbkZvckF4aXMoJ2RyYXdBeGlzJywgJ3gnKSkge1xuICAgICAgICAgICAgICAgIHhBeGlzTGFiZWxIZWlnaHQgPSB0aGlzLmc/LmdldE9wdGlvbigneEF4aXNIZWlnaHQnKSB8fCAodGhpcy5nPy5nZXRPcHRpb24oJ2F4aXNMYWJlbEZvbnRTaXplJykgKyAyICogdGhpcy5nPy5nZXRPcHRpb24oJ2F4aXNUaWNrU2l6ZScpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwbG90QXJlYSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0ID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiBwbG90QXJlYS54LFxuICAgICAgICAgICAgICAgICAgICB5OiBwbG90QXJlYS55ICsgcGxvdEFyZWEuaCArIHhBeGlzTGFiZWxIZWlnaHQgKyA0LFxuICAgICAgICAgICAgICAgICAgICB3OiBwbG90QXJlYS53LFxuICAgICAgICAgICAgICAgICAgICBoOiB0aGlzLmc/LmdldE9wdGlvbigncmFuZ2VTZWxlY3RvckhlaWdodCcpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGdldCBoYW5kbGVzXG4gICAgICAgICAgICBjb25zdCBoYW5kbGVzID0gdGhpcy5ncmFwaERpdj8uZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnZHlncmFwaC1yYW5nZXNlbC16b29taGFuZGxlJyk7XG5cbiAgICAgICAgICAgIGlmIChoYW5kbGVzICYmIGhhbmRsZXMubGVuZ3RoID4gMCAmJiB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdCAmJiB0aGlzLnNpbmdsZVpvb21IYW5kbGUpIHtcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIGNvbnN0IGxlZnRIYW5kbGUgPSA8SFRNTEltYWdlRWxlbWVudD5oYW5kbGVzWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJpZ2h0SGFuZGxlID0gPEhUTUxJbWFnZUVsZW1lbnQ+aGFuZGxlc1sxXTtcbiAgICAgICAgICAgICAgICBpZiAobGVmdEhhbmRsZS5zdHlsZS5sZWZ0ICE9IFwiXCIgJiYgcmlnaHRIYW5kbGUuc3R5bGUubGVmdCAhPSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBsZWZ0SGFuZGxlUG9zID0gcGFyc2VGbG9hdChsZWZ0SGFuZGxlLnN0eWxlLmxlZnQpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmlnaHRIYW5kbGVQb3MgPSBwYXJzZUZsb2F0KHJpZ2h0SGFuZGxlLnN0eWxlLmxlZnQpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgocmlnaHRIYW5kbGVQb3MgLSBsZWZ0SGFuZGxlUG9zKSA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGhhbGZIYW5kbGVXaWR0aCA9IHRoaXMuc2luZ2xlWm9vbUhhbmRsZS53aWR0aCAvIDI7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJhbmdlU2l6ZSA9IChwYXJzZUZsb2F0KHJpZ2h0SGFuZGxlLnN0eWxlLmxlZnQpICsgaGFsZkhhbmRsZVdpZHRoKSAtIChwYXJzZUZsb2F0KGxlZnRIYW5kbGUuc3R5bGUubGVmdCkgKyBoYWxmSGFuZGxlV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHV0IHRoZSBoYW5kbGUgdG8gY29ycmVjdCBzcG90LlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeEV4dHJlbWVzID0gdGhpcy5nPy54QXhpc0V4dHJlbWVzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4V2luZG93TGltaXRzID0gdGhpcy5nPy54QXhpc1JhbmdlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4UmFuZ2UgPSB4RXh0cmVtZXNbMV0gLSB4RXh0cmVtZXNbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0UGVyY2VudCA9IE1hdGgubWF4KDAsICh4V2luZG93TGltaXRzWzBdIC0geEV4dHJlbWVzWzBdKSAvIHhSYW5nZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0Q29vcmQgPSB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC54ICsgdGhpcy5yYW5nZWJhckNhbnZhc1JlY3QudyAqIGxlZnRQZXJjZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlVG9wID0gTWF0aC5tYXgodGhpcy5yYW5nZWJhckNhbnZhc1JlY3QueSwgdGhpcy5yYW5nZWJhckNhbnZhc1JlY3QueSArICh0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC5oIC0gdGhpcy5zaW5nbGVab29tSGFuZGxlLmhlaWdodCkgLyAyKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaW5nbGVab29tSGFuZGxlLnN0eWxlLmxlZnQgPSAobGVmdENvb3JkIC0gaGFsZkhhbmRsZVdpZHRoKSArICdweCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNpbmdsZVpvb21IYW5kbGUuc3R5bGUudG9wID0gaGFuZGxlVG9wICsgJ3B4JztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2luZ2xlWm9vbUhhbmRsZS5zdHlsZS52aXNpYmlsaXR5ID0gJ3Zpc2libGUnO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaW5nbGVab29tSGFuZGxlLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNpbmdsZVpvb21IYW5kbGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNpbmdsZVpvb21IYW5kbGUuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuXG4gICAgfTtcblxuXG59XG4iXX0=