UNPKG

dygraphs

Version:

dygraphs is a fast, flexible open source JavaScript charting library.

284 lines (271 loc) 40.1 kB
'use strict'; /** * @license * Copyright 2012 Dan Vanderkam (danvdk@gmail.com) * MIT-licenced: https://opensource.org/license/MIT */ /*global Dygraph:false */ /* Bits of jankiness: - Direct layout access - Direct area access - Should include calculation of ticks, not just the drawing. Options left to make axis-friendly. ('drawAxesAtZero') ('xAxisHeight') */ Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var utils = _interopRequireWildcard(require("../dygraph-utils")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } /** * Draws the axes. This includes the labels on the x- and y-axes, as well * as the tick marks on the axes. * It does _not_ draw the grid lines which span the entire chart. */ var axes = function axes() { this.xlabels_ = []; this.ylabels_ = []; }; axes.prototype.toString = function () { return 'Axes Plugin'; }; axes.prototype.activate = function (g) { return { layout: this.layout, clearChart: this.clearChart, willDrawChart: this.willDrawChart }; }; axes.prototype.layout = function (e) { var g = e.dygraph; if (g.getOptionForAxis('drawAxis', 'y')) { var w = g.getOptionForAxis('axisLabelWidth', 'y') + 2 * g.getOptionForAxis('axisTickSize', 'y'); e.reserveSpaceLeft(w); } if (g.getOptionForAxis('drawAxis', 'x')) { var h; // NOTE: I think this is probably broken now, since g.getOption() now // hits the dictionary. (That is, g.getOption('xAxisHeight') now always // has a value.) if (g.getOption('xAxisHeight')) { h = g.getOption('xAxisHeight'); } else { h = g.getOptionForAxis('axisLabelFontSize', 'x') + 2 * g.getOptionForAxis('axisTickSize', 'x'); } e.reserveSpaceBottom(h); } if (g.numAxes() == 2) { if (g.getOptionForAxis('drawAxis', 'y2')) { var w = g.getOptionForAxis('axisLabelWidth', 'y2') + 2 * g.getOptionForAxis('axisTickSize', 'y2'); e.reserveSpaceRight(w); } } else if (g.numAxes() > 2) { g.error('Only two y-axes are supported at this time. (Trying ' + 'to use ' + g.numAxes() + ')'); } }; axes.prototype.detachLabels = function () { function removeArray(ary) { for (var i = 0; i < ary.length; i++) { var el = ary[i]; if (el.parentNode) el.parentNode.removeChild(el); } } removeArray(this.xlabels_); removeArray(this.ylabels_); this.xlabels_ = []; this.ylabels_ = []; }; axes.prototype.clearChart = function (e) { this.detachLabels(); }; axes.prototype.willDrawChart = function (e) { var g = e.dygraph; if (!g.getOptionForAxis('drawAxis', 'x') && !g.getOptionForAxis('drawAxis', 'y') && !g.getOptionForAxis('drawAxis', 'y2')) { return; } // Round pixels to half-integer boundaries for crisper drawing. function halfUp(x) { return Math.round(x) + 0.5; } function halfDown(y) { return Math.round(y) - 0.5; } var context = e.drawingContext; var containerDiv = e.canvas.parentNode; var canvasWidth = g.width_; // e.canvas.width is affected by pixel ratio. var canvasHeight = g.height_; var label, x, y, tick, i; var makeLabelStyle = function makeLabelStyle(axis) { return { position: 'absolute', fontSize: g.getOptionForAxis('axisLabelFontSize', axis) + 'px', width: g.getOptionForAxis('axisLabelWidth', axis) + 'px' }; }; var labelStyles = { x: makeLabelStyle('x'), y: makeLabelStyle('y'), y2: makeLabelStyle('y2') }; var makeDiv = function makeDiv(txt, axis, prec_axis) { /* * This seems to be called with the following three sets of axis/prec_axis: * x: undefined * y: y1 * y: y2 */ var div = document.createElement('div'); var labelStyle = labelStyles[prec_axis == 'y2' ? 'y2' : axis]; utils.update(div.style, labelStyle); // TODO: combine outer & inner divs var inner_div = document.createElement('div'); inner_div.className = 'dygraph-axis-label' + ' dygraph-axis-label-' + axis + (prec_axis ? ' dygraph-axis-label-' + prec_axis : ''); inner_div.innerHTML = txt; div.appendChild(inner_div); return div; }; // axis lines context.save(); var layout = g.layout_; var area = e.dygraph.plotter_.area; // Helper for repeated axis-option accesses. var makeOptionGetter = function makeOptionGetter(axis) { return function (option) { return g.getOptionForAxis(option, axis); }; }; var that = this; if (g.getOptionForAxis('drawAxis', 'y') || g.numAxes() == 2 && g.getOptionForAxis('drawAxis', 'y2')) { if (layout.yticks && layout.yticks.length > 0) { var num_axes = g.numAxes(); var getOptions = [makeOptionGetter('y'), makeOptionGetter('y2')]; layout.yticks.forEach(function (tick) { if (tick.label === undefined) return; // this tick only has a grid line. x = area.x; var sgn = 1; var prec_axis = 'y1'; var getAxisOption = getOptions[0]; if (tick.axis == 1) { // right-side y-axis x = area.x + area.w; sgn = -1; prec_axis = 'y2'; getAxisOption = getOptions[1]; } if (!getAxisOption('drawAxis')) return; var fontSize = getAxisOption('axisLabelFontSize'); y = area.y + tick.pos * area.h; /* Tick marks are currently clipped, so don't bother drawing them. context.beginPath(); context.moveTo(halfUp(x), halfDown(y)); context.lineTo(halfUp(x - sgn * that.attr_('axisTickSize')), halfDown(y)); context.closePath(); context.stroke(); */ label = makeDiv(tick.label, 'y', num_axes == 2 ? prec_axis : null); var top = y - fontSize / 2; if (top < 0) top = 0; if (top + fontSize + 3 > canvasHeight) { label.style.bottom = '0'; } else { // The lowest tick on the y-axis often overlaps with the leftmost // tick on the x-axis. Shift the bottom tick up a little bit to // compensate if necessary. label.style.top = Math.min(top, canvasHeight - 2 * fontSize) + 'px'; } // TODO: replace these with css classes? if (tick.axis === 0) { label.style.left = area.x - getAxisOption('axisLabelWidth') - getAxisOption('axisTickSize') + 'px'; label.style.textAlign = 'right'; } else if (tick.axis == 1) { label.style.left = area.x + area.w + getAxisOption('axisTickSize') + 'px'; label.style.textAlign = 'left'; } label.style.width = getAxisOption('axisLabelWidth') + 'px'; containerDiv.appendChild(label); that.ylabels_.push(label); }); } // draw a vertical line on the left to separate the chart from the labels. var axisX; if (g.getOption('drawAxesAtZero')) { var r = g.toPercentXCoord(0); if (r > 1 || r < 0 || isNaN(r)) r = 0; axisX = halfUp(area.x + r * area.w); } else { axisX = halfUp(area.x); } context.strokeStyle = g.getOptionForAxis('axisLineColor', 'y'); context.lineWidth = g.getOptionForAxis('axisLineWidth', 'y'); context.beginPath(); context.moveTo(axisX, halfDown(area.y)); context.lineTo(axisX, halfDown(area.y + area.h)); context.closePath(); context.stroke(); // if there's a secondary y-axis, draw a vertical line for that, too. if (g.numAxes() == 2 && g.getOptionForAxis('drawAxis', 'y2')) { context.strokeStyle = g.getOptionForAxis('axisLineColor', 'y2'); context.lineWidth = g.getOptionForAxis('axisLineWidth', 'y2'); context.beginPath(); context.moveTo(halfDown(area.x + area.w), halfDown(area.y)); context.lineTo(halfDown(area.x + area.w), halfDown(area.y + area.h)); context.closePath(); context.stroke(); } } if (g.getOptionForAxis('drawAxis', 'x')) { if (layout.xticks) { var getAxisOption = makeOptionGetter('x'); layout.xticks.forEach(function (tick) { if (tick.label === undefined) return; // this tick only has a grid line. x = area.x + tick.pos * area.w; y = area.y + area.h; /* Tick marks are currently clipped, so don't bother drawing them. context.beginPath(); context.moveTo(halfUp(x), halfDown(y)); context.lineTo(halfUp(x), halfDown(y + that.attr_('axisTickSize'))); context.closePath(); context.stroke(); */ label = makeDiv(tick.label, 'x'); label.style.textAlign = 'center'; label.style.top = y + getAxisOption('axisTickSize') + 'px'; var left = x - getAxisOption('axisLabelWidth') / 2; if (left + getAxisOption('axisLabelWidth') > canvasWidth) { left = canvasWidth - getAxisOption('axisLabelWidth'); label.style.textAlign = 'right'; } if (left < 0) { left = 0; label.style.textAlign = 'left'; } label.style.left = left + 'px'; label.style.width = getAxisOption('axisLabelWidth') + 'px'; containerDiv.appendChild(label); that.xlabels_.push(label); }); } context.strokeStyle = g.getOptionForAxis('axisLineColor', 'x'); context.lineWidth = g.getOptionForAxis('axisLineWidth', 'x'); context.beginPath(); var axisY; if (g.getOption('drawAxesAtZero')) { var r = g.toPercentYCoord(0, 0); if (r > 1 || r < 0) r = 1; axisY = halfDown(area.y + r * area.h); } else { axisY = halfDown(area.y + area.h); } context.moveTo(halfUp(area.x), axisY); context.lineTo(halfUp(area.x + area.w), axisY); context.closePath(); context.stroke(); } context.restore(); }; var _default = exports["default"] = axes; module.exports = exports.default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImV4cG9ydHMiLCJ2YWx1ZSIsInV0aWxzIiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJyZXF1aXJlIiwiZSIsInQiLCJXZWFrTWFwIiwiciIsIm4iLCJfX2VzTW9kdWxlIiwibyIsImkiLCJmIiwiX19wcm90b19fIiwiaGFzIiwiZ2V0Iiwic2V0IiwiX3QiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJheGVzIiwieGxhYmVsc18iLCJ5bGFiZWxzXyIsInByb3RvdHlwZSIsInRvU3RyaW5nIiwiYWN0aXZhdGUiLCJnIiwibGF5b3V0IiwiY2xlYXJDaGFydCIsIndpbGxEcmF3Q2hhcnQiLCJkeWdyYXBoIiwiZ2V0T3B0aW9uRm9yQXhpcyIsInciLCJyZXNlcnZlU3BhY2VMZWZ0IiwiaCIsImdldE9wdGlvbiIsInJlc2VydmVTcGFjZUJvdHRvbSIsIm51bUF4ZXMiLCJyZXNlcnZlU3BhY2VSaWdodCIsImVycm9yIiwiZGV0YWNoTGFiZWxzIiwicmVtb3ZlQXJyYXkiLCJhcnkiLCJsZW5ndGgiLCJlbCIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsImhhbGZVcCIsIngiLCJNYXRoIiwicm91bmQiLCJoYWxmRG93biIsInkiLCJjb250ZXh0IiwiZHJhd2luZ0NvbnRleHQiLCJjb250YWluZXJEaXYiLCJjYW52YXMiLCJjYW52YXNXaWR0aCIsIndpZHRoXyIsImNhbnZhc0hlaWdodCIsImhlaWdodF8iLCJsYWJlbCIsInRpY2siLCJtYWtlTGFiZWxTdHlsZSIsImF4aXMiLCJwb3NpdGlvbiIsImZvbnRTaXplIiwid2lkdGgiLCJsYWJlbFN0eWxlcyIsInkyIiwibWFrZURpdiIsInR4dCIsInByZWNfYXhpcyIsImRpdiIsImRvY3VtZW50IiwiY3JlYXRlRWxlbWVudCIsImxhYmVsU3R5bGUiLCJ1cGRhdGUiLCJzdHlsZSIsImlubmVyX2RpdiIsImNsYXNzTmFtZSIsImlubmVySFRNTCIsImFwcGVuZENoaWxkIiwic2F2ZSIsImxheW91dF8iLCJhcmVhIiwicGxvdHRlcl8iLCJtYWtlT3B0aW9uR2V0dGVyIiwib3B0aW9uIiwidGhhdCIsInl0aWNrcyIsIm51bV9heGVzIiwiZ2V0T3B0aW9ucyIsImZvckVhY2giLCJ1bmRlZmluZWQiLCJzZ24iLCJnZXRBeGlzT3B0aW9uIiwicG9zIiwidG9wIiwiYm90dG9tIiwibWluIiwibGVmdCIsInRleHRBbGlnbiIsInB1c2giLCJheGlzWCIsInRvUGVyY2VudFhDb29yZCIsImlzTmFOIiwic3Ryb2tlU3R5bGUiLCJsaW5lV2lkdGgiLCJiZWdpblBhdGgiLCJtb3ZlVG8iLCJsaW5lVG8iLCJjbG9zZVBhdGgiLCJzdHJva2UiLCJ4dGlja3MiLCJheGlzWSIsInRvUGVyY2VudFlDb29yZCIsInJlc3RvcmUiLCJfZGVmYXVsdCIsIm1vZHVsZSIsImRlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcGx1Z2lucy9heGVzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTIgRGFuIFZhbmRlcmthbSAoZGFudmRrQGdtYWlsLmNvbSlcbiAqIE1JVC1saWNlbmNlZDogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlL01JVFxuICovXG5cbi8qZ2xvYmFsIER5Z3JhcGg6ZmFsc2UgKi9cblxuLypcbkJpdHMgb2YgamFua2luZXNzOlxuLSBEaXJlY3QgbGF5b3V0IGFjY2Vzc1xuLSBEaXJlY3QgYXJlYSBhY2Nlc3Ncbi0gU2hvdWxkIGluY2x1ZGUgY2FsY3VsYXRpb24gb2YgdGlja3MsIG5vdCBqdXN0IHRoZSBkcmF3aW5nLlxuXG5PcHRpb25zIGxlZnQgdG8gbWFrZSBheGlzLWZyaWVuZGx5LlxuICAoJ2RyYXdBeGVzQXRaZXJvJylcbiAgKCd4QXhpc0hlaWdodCcpXG4qL1xuXG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuLi9keWdyYXBoLXV0aWxzJztcblxuLyoqXG4gKiBEcmF3cyB0aGUgYXhlcy4gVGhpcyBpbmNsdWRlcyB0aGUgbGFiZWxzIG9uIHRoZSB4LSBhbmQgeS1heGVzLCBhcyB3ZWxsXG4gKiBhcyB0aGUgdGljayBtYXJrcyBvbiB0aGUgYXhlcy5cbiAqIEl0IGRvZXMgX25vdF8gZHJhdyB0aGUgZ3JpZCBsaW5lcyB3aGljaCBzcGFuIHRoZSBlbnRpcmUgY2hhcnQuXG4gKi9cbnZhciBheGVzID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMueGxhYmVsc18gPSBbXTtcbiAgdGhpcy55bGFiZWxzXyA9IFtdO1xufTtcblxuYXhlcy5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuICdBeGVzIFBsdWdpbic7XG59O1xuXG5heGVzLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uKGcpIHtcbiAgcmV0dXJuIHtcbiAgICBsYXlvdXQ6IHRoaXMubGF5b3V0LFxuICAgIGNsZWFyQ2hhcnQ6IHRoaXMuY2xlYXJDaGFydCxcbiAgICB3aWxsRHJhd0NoYXJ0OiB0aGlzLndpbGxEcmF3Q2hhcnRcbiAgfTtcbn07XG5cbmF4ZXMucHJvdG90eXBlLmxheW91dCA9IGZ1bmN0aW9uKGUpIHtcbiAgdmFyIGcgPSBlLmR5Z3JhcGg7XG5cbiAgaWYgKGcuZ2V0T3B0aW9uRm9yQXhpcygnZHJhd0F4aXMnLCAneScpKSB7XG4gICAgdmFyIHcgPSBnLmdldE9wdGlvbkZvckF4aXMoJ2F4aXNMYWJlbFdpZHRoJywgJ3knKSArIDIgKiBnLmdldE9wdGlvbkZvckF4aXMoJ2F4aXNUaWNrU2l6ZScsICd5Jyk7XG4gICAgZS5yZXNlcnZlU3BhY2VMZWZ0KHcpO1xuICB9XG5cbiAgaWYgKGcuZ2V0T3B0aW9uRm9yQXhpcygnZHJhd0F4aXMnLCAneCcpKSB7XG4gICAgdmFyIGg7XG4gICAgLy8gTk9URTogSSB0aGluayB0aGlzIGlzIHByb2JhYmx5IGJyb2tlbiBub3csIHNpbmNlIGcuZ2V0T3B0aW9uKCkgbm93XG4gICAgLy8gaGl0cyB0aGUgZGljdGlvbmFyeS4gKFRoYXQgaXMsIGcuZ2V0T3B0aW9uKCd4QXhpc0hlaWdodCcpIG5vdyBhbHdheXNcbiAgICAvLyBoYXMgYSB2YWx1ZS4pXG4gICAgaWYgKGcuZ2V0T3B0aW9uKCd4QXhpc0hlaWdodCcpKSB7XG4gICAgICBoID0gZy5nZXRPcHRpb24oJ3hBeGlzSGVpZ2h0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGggPSBnLmdldE9wdGlvbkZvckF4aXMoJ2F4aXNMYWJlbEZvbnRTaXplJywgJ3gnKSArIDIgKiBnLmdldE9wdGlvbkZvckF4aXMoJ2F4aXNUaWNrU2l6ZScsICd4Jyk7XG4gICAgfVxuICAgIGUucmVzZXJ2ZVNwYWNlQm90dG9tKGgpO1xuICB9XG5cbiAgaWYgKGcubnVtQXhlcygpID09IDIpIHtcbiAgICBpZiAoZy5nZXRPcHRpb25Gb3JBeGlzKCdkcmF3QXhpcycsICd5MicpKSB7XG4gICAgICB2YXIgdyA9IGcuZ2V0T3B0aW9uRm9yQXhpcygnYXhpc0xhYmVsV2lkdGgnLCAneTInKSArIDIgKiBnLmdldE9wdGlvbkZvckF4aXMoJ2F4aXNUaWNrU2l6ZScsICd5MicpO1xuICAgICAgZS5yZXNlcnZlU3BhY2VSaWdodCh3KTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoZy5udW1BeGVzKCkgPiAyKSB7XG4gICAgZy5lcnJvcignT25seSB0d28geS1heGVzIGFyZSBzdXBwb3J0ZWQgYXQgdGhpcyB0aW1lLiAoVHJ5aW5nICcgK1xuICAgICAgICAgICAgJ3RvIHVzZSAnICsgZy5udW1BeGVzKCkgKyAnKScpO1xuICB9XG59O1xuXG5heGVzLnByb3RvdHlwZS5kZXRhY2hMYWJlbHMgPSBmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gcmVtb3ZlQXJyYXkoYXJ5KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBlbCA9IGFyeVtpXTtcbiAgICAgIGlmIChlbC5wYXJlbnROb2RlKSBlbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsKTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVBcnJheSh0aGlzLnhsYWJlbHNfKTtcbiAgcmVtb3ZlQXJyYXkodGhpcy55bGFiZWxzXyk7XG4gIHRoaXMueGxhYmVsc18gPSBbXTtcbiAgdGhpcy55bGFiZWxzXyA9IFtdO1xufTtcblxuYXhlcy5wcm90b3R5cGUuY2xlYXJDaGFydCA9IGZ1bmN0aW9uKGUpIHtcbiAgdGhpcy5kZXRhY2hMYWJlbHMoKTtcbn07XG5cbmF4ZXMucHJvdG90eXBlLndpbGxEcmF3Q2hhcnQgPSBmdW5jdGlvbihlKSB7XG4gIHZhciBnID0gZS5keWdyYXBoO1xuXG4gIGlmICghZy5nZXRPcHRpb25Gb3JBeGlzKCdkcmF3QXhpcycsICd4JykgJiZcbiAgICAgICFnLmdldE9wdGlvbkZvckF4aXMoJ2RyYXdBeGlzJywgJ3knKSAmJlxuICAgICAgIWcuZ2V0T3B0aW9uRm9yQXhpcygnZHJhd0F4aXMnLCAneTInKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFJvdW5kIHBpeGVscyB0byBoYWxmLWludGVnZXIgYm91bmRhcmllcyBmb3IgY3Jpc3BlciBkcmF3aW5nLlxuICBmdW5jdGlvbiBoYWxmVXAoeCkgIHsgcmV0dXJuIE1hdGgucm91bmQoeCkgKyAwLjU7IH1cbiAgZnVuY3Rpb24gaGFsZkRvd24oeSl7IHJldHVybiBNYXRoLnJvdW5kKHkpIC0gMC41OyB9XG5cbiAgdmFyIGNvbnRleHQgPSBlLmRyYXdpbmdDb250ZXh0O1xuICB2YXIgY29udGFpbmVyRGl2ID0gZS5jYW52YXMucGFyZW50Tm9kZTtcbiAgdmFyIGNhbnZhc1dpZHRoID0gZy53aWR0aF87ICAvLyBlLmNhbnZhcy53aWR0aCBpcyBhZmZlY3RlZCBieSBwaXhlbCByYXRpby5cbiAgdmFyIGNhbnZhc0hlaWdodCA9IGcuaGVpZ2h0XztcblxuICB2YXIgbGFiZWwsIHgsIHksIHRpY2ssIGk7XG5cbiAgdmFyIG1ha2VMYWJlbFN0eWxlID0gZnVuY3Rpb24oYXhpcykge1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIGZvbnRTaXplOiBnLmdldE9wdGlvbkZvckF4aXMoJ2F4aXNMYWJlbEZvbnRTaXplJywgYXhpcykgKyAncHgnLFxuICAgICAgd2lkdGg6IGcuZ2V0T3B0aW9uRm9yQXhpcygnYXhpc0xhYmVsV2lkdGgnLCBheGlzKSArICdweCcsXG4gICAgfTtcbiAgfTtcblxuICB2YXIgbGFiZWxTdHlsZXMgPSB7XG4gICAgeDogbWFrZUxhYmVsU3R5bGUoJ3gnKSxcbiAgICB5OiBtYWtlTGFiZWxTdHlsZSgneScpLFxuICAgIHkyOiBtYWtlTGFiZWxTdHlsZSgneTInKVxuICB9O1xuXG4gIHZhciBtYWtlRGl2ID0gZnVuY3Rpb24odHh0LCBheGlzLCBwcmVjX2F4aXMpIHtcbiAgICAvKlxuICAgICAqIFRoaXMgc2VlbXMgdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZvbGxvd2luZyB0aHJlZSBzZXRzIG9mIGF4aXMvcHJlY19heGlzOlxuICAgICAqIHg6IHVuZGVmaW5lZFxuICAgICAqIHk6IHkxXG4gICAgICogeTogeTJcbiAgICAgKi9cbiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdmFyIGxhYmVsU3R5bGUgPSBsYWJlbFN0eWxlc1twcmVjX2F4aXMgPT0gJ3kyJyA/ICd5MicgOiBheGlzXTtcbiAgICB1dGlscy51cGRhdGUoZGl2LnN0eWxlLCBsYWJlbFN0eWxlKTtcbiAgICAvLyBUT0RPOiBjb21iaW5lIG91dGVyICYgaW5uZXIgZGl2c1xuICAgIHZhciBpbm5lcl9kaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBpbm5lcl9kaXYuY2xhc3NOYW1lID0gJ2R5Z3JhcGgtYXhpcy1sYWJlbCcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnIGR5Z3JhcGgtYXhpcy1sYWJlbC0nICsgYXhpcyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChwcmVjX2F4aXMgPyAnIGR5Z3JhcGgtYXhpcy1sYWJlbC0nICsgcHJlY19heGlzIDogJycpO1xuICAgIGlubmVyX2Rpdi5pbm5lckhUTUwgPSB0eHQ7XG4gICAgZGl2LmFwcGVuZENoaWxkKGlubmVyX2Rpdik7XG4gICAgcmV0dXJuIGRpdjtcbiAgfTtcblxuICAvLyBheGlzIGxpbmVzXG4gIGNvbnRleHQuc2F2ZSgpO1xuXG4gIHZhciBsYXlvdXQgPSBnLmxheW91dF87XG4gIHZhciBhcmVhID0gZS5keWdyYXBoLnBsb3R0ZXJfLmFyZWE7XG5cbiAgLy8gSGVscGVyIGZvciByZXBlYXRlZCBheGlzLW9wdGlvbiBhY2Nlc3Nlcy5cbiAgdmFyIG1ha2VPcHRpb25HZXR0ZXIgPSBmdW5jdGlvbihheGlzKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKG9wdGlvbikge1xuICAgICAgcmV0dXJuIGcuZ2V0T3B0aW9uRm9yQXhpcyhvcHRpb24sIGF4aXMpO1xuICAgIH07XG4gIH07XG5cbiAgY29uc3QgdGhhdCA9IHRoaXM7XG5cbiAgaWYgKGcuZ2V0T3B0aW9uRm9yQXhpcygnZHJhd0F4aXMnLCAneScpIHx8XG4gICAgICAoZy5udW1BeGVzKCkgPT0gMiAmJiBnLmdldE9wdGlvbkZvckF4aXMoJ2RyYXdBeGlzJywgJ3kyJykpKSB7XG4gICAgaWYgKGxheW91dC55dGlja3MgJiYgbGF5b3V0Lnl0aWNrcy5sZW5ndGggPiAwKSB7XG4gICAgICB2YXIgbnVtX2F4ZXMgPSBnLm51bUF4ZXMoKTtcbiAgICAgIHZhciBnZXRPcHRpb25zID0gW21ha2VPcHRpb25HZXR0ZXIoJ3knKSwgbWFrZU9wdGlvbkdldHRlcigneTInKV07XG4gICAgICBsYXlvdXQueXRpY2tzLmZvckVhY2goZnVuY3Rpb24gKHRpY2spIHtcbiAgICAgICAgaWYgKHRpY2subGFiZWwgPT09IHVuZGVmaW5lZCkgcmV0dXJuOyAgLy8gdGhpcyB0aWNrIG9ubHkgaGFzIGEgZ3JpZCBsaW5lLlxuICAgICAgICB4ID0gYXJlYS54O1xuICAgICAgICB2YXIgc2duID0gMTtcbiAgICAgICAgdmFyIHByZWNfYXhpcyA9ICd5MSc7XG4gICAgICAgIHZhciBnZXRBeGlzT3B0aW9uID0gZ2V0T3B0aW9uc1swXTtcbiAgICAgICAgaWYgKHRpY2suYXhpcyA9PSAxKSB7ICAvLyByaWdodC1zaWRlIHktYXhpc1xuICAgICAgICAgIHggPSBhcmVhLnggKyBhcmVhLnc7XG4gICAgICAgICAgc2duID0gLTE7XG4gICAgICAgICAgcHJlY19heGlzID0gJ3kyJztcbiAgICAgICAgICBnZXRBeGlzT3B0aW9uID0gZ2V0T3B0aW9uc1sxXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWdldEF4aXNPcHRpb24oJ2RyYXdBeGlzJykpIHJldHVybjtcbiAgICAgICAgdmFyIGZvbnRTaXplID0gZ2V0QXhpc09wdGlvbignYXhpc0xhYmVsRm9udFNpemUnKTtcbiAgICAgICAgeSA9IGFyZWEueSArIHRpY2sucG9zICogYXJlYS5oO1xuXG4gICAgICAgIC8qIFRpY2sgbWFya3MgYXJlIGN1cnJlbnRseSBjbGlwcGVkLCBzbyBkb24ndCBib3RoZXIgZHJhd2luZyB0aGVtLlxuICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgICAgICBjb250ZXh0Lm1vdmVUbyhoYWxmVXAoeCksIGhhbGZEb3duKHkpKTtcbiAgICAgICAgY29udGV4dC5saW5lVG8oaGFsZlVwKHggLSBzZ24gKiB0aGF0LmF0dHJfKCdheGlzVGlja1NpemUnKSksIGhhbGZEb3duKHkpKTtcbiAgICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICAgICAgKi9cblxuICAgICAgICBsYWJlbCA9IG1ha2VEaXYodGljay5sYWJlbCwgJ3knLCBudW1fYXhlcyA9PSAyID8gcHJlY19heGlzIDogbnVsbCk7XG4gICAgICAgIHZhciB0b3AgPSAoeSAtIGZvbnRTaXplIC8gMik7XG4gICAgICAgIGlmICh0b3AgPCAwKSB0b3AgPSAwO1xuXG4gICAgICAgIGlmICh0b3AgKyBmb250U2l6ZSArIDMgPiBjYW52YXNIZWlnaHQpIHtcbiAgICAgICAgICBsYWJlbC5zdHlsZS5ib3R0b20gPSAnMCc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGhlIGxvd2VzdCB0aWNrIG9uIHRoZSB5LWF4aXMgb2Z0ZW4gb3ZlcmxhcHMgd2l0aCB0aGUgbGVmdG1vc3RcbiAgICAgICAgICAvLyB0aWNrIG9uIHRoZSB4LWF4aXMuIFNoaWZ0IHRoZSBib3R0b20gdGljayB1cCBhIGxpdHRsZSBiaXQgdG9cbiAgICAgICAgICAvLyBjb21wZW5zYXRlIGlmIG5lY2Vzc2FyeS5cbiAgICAgICAgICBsYWJlbC5zdHlsZS50b3AgPSBNYXRoLm1pbih0b3AsIGNhbnZhc0hlaWdodCAtICgyICogZm9udFNpemUpKSArICdweCc7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVE9ETzogcmVwbGFjZSB0aGVzZSB3aXRoIGNzcyBjbGFzc2VzP1xuICAgICAgICBpZiAodGljay5heGlzID09PSAwKSB7XG4gICAgICAgICAgbGFiZWwuc3R5bGUubGVmdCA9IChhcmVhLnggLSBnZXRBeGlzT3B0aW9uKCdheGlzTGFiZWxXaWR0aCcpIC0gZ2V0QXhpc09wdGlvbignYXhpc1RpY2tTaXplJykpICsgJ3B4JztcbiAgICAgICAgICBsYWJlbC5zdHlsZS50ZXh0QWxpZ24gPSAncmlnaHQnO1xuICAgICAgICB9IGVsc2UgaWYgKHRpY2suYXhpcyA9PSAxKSB7XG4gICAgICAgICAgbGFiZWwuc3R5bGUubGVmdCA9IChhcmVhLnggKyBhcmVhLncgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0QXhpc09wdGlvbignYXhpc1RpY2tTaXplJykpICsgJ3B4JztcbiAgICAgICAgICBsYWJlbC5zdHlsZS50ZXh0QWxpZ24gPSAnbGVmdCc7XG4gICAgICAgIH1cbiAgICAgICAgbGFiZWwuc3R5bGUud2lkdGggPSBnZXRBeGlzT3B0aW9uKCdheGlzTGFiZWxXaWR0aCcpICsgJ3B4JztcbiAgICAgICAgY29udGFpbmVyRGl2LmFwcGVuZENoaWxkKGxhYmVsKTtcbiAgICAgICAgdGhhdC55bGFiZWxzXy5wdXNoKGxhYmVsKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGRyYXcgYSB2ZXJ0aWNhbCBsaW5lIG9uIHRoZSBsZWZ0IHRvIHNlcGFyYXRlIHRoZSBjaGFydCBmcm9tIHRoZSBsYWJlbHMuXG4gICAgdmFyIGF4aXNYO1xuICAgIGlmIChnLmdldE9wdGlvbignZHJhd0F4ZXNBdFplcm8nKSkge1xuICAgICAgdmFyIHIgPSBnLnRvUGVyY2VudFhDb29yZCgwKTtcbiAgICAgIGlmIChyID4gMSB8fCByIDwgMCB8fCBpc05hTihyKSkgciA9IDA7XG4gICAgICBheGlzWCA9IGhhbGZVcChhcmVhLnggKyByICogYXJlYS53KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXhpc1ggPSBoYWxmVXAoYXJlYS54KTtcbiAgICB9XG5cbiAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gZy5nZXRPcHRpb25Gb3JBeGlzKCdheGlzTGluZUNvbG9yJywgJ3knKTtcbiAgICBjb250ZXh0LmxpbmVXaWR0aCA9IGcuZ2V0T3B0aW9uRm9yQXhpcygnYXhpc0xpbmVXaWR0aCcsICd5Jyk7XG5cbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIGNvbnRleHQubW92ZVRvKGF4aXNYLCBoYWxmRG93bihhcmVhLnkpKTtcbiAgICBjb250ZXh0LmxpbmVUbyhheGlzWCwgaGFsZkRvd24oYXJlYS55ICsgYXJlYS5oKSk7XG4gICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICBjb250ZXh0LnN0cm9rZSgpO1xuXG4gICAgLy8gaWYgdGhlcmUncyBhIHNlY29uZGFyeSB5LWF4aXMsIGRyYXcgYSB2ZXJ0aWNhbCBsaW5lIGZvciB0aGF0LCB0b28uXG4gICAgaWYgKGcubnVtQXhlcygpID09IDIgJiYgZy5nZXRPcHRpb25Gb3JBeGlzKCdkcmF3QXhpcycsICd5MicpKSB7XG4gICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gZy5nZXRPcHRpb25Gb3JBeGlzKCdheGlzTGluZUNvbG9yJywgJ3kyJyk7XG4gICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IGcuZ2V0T3B0aW9uRm9yQXhpcygnYXhpc0xpbmVXaWR0aCcsICd5MicpO1xuICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICAgIGNvbnRleHQubW92ZVRvKGhhbGZEb3duKGFyZWEueCArIGFyZWEudyksIGhhbGZEb3duKGFyZWEueSkpO1xuICAgICAgY29udGV4dC5saW5lVG8oaGFsZkRvd24oYXJlYS54ICsgYXJlYS53KSwgaGFsZkRvd24oYXJlYS55ICsgYXJlYS5oKSk7XG4gICAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICB9XG4gIH1cblxuICBpZiAoZy5nZXRPcHRpb25Gb3JBeGlzKCdkcmF3QXhpcycsICd4JykpIHtcbiAgICBpZiAobGF5b3V0Lnh0aWNrcykge1xuICAgICAgdmFyIGdldEF4aXNPcHRpb24gPSBtYWtlT3B0aW9uR2V0dGVyKCd4Jyk7XG4gICAgICBsYXlvdXQueHRpY2tzLmZvckVhY2goZnVuY3Rpb24gKHRpY2spIHtcbiAgICAgICAgaWYgKHRpY2subGFiZWwgPT09IHVuZGVmaW5lZCkgcmV0dXJuOyAgLy8gdGhpcyB0aWNrIG9ubHkgaGFzIGEgZ3JpZCBsaW5lLlxuICAgICAgICB4ID0gYXJlYS54ICsgdGljay5wb3MgKiBhcmVhLnc7XG4gICAgICAgIHkgPSBhcmVhLnkgKyBhcmVhLmg7XG5cbiAgICAgICAgLyogVGljayBtYXJrcyBhcmUgY3VycmVudGx5IGNsaXBwZWQsIHNvIGRvbid0IGJvdGhlciBkcmF3aW5nIHRoZW0uXG4gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICAgIGNvbnRleHQubW92ZVRvKGhhbGZVcCh4KSwgaGFsZkRvd24oeSkpO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyhoYWxmVXAoeCksIGhhbGZEb3duKHkgKyB0aGF0LmF0dHJfKCdheGlzVGlja1NpemUnKSkpO1xuICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgICAgICAqL1xuXG4gICAgICAgIGxhYmVsID0gbWFrZURpdih0aWNrLmxhYmVsLCAneCcpO1xuICAgICAgICBsYWJlbC5zdHlsZS50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgbGFiZWwuc3R5bGUudG9wID0gKHkgKyBnZXRBeGlzT3B0aW9uKCdheGlzVGlja1NpemUnKSkgKyAncHgnO1xuXG4gICAgICAgIHZhciBsZWZ0ID0gKHggLSBnZXRBeGlzT3B0aW9uKCdheGlzTGFiZWxXaWR0aCcpLzIpO1xuICAgICAgICBpZiAobGVmdCArIGdldEF4aXNPcHRpb24oJ2F4aXNMYWJlbFdpZHRoJykgPiBjYW52YXNXaWR0aCkge1xuICAgICAgICAgIGxlZnQgPSBjYW52YXNXaWR0aCAtIGdldEF4aXNPcHRpb24oJ2F4aXNMYWJlbFdpZHRoJyk7XG4gICAgICAgICAgbGFiZWwuc3R5bGUudGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgfVxuICAgICAgICBpZiAobGVmdCA8IDApIHtcbiAgICAgICAgICBsZWZ0ID0gMDtcbiAgICAgICAgICBsYWJlbC5zdHlsZS50ZXh0QWxpZ24gPSAnbGVmdCc7XG4gICAgICAgIH1cblxuICAgICAgICBsYWJlbC5zdHlsZS5sZWZ0ID0gbGVmdCArICdweCc7XG4gICAgICAgIGxhYmVsLnN0eWxlLndpZHRoID0gZ2V0QXhpc09wdGlvbignYXhpc0xhYmVsV2lkdGgnKSArICdweCc7XG4gICAgICAgIGNvbnRhaW5lckRpdi5hcHBlbmRDaGlsZChsYWJlbCk7XG4gICAgICAgIHRoYXQueGxhYmVsc18ucHVzaChsYWJlbCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gZy5nZXRPcHRpb25Gb3JBeGlzKCdheGlzTGluZUNvbG9yJywgJ3gnKTtcbiAgICBjb250ZXh0LmxpbmVXaWR0aCA9IGcuZ2V0T3B0aW9uRm9yQXhpcygnYXhpc0xpbmVXaWR0aCcsICd4Jyk7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICB2YXIgYXhpc1k7XG4gICAgaWYgKGcuZ2V0T3B0aW9uKCdkcmF3QXhlc0F0WmVybycpKSB7XG4gICAgICB2YXIgciA9IGcudG9QZXJjZW50WUNvb3JkKDAsIDApO1xuICAgICAgaWYgKHIgPiAxIHx8IHIgPCAwKSByID0gMTtcbiAgICAgIGF4aXNZID0gaGFsZkRvd24oYXJlYS55ICsgciAqIGFyZWEuaCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF4aXNZID0gaGFsZkRvd24oYXJlYS55ICsgYXJlYS5oKTtcbiAgICB9XG4gICAgY29udGV4dC5tb3ZlVG8oaGFsZlVwKGFyZWEueCksIGF4aXNZKTtcbiAgICBjb250ZXh0LmxpbmVUbyhoYWxmVXAoYXJlYS54ICsgYXJlYS53KSwgYXhpc1kpO1xuICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgY29udGV4dC5zdHJva2UoKTtcbiAgfVxuXG4gIGNvbnRleHQucmVzdG9yZSgpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgYXhlcztcbiJdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTs7QUFFWjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBVEFBLE1BQUEsQ0FBQUMsY0FBQSxDQUFBQyxPQUFBO0VBQUFDLEtBQUE7QUFBQTtBQUFBRCxPQUFBO0FBV0EsSUFBQUUsS0FBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQTBDLFNBQUFELHdCQUFBRSxDQUFBLEVBQUFDLENBQUEsNkJBQUFDLE9BQUEsTUFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBSix1QkFBQSxZQUFBQSx3QkFBQUUsQ0FBQSxFQUFBQyxDQUFBLFNBQUFBLENBQUEsSUFBQUQsQ0FBQSxJQUFBQSxDQUFBLENBQUFLLFVBQUEsU0FBQUwsQ0FBQSxNQUFBTSxDQUFBLEVBQUFDLENBQUEs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