@future-grid/fgp-graph
Version:
fgp-graph is a chart lib based on Dygraphs
530 lines (405 loc) • 72.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.GraphInteractions = void 0;
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 GraphInteractions = function GraphInteractions(callback, dateRange) {
var _this = this;
_classCallCheck(this, GraphInteractions);
this.callback = callback;
this.dateRange = dateRange;
_defineProperty(this, "panEnable", void 0);
_defineProperty(this, "mouseTimer", void 0);
_defineProperty(this, "scrollEnable", void 0);
_defineProperty(this, "scrollTimer", void 0);
_defineProperty(this, "zoomTimer", void 0);
_defineProperty(this, "scaleTimer", void 0);
_defineProperty(this, "preDatewindow", void 0);
_defineProperty(this, "needRefresh", void 0);
_defineProperty(this, "yAxisRangeChanged", void 0);
_defineProperty(this, "LOG_SCALE", 10);
_defineProperty(this, "LN_TEN", Math.log(this.LOG_SCALE));
_defineProperty(this, "log10", function (x) {
return Math.log(x) / _this.LN_TEN;
});
_defineProperty(this, "pageX", function (e) {
return !e.pageX || e.pageX < 0 ? 0 : e.pageX;
});
_defineProperty(this, "pageY", function (e) {
return !e.pageY || e.pageY < 0 ? 0 : e.pageY;
});
_defineProperty(this, "dragGetX_", function (e, context) {
return _this.pageX(e) - context.px;
});
_defineProperty(this, "dragGetY_", function (e, context) {
return _this.pageY(e) - context.py;
});
_defineProperty(this, "endPan", function (event, g, context) {
context.dragEndX = _this.dragGetX_(event, context);
context.dragEndY = _this.dragGetY_(event, context);
var regionWidth = Math.abs(context.dragEndX - context.dragStartX);
var regionHeight = Math.abs(context.dragEndY - context.dragStartY);
if (regionWidth < 2 && regionHeight < 2 && g.lastx_ !== undefined && g.lastx_ != -1) {
_this.treatMouseOpAsClick(g, event, context);
}
context.regionWidth = regionWidth;
context.regionHeight = regionHeight;
});
_defineProperty(this, "startPan", function (event, g, context) {
var i, axis;
context.isPanning = true;
var xRange = g.xAxisRange();
if (g.getOptionForAxis("logscale", "x")) {
context.initialLeftmostDate = _this.log10(xRange[0]);
context.dateRange = _this.log10(xRange[1]) - _this.log10(xRange[0]);
} else {
context.initialLeftmostDate = xRange[0];
context.dateRange = xRange[1] - xRange[0];
}
context.xUnitsPerPixel = context.dateRange / (g.plotter_.area.w - 1);
if (g.getNumericOption("panEdgeFraction")) {
var maxXPixelsToDraw = g.width_ * g.getNumericOption("panEdgeFraction");
var xExtremes = g.xAxisExtremes(); // I REALLY WANT TO CALL THIS xTremes!
var boundedLeftX = g.toDomXCoord(xExtremes[0]) - maxXPixelsToDraw;
var boundedRightX = g.toDomXCoord(xExtremes[1]) + maxXPixelsToDraw;
var boundedLeftDate = g.toDataXCoord(boundedLeftX);
var boundedRightDate = g.toDataXCoord(boundedRightX);
context.boundedDates = [boundedLeftDate, boundedRightDate];
var boundedValues = [];
var maxYPixelsToDraw = g.height_ * g.getNumericOption("panEdgeFraction");
for (i = 0; i < g.axes_.length; i++) {
axis = g.axes_[i];
var yExtremes = axis.extremeRange;
var boundedTopY = g.toDomYCoord(yExtremes[0], i) + maxYPixelsToDraw;
var boundedBottomY = g.toDomYCoord(yExtremes[1], i) - maxYPixelsToDraw;
var boundedTopValue = g.toDataYCoord(boundedTopY, i);
var boundedBottomValue = g.toDataYCoord(boundedBottomY, i);
boundedValues[i] = [boundedTopValue, boundedBottomValue];
}
context.boundedValues = boundedValues;
} // Record the range of each y-axis at the start of the drag.
// If any axis has a valueRange, then we want a 2D pan.
// We can't store data directly in g.axes_, because it does not belong to us
// and could change out from under us during a pan (say if there's a data
// update).
context.is2DPan = false;
context.axes = [];
for (i = 0; i < g.axes_.length; i++) {
axis = g.axes_[i];
var axis_data = {
initialTopValue: 0,
dragValueRange: 0,
unitsPerPixel: 0
};
var yRange = g.yAxisRange(i); // TODO(konigsberg): These values should be in |context|.
// In log scale, initialTopValue, dragValueRange and unitsPerPixel are log scale.
var logscale = g.attributes_.getForAxis("logscale", i);
if (logscale) {
axis_data.initialTopValue = _this.log10(yRange[1]);
axis_data.dragValueRange = _this.log10(yRange[1]) - _this.log10(yRange[0]);
} else {
axis_data.initialTopValue = yRange[1];
axis_data.dragValueRange = yRange[1] - yRange[0];
}
axis_data.unitsPerPixel = axis_data.dragValueRange / (g.plotter_.area.h - 1);
context.axes.push(axis_data); // While calculating axes, set 2dpan.
if (axis.valueRange) context.is2DPan = true;
}
});
_defineProperty(this, "treatMouseOpAsClick", function (g, event, context) {
var clickCallback = g.getFunctionOption('clickCallback');
var pointClickCallback = g.getFunctionOption('pointClickCallback');
var selectedPoint = null; // Find out if the click occurs on a point.
var closestIdx = -1;
var closestDistance = Number.MAX_VALUE; // check if the click was on a particular point.
for (var i = 0; i < g.selPoints_.length; i++) {
var p = g.selPoints_[i];
var distance = Math.pow(p.canvasx - context.dragEndX, 2) + Math.pow(p.canvasy - context.dragEndY, 2);
if (!isNaN(distance) && (closestIdx == -1 || distance < closestDistance)) {
closestDistance = distance;
closestIdx = i;
}
} // Allow any click within two pixels of the dot.
var radius = g.getNumericOption('highlightCircleSize') + 2;
if (closestDistance <= radius * radius) {
selectedPoint = g.selPoints_[closestIdx];
}
if (selectedPoint) {
var _e = {
cancelable: true,
point: selectedPoint,
canvasx: context.dragEndX,
canvasy: context.dragEndY
};
var defaultPrevented = g.cascadeEvents_('pointClick', _e);
if (defaultPrevented) {
// Note: this also prevents click / clickCallback from firing.
return;
}
if (pointClickCallback) {
pointClickCallback.call(g, event, selectedPoint);
}
}
var e = {
cancelable: true,
xval: g.lastx_,
// closest point by x value
pts: g.selPoints_,
canvasx: context.dragEndX,
canvasy: context.dragEndY
};
if (!g.cascadeEvents_('click', e)) {
if (clickCallback) {
// TODO(danvk): pass along more info about the points, e.g. 'x'
clickCallback.call(g, event, g.lastx_, g.selPoints_);
}
}
});
_defineProperty(this, "offsetToPercentage", function (g, offsetX, offsetY) {
// This is calculating the pixel offset of the leftmost date.
var xOffset = g.toDomCoords(g.xAxisRange()[0], null)[0];
var yar0 = g.yAxisRange(0); // This is calculating the pixel of the higest value. (Top pixel)
var yOffset = g.toDomCoords(null, yar0[1])[1]; // x y w and h are relative to the corner of the drawing area,
// so that the upper corner of the drawing area is (0, 0).
var x = offsetX - xOffset;
var y = offsetY - yOffset; // This is computing the rightmost pixel, effectively defining the
// width.
var w = g.toDomCoords(g.xAxisRange()[1], null)[0] - xOffset; // This is computing the lowest pixel, effectively defining the height.
var h = g.toDomCoords(null, yar0[0])[1] - yOffset; // Percentage from the left.
var xPct = w == 0 ? 0 : x / w; // Percentage from the top.
var yPct = h == 0 ? 0 : y / h; // The (1-) part below changes it from "% distance down from the top"
// to "% distance up from the bottom".
return [xPct, 1 - yPct];
});
_defineProperty(this, "pan", function (event, g, context, side) {
context.dragEndX = _this.dragGetX_(event, context);
context.dragEndY = _this.dragGetY_(event, context);
var minDate = context.initialLeftmostDate - (context.dragEndX - context.dragStartX) * context.xUnitsPerPixel;
if (context.boundedDates) {
minDate = Math.max(minDate, context.boundedDates[0]);
}
var maxDate = minDate + context.dateRange;
if (context.boundedDates) {
if (maxDate > context.boundedDates[1]) {
// Adjust minDate, and recompute maxDate.
minDate = minDate - (maxDate - context.boundedDates[1]);
maxDate = minDate + context.dateRange;
}
} // y-axis scaling is automatic unless this is a full 2D pan.
if (context.is2DPan) {
var pixelsDragged = context.dragEndY - context.dragStartY; // Adjust each axis appropriately.
if (side && ("r" == side || "l" == side)) {
var index = side == 'l' ? 0 : 1;
var axis = g.axes_[index];
var axis_data = context.axes[index];
var unitsDragged = pixelsDragged * axis_data.unitsPerPixel;
var boundedValue = context.boundedValues ? context.boundedValues[index] : null; // In log scale, maxValue and minValue are the logs of those values.
var maxValue = axis_data.initialTopValue + unitsDragged;
if (boundedValue) {
maxValue = Math.min(maxValue, boundedValue[index]);
}
var minValue = maxValue - axis_data.dragValueRange;
if (boundedValue) {
if (minValue < boundedValue[0]) {
// Adjust maxValue, and recompute minValue.
maxValue = maxValue - (minValue - boundedValue[0]);
minValue = maxValue - axis_data.dragValueRange;
}
}
if (g.attributes_.getForAxis("logscale", index)) {
axis.valueRange = [Math.pow(10, minValue), Math.pow(10, maxValue)];
axis.valueWindow = [Math.pow(10, minValue), Math.pow(10, maxValue)];
axis.extremeRange = [Math.pow(10, minValue), Math.pow(10, maxValue)];
} else {
axis.valueRange = [minValue, maxValue];
axis.valueWindow = [minValue, maxValue];
axis.extremeRange = [minValue, maxValue];
}
g.drawGraph_(true);
} else {
//
var zoomRange = _this.dateRange;
if (zoomRange && (minDate < zoomRange[0] || maxDate > zoomRange[1])) {
// console.info("return~~~~", new Date(minDate), new Date(zoomRange[0]), new Date(maxDate), new Date(zoomRange[1]));
return;
}
if (g.getOptionForAxis("logscale", "x")) {
g.dateWindow_ = [new Date(Math.pow(10, minDate)), new Date(Math.pow(10, maxDate))];
} else {
g.dateWindow_ = [new Date(minDate), new Date(maxDate)];
}
g.drawGraph_(false);
}
}
});
_defineProperty(this, "adjustAxis", function (axis, zoomInPercentage, bias) {
var delta = axis[1] - axis[0];
var increment = delta * zoomInPercentage;
var foo = [increment * bias, increment * (1 - bias)];
return [axis[0] + foo[0], axis[1] - foo[1]];
});
_defineProperty(this, "zoom", function (g, zoomInPercentage, xBias, yBias, direction, side, e) {
xBias = xBias || 0.5;
yBias = yBias || 0.5;
var yAxes = g.axes_;
var newYAxes = [];
for (var i = 0; i < g.numAxes(); i++) {
if (!yAxes[i].valueRange) {
yAxes[i].valueRange = [yAxes[i].minyval, yAxes[i].maxyval];
}
newYAxes[i] = _this.adjustAxis(yAxes[i].valueRange, zoomInPercentage, yBias);
}
if ('v' == direction) {
if (_this.zoomTimer) {
window.clearTimeout(_this.zoomTimer);
}
if ('l' == side) {
yAxes[0]['valueRange'] = newYAxes[0];
yAxes[0]['valueWindow'] = newYAxes[0];
yAxes[0]['extremeRange'] = newYAxes[0];
} else if ('r' == side && g.numAxes() == 2) {
yAxes[1]['valueRange'] = newYAxes[1];
yAxes[1]['valueWindow'] = newYAxes[1];
yAxes[1]['extremeRange'] = newYAxes[1];
}
_this.zoomTimer = window.setTimeout(function () {
_this.callback(e, g.yAxisRanges(), false);
}, 500);
g.drawGraph_(false);
} else {
if (_this.scrollTimer) {
window.clearTimeout(_this.scrollTimer);
}
var ranges = g.dateWindow_;
if (ranges[0] instanceof Date) {
ranges[0] = ranges[0].getTime();
ranges[1] = ranges[1].getTime();
}
var newZoomRange = _this.adjustAxis(ranges, zoomInPercentage, xBias); // do not bigger than range data
var zoomRange = _this.dateRange;
_this.scrollTimer = window.setTimeout(function () {
_this.callback(e, g.yAxisRanges(), true);
}, 500);
if (zoomRange && newZoomRange[0] < zoomRange[0] && newZoomRange[1] > zoomRange[1]) {
return;
} else if (newZoomRange[0] >= newZoomRange[1]) {
return;
} else if (zoomRange && newZoomRange[0] <= zoomRange[0] && newZoomRange[1] < zoomRange[1]) {
g.updateOptions({
dateWindow: [zoomRange[0], newZoomRange[1]]
});
} else if (zoomRange && newZoomRange[0] > zoomRange[0] && newZoomRange[1] >= zoomRange[1]) {
g.updateOptions({
dateWindow: [newZoomRange[0], zoomRange[1]]
});
} else {
g.updateOptions({
dateWindow: [newZoomRange[0], newZoomRange[1]]
});
}
}
});
_defineProperty(this, "mouseUp", function (e, g, context) {
// call callback on windows mouseup
// console.debug("mouse up");
var currentDatewindow = g.dateWindow_;
if (currentDatewindow[0] instanceof Date) {
currentDatewindow[0] = currentDatewindow[0].getTime();
currentDatewindow[1] = currentDatewindow[1].getTime();
}
context.isPanning = false; // Dygraph.endPan(event, g, context);
_this.endPan(e, g, context); // call upadte this.panEnable = false;
if (_this.panEnable && _this.needRefresh && (_this.preDatewindow[0] != currentDatewindow[0] || _this.preDatewindow[1] != currentDatewindow[1])) {
_this.callback(e, g.yAxisRanges(), true);
_this.panEnable = false;
} else if (_this.yAxisRangeChanged) {
_this.callback(e, g.yAxisRanges(), false);
_this.panEnable = false;
}
});
_defineProperty(this, "mouseDown", function (e, g, context) {
_this.preDatewindow = g.dateWindow_;
if (_this.preDatewindow[0] instanceof Date) {
_this.preDatewindow[0] = _this.preDatewindow[0].getTime();
_this.preDatewindow[1] = _this.preDatewindow[1].getTime();
}
_this.panEnable = true;
context.initializeMouseDown(event, g, context);
_this.startPan(e, g, context); // console.debug("mouse down", context);
});
_defineProperty(this, "mouseMove", function (e, g, context) {
if (_this.scaleTimer) {
window.clearTimeout(_this.scaleTimer);
}
if (_this.panEnable && context.isPanning) {
if (e.offsetX <= g.plotter_.area.x) {
_this.needRefresh = false;
_this.yAxisRangeChanged = true;
_this.pan(e, g, context, 'l');
_this.callback(e, g.yAxisRanges(), false);
} else if (e.offsetX >= g.plotter_.area.x + g.plotter_.area.w) {
_this.needRefresh = false;
_this.yAxisRangeChanged = true;
_this.pan(e, g, context, 'r');
_this.callback(e, g.yAxisRanges(), false);
} else {
_this.needRefresh = true;
_this.pan(e, g, context, 'h');
}
}
});
_defineProperty(this, "mouseOut", function (e, g, context) {
// console.debug("mouse out");
if (_this.mouseTimer) {
window.clearTimeout(_this.mouseTimer);
}
_this.scrollEnable = false;
});
_defineProperty(this, "mouseScroll", function (e, g, context) {
if (_this.scrollEnable) {
//
var normal;
if (e instanceof WheelEvent) {
normal = e.detail ? e.detail * -1 : e.deltaY / 40;
} else {
normal = e.detail ? e.detail * -1 : e.wheelDelta / 40;
} // For me the normalized value shows 0.075 for one click. If I took
// that verbatim, it would be a 7.5%.
var percentage = normal / 50;
if (!(e.offsetX && e.offsetY)) {
e.offsetX = e.layerX - e.target.offsetLeft;
e.offsetY = e.layerY - e.target.offsetTop;
}
var percentages = _this.offsetToPercentage(g, e.offsetX, e.offsetY);
var xPct = percentages[0];
var yPct = percentages[1]; //
if (e.offsetX <= g.plotter_.area.x) {
// left zoom
_this.zoom(g, percentage, xPct, yPct, 'v', 'l');
} else if (e.offsetX >= g.plotter_.area.x + g.plotter_.area.w) {
// right zoom
_this.zoom(g, percentage, xPct, yPct, 'v', 'r');
} else {
// middle zoom
_this.zoom(g, percentage, xPct, yPct, 'h', 'm');
}
_utils["default"].cancelEvent(e);
}
});
_defineProperty(this, "mouseEnter", function (e, g, context) {
if (_this.mouseTimer) {
window.clearTimeout(_this.mouseTimer);
}
_this.mouseTimer = window.setTimeout(function () {
_this.scrollEnable = true; // console.debug("enable scroll zooming~");
}, 1000);
});
this.panEnable = false;
this.scrollEnable = false;
};
exports.GraphInteractions = GraphInteractions;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9leHRyYXMvaW50ZXJhY3Rpb25zLnRzIl0sIm5hbWVzIjpbIkdyYXBoSW50ZXJhY3Rpb25zIiwiY2FsbGJhY2siLCJkYXRlUmFuZ2UiLCJNYXRoIiwibG9nIiwiTE9HX1NDQUxFIiwieCIsIkxOX1RFTiIsImUiLCJwYWdlWCIsInBhZ2VZIiwiY29udGV4dCIsInB4IiwicHkiLCJldmVudCIsImciLCJkcmFnRW5kWCIsImRyYWdHZXRYXyIsImRyYWdFbmRZIiwiZHJhZ0dldFlfIiwicmVnaW9uV2lkdGgiLCJhYnMiLCJkcmFnU3RhcnRYIiwicmVnaW9uSGVpZ2h0IiwiZHJhZ1N0YXJ0WSIsImxhc3R4XyIsInVuZGVmaW5lZCIsInRyZWF0TW91c2VPcEFzQ2xpY2siLCJpIiwiYXhpcyIsImlzUGFubmluZyIsInhSYW5nZSIsInhBeGlzUmFuZ2UiLCJnZXRPcHRpb25Gb3JBeGlzIiwiaW5pdGlhbExlZnRtb3N0RGF0ZSIsImxvZzEwIiwieFVuaXRzUGVyUGl4ZWwiLCJwbG90dGVyXyIsImFyZWEiLCJ3IiwiZ2V0TnVtZXJpY09wdGlvbiIsIm1heFhQaXhlbHNUb0RyYXciLCJ3aWR0aF8iLCJ4RXh0cmVtZXMiLCJ4QXhpc0V4dHJlbWVzIiwiYm91bmRlZExlZnRYIiwidG9Eb21YQ29vcmQiLCJib3VuZGVkUmlnaHRYIiwiYm91bmRlZExlZnREYXRlIiwidG9EYXRhWENvb3JkIiwiYm91bmRlZFJpZ2h0RGF0ZSIsImJvdW5kZWREYXRlcyIsImJvdW5kZWRWYWx1ZXMiLCJtYXhZUGl4ZWxzVG9EcmF3IiwiaGVpZ2h0XyIsImF4ZXNfIiwibGVuZ3RoIiwieUV4dHJlbWVzIiwiZXh0cmVtZVJhbmdlIiwiYm91bmRlZFRvcFkiLCJ0b0RvbVlDb29yZCIsImJvdW5kZWRCb3R0b21ZIiwiYm91bmRlZFRvcFZhbHVlIiwidG9EYXRhWUNvb3JkIiwiYm91bmRlZEJvdHRvbVZhbHVlIiwiaXMyRFBhbiIsImF4ZXMiLCJheGlzX2RhdGEiLCJpbml0aWFsVG9wVmFsdWUiLCJkcmFnVmFsdWVSYW5nZSIsInVuaXRzUGVyUGl4ZWwiLCJ5UmFuZ2UiLCJ5QXhpc1JhbmdlIiwibG9nc2NhbGUiLCJhdHRyaWJ1dGVzXyIsImdldEZvckF4aXMiLCJoIiwicHVzaCIsInZhbHVlUmFuZ2UiLCJjbGlja0NhbGxiYWNrIiwiZ2V0RnVuY3Rpb25PcHRpb24iLCJwb2ludENsaWNrQ2FsbGJhY2siLCJzZWxlY3RlZFBvaW50IiwiY2xvc2VzdElkeCIsImNsb3Nlc3REaXN0YW5jZSIsIk51bWJlciIsIk1BWF9WQUxVRSIsInNlbFBvaW50c18iLCJwIiwiZGlzdGFuY2UiLCJwb3ciLCJjYW52YXN4IiwiY2FudmFzeSIsImlzTmFOIiwicmFkaXVzIiwiY2FuY2VsYWJsZSIsInBvaW50IiwiZGVmYXVsdFByZXZlbnRlZCIsImNhc2NhZGVFdmVudHNfIiwiY2FsbCIsInh2YWwiLCJwdHMiLCJvZmZzZXRYIiwib2Zmc2V0WSIsInhPZmZzZXQiLCJ0b0RvbUNvb3JkcyIsInlhcjAiLCJ5T2Zmc2V0IiwieSIsInhQY3QiLCJ5UGN0Iiwic2lkZSIsIm1pbkRhdGUiLCJtYXgiLCJtYXhEYXRlIiwicGl4ZWxzRHJhZ2dlZCIsImluZGV4IiwidW5pdHNEcmFnZ2VkIiwiYm91bmRlZFZhbHVlIiwibWF4VmFsdWUiLCJtaW4iLCJtaW5WYWx1ZSIsInZhbHVlV2luZG93IiwiZHJhd0dyYXBoXyIsInpvb21SYW5nZSIsImRhdGVXaW5kb3dfIiwiRGF0ZSIsInpvb21JblBlcmNlbnRhZ2UiLCJiaWFzIiwiZGVsdGEiLCJpbmNyZW1lbnQiLCJmb28iLCJ4QmlhcyIsInlCaWFzIiwiZGlyZWN0aW9uIiwieUF4ZXMiLCJuZXdZQXhlcyIsIm51bUF4ZXMiLCJtaW55dmFsIiwibWF4eXZhbCIsImFkanVzdEF4aXMiLCJ6b29tVGltZXIiLCJ3aW5kb3ciLCJjbGVhclRpbWVvdXQiLCJzZXRUaW1lb3V0IiwieUF4aXNSYW5nZXMiLCJzY3JvbGxUaW1lciIsInJhbmdlcyIsImdldFRpbWUiLCJuZXdab29tUmFuZ2UiLCJ1cGRhdGVPcHRpb25zIiwiZGF0ZVdpbmRvdyIsImN1cnJlbnREYXRld2luZG93IiwiZW5kUGFuIiwicGFuRW5hYmxlIiwibmVlZFJlZnJlc2giLCJwcmVEYXRld2luZG93IiwieUF4aXNSYW5nZUNoYW5nZWQiLCJpbml0aWFsaXplTW91c2VEb3duIiwic3RhcnRQYW4iLCJzY2FsZVRpbWVyIiwicGFuIiwibW91c2VUaW1lciIsInNjcm9sbEVuYWJsZSIsIm5vcm1hbCIsIldoZWVsRXZlbnQiLCJkZXRhaWwiLCJkZWx0YVkiLCJ3aGVlbERlbHRhIiwicGVyY2VudGFnZSIsImxheWVyWCIsInRhcmdldCIsIm9mZnNldExlZnQiLCJsYXllclkiLCJvZmZzZXRUb3AiLCJwZXJjZW50YWdlcyIsIm9mZnNldFRvUGVyY2VudGFnZSIsInpvb20iLCJ1dGlscyIsImNhbmNlbEV2ZW50Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7Ozs7O0lBRWFBLGlCLEdBc0JULDJCQUFtQkMsUUFBbkIsRUFBeUNDLFNBQXpDLEVBQW9FO0FBQUE7O0FBQUE7O0FBQUEsT0FBakRELFFBQWlELEdBQWpEQSxRQUFpRDtBQUFBLE9BQTNCQyxTQUEyQixHQUEzQkEsU0FBMkI7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUEscUNBS2hELEVBTGdEOztBQUFBLGtDQU1uREMsSUFBSSxDQUFDQyxHQUFMLENBQVMsS0FBS0MsU0FBZCxDQU5tRDs7QUFBQSxpQ0FTcEQsVUFBQ0MsQ0FBRCxFQUFlO0FBQzNCLFdBQU9ILElBQUksQ0FBQ0MsR0FBTCxDQUFTRSxDQUFULElBQWMsS0FBSSxDQUFDQyxNQUExQjtBQUNILEdBWG1FOztBQUFBLGlDQWFwRCxVQUFDQyxDQUFELEVBQW1CO0FBQy9CLFdBQU8sQ0FBQ0EsQ0FBQyxDQUFDQyxLQUFILElBQVlELENBQUMsQ0FBQ0MsS0FBRixHQUFVLENBQXRCLEdBQTBCLENBQTFCLEdBQThCRCxDQUFDLENBQUNDLEtBQXZDO0FB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QXlCNUQsSUFBekIsRUFBK0JDLElBQS9CLEVBQXFDLEdBQXJDLEVBQTBDLEdBQTFDO0FBQ0gsT0FITSxNQUdBO0FBQ0g7QUFDQSxRQUFBLEtBQUksQ0FBQ21FLElBQUwsQ0FBVWxLLENBQVYsRUFBYTBKLFVBQWIsRUFBeUI1RCxJQUF6QixFQUErQkMsSUFBL0IsRUFBcUMsR0FBckMsRUFBMEMsR0FBMUM7QUFDSDs7QUFDRG9FLHdCQUFNQyxXQUFOLENBQWtCM0ssQ0FBbEI7QUFDSDtBQUNKLEdBdmNtRTs7QUFBQSxzQ0F5Y2hELFVBQUNBLENBQUQsRUFBZ0JPLENBQWhCLEVBQXdCSixPQUF4QixFQUF5QztBQUV6RCxRQUFJLEtBQUksQ0FBQ3VKLFVBQVQsRUFBcUI7QUFDakJwQixNQUFBQSxNQUFNLENBQUNDLFlBQVAsQ0FBb0IsS0FBSSxDQUFDbUIsVUFBekI7QUFDSDs7QUFDRCxJQUFBLEtBQUksQ0FBQ0EsVUFBTCxHQUFrQnBCLE1BQU0sQ0FBQ0UsVUFBUCxDQUFrQixZQUFNO0FBQ3RDLE1BQUEsS0FBSSxDQUFDbUIsWUFBTCxHQUFvQixJQUFwQixDQURzQyxDQUV0QztBQUNILEtBSGlCLEVBR2YsSUFIZSxDQUFsQjtBQUlILEdBbGRtRTs7QUFDaEUsT0FBS1QsU0FBTCxHQUFpQixLQUFqQjtBQUNBLE9BQUtTLFlBQUwsR0FBb0IsS0FBcEI7QUFDSCxDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgR3JhcGhJbnRlcmFjdGlvbnMge1xuXG5cbiAgICBwcml2YXRlIHBhbkVuYWJsZSE6IGJvb2xlYW47XG5cbiAgICBwcml2YXRlIG1vdXNlVGltZXIhOiBudW1iZXI7XG5cbiAgICBwcml2YXRlIHNjcm9sbEVuYWJsZTogYm9vbGVhbjtcblxuICAgIHByaXZhdGUgc2Nyb2xsVGltZXIhOiBudW1iZXI7XG5cbiAgICBwcml2YXRlIHpvb21UaW1lciE6IG51bWJlcjtcbiAgICBwcml2YXRlIHNjYWxlVGltZXIhOiBudW1iZXI7XG5cbiAgICBwcml2YXRlIHByZURhdGV3aW5kb3chOiBBcnJheTxhbnk+O1xuXG4gICAgcHJpdmF0ZSBuZWVkUmVmcmVzaCE6IGJvb2xlYW47XG5cbiAgICBwcml2YXRlIHlBeGlzUmFuZ2VDaGFuZ2VkITogYm9vbGVhbjtcblxuXG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgY2FsbGJhY2s6IGFueSwgcHVibGljIGRhdGVSYW5nZT86IEFycmF5PG51bWJlcj4pIHtcbiAgICAgICAgdGhpcy5wYW5FbmFibGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zY3JvbGxFbmFibGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIExPR19TQ0FMRSA9IDEwO1xuICAgIHByaXZhdGUgTE5fVEVOID0gTWF0aC5sb2codGhpcy5MT0dfU0NBTEUpO1xuXG5cbiAgICBwcml2YXRlIGxvZzEwID0gKHg6IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4gTWF0aC5sb2coeCkgLyB0aGlzLkxOX1RFTjtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBwYWdlWCA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgIHJldHVybiAhZS5wYWdlWCB8fCBlLnBhZ2VYIDwgMCA/IDAgOiBlLnBhZ2VYO1xuICAgIH07XG5cbiAgICBwcml2YXRlIHBhZ2VZID0gKGU6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgcmV0dXJuICFlLnBhZ2VZIHx8IGUucGFnZVkgPCAwID8gMCA6IGUucGFnZVk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgZHJhZ0dldFhfID0gKGU6IE1vdXNlRXZlbnQsIGNvbnRleHQ6IGFueSkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wYWdlWChlKSAtIGNvbnRleHQucHg7XG4gICAgfTtcblxuICAgIHByaXZhdGUgZHJhZ0dldFlfID0gKGU6IE1vdXNlRXZlbnQsIGNvbnRleHQ6IGFueSkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wYWdlWShlKSAtIGNvbnRleHQucHk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgZW5kUGFuID0gKGV2ZW50OiBNb3VzZUV2ZW50LCBnOiBhbnksIGNvbnRleHQ6IGFueSkgPT4ge1xuICAgICAgICBjb250ZXh0LmRyYWdFbmRYID0gdGhpcy5kcmFnR2V0WF8oZXZlbnQsIGNvbnRleHQpO1xuICAgICAgICBjb250ZXh0LmRyYWdFbmRZID0gdGhpcy5kcmFnR2V0WV8oZXZlbnQsIGNvbnRleHQpO1xuICAgICAgICBsZXQgcmVnaW9uV2lkdGggPSBNYXRoLmFicyhjb250ZXh0LmRyYWdFbmRYIC0gY29udGV4dC5kcmFnU3RhcnRYKTtcbiAgICAgICAgbGV0IHJlZ2lvbkhlaWdodCA9IE1hdGguYWJzKGNvbnRleHQuZHJhZ0VuZFkgLSBjb250ZXh0LmRyYWdTdGFydFkpO1xuXG4gICAgICAgIGlmIChyZWdpb25XaWR0aCA8IDIgJiYgcmVnaW9uSGVpZ2h0IDwgMiAmJlxuICAgICAgICAgICAgZy5sYXN0eF8gIT09IHVuZGVmaW5lZCAmJiBnLmxhc3R4XyAhPSAtMSkge1xuICAgICAgICAgICAgdGhpcy50cmVhdE1vdXNlT3BBc0NsaWNrKGcsIGV2ZW50LCBjb250ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQucmVnaW9uV2lkdGggPSByZWdpb25XaWR0aDtcbiAgICAgICAgY29udGV4dC5yZWdpb25IZWlnaHQgPSByZWdpb25IZWlnaHQ7XG4gICAgfTtcblxuICAgIHByaXZhdGUgc3RhcnRQYW4gPSAoZXZlbnQ6IE1vdXNlRXZlbnQsIGc6IGFueSwgY29udGV4dDogYW55KSA9PiB7XG4gICAgICAgIGxldCBpLCBheGlzO1xuICAgICAgICBjb250ZXh0LmlzUGFubmluZyA9IHRydWU7XG4gICAgICAgIGxldCB4UmFuZ2UgPSBnLnhBeGlzUmFuZ2UoKTtcblxuICAgICAgICBpZiAoZy5nZXRPcHRpb25Gb3JBeGlzKFwibG9nc2NhbGVcIiwgXCJ4XCIpKSB7XG4gICAgICAgICAgICBjb250ZXh0LmluaXRpYWxMZWZ0bW9zdERhdGUgPSB0aGlzLmxvZzEwKHhSYW5nZVswXSk7XG4gICAgICAgICAgICBjb250ZXh0LmRhdGVSYW5nZSA9IHRoaXMubG9nMTAoeFJhbmdlWzFdKSAtIHRoaXMubG9nMTAoeFJhbmdlWzBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRleHQuaW5pdGlhbExlZnRtb3N0RGF0ZSA9IHhSYW5nZVswXTtcbiAgICAgICAgICAgIGNvbnRleHQuZGF0ZVJhbmdlID0geFJhbmdlWzFdIC0geFJhbmdlWzBdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQueFVuaXRzUGVyUGl4ZWwgPSBjb250ZXh0LmRhdGVSYW5nZSAvIChnLnBsb3R0ZXJfLmFyZWEudyAtIDEpO1xuXG4gICAgICAgIGlmIChnLmdldE51bWVyaWNPcHRpb24oXCJwYW5FZGdlRnJhY3Rpb25cIikpIHtcbiAgICAgICAgICAgIGxldCBtYXhYUGl4ZWxzVG9EcmF3ID0gZy53aWR0aF8gKiBnLmdldE51bWVyaWNPcHRpb24oXCJwYW5FZGdlRnJhY3Rpb25cIik7XG4gICAgICAgICAgICBsZXQgeEV4dHJlbWVzID0gZy54QXhpc0V4dHJlbWVzKCk7IC8vIEkgUkVBTExZIFdBTlQgVE8gQ0FMTCBUSElTIHhUcmVtZXMhXG5cbiAgICAgICAgICAgIGxldCBib3VuZGVkTGVmdFggPSBnLnRvRG9tWENvb3JkKHhFeHRyZW1lc1swXSkgLSBtYXhYUGl4ZWxzVG9EcmF3O1xuICAgICAgICAgICAgbGV0IGJvdW5kZWRSaWdodFggPSBnLnRvRG9tWENvb3JkKHhFeHRyZW1lc1sxXSkgKyBtYXhYUGl4ZWxzVG9EcmF3O1xuXG4gICAgICAgICAgICBsZXQgYm91bm