UNPKG

dygraphs

Version:

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

210 lines (196 loc) 21.9 kB
/** * @license * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com) * MIT-licenced: https://opensource.org/licenses/MIT */ /** * @fileoverview This file contains the managment of data handlers * @author David Eberlein (david.eberlein@ch.sauter-bc.com) * * The idea is to define a common, generic data format that works for all data * structures supported by dygraphs. To make this possible, the DataHandler * interface is introduced. This makes it possible, that dygraph itself can work * with the same logic for every data type independent of the actual format and * the DataHandler takes care of the data format specific jobs. * DataHandlers are implemented for all data types supported by Dygraphs and * return Dygraphs compliant formats. * By default the correct DataHandler is chosen based on the options set. * Optionally the user may use his own DataHandler (similar to the plugin * system). * * * The unified data format returend by each handler is defined as so: * series[n][point] = [x,y,(extras)] * * This format contains the common basis that is needed to draw a simple line * series extended by optional extras for more complex graphing types. It * contains a primitive x value as first array entry, a primitive y value as * second array entry and an optional extras object for additional data needed. * * x must always be a number. * y must always be a number, NaN of type number or null. * extras is optional and must be interpreted by the DataHandler. It may be of * any type. * * In practice this might look something like this: * default: [x, yVal] * errorBar / customBar: [x, yVal, [yTopVariance, yBottomVariance] ] * */ /*global Dygraph:false */ /*global DygraphLayout:false */ "use strict"; /** * * The data handler is responsible for all data specific operations. All of the * series data it receives and returns is always in the unified data format. * Initially the unified data is created by the extractSeries method * @constructor */ Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var DygraphDataHandler = function DygraphDataHandler() {}; var handler = DygraphDataHandler; /** * X-value array index constant for unified data samples. * @const * @type {number} */ handler.X = 0; /** * Y-value array index constant for unified data samples. * @const * @type {number} */ handler.Y = 1; /** * Extras-value array index constant for unified data samples. * @const * @type {number} */ handler.EXTRAS = 2; /** * Extracts one series from the raw data (a 2D array) into an array of the * unified data format. * This is where undesirable points (i.e. negative values on log scales and * missing values through which we wish to connect lines) are dropped. * TODO(danvk): the "missing values" bit above doesn't seem right. * * @param {!Array.<Array>} rawData The raw data passed into dygraphs where * rawData[i] = [x,ySeries1,...,ySeriesN]. * @param {!number} seriesIndex Index of the series to extract. All other * series should be ignored. * @param {!DygraphOptions} options Dygraph options. * @return {Array.<[!number,?number,?]>} The series in the unified data format * where series[i] = [x,y,{extras}]. */ handler.prototype.extractSeries = function (rawData, seriesIndex, options) {}; /** * Converts a series to a Point array. The resulting point array must be * returned in increasing order of idx property. * * @param {!Array.<[!number,?number,?]>} series The series in the unified * data format where series[i] = [x,y,{extras}]. * @param {!string} setName Name of the series. * @param {!number} boundaryIdStart Index offset of the first point, equal to the * number of skipped points left of the date window minimum (if any). * @return {!Array.<Dygraph.PointType>} List of points for this series. */ handler.prototype.seriesToPoints = function (series, setName, boundaryIdStart) { // TODO(bhs): these loops are a hot-spot for high-point-count charts. In // fact, // on chrome+linux, they are 6 times more expensive than iterating through // the // points and drawing the lines. The brunt of the cost comes from allocating // the |point| structures. var points = []; for (var i = 0; i < series.length; ++i) { var item = series[i]; var yraw = item[1]; var yval = yraw === null ? null : handler.parseFloat(yraw); var point = { x: NaN, y: NaN, xval: handler.parseFloat(item[0]), yval: yval, name: setName, // TODO(danvk): is this really necessary? idx: i + boundaryIdStart, canvasx: NaN, // add these so we do not alter the structure later, which slows Chrome canvasy: NaN }; points.push(point); } this.onPointsCreated_(series, points); return points; }; /** * Callback called for each series after the series points have been generated * which will later be used by the plotters to draw the graph. * Here data may be added to the seriesPoints which is needed by the plotters. * The indexes of series and points are in sync meaning the original data * sample for series[i] is points[i]. * * @param {!Array.<[!number,?number,?]>} series The series in the unified * data format where series[i] = [x,y,{extras}]. * @param {!Array.<Dygraph.PointType>} points The corresponding points passed * to the plotter. * @protected */ handler.prototype.onPointsCreated_ = function (series, points) {}; /** * Calculates the rolling average of a data set. * * @param {!Array.<[!number,?number,?]>} series The series in the unified * data format where series[i] = [x,y,{extras}]. * @param {!number} rollPeriod The number of points over which to average the data * @param {!DygraphOptions} options The dygraph options. * @param {!number} seriesIndex Index of the series this was extracted from. * @return {!Array.<[!number,?number,?]>} the rolled series. */ handler.prototype.rollingAverage = function (series, rollPeriod, options, seriesIndex) {}; /** * Computes the range of the data series (including confidence intervals). * * @param {!Array.<[!number,?number,?]>} series The series in the unified * data format where series[i] = [x, y, {extras}]. * @param {!Array.<number>} dateWindow The x-value range to display with * the format: [min, max]. * @param {boolean} stepPlot Whether the stepPlot option is set. * @return {Array.<number>} The low and high extremes of the series in the * given window with the format: [low, high]. */ handler.prototype.getExtremeYValues = function (series, dateWindow, stepPlot) {}; /** * Callback called for each series after the layouting data has been * calculated before the series is drawn. Here normalized positioning data * should be calculated for the extras of each point. * * @param {!Array.<Dygraph.PointType>} points The points passed to * the plotter. * @param {!Object} axis The axis on which the series will be plotted. * @param {!boolean} logscale Whether or not to use a logscale. */ handler.prototype.onLineEvaluated = function (points, axis, logscale) {}; /** * Optimized replacement for parseFloat, which was way too slow when almost * all values were type number, with few edge cases, none of which were strings. * @param {?number} val * @return {number} * @protected */ handler.parseFloat = function (val) { // parseFloat(null) is NaN if (val === null) { return NaN; } // Assume it's a number or NaN. If it's something else, I'll be shocked. return val; }; var _default = DygraphDataHandler; exports["default"] = _default; module.exports = exports.default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJEeWdyYXBoRGF0YUhhbmRsZXIiLCJoYW5kbGVyIiwiWCIsIlkiLCJFWFRSQVMiLCJwcm90b3R5cGUiLCJleHRyYWN0U2VyaWVzIiwicmF3RGF0YSIsInNlcmllc0luZGV4Iiwib3B0aW9ucyIsInNlcmllc1RvUG9pbnRzIiwic2VyaWVzIiwic2V0TmFtZSIsImJvdW5kYXJ5SWRTdGFydCIsInBvaW50cyIsImkiLCJsZW5ndGgiLCJpdGVtIiwieXJhdyIsInl2YWwiLCJwYXJzZUZsb2F0IiwicG9pbnQiLCJ4IiwiTmFOIiwieSIsInh2YWwiLCJuYW1lIiwiaWR4IiwiY2FudmFzeCIsImNhbnZhc3kiLCJwdXNoIiwib25Qb2ludHNDcmVhdGVkXyIsInJvbGxpbmdBdmVyYWdlIiwicm9sbFBlcmlvZCIsImdldEV4dHJlbWVZVmFsdWVzIiwiZGF0ZVdpbmRvdyIsInN0ZXBQbG90Iiwib25MaW5lRXZhbHVhdGVkIiwiYXhpcyIsImxvZ3NjYWxlIiwidmFsIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RhdGFoYW5kbGVyL2RhdGFoYW5kbGVyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDEzIERhdmlkIEViZXJsZWluIChkYXZpZC5lYmVybGVpbkBjaC5zYXV0ZXItYmMuY29tKVxuICogTUlULWxpY2VuY2VkOiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVFxuICovXG5cbi8qKlxuICogQGZpbGVvdmVydmlldyBUaGlzIGZpbGUgY29udGFpbnMgdGhlIG1hbmFnbWVudCBvZiBkYXRhIGhhbmRsZXJzXG4gKiBAYXV0aG9yIERhdmlkIEViZXJsZWluIChkYXZpZC5lYmVybGVpbkBjaC5zYXV0ZXItYmMuY29tKVxuICpcbiAqIFRoZSBpZGVhIGlzIHRvIGRlZmluZSBhIGNvbW1vbiwgZ2VuZXJpYyBkYXRhIGZvcm1hdCB0aGF0IHdvcmtzIGZvciBhbGwgZGF0YVxuICogc3RydWN0dXJlcyBzdXBwb3J0ZWQgYnkgZHlncmFwaHMuIFRvIG1ha2UgdGhpcyBwb3NzaWJsZSwgdGhlIERhdGFIYW5kbGVyXG4gKiBpbnRlcmZhY2UgaXMgaW50cm9kdWNlZC4gVGhpcyBtYWtlcyBpdCBwb3NzaWJsZSwgdGhhdCBkeWdyYXBoIGl0c2VsZiBjYW4gd29ya1xuICogd2l0aCB0aGUgc2FtZSBsb2dpYyBmb3IgZXZlcnkgZGF0YSB0eXBlIGluZGVwZW5kZW50IG9mIHRoZSBhY3R1YWwgZm9ybWF0IGFuZFxuICogdGhlIERhdGFIYW5kbGVyIHRha2VzIGNhcmUgb2YgdGhlIGRhdGEgZm9ybWF0IHNwZWNpZmljIGpvYnMuXG4gKiBEYXRhSGFuZGxlcnMgYXJlIGltcGxlbWVudGVkIGZvciBhbGwgZGF0YSB0eXBlcyBzdXBwb3J0ZWQgYnkgRHlncmFwaHMgYW5kXG4gKiByZXR1cm4gRHlncmFwaHMgY29tcGxpYW50IGZvcm1hdHMuXG4gKiBCeSBkZWZhdWx0IHRoZSBjb3JyZWN0IERhdGFIYW5kbGVyIGlzIGNob3NlbiBiYXNlZCBvbiB0aGUgb3B0aW9ucyBzZXQuXG4gKiBPcHRpb25hbGx5IHRoZSB1c2VyIG1heSB1c2UgaGlzIG93biBEYXRhSGFuZGxlciAoc2ltaWxhciB0byB0aGUgcGx1Z2luXG4gKiBzeXN0ZW0pLlxuICpcbiAqXG4gKiBUaGUgdW5pZmllZCBkYXRhIGZvcm1hdCByZXR1cmVuZCBieSBlYWNoIGhhbmRsZXIgaXMgZGVmaW5lZCBhcyBzbzpcbiAqIHNlcmllc1tuXVtwb2ludF0gPSBbeCx5LChleHRyYXMpXVxuICpcbiAqIFRoaXMgZm9ybWF0IGNvbnRhaW5zIHRoZSBjb21tb24gYmFzaXMgdGhhdCBpcyBuZWVkZWQgdG8gZHJhdyBhIHNpbXBsZSBsaW5lXG4gKiBzZXJpZXMgZXh0ZW5kZWQgYnkgb3B0aW9uYWwgZXh0cmFzIGZvciBtb3JlIGNvbXBsZXggZ3JhcGhpbmcgdHlwZXMuIEl0XG4gKiBjb250YWlucyBhIHByaW1pdGl2ZSB4IHZhbHVlIGFzIGZpcnN0IGFycmF5IGVudHJ5LCBhIHByaW1pdGl2ZSB5IHZhbHVlIGFzXG4gKiBzZWNvbmQgYXJyYXkgZW50cnkgYW5kIGFuIG9wdGlvbmFsIGV4dHJhcyBvYmplY3QgZm9yIGFkZGl0aW9uYWwgZGF0YSBuZWVkZWQuXG4gKlxuICogeCBtdXN0IGFsd2F5cyBiZSBhIG51bWJlci5cbiAqIHkgbXVzdCBhbHdheXMgYmUgYSBudW1iZXIsIE5hTiBvZiB0eXBlIG51bWJlciBvciBudWxsLlxuICogZXh0cmFzIGlzIG9wdGlvbmFsIGFuZCBtdXN0IGJlIGludGVycHJldGVkIGJ5IHRoZSBEYXRhSGFuZGxlci4gSXQgbWF5IGJlIG9mXG4gKiBhbnkgdHlwZS5cbiAqXG4gKiBJbiBwcmFjdGljZSB0aGlzIG1pZ2h0IGxvb2sgc29tZXRoaW5nIGxpa2UgdGhpczpcbiAqIGRlZmF1bHQ6IFt4LCB5VmFsXVxuICogZXJyb3JCYXIgLyBjdXN0b21CYXI6IFt4LCB5VmFsLCBbeVRvcFZhcmlhbmNlLCB5Qm90dG9tVmFyaWFuY2VdIF1cbiAqXG4gKi9cbi8qZ2xvYmFsIER5Z3JhcGg6ZmFsc2UgKi9cbi8qZ2xvYmFsIER5Z3JhcGhMYXlvdXQ6ZmFsc2UgKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKlxuICpcbiAqIFRoZSBkYXRhIGhhbmRsZXIgaXMgcmVzcG9uc2libGUgZm9yIGFsbCBkYXRhIHNwZWNpZmljIG9wZXJhdGlvbnMuIEFsbCBvZiB0aGVcbiAqIHNlcmllcyBkYXRhIGl0IHJlY2VpdmVzIGFuZCByZXR1cm5zIGlzIGFsd2F5cyBpbiB0aGUgdW5pZmllZCBkYXRhIGZvcm1hdC5cbiAqIEluaXRpYWxseSB0aGUgdW5pZmllZCBkYXRhIGlzIGNyZWF0ZWQgYnkgdGhlIGV4dHJhY3RTZXJpZXMgbWV0aG9kXG4gKiBAY29uc3RydWN0b3JcbiAqL1xudmFyIER5Z3JhcGhEYXRhSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbn07XG5cbnZhciBoYW5kbGVyID0gRHlncmFwaERhdGFIYW5kbGVyO1xuXG4vKipcbiAqIFgtdmFsdWUgYXJyYXkgaW5kZXggY29uc3RhbnQgZm9yIHVuaWZpZWQgZGF0YSBzYW1wbGVzLlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5oYW5kbGVyLlggPSAwO1xuXG4vKipcbiAqIFktdmFsdWUgYXJyYXkgaW5kZXggY29uc3RhbnQgZm9yIHVuaWZpZWQgZGF0YSBzYW1wbGVzLlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5oYW5kbGVyLlkgPSAxO1xuXG4vKipcbiAqIEV4dHJhcy12YWx1ZSBhcnJheSBpbmRleCBjb25zdGFudCBmb3IgdW5pZmllZCBkYXRhIHNhbXBsZXMuXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmhhbmRsZXIuRVhUUkFTID0gMjtcblxuLyoqXG4gKiBFeHRyYWN0cyBvbmUgc2VyaWVzIGZyb20gdGhlIHJhdyBkYXRhIChhIDJEIGFycmF5KSBpbnRvIGFuIGFycmF5IG9mIHRoZVxuICogdW5pZmllZCBkYXRhIGZvcm1hdC5cbiAqIFRoaXMgaXMgd2hlcmUgdW5kZXNpcmFibGUgcG9pbnRzIChpLmUuIG5lZ2F0aXZlIHZhbHVlcyBvbiBsb2cgc2NhbGVzIGFuZFxuICogbWlzc2luZyB2YWx1ZXMgdGhyb3VnaCB3aGljaCB3ZSB3aXNoIHRvIGNvbm5lY3QgbGluZXMpIGFyZSBkcm9wcGVkLlxuICogVE9ETyhkYW52ayk6IHRoZSBcIm1pc3NpbmcgdmFsdWVzXCIgYml0IGFib3ZlIGRvZXNuJ3Qgc2VlbSByaWdodC5cbiAqXG4gKiBAcGFyYW0geyFBcnJheS48QXJyYXk+fSByYXdEYXRhIFRoZSByYXcgZGF0YSBwYXNzZWQgaW50byBkeWdyYXBocyB3aGVyZVxuICogICAgIHJhd0RhdGFbaV0gPSBbeCx5U2VyaWVzMSwuLi4seVNlcmllc05dLlxuICogQHBhcmFtIHshbnVtYmVyfSBzZXJpZXNJbmRleCBJbmRleCBvZiB0aGUgc2VyaWVzIHRvIGV4dHJhY3QuIEFsbCBvdGhlclxuICogICAgIHNlcmllcyBzaG91bGQgYmUgaWdub3JlZC5cbiAqIEBwYXJhbSB7IUR5Z3JhcGhPcHRpb25zfSBvcHRpb25zIER5Z3JhcGggb3B0aW9ucy5cbiAqIEByZXR1cm4ge0FycmF5LjxbIW51bWJlciw/bnVtYmVyLD9dPn0gVGhlIHNlcmllcyBpbiB0aGUgdW5pZmllZCBkYXRhIGZvcm1hdFxuICogICAgIHdoZXJlIHNlcmllc1tpXSA9IFt4LHkse2V4dHJhc31dLlxuICovXG5oYW5kbGVyLnByb3RvdHlwZS5leHRyYWN0U2VyaWVzID0gZnVuY3Rpb24ocmF3RGF0YSwgc2VyaWVzSW5kZXgsIG9wdGlvbnMpIHtcbn07XG5cbi8qKlxuICogQ29udmVydHMgYSBzZXJpZXMgdG8gYSBQb2ludCBhcnJheS4gIFRoZSByZXN1bHRpbmcgcG9pbnQgYXJyYXkgbXVzdCBiZVxuICogcmV0dXJuZWQgaW4gaW5jcmVhc2luZyBvcmRlciBvZiBpZHggcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHshQXJyYXkuPFshbnVtYmVyLD9udW1iZXIsP10+fSBzZXJpZXMgVGhlIHNlcmllcyBpbiB0aGUgdW5pZmllZFxuICogICAgICAgICAgZGF0YSBmb3JtYXQgd2hlcmUgc2VyaWVzW2ldID0gW3gseSx7ZXh0cmFzfV0uXG4gKiBAcGFyYW0geyFzdHJpbmd9IHNldE5hbWUgTmFtZSBvZiB0aGUgc2VyaWVzLlxuICogQHBhcmFtIHshbnVtYmVyfSBib3VuZGFyeUlkU3RhcnQgSW5kZXggb2Zmc2V0IG9mIHRoZSBmaXJzdCBwb2ludCwgZXF1YWwgdG8gdGhlXG4gKiAgICAgICAgICBudW1iZXIgb2Ygc2tpcHBlZCBwb2ludHMgbGVmdCBvZiB0aGUgZGF0ZSB3aW5kb3cgbWluaW11bSAoaWYgYW55KS5cbiAqIEByZXR1cm4geyFBcnJheS48RHlncmFwaC5Qb2ludFR5cGU+fSBMaXN0IG9mIHBvaW50cyBmb3IgdGhpcyBzZXJpZXMuXG4gKi9cbmhhbmRsZXIucHJvdG90eXBlLnNlcmllc1RvUG9pbnRzID0gZnVuY3Rpb24oc2VyaWVzLCBzZXROYW1lLCBib3VuZGFyeUlkU3RhcnQpIHtcbiAgLy8gVE9ETyhiaHMpOiB0aGVzZSBsb29wcyBhcmUgYSBob3Qtc3BvdCBmb3IgaGlnaC1wb2ludC1jb3VudCBjaGFydHMuIEluXG4gIC8vIGZhY3QsXG4gIC8vIG9uIGNocm9tZStsaW51eCwgdGhleSBhcmUgNiB0aW1lcyBtb3JlIGV4cGVuc2l2ZSB0aGFuIGl0ZXJhdGluZyB0aHJvdWdoXG4gIC8vIHRoZVxuICAvLyBwb2ludHMgYW5kIGRyYXdpbmcgdGhlIGxpbmVzLiBUaGUgYnJ1bnQgb2YgdGhlIGNvc3QgY29tZXMgZnJvbSBhbGxvY2F0aW5nXG4gIC8vIHRoZSB8cG9pbnR8IHN0cnVjdHVyZXMuXG4gIHZhciBwb2ludHMgPSBbXTtcbiAgZm9yICggdmFyIGkgPSAwOyBpIDwgc2VyaWVzLmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGl0ZW0gPSBzZXJpZXNbaV07XG4gICAgdmFyIHlyYXcgPSBpdGVtWzFdO1xuICAgIHZhciB5dmFsID0geXJhdyA9PT0gbnVsbCA/IG51bGwgOiBoYW5kbGVyLnBhcnNlRmxvYXQoeXJhdyk7XG4gICAgdmFyIHBvaW50ID0ge1xuICAgICAgeCA6IE5hTixcbiAgICAgIHkgOiBOYU4sXG4gICAgICB4dmFsIDogaGFuZGxlci5wYXJzZUZsb2F0KGl0ZW1bMF0pLFxuICAgICAgeXZhbCA6IHl2YWwsXG4gICAgICBuYW1lIDogc2V0TmFtZSwgLy8gVE9ETyhkYW52ayk6IGlzIHRoaXMgcmVhbGx5IG5lY2Vzc2FyeT9cbiAgICAgIGlkeCA6IGkgKyBib3VuZGFyeUlkU3RhcnQsXG4gICAgICBjYW52YXN4OiBOYU4sIC8vIGFkZCB0aGVzZSBzbyB3ZSBkbyBub3QgYWx0ZXIgdGhlIHN0cnVjdHVyZSBsYXRlciwgd2hpY2ggc2xvd3MgQ2hyb21lXG4gICAgICBjYW52YXN5OiBOYU4sXG4gICAgfTtcbiAgICBwb2ludHMucHVzaChwb2ludCk7XG4gIH1cbiAgdGhpcy5vblBvaW50c0NyZWF0ZWRfKHNlcmllcywgcG9pbnRzKTtcbiAgcmV0dXJuIHBvaW50cztcbn07XG5cbi8qKlxuICogQ2FsbGJhY2sgY2FsbGVkIGZvciBlYWNoIHNlcmllcyBhZnRlciB0aGUgc2VyaWVzIHBvaW50cyBoYXZlIGJlZW4gZ2VuZXJhdGVkXG4gKiB3aGljaCB3aWxsIGxhdGVyIGJlIHVzZWQgYnkgdGhlIHBsb3R0ZXJzIHRvIGRyYXcgdGhlIGdyYXBoLlxuICogSGVyZSBkYXRhIG1heSBiZSBhZGRlZCB0byB0aGUgc2VyaWVzUG9pbnRzIHdoaWNoIGlzIG5lZWRlZCBieSB0aGUgcGxvdHRlcnMuXG4gKiBUaGUgaW5kZXhlcyBvZiBzZXJpZXMgYW5kIHBvaW50cyBhcmUgaW4gc3luYyBtZWFuaW5nIHRoZSBvcmlnaW5hbCBkYXRhXG4gKiBzYW1wbGUgZm9yIHNlcmllc1tpXSBpcyBwb2ludHNbaV0uXG4gKlxuICogQHBhcmFtIHshQXJyYXkuPFshbnVtYmVyLD9udW1iZXIsP10+fSBzZXJpZXMgVGhlIHNlcmllcyBpbiB0aGUgdW5pZmllZFxuICogICAgIGRhdGEgZm9ybWF0IHdoZXJlIHNlcmllc1tpXSA9IFt4LHkse2V4dHJhc31dLlxuICogQHBhcmFtIHshQXJyYXkuPER5Z3JhcGguUG9pbnRUeXBlPn0gcG9pbnRzIFRoZSBjb3JyZXNwb25kaW5nIHBvaW50cyBwYXNzZWRcbiAqICAgICB0byB0aGUgcGxvdHRlci5cbiAqIEBwcm90ZWN0ZWRcbiAqL1xuaGFuZGxlci5wcm90b3R5cGUub25Qb2ludHNDcmVhdGVkXyA9IGZ1bmN0aW9uKHNlcmllcywgcG9pbnRzKSB7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHJvbGxpbmcgYXZlcmFnZSBvZiBhIGRhdGEgc2V0LlxuICpcbiAqIEBwYXJhbSB7IUFycmF5LjxbIW51bWJlciw/bnVtYmVyLD9dPn0gc2VyaWVzIFRoZSBzZXJpZXMgaW4gdGhlIHVuaWZpZWRcbiAqICAgICAgICAgIGRhdGEgZm9ybWF0IHdoZXJlIHNlcmllc1tpXSA9IFt4LHkse2V4dHJhc31dLlxuICogQHBhcmFtIHshbnVtYmVyfSByb2xsUGVyaW9kIFRoZSBudW1iZXIgb2YgcG9pbnRzIG92ZXIgd2hpY2ggdG8gYXZlcmFnZSB0aGUgZGF0YVxuICogQHBhcmFtIHshRHlncmFwaE9wdGlvbnN9IG9wdGlvbnMgVGhlIGR5Z3JhcGggb3B0aW9ucy5cbiAqIEBwYXJhbSB7IW51bWJlcn0gc2VyaWVzSW5kZXggSW5kZXggb2YgdGhlIHNlcmllcyB0aGlzIHdhcyBleHRyYWN0ZWQgZnJvbS5cbiAqIEByZXR1cm4geyFBcnJheS48WyFudW1iZXIsP251bWJlciw/XT59IHRoZSByb2xsZWQgc2VyaWVzLlxuICovXG5oYW5kbGVyLnByb3RvdHlwZS5yb2xsaW5nQXZlcmFnZSA9IGZ1bmN0aW9uKHNlcmllcywgcm9sbFBlcmlvZCwgb3B0aW9ucywgc2VyaWVzSW5kZXgpIHtcbn07XG5cbi8qKlxuICogQ29tcHV0ZXMgdGhlIHJhbmdlIG9mIHRoZSBkYXRhIHNlcmllcyAoaW5jbHVkaW5nIGNvbmZpZGVuY2UgaW50ZXJ2YWxzKS5cbiAqXG4gKiBAcGFyYW0geyFBcnJheS48WyFudW1iZXIsP251bWJlciw/XT59IHNlcmllcyBUaGUgc2VyaWVzIGluIHRoZSB1bmlmaWVkXG4gKiAgICAgZGF0YSBmb3JtYXQgd2hlcmUgc2VyaWVzW2ldID0gW3gsIHksIHtleHRyYXN9XS5cbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBkYXRlV2luZG93IFRoZSB4LXZhbHVlIHJhbmdlIHRvIGRpc3BsYXkgd2l0aFxuICogICAgIHRoZSBmb3JtYXQ6IFttaW4sIG1heF0uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHN0ZXBQbG90IFdoZXRoZXIgdGhlIHN0ZXBQbG90IG9wdGlvbiBpcyBzZXQuXG4gKiBAcmV0dXJuIHtBcnJheS48bnVtYmVyPn0gVGhlIGxvdyBhbmQgaGlnaCBleHRyZW1lcyBvZiB0aGUgc2VyaWVzIGluIHRoZVxuICogICAgIGdpdmVuIHdpbmRvdyB3aXRoIHRoZSBmb3JtYXQ6IFtsb3csIGhpZ2hdLlxuICovXG5oYW5kbGVyLnByb3RvdHlwZS5nZXRFeHRyZW1lWVZhbHVlcyA9IGZ1bmN0aW9uKHNlcmllcywgZGF0ZVdpbmRvdywgc3RlcFBsb3QpIHtcbn07XG5cbi8qKlxuICogQ2FsbGJhY2sgY2FsbGVkIGZvciBlYWNoIHNlcmllcyBhZnRlciB0aGUgbGF5b3V0aW5nIGRhdGEgaGFzIGJlZW5cbiAqIGNhbGN1bGF0ZWQgYmVmb3JlIHRoZSBzZXJpZXMgaXMgZHJhd24uIEhlcmUgbm9ybWFsaXplZCBwb3NpdGlvbmluZyBkYXRhXG4gKiBzaG91bGQgYmUgY2FsY3VsYXRlZCBmb3IgdGhlIGV4dHJhcyBvZiBlYWNoIHBvaW50LlxuICpcbiAqIEBwYXJhbSB7IUFycmF5LjxEeWdyYXBoLlBvaW50VHlwZT59IHBvaW50cyBUaGUgcG9pbnRzIHBhc3NlZCB0b1xuICogICAgICAgICAgdGhlIHBsb3R0ZXIuXG4gKiBAcGFyYW0geyFPYmplY3R9IGF4aXMgVGhlIGF4aXMgb24gd2hpY2ggdGhlIHNlcmllcyB3aWxsIGJlIHBsb3R0ZWQuXG4gKiBAcGFyYW0geyFib29sZWFufSBsb2dzY2FsZSBXaGV0aGVyIG9yIG5vdCB0byB1c2UgYSBsb2dzY2FsZS5cbiAqL1xuaGFuZGxlci5wcm90b3R5cGUub25MaW5lRXZhbHVhdGVkID0gZnVuY3Rpb24ocG9pbnRzLCBheGlzLCBsb2dzY2FsZSkge1xufTtcblxuLyoqXG4gKiBPcHRpbWl6ZWQgcmVwbGFjZW1lbnQgZm9yIHBhcnNlRmxvYXQsIHdoaWNoIHdhcyB3YXkgdG9vIHNsb3cgd2hlbiBhbG1vc3RcbiAqIGFsbCB2YWx1ZXMgd2VyZSB0eXBlIG51bWJlciwgd2l0aCBmZXcgZWRnZSBjYXNlcywgbm9uZSBvZiB3aGljaCB3ZXJlIHN0cmluZ3MuXG4gKiBAcGFyYW0gez9udW1iZXJ9IHZhbFxuICogQHJldHVybiB7bnVtYmVyfVxuICogQHByb3RlY3RlZFxuICovXG5oYW5kbGVyLnBhcnNlRmxvYXQgPSBmdW5jdGlvbih2YWwpIHtcbiAgLy8gcGFyc2VGbG9hdChudWxsKSBpcyBOYU5cbiAgaWYgKHZhbCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBOYU47XG4gIH1cblxuICAvLyBBc3N1bWUgaXQncyBhIG51bWJlciBvciBOYU4uIElmIGl0J3Mgc29tZXRoaW5nIGVsc2UsIEknbGwgYmUgc2hvY2tlZC5cbiAgcmV0dXJuIHZhbDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IER5Z3JhcGhEYXRhSGFuZGxlcjtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsWUFBWTs7QUFFWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU5BO0VBQUE7QUFBQTtBQUFBO0FBT0EsSUFBSUEsa0JBQWtCLEdBQUcsU0FBckJBLGtCQUFrQixHQUFlLENBQ3JDLENBQUM7QUFFRCxJQUFJQyxPQUFPLEdBQUdELGtCQUFrQjs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBQyxPQUFPLENBQUNDLENBQUMsR0FBRyxDQUFDOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQUQsT0FBTyxDQUFDRSxDQUFDLEdBQUcsQ0FBQzs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0FGLE9BQU8sQ0FBQ0csTUFBTSxHQUFHLENBQUM7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBSCxPQUFPLENBQUNJLFNBQVMsQ0FBQ0MsYUFBYSxHQUFHLFVBQVNDLE9BQU8sRUFBRUMsV0FBVyxFQUFFQyxPQUFPLEVBQUUsQ0FDMUUsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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