UNPKG

dygraphs

Version:

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

397 lines (369 loc) 41.2 kB
/** * @license * Copyright 2011 Dan Vanderkam (danvdk@gmail.com) * MIT-licenced: https://opensource.org/licenses/MIT */ /** * @fileoverview DygraphOptions is responsible for parsing and returning * information about options. */ // TODO: remove this jshint directive & fix the warnings. /*jshint sub:true */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var utils = _interopRequireWildcard(require("./dygraph-utils")); var _dygraphDefaultAttrs = _interopRequireDefault(require("./dygraph-default-attrs")); var _dygraphOptionsReference = _interopRequireDefault(require("./dygraph-options-reference")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * Interesting member variables: (REMOVING THIS LIST AS I CLOSURIZE) * global_ - global attributes (common among all graphs, AIUI) * user - attributes set by the user * series_ - { seriesName -> { idx, yAxis, options }} */ /** * This parses attributes into an object that can be easily queried. * * It doesn't necessarily mean that all options are available, specifically * if labels are not yet available, since those drive details of the per-series * and per-axis options. * * @param {Dygraph} dygraph The chart to which these options belong. * @constructor */ var DygraphOptions = function DygraphOptions(dygraph) { /** * The dygraph. * @type {!Dygraph} */ this.dygraph_ = dygraph; /** * Array of axis index to { series : [ series names ] , options : { axis-specific options. } } * @type {Array.<{series : Array.<string>, options : Object}>} @private */ this.yAxes_ = []; /** * Contains x-axis specific options, which are stored in the options key. * This matches the yAxes_ object structure (by being a dictionary with an * options element) allowing for shared code. * @type {options: Object} @private */ this.xAxis_ = {}; this.series_ = {}; // Once these two objects are initialized, you can call get(); this.global_ = this.dygraph_.attrs_; this.user_ = this.dygraph_.user_attrs_ || {}; /** * A list of series in columnar order. * @type {Array.<string>} */ this.labels_ = []; this.highlightSeries_ = this.get("highlightSeriesOpts") || {}; this.reparseSeries(); }; /** * Not optimal, but does the trick when you're only using two axes. * If we move to more axes, this can just become a function. * * @type {Object.<number>} * @private */ DygraphOptions.AXIS_STRING_MAPPINGS_ = { 'y': 0, 'Y': 0, 'y1': 0, 'Y1': 0, 'y2': 1, 'Y2': 1 }; /** * @param {string|number} axis * @private */ DygraphOptions.axisToIndex_ = function (axis) { if (typeof axis == "string") { if (DygraphOptions.AXIS_STRING_MAPPINGS_.hasOwnProperty(axis)) { return DygraphOptions.AXIS_STRING_MAPPINGS_[axis]; } throw "Unknown axis : " + axis; } if (typeof axis == "number") { if (axis === 0 || axis === 1) { return axis; } throw "Dygraphs only supports two y-axes, indexed from 0-1."; } if (axis) { throw "Unknown axis : " + axis; } // No axis specification means axis 0. return 0; }; /** * Reparses options that are all related to series. This typically occurs when * options are either updated, or source data has been made available. * * TODO(konigsberg): The method name is kind of weak; fix. */ DygraphOptions.prototype.reparseSeries = function () { var labels = this.get("labels"); if (!labels) { return; // -- can't do more for now, will parse after getting the labels. } this.labels_ = labels.slice(1); this.yAxes_ = [{ series: [], options: {} }]; // Always one axis at least. this.xAxis_ = { options: {} }; this.series_ = {}; // Series are specified in the series element: // // { // labels: [ "X", "foo", "bar" ], // pointSize: 3, // series : { // foo : {}, // options for foo // bar : {} // options for bar // } // } // // So, if series is found, it's expected to contain per-series data, // otherwise set a default. var seriesDict = this.user_.series || {}; for (var idx = 0; idx < this.labels_.length; idx++) { var seriesName = this.labels_[idx]; var optionsForSeries = seriesDict[seriesName] || {}; var yAxis = DygraphOptions.axisToIndex_(optionsForSeries["axis"]); this.series_[seriesName] = { idx: idx, yAxis: yAxis, options: optionsForSeries }; if (!this.yAxes_[yAxis]) { this.yAxes_[yAxis] = { series: [seriesName], options: {} }; } else { this.yAxes_[yAxis].series.push(seriesName); } } var axis_opts = this.user_["axes"] || {}; utils.update(this.yAxes_[0].options, axis_opts["y"] || {}); if (this.yAxes_.length > 1) { utils.update(this.yAxes_[1].options, axis_opts["y2"] || {}); } utils.update(this.xAxis_.options, axis_opts["x"] || {}); if (typeof process !== 'undefined' && process.env.NODE_ENV != 'production') { // For "production" code, this gets removed by uglifyjs. this.validateOptions_(); } }; /** * Get a global value. * * @param {string} name the name of the option. */ DygraphOptions.prototype.get = function (name) { var result = this.getGlobalUser_(name); if (result !== null) { return result; } return this.getGlobalDefault_(name); }; DygraphOptions.prototype.getGlobalUser_ = function (name) { if (this.user_.hasOwnProperty(name)) { return this.user_[name]; } return null; }; DygraphOptions.prototype.getGlobalDefault_ = function (name) { if (this.global_.hasOwnProperty(name)) { return this.global_[name]; } if (_dygraphDefaultAttrs["default"].hasOwnProperty(name)) { return _dygraphDefaultAttrs["default"][name]; } return null; }; /** * Get a value for a specific axis. If there is no specific value for the axis, * the global value is returned. * * @param {string} name the name of the option. * @param {string|number} axis the axis to search. Can be the string representation * ("y", "y2") or the axis number (0, 1). */ DygraphOptions.prototype.getForAxis = function (name, axis) { var axisIdx; var axisString; // Since axis can be a number or a string, straighten everything out here. if (typeof axis == 'number') { axisIdx = axis; axisString = axisIdx === 0 ? "y" : "y2"; } else { if (axis == "y1") { axis = "y"; } // Standardize on 'y'. Is this bad? I think so. if (axis == "y") { axisIdx = 0; } else if (axis == "y2") { axisIdx = 1; } else if (axis == "x") { axisIdx = -1; // simply a placeholder for below. } else { throw "Unknown axis " + axis; } axisString = axis; } var userAxis = axisIdx == -1 ? this.xAxis_ : this.yAxes_[axisIdx]; // Search the user-specified axis option first. if (userAxis) { // This condition could be removed if we always set up this.yAxes_ for y2. var axisOptions = userAxis.options; if (axisOptions.hasOwnProperty(name)) { return axisOptions[name]; } } // User-specified global options second. // But, hack, ignore globally-specified 'logscale' for 'x' axis declaration. if (!(axis === 'x' && name === 'logscale')) { var result = this.getGlobalUser_(name); if (result !== null) { return result; } } // Default axis options third. var defaultAxisOptions = _dygraphDefaultAttrs["default"].axes[axisString]; if (defaultAxisOptions.hasOwnProperty(name)) { return defaultAxisOptions[name]; } // Default global options last. return this.getGlobalDefault_(name); }; /** * Get a value for a specific series. If there is no specific value for the series, * the value for the axis is returned (and afterwards, the global value.) * * @param {string} name the name of the option. * @param {string} series the series to search. */ DygraphOptions.prototype.getForSeries = function (name, series) { // Honors indexes as series. if (series === this.dygraph_.getHighlightSeries()) { if (this.highlightSeries_.hasOwnProperty(name)) { return this.highlightSeries_[name]; } } if (!this.series_.hasOwnProperty(series)) { throw "Unknown series: " + series; } var seriesObj = this.series_[series]; var seriesOptions = seriesObj["options"]; if (seriesOptions.hasOwnProperty(name)) { return seriesOptions[name]; } return this.getForAxis(name, seriesObj["yAxis"]); }; /** * Returns the number of y-axes on the chart. * @return {number} the number of axes. */ DygraphOptions.prototype.numAxes = function () { return this.yAxes_.length; }; /** * Return the y-axis for a given series, specified by name. */ DygraphOptions.prototype.axisForSeries = function (series) { return this.series_[series].yAxis; }; /** * Returns the options for the specified axis. */ // TODO(konigsberg): this is y-axis specific. Support the x axis. DygraphOptions.prototype.axisOptions = function (yAxis) { return this.yAxes_[yAxis].options; }; /** * Return the series associated with an axis. */ DygraphOptions.prototype.seriesForAxis = function (yAxis) { return this.yAxes_[yAxis].series; }; /** * Return the list of all series, in their columnar order. */ DygraphOptions.prototype.seriesNames = function () { return this.labels_; }; if (typeof process !== 'undefined' && process.env.NODE_ENV != 'production') { // For "production" code, this gets removed by uglifyjs. /** * Validate all options. * This requires OPTIONS_REFERENCE, which is only available in debug builds. * @private */ DygraphOptions.prototype.validateOptions_ = function () { if (typeof _dygraphOptionsReference["default"] === 'undefined') { throw 'Called validateOptions_ in prod build.'; } var that = this; var validateOption = function validateOption(optionName) { if (!_dygraphOptionsReference["default"][optionName]) { that.warnInvalidOption_(optionName); } }; var optionsDicts = [this.xAxis_.options, this.yAxes_[0].options, this.yAxes_[1] && this.yAxes_[1].options, this.global_, this.user_, this.highlightSeries_]; var names = this.seriesNames(); for (var i = 0; i < names.length; i++) { var name = names[i]; if (this.series_.hasOwnProperty(name)) { optionsDicts.push(this.series_[name].options); } } for (var i = 0; i < optionsDicts.length; i++) { var dict = optionsDicts[i]; if (!dict) continue; for (var optionName in dict) { if (dict.hasOwnProperty(optionName)) { validateOption(optionName); } } } }; var WARNINGS = {}; // Only show any particular warning once. /** * Logs a warning about invalid options. * TODO: make this throw for testing * @private */ DygraphOptions.prototype.warnInvalidOption_ = function (optionName) { if (!WARNINGS[optionName]) { WARNINGS[optionName] = true; var isSeries = this.labels_.indexOf(optionName) >= 0; if (isSeries) { console.warn('Use new-style per-series options (saw ' + optionName + ' as top-level options key). See http://blog.dygraphs.com/2012/12/the-new-and-better-way-to-specify.html (The New and Better Way to Specify Series and Axis Options).'); } else { console.warn('Unknown option ' + optionName + ' (see https://dygraphs.com/options.html for the full list of options)'); } throw "invalid option " + optionName; } }; // Reset list of previously-shown warnings. Used for testing. DygraphOptions.resetWarnings_ = function () { WARNINGS = {}; }; } var _default = DygraphOptions; exports["default"] = _default; module.exports = exports.default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJEeWdyYXBoT3B0aW9ucyIsImR5Z3JhcGgiLCJkeWdyYXBoXyIsInlBeGVzXyIsInhBeGlzXyIsInNlcmllc18iLCJnbG9iYWxfIiwiYXR0cnNfIiwidXNlcl8iLCJ1c2VyX2F0dHJzXyIsImxhYmVsc18iLCJoaWdobGlnaHRTZXJpZXNfIiwiZ2V0IiwicmVwYXJzZVNlcmllcyIsIkFYSVNfU1RSSU5HX01BUFBJTkdTXyIsImF4aXNUb0luZGV4XyIsImF4aXMiLCJoYXNPd25Qcm9wZXJ0eSIsInByb3RvdHlwZSIsImxhYmVscyIsInNsaWNlIiwic2VyaWVzIiwib3B0aW9ucyIsInNlcmllc0RpY3QiLCJpZHgiLCJsZW5ndGgiLCJzZXJpZXNOYW1lIiwib3B0aW9uc0ZvclNlcmllcyIsInlBeGlzIiwicHVzaCIsImF4aXNfb3B0cyIsInV0aWxzIiwidXBkYXRlIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwidmFsaWRhdGVPcHRpb25zXyIsIm5hbWUiLCJyZXN1bHQiLCJnZXRHbG9iYWxVc2VyXyIsImdldEdsb2JhbERlZmF1bHRfIiwiREVGQVVMVF9BVFRSUyIsImdldEZvckF4aXMiLCJheGlzSWR4IiwiYXhpc1N0cmluZyIsInVzZXJBeGlzIiwiYXhpc09wdGlvbnMiLCJkZWZhdWx0QXhpc09wdGlvbnMiLCJheGVzIiwiZ2V0Rm9yU2VyaWVzIiwiZ2V0SGlnaGxpZ2h0U2VyaWVzIiwic2VyaWVzT2JqIiwic2VyaWVzT3B0aW9ucyIsIm51bUF4ZXMiLCJheGlzRm9yU2VyaWVzIiwic2VyaWVzRm9yQXhpcyIsInNlcmllc05hbWVzIiwiT1BUSU9OU19SRUZFUkVOQ0UiLCJ0aGF0IiwidmFsaWRhdGVPcHRpb24iLCJvcHRpb25OYW1lIiwid2FybkludmFsaWRPcHRpb25fIiwib3B0aW9uc0RpY3RzIiwibmFtZXMiLCJpIiwiZGljdCIsIldBUk5JTkdTIiwiaXNTZXJpZXMiLCJpbmRleE9mIiwiY29uc29sZSIsIndhcm4iLCJyZXNldFdhcm5pbmdzXyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9keWdyYXBoLW9wdGlvbnMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTEgRGFuIFZhbmRlcmthbSAoZGFudmRrQGdtYWlsLmNvbSlcbiAqIE1JVC1saWNlbmNlZDogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVRcbiAqL1xuXG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcgRHlncmFwaE9wdGlvbnMgaXMgcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgYW5kIHJldHVybmluZ1xuICogaW5mb3JtYXRpb24gYWJvdXQgb3B0aW9ucy5cbiAqL1xuXG4vLyBUT0RPOiByZW1vdmUgdGhpcyBqc2hpbnQgZGlyZWN0aXZlICYgZml4IHRoZSB3YXJuaW5ncy5cbi8qanNoaW50IHN1Yjp0cnVlICovXG5cInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0ICogYXMgdXRpbHMgZnJvbSAnLi9keWdyYXBoLXV0aWxzJztcbmltcG9ydCBERUZBVUxUX0FUVFJTIGZyb20gJy4vZHlncmFwaC1kZWZhdWx0LWF0dHJzJztcbmltcG9ydCBPUFRJT05TX1JFRkVSRU5DRSBmcm9tICcuL2R5Z3JhcGgtb3B0aW9ucy1yZWZlcmVuY2UnO1xuXG4vKlxuICogSW50ZXJlc3RpbmcgbWVtYmVyIHZhcmlhYmxlczogKFJFTU9WSU5HIFRISVMgTElTVCBBUyBJIENMT1NVUklaRSlcbiAqIGdsb2JhbF8gLSBnbG9iYWwgYXR0cmlidXRlcyAoY29tbW9uIGFtb25nIGFsbCBncmFwaHMsIEFJVUkpXG4gKiB1c2VyIC0gYXR0cmlidXRlcyBzZXQgYnkgdGhlIHVzZXJcbiAqIHNlcmllc18gLSB7IHNlcmllc05hbWUgLT4geyBpZHgsIHlBeGlzLCBvcHRpb25zIH19XG4gKi9cblxuLyoqXG4gKiBUaGlzIHBhcnNlcyBhdHRyaWJ1dGVzIGludG8gYW4gb2JqZWN0IHRoYXQgY2FuIGJlIGVhc2lseSBxdWVyaWVkLlxuICpcbiAqIEl0IGRvZXNuJ3QgbmVjZXNzYXJpbHkgbWVhbiB0aGF0IGFsbCBvcHRpb25zIGFyZSBhdmFpbGFibGUsIHNwZWNpZmljYWxseVxuICogaWYgbGFiZWxzIGFyZSBub3QgeWV0IGF2YWlsYWJsZSwgc2luY2UgdGhvc2UgZHJpdmUgZGV0YWlscyBvZiB0aGUgcGVyLXNlcmllc1xuICogYW5kIHBlci1heGlzIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIHtEeWdyYXBofSBkeWdyYXBoIFRoZSBjaGFydCB0byB3aGljaCB0aGVzZSBvcHRpb25zIGJlbG9uZy5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG52YXIgRHlncmFwaE9wdGlvbnMgPSBmdW5jdGlvbihkeWdyYXBoKSB7XG4gIC8qKlxuICAgKiBUaGUgZHlncmFwaC5cbiAgICogQHR5cGUgeyFEeWdyYXBofVxuICAgKi9cbiAgdGhpcy5keWdyYXBoXyA9IGR5Z3JhcGg7XG5cbiAgLyoqXG4gICAqIEFycmF5IG9mIGF4aXMgaW5kZXggdG8geyBzZXJpZXMgOiBbIHNlcmllcyBuYW1lcyBdICwgb3B0aW9ucyA6IHsgYXhpcy1zcGVjaWZpYyBvcHRpb25zLiB9IH1cbiAgICogQHR5cGUge0FycmF5Ljx7c2VyaWVzIDogQXJyYXkuPHN0cmluZz4sIG9wdGlvbnMgOiBPYmplY3R9Pn0gQHByaXZhdGVcbiAgICovXG4gIHRoaXMueUF4ZXNfID0gW107XG5cbiAgLyoqXG4gICAqIENvbnRhaW5zIHgtYXhpcyBzcGVjaWZpYyBvcHRpb25zLCB3aGljaCBhcmUgc3RvcmVkIGluIHRoZSBvcHRpb25zIGtleS5cbiAgICogVGhpcyBtYXRjaGVzIHRoZSB5QXhlc18gb2JqZWN0IHN0cnVjdHVyZSAoYnkgYmVpbmcgYSBkaWN0aW9uYXJ5IHdpdGggYW5cbiAgICogb3B0aW9ucyBlbGVtZW50KSBhbGxvd2luZyBmb3Igc2hhcmVkIGNvZGUuXG4gICAqIEB0eXBlIHtvcHRpb25zOiBPYmplY3R9IEBwcml2YXRlXG4gICAqL1xuICB0aGlzLnhBeGlzXyA9IHt9O1xuICB0aGlzLnNlcmllc18gPSB7fTtcblxuICAvLyBPbmNlIHRoZXNlIHR3byBvYmplY3RzIGFyZSBpbml0aWFsaXplZCwgeW91IGNhbiBjYWxsIGdldCgpO1xuICB0aGlzLmdsb2JhbF8gPSB0aGlzLmR5Z3JhcGhfLmF0dHJzXztcbiAgdGhpcy51c2VyXyA9IHRoaXMuZHlncmFwaF8udXNlcl9hdHRyc18gfHwge307XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBzZXJpZXMgaW4gY29sdW1uYXIgb3JkZXIuXG4gICAqIEB0eXBlIHtBcnJheS48c3RyaW5nPn1cbiAgICovXG4gIHRoaXMubGFiZWxzXyA9IFtdO1xuXG4gIHRoaXMuaGlnaGxpZ2h0U2VyaWVzXyA9IHRoaXMuZ2V0KFwiaGlnaGxpZ2h0U2VyaWVzT3B0c1wiKSB8fCB7fTtcbiAgdGhpcy5yZXBhcnNlU2VyaWVzKCk7XG59O1xuXG4vKipcbiAqIE5vdCBvcHRpbWFsLCBidXQgZG9lcyB0aGUgdHJpY2sgd2hlbiB5b3UncmUgb25seSB1c2luZyB0d28gYXhlcy5cbiAqIElmIHdlIG1vdmUgdG8gbW9yZSBheGVzLCB0aGlzIGNhbiBqdXN0IGJlY29tZSBhIGZ1bmN0aW9uLlxuICpcbiAqIEB0eXBlIHtPYmplY3QuPG51bWJlcj59XG4gKiBAcHJpdmF0ZVxuICovXG5EeWdyYXBoT3B0aW9ucy5BWElTX1NUUklOR19NQVBQSU5HU18gPSB7XG4gICd5JyA6IDAsXG4gICdZJyA6IDAsXG4gICd5MScgOiAwLFxuICAnWTEnIDogMCxcbiAgJ3kyJyA6IDEsXG4gICdZMicgOiAxXG59O1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gYXhpc1xuICogQHByaXZhdGVcbiAqL1xuRHlncmFwaE9wdGlvbnMuYXhpc1RvSW5kZXhfID0gZnVuY3Rpb24oYXhpcykge1xuICBpZiAodHlwZW9mKGF4aXMpID09IFwic3RyaW5nXCIpIHtcbiAgICBpZiAoRHlncmFwaE9wdGlvbnMuQVhJU19TVFJJTkdfTUFQUElOR1NfLmhhc093blByb3BlcnR5KGF4aXMpKSB7XG4gICAgICByZXR1cm4gRHlncmFwaE9wdGlvbnMuQVhJU19TVFJJTkdfTUFQUElOR1NfW2F4aXNdO1xuICAgIH1cbiAgICB0aHJvdyBcIlVua25vd24gYXhpcyA6IFwiICsgYXhpcztcbiAgfVxuICBpZiAodHlwZW9mKGF4aXMpID09IFwibnVtYmVyXCIpIHtcbiAgICBpZiAoYXhpcyA9PT0gMCB8fCBheGlzID09PSAxKSB7XG4gICAgICByZXR1cm4gYXhpcztcbiAgICB9XG4gICAgdGhyb3cgXCJEeWdyYXBocyBvbmx5IHN1cHBvcnRzIHR3byB5LWF4ZXMsIGluZGV4ZWQgZnJvbSAwLTEuXCI7XG4gIH1cbiAgaWYgKGF4aXMpIHtcbiAgICB0aHJvdyBcIlVua25vd24gYXhpcyA6IFwiICsgYXhpcztcbiAgfVxuICAvLyBObyBheGlzIHNwZWNpZmljYXRpb24gbWVhbnMgYXhpcyAwLlxuICByZXR1cm4gMDtcbn07XG5cbi8qKlxuICogUmVwYXJzZXMgb3B0aW9ucyB0aGF0IGFyZSBhbGwgcmVsYXRlZCB0byBzZXJpZXMuIFRoaXMgdHlwaWNhbGx5IG9jY3VycyB3aGVuXG4gKiBvcHRpb25zIGFyZSBlaXRoZXIgdXBkYXRlZCwgb3Igc291cmNlIGRhdGEgaGFzIGJlZW4gbWFkZSBhdmFpbGFibGUuXG4gKlxuICogVE9ETyhrb25pZ3NiZXJnKTogVGhlIG1ldGhvZCBuYW1lIGlzIGtpbmQgb2Ygd2VhazsgZml4LlxuICovXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUucmVwYXJzZVNlcmllcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbGFiZWxzID0gdGhpcy5nZXQoXCJsYWJlbHNcIik7XG4gIGlmICghbGFiZWxzKSB7XG4gICAgcmV0dXJuOyAvLyAtLSBjYW4ndCBkbyBtb3JlIGZvciBub3csIHdpbGwgcGFyc2UgYWZ0ZXIgZ2V0dGluZyB0aGUgbGFiZWxzLlxuICB9XG5cbiAgdGhpcy5sYWJlbHNfID0gbGFiZWxzLnNsaWNlKDEpO1xuXG4gIHRoaXMueUF4ZXNfID0gWyB7IHNlcmllcyA6IFtdLCBvcHRpb25zIDoge319IF07IC8vIEFsd2F5cyBvbmUgYXhpcyBhdCBsZWFzdC5cbiAgdGhpcy54QXhpc18gPSB7IG9wdGlvbnMgOiB7fSB9O1xuICB0aGlzLnNlcmllc18gPSB7fTtcblxuICAvLyBTZXJpZXMgYXJlIHNwZWNpZmllZCBpbiB0aGUgc2VyaWVzIGVsZW1lbnQ6XG4gIC8vXG4gIC8vIHtcbiAgLy8gICBsYWJlbHM6IFsgXCJYXCIsIFwiZm9vXCIsIFwiYmFyXCIgXSxcbiAgLy8gICBwb2ludFNpemU6IDMsXG4gIC8vICAgc2VyaWVzIDoge1xuICAvLyAgICAgZm9vIDoge30sIC8vIG9wdGlvbnMgZm9yIGZvb1xuICAvLyAgICAgYmFyIDoge30gLy8gb3B0aW9ucyBmb3IgYmFyXG4gIC8vICAgfVxuICAvLyB9XG4gIC8vXG4gIC8vIFNvLCBpZiBzZXJpZXMgaXMgZm91bmQsIGl0J3MgZXhwZWN0ZWQgdG8gY29udGFpbiBwZXItc2VyaWVzIGRhdGEsXG4gIC8vIG90aGVyd2lzZSBzZXQgYSBkZWZhdWx0LlxuICB2YXIgc2VyaWVzRGljdCA9IHRoaXMudXNlcl8uc2VyaWVzIHx8IHt9O1xuICBmb3IgKHZhciBpZHggPSAwOyBpZHggPCB0aGlzLmxhYmVsc18ubGVuZ3RoOyBpZHgrKykge1xuICAgIHZhciBzZXJpZXNOYW1lID0gdGhpcy5sYWJlbHNfW2lkeF07XG4gICAgdmFyIG9wdGlvbnNGb3JTZXJpZXMgPSBzZXJpZXNEaWN0W3Nlcmllc05hbWVdIHx8IHt9O1xuICAgIHZhciB5QXhpcyA9IER5Z3JhcGhPcHRpb25zLmF4aXNUb0luZGV4XyhvcHRpb25zRm9yU2VyaWVzW1wiYXhpc1wiXSk7XG5cbiAgICB0aGlzLnNlcmllc19bc2VyaWVzTmFtZV0gPSB7XG4gICAgICBpZHg6IGlkeCxcbiAgICAgIHlBeGlzOiB5QXhpcyxcbiAgICAgIG9wdGlvbnMgOiBvcHRpb25zRm9yU2VyaWVzIH07XG5cbiAgICBpZiAoIXRoaXMueUF4ZXNfW3lBeGlzXSkge1xuICAgICAgdGhpcy55QXhlc19beUF4aXNdID0gIHsgc2VyaWVzIDogWyBzZXJpZXNOYW1lIF0sIG9wdGlvbnMgOiB7fSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnlBeGVzX1t5QXhpc10uc2VyaWVzLnB1c2goc2VyaWVzTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGF4aXNfb3B0cyA9IHRoaXMudXNlcl9bXCJheGVzXCJdIHx8IHt9O1xuICB1dGlscy51cGRhdGUodGhpcy55QXhlc19bMF0ub3B0aW9ucywgYXhpc19vcHRzW1wieVwiXSB8fCB7fSk7XG4gIGlmICh0aGlzLnlBeGVzXy5sZW5ndGggPiAxKSB7XG4gICAgdXRpbHMudXBkYXRlKHRoaXMueUF4ZXNfWzFdLm9wdGlvbnMsIGF4aXNfb3B0c1tcInkyXCJdIHx8IHt9KTtcbiAgfVxuICB1dGlscy51cGRhdGUodGhpcy54QXhpc18ub3B0aW9ucywgYXhpc19vcHRzW1wieFwiXSB8fCB7fSk7XG5cbiAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPSAncHJvZHVjdGlvbicpIHtcbiAgLy8gRm9yIFwicHJvZHVjdGlvblwiIGNvZGUsIHRoaXMgZ2V0cyByZW1vdmVkIGJ5IHVnbGlmeWpzLlxuICAgIHRoaXMudmFsaWRhdGVPcHRpb25zXygpO1xuICB9XG59O1xuXG4vKipcbiAqIEdldCBhIGdsb2JhbCB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSB0aGUgbmFtZSBvZiB0aGUgb3B0aW9uLlxuICovXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24obmFtZSkge1xuICB2YXIgcmVzdWx0ID0gdGhpcy5nZXRHbG9iYWxVc2VyXyhuYW1lKTtcbiAgaWYgKHJlc3VsdCAhPT0gbnVsbCkge1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIHRoaXMuZ2V0R2xvYmFsRGVmYXVsdF8obmFtZSk7XG59O1xuXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUuZ2V0R2xvYmFsVXNlcl8gPSBmdW5jdGlvbihuYW1lKSB7XG4gIGlmICh0aGlzLnVzZXJfLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgcmV0dXJuIHRoaXMudXNlcl9bbmFtZV07XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUuZ2V0R2xvYmFsRGVmYXVsdF8gPSBmdW5jdGlvbihuYW1lKSB7XG4gIGlmICh0aGlzLmdsb2JhbF8uaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICByZXR1cm4gdGhpcy5nbG9iYWxfW25hbWVdO1xuICB9XG4gIGlmIChERUZBVUxUX0FUVFJTLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgcmV0dXJuIERFRkFVTFRfQVRUUlNbbmFtZV07XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIEdldCBhIHZhbHVlIGZvciBhIHNwZWNpZmljIGF4aXMuIElmIHRoZXJlIGlzIG5vIHNwZWNpZmljIHZhbHVlIGZvciB0aGUgYXhpcyxcbiAqIHRoZSBnbG9iYWwgdmFsdWUgaXMgcmV0dXJuZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgdGhlIG5hbWUgb2YgdGhlIG9wdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gYXhpcyB0aGUgYXhpcyB0byBzZWFyY2guIENhbiBiZSB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gKiAoXCJ5XCIsIFwieTJcIikgb3IgdGhlIGF4aXMgbnVtYmVyICgwLCAxKS5cbiAqL1xuRHlncmFwaE9wdGlvbnMucHJvdG90eXBlLmdldEZvckF4aXMgPSBmdW5jdGlvbihuYW1lLCBheGlzKSB7XG4gIHZhciBheGlzSWR4O1xuICB2YXIgYXhpc1N0cmluZztcblxuICAvLyBTaW5jZSBheGlzIGNhbiBiZSBhIG51bWJlciBvciBhIHN0cmluZywgc3RyYWlnaHRlbiBldmVyeXRoaW5nIG91dCBoZXJlLlxuICBpZiAodHlwZW9mKGF4aXMpID09ICdudW1iZXInKSB7XG4gICAgYXhpc0lkeCA9IGF4aXM7XG4gICAgYXhpc1N0cmluZyA9IGF4aXNJZHggPT09IDAgPyBcInlcIiA6IFwieTJcIjtcbiAgfSBlbHNlIHtcbiAgICBpZiAoYXhpcyA9PSBcInkxXCIpIHsgYXhpcyA9IFwieVwiOyB9IC8vIFN0YW5kYXJkaXplIG9uICd5Jy4gSXMgdGhpcyBiYWQ/IEkgdGhpbmsgc28uXG4gICAgaWYgKGF4aXMgPT0gXCJ5XCIpIHtcbiAgICAgIGF4aXNJZHggPSAwO1xuICAgIH0gZWxzZSBpZiAoYXhpcyA9PSBcInkyXCIpIHtcbiAgICAgIGF4aXNJZHggPSAxO1xuICAgIH0gZWxzZSBpZiAoYXhpcyA9PSBcInhcIikge1xuICAgICAgYXhpc0lkeCA9IC0xOyAvLyBzaW1wbHkgYSBwbGFjZWhvbGRlciBmb3IgYmVsb3cuXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IFwiVW5rbm93biBheGlzIFwiICsgYXhpcztcbiAgICB9XG4gICAgYXhpc1N0cmluZyA9IGF4aXM7XG4gIH1cblxuICB2YXIgdXNlckF4aXMgPSAoYXhpc0lkeCA9PSAtMSkgPyB0aGlzLnhBeGlzXyA6IHRoaXMueUF4ZXNfW2F4aXNJZHhdO1xuXG4gIC8vIFNlYXJjaCB0aGUgdXNlci1zcGVjaWZpZWQgYXhpcyBvcHRpb24gZmlyc3QuXG4gIGlmICh1c2VyQXhpcykgeyAvLyBUaGlzIGNvbmRpdGlvbiBjb3VsZCBiZSByZW1vdmVkIGlmIHdlIGFsd2F5cyBzZXQgdXAgdGhpcy55QXhlc18gZm9yIHkyLlxuICAgIHZhciBheGlzT3B0aW9ucyA9IHVzZXJBeGlzLm9wdGlvbnM7XG4gICAgaWYgKGF4aXNPcHRpb25zLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICByZXR1cm4gYXhpc09wdGlvbnNbbmFtZV07XG4gICAgfVxuICB9XG5cbiAgLy8gVXNlci1zcGVjaWZpZWQgZ2xvYmFsIG9wdGlvbnMgc2Vjb25kLlxuICAvLyBCdXQsIGhhY2ssIGlnbm9yZSBnbG9iYWxseS1zcGVjaWZpZWQgJ2xvZ3NjYWxlJyBmb3IgJ3gnIGF4aXMgZGVjbGFyYXRpb24uXG4gIGlmICghKGF4aXMgPT09ICd4JyAmJiBuYW1lID09PSAnbG9nc2NhbGUnKSkge1xuICAgIHZhciByZXN1bHQgPSB0aGlzLmdldEdsb2JhbFVzZXJfKG5hbWUpO1xuICAgIGlmIChyZXN1bHQgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICB9XG4gIC8vIERlZmF1bHQgYXhpcyBvcHRpb25zIHRoaXJkLlxuICB2YXIgZGVmYXVsdEF4aXNPcHRpb25zID0gREVGQVVMVF9BVFRSUy5heGVzW2F4aXNTdHJpbmddO1xuICBpZiAoZGVmYXVsdEF4aXNPcHRpb25zLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRBeGlzT3B0aW9uc1tuYW1lXTtcbiAgfVxuXG4gIC8vIERlZmF1bHQgZ2xvYmFsIG9wdGlvbnMgbGFzdC5cbiAgcmV0dXJuIHRoaXMuZ2V0R2xvYmFsRGVmYXVsdF8obmFtZSk7XG59O1xuXG4vKipcbiAqIEdldCBhIHZhbHVlIGZvciBhIHNwZWNpZmljIHNlcmllcy4gSWYgdGhlcmUgaXMgbm8gc3BlY2lmaWMgdmFsdWUgZm9yIHRoZSBzZXJpZXMsXG4gKiB0aGUgdmFsdWUgZm9yIHRoZSBheGlzIGlzIHJldHVybmVkIChhbmQgYWZ0ZXJ3YXJkcywgdGhlIGdsb2JhbCB2YWx1ZS4pXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgdGhlIG5hbWUgb2YgdGhlIG9wdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzZXJpZXMgdGhlIHNlcmllcyB0byBzZWFyY2guXG4gKi9cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5nZXRGb3JTZXJpZXMgPSBmdW5jdGlvbihuYW1lLCBzZXJpZXMpIHtcbiAgLy8gSG9ub3JzIGluZGV4ZXMgYXMgc2VyaWVzLlxuICBpZiAoc2VyaWVzID09PSB0aGlzLmR5Z3JhcGhfLmdldEhpZ2hsaWdodFNlcmllcygpKSB7XG4gICAgaWYgKHRoaXMuaGlnaGxpZ2h0U2VyaWVzXy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgcmV0dXJuIHRoaXMuaGlnaGxpZ2h0U2VyaWVzX1tuYW1lXTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXRoaXMuc2VyaWVzXy5oYXNPd25Qcm9wZXJ0eShzZXJpZXMpKSB7XG4gICAgdGhyb3cgXCJVbmtub3duIHNlcmllczogXCIgKyBzZXJpZXM7XG4gIH1cblxuICB2YXIgc2VyaWVzT2JqID0gdGhpcy5zZXJpZXNfW3Nlcmllc107XG4gIHZhciBzZXJpZXNPcHRpb25zID0gc2VyaWVzT2JqW1wib3B0aW9uc1wiXTtcbiAgaWYgKHNlcmllc09wdGlvbnMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICByZXR1cm4gc2VyaWVzT3B0aW9uc1tuYW1lXTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmdldEZvckF4aXMobmFtZSwgc2VyaWVzT2JqW1wieUF4aXNcIl0pO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgeS1heGVzIG9uIHRoZSBjaGFydC5cbiAqIEByZXR1cm4ge251bWJlcn0gdGhlIG51bWJlciBvZiBheGVzLlxuICovXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUubnVtQXhlcyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy55QXhlc18ubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gdGhlIHktYXhpcyBmb3IgYSBnaXZlbiBzZXJpZXMsIHNwZWNpZmllZCBieSBuYW1lLlxuICovXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUuYXhpc0ZvclNlcmllcyA9IGZ1bmN0aW9uKHNlcmllcykge1xuICByZXR1cm4gdGhpcy5zZXJpZXNfW3Nlcmllc10ueUF4aXM7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG9wdGlvbnMgZm9yIHRoZSBzcGVjaWZpZWQgYXhpcy5cbiAqL1xuLy8gVE9ETyhrb25pZ3NiZXJnKTogdGhpcyBpcyB5LWF4aXMgc3BlY2lmaWMuIFN1cHBvcnQgdGhlIHggYXhpcy5cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5heGlzT3B0aW9ucyA9IGZ1bmN0aW9uKHlBeGlzKSB7XG4gIHJldHVybiB0aGlzLnlBeGVzX1t5QXhpc10ub3B0aW9ucztcbn07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBzZXJpZXMgYXNzb2NpYXRlZCB3aXRoIGFuIGF4aXMuXG4gKi9cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5zZXJpZXNGb3JBeGlzID0gZnVuY3Rpb24oeUF4aXMpIHtcbiAgcmV0dXJuIHRoaXMueUF4ZXNfW3lBeGlzXS5zZXJpZXM7XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgbGlzdCBvZiBhbGwgc2VyaWVzLCBpbiB0aGVpciBjb2x1bW5hciBvcmRlci5cbiAqL1xuRHlncmFwaE9wdGlvbnMucHJvdG90eXBlLnNlcmllc05hbWVzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmxhYmVsc187XG59O1xuXG5pZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9ICdwcm9kdWN0aW9uJykge1xuLy8gRm9yIFwicHJvZHVjdGlvblwiIGNvZGUsIHRoaXMgZ2V0cyByZW1vdmVkIGJ5IHVnbGlmeWpzLlxuXG4vKipcbiAqIFZhbGlkYXRlIGFsbCBvcHRpb25zLlxuICogVGhpcyByZXF1aXJlcyBPUFRJT05TX1JFRkVSRU5DRSwgd2hpY2ggaXMgb25seSBhdmFpbGFibGUgaW4gZGVidWcgYnVpbGRzLlxuICogQHByaXZhdGVcbiAqL1xuRHlncmFwaE9wdGlvbnMucHJvdG90eXBlLnZhbGlkYXRlT3B0aW9uc18gPSBmdW5jdGlvbigpIHtcbiAgaWYgKHR5cGVvZiBPUFRJT05TX1JFRkVSRU5DRSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aHJvdyAnQ2FsbGVkIHZhbGlkYXRlT3B0aW9uc18gaW4gcHJvZCBidWlsZC4nO1xuICB9XG5cbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIgdmFsaWRhdGVPcHRpb24gPSBmdW5jdGlvbihvcHRpb25OYW1lKSB7XG4gICAgaWYgKCFPUFRJT05TX1JFRkVSRU5DRVtvcHRpb25OYW1lXSkge1xuICAgICAgdGhhdC53YXJuSW52YWxpZE9wdGlvbl8ob3B0aW9uTmFtZSk7XG4gICAgfVxuICB9O1xuXG4gIHZhciBvcHRpb25zRGljdHMgPSBbdGhpcy54QXhpc18ub3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnlBeGVzX1swXS5vcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMueUF4ZXNfWzFdICYmIHRoaXMueUF4ZXNfWzFdLm9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5nbG9iYWxfLFxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXNlcl8sXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5oaWdobGlnaHRTZXJpZXNfXTtcbiAgdmFyIG5hbWVzID0gdGhpcy5zZXJpZXNOYW1lcygpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG5hbWUgPSBuYW1lc1tpXTtcbiAgICBpZiAodGhpcy5zZXJpZXNfLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICBvcHRpb25zRGljdHMucHVzaCh0aGlzLnNlcmllc19bbmFtZV0ub3B0aW9ucyk7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgb3B0aW9uc0RpY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGRpY3QgPSBvcHRpb25zRGljdHNbaV07XG4gICAgaWYgKCFkaWN0KSBjb250aW51ZTtcbiAgICBmb3IgKHZhciBvcHRpb25OYW1lIGluIGRpY3QpIHtcbiAgICAgIGlmIChkaWN0Lmhhc093blByb3BlcnR5KG9wdGlvbk5hbWUpKSB7XG4gICAgICAgIHZhbGlkYXRlT3B0aW9uKG9wdGlvbk5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxudmFyIFdBUk5JTkdTID0ge307ICAvLyBPbmx5IHNob3cgYW55IHBhcnRpY3VsYXIgd2FybmluZyBvbmNlLlxuXG4vKipcbiAqIExvZ3MgYSB3YXJuaW5nIGFib3V0IGludmFsaWQgb3B0aW9ucy5cbiAqIFRPRE86IG1ha2UgdGhpcyB0aHJvdyBmb3IgdGVzdGluZ1xuICogQHByaXZhdGVcbiAqL1xuRHlncmFwaE9wdGlvbnMucHJvdG90eXBlLndhcm5JbnZhbGlkT3B0aW9uXyA9IGZ1bmN0aW9uKG9wdGlvbk5hbWUpIHtcbiAgaWYgKCFXQVJOSU5HU1tvcHRpb25OYW1lXSkge1xuICAgIFdBUk5JTkdTW29wdGlvbk5hbWVdID0gdHJ1ZTtcbiAgICB2YXIgaXNTZXJpZXMgPSAodGhpcy5sYWJlbHNfLmluZGV4T2Yob3B0aW9uTmFtZSkgPj0gMCk7XG4gICAgaWYgKGlzU2VyaWVzKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1VzZSBuZXctc3R5bGUgcGVyLXNlcmllcyBvcHRpb25zIChzYXcgJyArIG9wdGlvbk5hbWUgKyAnIGFzIHRvcC1sZXZlbCBvcHRpb25zIGtleSkuIFNlZSBodHRwOi8vYmxvZy5keWdyYXBocy5jb20vMjAxMi8xMi90aGUtbmV3LWFuZC1iZXR0ZXItd2F5LXRvLXNwZWNpZnkuaHRtbCAoVGhlIE5ldyBhbmQgQmV0dGVyIFdheSB0byBTcGVjaWZ5IFNlcmllcyBhbmQgQXhpcyBPcHRpb25zKS4nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS53YXJuKCdVbmtub3duIG9wdGlvbiAnICsgb3B0aW9uTmFtZSArICcgKHNlZSBodHRwczovL2R5Z3JhcGhzLmNvbS9vcHRpb25zLmh0bWwgZm9yIHRoZSBmdWxsIGxpc3Qgb2Ygb3B0aW9ucyknKTtcbiAgICB9XG4gICAgdGhyb3cgXCJpbnZhbGlkIG9wdGlvbiBcIiArIG9wdGlvbk5hbWU7XG4gIH1cbn07XG5cbi8vIFJlc2V0IGxpc3Qgb2YgcHJldmlvdXNseS1zaG93biB3YXJuaW5ncy4gVXNlZCBmb3IgdGVzdGluZy5cbkR5Z3JhcGhPcHRpb25zLnJlc2V0V2FybmluZ3NfID0gZnVuY3Rpb24oKSB7XG4gIFdBUk5JTkdTID0ge307XG59O1xuXG59XG5cbmV4cG9ydCBkZWZhdWx0IER5Z3JhcGhPcHRpb25zO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxZQUFZOztBQUFDO0VBQUE7QUFBQTtBQUFBO0FBRWI7QUFDQTtBQUNBO0FBQTREO0FBQUE7QUFBQTtBQUU1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJQSxjQUFjLEdBQUcsU0FBakJBLGNBQWMsQ0FBWUMsT0FBTyxFQUFFO0VBQ3JDO0FBQ0Y7QUFDQTtBQUNBO0VBQ0UsSUFBSSxDQUFDQyxRQUFRLEdBQUdELE9BQU87O0VBRXZCO0FBQ0Y7QUFDQTtBQUNBO0VBQ0UsSUFBSSxDQUFDRSxNQUFNLEdBQUcsRUFBRTs7RUFFaEI7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0UsSUFBSSxDQUFDQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0VBQ2hCLElBQUksQ0FBQ0MsT0FBTyxHQUFHLENBQUMsQ0FBQzs7RUFFakI7RUFDQSxJQUFJLENBQUNDLE9BQU8sR0FBRyxJQUFJLENBQUNKLFFBQVEsQ0FBQ0ssTUFBTTtFQUNuQyxJQUFJLENBQUNDLEtBQUssR0FBRyxJQUFJLENBQUNOLFFBQVEsQ0FBQ08sV0FBVyxJQUFJLENBQUMsQ0FBQzs7RUFFNUM7QUFDRjtBQUNBO0FBQ0E7RUFDRSxJQUFJLENBQUNDLE9BQU8sR0FBRyxFQUFFO0VBRWpCLElBQUksQ0FBQ0MsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDQyxHQUFHLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7RUFDN0QsSUFBSSxDQUFDQyxhQUFhLEVBQUU7QUFDdEIsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBYixjQUFjLENBQUNjLHFCQUFx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